48 use mpi_f08,
only : mpi_info_null, mpi_allreduce, mpi_allgather, &
49 mpi_in_place, mpi_integer, mpi_sum, mpi_max, mpi_comm_size, mpi_exscan, &
50 mpi_barrier, mpi_bcast, mpi_logical
55 hid_t, hsize_t, size_t, &
56 h5fcreate_f, h5fopen_f, h5fclose_f, h5fflush_f, h5fget_obj_count_f, &
57 h5f_obj_all_f, h5f_scope_global_f, &
58 h5gcreate_f, h5gopen_f, h5gclose_f, &
59 h5acreate_f, h5aopen_f, h5awrite_f, h5aread_f, h5aclose_f, h5aexists_f, &
61 h5dcreate_f, h5dopen_f, h5dwrite_f, h5dread_f, h5dclose_f, &
62 h5dget_create_plist_f, &
63 h5tcopy_f, h5tclose_f, h5tset_strpad_f, h5tset_size_f, &
64 h5screate_f, h5screate_simple_f, h5sclose_f, &
65 h5sselect_hyperslab_f, h5sselect_all_f, h5sget_simple_extent_dims_f, &
66 h5dget_space_f, h5dset_extent_f, &
67 h5pcreate_f, h5pclose_f, h5pset_fapl_mpio_f, h5pset_dxpl_mpio_f, &
68 h5pget_virtual_count_f, h5pget_virtual_filename_f, &
69 h5lexists_f, h5ldelete_f, &
70 h5p_file_access_f, h5p_dataset_xfer_f, h5p_dataset_create_f, &
71 h5f_acc_trunc_f, h5f_acc_rdwr_f, h5f_acc_rdonly_f, h5pset_chunk_f, &
72 h5t_std_u8le, h5t_native_integer, h5t_fortran_s1, h5t_str_nullterm_f, &
73 h5kind_to_type, h5_real_kind, h5_integer_kind, h5pset_virtual_f, &
74 h5s_scalar_f, h5s_select_set_f, h5fd_mpio_collective_f, h5p_default_f, &
82 logical :: amr_enabled = .false.
83 logical :: subdivide = .false.
84 logical :: enable_vds = .false.
85 integer :: precision = -1
107 logical,
intent(in) :: overwrite
108 this%overwrite = overwrite
114 this%amr_enabled = .false.
120 integer,
intent(in) :: precision
121 this%precision = precision
127 character(len=1024) :: base_fname
128 character(len=1024) :: fname
129 character(len=1024) :: path, name, suffix
131 fname = trim(this%get_base_fname())
134 write(base_fname,
'(A,A,"_",I0,A)') &
135 trim(path), trim(name), this%get_start_counter(), trim(suffix)
142 character(len=1024) :: fname
144 fname = this%get_vtkhdf_fname()
155 logical,
intent(in) :: subdivide
156 this%subdivide = subdivide
167 class(*),
target,
intent(in) :: data
168 real(kind=
dp),
intent(in),
optional :: t
169 type(
mesh_t),
pointer :: msh
172 integer :: ierr, mpi_info, mpi_comm, i, n_fields
173 integer(hid_t) :: plist_id, file_id, attr_id, vtkhdf_grp
174 integer(hid_t) :: filespace, H5T_NEKO_STRING
175 integer(hsize_t),
dimension(1) :: vdims
176 integer(size_t) :: type_len
177 integer :: lx, ly, lz
178 integer :: local_points, local_cells, local_conn
179 integer :: total_points, total_cells, total_conn
180 integer :: point_offset
181 integer :: max_local_points
182 integer,
allocatable :: part_points(:), part_cells(:), part_conns(:)
183 character(len=1024) :: fname
184 character(len=16) :: type_str
198 call fields%assign_to_field(1, data)
202 call fields%assign_to_list(data)
204 call neko_error(
'Invalid data type for vtkhdf_file_write')
208 if (.not.
associated(msh))
then
209 call neko_error(
'Mesh must be associated for vtkhdf_file_write')
211 if (dof%Xh%lx .lt. 2 .or. dof%Xh%ly .lt. 2)
then
212 call neko_error(
'VTKHDF linear output requires lx, ly >= 2')
214 if (msh%gdim .eq. 3 .and. dof%Xh%lz .lt. 2)
then
215 call neko_error(
'VTKHDF linear output requires lz >= 2 in 3D')
217 if (msh%gdim .lt. 2 .or. msh%gdim .gt. 3)
then
218 call neko_error(
'VTKHDF output only supports 2D and 3D meshes')
222 if (this%precision .gt.
rp)
then
224 call neko_warning(
'Requested precision is higher than working precision')
225 else if (this%precision .eq. -1)
then
229 call this%increment_counter()
230 fname = trim(this%get_vtkhdf_fname())
231 counter = this%get_counter() - this%get_start_counter()
233 mpi_info = mpi_info_null%mpi_val
237 call h5pcreate_f(h5p_file_access_f, plist_id, ierr)
238 call h5pset_fapl_mpio_f(plist_id, mpi_comm, mpi_info, ierr)
240 if (counter .eq. 0)
then
242 call h5fcreate_f(fname, h5f_acc_trunc_f, &
243 file_id, ierr, access_prp = plist_id)
245 call h5fopen_f(fname, h5f_acc_rdwr_f, file_id, ierr, &
246 access_prp = plist_id)
250 call h5lexists_f(file_id,
"VTKHDF", exists, ierr)
252 call h5gopen_f(file_id,
"VTKHDF", vtkhdf_grp, ierr)
254 call h5gcreate_f(file_id,
"VTKHDF", vtkhdf_grp, ierr)
258 call h5screate_simple_f(1, vdims, filespace, ierr)
259 call h5acreate_f(vtkhdf_grp,
"Version", h5t_native_integer, filespace, &
261 call h5awrite_f(attr_id, h5t_native_integer,
vtkhdf_version, vdims, ierr)
262 call h5aclose_f(attr_id, ierr)
263 call h5sclose_f(filespace, ierr)
266 type_str =
"UnstructuredGrid"
267 type_len = int(len_trim(type_str), kind=size_t)
269 call h5screate_f(h5s_scalar_f, filespace, ierr)
271 call h5tcopy_f(h5t_fortran_s1, h5t_neko_string, ierr)
272 call h5tset_size_f(h5t_neko_string, type_len, ierr)
273 call h5tset_strpad_f(h5t_neko_string, h5t_str_nullterm_f, ierr)
275 call h5acreate_f(vtkhdf_grp,
"Type", h5t_neko_string, filespace, &
277 call h5awrite_f(attr_id, h5t_neko_string, [type_str], vdims, ierr)
278 call h5aclose_f(attr_id, ierr)
280 call h5tclose_f(h5t_neko_string, ierr)
281 call h5sclose_f(filespace, ierr)
285 call vtkhdf_write_steps(vtkhdf_grp, counter, t)
288 if (
associated(msh))
then
289 call vtkhdf_write_mesh(vtkhdf_grp, dof, msh, &
290 this%amr_enabled, counter, this%subdivide, t)
294 if (fields%size() .gt. 0)
then
295 call vtkhdf_write_pointdata(vtkhdf_grp, fields, this%precision, &
299 call h5gclose_f(vtkhdf_grp, ierr)
300 call h5pclose_f(plist_id, ierr)
306 integer(size_t) :: obj_count
307 character(len=80) :: wrn_buf
308 call h5fget_obj_count_f(file_id, h5f_obj_all_f, obj_count, ierr)
309 if (obj_count .gt. 1_size_t .and.
pe_rank .eq. 0)
then
310 write(wrn_buf,
'(A,I0,A)')
'VTKHDF: ', obj_count - 1, &
311 ' HDF5 id(s) still open at file close'
315 call h5fflush_f(file_id, h5f_scope_global_f, ierr)
316 call h5fclose_f(file_id, ierr)
335 subroutine vtkhdf_write_mesh(vtkhdf_grp, dof, msh, amr, counter, subdivide, t)
336 type(dofmap_t),
intent(in) :: dof
337 type(mesh_t),
intent(in) :: msh
338 integer(hid_t),
intent(in) :: vtkhdf_grp
339 logical,
intent(in) :: amr
340 integer,
intent(in) :: counter
341 logical,
intent(in) :: subdivide
342 real(kind=dp),
intent(in),
optional :: t
344 integer(kind=1) :: VTK_cell_type
345 integer :: ierr, i, ii, jj, kk, el, local_idx
346 integer :: lx, ly, lz, npts_per_cell, nodes_per_cell, cells_per_element
347 integer :: local_points, local_cells, local_conn
348 integer :: total_points, total_cells, total_conn
349 integer :: point_offset, max_local_points
350 integer :: total_offsets, cell_offset, conn_offset, offsets_offset
351 integer :: max_local_cells, max_local_conn
352 integer(hid_t) :: xf_id, dset_id, dcpl_id, grp_id, attr_id
353 integer(hid_t) :: filespace, memspace, H5T_NEKO_DOUBLE
354 integer(hsize_t),
dimension(1) :: dcount, vdims, maxdims, doffset, chunkdims
355 integer(hsize_t),
dimension(2) :: dcount2, vdims2, maxdims2, doffset2
356 integer(kind=i8) :: i8_value
358 integer,
dimension(3) :: component_sizes
359 integer,
dimension(3) :: component_offsets
360 integer,
dimension(3) :: component_max_sizes
366 if (subdivide .and. msh%gdim .eq. 3)
then
367 vtk_cell_type = int(12, kind=1)
368 cells_per_element = (lx - 1) * (ly - 1) * (lz - 1)
370 else if (subdivide .and. msh%gdim .eq. 2)
then
371 vtk_cell_type = int(9, kind=1)
372 cells_per_element = (lx - 1) * (ly - 1)
374 else if (msh%gdim .eq. 3)
then
375 vtk_cell_type = int(72, kind=1)
376 cells_per_element = 1
377 nodes_per_cell = lx * ly * lz
378 else if (msh%gdim .eq. 2)
then
379 vtk_cell_type = int(70, kind=1)
380 cells_per_element = 1
381 nodes_per_cell = lx * ly
385 local_points = dof%size()
386 local_cells = msh%nelv * cells_per_element
387 local_conn = local_cells * nodes_per_cell
389 total_points = dof%global_size()
390 total_cells = msh%glb_nelv * cells_per_element
391 total_conn = total_cells * nodes_per_cell
393 component_sizes = [local_points, local_cells, local_conn]
394 component_offsets = 0
395 component_max_sizes = 0
397 call mpi_exscan(component_sizes, component_offsets, 3, mpi_integer, &
398 mpi_sum, neko_comm, ierr)
399 call mpi_allreduce(component_sizes, component_max_sizes, 3, mpi_integer, &
400 mpi_max, neko_comm, ierr)
402 point_offset = component_offsets(1)
403 cell_offset = component_offsets(2)
404 conn_offset = component_offsets(3)
405 max_local_points = component_max_sizes(1)
406 max_local_cells = component_max_sizes(2)
407 max_local_conn = component_max_sizes(3)
409 offsets_offset = cell_offset + pe_rank
410 total_offsets = total_cells + pe_size
413 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
414 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
422 integer(hsize_t),
dimension(1) :: nof_dims, nof_maxdims
423 integer(hsize_t),
dimension(1) :: nof_count, nof_offset, nof_chunk
424 integer(hid_t) :: nof_filespace, nof_memspace, nof_dcpl
425 integer(kind=i8) :: nof_values(3)
427 nof_count(1) = 1_hsize_t
428 nof_offset(1) = int(counter, hsize_t) * int(pe_size, hsize_t) &
429 + int(pe_rank, hsize_t)
430 nof_chunk(1) =
max(1_hsize_t, int(pe_size, hsize_t))
431 nof_values = [int(local_points, kind=i8), int(local_cells, kind=i8), &
432 int(local_conn, kind=i8)]
434 call h5pcreate_f(h5p_dataset_create_f, nof_dcpl, ierr)
435 call h5pset_chunk_f(nof_dcpl, 1, nof_chunk, ierr)
437 call vtkhdf_write_numberof(vtkhdf_grp,
"NumberOfPoints", &
438 nof_values(1), nof_offset, nof_count, nof_dcpl, &
439 counter, xf_id, ierr)
440 call vtkhdf_write_numberof(vtkhdf_grp,
"NumberOfCells", &
441 nof_values(2), nof_offset, nof_count, nof_dcpl, &
442 counter, xf_id, ierr)
443 call vtkhdf_write_numberof(vtkhdf_grp,
"NumberOfConnectivityIds", &
444 nof_values(3), nof_offset, nof_count, nof_dcpl, &
445 counter, xf_id, ierr)
447 call h5pclose_f(nof_dcpl, ierr)
451 call h5lexists_f(vtkhdf_grp,
"Points", exists, ierr)
452 if (.not. exists)
then
454 vdims2 = [3_hsize_t, int(total_points, hsize_t)]
455 maxdims2 = [3_hsize_t, h5s_unlimited_f]
456 chunkdims(1) = int(
max(1, min(max_local_points, total_points)), hsize_t)
457 dcount2 = [3_hsize_t, int(local_points, hsize_t)]
458 doffset2 = [0_hsize_t, int(point_offset, hsize_t)]
459 h5t_neko_double = h5kind_to_type(dp, h5_real_kind)
461 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
462 call h5screate_simple_f(2, dcount2, memspace, ierr)
463 call h5screate_simple_f(2, vdims2, filespace, ierr, maxdims2)
465 call h5pset_chunk_f(dcpl_id, 2, [3_hsize_t, chunkdims(1)], ierr)
466 call h5dcreate_f(vtkhdf_grp,
"Points", h5t_neko_double, &
467 filespace, dset_id, ierr, dcpl_id = dcpl_id)
468 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
469 doffset2, dcount2, ierr)
472 real(kind=dp),
allocatable :: coords(:,:)
474 allocate(coords(3, local_points))
475 do concurrent(local_idx = 1:local_points)
478 real(kind=dp) :: x, y, z
481 x =
real(dof%x%x(idx(1), idx(2), idx(3), idx(4)), dp)
482 y =
real(dof%y%x(idx(1), idx(2), idx(3), idx(4)), dp)
483 z =
real(dof%z%x(idx(1), idx(2), idx(3), idx(4)), dp)
485 coords(1, local_idx) = x
486 coords(2, local_idx) = y
487 coords(3, local_idx) = z
490 call h5dwrite_f(dset_id, h5t_neko_double, coords, dcount2, ierr, &
491 file_space_id = filespace, mem_space_id = memspace, &
496 call h5dclose_f(dset_id, ierr)
497 call h5sclose_f(filespace, ierr)
498 call h5sclose_f(memspace, ierr)
499 call h5pclose_f(dcpl_id, ierr)
503 call h5lexists_f(vtkhdf_grp,
"Connectivity", exists, ierr)
504 if (exists)
call h5ldelete_f(vtkhdf_grp,
"Connectivity", ierr)
506 vdims = int(total_conn, hsize_t)
507 maxdims = h5s_unlimited_f
508 chunkdims = int(
max(1, min(max_local_conn, total_conn)), hsize_t)
509 dcount = int(local_conn, hsize_t)
510 doffset = int(conn_offset, hsize_t)
512 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
513 call h5screate_simple_f(1, dcount, memspace, ierr)
514 call h5screate_simple_f(1, vdims, filespace, ierr, maxdims)
516 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
517 call h5dcreate_f(vtkhdf_grp,
"Connectivity", h5t_native_integer, &
518 filespace, dset_id, ierr, dcpl_id = dcpl_id)
519 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
520 doffset, dcount, ierr)
523 integer,
allocatable :: connectivity(:)
525 allocate(connectivity(local_conn))
526 call vtkhdf_build_connectivity(connectivity, vtk_cell_type, msh, dof, &
528 call h5dwrite_f(dset_id, h5t_native_integer, connectivity, dcount, &
529 ierr, file_space_id = filespace, mem_space_id = memspace, &
531 deallocate(connectivity)
534 call h5dclose_f(dset_id, ierr)
535 call h5sclose_f(filespace, ierr)
536 call h5sclose_f(memspace, ierr)
537 call h5pclose_f(dcpl_id, ierr)
540 call h5lexists_f(vtkhdf_grp,
"Offsets", exists, ierr)
541 if (exists)
call h5ldelete_f(vtkhdf_grp,
"Offsets", ierr)
543 vdims = int(total_offsets, hsize_t)
544 maxdims = h5s_unlimited_f
545 chunkdims = int(
max(1, min(max_local_cells + 1, total_offsets)), hsize_t)
546 dcount = int(local_cells + 1, hsize_t)
547 doffset = int(offsets_offset, hsize_t)
549 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
550 call h5screate_simple_f(1, dcount, memspace, ierr)
551 call h5screate_simple_f(1, vdims, filespace, ierr, maxdims)
553 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
554 call h5dcreate_f(vtkhdf_grp,
"Offsets", h5t_native_integer, &
555 filespace, dset_id, ierr, dcpl_id = dcpl_id)
556 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
557 doffset, dcount, ierr)
560 integer,
allocatable :: offsets(:)
562 allocate(offsets(local_cells + 1))
563 do concurrent(i = 1:local_cells)
564 offsets(i) = (i - 1) * nodes_per_cell
566 offsets(local_cells + 1) = local_conn
567 call h5dwrite_f(dset_id, h5t_native_integer, offsets, dcount, ierr, &
568 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
572 call h5dclose_f(dset_id, ierr)
573 call h5sclose_f(filespace, ierr)
574 call h5sclose_f(memspace, ierr)
575 call h5pclose_f(dcpl_id, ierr)
578 call h5lexists_f(vtkhdf_grp,
"Types", exists, ierr)
579 if (exists)
call h5ldelete_f(vtkhdf_grp,
"Types", ierr)
581 vdims = int(total_cells, hsize_t)
582 maxdims = h5s_unlimited_f
583 chunkdims = int(
max(1, min(max_local_cells, total_cells)), hsize_t)
584 dcount = int(local_cells, hsize_t)
585 doffset = int(cell_offset, hsize_t)
587 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
588 call h5screate_simple_f(1, dcount, memspace, ierr)
589 call h5screate_simple_f(1, vdims, filespace, ierr, maxdims)
591 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
592 call h5dcreate_f(vtkhdf_grp,
"Types", h5t_std_u8le, &
593 filespace, dset_id, ierr, dcpl_id = dcpl_id)
594 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
595 doffset, dcount, ierr)
598 integer(kind=1),
allocatable :: cell_types(:)
599 allocate(cell_types(local_cells), source=vtk_cell_type)
600 call h5dwrite_f(dset_id, h5t_std_u8le, cell_types, dcount, ierr, &
601 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
602 deallocate(cell_types)
605 call h5dclose_f(dset_id, ierr)
606 call h5sclose_f(filespace, ierr)
607 call h5sclose_f(memspace, ierr)
608 call h5pclose_f(dcpl_id, ierr)
612 call h5gopen_f(vtkhdf_grp,
"Steps", grp_id, ierr)
615 call vtkhdf_write_i8_at(grp_id,
"NumberOfParts", int(pe_size, kind=i8), &
621 i8_value = int(counter - 1, kind=i8) * int(pe_size, kind=i8)
622 call vtkhdf_write_i8_at(grp_id,
"PartOffsets", i8_value, counter)
624 i8_value = int(counter - 1, kind=i8) * int(total_points, kind=i8)
625 call vtkhdf_write_i8_at(grp_id,
"PointOffsets", i8_value, counter)
627 i8_value = int(counter - 1, kind=i8) * int(total_cells, kind=i8)
628 call vtkhdf_write_i8_at(grp_id,
"CellOffsets", i8_value, counter)
630 i8_value = int(counter - 1, kind=i8) * int(total_conn, kind=i8)
631 call vtkhdf_write_i8_at(grp_id,
"ConnectivityIdOffsets", i8_value, &
636 call vtkhdf_write_i8_at(grp_id,
"PartOffsets", i8_value, counter)
637 call vtkhdf_write_i8_at(grp_id,
"PointOffsets", i8_value, counter)
638 call vtkhdf_write_i8_at(grp_id,
"CellOffsets", i8_value, counter)
639 call vtkhdf_write_i8_at(grp_id,
"ConnectivityIdOffsets", i8_value, &
643 call h5gclose_f(grp_id, ierr)
646 call h5pclose_f(xf_id, ierr)
648 end subroutine vtkhdf_write_mesh
656 subroutine vtkhdf_write_steps(vtkhdf_grp, counter, t)
657 integer(hid_t),
intent(in) :: vtkhdf_grp
658 integer,
intent(in) :: counter
659 real(kind=dp),
intent(in) :: t
661 integer(hid_t) :: xf_id, H5T_NEKO_DOUBLE
663 integer(hid_t) :: grp_id, dset_id, dcpl_id, filespace, memspace, attr_id
664 integer(hsize_t),
dimension(1) :: step_dims, step_maxdims
665 integer(hsize_t),
dimension(1) :: step_count, step_offset, chunkdims, ddim
666 real(kind=dp),
dimension(1) :: time_value
667 integer(kind=i8) :: i8_value
668 logical :: exists, attr_exists
671 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
672 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
673 h5t_neko_double = h5kind_to_type(dp, h5_real_kind)
676 call h5lexists_f(vtkhdf_grp,
"Steps", exists, ierr)
678 call h5gopen_f(vtkhdf_grp,
"Steps", grp_id, ierr)
680 call h5gcreate_f(vtkhdf_grp,
"Steps", grp_id, ierr)
684 call h5lexists_f(grp_id,
"Values", exists, ierr)
686 call h5dopen_f(grp_id,
"Values", dset_id, ierr)
687 call h5dget_space_f(dset_id, filespace, ierr)
688 call h5sget_simple_extent_dims_f(filespace, step_dims, step_maxdims, &
690 call h5sclose_f(filespace, ierr)
693 if (step_dims(1) .eq. int(counter, hsize_t))
then
694 step_dims(1) = int(counter + 1, hsize_t)
695 call h5dset_extent_f(dset_id, step_dims, ierr)
696 else if (step_dims(1) .lt. int(counter, hsize_t))
then
697 call neko_error(
"VTKHDF: Time steps written out of order.")
700 step_dims(1) = 1_hsize_t
701 step_maxdims(1) = h5s_unlimited_f
702 chunkdims(1) = 1_hsize_t
704 call h5screate_simple_f(1, step_dims, filespace, ierr, step_maxdims)
705 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
706 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
707 call h5dcreate_f(grp_id,
"Values", h5t_neko_double, &
708 filespace, dset_id, ierr, dcpl_id = dcpl_id)
709 call h5sclose_f(filespace, ierr)
710 call h5pclose_f(dcpl_id, ierr)
713 step_count(1) = 1_hsize_t
714 step_offset(1) = int(counter, hsize_t)
716 call h5dget_space_f(dset_id, filespace, ierr)
717 call h5screate_simple_f(1, step_count, memspace, ierr)
718 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
719 step_offset, step_count, ierr)
722 call h5dwrite_f(dset_id, h5t_neko_double, time_value, step_count, ierr, &
723 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
725 call h5sclose_f(memspace, ierr)
726 call h5sclose_f(filespace, ierr)
727 call h5dclose_f(dset_id, ierr)
731 call h5aexists_f(grp_id,
"NSteps", attr_exists, ierr)
732 if (attr_exists)
then
733 call h5aopen_f(grp_id,
"NSteps", attr_id, ierr)
735 call h5screate_f(h5s_scalar_f, filespace, ierr)
736 call h5acreate_f(grp_id,
"NSteps", h5t_native_integer, filespace, &
737 attr_id, ierr, h5p_default_f, h5p_default_f)
738 call h5sclose_f(filespace, ierr)
741 call h5awrite_f(attr_id, h5t_native_integer, counter + 1, ddim, ierr)
743 call h5aclose_f(attr_id, ierr)
744 call h5gclose_f(grp_id, ierr)
745 call h5pclose_f(xf_id, ierr)
747 end subroutine vtkhdf_write_steps
763 subroutine vtkhdf_write_pointdata(vtkhdf_grp, fields, precision, counter, &
765 integer(hid_t),
intent(in) :: vtkhdf_grp
766 type(field_list_t),
intent(inout) :: fields
767 integer,
intent(in) :: precision
768 integer,
intent(in) :: counter
769 character(len=*),
intent(in) :: fname
770 real(kind=dp),
intent(in),
optional :: t
772 integer(kind=i8) :: time_offset
773 integer :: local_points, point_offset, total_points
774 integer(hid_t) :: precision_hdf
775 integer :: ierr, i, j
777 integer(hid_t) :: pointdata_grp, grp_id, step_grp_id
778 integer(hid_t) :: dset_id, dcpl_id, filespace
779 integer(hsize_t),
dimension(1) :: pd_dims1, pd_maxdims1
780 integer(hsize_t),
dimension(2) :: pd_dims2, pd_maxdims2
781 type(field_t),
pointer :: u, v, w
782 character(len=128) :: field_name
783 logical :: exists, is_vector
786 character(len=1024) :: ext_fname, ext_path, src_pattern
787 character(len=1024) :: main_path, main_name, main_suffix
788 integer(hid_t) :: ext_file_id, ext_plist_id, vds_src_space
789 integer(hid_t) :: write_target, attr_id, H5T_NEKO_STRING
790 integer :: mpi_info, mpi_comm
793 integer :: fields_written
794 character(len=128),
allocatable :: name_list(:)
795 logical,
allocatable :: vector_list(:)
797 mpi_info = mpi_info_null%mpi_val
798 mpi_comm = neko_comm%mpi_val
800 n_fields = fields%size()
803 local_points = fields%item_size(1)
804 total_points = fields%items(1)%ptr%dof%global_size()
806 call mpi_exscan(local_points, point_offset, 1, mpi_integer, &
807 mpi_sum, neko_comm, ierr)
811 if (
associated(fields%items(i)%ptr))
then
812 call fields%items(i)%ptr%copy_from(device_to_host, sync = i .eq. n_fields)
817 allocate(name_list(n_fields))
821 call h5lexists_f(vtkhdf_grp,
"PointData", exists, ierr)
822 if (.not. exists)
then
823 call h5gcreate_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
824 call h5gclose_f(pointdata_grp, ierr)
833 call filename_split(fname, main_path, main_name, main_suffix)
834 write(ext_path,
'(A,A,".data/")') trim(main_path), trim(main_name)
835 write(ext_fname,
'(A,I0,".h5")') trim(ext_path), counter
836 write(src_pattern,
'(A,".data/%b.h5")') trim(main_name)
838 if (pe_rank .eq. 0)
then
839 call mkdir(trim(ext_path))
841 call mpi_barrier(neko_comm, ierr)
843 call h5pcreate_f(h5p_file_access_f, ext_plist_id, ierr)
844 call h5pset_fapl_mpio_f(ext_plist_id, mpi_comm, mpi_info, ierr)
845 call h5fcreate_f(trim(ext_fname), h5f_acc_trunc_f, write_target, ierr, &
846 access_prp = ext_plist_id)
847 call h5pclose_f(ext_plist_id, ierr)
851 call h5gopen_f(vtkhdf_grp,
"PointData", write_target, ierr)
858 field_name = fields%name(i)
859 if (field_name .eq.
'p') field_name =
'Pressure'
863 if (field_name .eq.
'u' .or. field_name .eq.
'v' .or. &
864 field_name .eq.
'w')
then
869 select case (trim(fields%name(j)))
879 if (
associated(u) .and.
associated(v) .and.
associated(w))
then
881 field_name =
'Velocity'
888 do j = 1, fields_written
889 if (trim(name_list(j)) .eq. trim(field_name))
then
899 fields_written = fields_written + 1
900 name_list(fields_written) = field_name
905 call write_vector_field(write_target, field_name, u%x, v%x, w%x, &
906 local_points, precision, total_points, point_offset)
908 call write_scalar_field(write_target, field_name, fields%x(i), &
909 local_points, precision, total_points, point_offset)
915 call h5fclose_f(write_target, ierr)
917 call h5gclose_f(write_target, ierr)
926 call h5gopen_f(vtkhdf_grp,
"Steps", step_grp_id, ierr)
927 time_offset = int(counter, kind=i8) * int(total_points, kind=i8)
930 call h5lexists_f(step_grp_id,
"PointDataOffsets", exists, ierr)
932 call h5gopen_f(step_grp_id,
"PointDataOffsets", grp_id, ierr)
934 call h5gcreate_f(step_grp_id,
"PointDataOffsets", grp_id, ierr)
936 do i = 1, fields_written
937 call vtkhdf_write_i8_at(grp_id, trim(name_list(i)), &
938 time_offset, counter)
940 call h5gclose_f(grp_id, ierr)
941 call h5gclose_f(step_grp_id, ierr)
944 call h5gopen_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
946 do i = 1, fields_written
947 field_name = name_list(i)
950 if (counter .eq. 0)
then
952 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
953 precision_hdf = h5kind_to_type(precision, h5_real_kind)
956 pd_dims2 = [3_hsize_t, int(total_points, hsize_t)]
957 call h5screate_simple_f(2, pd_dims2, vds_src_space, ierr)
958 call h5sselect_all_f(vds_src_space, ierr)
960 pd_maxdims2 = [3_hsize_t, h5s_unlimited_f]
961 call h5screate_simple_f(2, pd_dims2, filespace, ierr, &
964 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
965 [0_hsize_t, 0_hsize_t], &
966 [1_hsize_t, h5s_unlimited_f], &
968 stride = [3_hsize_t, int(total_points, hsize_t)], &
969 block = [3_hsize_t, int(total_points, hsize_t)])
971 call h5pset_virtual_f(dcpl_id, filespace, trim(src_pattern), &
972 trim(field_name), vds_src_space, ierr)
973 call h5sclose_f(vds_src_space, ierr)
975 call h5dcreate_f(pointdata_grp, trim(field_name), &
976 precision_hdf, filespace, dset_id, ierr, &
978 call h5sclose_f(filespace, ierr)
980 pd_dims1 = int(total_points, hsize_t)
981 call h5screate_simple_f(1, pd_dims1, vds_src_space, ierr)
982 call h5sselect_all_f(vds_src_space, ierr)
984 pd_maxdims1(1) = h5s_unlimited_f
985 call h5screate_simple_f(1, pd_dims1, filespace, ierr, &
988 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
992 stride = [int(total_points, hsize_t)], &
993 block = [int(total_points, hsize_t)])
995 call h5pset_virtual_f(dcpl_id, filespace, trim(src_pattern), &
996 trim(field_name), vds_src_space, ierr)
997 call h5sclose_f(vds_src_space, ierr)
999 call h5dcreate_f(pointdata_grp, trim(field_name), &
1000 precision_hdf, filespace, dset_id, ierr, &
1002 call h5sclose_f(filespace, ierr)
1005 call h5pclose_f(dcpl_id, ierr)
1006 call h5dclose_f(dset_id, ierr)
1010 call h5dopen_f(pointdata_grp, trim(field_name), dset_id, ierr)
1013 pd_dims2 = [3_hsize_t, &
1014 int(counter + 1, hsize_t) * int(total_points, hsize_t)]
1015 call h5dset_extent_f(dset_id, pd_dims2, ierr)
1017 pd_dims1 = int(counter + 1, hsize_t) * int(total_points, hsize_t)
1018 call h5dset_extent_f(dset_id, pd_dims1, ierr)
1021 call h5dclose_f(dset_id, ierr)
1025 call h5gclose_f(pointdata_grp, ierr)
1031 deallocate(name_list)
1034 end subroutine vtkhdf_write_pointdata
1051 subroutine vtkhdf_build_connectivity(conn, vtk_type, msh, dof, subdivide)
1052 integer,
intent(inout) :: conn(:)
1053 integer(kind=1),
intent(in) :: vtk_type
1054 type(mesh_t),
intent(in) :: msh
1055 type(dofmap_t),
intent(in) :: dof
1056 logical,
intent(in) :: subdivide
1057 integer :: lx, ly, lz, nelv
1058 integer :: ie, ii, n_pts_per_elem, n_conn_per_elem
1059 integer,
allocatable :: node_order(:)
1065 n_pts_per_elem = lx * ly * lz
1067 if (subdivide .and. vtk_type .eq. int(12, kind=1))
then
1069 else if (subdivide .and. vtk_type .eq. int(9, kind=1))
then
1072 node_order = vtk_ordering(vtk_type, lx, ly, lz)
1075 n_conn_per_elem =
size(node_order)
1077 do concurrent(ie = 1:nelv, ii = 1:n_conn_per_elem)
1079 integer :: idx, base
1080 idx = (ie - 1) * n_conn_per_elem
1081 base = (ie - 1) * n_pts_per_elem
1082 conn(idx + ii) = base + node_order(ii)
1086 deallocate(node_order)
1088 end subroutine vtkhdf_build_connectivity
1102 subroutine vtkhdf_write_numberof(grp, dset_name, value, offset, cnt, &
1103 dcpl, index, xf_id, ierr)
1104 integer(hid_t),
intent(in) :: grp, dcpl, xf_id
1105 character(len=*),
intent(in) :: dset_name
1106 integer(kind=i8),
intent(in) :: value
1107 integer,
intent(in):: index
1108 integer(hsize_t),
dimension(1),
intent(in) :: offset, cnt
1109 integer,
intent(out) :: ierr
1111 integer(hid_t) :: dset_id, fspace, mspace
1112 integer(hsize_t),
dimension(1) :: dims, maxdims
1113 integer(hid_t) :: H5T_NEKO_INTEGER
1116 h5t_neko_integer = h5kind_to_type(i8, h5_integer_kind)
1118 call h5lexists_f(grp, dset_name, exists, ierr)
1120 call h5dopen_f(grp, dset_name, dset_id, ierr)
1121 dims(1) = int(index + 1, hsize_t) * int(pe_size, hsize_t)
1122 call h5dset_extent_f(dset_id, dims, ierr)
1124 dims(1) = int(pe_size, hsize_t)
1125 maxdims(1) = h5s_unlimited_f
1126 call h5screate_simple_f(1, dims, fspace, ierr, maxdims)
1127 call h5dcreate_f(grp, dset_name, h5t_neko_integer, &
1128 fspace, dset_id, ierr, dcpl_id = dcpl)
1129 call h5sclose_f(fspace, ierr)
1132 call h5dget_space_f(dset_id, fspace, ierr)
1133 call h5screate_simple_f(1, cnt, mspace, ierr)
1134 call h5sselect_hyperslab_f(fspace, h5s_select_set_f, offset, cnt, ierr)
1136 call h5dwrite_f(dset_id, h5t_neko_integer,
value, cnt, ierr, &
1137 file_space_id = fspace, mem_space_id = mspace, xfer_prp = xf_id)
1139 call h5sclose_f(mspace, ierr)
1140 call h5sclose_f(fspace, ierr)
1141 call h5dclose_f(dset_id, ierr)
1142 end subroutine vtkhdf_write_numberof
1151 subroutine vtkhdf_write_i8_at(grp_id, name, value, index)
1152 integer(hid_t),
intent(in) :: grp_id
1153 character(len=*),
intent(in) :: name
1154 integer(kind=i8),
intent(in) :: value
1155 integer,
intent(in) :: index
1158 integer(hid_t) :: dset_id, dcpl_id, xf_id, filespace, memspace
1159 integer(hsize_t),
dimension(1) :: dims, maxdims, count, offset, chunkdims
1160 integer(hid_t) :: H5T_NEKO_INTEGER
1163 h5t_neko_integer = h5kind_to_type(i8, h5_integer_kind)
1166 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1167 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1169 call h5lexists_f(grp_id, name, exists, ierr)
1171 call h5dopen_f(grp_id, name, dset_id, ierr)
1172 call h5dget_space_f(dset_id, filespace, ierr)
1173 call h5sget_simple_extent_dims_f(filespace, dims, maxdims, ierr)
1174 call h5sclose_f(filespace, ierr)
1176 if (int(index, hsize_t) .eq. dims(1))
then
1177 dims(1) = int(index + 1, hsize_t)
1178 call h5dset_extent_f(dset_id, dims, ierr)
1179 else if (int(index, hsize_t) .gt. dims(1))
then
1180 call neko_error(
"VTKHDF: Values written out of order.")
1184 maxdims = h5s_unlimited_f
1185 chunkdims = 1_hsize_t
1187 call h5screate_simple_f(1, dims, filespace, ierr, maxdims)
1188 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
1189 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
1190 call h5dcreate_f(grp_id, name, h5t_neko_integer, &
1191 filespace, dset_id, ierr, dcpl_id = dcpl_id)
1192 call h5sclose_f(filespace, ierr)
1193 call h5pclose_f(dcpl_id, ierr)
1197 offset = int(index, hsize_t)
1199 call h5dget_space_f(dset_id, filespace, ierr)
1200 call h5screate_simple_f(1, count, memspace, ierr)
1201 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, offset, count, ierr)
1202 call h5dwrite_f(dset_id, h5t_neko_integer,
value, count, ierr, &
1203 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
1205 call h5sclose_f(memspace, ierr)
1206 call h5sclose_f(filespace, ierr)
1207 call h5dclose_f(dset_id, ierr)
1208 call h5pclose_f(xf_id, ierr)
1210 end subroutine vtkhdf_write_i8_at
1223 subroutine write_scalar_field(hdf_root, name, x, n_local, &
1224 precision, n_total, offset)
1225 integer,
intent(in) :: n_local
1226 integer(hid_t),
intent(in) :: hdf_root
1227 character(len=*),
intent(in) :: name
1228 real(kind=rp),
dimension(n_local),
intent(in) :: x
1229 integer,
intent(in),
optional :: precision
1230 integer,
intent(in),
optional :: n_total, offset
1232 integer(hsize_t),
dimension(1) :: dims, dcount, doffset
1233 integer(hid_t) :: xf_id, dset_id, filespace, memspace, precision_hdf
1234 integer :: i, ierr, precision_local, n_tot, off
1237 dcount = int(n_local, hsize_t)
1239 if (
present(n_total))
then
1240 dims = int(n_total, hsize_t)
1242 call mpi_allreduce(n_local, n_tot, 1, mpi_integer, mpi_sum, neko_comm, &
1244 dims = int(n_tot, hsize_t)
1247 if (
present(offset))
then
1248 doffset = int(offset, hsize_t)
1250 call mpi_exscan(n_local, off, 1, mpi_integer, mpi_sum, neko_comm, &
1252 doffset = int(off, hsize_t)
1255 if (
present(precision))
then
1256 precision_local = precision
1258 precision_local = rp
1260 precision_hdf = h5kind_to_type(precision_local, h5_real_kind)
1263 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1264 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1266 call h5screate_simple_f(1, dims, filespace, ierr)
1267 call h5screate_simple_f(1, dcount, memspace, ierr)
1268 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1269 doffset, dcount, ierr)
1271 call h5dcreate_f(hdf_root, trim(name), precision_hdf, &
1272 filespace, dset_id, ierr)
1274 if (precision_local .eq. rp)
then
1275 call h5dwrite_f(dset_id, precision_hdf, x, dcount, ierr, &
1276 file_space_id = filespace, mem_space_id = memspace, &
1279 else if (precision_local .eq. sp)
then
1281 real(kind=sp),
allocatable :: x_sp(:)
1283 allocate(x_sp(n_local))
1284 do concurrent(i = 1:n_local)
1285 x_sp(i) =
real(x(i), sp)
1288 call h5dwrite_f(dset_id, precision_hdf, x_sp, dcount, ierr, &
1289 file_space_id = filespace, mem_space_id = memspace, &
1294 else if (precision_local .eq. dp)
then
1296 real(kind=dp),
allocatable :: x_dp(:)
1298 allocate(x_dp(n_local))
1299 do concurrent(i = 1:n_local)
1300 x_dp(i) =
real(x(i), dp)
1303 call h5dwrite_f(dset_id, precision_hdf, x_dp, dcount, ierr, &
1304 file_space_id = filespace, mem_space_id = memspace, &
1309 else if (precision_local .eq. qp)
then
1311 real(kind=qp),
allocatable :: x_qp(:)
1313 allocate(x_qp(n_local))
1314 do concurrent(i = 1:n_local)
1315 x_qp(i) =
real(x(i), qp)
1318 call h5dwrite_f(dset_id, precision_hdf, x_qp, dcount, ierr, &
1319 file_space_id = filespace, mem_space_id = memspace, &
1325 call neko_error(
"Unsupported precision in HDF5 write_scalar_field")
1328 call h5sclose_f(filespace, ierr)
1329 call h5sclose_f(memspace, ierr)
1330 call h5dclose_f(dset_id, ierr)
1331 call h5pclose_f(xf_id, ierr)
1332 end subroutine write_scalar_field
1347 subroutine write_vector_field(hdf_root, name, u, v, w, n_local, &
1348 precision, n_total, offset)
1349 integer,
intent(in) :: n_local
1350 integer(hid_t),
intent(in) :: hdf_root
1351 character(len=*),
intent(in) :: name
1352 real(kind=rp),
dimension(n_local),
intent(in) :: u, v, w
1353 integer,
intent(in),
optional :: precision
1354 integer,
intent(in),
optional :: n_total, offset
1356 integer(hsize_t),
dimension(2) :: dims, dcount, doffset
1357 integer(hid_t) :: xf_id, dset_id, filespace, memspace, precision_hdf
1358 integer :: i, ierr, precision_local, n_tot, off
1361 dcount = [3_hsize_t, int(n_local, hsize_t)]
1363 if (
present(n_total))
then
1364 dims = [3_hsize_t, int(n_total, hsize_t)]
1366 call mpi_allreduce(n_local, n_tot, 1, mpi_integer, mpi_sum, neko_comm, &
1368 dims = [3_hsize_t, int(n_tot, hsize_t)]
1371 if (
present(offset))
then
1372 doffset = [0_hsize_t, int(offset, hsize_t)]
1374 call mpi_exscan(n_local, off, 1, mpi_integer, mpi_sum, neko_comm, &
1376 doffset = [0_hsize_t, int(off, hsize_t)]
1379 if (
present(precision))
then
1380 precision_local = precision
1382 precision_local = rp
1384 precision_hdf = h5kind_to_type(precision_local, h5_real_kind)
1387 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1388 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1390 call h5screate_simple_f(2, dims, filespace, ierr)
1391 call h5screate_simple_f(2, dcount, memspace, ierr)
1392 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1393 doffset, dcount, ierr)
1395 call h5dcreate_f(hdf_root, trim(name), precision_hdf, filespace, dset_id, &
1398 if (precision_local .eq. rp)
then
1401 call h5dwrite_f(dset_id, precision_hdf, u, dcount, ierr, &
1402 file_space_id = filespace, mem_space_id = memspace, &
1404 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1405 [1_hsize_t, doffset(2)], [1_hsize_t, dcount(2)], ierr)
1406 call h5dwrite_f(dset_id, precision_hdf, v, dcount, ierr, &
1407 file_space_id = filespace, mem_space_id = memspace, &
1409 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1410 [2_hsize_t, doffset(2)], [1_hsize_t, dcount(2)], ierr)
1411 call h5dwrite_f(dset_id, precision_hdf, w, dcount, ierr, &
1412 file_space_id = filespace, mem_space_id = memspace, &
1414 else if (precision_local .eq. sp)
then
1416 real(kind=sp),
allocatable :: f(:,:)
1418 allocate(f(3, n_local))
1419 do concurrent(i = 1:n_local)
1420 f(1, i) =
real(u(i), sp)
1421 f(2, i) =
real(v(i), sp)
1422 f(3, i) =
real(w(i), sp)
1425 call h5dwrite_f(dset_id, precision_hdf, f, dcount, ierr, &
1426 file_space_id = filespace, mem_space_id = memspace, &
1431 else if (precision_local .eq. dp)
then
1433 real(kind=dp),
allocatable :: f(:,:)
1435 allocate(f(3, n_local))
1436 do concurrent(i = 1:n_local)
1437 f(1, i) =
real(u(i), dp)
1438 f(2, i) =
real(v(i), dp)
1439 f(3, i) =
real(w(i), dp)
1442 call h5dwrite_f(dset_id, precision_hdf, f, dcount, ierr, &
1443 file_space_id = filespace, mem_space_id = memspace, &
1448 else if (precision_local .eq. qp)
then
1450 real(kind=qp),
allocatable :: f(:,:)
1452 allocate(f(3, n_local))
1453 do concurrent(i = 1:n_local)
1454 f(1, i) =
real(u(i), qp)
1455 f(2, i) =
real(v(i), qp)
1456 f(3, i) =
real(w(i), qp)
1459 call h5dwrite_f(dset_id, precision_hdf, f, dcount, ierr, &
1460 file_space_id = filespace, mem_space_id = memspace, &
1466 call neko_error(
"Unsupported precision in HDF5 write_vector_field")
1469 call h5sclose_f(filespace, ierr)
1470 call h5sclose_f(memspace, ierr)
1471 call h5dclose_f(dset_id, ierr)
1472 call h5pclose_f(xf_id, ierr)
1473 end subroutine write_vector_field
1481 class(*),
target,
intent(inout) :: data
1482 character(len=1024) :: fname
1483 integer(hid_t) :: plist_id, file_id, vtkhdf_grp
1484 integer :: mpi_info, mpi_comm, counter, ierr
1485 type(field_list_t) :: fields
1489 fname = trim(this%get_base_fname())
1490 counter = this%get_counter() - this%get_start_counter()
1491 if (counter .lt. 0) counter = 0
1493 mpi_info = mpi_info_null%mpi_val
1494 mpi_comm = neko_comm%mpi_val
1496 call hdf5_session_init()
1497 call h5pcreate_f(h5p_file_access_f, plist_id, ierr)
1498 call h5pset_fapl_mpio_f(plist_id, mpi_comm, mpi_info, ierr)
1500 call h5fopen_f(fname, h5f_acc_rdonly_f, file_id, ierr, &
1501 access_prp = plist_id)
1502 if (ierr .ne. 0)
then
1503 call neko_error(
'Error opening VTKHDF file: ' // trim(fname))
1506 call h5gopen_f(file_id,
"VTKHDF", vtkhdf_grp, ierr)
1507 if (ierr .ne. 0)
then
1508 call h5fclose_f(file_id, ierr)
1509 call h5pclose_f(plist_id, ierr)
1510 call neko_error(
'VTKHDF group not found in file: ' // trim(fname))
1518 call fields%assign_to_field(1, data)
1519 type is (field_list_t)
1520 call fields%assign_to_list(data)
1522 call neko_error(
"Unsupported data type in vtkhdf_file_read")
1525 do i = 1, fields%size()
1526 call vtkhdf_read_field(vtkhdf_grp, fname, counter, fields%get(i))
1528 call fields%copy_from(host_to_device, .true.)
1530 call h5gclose_f(vtkhdf_grp, ierr)
1531 call h5fclose_f(file_id, ierr)
1532 call h5pclose_f(plist_id, ierr)
1533 call hdf5_session_finalize()
1548 subroutine vtkhdf_read_field(vtkhdf_grp, fname, counter, fld)
1549 integer(hid_t),
intent(in) :: vtkhdf_grp
1550 character(len=*),
intent(in) :: fname
1551 integer,
intent(in) :: counter
1552 type(field_t),
intent(inout) :: fld
1554 character(len=:),
allocatable :: field_name
1555 integer :: ierr, local_points, total_points, point_offset, component
1556 integer(hid_t) :: pointdata_grp, dset_id, filespace, memspace, xf_id
1557 integer(hid_t) :: dcpl_id, ext_file_id, ext_plist_id, attr_id
1558 integer(hid_t) :: H5T_NEKO_REAL
1559 integer(hsize_t),
dimension(1) :: dcount1, doffset1
1560 integer(hsize_t),
dimension(2) :: dcount2, doffset2
1562 integer(size_t) :: vds_count
1563 character(len=128) :: dset_name
1564 character(len=1024) :: vds_src_file, ext_fname, main_path, main_name, main_suffix
1565 logical :: exists, is_vds
1566 real(kind=rp),
allocatable :: vec_component(:,:)
1567 integer :: mpi_info, mpi_comm, pct_pos, nsteps
1568 character(len=256) :: error_message
1570 field_name = trim(fld%name)
1573 call h5lexists_f(vtkhdf_grp,
"Steps", exists, ierr)
1575 call h5aopen_by_name_f(vtkhdf_grp,
"Steps",
"NSteps", attr_id, ierr)
1576 call h5aread_f(attr_id, h5t_native_integer, nsteps, [1_hsize_t], ierr)
1577 call h5aclose_f(attr_id, ierr)
1579 if (counter .ge. nsteps)
then
1580 write(error_message,
'(A,I0,A,I0)') &
1581 'VTKHDF read: counter ', counter,
' >= NSteps ', nsteps
1582 call neko_error(trim(error_message))
1586 mpi_info = mpi_info_null%mpi_val
1587 mpi_comm = neko_comm%mpi_val
1589 local_points = fld%dof%size()
1590 total_points = fld%dof%global_size()
1592 call mpi_exscan(local_points, point_offset, 1, mpi_integer, &
1593 mpi_sum, neko_comm, ierr)
1595 h5t_neko_real = h5kind_to_type(rp, h5_real_kind)
1598 call h5gopen_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
1601 dset_name = trim(field_name)
1602 if (trim(dset_name) .eq.
'p') dset_name =
'Pressure'
1605 call h5lexists_f(pointdata_grp, trim(dset_name), exists, ierr)
1607 if (.not. exists)
then
1608 if (trim(field_name) .eq.
'u' .or. trim(field_name) .eq.
'v' .or. &
1609 trim(field_name) .eq.
'w')
then
1610 call h5lexists_f(pointdata_grp,
"Velocity", exists, ierr)
1612 dset_name =
'Velocity'
1613 select case (trim(field_name))
1625 if (.not. exists)
then
1626 call h5gclose_f(pointdata_grp, ierr)
1627 call neko_error(
'VTKHDF PointData field not found: ' // trim(dset_name))
1631 call h5dopen_f(pointdata_grp, trim(dset_name), dset_id, ierr)
1632 call h5dget_create_plist_f(dset_id, dcpl_id, ierr)
1633 call h5pget_virtual_count_f(dcpl_id, vds_count, ierr)
1634 is_vds = (vds_count .gt. 0_size_t)
1637 call filename_split(fname, main_path, main_name, main_suffix)
1643 call h5pget_virtual_filename_f(dcpl_id, 0_size_t, vds_src_file, ierr)
1644 pct_pos = index(vds_src_file,
'%b')
1646 if (pct_pos .gt. 0)
then
1651 if (vds_src_file(1:1) .eq.
'/')
then
1652 write(ext_fname,
'(A,I0,A)') &
1653 vds_src_file(1:pct_pos-1), counter, &
1654 trim(vds_src_file(pct_pos+2:))
1656 write(ext_fname,
'(A,A,I0,A)') &
1657 trim(main_path), vds_src_file(1:pct_pos-1), counter, &
1658 trim(vds_src_file(pct_pos+2:))
1664 if (int(counter, size_t) .ge. vds_count)
then
1665 call h5pclose_f(dcpl_id, ierr)
1666 call h5dclose_f(dset_id, ierr)
1667 call h5gclose_f(pointdata_grp, ierr)
1668 write(error_message,
'(A,I0,A,I0)') &
1669 'VTKHDF: VDS counter ', counter, &
1670 ' is out of range, number of mappings: ', int(vds_count)
1671 call neko_error(trim(error_message))
1673 call h5pget_virtual_filename_f(dcpl_id, int(counter, size_t), &
1675 if (vds_src_file(1:1) .eq.
'/')
then
1676 ext_fname = trim(vds_src_file)
1678 write(ext_fname,
'(A,A)') trim(main_path), trim(vds_src_file)
1682 call h5pclose_f(dcpl_id, ierr)
1683 call h5dclose_f(dset_id, ierr)
1684 call h5gclose_f(pointdata_grp, ierr)
1686 call h5pcreate_f(h5p_file_access_f, ext_plist_id, ierr)
1687 call h5pset_fapl_mpio_f(ext_plist_id, mpi_comm, mpi_info, ierr)
1688 call h5fopen_f(trim(ext_fname), h5f_acc_rdonly_f, ext_file_id, ierr, &
1689 access_prp = ext_plist_id)
1691 if (ierr .ne. 0)
then
1692 call neko_error(
'VTKHDF: Cannot open VDS source file: ' // &
1697 call h5dopen_f(ext_file_id, trim(dset_name), dset_id, ierr)
1699 call h5pclose_f(ext_plist_id, ierr)
1701 call h5pclose_f(dcpl_id, ierr)
1706 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1707 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1708 call h5dget_space_f(dset_id, filespace, ierr)
1710 if (trim(dset_name) .eq.
'Velocity' .and. component .ge. 0)
then
1712 dcount2 = [1_hsize_t, int(local_points, hsize_t)]
1713 doffset2 = [int(component, hsize_t), int(point_offset, hsize_t)]
1715 call h5screate_simple_f(2, dcount2, memspace, ierr)
1716 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1717 doffset2, dcount2, ierr)
1719 allocate(vec_component(1, local_points))
1720 call h5dread_f(dset_id, h5t_neko_real, vec_component, dcount2, ierr, &
1721 file_space_id = filespace, mem_space_id = memspace, &
1723 fld%x = reshape(vec_component, shape(fld%x))
1724 deallocate(vec_component)
1727 dcount1 = int(local_points, hsize_t)
1728 doffset1 = int(point_offset, hsize_t)
1730 call h5screate_simple_f(1, dcount1, memspace, ierr)
1731 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1732 doffset1, dcount1, ierr)
1734 call h5dread_f(dset_id, h5t_neko_real, fld%x(1,1,1,1), dcount1, ierr, &
1735 file_space_id = filespace, mem_space_id = memspace, &
1739 call h5sclose_f(memspace, ierr)
1740 call h5sclose_f(filespace, ierr)
1741 call h5dclose_f(dset_id, ierr)
1742 call h5pclose_f(xf_id, ierr)
1745 call h5fclose_f(ext_file_id, ierr)
1747 call h5gclose_f(pointdata_grp, ierr)
1750 end subroutine vtkhdf_read_field
1759 class(*),
target,
intent(in) :: data
1760 real(kind=dp),
intent(in),
optional :: t
1761 call neko_error(
'Neko needs to be built with HDF5 support')
1767 class(*),
target,
intent(inout) :: data
1768 call neko_error(
'Neko needs to be built with HDF5 support')
1785 integer,
intent(in) :: lx, ly, lz
1786 integer :: node_order(8 * (lx - 1) * (ly - 1) * (lz - 1))
1787 integer :: ii, jj, kk, idx
1794 node_order(idx + 1) = (kk - 1) * lx * ly + (jj - 1) * lx + ii - 1
1795 node_order(idx + 2) = (kk - 1) * lx * ly + (jj - 1) * lx + ii
1796 node_order(idx + 3) = (kk - 1) * lx * ly + jj * lx + ii
1797 node_order(idx + 4) = (kk - 1) * lx * ly + jj * lx + ii - 1
1798 node_order(idx + 5) = kk * lx * ly + (jj - 1) * lx + ii - 1
1799 node_order(idx + 6) = kk * lx * ly + (jj - 1) * lx + ii
1800 node_order(idx + 7) = kk * lx * ly + jj * lx + ii
1801 node_order(idx + 8) = kk * lx * ly + jj * lx + ii - 1
1817 integer,
intent(in) :: lx, ly
1818 integer :: node_order(4 * (lx - 1) * (ly - 1))
1819 integer :: ii, jj, idx
1825 node_order(idx + 1) = (jj - 1) * lx + ii - 1
1826 node_order(idx + 2) = (jj - 1) * lx + ii
1827 node_order(idx + 3) = jj * lx + ii
1828 node_order(idx + 4) = jj * lx + ii - 1
__inline__ __device__ void nonlinear_index(const int idx, const int lx, int *index)
Defines format-independent checkpoint registration and restart state.
integer, public pe_size
MPI size of communicator.
integer, public pe_rank
MPI rank.
type(mpi_comm), public neko_comm
MPI communicator.
Device abstraction, common interface for various accelerators.
integer, parameter, public host_to_device
integer, parameter, public device_to_host
Defines a mapping of the degrees of freedom.
Contains the field_serties_t type.
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.
type(log_t), public neko_log
Global log stream.
integer, parameter, public i8
integer, parameter, public qp
integer, parameter, public dp
integer, parameter, public sp
integer, parameter, public rp
Global precision used in computations.
pure integer function, public linear_index(i, j, k, l, lx, ly, lz)
Compute the address of a (i,j,k,l) array with sizes (1:lx, 1:ly, 1:lz, :)
subroutine, public filename_split(fname, path, name, suffix)
Extract file name components.
subroutine, public neko_warning(warning_msg)
Reports a warning to standard output.
recursive subroutine, public mkdir(path, mode)
Recursively create a directory and all parent directories if they do not exist. This should be safer ...
VTK Module containing utilities for VTK file handling.
integer function, dimension(:), allocatable, public vtk_ordering(cell_type, lx, ly, lz)
Get the VTK node ordering for a given cell type. For Lagrange cells, returns an array mapping VTK nod...
subroutine vtkhdf_file_set_overwrite(this, overwrite)
Set the overwrite flag for HDF5 files.
subroutine vtkhdf_file_enable_amr(this)
Enable support for Adaptive Mesh Refinement.
character(len=1024) function vtkhdf_file_get_next_output_fname(this)
Get the physical file name generated by the next write.
subroutine vtkhdf_file_set_precision(this, precision)
Set the precision for VTKHDF output (single or double)
subroutine vtkhdf_file_write(this, data, t)
Write data in HDF5 format (no HDF5 support)
pure integer function, dimension(8 *(lx - 1) *(ly - 1) *(lz - 1)) subdivide_to_hex_ordering(lx, ly, lz)
Build linear hexahedron sub-cell node ordering for a spectral element. Returns an array of 0-based te...
integer, dimension(2), parameter vtkhdf_version
subroutine vtkhdf_file_set_subdivide(this, subdivide)
Enable or disable subdivision of spectral elements into linear sub-cells. When subdivision is enabled...
subroutine vtkhdf_file_read(this, data)
Read data in HDF5 format (no HDF5 support)
character(len=1024) function vtkhdf_file_get_fname(this)
Return the file name with the start counter.
pure integer function, dimension(4 *(lx - 1) *(ly - 1)) subdivide_to_quad_ordering(lx, ly)
Build linear quadrilateral sub-cell node ordering for a spectral element. Returns an array of 0-based...
Collection of live simulation data registered for checkpointing.
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 ...
Interface for HDF5 files.