72 class(*),
target,
intent(in) :: data
73 real(kind=
rp),
intent(in),
optional :: t
75 character(len=5) :: id_str
76 character(len=1024) :: fname
77 integer :: ierr, suffix_pos, optional_fields
78 type(
field_t),
pointer :: u, v, w, p, s
79 type(
field_t),
pointer :: abx1,abx2
80 type(
field_t),
pointer :: aby1,aby2
81 type(
field_t),
pointer :: abz1,abz2
82 type(
field_t),
pointer :: abs1,abs2
87 real(kind=
rp),
pointer :: dtlag(:), tlag(:)
88 type(
mesh_t),
pointer :: msh
89 type(mpi_status) :: status
91 integer (kind=MPI_OFFSET_KIND) :: mpi_offset, byte_offset
92 integer(kind=i8) :: n_glb_dofs, dof_offset
93 logical :: write_lag, write_scalar, write_dtlag, write_scalarlag, write_abvel
105 if ( .not.
associated(data%u) .or. &
106 .not.
associated(data%v) .or. &
107 .not.
associated(data%w) .or. &
108 .not.
associated(data%p) )
then
120 if (
associated(data%ulag))
then
125 optional_fields = optional_fields + 1
130 if (
associated(data%s))
then
132 write_scalar = .true.
133 optional_fields = optional_fields + 2
135 write_scalar = .false.
138 if (
associated(data%tlag))
then
142 optional_fields = optional_fields + 4
144 write_dtlag = .false.
146 write_abvel = .false.
147 if (
associated(data%abx1))
then
154 optional_fields = optional_fields + 8
157 write_scalarlag = .false.
158 if (
associated(data%abs1))
then
162 optional_fields = optional_fields + 16
163 write_scalarlag = .true.
171 write(id_str,
'(i5.5)') this%counter
172 fname = trim(this%fname(1:suffix_pos-1))//id_str//
'.chkp'
175 dof_offset = int(msh%offset_el,
i8) * int(u%Xh%lx * u%Xh%ly * u%Xh%lz,
i8)
176 n_glb_dofs = int(u%Xh%lx * u%Xh%ly * u%Xh%lz,
i8) * int(msh%glb_nelv,
i8)
178 call mpi_file_open(
neko_comm, trim(fname), &
179 mpi_mode_wronly + mpi_mode_create, mpi_info_null, fh, ierr)
180 call mpi_file_write_all(fh, msh%glb_nelv, 1, mpi_integer, status, ierr)
181 call mpi_file_write_all(fh, msh%gdim, 1, mpi_integer, status, ierr)
182 call mpi_file_write_all(fh, u%Xh%lx, 1, mpi_integer, status, ierr)
183 call mpi_file_write_all(fh, optional_fields, 1, mpi_integer, status, ierr)
184 call mpi_file_write_all(fh, time, 1, mpi_double_precision, status, ierr)
192 byte_offset = byte_offset + &
194 call mpi_file_write_at_all(fh, byte_offset,u%x, u%dof%size(), &
197 mpi_offset = mpi_offset +&
200 byte_offset = mpi_offset + &
202 call mpi_file_write_at_all(fh, byte_offset, v%x, v%dof%size(), &
206 byte_offset = mpi_offset + &
208 call mpi_file_write_at_all(fh, byte_offset, w%x, w%dof%size(), &
212 byte_offset = mpi_offset + &
214 call mpi_file_write_at_all(fh, byte_offset, p%x, p%dof%size(), &
224 do i = 1, ulag%size()
225 byte_offset = mpi_offset + &
230 associate(x => ulag%lf(i)%x)
231 call mpi_file_write_at_all(fh, byte_offset, x, &
237 do i = 1, vlag%size()
238 byte_offset = mpi_offset + &
243 associate(x => vlag%lf(i)%x)
244 call mpi_file_write_at_all(fh, byte_offset, x, &
247 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
250 do i = 1, wlag%size()
251 byte_offset = mpi_offset + &
252 dof_offset * int(mpi_real_prec_size, i8)
256 associate(x => wlag%lf(i)%x)
257 call mpi_file_write_at_all(fh, byte_offset, x, &
258 wlag%lf(i)%dof%size(), mpi_real_precision, status, ierr)
260 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
265 if (write_scalar)
then
266 byte_offset = mpi_offset + &
267 dof_offset * int(mpi_real_prec_size, i8)
268 call mpi_file_write_at_all(fh, byte_offset, s%x, p%dof%size(), &
269 mpi_real_precision, status, ierr)
270 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
273 if (write_dtlag)
then
274 call mpi_file_write_at_all(fh, mpi_offset, tlag, 10, mpi_real_precision, status, ierr)
275 mpi_offset = mpi_offset + 10_i8 * int(mpi_real_prec_size, i8)
276 call mpi_file_write_at_all(fh, mpi_offset, dtlag, 10, mpi_real_precision, status, ierr)
277 mpi_offset = mpi_offset + 10_i8 * int(mpi_real_prec_size, i8)
280 if (write_abvel)
then
281 byte_offset = mpi_offset + &
282 dof_offset * int(mpi_real_prec_size, i8)
283 call mpi_file_write_at_all(fh, byte_offset, abx1%x, abx1%dof%size(), &
284 mpi_real_precision, status, ierr)
285 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
286 byte_offset = mpi_offset + &
287 dof_offset * int(mpi_real_prec_size, i8)
288 call mpi_file_write_at_all(fh, byte_offset, abx2%x, abx1%dof%size(), &
289 mpi_real_precision, status, ierr)
290 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
291 byte_offset = mpi_offset + &
292 dof_offset * int(mpi_real_prec_size, i8)
293 call mpi_file_write_at_all(fh, byte_offset, aby1%x, abx1%dof%size(), &
294 mpi_real_precision, status, ierr)
295 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
296 byte_offset = mpi_offset + &
297 dof_offset * int(mpi_real_prec_size, i8)
298 call mpi_file_write_at_all(fh, byte_offset, aby2%x, abx1%dof%size(), &
299 mpi_real_precision, status, ierr)
300 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
301 byte_offset = mpi_offset + &
302 dof_offset * int(mpi_real_prec_size, i8)
303 call mpi_file_write_at_all(fh, byte_offset, abz1%x, abx1%dof%size(), &
304 mpi_real_precision, status, ierr)
305 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
306 byte_offset = mpi_offset + &
307 dof_offset * int(mpi_real_prec_size, i8)
308 call mpi_file_write_at_all(fh, byte_offset, abz2%x, abx1%dof%size(), &
309 mpi_real_precision, status, ierr)
310 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
313 if (write_scalarlag)
then
314 do i = 1, slag%size()
315 byte_offset = mpi_offset + &
316 dof_offset * int(mpi_real_prec_size, i8)
320 associate(x => slag%lf(i)%x)
321 call mpi_file_write_at_all(fh, byte_offset, x, &
322 slag%lf(i)%dof%size(), mpi_real_precision, status, ierr)
324 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
327 byte_offset = mpi_offset + &
328 dof_offset * int(mpi_real_prec_size, i8)
329 call mpi_file_write_at_all(fh, byte_offset, abs1%x, abx1%dof%size(), &
330 mpi_real_precision, status, ierr)
331 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
332 byte_offset = mpi_offset + &
333 dof_offset * int(mpi_real_prec_size, i8)
334 call mpi_file_write_at_all(fh, byte_offset, abs2%x, abx1%dof%size(), &
335 mpi_real_precision, status, ierr)
336 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
339 call mpi_file_close(fh, ierr)
341 this%counter = this%counter + 1
348 class(*),
target,
intent(inout) :: data
349 type(chkp_t),
pointer :: chkp
350 character(len=5) :: id_str
351 character(len=1024) :: fname
352 integer :: ierr, suffix_pos
353 type(field_t),
pointer :: u, v, w, p, s
354 type(field_series_t),
pointer :: ulag => null()
355 type(field_series_t),
pointer :: vlag => null()
356 type(field_series_t),
pointer :: wlag => null()
357 type(field_series_t),
pointer :: slag => null()
358 type(mesh_t),
pointer :: msh
359 type(mpi_status) :: status
361 type(field_t),
pointer :: abx1,abx2
362 type(field_t),
pointer :: aby1,aby2
363 type(field_t),
pointer :: abz1,abz2
364 type(field_t),
pointer :: abs1,abs2
365 real(kind=rp),
allocatable :: x_coord(:,:,:,:)
366 real(kind=rp),
allocatable :: y_coord(:,:,:,:)
367 real(kind=rp),
allocatable :: z_coord(:,:,:,:)
368 real(kind=rp),
pointer :: dtlag(:), tlag(:)
369 integer (kind=MPI_OFFSET_KIND) :: mpi_offset, byte_offset
370 integer(kind=i8) :: n_glb_dofs, dof_offset
371 integer :: glb_nelv, gdim, lx, have_lag, have_scalar, nel, optional_fields, have_dtlag
372 integer :: have_abvel, have_scalarlag
373 logical :: read_lag, read_scalar, read_dtlag, read_abvel, read_scalarlag
375 real(kind=rp) :: center_x, center_y, center_z
377 type(dofmap_t) :: dof
379 call this%check_exists()
384 if ( .not.
associated(data%u) .or. &
385 .not.
associated(data%v) .or. &
386 .not.
associated(data%w) .or. &
387 .not.
associated(data%p) )
then
388 call neko_error(
'Checkpoint not initialized')
396 if (
allocated(data%previous_mesh%elements))
then
397 msh => data%previous_mesh
398 this%mesh2mesh = .true.
399 tol = data%mesh2mesh_tol
402 this%mesh2mesh = .false.
405 if (
associated(data%ulag))
then
414 if (
associated(data%s))
then
418 read_scalar = .false.
420 if (
associated(data%dtlag))
then
428 if (
associated(data%abx1))
then
437 read_scalarlag = .false.
438 if (
associated(data%abs1))
then
442 read_scalarlag = .true.
448 call neko_error(
'Invalid data')
453 call mpi_file_open(neko_comm, trim(this%fname), &
454 mpi_mode_rdonly, mpi_info_null, fh, ierr)
455 call mpi_file_read_all(fh, glb_nelv, 1, mpi_integer, status, ierr)
456 call mpi_file_read_all(fh, gdim, 1, mpi_integer, status, ierr)
457 call mpi_file_read_all(fh, lx, 1, mpi_integer, status, ierr)
458 call mpi_file_read_all(fh, optional_fields, 1, mpi_integer, status, ierr)
459 call mpi_file_read_all(fh, chkp%t, 1, mpi_double_precision, status, ierr)
461 have_lag = mod(optional_fields,2)/1
462 have_scalar = mod(optional_fields,4)/2
463 have_dtlag = mod(optional_fields,8)/4
464 have_abvel = mod(optional_fields,16)/8
465 have_scalarlag = mod(optional_fields,32)/16
467 if ( ( glb_nelv .ne. msh%glb_nelv ) .or. &
468 ( gdim .ne. msh%gdim) .or. &
469 ( (have_lag .eq. 0) .and. (read_lag) ) .or. &
470 ( (have_scalar .eq. 0) .and. (read_scalar) ) )
then
471 call neko_error(
'Checkpoint does not match case')
475 if (gdim .eq. 3)
then
476 call this%chkp_Xh%init(gll, lx, lx, lx)
478 call this%chkp_Xh%init(gll, lx, lx)
480 if (this%mesh2mesh)
then
481 dof = dofmap_t(msh, this%chkp_Xh)
482 allocate(x_coord(u%Xh%lx,u%Xh%ly,u%Xh%lz,u%msh%nelv))
483 allocate(y_coord(u%Xh%lx,u%Xh%ly,u%Xh%lz,u%msh%nelv))
484 allocate(z_coord(u%Xh%lx,u%Xh%ly,u%Xh%lz,u%msh%nelv))
489 do e = 1, u%dof%msh%nelv
493 do i = 1,u%dof%Xh%lxyz
494 center_x = center_x + u%dof%x(i,1,1,e)
495 center_y = center_y + u%dof%y(i,1,1,e)
496 center_z = center_z + u%dof%z(i,1,1,e)
498 center_x = center_x/u%Xh%lxyz
499 center_y = center_y/u%Xh%lxyz
500 center_z = center_z/u%Xh%lxyz
501 do i = 1,u%dof%Xh%lxyz
502 x_coord(i,1,1,e) = u%dof%x(i,1,1,e) - tol*(u%dof%x(i,1,1,e)-center_x)
503 y_coord(i,1,1,e) = u%dof%y(i,1,1,e) - tol*(u%dof%y(i,1,1,e)-center_y)
504 z_coord(i,1,1,e) = u%dof%z(i,1,1,e) - tol*(u%dof%z(i,1,1,e)-center_z)
507 call this%global_interp%init(dof,tol=tol)
508 call this%global_interp%find_points(x_coord,y_coord,z_coord,u%dof%size())
513 call this%space_interp%init(this%sim_Xh, this%chkp_Xh)
515 dof_offset = int(msh%offset_el, i8) * int(this%chkp_Xh%lxyz, i8)
516 n_glb_dofs = int(this%chkp_Xh%lxyz, i8) * int(msh%glb_nelv, i8)
522 byte_offset = 4_i8 * int(mpi_integer_size,i8) + int(mpi_double_precision_size,i8)
523 byte_offset = byte_offset + &
524 dof_offset * int(mpi_real_prec_size, i8)
525 call this%read_field(fh, byte_offset, u%x, nel)
526 mpi_offset = 4_i8 * int(mpi_integer_size,i8) + int(mpi_double_precision_size,i8)
527 mpi_offset = mpi_offset +&
528 n_glb_dofs * int(mpi_real_prec_size, i8)
530 byte_offset = mpi_offset + &
531 dof_offset * int(mpi_real_prec_size, i8)
532 call this%read_field(fh, byte_offset, v%x, nel)
533 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
535 byte_offset = mpi_offset + &
536 dof_offset * int(mpi_real_prec_size, i8)
537 call this%read_field(fh, byte_offset, w%x, nel)
538 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
540 byte_offset = mpi_offset + &
541 dof_offset * int(mpi_real_prec_size, i8)
542 call this%read_field(fh, byte_offset, p%x, nel)
543 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
550 do i = 1, ulag%size()
551 byte_offset = mpi_offset + &
552 dof_offset * int(mpi_real_prec_size, i8)
553 call this%read_field(fh, byte_offset, ulag%lf(i)%x, nel)
554 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
557 do i = 1, vlag%size()
558 byte_offset = mpi_offset + &
559 dof_offset * int(mpi_real_prec_size, i8)
560 call this%read_field(fh, byte_offset, vlag%lf(i)%x, nel)
561 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
564 do i = 1, wlag%size()
565 byte_offset = mpi_offset + &
566 dof_offset * int(mpi_real_prec_size, i8)
567 call this%read_field(fh, byte_offset, wlag%lf(i)%x, nel)
568 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
572 if (read_scalar)
then
573 byte_offset = mpi_offset + &
574 dof_offset * int(mpi_real_prec_size, i8)
575 call this%read_field(fh, byte_offset, s%x, nel)
576 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
579 if (read_dtlag .and. have_dtlag .eq. 1)
then
580 call mpi_file_read_at_all(fh, mpi_offset, tlag, 10, mpi_real_precision, status, ierr)
581 mpi_offset = mpi_offset + 10_i8 * int(mpi_real_prec_size, i8)
582 call mpi_file_read_at_all(fh, mpi_offset, dtlag, 10, mpi_real_precision, status, ierr)
583 mpi_offset = mpi_offset + 10_i8 * int(mpi_real_prec_size, i8)
586 if (read_abvel .and. have_abvel .eq. 1)
then
587 byte_offset = mpi_offset + &
588 dof_offset * int(mpi_real_prec_size, i8)
589 call this%read_field(fh, byte_offset, abx1%x, nel)
590 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
591 byte_offset = mpi_offset + &
592 dof_offset * int(mpi_real_prec_size, i8)
593 call this%read_field(fh, byte_offset, abx2%x, nel)
594 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
595 byte_offset = mpi_offset + &
596 dof_offset * int(mpi_real_prec_size, i8)
597 call this%read_field(fh, byte_offset, aby1%x, nel)
598 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
599 byte_offset = mpi_offset + &
600 dof_offset * int(mpi_real_prec_size, i8)
601 call this%read_field(fh, byte_offset, aby2%x, nel)
602 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
603 byte_offset = mpi_offset + &
604 dof_offset * int(mpi_real_prec_size, i8)
605 call this%read_field(fh, byte_offset, abz1%x, nel)
606 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
607 byte_offset = mpi_offset + &
608 dof_offset * int(mpi_real_prec_size, i8)
609 call this%read_field(fh, byte_offset, abz2%x, nel)
610 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
612 if (read_scalarlag .and. have_scalarlag .eq. 1)
then
613 do i = 1, slag%size()
614 byte_offset = mpi_offset + &
615 dof_offset * int(mpi_real_prec_size, i8)
616 call this%read_field(fh, byte_offset, slag%lf(i)%x, nel)
617 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
619 byte_offset = mpi_offset + &
620 dof_offset * int(mpi_real_prec_size, i8)
621 call this%read_field(fh, byte_offset, abs1%x, nel)
622 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
623 byte_offset = mpi_offset + &
624 dof_offset * int(mpi_real_prec_size, i8)
625 call this%read_field(fh, byte_offset, abs2%x, nel)
626 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
629 call mpi_file_close(fh, ierr)
631 call this%global_interp%free()
632 call this%space_interp%free()
639 integer(kind=MPI_OFFSET_KIND) :: byte_offset
640 integer,
intent(in) :: nel
641 real(kind=rp) :: x(this%sim_Xh%lxyz, nel)
642 real(kind=rp),
allocatable :: read_array(:)
643 integer :: nel_stride, frac_space
644 type(mpi_status) :: status
647 allocate(read_array(this%chkp_Xh%lxyz*nel))
649 call rzero(read_array,this%chkp_xh%lxyz*nel)
650 call mpi_file_read_at_all(fh, byte_offset, read_array, &
651 nel*this%chkp_Xh%lxyz, mpi_real_precision, status, ierr)
652 if (this%mesh2mesh)
then
654 call this%global_interp%evaluate(x,read_array)
657 call this%space_interp%map_host(x, read_array, nel, this%sim_Xh)
659 deallocate(read_array)
Neko checkpoint file format.
subroutine chkp_file_write(this, data, t)
Write a Neko checkpoint.
subroutine chkp_file_read(this, data)
Load a checkpoint from file.
subroutine chkp_read_field(this, fh, byte_offset, x, nel)
type(mpi_comm) neko_comm
MPI communicator.
type(mpi_datatype) mpi_real_precision
MPI type for working precision of REAL types.
Defines a mapping of the degrees of freedom.
Implements global_interpolation given a dofmap.
Routines to interpolate between different spaces.
integer, public mpi_double_precision_size
Size of MPI type double precision.
integer, public mpi_real_prec_size
Size of working precision REAL types.
integer, public mpi_integer_size
Size of MPI type integer.
integer, parameter, public i8
integer, parameter, public dp
integer, parameter, public rp
Global precision used in computations.
Defines a function space.
pure integer function, public filename_suffix_pos(fname)
Find position (in the string) of a filename's suffix.
Interface for Neko checkpoint files.
Implements global interpolation for arbitrary points in the domain.
Interpolation between two space::space_t.
The function space for the SEM solution fields.