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, &
57 h5gcreate_f, h5gopen_f, h5gclose_f, &
58 h5acreate_f, h5aopen_f, h5awrite_f, h5aread_f, h5aclose_f, h5aexists_f, &
60 h5dcreate_f, h5dopen_f, h5dwrite_f, h5dread_f, h5dclose_f, &
61 h5dget_create_plist_f, &
62 h5tcopy_f, h5tclose_f, h5tset_strpad_f, h5tset_size_f, &
63 h5screate_f, h5screate_simple_f, h5sclose_f, &
64 h5sselect_hyperslab_f, h5sselect_all_f, h5sget_simple_extent_dims_f, &
65 h5dget_space_f, h5dset_extent_f, &
66 h5pcreate_f, h5pclose_f, h5pset_fapl_mpio_f, h5pset_dxpl_mpio_f, &
67 h5pget_virtual_count_f, h5pget_virtual_filename_f, &
68 h5lexists_f, h5ldelete_f, &
69 h5p_file_access_f, h5p_dataset_xfer_f, h5p_dataset_create_f, &
70 h5f_acc_trunc_f, h5f_acc_rdwr_f, h5f_acc_rdonly_f, h5pset_chunk_f, &
71 h5t_std_u8le, h5t_native_integer, h5t_fortran_s1, h5t_str_nullterm_f, &
72 h5kind_to_type, h5_real_kind, h5_integer_kind, h5pset_virtual_f, &
73 h5s_scalar_f, h5s_select_set_f, h5fd_mpio_collective_f, h5p_default_f, &
81 logical :: amr_enabled = .false.
82 logical :: subdivide = .false.
83 logical :: enable_vds = .false.
84 integer :: precision = -1
105 logical,
intent(in) :: overwrite
106 this%overwrite = overwrite
112 this%amr_enabled = .false.
118 integer,
intent(in) :: precision
119 this%precision = precision
125 character(len=1024) :: base_fname
126 character(len=1024) :: fname
127 character(len=1024) :: path, name, suffix
129 fname = trim(this%get_base_fname())
132 write(base_fname,
'(A,A,"_",I0,A)') &
133 trim(path), trim(name), this%get_start_counter(), trim(suffix)
144 logical,
intent(in) :: subdivide
145 this%subdivide = subdivide
156 class(*),
target,
intent(in) :: data
157 real(kind=
rp),
intent(in),
optional :: t
158 type(
mesh_t),
pointer :: msh
161 integer :: ierr, mpi_info, mpi_comm, i, n_fields
162 integer(hid_t) :: plist_id, file_id, attr_id, vtkhdf_grp
163 integer(hid_t) :: filespace, H5T_NEKO_STRING
164 integer(hsize_t),
dimension(1) :: vdims
165 integer(size_t) :: type_len
166 integer :: lx, ly, lz
167 integer :: local_points, local_cells, local_conn
168 integer :: total_points, total_cells, total_conn
169 integer :: point_offset
170 integer :: max_local_points
171 integer,
allocatable :: part_points(:), part_cells(:), part_conns(:)
172 character(len=1024) :: fname
173 character(len=16) :: type_str
184 call fields%assign(1, data)
188 call fields%assign(data)
190 call neko_error(
'Invalid data type for vtkhdf_file_write')
194 if (.not.
associated(msh))
then
195 call neko_error(
'Mesh must be associated for vtkhdf_file_write')
197 if (dof%Xh%lx .lt. 2 .or. dof%Xh%ly .lt. 2)
then
198 call neko_error(
'VTKHDF linear output requires lx, ly >= 2')
200 if (msh%gdim .eq. 3 .and. dof%Xh%lz .lt. 2)
then
201 call neko_error(
'VTKHDF linear output requires lz >= 2 in 3D')
203 if (msh%gdim .lt. 2 .or. msh%gdim .gt. 3)
then
204 call neko_error(
'VTKHDF output only supports 2D and 3D meshes')
208 if (this%precision .gt.
rp)
then
210 call neko_warning(
'Requested precision is higher than working precision')
211 else if (this%precision .eq. -1)
then
215 call this%increment_counter()
216 fname = trim(this%get_vtkhdf_fname())
217 counter = this%get_counter() - this%get_start_counter()
219 mpi_info = mpi_info_null%mpi_val
223 call h5pcreate_f(h5p_file_access_f, plist_id, ierr)
224 call h5pset_fapl_mpio_f(plist_id, mpi_comm, mpi_info, ierr)
226 if (counter .eq. 0)
then
228 call h5fcreate_f(fname, h5f_acc_trunc_f, &
229 file_id, ierr, access_prp = plist_id)
231 call h5fopen_f(fname, h5f_acc_rdwr_f, file_id, ierr, &
232 access_prp = plist_id)
236 call h5lexists_f(file_id,
"VTKHDF", exists, ierr)
238 call h5gopen_f(file_id,
"VTKHDF", vtkhdf_grp, ierr)
240 call h5gcreate_f(file_id,
"VTKHDF", vtkhdf_grp, ierr)
244 call h5screate_simple_f(1, vdims, filespace, ierr)
245 call h5acreate_f(vtkhdf_grp,
"Version", h5t_native_integer, filespace, &
247 call h5awrite_f(attr_id, h5t_native_integer,
vtkhdf_version, vdims, ierr)
248 call h5aclose_f(attr_id, ierr)
249 call h5sclose_f(filespace, ierr)
252 type_str =
"UnstructuredGrid"
253 type_len = int(len_trim(type_str), kind=size_t)
255 call h5screate_f(h5s_scalar_f, filespace, ierr)
257 call h5tcopy_f(h5t_fortran_s1, h5t_neko_string, ierr)
258 call h5tset_size_f(h5t_neko_string, type_len, ierr)
259 call h5tset_strpad_f(h5t_neko_string, h5t_str_nullterm_f, ierr)
261 call h5acreate_f(vtkhdf_grp,
"Type", h5t_neko_string, filespace, &
263 call h5awrite_f(attr_id, h5t_neko_string, [type_str], vdims, ierr)
264 call h5aclose_f(attr_id, ierr)
266 call h5tclose_f(h5t_neko_string, ierr)
267 call h5sclose_f(filespace, ierr)
271 call vtkhdf_write_steps(vtkhdf_grp, counter, t)
274 if (
associated(msh))
then
275 call vtkhdf_write_mesh(vtkhdf_grp, dof, msh, &
276 this%amr_enabled, counter, this%subdivide, t)
280 if (fields%size() .gt. 0)
then
281 call vtkhdf_write_pointdata(vtkhdf_grp, fields, this%precision, &
285 call h5gclose_f(vtkhdf_grp, ierr)
286 call h5pclose_f(plist_id, ierr)
287 call h5fclose_f(file_id, ierr)
306 subroutine vtkhdf_write_mesh(vtkhdf_grp, dof, msh, amr, counter, subdivide, t)
308 type(
mesh_t),
intent(in) :: msh
309 integer(hid_t),
intent(in) :: vtkhdf_grp
310 logical,
intent(in) :: amr
311 integer,
intent(in) :: counter
312 logical,
intent(in) :: subdivide
313 real(kind=
rp),
intent(in),
optional :: t
315 integer(kind=1) :: VTK_cell_type
316 integer :: ierr, i, ii, jj, kk, el, local_idx
317 integer :: lx, ly, lz, npts_per_cell, nodes_per_cell, cells_per_element
318 integer :: local_points, local_cells, local_conn
319 integer :: total_points, total_cells, total_conn
320 integer :: point_offset, max_local_points
321 integer :: total_offsets, cell_offset, conn_offset, offsets_offset
322 integer :: max_local_cells, max_local_conn
323 integer(hid_t) :: xf_id, dset_id, dcpl_id, grp_id, attr_id
324 integer(hid_t) :: filespace, memspace, H5T_NEKO_DOUBLE
325 integer(hsize_t),
dimension(1) :: dcount, vdims, maxdims, doffset, chunkdims
326 integer(hsize_t),
dimension(2) :: dcount2, vdims2, maxdims2, doffset2
327 integer(kind=i8) :: i8_value
329 integer,
dimension(3) :: component_sizes
330 integer,
dimension(3) :: component_offsets
331 integer,
dimension(3) :: component_max_sizes
337 if (subdivide .and. msh%gdim .eq. 3)
then
338 vtk_cell_type = int(12, kind=1)
339 cells_per_element = (lx - 1) * (ly - 1) * (lz - 1)
341 else if (subdivide .and. msh%gdim .eq. 2)
then
342 vtk_cell_type = int(9, kind=1)
343 cells_per_element = (lx - 1) * (ly - 1)
345 else if (msh%gdim .eq. 3)
then
346 vtk_cell_type = int(72, kind=1)
347 cells_per_element = 1
348 nodes_per_cell = lx * ly * lz
349 else if (msh%gdim .eq. 2)
then
350 vtk_cell_type = int(70, kind=1)
351 cells_per_element = 1
352 nodes_per_cell = lx * ly
356 local_points = dof%size()
357 local_cells = msh%nelv * cells_per_element
358 local_conn = local_cells * nodes_per_cell
360 total_points = dof%global_size()
361 total_cells = msh%glb_nelv * cells_per_element
362 total_conn = total_cells * nodes_per_cell
364 component_sizes = [local_points, local_cells, local_conn]
365 component_offsets = 0
366 component_max_sizes = 0
368 call mpi_exscan(component_sizes, component_offsets, 3, mpi_integer, &
370 call mpi_allreduce(component_sizes, component_max_sizes, 3, mpi_integer, &
373 point_offset = component_offsets(1)
374 cell_offset = component_offsets(2)
375 conn_offset = component_offsets(3)
376 max_local_points = component_max_sizes(1)
377 max_local_cells = component_max_sizes(2)
378 max_local_conn = component_max_sizes(3)
380 offsets_offset = cell_offset +
pe_rank
381 total_offsets = total_cells +
pe_size
384 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
385 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
393 integer(hsize_t),
dimension(1) :: nof_dims, nof_maxdims
394 integer(hsize_t),
dimension(1) :: nof_count, nof_offset, nof_chunk
395 integer(hid_t) :: nof_filespace, nof_memspace, nof_dcpl
396 integer(kind=i8) :: nof_values(3)
398 nof_count(1) = 1_hsize_t
399 nof_offset(1) = int(counter, hsize_t) * int(
pe_size, hsize_t) &
401 nof_chunk(1) =
max(1_hsize_t, int(
pe_size, hsize_t))
402 nof_values = [int(local_points, kind=
i8), int(local_cells, kind=
i8), &
403 int(local_conn, kind=
i8)]
405 call h5pcreate_f(h5p_dataset_create_f, nof_dcpl, ierr)
406 call h5pset_chunk_f(nof_dcpl, 1, nof_chunk, ierr)
408 call vtkhdf_write_numberof(vtkhdf_grp,
"NumberOfPoints", &
409 nof_values(1), nof_offset, nof_count, nof_dcpl, &
410 counter, xf_id, ierr)
411 call vtkhdf_write_numberof(vtkhdf_grp,
"NumberOfCells", &
412 nof_values(2), nof_offset, nof_count, nof_dcpl, &
413 counter, xf_id, ierr)
414 call vtkhdf_write_numberof(vtkhdf_grp,
"NumberOfConnectivityIds", &
415 nof_values(3), nof_offset, nof_count, nof_dcpl, &
416 counter, xf_id, ierr)
418 call h5pclose_f(nof_dcpl, ierr)
422 call h5lexists_f(vtkhdf_grp,
"Points", exists, ierr)
423 if (.not. exists)
then
425 vdims2 = [3_hsize_t, int(total_points, hsize_t)]
426 maxdims2 = [3_hsize_t, h5s_unlimited_f]
427 chunkdims(1) = int(
max(1, min(max_local_points, total_points)), hsize_t)
428 dcount2 = [3_hsize_t, int(local_points, hsize_t)]
429 doffset2 = [0_hsize_t, int(point_offset, hsize_t)]
430 h5t_neko_double = h5kind_to_type(
dp, h5_real_kind)
432 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
433 call h5screate_simple_f(2, dcount2, memspace, ierr)
434 call h5screate_simple_f(2, vdims2, filespace, ierr, maxdims2)
436 call h5pset_chunk_f(dcpl_id, 2, [3_hsize_t, chunkdims(1)], ierr)
437 call h5dcreate_f(vtkhdf_grp,
"Points", h5t_neko_double, &
438 filespace, dset_id, ierr, dcpl_id = dcpl_id)
439 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
440 doffset2, dcount2, ierr)
443 real(kind=
dp),
allocatable :: coords(:,:)
445 allocate(coords(3, local_points))
446 do concurrent(local_idx = 1:local_points)
449 real(kind=
dp) :: x, y, z
452 x =
real(dof%x(idx(1), idx(2), idx(3), idx(4)),
dp)
453 y =
real(dof%y(idx(1), idx(2), idx(3), idx(4)),
dp)
454 z =
real(dof%z(idx(1), idx(2), idx(3), idx(4)),
dp)
456 coords(1, local_idx) = x
457 coords(2, local_idx) = y
458 coords(3, local_idx) = z
461 call h5dwrite_f(dset_id, h5t_neko_double, coords, dcount2, ierr, &
462 file_space_id = filespace, mem_space_id = memspace, &
467 call h5dclose_f(dset_id, ierr)
468 call h5sclose_f(filespace, ierr)
469 call h5sclose_f(memspace, ierr)
470 call h5pclose_f(dcpl_id, ierr)
474 call h5lexists_f(vtkhdf_grp,
"Connectivity", exists, ierr)
475 if (exists)
call h5ldelete_f(vtkhdf_grp,
"Connectivity", ierr)
477 vdims = int(total_conn, hsize_t)
478 maxdims = h5s_unlimited_f
479 chunkdims = int(
max(1, min(max_local_conn, total_conn)), hsize_t)
480 dcount = int(local_conn, hsize_t)
481 doffset = int(conn_offset, hsize_t)
483 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
484 call h5screate_simple_f(1, dcount, memspace, ierr)
485 call h5screate_simple_f(1, vdims, filespace, ierr, maxdims)
487 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
488 call h5dcreate_f(vtkhdf_grp,
"Connectivity", h5t_native_integer, &
489 filespace, dset_id, ierr, dcpl_id = dcpl_id)
490 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
491 doffset, dcount, ierr)
494 integer,
allocatable :: connectivity(:)
496 allocate(connectivity(local_conn))
497 call vtkhdf_build_connectivity(connectivity, vtk_cell_type, msh, dof, &
499 call h5dwrite_f(dset_id, h5t_native_integer, connectivity, dcount, &
500 ierr, file_space_id = filespace, mem_space_id = memspace, &
502 deallocate(connectivity)
505 call h5dclose_f(dset_id, ierr)
506 call h5sclose_f(filespace, ierr)
507 call h5sclose_f(memspace, ierr)
508 call h5pclose_f(dcpl_id, ierr)
511 call h5lexists_f(vtkhdf_grp,
"Offsets", exists, ierr)
512 if (exists)
call h5ldelete_f(vtkhdf_grp,
"Offsets", ierr)
514 vdims = int(total_offsets, hsize_t)
515 maxdims = h5s_unlimited_f
516 chunkdims = int(
max(1, min(max_local_cells + 1, total_offsets)), hsize_t)
517 dcount = int(local_cells + 1, hsize_t)
518 doffset = int(offsets_offset, hsize_t)
520 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
521 call h5screate_simple_f(1, dcount, memspace, ierr)
522 call h5screate_simple_f(1, vdims, filespace, ierr, maxdims)
524 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
525 call h5dcreate_f(vtkhdf_grp,
"Offsets", h5t_native_integer, &
526 filespace, dset_id, ierr, dcpl_id = dcpl_id)
527 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
528 doffset, dcount, ierr)
531 integer,
allocatable :: offsets(:)
533 allocate(offsets(local_cells + 1))
534 do concurrent(i = 1:local_cells)
535 offsets(i) = (i - 1) * nodes_per_cell
537 offsets(local_cells + 1) = local_conn
538 call h5dwrite_f(dset_id, h5t_native_integer, offsets, dcount, ierr, &
539 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
543 call h5dclose_f(dset_id, ierr)
544 call h5sclose_f(filespace, ierr)
545 call h5sclose_f(memspace, ierr)
546 call h5pclose_f(dcpl_id, ierr)
549 call h5lexists_f(vtkhdf_grp,
"Types", exists, ierr)
550 if (exists)
call h5ldelete_f(vtkhdf_grp,
"Types", ierr)
552 vdims = int(total_cells, hsize_t)
553 maxdims = h5s_unlimited_f
554 chunkdims = int(
max(1, min(max_local_cells, total_cells)), hsize_t)
555 dcount = int(local_cells, hsize_t)
556 doffset = int(cell_offset, hsize_t)
558 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
559 call h5screate_simple_f(1, dcount, memspace, ierr)
560 call h5screate_simple_f(1, vdims, filespace, ierr, maxdims)
562 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
563 call h5dcreate_f(vtkhdf_grp,
"Types", h5t_std_u8le, &
564 filespace, dset_id, ierr, dcpl_id = dcpl_id)
565 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
566 doffset, dcount, ierr)
569 integer(kind=1),
allocatable :: cell_types(:)
570 allocate(cell_types(local_cells), source=vtk_cell_type)
571 call h5dwrite_f(dset_id, h5t_std_u8le, cell_types, dcount, ierr, &
572 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
573 deallocate(cell_types)
576 call h5dclose_f(dset_id, ierr)
577 call h5sclose_f(filespace, ierr)
578 call h5sclose_f(memspace, ierr)
579 call h5pclose_f(dcpl_id, ierr)
583 call h5gopen_f(vtkhdf_grp,
"Steps", grp_id, ierr)
586 call vtkhdf_write_i8_at(grp_id,
"NumberOfParts", int(pe_size, kind=i8), &
592 i8_value = int(counter - 1, kind=i8) * int(pe_size, kind=i8)
593 call vtkhdf_write_i8_at(grp_id,
"PartOffsets", i8_value, counter)
595 i8_value = int(counter - 1, kind=i8) * int(total_points, kind=i8)
596 call vtkhdf_write_i8_at(grp_id,
"PointOffsets", i8_value, counter)
598 i8_value = int(counter - 1, kind=i8) * int(total_cells, kind=i8)
599 call vtkhdf_write_i8_at(grp_id,
"CellOffsets", i8_value, counter)
601 i8_value = int(counter - 1, kind=i8) * int(total_conn, kind=i8)
602 call vtkhdf_write_i8_at(grp_id,
"ConnectivityIdOffsets", i8_value, &
607 call vtkhdf_write_i8_at(grp_id,
"PartOffsets", i8_value, counter)
608 call vtkhdf_write_i8_at(grp_id,
"PointOffsets", i8_value, counter)
609 call vtkhdf_write_i8_at(grp_id,
"CellOffsets", i8_value, counter)
610 call vtkhdf_write_i8_at(grp_id,
"ConnectivityIdOffsets", i8_value, &
614 call h5gclose_f(grp_id, ierr)
617 call h5pclose_f(xf_id, ierr)
619 end subroutine vtkhdf_write_mesh
627 subroutine vtkhdf_write_steps(vtkhdf_grp, counter, t)
628 integer(hid_t),
intent(in) :: vtkhdf_grp
629 integer,
intent(in) :: counter
630 real(kind=rp),
intent(in) :: t
632 integer(hid_t) :: xf_id, H5T_NEKO_DOUBLE
634 integer(hid_t) :: grp_id, dset_id, dcpl_id, filespace, memspace, attr_id
635 integer(hsize_t),
dimension(1) :: step_dims, step_maxdims
636 integer(hsize_t),
dimension(1) :: step_count, step_offset, chunkdims, ddim
637 real(kind=dp),
dimension(1) :: time_value
638 integer(kind=i8) :: i8_value
639 logical :: exists, attr_exists
642 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
643 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
644 h5t_neko_double = h5kind_to_type(dp, h5_real_kind)
647 call h5lexists_f(vtkhdf_grp,
"Steps", exists, ierr)
649 call h5gopen_f(vtkhdf_grp,
"Steps", grp_id, ierr)
651 call h5gcreate_f(vtkhdf_grp,
"Steps", grp_id, ierr)
655 call h5lexists_f(grp_id,
"Values", exists, ierr)
657 call h5dopen_f(grp_id,
"Values", dset_id, ierr)
658 call h5dget_space_f(dset_id, filespace, ierr)
659 call h5sget_simple_extent_dims_f(filespace, step_dims, step_maxdims, &
661 call h5sclose_f(filespace, ierr)
664 if (step_dims(1) .eq. int(counter, hsize_t))
then
665 step_dims(1) = int(counter + 1, hsize_t)
666 call h5dset_extent_f(dset_id, step_dims, ierr)
667 else if (step_dims(1) .lt. int(counter, hsize_t))
then
668 call neko_error(
"VTKHDF: Time steps written out of order.")
671 step_dims(1) = 1_hsize_t
672 step_maxdims(1) = h5s_unlimited_f
673 chunkdims(1) = 1_hsize_t
675 call h5screate_simple_f(1, step_dims, filespace, ierr, step_maxdims)
676 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
677 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
678 call h5dcreate_f(grp_id,
"Values", h5t_neko_double, &
679 filespace, dset_id, ierr, dcpl_id = dcpl_id)
680 call h5sclose_f(filespace, ierr)
681 call h5pclose_f(dcpl_id, ierr)
684 step_count(1) = 1_hsize_t
685 step_offset(1) = int(counter, hsize_t)
687 call h5dget_space_f(dset_id, filespace, ierr)
688 call h5screate_simple_f(1, step_count, memspace, ierr)
689 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
690 step_offset, step_count, ierr)
692 time_value(1) =
real(t, kind=dp)
693 call h5dwrite_f(dset_id, h5t_neko_double, time_value, step_count, ierr, &
694 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
696 call h5sclose_f(memspace, ierr)
697 call h5sclose_f(filespace, ierr)
698 call h5dclose_f(dset_id, ierr)
702 call h5aexists_f(grp_id,
"NSteps", attr_exists, ierr)
703 if (attr_exists)
then
704 call h5aopen_f(grp_id,
"NSteps", attr_id, ierr)
706 call h5screate_f(h5s_scalar_f, filespace, ierr)
707 call h5acreate_f(grp_id,
"NSteps", h5t_native_integer, filespace, &
708 attr_id, ierr, h5p_default_f, h5p_default_f)
709 call h5sclose_f(filespace, ierr)
712 call h5awrite_f(attr_id, h5t_native_integer, counter + 1, ddim, ierr)
714 call h5aclose_f(attr_id, ierr)
715 call h5gclose_f(grp_id, ierr)
716 call h5pclose_f(xf_id, ierr)
718 end subroutine vtkhdf_write_steps
734 subroutine vtkhdf_write_pointdata(vtkhdf_grp, fields, precision, counter, &
736 integer(hid_t),
intent(in) :: vtkhdf_grp
737 type(field_list_t),
intent(inout) :: fields
738 integer,
intent(in) :: precision
739 integer,
intent(in) :: counter
740 character(len=*),
intent(in) :: fname
741 real(kind=rp),
intent(in),
optional :: t
743 integer(kind=i8) :: time_offset
744 integer :: local_points, point_offset, total_points
745 integer(hid_t) :: precision_hdf
746 integer :: ierr, i, j
748 integer(hid_t) :: pointdata_grp, grp_id, step_grp_id
749 integer(hid_t) :: dset_id, dcpl_id, filespace
750 integer(hsize_t),
dimension(1) :: pd_dims1, pd_maxdims1
751 integer(hsize_t),
dimension(2) :: pd_dims2, pd_maxdims2
752 type(field_t),
pointer :: u, v, w
753 character(len=128) :: field_name
754 logical :: exists, is_vector
757 character(len=1024) :: ext_fname, ext_path, src_pattern
758 character(len=1024) :: main_path, main_name, main_suffix
759 integer(hid_t) :: ext_file_id, ext_plist_id, vds_src_space
760 integer(hid_t) :: write_target, attr_id, H5T_NEKO_STRING
761 integer :: mpi_info, mpi_comm
764 integer :: fields_written
765 character(len=128),
allocatable :: name_list(:)
766 logical,
allocatable :: vector_list(:)
768 mpi_info = mpi_info_null%mpi_val
769 mpi_comm = neko_comm%mpi_val
771 n_fields = fields%size()
774 local_points = fields%item_size(1)
775 total_points = fields%items(1)%ptr%dof%global_size()
777 call mpi_exscan(local_points, point_offset, 1, mpi_integer, &
778 mpi_sum, neko_comm, ierr)
782 if (
associated(fields%items(i)%ptr))
then
783 call fields%items(i)%ptr%copy_from(device_to_host, sync = i .eq. n_fields)
788 allocate(name_list(n_fields))
792 call h5lexists_f(vtkhdf_grp,
"PointData", exists, ierr)
793 if (.not. exists)
then
794 call h5gcreate_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
795 call h5gclose_f(pointdata_grp, ierr)
804 call filename_split(fname, main_path, main_name, main_suffix)
805 write(ext_path,
'(A,A,".data/")') trim(main_path), trim(main_name)
806 write(ext_fname,
'(A,I0,".h5")') trim(ext_path), counter
807 write(src_pattern,
'(A,".data/%b.h5")') trim(main_name)
809 if (pe_rank .eq. 0)
then
810 call mkdir(trim(ext_path))
812 call mpi_barrier(neko_comm, ierr)
814 call h5pcreate_f(h5p_file_access_f, ext_plist_id, ierr)
815 call h5pset_fapl_mpio_f(ext_plist_id, mpi_comm, mpi_info, ierr)
816 call h5fcreate_f(trim(ext_fname), h5f_acc_trunc_f, write_target, ierr, &
817 access_prp = ext_plist_id)
818 call h5pclose_f(ext_plist_id, ierr)
822 call h5gopen_f(vtkhdf_grp,
"PointData", write_target, ierr)
829 field_name = fields%name(i)
830 if (field_name .eq.
'p') field_name =
'Pressure'
834 if (field_name .eq.
'u' .or. field_name .eq.
'v' .or. &
835 field_name .eq.
'w')
then
840 select case (trim(fields%name(j)))
850 if (
associated(u) .and.
associated(v) .and.
associated(w))
then
852 field_name =
'Velocity'
859 do j = 1, fields_written
860 if (trim(name_list(j)) .eq. trim(field_name))
then
870 fields_written = fields_written + 1
871 name_list(fields_written) = field_name
876 call write_vector_field(write_target, field_name, u%x, v%x, w%x, &
877 local_points, precision, total_points, point_offset)
879 call write_scalar_field(write_target, field_name, fields%x(i), &
880 local_points, precision, total_points, point_offset)
886 call h5fclose_f(write_target, ierr)
888 call h5gclose_f(write_target, ierr)
897 call h5gopen_f(vtkhdf_grp,
"Steps", step_grp_id, ierr)
898 time_offset = int(counter, kind=i8) * int(total_points, kind=i8)
901 call h5lexists_f(step_grp_id,
"PointDataOffsets", exists, ierr)
903 call h5gopen_f(step_grp_id,
"PointDataOffsets", grp_id, ierr)
905 call h5gcreate_f(step_grp_id,
"PointDataOffsets", grp_id, ierr)
907 do i = 1, fields_written
908 call vtkhdf_write_i8_at(grp_id, trim(name_list(i)), &
909 time_offset, counter)
911 call h5gclose_f(grp_id, ierr)
912 call h5gclose_f(step_grp_id, ierr)
915 call h5gopen_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
917 do i = 1, fields_written
918 field_name = name_list(i)
921 if (counter .eq. 0)
then
923 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
924 precision_hdf = h5kind_to_type(precision, h5_real_kind)
927 pd_dims2 = [3_hsize_t, int(total_points, hsize_t)]
928 call h5screate_simple_f(2, pd_dims2, vds_src_space, ierr)
929 call h5sselect_all_f(vds_src_space, ierr)
931 pd_maxdims2 = [3_hsize_t, h5s_unlimited_f]
932 call h5screate_simple_f(2, pd_dims2, filespace, ierr, &
935 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
936 [0_hsize_t, 0_hsize_t], &
937 [1_hsize_t, h5s_unlimited_f], &
939 stride = [3_hsize_t, int(total_points, hsize_t)], &
940 block = [3_hsize_t, int(total_points, hsize_t)])
942 call h5pset_virtual_f(dcpl_id, filespace, trim(src_pattern), &
943 trim(field_name), vds_src_space, ierr)
944 call h5sclose_f(vds_src_space, ierr)
946 call h5dcreate_f(pointdata_grp, trim(field_name), &
947 precision_hdf, filespace, dset_id, ierr, &
949 call h5sclose_f(filespace, ierr)
951 pd_dims1 = int(total_points, hsize_t)
952 call h5screate_simple_f(1, pd_dims1, vds_src_space, ierr)
953 call h5sselect_all_f(vds_src_space, ierr)
955 pd_maxdims1(1) = h5s_unlimited_f
956 call h5screate_simple_f(1, pd_dims1, filespace, ierr, &
959 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
963 stride = [int(total_points, hsize_t)], &
964 block = [int(total_points, hsize_t)])
966 call h5pset_virtual_f(dcpl_id, filespace, trim(src_pattern), &
967 trim(field_name), vds_src_space, ierr)
968 call h5sclose_f(vds_src_space, ierr)
970 call h5dcreate_f(pointdata_grp, trim(field_name), &
971 precision_hdf, filespace, dset_id, ierr, &
973 call h5sclose_f(filespace, ierr)
976 call h5pclose_f(dcpl_id, ierr)
977 call h5dclose_f(dset_id, ierr)
981 call h5dopen_f(pointdata_grp, trim(field_name), dset_id, ierr)
984 pd_dims2 = [3_hsize_t, &
985 int(counter + 1, hsize_t) * int(total_points, hsize_t)]
986 call h5dset_extent_f(dset_id, pd_dims2, ierr)
988 pd_dims1 = int(counter + 1, hsize_t) * int(total_points, hsize_t)
989 call h5dset_extent_f(dset_id, pd_dims1, ierr)
992 call h5dclose_f(dset_id, ierr)
996 call h5gclose_f(pointdata_grp, ierr)
1002 do i = 1, fields_written
1003 field_name = name_list(i)
1005 pd_dims1 = 1_hsize_t
1007 call h5gopen_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
1008 call h5dopen_f(pointdata_grp, trim(field_name), dset_id, ierr)
1010 call h5aexists_f(dset_id,
"Attribute", exists, ierr)
1012 call h5dclose_f(dset_id, ierr)
1013 call h5gclose_f(pointdata_grp, ierr)
1018 call h5screate_f(h5s_scalar_f, filespace, ierr)
1020 call h5tcopy_f(h5t_fortran_s1, h5t_neko_string, ierr)
1021 call h5tset_size_f(h5t_neko_string, int(6, size_t), ierr)
1022 call h5tset_strpad_f(h5t_neko_string, h5t_str_nullterm_f, ierr)
1024 call h5acreate_f(dset_id,
"Attribute", h5t_neko_string, filespace, &
1027 call h5awrite_f(attr_id, h5t_neko_string, [
"Vector"], pd_dims1, ierr)
1029 call h5awrite_f(attr_id, h5t_neko_string, [
"Scalar"], pd_dims1, ierr)
1032 call h5aclose_f(attr_id, ierr)
1033 call h5tclose_f(h5t_neko_string, ierr)
1034 call h5sclose_f(filespace, ierr)
1035 call h5dclose_f(dset_id, ierr)
1036 call h5gclose_f(pointdata_grp, ierr)
1043 deallocate(name_list)
1046 end subroutine vtkhdf_write_pointdata
1063 subroutine vtkhdf_build_connectivity(conn, vtk_type, msh, dof, subdivide)
1064 integer,
intent(inout) :: conn(:)
1065 integer(kind=1),
intent(in) :: vtk_type
1066 type(mesh_t),
intent(in) :: msh
1067 type(dofmap_t),
intent(in) :: dof
1068 logical,
intent(in) :: subdivide
1069 integer :: lx, ly, lz, nelv
1070 integer :: ie, ii, n_pts_per_elem, n_conn_per_elem
1071 integer,
allocatable :: node_order(:)
1077 n_pts_per_elem = lx * ly * lz
1079 if (subdivide .and. vtk_type .eq. int(12, kind=1))
then
1081 else if (subdivide .and. vtk_type .eq. int(9, kind=1))
then
1084 node_order = vtk_ordering(vtk_type, lx, ly, lz)
1087 n_conn_per_elem =
size(node_order)
1089 do concurrent(ie = 1:nelv, ii = 1:n_conn_per_elem)
1091 integer :: idx, base
1092 idx = (ie - 1) * n_conn_per_elem
1093 base = (ie - 1) * n_pts_per_elem
1094 conn(idx + ii) = base + node_order(ii)
1098 deallocate(node_order)
1100 end subroutine vtkhdf_build_connectivity
1114 subroutine vtkhdf_write_numberof(grp, dset_name, value, offset, cnt, &
1115 dcpl, index, xf_id, ierr)
1116 integer(hid_t),
intent(in) :: grp, dcpl, xf_id
1117 character(len=*),
intent(in) :: dset_name
1118 integer(kind=i8),
intent(in) :: value
1119 integer,
intent(in):: index
1120 integer(hsize_t),
dimension(1),
intent(in) :: offset, cnt
1121 integer,
intent(out) :: ierr
1123 integer(hid_t) :: dset_id, fspace, mspace
1124 integer(hsize_t),
dimension(1) :: dims, maxdims
1125 integer(hid_t) :: H5T_NEKO_INTEGER
1128 h5t_neko_integer = h5kind_to_type(i8, h5_integer_kind)
1130 call h5lexists_f(grp, dset_name, exists, ierr)
1132 call h5dopen_f(grp, dset_name, dset_id, ierr)
1133 dims(1) = int(index + 1, hsize_t) * int(pe_size, hsize_t)
1134 call h5dset_extent_f(dset_id, dims, ierr)
1136 dims(1) = int(pe_size, hsize_t)
1137 maxdims(1) = h5s_unlimited_f
1138 call h5screate_simple_f(1, dims, fspace, ierr, maxdims)
1139 call h5dcreate_f(grp, dset_name, h5t_neko_integer, &
1140 fspace, dset_id, ierr, dcpl_id = dcpl)
1141 call h5sclose_f(fspace, ierr)
1144 call h5dget_space_f(dset_id, fspace, ierr)
1145 call h5screate_simple_f(1, cnt, mspace, ierr)
1146 call h5sselect_hyperslab_f(fspace, h5s_select_set_f, offset, cnt, ierr)
1148 call h5dwrite_f(dset_id, h5t_neko_integer,
value, cnt, ierr, &
1149 file_space_id = fspace, mem_space_id = mspace, xfer_prp = xf_id)
1151 call h5sclose_f(mspace, ierr)
1152 call h5sclose_f(fspace, ierr)
1153 call h5dclose_f(dset_id, ierr)
1154 end subroutine vtkhdf_write_numberof
1163 subroutine vtkhdf_write_i8_at(grp_id, name, value, index)
1164 integer(hid_t),
intent(in) :: grp_id
1165 character(len=*),
intent(in) :: name
1166 integer(kind=i8),
intent(in) :: value
1167 integer,
intent(in) :: index
1170 integer(hid_t) :: dset_id, dcpl_id, xf_id, filespace, memspace
1171 integer(hsize_t),
dimension(1) :: dims, maxdims, count, offset, chunkdims
1172 integer(hid_t) :: H5T_NEKO_INTEGER
1175 h5t_neko_integer = h5kind_to_type(i8, h5_integer_kind)
1178 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1179 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1181 call h5lexists_f(grp_id, name, exists, ierr)
1183 call h5dopen_f(grp_id, name, dset_id, ierr)
1184 call h5dget_space_f(dset_id, filespace, ierr)
1185 call h5sget_simple_extent_dims_f(filespace, dims, maxdims, ierr)
1186 call h5sclose_f(filespace, ierr)
1188 if (int(index, hsize_t) .eq. dims(1))
then
1189 dims(1) = int(index + 1, hsize_t)
1190 call h5dset_extent_f(dset_id, dims, ierr)
1191 else if (int(index, hsize_t) .gt. dims(1))
then
1192 call neko_error(
"VTKHDF: Values written out of order.")
1196 maxdims = h5s_unlimited_f
1197 chunkdims = 1_hsize_t
1199 call h5screate_simple_f(1, dims, filespace, ierr, maxdims)
1200 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
1201 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
1202 call h5dcreate_f(grp_id, name, h5t_neko_integer, &
1203 filespace, dset_id, ierr, dcpl_id = dcpl_id)
1204 call h5sclose_f(filespace, ierr)
1205 call h5pclose_f(dcpl_id, ierr)
1209 offset = int(index, hsize_t)
1211 call h5dget_space_f(dset_id, filespace, ierr)
1212 call h5screate_simple_f(1, count, memspace, ierr)
1213 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, offset, count, ierr)
1214 call h5dwrite_f(dset_id, h5t_neko_integer,
value, count, ierr, &
1215 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
1217 call h5sclose_f(memspace, ierr)
1218 call h5sclose_f(filespace, ierr)
1219 call h5dclose_f(dset_id, ierr)
1220 call h5pclose_f(xf_id, ierr)
1222 end subroutine vtkhdf_write_i8_at
1235 subroutine write_scalar_field(hdf_root, name, x, n_local, &
1236 precision, n_total, offset)
1237 integer,
intent(in) :: n_local
1238 integer(hid_t),
intent(in) :: hdf_root
1239 character(len=*),
intent(in) :: name
1240 real(kind=rp),
dimension(n_local),
intent(in) :: x
1241 integer,
intent(in),
optional :: precision
1242 integer,
intent(in),
optional :: n_total, offset
1244 integer(hsize_t),
dimension(1) :: dims, dcount, doffset
1245 integer(hid_t) :: xf_id, dset_id, filespace, memspace, precision_hdf
1246 integer :: i, ierr, precision_local, n_tot, off
1249 dcount = int(n_local, hsize_t)
1251 if (
present(n_total))
then
1252 dims = int(n_total, hsize_t)
1254 call mpi_allreduce(n_local, n_tot, 1, mpi_integer, mpi_sum, neko_comm, &
1256 dims = int(n_tot, hsize_t)
1259 if (
present(offset))
then
1260 doffset = int(offset, hsize_t)
1262 call mpi_exscan(n_local, off, 1, mpi_integer, mpi_sum, neko_comm, &
1264 doffset = int(off, hsize_t)
1267 if (
present(precision))
then
1268 precision_local = precision
1270 precision_local = rp
1272 precision_hdf = h5kind_to_type(precision_local, h5_real_kind)
1275 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1276 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1278 call h5screate_simple_f(1, dims, filespace, ierr)
1279 call h5screate_simple_f(1, dcount, memspace, ierr)
1280 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1281 doffset, dcount, ierr)
1283 call h5dcreate_f(hdf_root, trim(name), precision_hdf, &
1284 filespace, dset_id, ierr)
1286 if (precision_local .eq. rp)
then
1287 call h5dwrite_f(dset_id, precision_hdf, x, dcount, ierr, &
1288 file_space_id = filespace, mem_space_id = memspace, &
1291 else if (precision_local .eq. sp)
then
1293 real(kind=sp),
allocatable :: x_sp(:)
1295 allocate(x_sp(n_local))
1296 do concurrent(i = 1:n_local)
1297 x_sp(i) =
real(x(i), sp)
1300 call h5dwrite_f(dset_id, precision_hdf, x_sp, dcount, ierr, &
1301 file_space_id = filespace, mem_space_id = memspace, &
1306 else if (precision_local .eq. dp)
then
1308 real(kind=dp),
allocatable :: x_dp(:)
1310 allocate(x_dp(n_local))
1311 do concurrent(i = 1:n_local)
1312 x_dp(i) =
real(x(i), dp)
1315 call h5dwrite_f(dset_id, precision_hdf, x_dp, dcount, ierr, &
1316 file_space_id = filespace, mem_space_id = memspace, &
1321 else if (precision_local .eq. qp)
then
1323 real(kind=qp),
allocatable :: x_qp(:)
1325 allocate(x_qp(n_local))
1326 do concurrent(i = 1:n_local)
1327 x_qp(i) =
real(x(i), qp)
1330 call h5dwrite_f(dset_id, precision_hdf, x_qp, dcount, ierr, &
1331 file_space_id = filespace, mem_space_id = memspace, &
1337 call neko_error(
"Unsupported precision in HDF5 write_scalar_field")
1340 call h5sclose_f(filespace, ierr)
1341 call h5sclose_f(memspace, ierr)
1342 call h5dclose_f(dset_id, ierr)
1343 call h5pclose_f(xf_id, ierr)
1344 end subroutine write_scalar_field
1359 subroutine write_vector_field(hdf_root, name, u, v, w, n_local, &
1360 precision, n_total, offset)
1361 integer,
intent(in) :: n_local
1362 integer(hid_t),
intent(in) :: hdf_root
1363 character(len=*),
intent(in) :: name
1364 real(kind=rp),
dimension(n_local),
intent(in) :: u, v, w
1365 integer,
intent(in),
optional :: precision
1366 integer,
intent(in),
optional :: n_total, offset
1368 integer(hsize_t),
dimension(2) :: dims, dcount, doffset
1369 integer(hid_t) :: xf_id, dset_id, filespace, memspace, precision_hdf
1370 integer :: i, ierr, precision_local, n_tot, off
1373 dcount = [3_hsize_t, int(n_local, hsize_t)]
1375 if (
present(n_total))
then
1376 dims = [3_hsize_t, int(n_total, hsize_t)]
1378 call mpi_allreduce(n_local, n_tot, 1, mpi_integer, mpi_sum, neko_comm, &
1380 dims = [3_hsize_t, int(n_tot, hsize_t)]
1383 if (
present(offset))
then
1384 doffset = [0_hsize_t, int(offset, hsize_t)]
1386 call mpi_exscan(n_local, off, 1, mpi_integer, mpi_sum, neko_comm, &
1388 doffset = [0_hsize_t, int(off, hsize_t)]
1391 if (
present(precision))
then
1392 precision_local = precision
1394 precision_local = rp
1396 precision_hdf = h5kind_to_type(precision_local, h5_real_kind)
1399 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1400 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1402 call h5screate_simple_f(2, dims, filespace, ierr)
1403 call h5screate_simple_f(2, dcount, memspace, ierr)
1404 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1405 doffset, dcount, ierr)
1407 call h5dcreate_f(hdf_root, trim(name), precision_hdf, filespace, dset_id, &
1410 if (precision_local .eq. sp)
then
1412 real(kind=sp),
allocatable :: f(:,:)
1414 allocate(f(3, n_local))
1415 do concurrent(i = 1:n_local)
1416 f(1, i) =
real(u(i), sp)
1417 f(2, i) =
real(v(i), sp)
1418 f(3, i) =
real(w(i), sp)
1421 call h5dwrite_f(dset_id, precision_hdf, f, dcount, ierr, &
1422 file_space_id = filespace, mem_space_id = memspace, &
1427 else if (precision_local .eq. dp)
then
1429 real(kind=dp),
allocatable :: f(:,:)
1431 allocate(f(3, n_local))
1432 do concurrent(i = 1:n_local)
1433 f(1, i) =
real(u(i), dp)
1434 f(2, i) =
real(v(i), dp)
1435 f(3, i) =
real(w(i), dp)
1438 call h5dwrite_f(dset_id, precision_hdf, f, dcount, ierr, &
1439 file_space_id = filespace, mem_space_id = memspace, &
1444 else if (precision_local .eq. qp)
then
1446 real(kind=qp),
allocatable :: f(:,:)
1448 allocate(f(3, n_local))
1449 do concurrent(i = 1:n_local)
1450 f(1, i) =
real(u(i), qp)
1451 f(2, i) =
real(v(i), qp)
1452 f(3, i) =
real(w(i), qp)
1455 call h5dwrite_f(dset_id, precision_hdf, f, dcount, ierr, &
1456 file_space_id = filespace, mem_space_id = memspace, &
1462 call neko_error(
"Unsupported precision in HDF5 write_vector_field")
1465 call h5sclose_f(filespace, ierr)
1466 call h5sclose_f(memspace, ierr)
1467 call h5dclose_f(dset_id, ierr)
1468 call h5pclose_f(xf_id, ierr)
1469 end subroutine write_vector_field
1477 class(*),
target,
intent(inout) :: data
1478 character(len=1024) :: fname
1479 integer(hid_t) :: plist_id, file_id, vtkhdf_grp
1480 integer :: mpi_info, mpi_comm, counter, ierr
1481 type(field_list_t) :: fields
1485 fname = trim(this%get_base_fname())
1486 counter = this%get_counter() - this%get_start_counter()
1487 if (counter .lt. 0) counter = 0
1489 mpi_info = mpi_info_null%mpi_val
1490 mpi_comm = neko_comm%mpi_val
1493 call h5pcreate_f(h5p_file_access_f, plist_id, ierr)
1494 call h5pset_fapl_mpio_f(plist_id, mpi_comm, mpi_info, ierr)
1496 call h5fopen_f(fname, h5f_acc_rdonly_f, file_id, ierr, &
1497 access_prp = plist_id)
1498 if (ierr .ne. 0)
then
1499 call neko_error(
'Error opening VTKHDF file: ' // trim(fname))
1502 call h5gopen_f(file_id,
"VTKHDF", vtkhdf_grp, ierr)
1503 if (ierr .ne. 0)
then
1504 call h5fclose_f(file_id, ierr)
1505 call h5pclose_f(plist_id, ierr)
1506 call h5close_f(ierr)
1507 call neko_error(
'VTKHDF group not found in file: ' // trim(fname))
1513 call fields%assign(1, data)
1514 type is (field_list_t)
1515 call fields%assign(data)
1517 call neko_error(
"Unsupported data type in vtkhdf_file_read")
1520 do i = 1, fields%size()
1521 call vtkhdf_read_field(vtkhdf_grp, fname, counter, fields%get(i))
1523 call fields%copy_from(host_to_device, .true.)
1525 call h5gclose_f(vtkhdf_grp, ierr)
1526 call h5fclose_f(file_id, ierr)
1527 call h5pclose_f(plist_id, ierr)
1528 call h5close_f(ierr)
1543 subroutine vtkhdf_read_field(vtkhdf_grp, fname, counter, fld)
1544 integer(hid_t),
intent(in) :: vtkhdf_grp
1545 character(len=*),
intent(in) :: fname
1546 integer,
intent(in) :: counter
1547 type(field_t),
intent(inout) :: fld
1549 character(len=:),
allocatable :: field_name
1550 integer :: ierr, local_points, total_points, point_offset, component
1551 integer(hid_t) :: pointdata_grp, dset_id, filespace, memspace, xf_id
1552 integer(hid_t) :: dcpl_id, ext_file_id, ext_plist_id, attr_id
1553 integer(hid_t) :: H5T_NEKO_REAL
1554 integer(hsize_t),
dimension(1) :: dcount1, doffset1
1555 integer(hsize_t),
dimension(2) :: dcount2, doffset2
1557 integer(size_t) :: vds_count
1558 character(len=128) :: dset_name
1559 character(len=1024) :: vds_src_file, ext_fname, main_path, main_name, main_suffix
1560 logical :: exists, is_vds
1561 real(kind=rp),
allocatable :: vec_component(:,:)
1562 integer :: mpi_info, mpi_comm, pct_pos, nsteps
1563 character(len=256) :: error_message
1565 field_name = trim(fld%name)
1568 call h5lexists_f(vtkhdf_grp,
"Steps", exists, ierr)
1570 call h5aopen_by_name_f(vtkhdf_grp,
"Steps",
"NSteps", attr_id, ierr)
1571 call h5aread_f(attr_id, h5t_native_integer, nsteps, [1_hsize_t], ierr)
1572 call h5aclose_f(attr_id, ierr)
1574 if (counter .ge. nsteps)
then
1575 write(error_message,
'(A,I0,A,I0)') &
1576 'VTKHDF read: counter ', counter,
' >= NSteps ', nsteps
1577 call neko_error(trim(error_message))
1581 mpi_info = mpi_info_null%mpi_val
1582 mpi_comm = neko_comm%mpi_val
1584 local_points = fld%dof%size()
1585 total_points = fld%dof%global_size()
1587 call mpi_exscan(local_points, point_offset, 1, mpi_integer, &
1588 mpi_sum, neko_comm, ierr)
1590 h5t_neko_real = h5kind_to_type(rp, h5_real_kind)
1593 call h5gopen_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
1596 dset_name = trim(field_name)
1597 if (trim(dset_name) .eq.
'p') dset_name =
'Pressure'
1600 call h5lexists_f(pointdata_grp, trim(dset_name), exists, ierr)
1602 if (.not. exists)
then
1603 if (trim(field_name) .eq.
'u' .or. trim(field_name) .eq.
'v' .or. &
1604 trim(field_name) .eq.
'w')
then
1605 call h5lexists_f(pointdata_grp,
"Velocity", exists, ierr)
1607 dset_name =
'Velocity'
1608 select case (trim(field_name))
1620 if (.not. exists)
then
1621 call h5gclose_f(pointdata_grp, ierr)
1622 call neko_error(
'VTKHDF PointData field not found: ' // trim(dset_name))
1626 call h5dopen_f(pointdata_grp, trim(dset_name), dset_id, ierr)
1627 call h5dget_create_plist_f(dset_id, dcpl_id, ierr)
1628 call h5pget_virtual_count_f(dcpl_id, vds_count, ierr)
1629 is_vds = (vds_count .gt. 0_size_t)
1632 call filename_split(fname, main_path, main_name, main_suffix)
1638 call h5pget_virtual_filename_f(dcpl_id, 0_size_t, vds_src_file, ierr)
1639 pct_pos = index(vds_src_file,
'%b')
1641 if (pct_pos .gt. 0)
then
1646 if (vds_src_file(1:1) .eq.
'/')
then
1647 write(ext_fname,
'(A,I0,A)') &
1648 vds_src_file(1:pct_pos-1), counter, &
1649 trim(vds_src_file(pct_pos+2:))
1651 write(ext_fname,
'(A,A,I0,A)') &
1652 trim(main_path), vds_src_file(1:pct_pos-1), counter, &
1653 trim(vds_src_file(pct_pos+2:))
1659 if (int(counter, size_t) .ge. vds_count)
then
1660 call h5pclose_f(dcpl_id, ierr)
1661 call h5dclose_f(dset_id, ierr)
1662 call h5gclose_f(pointdata_grp, ierr)
1663 write(error_message,
'(A,I0,A,I0)') &
1664 'VTKHDF: VDS counter ', counter, &
1665 ' is out of range, number of mappings: ', int(vds_count)
1666 call neko_error(trim(error_message))
1668 call h5pget_virtual_filename_f(dcpl_id, int(counter, size_t), &
1670 if (vds_src_file(1:1) .eq.
'/')
then
1671 ext_fname = trim(vds_src_file)
1673 write(ext_fname,
'(A,A)') trim(main_path), trim(vds_src_file)
1677 call h5pclose_f(dcpl_id, ierr)
1678 call h5dclose_f(dset_id, ierr)
1679 call h5gclose_f(pointdata_grp, ierr)
1681 call h5pcreate_f(h5p_file_access_f, ext_plist_id, ierr)
1682 call h5pset_fapl_mpio_f(ext_plist_id, mpi_comm, mpi_info, ierr)
1683 call h5fopen_f(trim(ext_fname), h5f_acc_rdonly_f, ext_file_id, ierr, &
1684 access_prp = ext_plist_id)
1686 if (ierr .ne. 0)
then
1687 call neko_error(
'VTKHDF: Cannot open VDS source file: ' // &
1692 call h5dopen_f(ext_file_id, trim(dset_name), dset_id, ierr)
1694 call h5pclose_f(ext_plist_id, ierr)
1696 call h5pclose_f(dcpl_id, ierr)
1701 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1702 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1703 call h5dget_space_f(dset_id, filespace, ierr)
1705 if (trim(dset_name) .eq.
'Velocity' .and. component .ge. 0)
then
1707 dcount2 = [1_hsize_t, int(local_points, hsize_t)]
1708 doffset2 = [int(component, hsize_t), int(point_offset, hsize_t)]
1710 call h5screate_simple_f(2, dcount2, memspace, ierr)
1711 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1712 doffset2, dcount2, ierr)
1714 allocate(vec_component(1, local_points))
1715 call h5dread_f(dset_id, h5t_neko_real, vec_component, dcount2, ierr, &
1716 file_space_id = filespace, mem_space_id = memspace, &
1718 fld%x = reshape(vec_component, shape(fld%x))
1719 deallocate(vec_component)
1722 dcount1 = int(local_points, hsize_t)
1723 doffset1 = int(point_offset, hsize_t)
1725 call h5screate_simple_f(1, dcount1, memspace, ierr)
1726 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1727 doffset1, dcount1, ierr)
1729 call h5dread_f(dset_id, h5t_neko_real, fld%x(1,1,1,1), dcount1, ierr, &
1730 file_space_id = filespace, mem_space_id = memspace, &
1734 call h5sclose_f(memspace, ierr)
1735 call h5sclose_f(filespace, ierr)
1736 call h5dclose_f(dset_id, ierr)
1737 call h5pclose_f(xf_id, ierr)
1740 call h5fclose_f(ext_file_id, ierr)
1742 call h5gclose_f(pointdata_grp, ierr)
1745 end subroutine vtkhdf_read_field
1754 class(*),
target,
intent(in) :: data
1755 real(kind=rp),
intent(in),
optional :: t
1756 call neko_error(
'Neko needs to be built with HDF5 support')
1762 class(*),
target,
intent(inout) :: data
1763 call neko_error(
'Neko needs to be built with HDF5 support')
1780 integer,
intent(in) :: lx, ly, lz
1781 integer :: node_order(8 * (lx - 1) * (ly - 1) * (lz - 1))
1782 integer :: ii, jj, kk, idx
1789 node_order(idx + 1) = (kk - 1) * lx * ly + (jj - 1) * lx + ii - 1
1790 node_order(idx + 2) = (kk - 1) * lx * ly + (jj - 1) * lx + ii
1791 node_order(idx + 3) = (kk - 1) * lx * ly + jj * lx + ii
1792 node_order(idx + 4) = (kk - 1) * lx * ly + jj * lx + ii - 1
1793 node_order(idx + 5) = kk * lx * ly + (jj - 1) * lx + ii - 1
1794 node_order(idx + 6) = kk * lx * ly + (jj - 1) * lx + ii
1795 node_order(idx + 7) = kk * lx * ly + jj * lx + ii
1796 node_order(idx + 8) = kk * lx * ly + jj * lx + ii - 1
1812 integer,
intent(in) :: lx, ly
1813 integer :: node_order(4 * (lx - 1) * (ly - 1))
1814 integer :: ii, jj, idx
1820 node_order(idx + 1) = (jj - 1) * lx + ii - 1
1821 node_order(idx + 2) = (jj - 1) * lx + ii
1822 node_order(idx + 3) = jj * lx + ii
1823 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.