56 use mpi_f08,
only : mpi_info_null, mpi_allreduce, mpi_allgather, &
57 mpi_in_place, mpi_integer, mpi_sum, mpi_max, mpi_comm_size, mpi_exscan, &
58 mpi_barrier, mpi_integer8, mpi_scan, mpi_bcast, &
72 integer(hid_t) :: file_id = -1_hid_t
73 integer(hid_t) :: active_group_id = -1_hid_t
74 integer(hid_t) :: plist_id = -1_hid_t
76 character(len=1) :: mode
77 integer :: precision = -1
97 procedure, pass(this) :: write_int_attribute => &
119 type(neko_space_t) :: xh
121 logical :: mesh2mesh = .false.
136 character(len=1024) :: fname
137 character(len=5) :: id_str
138 integer :: counter, suffix_pos
140 if (this%overwrite)
then
141 fname = this%get_fname()
143 counter = this%get_counter()
144 if (counter .eq. -1)
then
145 counter = this%get_start_counter()
147 counter = counter + 1
150 fname = this%get_base_fname()
152 write(id_str,
'(i5.5)') counter
153 fname = trim(fname(1:suffix_pos-1)) // id_str // fname(suffix_pos:)
161 logical,
intent(in) :: overwrite
162 this%overwrite = overwrite
168 character(len=1024) :: base_fname
169 character(len=1024) :: fname
170 character(len=1024) :: path, name, suffix
172 fname = trim(this%get_base_fname())
180 base_fname = trim(fname)
187 integer,
intent(in) :: precision
188 this%precision = precision
196 if (this%mesh2mesh)
then
197 call this%global_interp%free()
198 call this%src_dof%free()
202 this%mesh2mesh = .false.
218 class(*),
target,
intent(in) :: data
219 real(kind=
dp),
intent(in),
optional :: t
220 type(
mesh_t),
pointer :: msh
224 real(kind=
dp),
pointer :: dtlag(:)
225 real(kind=
dp),
pointer :: tlag(:)
226 integer :: ierr, info, drank, i, j
227 integer(hid_t) :: plist_id, fapl_id
228 integer(hid_t) :: file_id, dset_id, grp_id, attr_id
229 integer(hid_t) :: filespace, dspace_id, memspace
230 integer(hid_t) :: H5T_NEKO_REAL
231 integer(hsize_t),
dimension(1) :: ddim, dcount, doffset
232 integer :: suffix_pos
233 character(len=5) :: id_str
234 character(len=1024) :: fname
235 logical :: checkpoint_data
237 call hdf5_file_determine_data(
data, msh, dof, fp, fsp, dtlag, tlag)
238 checkpoint_data = .false.
241 checkpoint_data = .true.
244 if (.not. this%overwrite)
call this%increment_counter()
245 fname = trim(this%get_fname())
249 call hdf5_file_determine_real(h5t_neko_real)
254 call h5pcreate_f(h5p_file_access_f, fapl_id, ierr)
255 info = mpi_info_null%mpi_val
256 call h5pset_fapl_mpio_f(fapl_id,
neko_comm%mpi_val, info, ierr)
258 call h5fcreate_f(fname, h5f_acc_trunc_f, &
259 file_id, ierr, access_prp = fapl_id)
260 call h5pclose_f(fapl_id, ierr)
262 call h5pcreate_f(h5p_dataset_xfer_f, plist_id, ierr)
263 call h5pset_dxpl_mpio_f(plist_id, h5fd_mpio_collective_f, ierr)
265 call h5screate_f(h5s_scalar_f, filespace, ierr)
269 call h5acreate_f(file_id,
"Time", h5t_native_double, filespace, attr_id, &
270 ierr, h5p_default_f, h5p_default_f)
271 call h5awrite_f(attr_id, h5t_native_double, t, ddim, ierr)
272 call h5aclose_f(attr_id, ierr)
275 if (
associated(dof))
then
276 call h5acreate_f(file_id,
"Lx", h5t_native_integer, filespace, attr_id, &
277 ierr, h5p_default_f, h5p_default_f)
278 call h5awrite_f(attr_id, h5t_native_integer, dof%Xh%lx, ddim, ierr)
279 call h5aclose_f(attr_id, ierr)
282 if (
associated(msh))
then
283 call h5gcreate_f(file_id,
"Mesh", grp_id, ierr, &
284 lcpl_id = h5p_default_f, gcpl_id = h5p_default_f, &
285 gapl_id = h5p_default_f)
287 call h5acreate_f(grp_id,
"Elements", h5t_native_integer, filespace, &
288 attr_id, ierr, h5p_default_f, h5p_default_f)
289 call h5awrite_f(attr_id, h5t_native_integer, msh%glb_nelv, ddim, ierr)
290 call h5aclose_f(attr_id, ierr)
292 call h5acreate_f(grp_id,
"Dimension", h5t_native_integer, filespace, &
293 attr_id, ierr, h5p_default_f, h5p_default_f)
294 call h5awrite_f(attr_id, h5t_native_integer, msh%gdim, ddim, ierr)
295 call h5aclose_f(attr_id, ierr)
297 call h5gclose_f(grp_id, ierr)
301 call h5sclose_f(filespace, ierr)
306 if (
associated(tlag) .and.
associated(dtlag))
then
307 call h5gcreate_f(file_id,
"Restart", grp_id, ierr, &
308 lcpl_id = h5p_default_f, gcpl_id = h5p_default_f, &
309 gapl_id = h5p_default_f)
320 call h5screate_simple_f(drank, ddim, filespace, ierr)
322 call h5dcreate_f(grp_id,
'tlag', h5t_native_double, &
323 filespace, dset_id, ierr)
324 call h5dget_space_f(dset_id, dspace_id, ierr)
325 call h5sselect_hyperslab_f (dspace_id, h5s_select_set_f, &
326 doffset, dcount, ierr)
327 call h5dwrite_f(dset_id, h5t_native_double, tlag, &
328 ddim, ierr, xfer_prp = plist_id)
329 call h5sclose_f(dspace_id, ierr)
330 call h5dclose_f(dset_id, ierr)
332 call h5dcreate_f(grp_id,
'dtlag', h5t_native_double, &
333 filespace, dset_id, ierr)
334 call h5dget_space_f(dset_id, dspace_id, ierr)
335 call h5sselect_hyperslab_f (dspace_id, h5s_select_set_f, &
336 doffset, dcount, ierr)
337 call h5dwrite_f(dset_id, h5t_native_double, dtlag, &
338 ddim, ierr, xfer_prp = plist_id)
339 call h5sclose_f(dspace_id, ierr)
340 call h5dclose_f(dset_id, ierr)
342 call h5sclose_f(filespace, ierr)
343 call h5gclose_f(grp_id, ierr)
351 if (checkpoint_data)
then
354 call hdf5_checkpoint_write_payloads( &
355 file_id, plist_id, h5t_neko_real, data)
357 if (
allocated(fp))
deallocate(fp)
358 if (
allocated(fsp))
deallocate(fsp)
359 else if (
allocated(fp) .or.
allocated(fsp))
then
360 call h5gcreate_f(file_id,
"Fields", grp_id, ierr, &
361 lcpl_id = h5p_default_f, gcpl_id = h5p_default_f, &
362 gapl_id = h5p_default_f)
366 dcount(1) = int(dof%size(), 8)
367 doffset(1) = int(msh%offset_el, 8) * int(dof%Xh%lxyz, 8)
368 ddim = int(dof%size(), 8)
370 call mpi_allreduce(mpi_in_place, ddim(1), 1, &
373 call h5screate_simple_f(drank, ddim, filespace, ierr)
374 call h5screate_simple_f(drank, dcount, memspace, ierr)
377 if (
allocated(fp))
then
379 call h5dcreate_f(grp_id, fp(i)%ptr%name, h5t_neko_real, &
380 filespace, dset_id, ierr)
381 call h5dget_space_f(dset_id, dspace_id, ierr)
382 call h5sselect_hyperslab_f(dspace_id, h5s_select_set_f, &
383 doffset, dcount, ierr)
384 call h5dwrite_f(dset_id, h5t_neko_real, &
385 fp(i)%ptr%x(1,1,1,1), &
386 ddim, ierr, file_space_id = dspace_id, &
387 mem_space_id = memspace, xfer_prp = plist_id)
388 call h5sclose_f(dspace_id, ierr)
389 call h5dclose_f(dset_id, ierr)
394 if (
allocated(fsp))
then
396 do j = 1, fsp(i)%ptr%size()
397 call h5dcreate_f(grp_id, fsp(i)%ptr%lf(j)%name, &
398 h5t_neko_real, filespace, dset_id, ierr)
399 call h5dget_space_f(dset_id, dspace_id, ierr)
400 call h5sselect_hyperslab_f(dspace_id, h5s_select_set_f, &
401 doffset, dcount, ierr)
402 call h5dwrite_f(dset_id, h5t_neko_real, &
403 fsp(i)%ptr%lf(j)%x(1,1,1,1), &
404 ddim, ierr, file_space_id = dspace_id, &
405 mem_space_id = memspace, xfer_prp = plist_id)
406 call h5sclose_f(dspace_id, ierr)
407 call h5dclose_f(dset_id, ierr)
413 call h5gclose_f(grp_id, ierr)
414 call h5sclose_f(filespace, ierr)
415 call h5sclose_f(memspace, ierr)
418 call h5pclose_f(plist_id, ierr)
419 call h5fclose_f(file_id, ierr)
428 class(*),
target,
intent(inout) :: data
429 integer(hid_t) :: plist_id, fapl_id
430 integer(hid_t) :: file_id, dset_id, grp_id, attr_id
431 integer(hid_t) :: filespace, memspace
432 integer(hid_t) :: H5T_NEKO_REAL
433 integer(hsize_t),
dimension(1) :: ddim, dcount, doffset
434 integer :: i,j, ierr, info, glb_nelv, gdim, lx, drank
435 type(
mesh_t),
pointer :: msh
440 real(kind=
dp),
pointer :: dtlag(:)
441 real(kind=
dp),
pointer :: tlag(:)
443 character(len=1024) :: fname
446 character(len=256) :: err_msg
447 logical :: payloads_exist
449 fname = trim(this%get_fname())
453 call hdf5_file_determine_data(
data, msh, dof, fp, fsp, dtlag, tlag)
454 call hdf5_file_determine_real(h5t_neko_real)
458 call h5pcreate_f(h5p_file_access_f, fapl_id, ierr)
459 info = mpi_info_null%mpi_val
460 call h5pset_fapl_mpio_f(fapl_id,
neko_comm%mpi_val, info, ierr)
462 call h5fopen_f(fname, h5f_acc_rdonly_f, &
463 file_id, ierr, access_prp = fapl_id)
464 call h5pclose_f(fapl_id, ierr)
466 call h5lexists_f(file_id,
'Payloads', payloads_exist, ierr)
468 call h5pcreate_f(h5p_dataset_xfer_f, plist_id, ierr)
469 call h5pset_dxpl_mpio_f(plist_id, h5fd_mpio_collective_f, ierr)
472 call h5aopen_name_f(file_id,
'Time', attr_id, ierr)
473 call h5aread_f(attr_id, h5t_native_double, t, ddim, ierr)
474 call h5aclose_f(attr_id, ierr)
481 call h5aopen_name_f(file_id,
'Lx', attr_id, ierr)
482 call h5aread_f(attr_id, h5t_native_integer, lx, ddim, ierr)
483 call h5aclose_f(attr_id, ierr)
485 call h5gopen_f(file_id,
'Mesh', grp_id, ierr, gapl_id = h5p_default_f)
487 call h5aopen_name_f(grp_id,
'Elements', attr_id, ierr)
488 call h5aread_f(attr_id, h5t_native_integer, glb_nelv, ddim, ierr)
489 call h5aclose_f(attr_id, ierr)
491 call h5aopen_name_f(grp_id,
'Dimension', attr_id, ierr)
492 call h5aread_f(attr_id, h5t_native_integer, gdim, ddim, ierr)
493 call h5aclose_f(attr_id, ierr)
494 call h5gclose_f(grp_id, ierr)
499 layout%mesh2mesh = .false.
502 if (
allocated(data%previous_mesh%elements))
then
503 layout%msh => data%previous_mesh
504 layout%mesh2mesh = .true.
508 if (gdim .ne. layout%msh%gdim)
then
509 write(err_msg,
'(A,I0,A,I0,A)')
'HDF5 checkpoint is for a ', gdim, &
510 'D mesh but this case is ', layout%msh%gdim,
'D'
514 if (glb_nelv .ne. layout%msh%glb_nelv)
then
515 write(err_msg,
'(A,I0,A,I0,A)')
'HDF5 checkpoint has ', glb_nelv, &
516 ' elements but the mesh it is read on has ', &
517 layout%msh%glb_nelv,
'; set case.restart_mesh_file to the ' // &
518 'mesh the checkpoint was written on'
522 if (gdim .eq. 3)
then
523 call layout%Xh%init(
gll, lx, lx, lx)
525 call layout%Xh%init(
gll, lx, lx)
530 if (gdim .eq. 3)
then
531 call data%previous_Xh%init(
gll, lx, lx, lx)
533 call data%previous_Xh%init(
gll, lx, lx)
536 if (layout%mesh2mesh)
then
537 call layout%src_dof%init(layout%msh, layout%Xh)
538 call layout%global_interp%init(layout%src_dof,
neko_comm, &
539 tol = data%mesh2mesh_tol)
540 call layout%global_interp%find_points(dof%x%x, dof%y%x, dof%z%x, &
545 if (
associated(tlag) .and.
associated(dtlag))
then
555 call h5gopen_f(file_id,
'Restart', grp_id, ierr, &
556 gapl_id = h5p_default_f)
557 call h5dopen_f(grp_id,
'tlag', dset_id, ierr)
558 call h5dget_space_f(dset_id, filespace, ierr)
559 call h5sselect_hyperslab_f (filespace, h5s_select_set_f, &
560 doffset, dcount, ierr)
561 call h5dread_f(dset_id, h5t_native_double, tlag, ddim, ierr, &
563 call h5dclose_f(dset_id, ierr)
564 call h5sclose_f(filespace, ierr)
566 call h5dopen_f(grp_id,
'dtlag', dset_id, ierr)
567 call h5dget_space_f(dset_id, filespace, ierr)
568 call h5sselect_hyperslab_f (filespace, h5s_select_set_f, &
569 doffset, dcount, ierr)
570 call h5dread_f(dset_id, h5t_native_double, dtlag, ddim, ierr, &
572 call h5dclose_f(dset_id, ierr)
573 call h5sclose_f(filespace, ierr)
575 call h5gclose_f(grp_id, ierr)
578 if (payloads_exist)
then
581 call hdf5_checkpoint_read_payloads( &
582 file_id, plist_id, h5t_neko_real,
data, layout)
585 "HDF5 payload checkpoints require a checkpoint object")
587 if (
allocated(fp))
deallocate(fp)
588 if (
allocated(fsp))
deallocate(fsp)
589 else if (
allocated(fp) .or.
allocated(fsp))
then
590 call h5gopen_f(file_id,
'Fields', grp_id, ierr, gapl_id = h5p_default_f)
592 if (
allocated(fp))
then
594 call hdf5_checkpoint_read_field(grp_id, plist_id, &
595 h5t_neko_real, fp(i)%ptr, layout)
599 if (
allocated(fsp))
then
601 do j = 1, fsp(i)%ptr%size()
602 call hdf5_checkpoint_read_field(grp_id, plist_id, &
603 h5t_neko_real, fsp(i)%ptr%lf(j), layout)
607 call h5gclose_f(grp_id, ierr)
610 call h5pclose_f(plist_id, ierr)
611 call h5fclose_f(file_id, ierr)
624 subroutine hdf5_checkpoint_write_payloads(file_id, plist_id, &
626 integer(hid_t),
intent(in) :: file_id, plist_id, h5_neko_real
627 type(
chkp_t),
intent(in) :: chkp
628 integer(hid_t) :: payloads_id, payload_id
629 integer :: i, j, k, ierr
631 call h5gcreate_f(file_id,
"Payloads", payloads_id, ierr)
633 do i = 1, chkp%payload_count()
634 call hdf5_checkpoint_open_group(payloads_id, &
635 chkp%payloads(i)%ptr%name, .true., payload_id)
637 do j = 1, chkp%payloads(i)%ptr%field_count()
638 call hdf5_checkpoint_write_field(payload_id, plist_id, &
639 h5_neko_real, chkp%payloads(i)%ptr%fields(j)%ptr)
642 do j = 1, chkp%payloads(i)%ptr%series_count()
643 do k = 1, chkp%payloads(i)%ptr%series(j)%ptr%size()
644 call hdf5_checkpoint_write_field(payload_id, plist_id, &
646 chkp%payloads(i)%ptr%series(j)%ptr%lf(k))
650 do j = 1, chkp%payloads(i)%ptr%mesh_array_count()
651 call hdf5_checkpoint_write_mesh_array(payload_id, plist_id, &
652 h5_neko_real, chkp%payloads(i)%ptr%mesh_arrays(j)%ptr)
655 do j = 1, chkp%payloads(i)%ptr%array_count()
656 call hdf5_checkpoint_write_array(payload_id, plist_id, &
657 h5_neko_real, chkp%payloads(i)%ptr%arrays(j)%ptr)
660 call h5gclose_f(payload_id, ierr)
663 call h5gclose_f(payloads_id, ierr)
665 end subroutine hdf5_checkpoint_write_payloads
673 subroutine hdf5_checkpoint_read_payloads(file_id, plist_id, &
674 h5_neko_real, chkp, layout)
675 integer(hid_t),
intent(in) :: file_id, plist_id, h5_neko_real
676 type(
chkp_t),
intent(inout) :: chkp
678 integer(hid_t) :: payloads_id, payload_id
679 integer :: i, j, k, ierr
681 call h5gopen_f(file_id,
"Payloads", payloads_id, ierr)
683 do i = 1, chkp%payload_count()
684 call hdf5_checkpoint_open_group(payloads_id, &
685 chkp%payloads(i)%ptr%name, .false., payload_id)
687 do j = 1, chkp%payloads(i)%ptr%field_count()
688 call hdf5_checkpoint_read_field(payload_id, plist_id, &
689 h5_neko_real, chkp%payloads(i)%ptr%fields(j)%ptr, &
693 do j = 1, chkp%payloads(i)%ptr%series_count()
694 do k = 1, chkp%payloads(i)%ptr%series(j)%ptr%size()
695 call hdf5_checkpoint_read_field(payload_id, plist_id, &
697 chkp%payloads(i)%ptr%series(j)%ptr%lf(k), layout)
701 do j = 1, chkp%payloads(i)%ptr%mesh_array_count()
702 call hdf5_checkpoint_read_mesh_array(payload_id, plist_id, &
703 h5_neko_real, chkp%payloads(i)%ptr%mesh_arrays(j)%ptr, &
707 do j = 1, chkp%payloads(i)%ptr%array_count()
708 call hdf5_checkpoint_read_array(payload_id, plist_id, &
709 h5_neko_real, chkp%payloads(i)%ptr%arrays(j)%ptr)
712 call h5gclose_f(payload_id, ierr)
715 call h5gclose_f(payloads_id, ierr)
717 end subroutine hdf5_checkpoint_read_payloads
724 subroutine hdf5_checkpoint_open_group(root_id, path, create, group_id)
725 integer(hid_t),
intent(in) :: root_id
726 character(len=*),
intent(in) :: path
727 logical,
intent(in) :: create
728 integer(hid_t),
intent(out) :: group_id
729 integer(hid_t) :: current_id, next_id
730 integer :: first, last, slash, path_len, ierr
731 logical :: group_exists
732 character(len=:),
allocatable :: group_name
736 path_len = len_trim(path)
739 slash = index(path(first:path_len),
"/")
740 if (slash .eq. 0)
then
743 last = first + slash - 2
746 group_name = path(first:last)
747 call h5lexists_f(current_id, group_name, group_exists, ierr)
748 if (group_exists)
then
749 call h5gopen_f(current_id, group_name, next_id, ierr)
750 else if (create)
then
751 call h5gcreate_f(current_id, group_name, next_id, ierr)
753 call neko_error(
"Checkpoint payload group '" // trim(path) // &
757 if (current_id .ne. root_id)
call h5gclose_f(current_id, ierr)
760 if (slash .eq. 0)
exit
764 group_id = current_id
766 end subroutine hdf5_checkpoint_open_group
773 subroutine hdf5_checkpoint_write_field(group_id, plist_id, &
775 integer(hid_t),
intent(in) :: group_id, plist_id, h5_neko_real
776 type(
field_t),
intent(in) :: fld
777 integer(hid_t) :: dset_id, filespace, memspace
778 integer(hsize_t),
dimension(1) :: ddim, dcount, doffset
781 dcount(1) = int(fld%dof%size(), 8)
782 doffset(1) = int(fld%msh%offset_el, 8) * int(fld%Xh%lxyz, 8)
784 call mpi_allreduce(mpi_in_place, ddim(1), 1, &
787 call h5screate_simple_f(1, ddim, filespace, ierr)
788 call h5screate_simple_f(1, dcount, memspace, ierr)
789 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
790 doffset, dcount, ierr)
791 call h5dcreate_f(group_id, trim(fld%name), h5_neko_real, &
792 filespace, dset_id, ierr)
793 call h5dwrite_f(dset_id, h5_neko_real, fld%x(1,1,1,1), &
794 dcount, ierr, file_space_id = filespace, mem_space_id = memspace, &
797 call h5dclose_f(dset_id, ierr)
798 call h5sclose_f(filespace, ierr)
799 call h5sclose_f(memspace, ierr)
801 end subroutine hdf5_checkpoint_write_field
809 subroutine hdf5_checkpoint_read_field(group_id, plist_id, &
810 h5_neko_real, fld, layout)
811 integer(hid_t),
intent(in) :: group_id, plist_id, h5_neko_real
812 type(
field_t),
intent(inout) :: fld
814 integer(hid_t) :: dset_id, filespace, memspace
815 integer(hsize_t),
dimension(1) :: dcount, doffset
816 real(kind=
rp),
allocatable :: checkpoint_data(:)
819 logical :: dataset_exists
821 call h5lexists_f(group_id, trim(fld%name), dataset_exists, ierr)
822 if (.not. dataset_exists)
then
823 call neko_error(
"Checkpoint field '" // trim(fld%name) // &
827 call h5dopen_f(group_id, trim(fld%name), dset_id, ierr)
828 call h5dget_space_f(dset_id, filespace, ierr)
832 dcount(1) = int(layout%msh%nelv, hsize_t) * int(layout%Xh%lxyz, hsize_t)
833 doffset(1) = int(layout%msh%offset_el, hsize_t) * &
834 int(layout%Xh%lxyz, hsize_t)
835 call h5screate_simple_f(1, dcount, memspace, ierr)
836 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
837 doffset, dcount, ierr)
839 if (layout%mesh2mesh)
then
840 allocate(checkpoint_data(int(dcount(1))))
841 call h5dread_f(dset_id, h5_neko_real, checkpoint_data, dcount, ierr, &
842 file_space_id = filespace, mem_space_id = memspace, &
844 call rzero(fld%x, fld%dof%size())
845 call layout%global_interp%evaluate(fld%x, checkpoint_data, .true.)
846 deallocate(checkpoint_data)
847 else if (layout%Xh%lxyz .ne. fld%Xh%lxyz)
then
848 allocate(checkpoint_data(int(dcount(1))))
849 call h5dread_f(dset_id, h5_neko_real, checkpoint_data, dcount, ierr, &
850 file_space_id = filespace, mem_space_id = memspace, &
852 call space_interp%init(fld%Xh, layout%Xh)
853 call space_interp%map_host(fld%x, checkpoint_data, fld%msh%nelv, &
855 call space_interp%free()
856 deallocate(checkpoint_data)
858 call h5dread_f(dset_id, h5_neko_real, fld%x(1,1,1,1), &
859 dcount, ierr, file_space_id = filespace, &
860 mem_space_id = memspace, xfer_prp = plist_id)
863 call h5dclose_f(dset_id, ierr)
864 call h5sclose_f(filespace, ierr)
865 call h5sclose_f(memspace, ierr)
867 end subroutine hdf5_checkpoint_read_field
874 subroutine hdf5_checkpoint_write_mesh_array(group_id, plist_id, &
876 integer(hid_t),
intent(in) :: group_id, plist_id, h5_neko_real
878 integer(hid_t) :: dset_id, filespace, memspace, attr_id, attr_space
879 integer(hsize_t),
dimension(1) :: ddim, dcount, doffset, attr_dims
880 integer :: nodal_shape(3)
883 dcount(1) = int(
size(array%x), hsize_t)
884 doffset(1) = int(array%msh%offset_el, hsize_t) * &
885 int(array%Xh%lxyz, hsize_t)
886 ddim(1) = int(array%msh%glb_nelv, hsize_t) * &
887 int(array%Xh%lxyz, hsize_t)
889 call h5screate_simple_f(1, ddim, filespace, ierr)
890 call h5screate_simple_f(1, dcount, memspace, ierr)
891 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
892 doffset, dcount, ierr)
893 call h5dcreate_f(group_id, trim(array%name), h5_neko_real, &
894 filespace, dset_id, ierr)
896 nodal_shape = [array%Xh%lx, array%Xh%ly, array%Xh%lz]
897 attr_dims(1) =
size(nodal_shape)
898 call h5screate_simple_f(1, attr_dims, attr_space, ierr)
899 call h5acreate_f(dset_id,
"NodalShape", h5t_native_integer, &
900 attr_space, attr_id, ierr)
901 call h5awrite_f(attr_id, h5t_native_integer, nodal_shape, &
903 call h5aclose_f(attr_id, ierr)
904 call h5sclose_f(attr_space, ierr)
906 call h5dwrite_f(dset_id, h5_neko_real, array%x, dcount, ierr, &
907 file_space_id = filespace, mem_space_id = memspace, &
910 call h5dclose_f(dset_id, ierr)
911 call h5sclose_f(filespace, ierr)
912 call h5sclose_f(memspace, ierr)
914 end subroutine hdf5_checkpoint_write_mesh_array
922 subroutine hdf5_checkpoint_read_mesh_array(group_id, plist_id, &
923 h5_neko_real, array, layout)
924 integer(hid_t),
intent(in) :: group_id, plist_id, h5_neko_real
927 integer(hid_t) :: dset_id, filespace, memspace, attr_id, attr_space
928 integer(hsize_t),
dimension(1) :: dcount, doffset
929 integer(hsize_t),
dimension(1) :: dataset_dims, dataset_maxdims
930 integer(hsize_t),
dimension(1) :: attr_dims, attr_maxdims
931 integer :: stored_shape(3)
932 real(kind=
rp),
allocatable :: stored_data(:)
933 type(neko_space_t),
target :: stored_xh
936 logical :: dataset_exists, shape_exists
941 if (layout%mesh2mesh)
then
942 call neko_error(
'ALE does not yet support mesh2mesh ' // &
943 'interpolation for restart!')
946 call h5lexists_f(group_id, trim(array%name), dataset_exists, ierr)
947 if (.not. dataset_exists)
then
948 call neko_error(
"Checkpoint mesh array '" // trim(array%name) // &
952 call h5dopen_f(group_id, trim(array%name), dset_id, ierr)
953 call h5dget_space_f(dset_id, filespace, ierr)
954 call h5sget_simple_extent_dims_f(filespace, dataset_dims, &
955 dataset_maxdims, ierr)
957 stored_shape = [layout%Xh%lx, layout%Xh%ly, layout%Xh%lz]
958 call h5aexists_f(dset_id,
"NodalShape", shape_exists, ierr)
959 if (shape_exists)
then
960 call h5aopen_f(dset_id,
"NodalShape", attr_id, ierr)
963 call h5aexists_f(dset_id,
"BlockShape", shape_exists, ierr)
964 if (shape_exists)
then
965 call h5aopen_f(dset_id,
"BlockShape", attr_id, ierr)
968 if (shape_exists)
then
969 call h5aget_space_f(attr_id, attr_space, ierr)
970 call h5sget_simple_extent_dims_f(attr_space, attr_dims, &
972 if (attr_dims(1) .ne. 3)
then
973 call neko_error(
"Checkpoint mesh-array nodal shape must have " // &
976 call h5aread_f(attr_id, h5t_native_integer, stored_shape, &
978 call h5sclose_f(attr_space, ierr)
979 call h5aclose_f(attr_id, ierr)
982 if (any(stored_shape .le. 0))
then
983 call neko_error(
"Checkpoint mesh-array nodal shape must be positive")
985 if (array%msh%gdim .eq. 3)
then
986 call stored_xh%init(
gll, stored_shape(1), stored_shape(2), &
989 if (stored_shape(3) .ne. 1)
then
990 call neko_error(
"Two-dimensional checkpoint mesh arrays must " // &
991 "have one nodal plane")
993 call stored_xh%init(
gll, stored_shape(1), stored_shape(2))
996 if (int(dataset_dims(1),
i8) .ne. &
997 int(layout%msh%glb_nelv,
i8) * int(stored_xh%lxyz,
i8))
then
998 call neko_error(
"Checkpoint mesh array '" // trim(array%name) // &
999 "' does not match the current mesh")
1002 dcount(1) = int(layout%msh%nelv, hsize_t) * &
1003 int(stored_xh%lxyz, hsize_t)
1004 doffset(1) = int(layout%msh%offset_el, hsize_t) * &
1005 int(stored_xh%lxyz, hsize_t)
1006 call h5screate_simple_f(1, dcount, memspace, ierr)
1007 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1008 doffset, dcount, ierr)
1010 if (stored_xh%lxyz .eq. array%Xh%lxyz)
then
1011 call h5dread_f(dset_id, h5_neko_real, array%x, dcount, ierr, &
1012 file_space_id = filespace, mem_space_id = memspace, &
1013 xfer_prp = plist_id)
1015 allocate(stored_data(int(dcount(1))))
1016 call h5dread_f(dset_id, h5_neko_real, stored_data, dcount, ierr, &
1017 file_space_id = filespace, mem_space_id = memspace, &
1018 xfer_prp = plist_id)
1019 call space_interp%init(array%Xh, stored_xh)
1020 call space_interp%map_host(array%x, stored_data, array%msh%nelv, &
1022 call space_interp%free()
1023 deallocate(stored_data)
1026 call stored_xh%free()
1027 call h5dclose_f(dset_id, ierr)
1028 call h5sclose_f(filespace, ierr)
1029 call h5sclose_f(memspace, ierr)
1031 end subroutine hdf5_checkpoint_read_mesh_array
1038 subroutine hdf5_checkpoint_write_array(group_id, plist_id, &
1039 h5_neko_real, array)
1040 integer(hid_t),
intent(in) :: group_id, plist_id, h5_neko_real
1042 integer(hid_t) :: dset_id, filespace, memspace, h5_type
1043 integer(hsize_t),
dimension(1) :: ddim, dcount, doffset
1045 logical :: stored_dp
1050 stored_dp =
associated(array%x_dp)
1052 h5_type = h5t_native_double
1053 dcount(1) = int(
size(array%x_dp), hsize_t)
1055 h5_type = h5_neko_real
1056 dcount(1) = int(
size(array%x), hsize_t)
1058 ddim(1) = int(array%global_count, hsize_t)
1059 doffset(1) = int(array%offset, hsize_t)
1061 call h5screate_simple_f(1, ddim, filespace, ierr)
1062 call h5screate_simple_f(1, dcount, memspace, ierr)
1063 call h5dcreate_f(group_id, trim(array%name), h5_type, &
1064 filespace, dset_id, ierr)
1066 if (array%replicated .and.
pe_rank .ne. 0)
then
1067 call h5sselect_none_f(filespace, ierr)
1068 call h5sselect_none_f(memspace, ierr)
1070 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1071 doffset, dcount, ierr)
1075 call h5dwrite_f(dset_id, h5_type, array%x_dp, dcount, ierr, &
1076 file_space_id = filespace, mem_space_id = memspace, &
1077 xfer_prp = plist_id)
1079 call h5dwrite_f(dset_id, h5_type, array%x, dcount, ierr, &
1080 file_space_id = filespace, mem_space_id = memspace, &
1081 xfer_prp = plist_id)
1084 call h5dclose_f(dset_id, ierr)
1085 call h5sclose_f(filespace, ierr)
1086 call h5sclose_f(memspace, ierr)
1088 end subroutine hdf5_checkpoint_write_array
1095 subroutine hdf5_checkpoint_read_array(group_id, plist_id, &
1096 h5_neko_real, array)
1097 integer(hid_t),
intent(in) :: group_id, plist_id, h5_neko_real
1099 integer(hid_t) :: dset_id, filespace, memspace, h5_type
1100 integer(hsize_t),
dimension(1) :: dcount, doffset
1101 integer(hsize_t),
dimension(1) :: dataset_dims, dataset_maxdims
1103 logical :: dataset_exists, stored_dp
1105 call h5lexists_f(group_id, trim(array%name), dataset_exists, ierr)
1106 if (.not. dataset_exists)
then
1107 call neko_error(
"Checkpoint array '" // trim(array%name) // &
1111 call h5dopen_f(group_id, trim(array%name), dset_id, ierr)
1112 call h5dget_space_f(dset_id, filespace, ierr)
1113 call h5sget_simple_extent_dims_f(filespace, dataset_dims, &
1114 dataset_maxdims, ierr)
1116 if (int(dataset_dims(1),
i8) .ne. array%global_count)
then
1117 call neko_error(
"Checkpoint array '" // trim(array%name) // &
1118 "' has an incompatible global extent")
1121 stored_dp =
associated(array%x_dp)
1123 h5_type = h5t_native_double
1124 dcount(1) = int(
size(array%x_dp), hsize_t)
1126 h5_type = h5_neko_real
1127 dcount(1) = int(
size(array%x), hsize_t)
1129 doffset(1) = int(array%offset, hsize_t)
1130 call h5screate_simple_f(1, dcount, memspace, ierr)
1132 if (array%replicated .and.
pe_rank .ne. 0)
then
1133 call h5sselect_none_f(filespace, ierr)
1134 call h5sselect_none_f(memspace, ierr)
1136 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1137 doffset, dcount, ierr)
1140 call h5dread_f(dset_id, h5_type, array%x_dp, dcount, ierr, &
1141 file_space_id = filespace, mem_space_id = memspace, &
1142 xfer_prp = plist_id)
1144 call h5dread_f(dset_id, h5_type, array%x, dcount, ierr, &
1145 file_space_id = filespace, mem_space_id = memspace, &
1146 xfer_prp = plist_id)
1149 call h5dclose_f(dset_id, ierr)
1150 call h5sclose_f(filespace, ierr)
1151 call h5sclose_f(memspace, ierr)
1155 if (array%replicated)
then
1157 call mpi_bcast(array%x_dp,
size(array%x_dp), &
1158 mpi_double_precision, 0,
neko_comm, ierr)
1165 end subroutine hdf5_checkpoint_read_array
1175 subroutine hdf5_file_determine_data(data, msh, dof, fp, fsp, dtlag, tlag)
1176 class(*),
target,
intent(in) :: data
1177 type(
mesh_t),
pointer,
intent(inout) :: msh
1178 type(
dofmap_t),
pointer,
intent(inout) :: dof
1179 type(
field_ptr_t),
allocatable,
intent(inout) :: fp(:)
1181 real(kind=
dp),
pointer,
intent(inout) :: dtlag(:)
1182 real(kind=
dp),
pointer,
intent(inout) :: tlag(:)
1183 integer :: i, j, fp_size, fp_cur, fsp_size, fsp_cur
1190 allocate(fp(fp_size))
1198 if (data%size() .gt. 0)
then
1199 allocate(fp(data%size()))
1204 do i = 1, data%size()
1205 fp(i)%ptr => data%items(i)%ptr
1219 fluid => data%get_payload(
"fluid")
1220 u => fluid%find_field(
"u")
1221 if (.not.
associated(u) .or. &
1222 .not.
associated(fluid%find_field(
"v")) .or. &
1223 .not.
associated(fluid%find_field(
"w")) .or. &
1224 .not.
associated(fluid%find_field(
"p")))
then
1225 call neko_error(
"Checkpoint not initialized")
1232 do i = 1, data%payload_count()
1233 fp_size = fp_size + data%payloads(i)%ptr%field_count()
1234 fsp_size = fsp_size + data%payloads(i)%ptr%series_count()
1237 if (fp_size .gt. 0)
allocate(fp(fp_size))
1238 if (fsp_size .gt. 0)
allocate(fsp(fsp_size))
1242 do i = 1, data%payload_count()
1243 do j = 1, data%payloads(i)%ptr%field_count()
1244 fp(fp_cur)%ptr => data%payloads(i)%ptr%fields(j)%ptr
1247 do j = 1, data%payloads(i)%ptr%series_count()
1248 fsp(fsp_cur)%ptr => data%payloads(i)%ptr%series(j)%ptr
1249 fsp_cur = fsp_cur + 1
1253 call data%get_time_history(tlag, dtlag)
1257 call neko_log%error(
'Invalid data')
1260 end subroutine hdf5_file_determine_data
1265 subroutine hdf5_file_determine_real(H5T_NEKO_REAL)
1266 integer(hid_t),
intent(inout) :: H5T_NEKO_REAL
1269 h5t_neko_real = h5t_native_double
1271 h5t_neko_real = h5t_native_real
1273 call neko_error(
"Unsupported real type")
1275 end subroutine hdf5_file_determine_real
1284 character(len=1),
intent(in) :: mode
1285 integer :: ierr, mpi_info, mpi_comm, i, n_fields, counter
1286 logical :: file_exists
1287 character(len=1024) :: fname
1288 character(len=LOG_SIZE) :: log_buf
1294 if (this%precision .gt. rp)
then
1296 call neko_warning(
'Requested precision is higher than working precision')
1297 else if (this%precision .eq. -1)
then
1302 counter = this%get_counter() - this%get_start_counter()
1305 call hdf5_session_init()
1307 mpi_info = mpi_info_null%mpi_val
1308 mpi_comm = neko_comm%mpi_val
1309 call h5pcreate_f(h5p_file_access_f, this%plist_id, ierr)
1310 call h5pset_fapl_mpio_f(this%plist_id, mpi_comm, mpi_info, ierr)
1313 inquire(
file = fname, exist = file_exists)
1314 if (file_exists)
then
1315 call h5fopen_f(fname, h5f_acc_rdwr_f, this%file_id, ierr, &
1316 access_prp = this%plist_id)
1318 call h5fcreate_f(fname, h5f_acc_trunc_f, &
1319 this%file_id, ierr, access_prp = this%plist_id)
1323 call this%set_active_group()
1325 write (log_buf, *)
"Opened HDF5 file: ", trim(fname),
" with counter: ", &
1327 call neko_log%message(log_buf, lvl = neko_log_debug)
1336 if (this%active_group_id .ne. -1_hid_t .and. &
1337 this%active_group_id .ne. this%file_id)
then
1338 call h5gclose_f(this%active_group_id, ierr)
1340 this%active_group_id = -1_hid_t
1342 call h5pclose_f(this%plist_id, ierr)
1343 this%plist_id = -1_hid_t
1344 call h5fclose_f(this%file_id, ierr)
1345 this%file_id = -1_hid_t
1346 call hdf5_session_finalize()
1348 call neko_log%message(
"Closed HDF5 file: " // trim(this%get_fname()), &
1349 lvl = neko_log_debug)
1359 character(len=*),
intent(in),
optional :: group_name_path
1360 character(len=1000),
allocatable :: group_name(:)
1362 integer(hid_t) :: current_id, group_id
1363 integer :: ierr, i, j, num_groups, name_len, group_loc
1364 logical :: group_exists
1368 if (this%active_group_id .ne. -1_hid_t .and. this%active_group_id .ne. &
1370 call h5gclose_f(this%active_group_id, ierr)
1372 this%active_group_id = -1_hid_t
1375 current_id = this%file_id
1377 if (.not.
present(group_name_path))
then
1378 this%active_group_id = current_id
1383 name_len = len(trim(group_name_path))
1387 if (group_name_path .eq.
"/")
then
1388 num_groups = num_groups + 1
1393 allocate(group_name(num_groups))
1397 if (group_name_path .eq.
"/")
then
1398 group_name(group_loc) = group_name_path(j:i-1)
1399 group_loc = group_loc + 1
1403 if (j .ne. name_len)
then
1404 group_name(group_loc) = group_name_path(j:name_len)
1408 do i = 1, num_groups
1409 call h5lexists_f(current_id, trim(group_name(i)), group_exists, ierr)
1412 if (group_exists)
then
1413 call h5gopen_f(current_id, trim(group_name(i)), group_id, ierr)
1415 if (this%mode ==
"r")
then
1416 call neko_error(
"Group " // trim(group_name(i)) // &
1419 call h5gcreate_f(current_id, trim(group_name(i)), group_id, ierr)
1424 call h5gclose_f(current_id, ierr)
1427 current_id = group_id
1430 this%active_group_id = current_id
1436 class(*),
intent(inout) :: data
1438 select type (d => data)
1440 call this%write_vector(d)
1442 call this%write_matrix(d)
1444 call this%write_field(d)
1446 call neko_error(
"write_dataset not implemented for this data type")
1452 character(len=*),
intent(in) :: data_name
1453 class(*),
intent(inout) :: data
1454 character(len=*),
intent(in),
optional :: strategy
1456 select type (d => data)
1458 call this%read_vector(data_name, d, strategy)
1460 call this%read_matrix(data_name, d, strategy)
1462 call neko_error(
"Reading a field_t is not supported yet")
1464 call neko_error(
"read_dataset not implemented for this data type")
1470 character(len=*),
intent(in) :: data_name
1471 class(*),
intent(inout) :: data
1473 select type (d => data)
1475 call this%write_int_attribute(data_name, d)
1476 type is (
real(kind=rp))
1477 call this%write_rp_attribute(data_name, d)
1479 call neko_error(
"write_attribute not implemented for this data type")
1485 character(len=*),
intent(in) :: data_name
1486 class(*),
intent(inout) :: data
1487 logical,
intent(inout) :: exist
1489 select type (d => data)
1491 call this%read_int_attribute(data_name, d, exist)
1492 type is (
real(kind=rp))
1493 call this%read_rp_attribute(data_name, d, exist)
1495 call neko_error(
"read_attribute not implemented for this data type")
1502 type(vector_t),
intent(inout) :: vec
1503 integer :: ierr, counts, offset, total_count, dset_rank, max_count
1504 integer(hsize_t) :: append_offset
1505 integer(hid_t) :: precision_hdf
1506 integer(hid_t) :: xf_id, filespace, dset_id, memspace, dcpl_id
1507 integer(hsize_t),
dimension(1) :: dcount, doffset
1508 integer(hsize_t),
dimension(1) :: ddims, ddims_max, chunkdims
1509 integer(hsize_t),
dimension(1) :: tempddims, tempmaxddims
1510 logical :: dset_exists
1511 real(kind=sp),
allocatable :: write_buffer_sp(:)
1512 real(kind=dp),
allocatable :: write_buffer_dp(:)
1518 append_offset = 0_hsize_t
1522 call mpi_scan(counts, offset, 1, mpi_integer, &
1523 mpi_sum, neko_comm, ierr)
1524 offset = offset - counts
1525 call mpi_allreduce(counts, total_count, 1, mpi_integer, &
1526 mpi_sum, neko_comm, ierr)
1527 call mpi_allreduce(counts, max_count, 1, mpi_integer, &
1528 mpi_max, neko_comm, ierr)
1533 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1534 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1535 precision_hdf = h5kind_to_type(this%precision, h5_real_kind)
1541 ddims = [int(total_count, hsize_t)]
1544 chunkdims = [
max(int(max_count, hsize_t), 1_hsize_t)]
1545 ddims_max = [h5s_unlimited_f]
1546 call h5lexists_f(this%active_group_id, trim(vec%name), dset_exists, ierr)
1547 if (dset_exists)
then
1548 if (this%overwrite)
then
1550 call h5dopen_f(this%active_group_id, trim(vec%name), dset_id, ierr)
1553 call h5dopen_f(this%active_group_id, trim(vec%name), dset_id, ierr)
1555 call h5dget_space_f(dset_id, filespace, ierr)
1557 call h5sget_simple_extent_dims_f(filespace, tempddims, tempmaxddims, &
1560 call h5sclose_f(filespace, ierr)
1562 ddims(1) = ddims(1) + tempddims(1)
1563 append_offset = tempddims(1)
1565 call h5dset_extent_f(dset_id, ddims, ierr)
1569 call h5screate_simple_f(dset_rank, ddims, filespace, ierr, ddims_max)
1571 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
1572 call h5pset_chunk_f(dcpl_id, dset_rank, chunkdims, ierr)
1574 call h5dcreate_f(this%active_group_id, trim(vec%name), precision_hdf, &
1575 filespace, dset_id, ierr, dcpl_id = dcpl_id)
1577 call h5sclose_f(filespace, ierr)
1578 call h5pclose_f(dcpl_id, ierr)
1584 dcount = [int(counts, hsize_t)]
1587 doffset = [int(offset, hsize_t) + append_offset]
1589 call h5dget_space_f(dset_id, filespace, ierr)
1591 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, doffset, dcount, &
1594 call h5screate_simple_f(dset_rank, dcount, memspace, ierr)
1600 if (this%precision == sp)
then
1601 allocate(write_buffer_sp(vec%size()))
1602 if (vec%size() > 0) write_buffer_sp =
real(vec%x, kind=sp)
1604 call h5dwrite_f(dset_id, precision_hdf, write_buffer_sp, dcount, ierr, &
1605 file_space_id = filespace, mem_space_id = memspace, &
1607 deallocate(write_buffer_sp)
1608 else if (this%precision == dp)
then
1609 allocate(write_buffer_dp(vec%size()))
1610 if (vec%size() > 0) write_buffer_dp =
real(vec%x, kind=dp)
1612 call h5dwrite_f(dset_id, precision_hdf, write_buffer_dp, dcount, ierr, &
1613 file_space_id = filespace, mem_space_id = memspace, &
1615 deallocate(write_buffer_dp)
1617 call neko_error(
"Unsupported precision")
1623 call h5pclose_f(xf_id, ierr)
1624 call h5sclose_f(memspace, ierr)
1625 call h5sclose_f(filespace, ierr)
1626 call h5dclose_f(dset_id, ierr)
1632 type(matrix_t),
intent(inout) :: mat
1633 integer :: ierr, counts, offset, total_count, dset_rank, strides, max_count
1634 integer(hsize_t) :: append_offset
1635 integer(hid_t) :: precision_hdf
1636 integer(hid_t) :: xf_id, filespace, dset_id, memspace, dcpl_id
1637 integer(hsize_t),
dimension(2) :: dcount, doffset
1638 integer(hsize_t),
dimension(2) :: ddims, ddims_max, chunkdims
1639 integer(hsize_t),
dimension(2) :: tempddims, tempmaxddims
1640 logical :: dset_exists
1641 real(kind=sp),
allocatable :: write_buffer_sp(:,:)
1642 real(kind=dp),
allocatable :: write_buffer_dp(:,:)
1647 strides = mat%get_nrows()
1648 counts = mat%get_ncols()
1649 append_offset = 0_hsize_t
1653 call mpi_scan(counts, offset, 1, mpi_integer, &
1654 mpi_sum, neko_comm, ierr)
1655 offset = offset - counts
1656 call mpi_allreduce(counts, total_count, 1, mpi_integer, &
1657 mpi_sum, neko_comm, ierr)
1658 call mpi_allreduce(counts, max_count, 1, mpi_integer, &
1659 mpi_max, neko_comm, ierr)
1664 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1665 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1666 precision_hdf = h5kind_to_type(this%precision, h5_real_kind)
1673 ddims = [int(strides, hsize_t), int(total_count, hsize_t)]
1674 chunkdims = [int(strides, hsize_t),
max(int(max_count, hsize_t), 1_hsize_t)]
1675 ddims_max = [int(strides, hsize_t), h5s_unlimited_f]
1676 call h5lexists_f(this%active_group_id, trim(mat%name), dset_exists, ierr)
1677 if (dset_exists)
then
1678 if (this%overwrite)
then
1680 if (pe_rank .eq. 0)
then
1681 call neko_warning(
"Dataset " // trim(mat%name) // &
1682 " already exists and wil be overwritten")
1685 call h5dopen_f(this%active_group_id, trim(mat%name), dset_id, ierr)
1687 call h5dopen_f(this%active_group_id, trim(mat%name), dset_id, ierr)
1688 call h5dget_space_f(dset_id, filespace, ierr)
1689 call h5sget_simple_extent_dims_f(filespace, tempddims, tempmaxddims, &
1691 call h5sclose_f(filespace, ierr)
1692 ddims(2) = ddims(2) + tempddims(2)
1693 append_offset = tempddims(2)
1694 call h5dset_extent_f(dset_id, ddims, ierr)
1698 call h5screate_simple_f(dset_rank, ddims, filespace, ierr, ddims_max)
1699 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
1700 call h5pset_chunk_f(dcpl_id, dset_rank, chunkdims, ierr)
1702 call h5dcreate_f(this%active_group_id, trim(mat%name), precision_hdf, &
1703 filespace, dset_id, ierr, dcpl_id = dcpl_id)
1704 call h5sclose_f(filespace, ierr)
1705 call h5pclose_f(dcpl_id, ierr)
1712 dcount = [int(strides, hsize_t), int(counts, hsize_t)]
1714 doffset = [0_hsize_t, int(offset, hsize_t) + append_offset]
1716 call h5dget_space_f(dset_id, filespace, ierr)
1718 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, doffset, dcount, &
1721 call h5screate_simple_f(dset_rank, dcount, memspace, ierr)
1726 if (this%precision == sp)
then
1727 allocate(write_buffer_sp(mat%get_nrows(), mat%get_ncols()))
1728 if (mat%size() > 0) write_buffer_sp =
real(mat%x, kind=sp)
1730 call h5dwrite_f(dset_id, precision_hdf, write_buffer_sp, dcount, ierr, &
1731 file_space_id = filespace, mem_space_id = memspace, &
1733 deallocate(write_buffer_sp)
1734 else if (this%precision == dp)
then
1735 allocate(write_buffer_dp(mat%get_nrows(), mat%get_ncols()))
1736 if (mat%size() > 0) write_buffer_dp =
real(mat%x, kind=dp)
1738 call h5dwrite_f(dset_id, precision_hdf, write_buffer_dp, dcount, ierr, &
1739 file_space_id = filespace, mem_space_id = memspace, &
1741 deallocate(write_buffer_dp)
1743 call neko_error(
"Unsupported precision")
1749 call h5pclose_f(xf_id, ierr)
1750 call h5sclose_f(memspace, ierr)
1751 call h5sclose_f(filespace, ierr)
1752 call h5dclose_f(dset_id, ierr)
1758 type(field_t),
intent(inout) :: field
1759 integer :: ierr, counts, offset, total_count, dset_rank, max_count
1760 integer :: stride_ax_1, stride_ax_2, stride_ax_3
1761 integer(hsize_t) :: append_offset
1762 integer(hid_t) :: precision_hdf
1763 integer(hid_t) :: xf_id, filespace, dset_id, memspace, dcpl_id
1764 integer(hsize_t),
dimension(4) :: dcount, doffset
1765 integer(hsize_t),
dimension(4) :: ddims, ddims_max, chunkdims
1766 integer(hsize_t),
dimension(4) :: tempddims, tempmaxddims
1767 logical :: dset_exists
1768 real(kind=sp),
allocatable :: write_buffer_sp(:,:,:,:)
1769 real(kind=dp),
allocatable :: write_buffer_dp(:,:,:,:)
1774 stride_ax_1 =
field%Xh%lx
1775 stride_ax_2 =
field%Xh%ly
1776 stride_ax_3 =
field%Xh%lz
1777 counts =
field%msh%nelv
1778 append_offset = 0_hsize_t
1779 total_count =
field%msh%glb_nelv
1781 offset =
field%msh%offset_el
1782 call mpi_allreduce(counts, max_count, 1, mpi_integer, &
1783 mpi_max, neko_comm, ierr)
1788 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1789 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1790 precision_hdf = h5kind_to_type(this%precision, h5_real_kind)
1796 ddims = [int(stride_ax_1, hsize_t), &
1797 int(stride_ax_2, hsize_t), &
1798 int(stride_ax_3, hsize_t), &
1799 int(total_count, hsize_t)]
1800 chunkdims = [int(stride_ax_1, hsize_t), &
1801 int(stride_ax_2, hsize_t), &
1802 int(stride_ax_3, hsize_t), &
1803 max(int(max_count, hsize_t), 1_hsize_t)]
1804 ddims_max = [int(stride_ax_1, hsize_t), &
1805 int(stride_ax_2, hsize_t), &
1806 int(stride_ax_3, hsize_t), &
1808 call h5lexists_f(this%active_group_id, trim(
field%name), dset_exists, ierr)
1809 if (dset_exists)
then
1810 if (this%overwrite)
then
1812 if (pe_rank .eq. 0)
then
1813 call neko_warning(
"Overwriting dataset: " // trim(
field%name))
1815 call h5dopen_f(this%active_group_id, trim(
field%name), dset_id, ierr)
1817 call h5dopen_f(this%active_group_id, trim(
field%name), dset_id, ierr)
1818 call h5dget_space_f(dset_id, filespace, ierr)
1819 call h5sget_simple_extent_dims_f(filespace, tempddims, tempmaxddims, &
1821 call h5sclose_f(filespace, ierr)
1822 ddims(4) = ddims(4) + tempddims(4)
1823 append_offset = tempddims(4)
1824 call h5dset_extent_f(dset_id, ddims, ierr)
1828 call h5screate_simple_f(dset_rank, ddims, filespace, ierr, ddims_max)
1829 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
1830 call h5pset_chunk_f(dcpl_id, dset_rank, chunkdims, ierr)
1832 call h5dcreate_f(this%active_group_id, trim(
field%name), precision_hdf, &
1833 filespace, dset_id, ierr, dcpl_id = dcpl_id)
1834 call h5sclose_f(filespace, ierr)
1835 call h5pclose_f(dcpl_id, ierr)
1841 dcount = [int(stride_ax_1, hsize_t), &
1842 int(stride_ax_2, hsize_t), &
1843 int(stride_ax_3, hsize_t), &
1844 int(counts, hsize_t)]
1845 doffset = [0_hsize_t, 0_hsize_t, 0_hsize_t, &
1846 int(offset, hsize_t) + append_offset]
1848 call h5dget_space_f(dset_id, filespace, ierr)
1850 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, doffset, dcount, &
1853 call h5screate_simple_f(dset_rank, dcount, memspace, ierr)
1858 if (this%precision == sp)
then
1863 call h5dwrite_f(dset_id, precision_hdf, write_buffer_sp, dcount, ierr, &
1864 file_space_id = filespace, mem_space_id = memspace, &
1866 deallocate(write_buffer_sp)
1867 else if (this%precision == dp)
then
1872 call h5dwrite_f(dset_id, precision_hdf, write_buffer_dp, dcount, ierr, &
1873 file_space_id = filespace, mem_space_id = memspace, &
1875 deallocate(write_buffer_dp)
1877 call neko_error(
"Unsupported precision")
1883 call h5pclose_f(xf_id, ierr)
1884 call h5sclose_f(memspace, ierr)
1885 call h5sclose_f(filespace, ierr)
1886 call h5dclose_f(dset_id, ierr)
1893 character(len=*),
intent(in) :: data_name
1894 type(vector_t),
intent(inout) :: vec
1895 character(len=*),
intent(in),
optional :: strategy
1896 character(len=1000) :: strategy_
1897 integer :: ierr, counts, offset, total_count, dset_rank
1898 integer(hid_t) :: precision_hdf
1899 integer(hid_t) :: xf_id, filespace, dset_id, memspace
1900 integer(hsize_t),
dimension(1) :: dcount, doffset
1901 integer(hsize_t),
dimension(1) :: tempddims, tempmaxddims
1903 logical :: dset_exists
1904 type(linear_dist_t) :: dist
1907 if (
present(strategy))
then
1908 if (trim(strategy) .eq.
"linear" .or. &
1909 trim(strategy) .eq.
"rank_0")
then
1910 strategy_ = strategy
1912 call neko_error(
"Unsupported strategy: " // trim(strategy))
1915 strategy_ =
"linear"
1924 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1925 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1926 precision_hdf = h5kind_to_type(rp, h5_real_kind)
1931 call h5lexists_f(this%active_group_id, trim(data_name), dset_exists, ierr)
1932 if (dset_exists)
then
1934 call h5dopen_f(this%active_group_id, trim(data_name), dset_id, ierr)
1936 call h5dget_space_f(dset_id, filespace, ierr)
1937 call h5sget_simple_extent_ndims_f(filespace, temprank, ierr)
1938 if (temprank .ne. 1)
then
1939 call neko_error(
"Dataset " // trim(data_name) // &
1940 " is not a rank 1 vector in file " // trim(
file_get_fname(this)))
1943 call h5sget_simple_extent_dims_f(filespace, tempddims, tempmaxddims, &
1945 call h5sclose_f(filespace, ierr)
1947 call neko_error(
"Dataset " // trim(data_name) // &
1948 " does not exist in current group " // trim(
file_get_fname(this)))
1954 total_count = int(tempddims(1))
1955 if (strategy_ .eq.
"linear")
then
1956 dist = linear_dist_t(total_count, pe_rank, pe_size, neko_comm)
1957 counts = dist%num_local()
1959 else if (strategy_ .eq.
"rank_0")
then
1960 if (pe_rank .eq. 0)
then
1961 counts = total_count
1967 call mpi_exscan(counts, offset, 1, mpi_integer, &
1968 mpi_sum, neko_comm, ierr)
1974 dcount = [int(counts, hsize_t)]
1975 doffset = [int(offset, hsize_t)]
1977 call h5dget_space_f(dset_id, filespace, ierr)
1979 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, doffset, dcount, &
1982 call h5screate_simple_f(dset_rank, dcount, memspace, ierr)
1987 call vec%init(counts, trim(data_name))
1988 call h5dread_f(dset_id, precision_hdf, vec%x, dcount, ierr, &
1989 file_space_id = filespace, mem_space_id = memspace, &
1995 call h5pclose_f(xf_id, ierr)
1996 call h5sclose_f(memspace, ierr)
1997 call h5sclose_f(filespace, ierr)
1998 call h5dclose_f(dset_id, ierr)
2005 character(len=*),
intent(in) :: data_name
2006 type(matrix_t),
intent(inout) :: mat
2007 character(len=*),
intent(in),
optional :: strategy
2008 character(len=1000) :: strategy_
2009 integer :: ierr, counts, offset, total_count, dset_rank
2010 integer(hid_t) :: precision_hdf
2011 integer(hid_t) :: xf_id, filespace, dset_id, memspace
2012 integer(hsize_t),
dimension(2) :: dcount, doffset
2013 integer(hsize_t),
dimension(2) :: tempddims, tempmaxddims
2015 logical :: dset_exists
2016 type(linear_dist_t) :: dist
2019 if (
present(strategy))
then
2020 if (trim(strategy) .eq.
"linear" .or. &
2021 trim(strategy) .eq.
"rank_0")
then
2022 strategy_ = strategy
2024 call neko_error(
"Unsupported strategy: " // trim(strategy))
2027 strategy_ =
"linear"
2036 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
2037 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
2038 precision_hdf = h5kind_to_type(rp, h5_real_kind)
2043 call h5lexists_f(this%active_group_id, trim(data_name), dset_exists, ierr)
2044 if (dset_exists)
then
2046 call h5dopen_f(this%active_group_id, trim(data_name), dset_id, ierr)
2048 call h5dget_space_f(dset_id, filespace, ierr)
2049 call h5sget_simple_extent_ndims_f(filespace, temprank, ierr)
2050 if (temprank .ne. 2)
then
2051 call neko_error(
"Dataset " // trim(data_name) // &
2052 " is not a rank 2 matrix in file " // trim(
file_get_fname(this)))
2055 call h5sget_simple_extent_dims_f(filespace, tempddims, tempmaxddims, &
2057 call h5sclose_f(filespace, ierr)
2059 call neko_error(
"Dataset " // trim(data_name) &
2060 //
" does not exist in current group " // &
2067 total_count = int(tempddims(2))
2068 if (strategy_ .eq.
"linear")
then
2069 dist = linear_dist_t(total_count, pe_rank, pe_size, neko_comm)
2070 counts = dist%num_local()
2072 else if (strategy_ .eq.
"rank_0")
then
2073 if (pe_rank .eq. 0)
then
2074 counts = total_count
2080 call mpi_scan(counts, offset, 1, mpi_integer, &
2081 mpi_sum, neko_comm, ierr)
2082 offset = offset - counts
2088 dcount = [int(tempddims(1), hsize_t), int(counts, hsize_t)]
2089 doffset = [0_hsize_t, int(offset, hsize_t)]
2091 call h5dget_space_f(dset_id, filespace, ierr)
2093 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, doffset, dcount, &
2096 call h5screate_simple_f(dset_rank, dcount, memspace, ierr)
2101 call mat%init(int(tempddims(1)), counts, trim(data_name))
2102 call h5dread_f(dset_id, precision_hdf, mat%x, dcount, ierr, &
2103 file_space_id = filespace, mem_space_id = memspace, &
2109 call h5pclose_f(xf_id, ierr)
2110 call h5sclose_f(memspace, ierr)
2111 call h5sclose_f(filespace, ierr)
2112 call h5dclose_f(dset_id, ierr)
2120 character(len=*),
intent(in) :: attr_name
2121 integer,
intent(in) :: attr
2123 integer(hid_t) :: filespace, attr_id
2124 integer(hsize_t),
dimension(1) :: dcount
2125 logical :: attr_exists
2130 dcount = [int(1, hsize_t)]
2131 call h5aexists_f(this%active_group_id, trim(attr_name), attr_exists, ierr)
2132 if (attr_exists)
then
2134 call h5aopen_f(this%active_group_id, trim(attr_name), attr_id, ierr)
2137 call h5screate_f(h5s_scalar_f, filespace, ierr)
2139 call h5acreate_f(this%active_group_id, trim(attr_name), &
2140 h5t_native_integer, &
2141 filespace, attr_id, ierr, h5p_default_f, h5p_default_f)
2142 call h5sclose_f(filespace, ierr)
2148 call h5awrite_f(attr_id, h5t_native_integer, attr, dcount, ierr)
2153 call h5aclose_f(attr_id, ierr)
2160 character(len=*),
intent(in) :: attr_name
2161 real(kind=rp),
intent(in) :: attr
2163 integer(hid_t) :: precision_hdf
2164 integer(hid_t) :: filespace, attr_id
2165 integer(hsize_t),
dimension(1) :: dcount
2166 logical :: attr_exists
2169 precision_hdf = h5kind_to_type(rp, h5_real_kind)
2174 dcount = [int(1, hsize_t)]
2175 call h5aexists_f(this%active_group_id, trim(attr_name), attr_exists, ierr)
2176 if (attr_exists)
then
2178 call h5aopen_f(this%active_group_id, trim(attr_name), attr_id, ierr)
2181 call h5screate_f(h5s_scalar_f, filespace, ierr)
2183 call h5acreate_f(this%active_group_id, trim(attr_name), precision_hdf, &
2184 filespace, attr_id, ierr, h5p_default_f, h5p_default_f)
2185 call h5sclose_f(filespace, ierr)
2191 call h5awrite_f(attr_id, precision_hdf, attr, dcount, ierr)
2196 call h5aclose_f(attr_id, ierr)
2203 character(len=*),
intent(in) :: attr_name
2204 integer,
intent(inout) :: attr
2205 logical,
intent(inout) :: attr_exists
2207 integer(hid_t) :: filespace, attr_id
2208 integer(hsize_t),
dimension(1) :: dcount
2213 dcount = [int(1, hsize_t)]
2214 call h5aexists_f(this%active_group_id, trim(attr_name), attr_exists, ierr)
2215 if (attr_exists)
then
2217 call h5aopen_f(this%active_group_id, trim(attr_name), attr_id, ierr)
2225 call h5aread_f(attr_id, h5t_native_integer, attr, dcount, ierr)
2230 call h5aclose_f(attr_id, ierr)
2237 character(len=*),
intent(in) :: attr_name
2238 real(kind=rp),
intent(inout) :: attr
2239 logical,
intent(inout) :: attr_exists
2241 integer(hid_t) :: precision_hdf
2242 integer(hid_t) :: filespace, attr_id
2243 integer(hsize_t),
dimension(1) :: dcount
2246 precision_hdf = h5kind_to_type(rp, h5_real_kind)
2251 dcount = [int(1, hsize_t)]
2252 call h5aexists_f(this%active_group_id, trim(attr_name), attr_exists, ierr)
2253 if (attr_exists)
then
2255 call h5aopen_f(this%active_group_id, trim(attr_name), attr_id, ierr)
2263 call h5aread_f(attr_id, precision_hdf, attr, dcount, ierr)
2268 call h5aclose_f(attr_id, ierr)
2277 character(len=1),
intent(in) :: mode
2278 call neko_error(
'Neko needs to be built with HDF5 support')
2284 call neko_error(
'Neko needs to be built with HDF5 support')
2290 character(len=*),
intent(in),
optional :: group_name_path
2291 call neko_error(
'Neko needs to be built with HDF5 support')
2299 class(*),
target,
intent(in) :: data
2300 real(kind=dp),
intent(in),
optional :: t
2301 call neko_error(
'Neko needs to be built with HDF5 support')
2308 class(*),
target,
intent(inout) :: data
2309 call neko_error(
'Neko needs to be built with HDF5 support')
2314 class(*),
intent(inout) :: data
2315 call neko_error(
'Neko needs to be built with HDF5 support')
2320 character(len=*),
intent(in) :: data_name
2321 class(*),
intent(inout) :: data
2322 character(len=*),
intent(in),
optional :: strategy
2323 call neko_error(
'Neko needs to be built with HDF5 support')
2328 character(len=*),
intent(in) :: data_name
2329 class(*),
intent(inout) :: data
2330 call neko_error(
'Neko needs to be built with HDF5 support')
2335 character(len=*),
intent(in) :: data_name
2336 class(*),
intent(inout) :: data
2337 logical,
intent(inout) :: exist
2338 call neko_error(
'Neko needs to be built with HDF5 support')
2343 type(vector_t),
intent(inout) :: vec
2344 call neko_error(
'Neko needs to be built with HDF5 support')
2349 type(matrix_t),
intent(inout) :: mat
2350 call neko_error(
'Neko needs to be built with HDF5 support')
2355 type(field_t),
intent(inout) :: fld
2356 call neko_error(
'Neko needs to be built with HDF5 support')
2361 character(len=*),
intent(in) :: data_name
2362 type(vector_t),
intent(inout) :: vec
2363 character(len=*),
intent(in),
optional :: strategy
2364 call neko_error(
'Neko needs to be built with HDF5 support')
2369 character(len=*),
intent(in) :: data_name
2370 type(matrix_t),
intent(inout) :: mat
2371 character(len=*),
intent(in),
optional :: strategy
2372 call neko_error(
'Neko needs to be built with HDF5 support')
2377 character(len=*),
intent(in) :: attr_name
2378 integer,
intent(in) :: attr
2379 call neko_error(
'Neko needs to be built with HDF5 support')
2384 character(len=*),
intent(in) :: attr_name
2385 real(kind=rp),
intent(in) :: attr
2386 call neko_error(
'Neko needs to be built with HDF5 support')
2391 character(len=*),
intent(in) :: attr_name
2392 integer,
intent(inout) :: attr
2393 logical,
intent(inout) :: attr_exists
2394 call neko_error(
'Neko needs to be built with HDF5 support')
2399 character(len=*),
intent(in) :: attr_name
2400 real(kind=rp),
intent(inout) :: attr
2401 logical,
intent(inout) :: attr_exists
2402 call neko_error(
'Neko needs to be built with HDF5 support')
Format-independent checkpoint payloads.
Defines format-independent checkpoint registration and restart state.
type(mpi_datatype), public mpi_real_precision
MPI type for working precision of REAL types.
integer, public pe_size
MPI size of communicator.
integer, public pe_rank
MPI rank.
type(mpi_comm), public neko_comm
MPI communicator.
Defines practical data distributions.
Defines a mapping of the degrees of freedom.
Contains the field_serties_t type.
Module for file I/O operations.
Implements global_interpolation given a dofmap.
subroutine hdf5_file_open(this, mode)
Open a HDF5 file in a given mode.
character(len=1024) function file_get_fname(this)
Return the file name with the start counter.
subroutine hdf5_file_write_field(this, fld)
subroutine hdf5_file_read(this, data)
Read data in HDF5 format.
subroutine hdf5_file_write(this, data, t)
Write data in HDF5 format.
subroutine hdf5_file_read_dataset(this, data_name, data, strategy)
subroutine hdf5_file_write_int_attribute(this, attr_name, attr)
subroutine hdf5_file_write_attribute(this, data_name, data)
subroutine hdf5_file_read_vector(this, data_name, vec, strategy)
subroutine hdf5_file_write_vector(this, vec)
subroutine hdf5_file_read_matrix(this, data_name, mat, strategy)
subroutine hdf5_file_read_int_attribute(this, attr_name, attr, attr_exists)
subroutine hdf5_file_write_rp_attribute(this, attr_name, attr)
subroutine hdf5_file_set_precision(this, precision)
Set the precision for the output (single or double)
character(len=1024) function hdf5_file_get_next_output_fname(this)
Get the physical file name generated by the next write.
subroutine hdf5_file_read_rp_attribute(this, attr_name, attr, attr_exists)
subroutine hdf5_file_read_attribute(this, data_name, data, exist)
subroutine hdf5_file_close(this)
Close the file.
subroutine hdf5_file_set_group(this, group_name_path)
Set the active group for HDF5 files.
subroutine hdf5_file_write_matrix(this, mat)
subroutine hdf5_checkpoint_layout_free(this)
Release the interpolation state and the function space of a layout. The mesh is only referenced; it b...
subroutine hdf5_file_write_dataset(this, data)
subroutine hdf5_file_set_overwrite(this, overwrite)
Set the overwrite flag for HDF5 files.
subroutine, public hdf5_session_init
Initialise the global HDF5 session HDF5 does not maintain a global reference count,...
subroutine, public hdf5_session_finalize
Finalize the global HDF5 session.
Routines to interpolate between different spaces.
integer, parameter, public neko_log_debug
Debug.
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
subroutine, public rzero(a, n)
Zero a real vector.
integer, parameter, public i8
integer, parameter, public dp
integer, parameter, public sp
integer, parameter, public rp
Global precision used in computations.
Defines a function space.
integer, parameter, public gll
subroutine, public filename_split(fname, path, name, suffix)
Extract file name components.
subroutine, public neko_warning(warning_msg)
Reports a warning to standard output.
pure integer function, public filename_suffix_pos(fname)
Find position (in the string) of a filename's suffix.
Collection of live simulation data registered for checkpointing.
A named real array and its selection in a global checkpoint dataset.
A named nodal real array distributed over mesh elements.
A named collection of live fields to checkpoint together.
Load-balanced linear distribution .
field_ptr_t, To easily obtain a pointer to a field
field_list_t, To be able to group fields together
A wrapper for a pointer to a field_series_t.
Stores a series (sequence) of fields, logically connected to a base field, and arranged according to ...
Implements global interpolation for arbitrary points in the domain.
Where the data in a checkpoint file sits and how it maps onto the running case. Built once per read a...
Interface for HDF5 files.
Interpolation between two space::space_t.
The function space for the SEM solution fields.