75 class(*),
target,
intent(in) :: data
76 real(kind=
rp),
intent(in),
optional :: t
78 character(len=5) :: id_str
79 character(len=1024) :: fname
80 integer :: ierr, suffix_pos, optional_fields
81 type(
field_t),
pointer :: u, v, w, p, s
82 type(
field_t),
pointer :: abx1,abx2
83 type(
field_t),
pointer :: aby1,aby2
84 type(
field_t),
pointer :: abz1,abz2
85 type(
field_t),
pointer :: abs1,abs2
90 real(kind=
rp),
pointer :: dtlag(:), tlag(:)
91 type(
mesh_t),
pointer :: msh
92 type(mpi_status) :: status
94 integer (kind=MPI_OFFSET_KIND) :: mpi_offset, byte_offset
95 integer(kind=i8) :: n_glb_dofs, dof_offset
96 logical :: write_lag, write_scalar, write_dtlag, write_scalarlag, write_abvel
108 if ( .not.
associated(data%u) .or. &
109 .not.
associated(data%v) .or. &
110 .not.
associated(data%w) .or. &
111 .not.
associated(data%p) )
then
123 if (
associated(data%ulag))
then
128 optional_fields = optional_fields + 1
133 if (
associated(data%s))
then
135 write_scalar = .true.
136 optional_fields = optional_fields + 2
138 write_scalar = .false.
141 if (
associated(data%tlag))
then
145 optional_fields = optional_fields + 4
147 write_dtlag = .false.
149 write_abvel = .false.
150 if (
associated(data%abx1))
then
157 optional_fields = optional_fields + 8
160 write_scalarlag = .false.
161 if (
associated(data%abs1))
then
165 optional_fields = optional_fields + 16
166 write_scalarlag = .true.
173 if (this%overwrite)
then
174 fname = trim(this%fname)
176 write(id_str,
'(i5.5)') this%counter
177 fname = trim(this%fname(1:suffix_pos-1)) // id_str //
'.chkp'
180 dof_offset = int(msh%offset_el,
i8) * int(u%Xh%lx * u%Xh%ly * u%Xh%lz,
i8)
181 n_glb_dofs = int(u%Xh%lx * u%Xh%ly * u%Xh%lz,
i8) * int(msh%glb_nelv,
i8)
183 call mpi_file_open(
neko_comm, trim(fname), &
184 mpi_mode_wronly + mpi_mode_create, mpi_info_null, fh, ierr)
185 call mpi_file_write_all(fh, msh%glb_nelv, 1, mpi_integer, status, ierr)
186 call mpi_file_write_all(fh, msh%gdim, 1, mpi_integer, status, ierr)
187 call mpi_file_write_all(fh, u%Xh%lx, 1, mpi_integer, status, ierr)
188 call mpi_file_write_all(fh, optional_fields, 1, mpi_integer, status, ierr)
189 call mpi_file_write_all(fh, time, 1, mpi_double_precision, status, ierr)
197 byte_offset = byte_offset + &
199 call mpi_file_write_at_all(fh, byte_offset,u%x, u%dof%size(), &
202 mpi_offset = mpi_offset +&
205 byte_offset = mpi_offset + &
207 call mpi_file_write_at_all(fh, byte_offset, v%x, v%dof%size(), &
211 byte_offset = mpi_offset + &
213 call mpi_file_write_at_all(fh, byte_offset, w%x, w%dof%size(), &
217 byte_offset = mpi_offset + &
219 call mpi_file_write_at_all(fh, byte_offset, p%x, p%dof%size(), &
229 do i = 1, ulag%size()
230 byte_offset = mpi_offset + &
235 associate(x => ulag%lf(i)%x)
236 call mpi_file_write_at_all(fh, byte_offset, x, &
242 do i = 1, vlag%size()
243 byte_offset = mpi_offset + &
248 associate(x => vlag%lf(i)%x)
249 call mpi_file_write_at_all(fh, byte_offset, x, &
252 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
255 do i = 1, wlag%size()
256 byte_offset = mpi_offset + &
257 dof_offset * int(mpi_real_prec_size, i8)
261 associate(x => wlag%lf(i)%x)
262 call mpi_file_write_at_all(fh, byte_offset, x, &
263 wlag%lf(i)%dof%size(), mpi_real_precision, status, ierr)
265 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
270 if (write_scalar)
then
271 byte_offset = mpi_offset + &
272 dof_offset * int(mpi_real_prec_size, i8)
273 call mpi_file_write_at_all(fh, byte_offset, s%x, p%dof%size(), &
274 mpi_real_precision, status, ierr)
275 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
278 if (write_dtlag)
then
279 call mpi_file_write_at_all(fh, mpi_offset, tlag, 10, mpi_real_precision, status, ierr)
280 mpi_offset = mpi_offset + 10_i8 * int(mpi_real_prec_size, i8)
281 call mpi_file_write_at_all(fh, mpi_offset, dtlag, 10, mpi_real_precision, status, ierr)
282 mpi_offset = mpi_offset + 10_i8 * int(mpi_real_prec_size, i8)
285 if (write_abvel)
then
286 byte_offset = mpi_offset + &
287 dof_offset * int(mpi_real_prec_size, i8)
288 call mpi_file_write_at_all(fh, byte_offset, abx1%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, abx2%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, aby1%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, aby2%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, abz1%x, abx1%dof%size(), &
309 mpi_real_precision, status, ierr)
310 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
311 byte_offset = mpi_offset + &
312 dof_offset * int(mpi_real_prec_size, i8)
313 call mpi_file_write_at_all(fh, byte_offset, abz2%x, abx1%dof%size(), &
314 mpi_real_precision, status, ierr)
315 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
318 if (write_scalarlag)
then
319 do i = 1, slag%size()
320 byte_offset = mpi_offset + &
321 dof_offset * int(mpi_real_prec_size, i8)
325 associate(x => slag%lf(i)%x)
326 call mpi_file_write_at_all(fh, byte_offset, x, &
327 slag%lf(i)%dof%size(), mpi_real_precision, status, ierr)
329 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, abs1%x, abx1%dof%size(), &
335 mpi_real_precision, status, ierr)
336 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
337 byte_offset = mpi_offset + &
338 dof_offset * int(mpi_real_prec_size, i8)
339 call mpi_file_write_at_all(fh, byte_offset, abs2%x, abx1%dof%size(), &
340 mpi_real_precision, status, ierr)
341 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
344 call mpi_file_close(fh, ierr)
346 if (ierr .ne. mpi_success)
then
347 call neko_error(
'Error writing checkpoint file ' // trim(fname))
350 this%counter = this%counter + 1
357 class(*),
target,
intent(inout) :: data
358 type(chkp_t),
pointer :: chkp
359 character(len=5) :: id_str
360 character(len=1024) :: fname
361 integer :: ierr, suffix_pos
362 type(field_t),
pointer :: u, v, w, p, s
363 type(field_series_t),
pointer :: ulag => null()
364 type(field_series_t),
pointer :: vlag => null()
365 type(field_series_t),
pointer :: wlag => null()
366 type(field_series_t),
pointer :: slag => null()
367 type(mesh_t),
pointer :: msh
368 type(mpi_status) :: status
370 type(field_t),
pointer :: abx1,abx2
371 type(field_t),
pointer :: aby1,aby2
372 type(field_t),
pointer :: abz1,abz2
373 type(field_t),
pointer :: abs1,abs2
374 real(kind=rp),
allocatable :: x_coord(:,:,:,:)
375 real(kind=rp),
allocatable :: y_coord(:,:,:,:)
376 real(kind=rp),
allocatable :: z_coord(:,:,:,:)
377 real(kind=rp),
pointer :: dtlag(:), tlag(:)
378 integer (kind=MPI_OFFSET_KIND) :: mpi_offset, byte_offset
379 integer(kind=i8) :: n_glb_dofs, dof_offset
380 integer :: glb_nelv, gdim, lx, have_lag, have_scalar, nel, optional_fields, have_dtlag
381 integer :: have_abvel, have_scalarlag
382 logical :: read_lag, read_scalar, read_dtlag, read_abvel, read_scalarlag
384 real(kind=rp) :: center_x, center_y, center_z
386 type(dofmap_t) :: dof
388 call this%check_exists()
393 if ( .not.
associated(data%u) .or. &
394 .not.
associated(data%v) .or. &
395 .not.
associated(data%w) .or. &
396 .not.
associated(data%p) )
then
397 call neko_error(
'Checkpoint not initialized')
404 this%chkp_Xh => data%previous_Xh
406 if (
allocated(data%previous_mesh%elements))
then
407 msh => data%previous_mesh
408 this%mesh2mesh = .true.
409 tol = data%mesh2mesh_tol
412 this%mesh2mesh = .false.
415 if (
associated(data%ulag))
then
424 if (
associated(data%s))
then
428 read_scalar = .false.
430 if (
associated(data%dtlag))
then
438 if (
associated(data%abx1))
then
447 read_scalarlag = .false.
448 if (
associated(data%abs1))
then
452 read_scalarlag = .true.
458 call neko_error(
'Invalid data')
463 call mpi_file_open(neko_comm, trim(this%fname), &
464 mpi_mode_rdonly, mpi_info_null, fh, ierr)
465 call mpi_file_read_all(fh, glb_nelv, 1, mpi_integer, status, ierr)
466 call mpi_file_read_all(fh, gdim, 1, mpi_integer, status, ierr)
467 call mpi_file_read_all(fh, lx, 1, mpi_integer, status, ierr)
468 call mpi_file_read_all(fh, optional_fields, 1, mpi_integer, status, ierr)
469 call mpi_file_read_all(fh, chkp%t, 1, mpi_double_precision, status, ierr)
471 have_lag = mod(optional_fields,2)/1
472 have_scalar = mod(optional_fields,4)/2
473 have_dtlag = mod(optional_fields,8)/4
474 have_abvel = mod(optional_fields,16)/8
475 have_scalarlag = mod(optional_fields,32)/16
477 if ( ( glb_nelv .ne. msh%glb_nelv ) .or. &
478 ( gdim .ne. msh%gdim) .or. &
479 ( (have_lag .eq. 0) .and. (read_lag) ) .or. &
480 ( (have_scalar .eq. 0) .and. (read_scalar) ) )
then
481 call neko_error(
'Checkpoint does not match case')
485 if (gdim .eq. 3)
then
486 call this%chkp_Xh%init(gll, lx, lx, lx)
488 call this%chkp_Xh%init(gll, lx, lx)
490 if (this%mesh2mesh)
then
491 call dof%init(msh, this%chkp_Xh)
492 allocate(x_coord(u%Xh%lx,u%Xh%ly,u%Xh%lz,u%msh%nelv))
493 allocate(y_coord(u%Xh%lx,u%Xh%ly,u%Xh%lz,u%msh%nelv))
494 allocate(z_coord(u%Xh%lx,u%Xh%ly,u%Xh%lz,u%msh%nelv))
499 do e = 1, u%dof%msh%nelv
503 do i = 1,u%dof%Xh%lxyz
504 center_x = center_x + u%dof%x(i,1,1,e)
505 center_y = center_y + u%dof%y(i,1,1,e)
506 center_z = center_z + u%dof%z(i,1,1,e)
508 center_x = center_x/u%Xh%lxyz
509 center_y = center_y/u%Xh%lxyz
510 center_z = center_z/u%Xh%lxyz
511 do i = 1,u%dof%Xh%lxyz
512 x_coord(i,1,1,e) = u%dof%x(i,1,1,e) - tol*(u%dof%x(i,1,1,e)-center_x)
513 y_coord(i,1,1,e) = u%dof%y(i,1,1,e) - tol*(u%dof%y(i,1,1,e)-center_y)
514 z_coord(i,1,1,e) = u%dof%z(i,1,1,e) - tol*(u%dof%z(i,1,1,e)-center_z)
517 call this%global_interp%init(dof,tol=tol)
518 call this%global_interp%find_points(x_coord,y_coord,z_coord,u%dof%size())
523 call this%space_interp%init(this%sim_Xh, this%chkp_Xh)
525 dof_offset = int(msh%offset_el, i8) * int(this%chkp_Xh%lxyz, i8)
526 n_glb_dofs = int(this%chkp_Xh%lxyz, i8) * int(msh%glb_nelv, i8)
532 byte_offset = 4_i8 * int(mpi_integer_size,i8) + int(mpi_double_precision_size,i8)
533 byte_offset = byte_offset + &
534 dof_offset * int(mpi_real_prec_size, i8)
535 call this%read_field(fh, byte_offset, u%x, nel)
536 mpi_offset = 4_i8 * int(mpi_integer_size,i8) + int(mpi_double_precision_size,i8)
537 mpi_offset = mpi_offset +&
538 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, v%x, nel)
543 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
545 byte_offset = mpi_offset + &
546 dof_offset * int(mpi_real_prec_size, i8)
547 call this%read_field(fh, byte_offset, w%x, nel)
548 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
550 byte_offset = mpi_offset + &
551 dof_offset * int(mpi_real_prec_size, i8)
552 call this%read_field(fh, byte_offset, p%x, nel)
553 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
560 do i = 1, ulag%size()
561 byte_offset = mpi_offset + &
562 dof_offset * int(mpi_real_prec_size, i8)
563 call this%read_field(fh, byte_offset, ulag%lf(i)%x, nel)
564 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
567 do i = 1, vlag%size()
568 byte_offset = mpi_offset + &
569 dof_offset * int(mpi_real_prec_size, i8)
570 call this%read_field(fh, byte_offset, vlag%lf(i)%x, nel)
571 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
574 do i = 1, wlag%size()
575 byte_offset = mpi_offset + &
576 dof_offset * int(mpi_real_prec_size, i8)
577 call this%read_field(fh, byte_offset, wlag%lf(i)%x, nel)
578 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
582 if (read_scalar)
then
583 byte_offset = mpi_offset + &
584 dof_offset * int(mpi_real_prec_size, i8)
585 call this%read_field(fh, byte_offset, s%x, nel)
586 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
589 if (read_dtlag .and. have_dtlag .eq. 1)
then
590 call mpi_file_read_at_all(fh, mpi_offset, tlag, 10, mpi_real_precision, status, ierr)
591 mpi_offset = mpi_offset + 10_i8 * int(mpi_real_prec_size, i8)
592 call mpi_file_read_at_all(fh, mpi_offset, dtlag, 10, mpi_real_precision, status, ierr)
593 mpi_offset = mpi_offset + 10_i8 * int(mpi_real_prec_size, i8)
596 if (read_abvel .and. have_abvel .eq. 1)
then
597 byte_offset = mpi_offset + &
598 dof_offset * int(mpi_real_prec_size, i8)
599 call this%read_field(fh, byte_offset, abx1%x, nel)
600 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
601 byte_offset = mpi_offset + &
602 dof_offset * int(mpi_real_prec_size, i8)
603 call this%read_field(fh, byte_offset, abx2%x, nel)
604 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
605 byte_offset = mpi_offset + &
606 dof_offset * int(mpi_real_prec_size, i8)
607 call this%read_field(fh, byte_offset, aby1%x, nel)
608 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
609 byte_offset = mpi_offset + &
610 dof_offset * int(mpi_real_prec_size, i8)
611 call this%read_field(fh, byte_offset, aby2%x, nel)
612 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
613 byte_offset = mpi_offset + &
614 dof_offset * int(mpi_real_prec_size, i8)
615 call this%read_field(fh, byte_offset, abz1%x, nel)
616 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
617 byte_offset = mpi_offset + &
618 dof_offset * int(mpi_real_prec_size, i8)
619 call this%read_field(fh, byte_offset, abz2%x, nel)
620 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
622 if (read_scalarlag .and. have_scalarlag .eq. 1)
then
623 do i = 1, slag%size()
624 byte_offset = mpi_offset + &
625 dof_offset * int(mpi_real_prec_size, i8)
626 call this%read_field(fh, byte_offset, slag%lf(i)%x, nel)
627 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
629 byte_offset = mpi_offset + &
630 dof_offset * int(mpi_real_prec_size, i8)
631 call this%read_field(fh, byte_offset, abs1%x, nel)
632 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
633 byte_offset = mpi_offset + &
634 dof_offset * int(mpi_real_prec_size, i8)
635 call this%read_field(fh, byte_offset, abs2%x, nel)
636 mpi_offset = mpi_offset + n_glb_dofs * int(mpi_real_prec_size, i8)
639 call mpi_file_close(fh, ierr)
641 if (ierr .ne. mpi_success)
then
642 call neko_error(
'Error reading checkpoint file ' // trim(this%fname))
645 call this%global_interp%free()
646 call this%space_interp%free()