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
54 hid_t, hsize_t, size_t, &
55 h5open_f, h5close_f, &
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
106 logical,
intent(in) :: overwrite
107 this%overwrite = overwrite
113 this%amr_enabled = .false.
119 integer,
intent(in) :: precision
120 this%precision = precision
126 character(len=1024) :: base_fname
127 character(len=1024) :: fname
128 character(len=1024) :: path, name, suffix
130 fname = trim(this%get_base_fname())
133 write(base_fname,
'(A,A,"_",I0,A)') &
134 trim(path), trim(name), this%get_start_counter(), trim(suffix)
145 logical,
intent(in) :: subdivide
146 this%subdivide = subdivide
157 class(*),
target,
intent(in) :: data
158 real(kind=
rp),
intent(in),
optional :: t
159 type(
mesh_t),
pointer :: msh
162 integer :: ierr, mpi_info, mpi_comm, i, n_fields
163 integer(hid_t) :: plist_id, file_id, attr_id, vtkhdf_grp
164 integer(hid_t) :: filespace, H5T_NEKO_STRING
165 integer(hsize_t),
dimension(1) :: vdims
166 integer(size_t) :: type_len
167 integer :: lx, ly, lz
168 integer :: local_points, local_cells, local_conn
169 integer :: total_points, total_cells, total_conn
170 integer :: point_offset
171 integer :: max_local_points
172 integer,
allocatable :: part_points(:), part_cells(:), part_conns(:)
173 character(len=1024) :: fname
174 character(len=16) :: type_str
188 call fields%assign_to_field(1, data)
192 call fields%assign_to_list(data)
194 call neko_error(
'Invalid data type for vtkhdf_file_write')
198 if (.not.
associated(msh))
then
199 call neko_error(
'Mesh must be associated for vtkhdf_file_write')
201 if (dof%Xh%lx .lt. 2 .or. dof%Xh%ly .lt. 2)
then
202 call neko_error(
'VTKHDF linear output requires lx, ly >= 2')
204 if (msh%gdim .eq. 3 .and. dof%Xh%lz .lt. 2)
then
205 call neko_error(
'VTKHDF linear output requires lz >= 2 in 3D')
207 if (msh%gdim .lt. 2 .or. msh%gdim .gt. 3)
then
208 call neko_error(
'VTKHDF output only supports 2D and 3D meshes')
212 if (this%precision .gt.
rp)
then
214 call neko_warning(
'Requested precision is higher than working precision')
215 else if (this%precision .eq. -1)
then
219 call this%increment_counter()
220 fname = trim(this%get_vtkhdf_fname())
221 counter = this%get_counter() - this%get_start_counter()
223 mpi_info = mpi_info_null%mpi_val
227 call h5pcreate_f(h5p_file_access_f, plist_id, ierr)
228 call h5pset_fapl_mpio_f(plist_id, mpi_comm, mpi_info, ierr)
230 if (counter .eq. 0)
then
232 call h5fcreate_f(fname, h5f_acc_trunc_f, &
233 file_id, ierr, access_prp = plist_id)
235 call h5fopen_f(fname, h5f_acc_rdwr_f, file_id, ierr, &
236 access_prp = plist_id)
240 call h5lexists_f(file_id,
"VTKHDF", exists, ierr)
242 call h5gopen_f(file_id,
"VTKHDF", vtkhdf_grp, ierr)
244 call h5gcreate_f(file_id,
"VTKHDF", vtkhdf_grp, ierr)
248 call h5screate_simple_f(1, vdims, filespace, ierr)
249 call h5acreate_f(vtkhdf_grp,
"Version", h5t_native_integer, filespace, &
251 call h5awrite_f(attr_id, h5t_native_integer,
vtkhdf_version, vdims, ierr)
252 call h5aclose_f(attr_id, ierr)
253 call h5sclose_f(filespace, ierr)
256 type_str =
"UnstructuredGrid"
257 type_len = int(len_trim(type_str), kind=size_t)
259 call h5screate_f(h5s_scalar_f, filespace, ierr)
261 call h5tcopy_f(h5t_fortran_s1, h5t_neko_string, ierr)
262 call h5tset_size_f(h5t_neko_string, type_len, ierr)
263 call h5tset_strpad_f(h5t_neko_string, h5t_str_nullterm_f, ierr)
265 call h5acreate_f(vtkhdf_grp,
"Type", h5t_neko_string, filespace, &
267 call h5awrite_f(attr_id, h5t_neko_string, [type_str], vdims, ierr)
268 call h5aclose_f(attr_id, ierr)
270 call h5tclose_f(h5t_neko_string, ierr)
271 call h5sclose_f(filespace, ierr)
275 call vtkhdf_write_steps(vtkhdf_grp, counter, t)
278 if (
associated(msh))
then
279 call vtkhdf_write_mesh(vtkhdf_grp, dof, msh, &
280 this%amr_enabled, counter, this%subdivide, t)
284 if (fields%size() .gt. 0)
then
285 call vtkhdf_write_pointdata(vtkhdf_grp, fields, this%precision, &
289 call h5gclose_f(vtkhdf_grp, ierr)
290 call h5pclose_f(plist_id, ierr)
296 integer(size_t) :: obj_count
297 character(len=80) :: wrn_buf
298 call h5fget_obj_count_f(file_id, h5f_obj_all_f, obj_count, ierr)
299 if (obj_count .gt. 1_size_t .and.
pe_rank .eq. 0)
then
300 write(wrn_buf,
'(A,I0,A)')
'VTKHDF: ', obj_count - 1, &
301 ' HDF5 id(s) still open at file close'
305 call h5fflush_f(file_id, h5f_scope_global_f, ierr)
306 call h5fclose_f(file_id, ierr)
325 subroutine vtkhdf_write_mesh(vtkhdf_grp, dof, msh, amr, counter, subdivide, t)
326 type(dofmap_t),
intent(in) :: dof
327 type(mesh_t),
intent(in) :: msh
328 integer(hid_t),
intent(in) :: vtkhdf_grp
329 logical,
intent(in) :: amr
330 integer,
intent(in) :: counter
331 logical,
intent(in) :: subdivide
332 real(kind=rp),
intent(in),
optional :: t
334 integer(kind=1) :: VTK_cell_type
335 integer :: ierr, i, ii, jj, kk, el, local_idx
336 integer :: lx, ly, lz, npts_per_cell, nodes_per_cell, cells_per_element
337 integer :: local_points, local_cells, local_conn
338 integer :: total_points, total_cells, total_conn
339 integer :: point_offset, max_local_points
340 integer :: total_offsets, cell_offset, conn_offset, offsets_offset
341 integer :: max_local_cells, max_local_conn
342 integer(hid_t) :: xf_id, dset_id, dcpl_id, grp_id, attr_id
343 integer(hid_t) :: filespace, memspace, H5T_NEKO_DOUBLE
344 integer(hsize_t),
dimension(1) :: dcount, vdims, maxdims, doffset, chunkdims
345 integer(hsize_t),
dimension(2) :: dcount2, vdims2, maxdims2, doffset2
346 integer(kind=i8) :: i8_value
348 integer,
dimension(3) :: component_sizes
349 integer,
dimension(3) :: component_offsets
350 integer,
dimension(3) :: component_max_sizes
356 if (subdivide .and. msh%gdim .eq. 3)
then
357 vtk_cell_type = int(12, kind=1)
358 cells_per_element = (lx - 1) * (ly - 1) * (lz - 1)
360 else if (subdivide .and. msh%gdim .eq. 2)
then
361 vtk_cell_type = int(9, kind=1)
362 cells_per_element = (lx - 1) * (ly - 1)
364 else if (msh%gdim .eq. 3)
then
365 vtk_cell_type = int(72, kind=1)
366 cells_per_element = 1
367 nodes_per_cell = lx * ly * lz
368 else if (msh%gdim .eq. 2)
then
369 vtk_cell_type = int(70, kind=1)
370 cells_per_element = 1
371 nodes_per_cell = lx * ly
375 local_points = dof%size()
376 local_cells = msh%nelv * cells_per_element
377 local_conn = local_cells * nodes_per_cell
379 total_points = dof%global_size()
380 total_cells = msh%glb_nelv * cells_per_element
381 total_conn = total_cells * nodes_per_cell
383 component_sizes = [local_points, local_cells, local_conn]
384 component_offsets = 0
385 component_max_sizes = 0
387 call mpi_exscan(component_sizes, component_offsets, 3, mpi_integer, &
388 mpi_sum, neko_comm, ierr)
389 call mpi_allreduce(component_sizes, component_max_sizes, 3, mpi_integer, &
390 mpi_max, neko_comm, ierr)
392 point_offset = component_offsets(1)
393 cell_offset = component_offsets(2)
394 conn_offset = component_offsets(3)
395 max_local_points = component_max_sizes(1)
396 max_local_cells = component_max_sizes(2)
397 max_local_conn = component_max_sizes(3)
399 offsets_offset = cell_offset + pe_rank
400 total_offsets = total_cells + pe_size
403 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
404 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
412 integer(hsize_t),
dimension(1) :: nof_dims, nof_maxdims
413 integer(hsize_t),
dimension(1) :: nof_count, nof_offset, nof_chunk
414 integer(hid_t) :: nof_filespace, nof_memspace, nof_dcpl
415 integer(kind=i8) :: nof_values(3)
417 nof_count(1) = 1_hsize_t
418 nof_offset(1) = int(counter, hsize_t) * int(pe_size, hsize_t) &
419 + int(pe_rank, hsize_t)
420 nof_chunk(1) =
max(1_hsize_t, int(pe_size, hsize_t))
421 nof_values = [int(local_points, kind=i8), int(local_cells, kind=i8), &
422 int(local_conn, kind=i8)]
424 call h5pcreate_f(h5p_dataset_create_f, nof_dcpl, ierr)
425 call h5pset_chunk_f(nof_dcpl, 1, nof_chunk, ierr)
427 call vtkhdf_write_numberof(vtkhdf_grp,
"NumberOfPoints", &
428 nof_values(1), nof_offset, nof_count, nof_dcpl, &
429 counter, xf_id, ierr)
430 call vtkhdf_write_numberof(vtkhdf_grp,
"NumberOfCells", &
431 nof_values(2), nof_offset, nof_count, nof_dcpl, &
432 counter, xf_id, ierr)
433 call vtkhdf_write_numberof(vtkhdf_grp,
"NumberOfConnectivityIds", &
434 nof_values(3), nof_offset, nof_count, nof_dcpl, &
435 counter, xf_id, ierr)
437 call h5pclose_f(nof_dcpl, ierr)
441 call h5lexists_f(vtkhdf_grp,
"Points", exists, ierr)
442 if (.not. exists)
then
444 vdims2 = [3_hsize_t, int(total_points, hsize_t)]
445 maxdims2 = [3_hsize_t, h5s_unlimited_f]
446 chunkdims(1) = int(
max(1, min(max_local_points, total_points)), hsize_t)
447 dcount2 = [3_hsize_t, int(local_points, hsize_t)]
448 doffset2 = [0_hsize_t, int(point_offset, hsize_t)]
449 h5t_neko_double = h5kind_to_type(dp, h5_real_kind)
451 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
452 call h5screate_simple_f(2, dcount2, memspace, ierr)
453 call h5screate_simple_f(2, vdims2, filespace, ierr, maxdims2)
455 call h5pset_chunk_f(dcpl_id, 2, [3_hsize_t, chunkdims(1)], ierr)
456 call h5dcreate_f(vtkhdf_grp,
"Points", h5t_neko_double, &
457 filespace, dset_id, ierr, dcpl_id = dcpl_id)
458 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
459 doffset2, dcount2, ierr)
462 real(kind=dp),
allocatable :: coords(:,:)
464 allocate(coords(3, local_points))
465 do concurrent(local_idx = 1:local_points)
468 real(kind=dp) :: x, y, z
471 x =
real(dof%x(idx(1), idx(2), idx(3), idx(4)), dp)
472 y =
real(dof%y(idx(1), idx(2), idx(3), idx(4)), dp)
473 z =
real(dof%z(idx(1), idx(2), idx(3), idx(4)), dp)
475 coords(1, local_idx) = x
476 coords(2, local_idx) = y
477 coords(3, local_idx) = z
480 call h5dwrite_f(dset_id, h5t_neko_double, coords, dcount2, ierr, &
481 file_space_id = filespace, mem_space_id = memspace, &
486 call h5dclose_f(dset_id, ierr)
487 call h5sclose_f(filespace, ierr)
488 call h5sclose_f(memspace, ierr)
489 call h5pclose_f(dcpl_id, ierr)
493 call h5lexists_f(vtkhdf_grp,
"Connectivity", exists, ierr)
494 if (exists)
call h5ldelete_f(vtkhdf_grp,
"Connectivity", ierr)
496 vdims = int(total_conn, hsize_t)
497 maxdims = h5s_unlimited_f
498 chunkdims = int(
max(1, min(max_local_conn, total_conn)), hsize_t)
499 dcount = int(local_conn, hsize_t)
500 doffset = int(conn_offset, hsize_t)
502 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
503 call h5screate_simple_f(1, dcount, memspace, ierr)
504 call h5screate_simple_f(1, vdims, filespace, ierr, maxdims)
506 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
507 call h5dcreate_f(vtkhdf_grp,
"Connectivity", h5t_native_integer, &
508 filespace, dset_id, ierr, dcpl_id = dcpl_id)
509 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
510 doffset, dcount, ierr)
513 integer,
allocatable :: connectivity(:)
515 allocate(connectivity(local_conn))
516 call vtkhdf_build_connectivity(connectivity, vtk_cell_type, msh, dof, &
518 call h5dwrite_f(dset_id, h5t_native_integer, connectivity, dcount, &
519 ierr, file_space_id = filespace, mem_space_id = memspace, &
521 deallocate(connectivity)
524 call h5dclose_f(dset_id, ierr)
525 call h5sclose_f(filespace, ierr)
526 call h5sclose_f(memspace, ierr)
527 call h5pclose_f(dcpl_id, ierr)
530 call h5lexists_f(vtkhdf_grp,
"Offsets", exists, ierr)
531 if (exists)
call h5ldelete_f(vtkhdf_grp,
"Offsets", ierr)
533 vdims = int(total_offsets, hsize_t)
534 maxdims = h5s_unlimited_f
535 chunkdims = int(
max(1, min(max_local_cells + 1, total_offsets)), hsize_t)
536 dcount = int(local_cells + 1, hsize_t)
537 doffset = int(offsets_offset, hsize_t)
539 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
540 call h5screate_simple_f(1, dcount, memspace, ierr)
541 call h5screate_simple_f(1, vdims, filespace, ierr, maxdims)
543 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
544 call h5dcreate_f(vtkhdf_grp,
"Offsets", h5t_native_integer, &
545 filespace, dset_id, ierr, dcpl_id = dcpl_id)
546 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
547 doffset, dcount, ierr)
550 integer,
allocatable :: offsets(:)
552 allocate(offsets(local_cells + 1))
553 do concurrent(i = 1:local_cells)
554 offsets(i) = (i - 1) * nodes_per_cell
556 offsets(local_cells + 1) = local_conn
557 call h5dwrite_f(dset_id, h5t_native_integer, offsets, dcount, ierr, &
558 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
562 call h5dclose_f(dset_id, ierr)
563 call h5sclose_f(filespace, ierr)
564 call h5sclose_f(memspace, ierr)
565 call h5pclose_f(dcpl_id, ierr)
568 call h5lexists_f(vtkhdf_grp,
"Types", exists, ierr)
569 if (exists)
call h5ldelete_f(vtkhdf_grp,
"Types", ierr)
571 vdims = int(total_cells, hsize_t)
572 maxdims = h5s_unlimited_f
573 chunkdims = int(
max(1, min(max_local_cells, total_cells)), hsize_t)
574 dcount = int(local_cells, hsize_t)
575 doffset = int(cell_offset, hsize_t)
577 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
578 call h5screate_simple_f(1, dcount, memspace, ierr)
579 call h5screate_simple_f(1, vdims, filespace, ierr, maxdims)
581 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
582 call h5dcreate_f(vtkhdf_grp,
"Types", h5t_std_u8le, &
583 filespace, dset_id, ierr, dcpl_id = dcpl_id)
584 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
585 doffset, dcount, ierr)
588 integer(kind=1),
allocatable :: cell_types(:)
589 allocate(cell_types(local_cells), source=vtk_cell_type)
590 call h5dwrite_f(dset_id, h5t_std_u8le, cell_types, dcount, ierr, &
591 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
592 deallocate(cell_types)
595 call h5dclose_f(dset_id, ierr)
596 call h5sclose_f(filespace, ierr)
597 call h5sclose_f(memspace, ierr)
598 call h5pclose_f(dcpl_id, ierr)
602 call h5gopen_f(vtkhdf_grp,
"Steps", grp_id, ierr)
605 call vtkhdf_write_i8_at(grp_id,
"NumberOfParts", int(pe_size, kind=i8), &
611 i8_value = int(counter - 1, kind=i8) * int(pe_size, kind=i8)
612 call vtkhdf_write_i8_at(grp_id,
"PartOffsets", i8_value, counter)
614 i8_value = int(counter - 1, kind=i8) * int(total_points, kind=i8)
615 call vtkhdf_write_i8_at(grp_id,
"PointOffsets", i8_value, counter)
617 i8_value = int(counter - 1, kind=i8) * int(total_cells, kind=i8)
618 call vtkhdf_write_i8_at(grp_id,
"CellOffsets", i8_value, counter)
620 i8_value = int(counter - 1, kind=i8) * int(total_conn, kind=i8)
621 call vtkhdf_write_i8_at(grp_id,
"ConnectivityIdOffsets", i8_value, &
626 call vtkhdf_write_i8_at(grp_id,
"PartOffsets", i8_value, counter)
627 call vtkhdf_write_i8_at(grp_id,
"PointOffsets", i8_value, counter)
628 call vtkhdf_write_i8_at(grp_id,
"CellOffsets", i8_value, counter)
629 call vtkhdf_write_i8_at(grp_id,
"ConnectivityIdOffsets", i8_value, &
633 call h5gclose_f(grp_id, ierr)
636 call h5pclose_f(xf_id, ierr)
638 end subroutine vtkhdf_write_mesh
646 subroutine vtkhdf_write_steps(vtkhdf_grp, counter, t)
647 integer(hid_t),
intent(in) :: vtkhdf_grp
648 integer,
intent(in) :: counter
649 real(kind=rp),
intent(in) :: t
651 integer(hid_t) :: xf_id, H5T_NEKO_DOUBLE
653 integer(hid_t) :: grp_id, dset_id, dcpl_id, filespace, memspace, attr_id
654 integer(hsize_t),
dimension(1) :: step_dims, step_maxdims
655 integer(hsize_t),
dimension(1) :: step_count, step_offset, chunkdims, ddim
656 real(kind=dp),
dimension(1) :: time_value
657 integer(kind=i8) :: i8_value
658 logical :: exists, attr_exists
661 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
662 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
663 h5t_neko_double = h5kind_to_type(dp, h5_real_kind)
666 call h5lexists_f(vtkhdf_grp,
"Steps", exists, ierr)
668 call h5gopen_f(vtkhdf_grp,
"Steps", grp_id, ierr)
670 call h5gcreate_f(vtkhdf_grp,
"Steps", grp_id, ierr)
674 call h5lexists_f(grp_id,
"Values", exists, ierr)
676 call h5dopen_f(grp_id,
"Values", dset_id, ierr)
677 call h5dget_space_f(dset_id, filespace, ierr)
678 call h5sget_simple_extent_dims_f(filespace, step_dims, step_maxdims, &
680 call h5sclose_f(filespace, ierr)
683 if (step_dims(1) .eq. int(counter, hsize_t))
then
684 step_dims(1) = int(counter + 1, hsize_t)
685 call h5dset_extent_f(dset_id, step_dims, ierr)
686 else if (step_dims(1) .lt. int(counter, hsize_t))
then
687 call neko_error(
"VTKHDF: Time steps written out of order.")
690 step_dims(1) = 1_hsize_t
691 step_maxdims(1) = h5s_unlimited_f
692 chunkdims(1) = 1_hsize_t
694 call h5screate_simple_f(1, step_dims, filespace, ierr, step_maxdims)
695 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
696 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
697 call h5dcreate_f(grp_id,
"Values", h5t_neko_double, &
698 filespace, dset_id, ierr, dcpl_id = dcpl_id)
699 call h5sclose_f(filespace, ierr)
700 call h5pclose_f(dcpl_id, ierr)
703 step_count(1) = 1_hsize_t
704 step_offset(1) = int(counter, hsize_t)
706 call h5dget_space_f(dset_id, filespace, ierr)
707 call h5screate_simple_f(1, step_count, memspace, ierr)
708 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
709 step_offset, step_count, ierr)
711 time_value(1) =
real(t, kind=dp)
712 call h5dwrite_f(dset_id, h5t_neko_double, time_value, step_count, ierr, &
713 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
715 call h5sclose_f(memspace, ierr)
716 call h5sclose_f(filespace, ierr)
717 call h5dclose_f(dset_id, ierr)
721 call h5aexists_f(grp_id,
"NSteps", attr_exists, ierr)
722 if (attr_exists)
then
723 call h5aopen_f(grp_id,
"NSteps", attr_id, ierr)
725 call h5screate_f(h5s_scalar_f, filespace, ierr)
726 call h5acreate_f(grp_id,
"NSteps", h5t_native_integer, filespace, &
727 attr_id, ierr, h5p_default_f, h5p_default_f)
728 call h5sclose_f(filespace, ierr)
731 call h5awrite_f(attr_id, h5t_native_integer, counter + 1, ddim, ierr)
733 call h5aclose_f(attr_id, ierr)
734 call h5gclose_f(grp_id, ierr)
735 call h5pclose_f(xf_id, ierr)
737 end subroutine vtkhdf_write_steps
753 subroutine vtkhdf_write_pointdata(vtkhdf_grp, fields, precision, counter, &
755 integer(hid_t),
intent(in) :: vtkhdf_grp
756 type(field_list_t),
intent(inout) :: fields
757 integer,
intent(in) :: precision
758 integer,
intent(in) :: counter
759 character(len=*),
intent(in) :: fname
760 real(kind=rp),
intent(in),
optional :: t
762 integer(kind=i8) :: time_offset
763 integer :: local_points, point_offset, total_points
764 integer(hid_t) :: precision_hdf
765 integer :: ierr, i, j
767 integer(hid_t) :: pointdata_grp, grp_id, step_grp_id
768 integer(hid_t) :: dset_id, dcpl_id, filespace
769 integer(hsize_t),
dimension(1) :: pd_dims1, pd_maxdims1
770 integer(hsize_t),
dimension(2) :: pd_dims2, pd_maxdims2
771 type(field_t),
pointer :: u, v, w
772 character(len=128) :: field_name
773 logical :: exists, is_vector
776 character(len=1024) :: ext_fname, ext_path, src_pattern
777 character(len=1024) :: main_path, main_name, main_suffix
778 integer(hid_t) :: ext_file_id, ext_plist_id, vds_src_space
779 integer(hid_t) :: write_target, attr_id, H5T_NEKO_STRING
780 integer :: mpi_info, mpi_comm
783 integer :: fields_written
784 character(len=128),
allocatable :: name_list(:)
785 logical,
allocatable :: vector_list(:)
787 mpi_info = mpi_info_null%mpi_val
788 mpi_comm = neko_comm%mpi_val
790 n_fields = fields%size()
793 local_points = fields%item_size(1)
794 total_points = fields%items(1)%ptr%dof%global_size()
796 call mpi_exscan(local_points, point_offset, 1, mpi_integer, &
797 mpi_sum, neko_comm, ierr)
801 if (
associated(fields%items(i)%ptr))
then
802 call fields%items(i)%ptr%copy_from(device_to_host, sync = i .eq. n_fields)
807 allocate(name_list(n_fields))
811 call h5lexists_f(vtkhdf_grp,
"PointData", exists, ierr)
812 if (.not. exists)
then
813 call h5gcreate_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
814 call h5gclose_f(pointdata_grp, ierr)
823 call filename_split(fname, main_path, main_name, main_suffix)
824 write(ext_path,
'(A,A,".data/")') trim(main_path), trim(main_name)
825 write(ext_fname,
'(A,I0,".h5")') trim(ext_path), counter
826 write(src_pattern,
'(A,".data/%b.h5")') trim(main_name)
828 if (pe_rank .eq. 0)
then
829 call mkdir(trim(ext_path))
831 call mpi_barrier(neko_comm, ierr)
833 call h5pcreate_f(h5p_file_access_f, ext_plist_id, ierr)
834 call h5pset_fapl_mpio_f(ext_plist_id, mpi_comm, mpi_info, ierr)
835 call h5fcreate_f(trim(ext_fname), h5f_acc_trunc_f, write_target, ierr, &
836 access_prp = ext_plist_id)
837 call h5pclose_f(ext_plist_id, ierr)
841 call h5gopen_f(vtkhdf_grp,
"PointData", write_target, ierr)
848 field_name = fields%name(i)
849 if (field_name .eq.
'p') field_name =
'Pressure'
853 if (field_name .eq.
'u' .or. field_name .eq.
'v' .or. &
854 field_name .eq.
'w')
then
859 select case (trim(fields%name(j)))
869 if (
associated(u) .and.
associated(v) .and.
associated(w))
then
871 field_name =
'Velocity'
878 do j = 1, fields_written
879 if (trim(name_list(j)) .eq. trim(field_name))
then
889 fields_written = fields_written + 1
890 name_list(fields_written) = field_name
895 call write_vector_field(write_target, field_name, u%x, v%x, w%x, &
896 local_points, precision, total_points, point_offset)
898 call write_scalar_field(write_target, field_name, fields%x(i), &
899 local_points, precision, total_points, point_offset)
905 call h5fclose_f(write_target, ierr)
907 call h5gclose_f(write_target, ierr)
916 call h5gopen_f(vtkhdf_grp,
"Steps", step_grp_id, ierr)
917 time_offset = int(counter, kind=i8) * int(total_points, kind=i8)
920 call h5lexists_f(step_grp_id,
"PointDataOffsets", exists, ierr)
922 call h5gopen_f(step_grp_id,
"PointDataOffsets", grp_id, ierr)
924 call h5gcreate_f(step_grp_id,
"PointDataOffsets", grp_id, ierr)
926 do i = 1, fields_written
927 call vtkhdf_write_i8_at(grp_id, trim(name_list(i)), &
928 time_offset, counter)
930 call h5gclose_f(grp_id, ierr)
931 call h5gclose_f(step_grp_id, ierr)
934 call h5gopen_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
936 do i = 1, fields_written
937 field_name = name_list(i)
940 if (counter .eq. 0)
then
942 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
943 precision_hdf = h5kind_to_type(precision, h5_real_kind)
946 pd_dims2 = [3_hsize_t, int(total_points, hsize_t)]
947 call h5screate_simple_f(2, pd_dims2, vds_src_space, ierr)
948 call h5sselect_all_f(vds_src_space, ierr)
950 pd_maxdims2 = [3_hsize_t, h5s_unlimited_f]
951 call h5screate_simple_f(2, pd_dims2, filespace, ierr, &
954 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
955 [0_hsize_t, 0_hsize_t], &
956 [1_hsize_t, h5s_unlimited_f], &
958 stride = [3_hsize_t, int(total_points, hsize_t)], &
959 block = [3_hsize_t, int(total_points, hsize_t)])
961 call h5pset_virtual_f(dcpl_id, filespace, trim(src_pattern), &
962 trim(field_name), vds_src_space, ierr)
963 call h5sclose_f(vds_src_space, ierr)
965 call h5dcreate_f(pointdata_grp, trim(field_name), &
966 precision_hdf, filespace, dset_id, ierr, &
968 call h5sclose_f(filespace, ierr)
970 pd_dims1 = int(total_points, hsize_t)
971 call h5screate_simple_f(1, pd_dims1, vds_src_space, ierr)
972 call h5sselect_all_f(vds_src_space, ierr)
974 pd_maxdims1(1) = h5s_unlimited_f
975 call h5screate_simple_f(1, pd_dims1, filespace, ierr, &
978 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
982 stride = [int(total_points, hsize_t)], &
983 block = [int(total_points, hsize_t)])
985 call h5pset_virtual_f(dcpl_id, filespace, trim(src_pattern), &
986 trim(field_name), vds_src_space, ierr)
987 call h5sclose_f(vds_src_space, ierr)
989 call h5dcreate_f(pointdata_grp, trim(field_name), &
990 precision_hdf, filespace, dset_id, ierr, &
992 call h5sclose_f(filespace, ierr)
995 call h5pclose_f(dcpl_id, ierr)
996 call h5dclose_f(dset_id, ierr)
1000 call h5dopen_f(pointdata_grp, trim(field_name), dset_id, ierr)
1003 pd_dims2 = [3_hsize_t, &
1004 int(counter + 1, hsize_t) * int(total_points, hsize_t)]
1005 call h5dset_extent_f(dset_id, pd_dims2, ierr)
1007 pd_dims1 = int(counter + 1, hsize_t) * int(total_points, hsize_t)
1008 call h5dset_extent_f(dset_id, pd_dims1, ierr)
1011 call h5dclose_f(dset_id, ierr)
1015 call h5gclose_f(pointdata_grp, ierr)
1021 do i = 1, fields_written
1022 field_name = name_list(i)
1024 pd_dims1 = 1_hsize_t
1026 call h5gopen_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
1027 call h5dopen_f(pointdata_grp, trim(field_name), dset_id, ierr)
1029 call h5aexists_f(dset_id,
"Attribute", exists, ierr)
1031 call h5dclose_f(dset_id, ierr)
1032 call h5gclose_f(pointdata_grp, ierr)
1037 call h5screate_f(h5s_scalar_f, filespace, ierr)
1039 call h5tcopy_f(h5t_fortran_s1, h5t_neko_string, ierr)
1040 call h5tset_size_f(h5t_neko_string, int(6, size_t), ierr)
1041 call h5tset_strpad_f(h5t_neko_string, h5t_str_nullterm_f, ierr)
1043 call h5acreate_f(dset_id,
"Attribute", h5t_neko_string, filespace, &
1046 call h5awrite_f(attr_id, h5t_neko_string, [
"Vector"], pd_dims1, ierr)
1048 call h5awrite_f(attr_id, h5t_neko_string, [
"Scalar"], pd_dims1, ierr)
1051 call h5aclose_f(attr_id, ierr)
1052 call h5tclose_f(h5t_neko_string, ierr)
1053 call h5sclose_f(filespace, ierr)
1054 call h5dclose_f(dset_id, ierr)
1055 call h5gclose_f(pointdata_grp, ierr)
1062 deallocate(name_list)
1065 end subroutine vtkhdf_write_pointdata
1082 subroutine vtkhdf_build_connectivity(conn, vtk_type, msh, dof, subdivide)
1083 integer,
intent(inout) :: conn(:)
1084 integer(kind=1),
intent(in) :: vtk_type
1085 type(mesh_t),
intent(in) :: msh
1086 type(dofmap_t),
intent(in) :: dof
1087 logical,
intent(in) :: subdivide
1088 integer :: lx, ly, lz, nelv
1089 integer :: ie, ii, n_pts_per_elem, n_conn_per_elem
1090 integer,
allocatable :: node_order(:)
1096 n_pts_per_elem = lx * ly * lz
1098 if (subdivide .and. vtk_type .eq. int(12, kind=1))
then
1100 else if (subdivide .and. vtk_type .eq. int(9, kind=1))
then
1103 node_order = vtk_ordering(vtk_type, lx, ly, lz)
1106 n_conn_per_elem =
size(node_order)
1108 do concurrent(ie = 1:nelv, ii = 1:n_conn_per_elem)
1110 integer :: idx, base
1111 idx = (ie - 1) * n_conn_per_elem
1112 base = (ie - 1) * n_pts_per_elem
1113 conn(idx + ii) = base + node_order(ii)
1117 deallocate(node_order)
1119 end subroutine vtkhdf_build_connectivity
1133 subroutine vtkhdf_write_numberof(grp, dset_name, value, offset, cnt, &
1134 dcpl, index, xf_id, ierr)
1135 integer(hid_t),
intent(in) :: grp, dcpl, xf_id
1136 character(len=*),
intent(in) :: dset_name
1137 integer(kind=i8),
intent(in) :: value
1138 integer,
intent(in):: index
1139 integer(hsize_t),
dimension(1),
intent(in) :: offset, cnt
1140 integer,
intent(out) :: ierr
1142 integer(hid_t) :: dset_id, fspace, mspace
1143 integer(hsize_t),
dimension(1) :: dims, maxdims
1144 integer(hid_t) :: H5T_NEKO_INTEGER
1147 h5t_neko_integer = h5kind_to_type(i8, h5_integer_kind)
1149 call h5lexists_f(grp, dset_name, exists, ierr)
1151 call h5dopen_f(grp, dset_name, dset_id, ierr)
1152 dims(1) = int(index + 1, hsize_t) * int(pe_size, hsize_t)
1153 call h5dset_extent_f(dset_id, dims, ierr)
1155 dims(1) = int(pe_size, hsize_t)
1156 maxdims(1) = h5s_unlimited_f
1157 call h5screate_simple_f(1, dims, fspace, ierr, maxdims)
1158 call h5dcreate_f(grp, dset_name, h5t_neko_integer, &
1159 fspace, dset_id, ierr, dcpl_id = dcpl)
1160 call h5sclose_f(fspace, ierr)
1163 call h5dget_space_f(dset_id, fspace, ierr)
1164 call h5screate_simple_f(1, cnt, mspace, ierr)
1165 call h5sselect_hyperslab_f(fspace, h5s_select_set_f, offset, cnt, ierr)
1167 call h5dwrite_f(dset_id, h5t_neko_integer,
value, cnt, ierr, &
1168 file_space_id = fspace, mem_space_id = mspace, xfer_prp = xf_id)
1170 call h5sclose_f(mspace, ierr)
1171 call h5sclose_f(fspace, ierr)
1172 call h5dclose_f(dset_id, ierr)
1173 end subroutine vtkhdf_write_numberof
1182 subroutine vtkhdf_write_i8_at(grp_id, name, value, index)
1183 integer(hid_t),
intent(in) :: grp_id
1184 character(len=*),
intent(in) :: name
1185 integer(kind=i8),
intent(in) :: value
1186 integer,
intent(in) :: index
1189 integer(hid_t) :: dset_id, dcpl_id, xf_id, filespace, memspace
1190 integer(hsize_t),
dimension(1) :: dims, maxdims, count, offset, chunkdims
1191 integer(hid_t) :: H5T_NEKO_INTEGER
1194 h5t_neko_integer = h5kind_to_type(i8, h5_integer_kind)
1197 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1198 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1200 call h5lexists_f(grp_id, name, exists, ierr)
1202 call h5dopen_f(grp_id, name, dset_id, ierr)
1203 call h5dget_space_f(dset_id, filespace, ierr)
1204 call h5sget_simple_extent_dims_f(filespace, dims, maxdims, ierr)
1205 call h5sclose_f(filespace, ierr)
1207 if (int(index, hsize_t) .eq. dims(1))
then
1208 dims(1) = int(index + 1, hsize_t)
1209 call h5dset_extent_f(dset_id, dims, ierr)
1210 else if (int(index, hsize_t) .gt. dims(1))
then
1211 call neko_error(
"VTKHDF: Values written out of order.")
1215 maxdims = h5s_unlimited_f
1216 chunkdims = 1_hsize_t
1218 call h5screate_simple_f(1, dims, filespace, ierr, maxdims)
1219 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
1220 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
1221 call h5dcreate_f(grp_id, name, h5t_neko_integer, &
1222 filespace, dset_id, ierr, dcpl_id = dcpl_id)
1223 call h5sclose_f(filespace, ierr)
1224 call h5pclose_f(dcpl_id, ierr)
1228 offset = int(index, hsize_t)
1230 call h5dget_space_f(dset_id, filespace, ierr)
1231 call h5screate_simple_f(1, count, memspace, ierr)
1232 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, offset, count, ierr)
1233 call h5dwrite_f(dset_id, h5t_neko_integer,
value, count, ierr, &
1234 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
1236 call h5sclose_f(memspace, ierr)
1237 call h5sclose_f(filespace, ierr)
1238 call h5dclose_f(dset_id, ierr)
1239 call h5pclose_f(xf_id, ierr)
1241 end subroutine vtkhdf_write_i8_at
1254 subroutine write_scalar_field(hdf_root, name, x, n_local, &
1255 precision, n_total, offset)
1256 integer,
intent(in) :: n_local
1257 integer(hid_t),
intent(in) :: hdf_root
1258 character(len=*),
intent(in) :: name
1259 real(kind=rp),
dimension(n_local),
intent(in) :: x
1260 integer,
intent(in),
optional :: precision
1261 integer,
intent(in),
optional :: n_total, offset
1263 integer(hsize_t),
dimension(1) :: dims, dcount, doffset
1264 integer(hid_t) :: xf_id, dset_id, filespace, memspace, precision_hdf
1265 integer :: i, ierr, precision_local, n_tot, off
1268 dcount = int(n_local, hsize_t)
1270 if (
present(n_total))
then
1271 dims = int(n_total, hsize_t)
1273 call mpi_allreduce(n_local, n_tot, 1, mpi_integer, mpi_sum, neko_comm, &
1275 dims = int(n_tot, hsize_t)
1278 if (
present(offset))
then
1279 doffset = int(offset, hsize_t)
1281 call mpi_exscan(n_local, off, 1, mpi_integer, mpi_sum, neko_comm, &
1283 doffset = int(off, hsize_t)
1286 if (
present(precision))
then
1287 precision_local = precision
1289 precision_local = rp
1291 precision_hdf = h5kind_to_type(precision_local, h5_real_kind)
1294 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1295 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1297 call h5screate_simple_f(1, dims, filespace, ierr)
1298 call h5screate_simple_f(1, dcount, memspace, ierr)
1299 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1300 doffset, dcount, ierr)
1302 call h5dcreate_f(hdf_root, trim(name), precision_hdf, &
1303 filespace, dset_id, ierr)
1305 if (precision_local .eq. rp)
then
1306 call h5dwrite_f(dset_id, precision_hdf, x, dcount, ierr, &
1307 file_space_id = filespace, mem_space_id = memspace, &
1310 else if (precision_local .eq. sp)
then
1312 real(kind=sp),
allocatable :: x_sp(:)
1314 allocate(x_sp(n_local))
1315 do concurrent(i = 1:n_local)
1316 x_sp(i) =
real(x(i), sp)
1319 call h5dwrite_f(dset_id, precision_hdf, x_sp, dcount, ierr, &
1320 file_space_id = filespace, mem_space_id = memspace, &
1325 else if (precision_local .eq. dp)
then
1327 real(kind=dp),
allocatable :: x_dp(:)
1329 allocate(x_dp(n_local))
1330 do concurrent(i = 1:n_local)
1331 x_dp(i) =
real(x(i), dp)
1334 call h5dwrite_f(dset_id, precision_hdf, x_dp, dcount, ierr, &
1335 file_space_id = filespace, mem_space_id = memspace, &
1340 else if (precision_local .eq. qp)
then
1342 real(kind=qp),
allocatable :: x_qp(:)
1344 allocate(x_qp(n_local))
1345 do concurrent(i = 1:n_local)
1346 x_qp(i) =
real(x(i), qp)
1349 call h5dwrite_f(dset_id, precision_hdf, x_qp, dcount, ierr, &
1350 file_space_id = filespace, mem_space_id = memspace, &
1356 call neko_error(
"Unsupported precision in HDF5 write_scalar_field")
1359 call h5sclose_f(filespace, ierr)
1360 call h5sclose_f(memspace, ierr)
1361 call h5dclose_f(dset_id, ierr)
1362 call h5pclose_f(xf_id, ierr)
1363 end subroutine write_scalar_field
1378 subroutine write_vector_field(hdf_root, name, u, v, w, n_local, &
1379 precision, n_total, offset)
1380 integer,
intent(in) :: n_local
1381 integer(hid_t),
intent(in) :: hdf_root
1382 character(len=*),
intent(in) :: name
1383 real(kind=rp),
dimension(n_local),
intent(in) :: u, v, w
1384 integer,
intent(in),
optional :: precision
1385 integer,
intent(in),
optional :: n_total, offset
1387 integer(hsize_t),
dimension(2) :: dims, dcount, doffset
1388 integer(hid_t) :: xf_id, dset_id, filespace, memspace, precision_hdf
1389 integer :: i, ierr, precision_local, n_tot, off
1392 dcount = [3_hsize_t, int(n_local, hsize_t)]
1394 if (
present(n_total))
then
1395 dims = [3_hsize_t, int(n_total, hsize_t)]
1397 call mpi_allreduce(n_local, n_tot, 1, mpi_integer, mpi_sum, neko_comm, &
1399 dims = [3_hsize_t, int(n_tot, hsize_t)]
1402 if (
present(offset))
then
1403 doffset = [0_hsize_t, int(offset, hsize_t)]
1405 call mpi_exscan(n_local, off, 1, mpi_integer, mpi_sum, neko_comm, &
1407 doffset = [0_hsize_t, int(off, hsize_t)]
1410 if (
present(precision))
then
1411 precision_local = precision
1413 precision_local = rp
1415 precision_hdf = h5kind_to_type(precision_local, h5_real_kind)
1418 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1419 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1421 call h5screate_simple_f(2, dims, filespace, ierr)
1422 call h5screate_simple_f(2, dcount, memspace, ierr)
1423 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1424 doffset, dcount, ierr)
1426 call h5dcreate_f(hdf_root, trim(name), precision_hdf, filespace, dset_id, &
1429 if (precision_local .eq. sp)
then
1431 real(kind=sp),
allocatable :: f(:,:)
1433 allocate(f(3, n_local))
1434 do concurrent(i = 1:n_local)
1435 f(1, i) =
real(u(i), sp)
1436 f(2, i) =
real(v(i), sp)
1437 f(3, i) =
real(w(i), sp)
1440 call h5dwrite_f(dset_id, precision_hdf, f, dcount, ierr, &
1441 file_space_id = filespace, mem_space_id = memspace, &
1446 else if (precision_local .eq. dp)
then
1448 real(kind=dp),
allocatable :: f(:,:)
1450 allocate(f(3, n_local))
1451 do concurrent(i = 1:n_local)
1452 f(1, i) =
real(u(i), dp)
1453 f(2, i) =
real(v(i), dp)
1454 f(3, i) =
real(w(i), dp)
1457 call h5dwrite_f(dset_id, precision_hdf, f, dcount, ierr, &
1458 file_space_id = filespace, mem_space_id = memspace, &
1463 else if (precision_local .eq. qp)
then
1465 real(kind=qp),
allocatable :: f(:,:)
1467 allocate(f(3, n_local))
1468 do concurrent(i = 1:n_local)
1469 f(1, i) =
real(u(i), qp)
1470 f(2, i) =
real(v(i), qp)
1471 f(3, i) =
real(w(i), qp)
1474 call h5dwrite_f(dset_id, precision_hdf, f, dcount, ierr, &
1475 file_space_id = filespace, mem_space_id = memspace, &
1481 call neko_error(
"Unsupported precision in HDF5 write_vector_field")
1484 call h5sclose_f(filespace, ierr)
1485 call h5sclose_f(memspace, ierr)
1486 call h5dclose_f(dset_id, ierr)
1487 call h5pclose_f(xf_id, ierr)
1488 end subroutine write_vector_field
1496 class(*),
target,
intent(inout) :: data
1497 character(len=1024) :: fname
1498 integer(hid_t) :: plist_id, file_id, vtkhdf_grp
1499 integer :: mpi_info, mpi_comm, counter, ierr
1500 type(field_list_t) :: fields
1504 fname = trim(this%get_base_fname())
1505 counter = this%get_counter() - this%get_start_counter()
1506 if (counter .lt. 0) counter = 0
1508 mpi_info = mpi_info_null%mpi_val
1509 mpi_comm = neko_comm%mpi_val
1512 call h5pcreate_f(h5p_file_access_f, plist_id, ierr)
1513 call h5pset_fapl_mpio_f(plist_id, mpi_comm, mpi_info, ierr)
1515 call h5fopen_f(fname, h5f_acc_rdonly_f, file_id, ierr, &
1516 access_prp = plist_id)
1517 if (ierr .ne. 0)
then
1518 call neko_error(
'Error opening VTKHDF file: ' // trim(fname))
1521 call h5gopen_f(file_id,
"VTKHDF", vtkhdf_grp, ierr)
1522 if (ierr .ne. 0)
then
1523 call h5fclose_f(file_id, ierr)
1524 call h5pclose_f(plist_id, ierr)
1525 call neko_error(
'VTKHDF group not found in file: ' // trim(fname))
1533 call fields%assign_to_field(1, data)
1534 type is (field_list_t)
1535 call fields%assign_to_list(data)
1537 call neko_error(
"Unsupported data type in vtkhdf_file_read")
1540 do i = 1, fields%size()
1541 call vtkhdf_read_field(vtkhdf_grp, fname, counter, fields%get(i))
1543 call fields%copy_from(host_to_device, .true.)
1545 call h5gclose_f(vtkhdf_grp, ierr)
1546 call h5fclose_f(file_id, ierr)
1547 call h5pclose_f(plist_id, ierr)
1548 call h5close_f(ierr)
1563 subroutine vtkhdf_read_field(vtkhdf_grp, fname, counter, fld)
1564 integer(hid_t),
intent(in) :: vtkhdf_grp
1565 character(len=*),
intent(in) :: fname
1566 integer,
intent(in) :: counter
1567 type(field_t),
intent(inout) :: fld
1569 character(len=:),
allocatable :: field_name
1570 integer :: ierr, local_points, total_points, point_offset, component
1571 integer(hid_t) :: pointdata_grp, dset_id, filespace, memspace, xf_id
1572 integer(hid_t) :: dcpl_id, ext_file_id, ext_plist_id, attr_id
1573 integer(hid_t) :: H5T_NEKO_REAL
1574 integer(hsize_t),
dimension(1) :: dcount1, doffset1
1575 integer(hsize_t),
dimension(2) :: dcount2, doffset2
1577 integer(size_t) :: vds_count
1578 character(len=128) :: dset_name
1579 character(len=1024) :: vds_src_file, ext_fname, main_path, main_name, main_suffix
1580 logical :: exists, is_vds
1581 real(kind=rp),
allocatable :: vec_component(:,:)
1582 integer :: mpi_info, mpi_comm, pct_pos, nsteps
1583 character(len=256) :: error_message
1585 field_name = trim(fld%name)
1588 call h5lexists_f(vtkhdf_grp,
"Steps", exists, ierr)
1590 call h5aopen_by_name_f(vtkhdf_grp,
"Steps",
"NSteps", attr_id, ierr)
1591 call h5aread_f(attr_id, h5t_native_integer, nsteps, [1_hsize_t], ierr)
1592 call h5aclose_f(attr_id, ierr)
1594 if (counter .ge. nsteps)
then
1595 write(error_message,
'(A,I0,A,I0)') &
1596 'VTKHDF read: counter ', counter,
' >= NSteps ', nsteps
1597 call neko_error(trim(error_message))
1601 mpi_info = mpi_info_null%mpi_val
1602 mpi_comm = neko_comm%mpi_val
1604 local_points = fld%dof%size()
1605 total_points = fld%dof%global_size()
1607 call mpi_exscan(local_points, point_offset, 1, mpi_integer, &
1608 mpi_sum, neko_comm, ierr)
1610 h5t_neko_real = h5kind_to_type(rp, h5_real_kind)
1613 call h5gopen_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
1616 dset_name = trim(field_name)
1617 if (trim(dset_name) .eq.
'p') dset_name =
'Pressure'
1620 call h5lexists_f(pointdata_grp, trim(dset_name), exists, ierr)
1622 if (.not. exists)
then
1623 if (trim(field_name) .eq.
'u' .or. trim(field_name) .eq.
'v' .or. &
1624 trim(field_name) .eq.
'w')
then
1625 call h5lexists_f(pointdata_grp,
"Velocity", exists, ierr)
1627 dset_name =
'Velocity'
1628 select case (trim(field_name))
1640 if (.not. exists)
then
1641 call h5gclose_f(pointdata_grp, ierr)
1642 call neko_error(
'VTKHDF PointData field not found: ' // trim(dset_name))
1646 call h5dopen_f(pointdata_grp, trim(dset_name), dset_id, ierr)
1647 call h5dget_create_plist_f(dset_id, dcpl_id, ierr)
1648 call h5pget_virtual_count_f(dcpl_id, vds_count, ierr)
1649 is_vds = (vds_count .gt. 0_size_t)
1652 call filename_split(fname, main_path, main_name, main_suffix)
1658 call h5pget_virtual_filename_f(dcpl_id, 0_size_t, vds_src_file, ierr)
1659 pct_pos = index(vds_src_file,
'%b')
1661 if (pct_pos .gt. 0)
then
1666 if (vds_src_file(1:1) .eq.
'/')
then
1667 write(ext_fname,
'(A,I0,A)') &
1668 vds_src_file(1:pct_pos-1), counter, &
1669 trim(vds_src_file(pct_pos+2:))
1671 write(ext_fname,
'(A,A,I0,A)') &
1672 trim(main_path), vds_src_file(1:pct_pos-1), counter, &
1673 trim(vds_src_file(pct_pos+2:))
1679 if (int(counter, size_t) .ge. vds_count)
then
1680 call h5pclose_f(dcpl_id, ierr)
1681 call h5dclose_f(dset_id, ierr)
1682 call h5gclose_f(pointdata_grp, ierr)
1683 write(error_message,
'(A,I0,A,I0)') &
1684 'VTKHDF: VDS counter ', counter, &
1685 ' is out of range, number of mappings: ', int(vds_count)
1686 call neko_error(trim(error_message))
1688 call h5pget_virtual_filename_f(dcpl_id, int(counter, size_t), &
1690 if (vds_src_file(1:1) .eq.
'/')
then
1691 ext_fname = trim(vds_src_file)
1693 write(ext_fname,
'(A,A)') trim(main_path), trim(vds_src_file)
1697 call h5pclose_f(dcpl_id, ierr)
1698 call h5dclose_f(dset_id, ierr)
1699 call h5gclose_f(pointdata_grp, ierr)
1701 call h5pcreate_f(h5p_file_access_f, ext_plist_id, ierr)
1702 call h5pset_fapl_mpio_f(ext_plist_id, mpi_comm, mpi_info, ierr)
1703 call h5fopen_f(trim(ext_fname), h5f_acc_rdonly_f, ext_file_id, ierr, &
1704 access_prp = ext_plist_id)
1706 if (ierr .ne. 0)
then
1707 call neko_error(
'VTKHDF: Cannot open VDS source file: ' // &
1712 call h5dopen_f(ext_file_id, trim(dset_name), dset_id, ierr)
1714 call h5pclose_f(ext_plist_id, ierr)
1716 call h5pclose_f(dcpl_id, ierr)
1721 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1722 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1723 call h5dget_space_f(dset_id, filespace, ierr)
1725 if (trim(dset_name) .eq.
'Velocity' .and. component .ge. 0)
then
1727 dcount2 = [1_hsize_t, int(local_points, hsize_t)]
1728 doffset2 = [int(component, hsize_t), int(point_offset, hsize_t)]
1730 call h5screate_simple_f(2, dcount2, memspace, ierr)
1731 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1732 doffset2, dcount2, ierr)
1734 allocate(vec_component(1, local_points))
1735 call h5dread_f(dset_id, h5t_neko_real, vec_component, dcount2, ierr, &
1736 file_space_id = filespace, mem_space_id = memspace, &
1738 fld%x = reshape(vec_component, shape(fld%x))
1739 deallocate(vec_component)
1742 dcount1 = int(local_points, hsize_t)
1743 doffset1 = int(point_offset, hsize_t)
1745 call h5screate_simple_f(1, dcount1, memspace, ierr)
1746 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1747 doffset1, dcount1, ierr)
1749 call h5dread_f(dset_id, h5t_neko_real, fld%x(1,1,1,1), dcount1, ierr, &
1750 file_space_id = filespace, mem_space_id = memspace, &
1754 call h5sclose_f(memspace, ierr)
1755 call h5sclose_f(filespace, ierr)
1756 call h5dclose_f(dset_id, ierr)
1757 call h5pclose_f(xf_id, ierr)
1760 call h5fclose_f(ext_file_id, ierr)
1762 call h5gclose_f(pointdata_grp, ierr)
1765 end subroutine vtkhdf_read_field
1774 class(*),
target,
intent(in) :: data
1775 real(kind=rp),
intent(in),
optional :: t
1776 call neko_error(
'Neko needs to be built with HDF5 support')
1782 class(*),
target,
intent(inout) :: data
1783 call neko_error(
'Neko needs to be built with HDF5 support')
1800 integer,
intent(in) :: lx, ly, lz
1801 integer :: node_order(8 * (lx - 1) * (ly - 1) * (lz - 1))
1802 integer :: ii, jj, kk, idx
1809 node_order(idx + 1) = (kk - 1) * lx * ly + (jj - 1) * lx + ii - 1
1810 node_order(idx + 2) = (kk - 1) * lx * ly + (jj - 1) * lx + ii
1811 node_order(idx + 3) = (kk - 1) * lx * ly + jj * lx + ii
1812 node_order(idx + 4) = (kk - 1) * lx * ly + jj * lx + ii - 1
1813 node_order(idx + 5) = kk * lx * ly + (jj - 1) * lx + ii - 1
1814 node_order(idx + 6) = kk * lx * ly + (jj - 1) * lx + ii
1815 node_order(idx + 7) = kk * lx * ly + jj * lx + ii
1816 node_order(idx + 8) = kk * lx * ly + jj * lx + ii - 1
1832 integer,
intent(in) :: lx, ly
1833 integer :: node_order(4 * (lx - 1) * (ly - 1))
1834 integer :: ii, jj, idx
1840 node_order(idx + 1) = (jj - 1) * lx + ii - 1
1841 node_order(idx + 2) = (jj - 1) * lx + ii
1842 node_order(idx + 3) = jj * lx + ii
1843 node_order(idx + 4) = jj * lx + ii - 1
__inline__ __device__ void nonlinear_index(const int idx, const int lx, int *index)
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.
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.
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...
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.