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
107 logical,
intent(in) :: overwrite
108 this%overwrite = overwrite
114 this%amr_enabled = .false.
120 integer,
intent(in) :: precision
121 this%precision = precision
127 character(len=1024) :: base_fname
128 character(len=1024) :: fname
129 character(len=1024) :: path, name, suffix
131 fname = trim(this%get_base_fname())
134 write(base_fname,
'(A,A,"_",I0,A)') &
135 trim(path), trim(name), this%get_start_counter(), trim(suffix)
142 character(len=1024) :: fname
144 fname = this%get_vtkhdf_fname()
155 logical,
intent(in) :: subdivide
156 this%subdivide = subdivide
167 class(*),
target,
intent(in) :: data
168 real(kind=
rp),
intent(in),
optional :: t
169 type(
mesh_t),
pointer :: msh
172 integer :: ierr, mpi_info, mpi_comm, i, n_fields
173 integer(hid_t) :: plist_id, file_id, attr_id, vtkhdf_grp
174 integer(hid_t) :: filespace, H5T_NEKO_STRING
175 integer(hsize_t),
dimension(1) :: vdims
176 integer(size_t) :: type_len
177 integer :: lx, ly, lz
178 integer :: local_points, local_cells, local_conn
179 integer :: total_points, total_cells, total_conn
180 integer :: point_offset
181 integer :: max_local_points
182 integer,
allocatable :: part_points(:), part_cells(:), part_conns(:)
183 character(len=1024) :: fname
184 character(len=16) :: type_str
198 call fields%assign_to_field(1, data)
202 call fields%assign_to_list(data)
204 call neko_error(
'Invalid data type for vtkhdf_file_write')
208 if (.not.
associated(msh))
then
209 call neko_error(
'Mesh must be associated for vtkhdf_file_write')
211 if (dof%Xh%lx .lt. 2 .or. dof%Xh%ly .lt. 2)
then
212 call neko_error(
'VTKHDF linear output requires lx, ly >= 2')
214 if (msh%gdim .eq. 3 .and. dof%Xh%lz .lt. 2)
then
215 call neko_error(
'VTKHDF linear output requires lz >= 2 in 3D')
217 if (msh%gdim .lt. 2 .or. msh%gdim .gt. 3)
then
218 call neko_error(
'VTKHDF output only supports 2D and 3D meshes')
222 if (this%precision .gt.
rp)
then
224 call neko_warning(
'Requested precision is higher than working precision')
225 else if (this%precision .eq. -1)
then
229 call this%increment_counter()
230 fname = trim(this%get_vtkhdf_fname())
231 counter = this%get_counter() - this%get_start_counter()
233 mpi_info = mpi_info_null%mpi_val
237 call h5pcreate_f(h5p_file_access_f, plist_id, ierr)
238 call h5pset_fapl_mpio_f(plist_id, mpi_comm, mpi_info, ierr)
240 if (counter .eq. 0)
then
242 call h5fcreate_f(fname, h5f_acc_trunc_f, &
243 file_id, ierr, access_prp = plist_id)
245 call h5fopen_f(fname, h5f_acc_rdwr_f, file_id, ierr, &
246 access_prp = plist_id)
250 call h5lexists_f(file_id,
"VTKHDF", exists, ierr)
252 call h5gopen_f(file_id,
"VTKHDF", vtkhdf_grp, ierr)
254 call h5gcreate_f(file_id,
"VTKHDF", vtkhdf_grp, ierr)
258 call h5screate_simple_f(1, vdims, filespace, ierr)
259 call h5acreate_f(vtkhdf_grp,
"Version", h5t_native_integer, filespace, &
261 call h5awrite_f(attr_id, h5t_native_integer,
vtkhdf_version, vdims, ierr)
262 call h5aclose_f(attr_id, ierr)
263 call h5sclose_f(filespace, ierr)
266 type_str =
"UnstructuredGrid"
267 type_len = int(len_trim(type_str), kind=size_t)
269 call h5screate_f(h5s_scalar_f, filespace, ierr)
271 call h5tcopy_f(h5t_fortran_s1, h5t_neko_string, ierr)
272 call h5tset_size_f(h5t_neko_string, type_len, ierr)
273 call h5tset_strpad_f(h5t_neko_string, h5t_str_nullterm_f, ierr)
275 call h5acreate_f(vtkhdf_grp,
"Type", h5t_neko_string, filespace, &
277 call h5awrite_f(attr_id, h5t_neko_string, [type_str], vdims, ierr)
278 call h5aclose_f(attr_id, ierr)
280 call h5tclose_f(h5t_neko_string, ierr)
281 call h5sclose_f(filespace, ierr)
285 call vtkhdf_write_steps(vtkhdf_grp, counter, t)
288 if (
associated(msh))
then
289 call vtkhdf_write_mesh(vtkhdf_grp, dof, msh, &
290 this%amr_enabled, counter, this%subdivide, t)
294 if (fields%size() .gt. 0)
then
295 call vtkhdf_write_pointdata(vtkhdf_grp, fields, this%precision, &
299 call h5gclose_f(vtkhdf_grp, ierr)
300 call h5pclose_f(plist_id, ierr)
306 integer(size_t) :: obj_count
307 character(len=80) :: wrn_buf
308 call h5fget_obj_count_f(file_id, h5f_obj_all_f, obj_count, ierr)
309 if (obj_count .gt. 1_size_t .and.
pe_rank .eq. 0)
then
310 write(wrn_buf,
'(A,I0,A)')
'VTKHDF: ', obj_count - 1, &
311 ' HDF5 id(s) still open at file close'
315 call h5fflush_f(file_id, h5f_scope_global_f, ierr)
316 call h5fclose_f(file_id, ierr)
335 subroutine vtkhdf_write_mesh(vtkhdf_grp, dof, msh, amr, counter, subdivide, t)
336 type(dofmap_t),
intent(in) :: dof
337 type(mesh_t),
intent(in) :: msh
338 integer(hid_t),
intent(in) :: vtkhdf_grp
339 logical,
intent(in) :: amr
340 integer,
intent(in) :: counter
341 logical,
intent(in) :: subdivide
342 real(kind=rp),
intent(in),
optional :: t
344 integer(kind=1) :: VTK_cell_type
345 integer :: ierr, i, ii, jj, kk, el, local_idx
346 integer :: lx, ly, lz, npts_per_cell, nodes_per_cell, cells_per_element
347 integer :: local_points, local_cells, local_conn
348 integer :: total_points, total_cells, total_conn
349 integer :: point_offset, max_local_points
350 integer :: total_offsets, cell_offset, conn_offset, offsets_offset
351 integer :: max_local_cells, max_local_conn
352 integer(hid_t) :: xf_id, dset_id, dcpl_id, grp_id, attr_id
353 integer(hid_t) :: filespace, memspace, H5T_NEKO_DOUBLE
354 integer(hsize_t),
dimension(1) :: dcount, vdims, maxdims, doffset, chunkdims
355 integer(hsize_t),
dimension(2) :: dcount2, vdims2, maxdims2, doffset2
356 integer(kind=i8) :: i8_value
358 integer,
dimension(3) :: component_sizes
359 integer,
dimension(3) :: component_offsets
360 integer,
dimension(3) :: component_max_sizes
366 if (subdivide .and. msh%gdim .eq. 3)
then
367 vtk_cell_type = int(12, kind=1)
368 cells_per_element = (lx - 1) * (ly - 1) * (lz - 1)
370 else if (subdivide .and. msh%gdim .eq. 2)
then
371 vtk_cell_type = int(9, kind=1)
372 cells_per_element = (lx - 1) * (ly - 1)
374 else if (msh%gdim .eq. 3)
then
375 vtk_cell_type = int(72, kind=1)
376 cells_per_element = 1
377 nodes_per_cell = lx * ly * lz
378 else if (msh%gdim .eq. 2)
then
379 vtk_cell_type = int(70, kind=1)
380 cells_per_element = 1
381 nodes_per_cell = lx * ly
385 local_points = dof%size()
386 local_cells = msh%nelv * cells_per_element
387 local_conn = local_cells * nodes_per_cell
389 total_points = dof%global_size()
390 total_cells = msh%glb_nelv * cells_per_element
391 total_conn = total_cells * nodes_per_cell
393 component_sizes = [local_points, local_cells, local_conn]
394 component_offsets = 0
395 component_max_sizes = 0
397 call mpi_exscan(component_sizes, component_offsets, 3, mpi_integer, &
398 mpi_sum, neko_comm, ierr)
399 call mpi_allreduce(component_sizes, component_max_sizes, 3, mpi_integer, &
400 mpi_max, neko_comm, ierr)
402 point_offset = component_offsets(1)
403 cell_offset = component_offsets(2)
404 conn_offset = component_offsets(3)
405 max_local_points = component_max_sizes(1)
406 max_local_cells = component_max_sizes(2)
407 max_local_conn = component_max_sizes(3)
409 offsets_offset = cell_offset + pe_rank
410 total_offsets = total_cells + pe_size
413 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
414 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
422 integer(hsize_t),
dimension(1) :: nof_dims, nof_maxdims
423 integer(hsize_t),
dimension(1) :: nof_count, nof_offset, nof_chunk
424 integer(hid_t) :: nof_filespace, nof_memspace, nof_dcpl
425 integer(kind=i8) :: nof_values(3)
427 nof_count(1) = 1_hsize_t
428 nof_offset(1) = int(counter, hsize_t) * int(pe_size, hsize_t) &
429 + int(pe_rank, hsize_t)
430 nof_chunk(1) =
max(1_hsize_t, int(pe_size, hsize_t))
431 nof_values = [int(local_points, kind=i8), int(local_cells, kind=i8), &
432 int(local_conn, kind=i8)]
434 call h5pcreate_f(h5p_dataset_create_f, nof_dcpl, ierr)
435 call h5pset_chunk_f(nof_dcpl, 1, nof_chunk, ierr)
437 call vtkhdf_write_numberof(vtkhdf_grp,
"NumberOfPoints", &
438 nof_values(1), nof_offset, nof_count, nof_dcpl, &
439 counter, xf_id, ierr)
440 call vtkhdf_write_numberof(vtkhdf_grp,
"NumberOfCells", &
441 nof_values(2), nof_offset, nof_count, nof_dcpl, &
442 counter, xf_id, ierr)
443 call vtkhdf_write_numberof(vtkhdf_grp,
"NumberOfConnectivityIds", &
444 nof_values(3), nof_offset, nof_count, nof_dcpl, &
445 counter, xf_id, ierr)
447 call h5pclose_f(nof_dcpl, ierr)
451 call h5lexists_f(vtkhdf_grp,
"Points", exists, ierr)
452 if (.not. exists)
then
454 vdims2 = [3_hsize_t, int(total_points, hsize_t)]
455 maxdims2 = [3_hsize_t, h5s_unlimited_f]
456 chunkdims(1) = int(
max(1, min(max_local_points, total_points)), hsize_t)
457 dcount2 = [3_hsize_t, int(local_points, hsize_t)]
458 doffset2 = [0_hsize_t, int(point_offset, hsize_t)]
459 h5t_neko_double = h5kind_to_type(dp, h5_real_kind)
461 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
462 call h5screate_simple_f(2, dcount2, memspace, ierr)
463 call h5screate_simple_f(2, vdims2, filespace, ierr, maxdims2)
465 call h5pset_chunk_f(dcpl_id, 2, [3_hsize_t, chunkdims(1)], ierr)
466 call h5dcreate_f(vtkhdf_grp,
"Points", h5t_neko_double, &
467 filespace, dset_id, ierr, dcpl_id = dcpl_id)
468 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
469 doffset2, dcount2, ierr)
472 real(kind=dp),
allocatable :: coords(:,:)
474 allocate(coords(3, local_points))
475 do concurrent(local_idx = 1:local_points)
478 real(kind=dp) :: x, y, z
481 x =
real(dof%x(idx(1), idx(2), idx(3), idx(4)), dp)
482 y =
real(dof%y(idx(1), idx(2), idx(3), idx(4)), dp)
483 z =
real(dof%z(idx(1), idx(2), idx(3), idx(4)), dp)
485 coords(1, local_idx) = x
486 coords(2, local_idx) = y
487 coords(3, local_idx) = z
490 call h5dwrite_f(dset_id, h5t_neko_double, coords, dcount2, ierr, &
491 file_space_id = filespace, mem_space_id = memspace, &
496 call h5dclose_f(dset_id, ierr)
497 call h5sclose_f(filespace, ierr)
498 call h5sclose_f(memspace, ierr)
499 call h5pclose_f(dcpl_id, ierr)
503 call h5lexists_f(vtkhdf_grp,
"Connectivity", exists, ierr)
504 if (exists)
call h5ldelete_f(vtkhdf_grp,
"Connectivity", ierr)
506 vdims = int(total_conn, hsize_t)
507 maxdims = h5s_unlimited_f
508 chunkdims = int(
max(1, min(max_local_conn, total_conn)), hsize_t)
509 dcount = int(local_conn, hsize_t)
510 doffset = int(conn_offset, hsize_t)
512 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
513 call h5screate_simple_f(1, dcount, memspace, ierr)
514 call h5screate_simple_f(1, vdims, filespace, ierr, maxdims)
516 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
517 call h5dcreate_f(vtkhdf_grp,
"Connectivity", h5t_native_integer, &
518 filespace, dset_id, ierr, dcpl_id = dcpl_id)
519 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
520 doffset, dcount, ierr)
523 integer,
allocatable :: connectivity(:)
525 allocate(connectivity(local_conn))
526 call vtkhdf_build_connectivity(connectivity, vtk_cell_type, msh, dof, &
528 call h5dwrite_f(dset_id, h5t_native_integer, connectivity, dcount, &
529 ierr, file_space_id = filespace, mem_space_id = memspace, &
531 deallocate(connectivity)
534 call h5dclose_f(dset_id, ierr)
535 call h5sclose_f(filespace, ierr)
536 call h5sclose_f(memspace, ierr)
537 call h5pclose_f(dcpl_id, ierr)
540 call h5lexists_f(vtkhdf_grp,
"Offsets", exists, ierr)
541 if (exists)
call h5ldelete_f(vtkhdf_grp,
"Offsets", ierr)
543 vdims = int(total_offsets, hsize_t)
544 maxdims = h5s_unlimited_f
545 chunkdims = int(
max(1, min(max_local_cells + 1, total_offsets)), hsize_t)
546 dcount = int(local_cells + 1, hsize_t)
547 doffset = int(offsets_offset, hsize_t)
549 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
550 call h5screate_simple_f(1, dcount, memspace, ierr)
551 call h5screate_simple_f(1, vdims, filespace, ierr, maxdims)
553 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
554 call h5dcreate_f(vtkhdf_grp,
"Offsets", h5t_native_integer, &
555 filespace, dset_id, ierr, dcpl_id = dcpl_id)
556 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
557 doffset, dcount, ierr)
560 integer,
allocatable :: offsets(:)
562 allocate(offsets(local_cells + 1))
563 do concurrent(i = 1:local_cells)
564 offsets(i) = (i - 1) * nodes_per_cell
566 offsets(local_cells + 1) = local_conn
567 call h5dwrite_f(dset_id, h5t_native_integer, offsets, dcount, ierr, &
568 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
572 call h5dclose_f(dset_id, ierr)
573 call h5sclose_f(filespace, ierr)
574 call h5sclose_f(memspace, ierr)
575 call h5pclose_f(dcpl_id, ierr)
578 call h5lexists_f(vtkhdf_grp,
"Types", exists, ierr)
579 if (exists)
call h5ldelete_f(vtkhdf_grp,
"Types", ierr)
581 vdims = int(total_cells, hsize_t)
582 maxdims = h5s_unlimited_f
583 chunkdims = int(
max(1, min(max_local_cells, total_cells)), hsize_t)
584 dcount = int(local_cells, hsize_t)
585 doffset = int(cell_offset, hsize_t)
587 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
588 call h5screate_simple_f(1, dcount, memspace, ierr)
589 call h5screate_simple_f(1, vdims, filespace, ierr, maxdims)
591 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
592 call h5dcreate_f(vtkhdf_grp,
"Types", h5t_std_u8le, &
593 filespace, dset_id, ierr, dcpl_id = dcpl_id)
594 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
595 doffset, dcount, ierr)
598 integer(kind=1),
allocatable :: cell_types(:)
599 allocate(cell_types(local_cells), source=vtk_cell_type)
600 call h5dwrite_f(dset_id, h5t_std_u8le, cell_types, dcount, ierr, &
601 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
602 deallocate(cell_types)
605 call h5dclose_f(dset_id, ierr)
606 call h5sclose_f(filespace, ierr)
607 call h5sclose_f(memspace, ierr)
608 call h5pclose_f(dcpl_id, ierr)
612 call h5gopen_f(vtkhdf_grp,
"Steps", grp_id, ierr)
615 call vtkhdf_write_i8_at(grp_id,
"NumberOfParts", int(pe_size, kind=i8), &
621 i8_value = int(counter - 1, kind=i8) * int(pe_size, kind=i8)
622 call vtkhdf_write_i8_at(grp_id,
"PartOffsets", i8_value, counter)
624 i8_value = int(counter - 1, kind=i8) * int(total_points, kind=i8)
625 call vtkhdf_write_i8_at(grp_id,
"PointOffsets", i8_value, counter)
627 i8_value = int(counter - 1, kind=i8) * int(total_cells, kind=i8)
628 call vtkhdf_write_i8_at(grp_id,
"CellOffsets", i8_value, counter)
630 i8_value = int(counter - 1, kind=i8) * int(total_conn, kind=i8)
631 call vtkhdf_write_i8_at(grp_id,
"ConnectivityIdOffsets", i8_value, &
636 call vtkhdf_write_i8_at(grp_id,
"PartOffsets", i8_value, counter)
637 call vtkhdf_write_i8_at(grp_id,
"PointOffsets", i8_value, counter)
638 call vtkhdf_write_i8_at(grp_id,
"CellOffsets", i8_value, counter)
639 call vtkhdf_write_i8_at(grp_id,
"ConnectivityIdOffsets", i8_value, &
643 call h5gclose_f(grp_id, ierr)
646 call h5pclose_f(xf_id, ierr)
648 end subroutine vtkhdf_write_mesh
656 subroutine vtkhdf_write_steps(vtkhdf_grp, counter, t)
657 integer(hid_t),
intent(in) :: vtkhdf_grp
658 integer,
intent(in) :: counter
659 real(kind=rp),
intent(in) :: t
661 integer(hid_t) :: xf_id, H5T_NEKO_DOUBLE
663 integer(hid_t) :: grp_id, dset_id, dcpl_id, filespace, memspace, attr_id
664 integer(hsize_t),
dimension(1) :: step_dims, step_maxdims
665 integer(hsize_t),
dimension(1) :: step_count, step_offset, chunkdims, ddim
666 real(kind=dp),
dimension(1) :: time_value
667 integer(kind=i8) :: i8_value
668 logical :: exists, attr_exists
671 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
672 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
673 h5t_neko_double = h5kind_to_type(dp, h5_real_kind)
676 call h5lexists_f(vtkhdf_grp,
"Steps", exists, ierr)
678 call h5gopen_f(vtkhdf_grp,
"Steps", grp_id, ierr)
680 call h5gcreate_f(vtkhdf_grp,
"Steps", grp_id, ierr)
684 call h5lexists_f(grp_id,
"Values", exists, ierr)
686 call h5dopen_f(grp_id,
"Values", dset_id, ierr)
687 call h5dget_space_f(dset_id, filespace, ierr)
688 call h5sget_simple_extent_dims_f(filespace, step_dims, step_maxdims, &
690 call h5sclose_f(filespace, ierr)
693 if (step_dims(1) .eq. int(counter, hsize_t))
then
694 step_dims(1) = int(counter + 1, hsize_t)
695 call h5dset_extent_f(dset_id, step_dims, ierr)
696 else if (step_dims(1) .lt. int(counter, hsize_t))
then
697 call neko_error(
"VTKHDF: Time steps written out of order.")
700 step_dims(1) = 1_hsize_t
701 step_maxdims(1) = h5s_unlimited_f
702 chunkdims(1) = 1_hsize_t
704 call h5screate_simple_f(1, step_dims, filespace, ierr, step_maxdims)
705 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
706 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
707 call h5dcreate_f(grp_id,
"Values", h5t_neko_double, &
708 filespace, dset_id, ierr, dcpl_id = dcpl_id)
709 call h5sclose_f(filespace, ierr)
710 call h5pclose_f(dcpl_id, ierr)
713 step_count(1) = 1_hsize_t
714 step_offset(1) = int(counter, hsize_t)
716 call h5dget_space_f(dset_id, filespace, ierr)
717 call h5screate_simple_f(1, step_count, memspace, ierr)
718 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
719 step_offset, step_count, ierr)
721 time_value(1) =
real(t, kind=dp)
722 call h5dwrite_f(dset_id, h5t_neko_double, time_value, step_count, ierr, &
723 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
725 call h5sclose_f(memspace, ierr)
726 call h5sclose_f(filespace, ierr)
727 call h5dclose_f(dset_id, ierr)
731 call h5aexists_f(grp_id,
"NSteps", attr_exists, ierr)
732 if (attr_exists)
then
733 call h5aopen_f(grp_id,
"NSteps", attr_id, ierr)
735 call h5screate_f(h5s_scalar_f, filespace, ierr)
736 call h5acreate_f(grp_id,
"NSteps", h5t_native_integer, filespace, &
737 attr_id, ierr, h5p_default_f, h5p_default_f)
738 call h5sclose_f(filespace, ierr)
741 call h5awrite_f(attr_id, h5t_native_integer, counter + 1, ddim, ierr)
743 call h5aclose_f(attr_id, ierr)
744 call h5gclose_f(grp_id, ierr)
745 call h5pclose_f(xf_id, ierr)
747 end subroutine vtkhdf_write_steps
763 subroutine vtkhdf_write_pointdata(vtkhdf_grp, fields, precision, counter, &
765 integer(hid_t),
intent(in) :: vtkhdf_grp
766 type(field_list_t),
intent(inout) :: fields
767 integer,
intent(in) :: precision
768 integer,
intent(in) :: counter
769 character(len=*),
intent(in) :: fname
770 real(kind=rp),
intent(in),
optional :: t
772 integer(kind=i8) :: time_offset
773 integer :: local_points, point_offset, total_points
774 integer(hid_t) :: precision_hdf
775 integer :: ierr, i, j
777 integer(hid_t) :: pointdata_grp, grp_id, step_grp_id
778 integer(hid_t) :: dset_id, dcpl_id, filespace
779 integer(hsize_t),
dimension(1) :: pd_dims1, pd_maxdims1
780 integer(hsize_t),
dimension(2) :: pd_dims2, pd_maxdims2
781 type(field_t),
pointer :: u, v, w
782 character(len=128) :: field_name
783 logical :: exists, is_vector
786 character(len=1024) :: ext_fname, ext_path, src_pattern
787 character(len=1024) :: main_path, main_name, main_suffix
788 integer(hid_t) :: ext_file_id, ext_plist_id, vds_src_space
789 integer(hid_t) :: write_target, attr_id, H5T_NEKO_STRING
790 integer :: mpi_info, mpi_comm
793 integer :: fields_written
794 character(len=128),
allocatable :: name_list(:)
795 logical,
allocatable :: vector_list(:)
797 mpi_info = mpi_info_null%mpi_val
798 mpi_comm = neko_comm%mpi_val
800 n_fields = fields%size()
803 local_points = fields%item_size(1)
804 total_points = fields%items(1)%ptr%dof%global_size()
806 call mpi_exscan(local_points, point_offset, 1, mpi_integer, &
807 mpi_sum, neko_comm, ierr)
811 if (
associated(fields%items(i)%ptr))
then
812 call fields%items(i)%ptr%copy_from(device_to_host, sync = i .eq. n_fields)
817 allocate(name_list(n_fields))
821 call h5lexists_f(vtkhdf_grp,
"PointData", exists, ierr)
822 if (.not. exists)
then
823 call h5gcreate_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
824 call h5gclose_f(pointdata_grp, ierr)
833 call filename_split(fname, main_path, main_name, main_suffix)
834 write(ext_path,
'(A,A,".data/")') trim(main_path), trim(main_name)
835 write(ext_fname,
'(A,I0,".h5")') trim(ext_path), counter
836 write(src_pattern,
'(A,".data/%b.h5")') trim(main_name)
838 if (pe_rank .eq. 0)
then
839 call mkdir(trim(ext_path))
841 call mpi_barrier(neko_comm, ierr)
843 call h5pcreate_f(h5p_file_access_f, ext_plist_id, ierr)
844 call h5pset_fapl_mpio_f(ext_plist_id, mpi_comm, mpi_info, ierr)
845 call h5fcreate_f(trim(ext_fname), h5f_acc_trunc_f, write_target, ierr, &
846 access_prp = ext_plist_id)
847 call h5pclose_f(ext_plist_id, ierr)
851 call h5gopen_f(vtkhdf_grp,
"PointData", write_target, ierr)
858 field_name = fields%name(i)
859 if (field_name .eq.
'p') field_name =
'Pressure'
863 if (field_name .eq.
'u' .or. field_name .eq.
'v' .or. &
864 field_name .eq.
'w')
then
869 select case (trim(fields%name(j)))
879 if (
associated(u) .and.
associated(v) .and.
associated(w))
then
881 field_name =
'Velocity'
888 do j = 1, fields_written
889 if (trim(name_list(j)) .eq. trim(field_name))
then
899 fields_written = fields_written + 1
900 name_list(fields_written) = field_name
905 call write_vector_field(write_target, field_name, u%x, v%x, w%x, &
906 local_points, precision, total_points, point_offset)
908 call write_scalar_field(write_target, field_name, fields%x(i), &
909 local_points, precision, total_points, point_offset)
915 call h5fclose_f(write_target, ierr)
917 call h5gclose_f(write_target, ierr)
926 call h5gopen_f(vtkhdf_grp,
"Steps", step_grp_id, ierr)
927 time_offset = int(counter, kind=i8) * int(total_points, kind=i8)
930 call h5lexists_f(step_grp_id,
"PointDataOffsets", exists, ierr)
932 call h5gopen_f(step_grp_id,
"PointDataOffsets", grp_id, ierr)
934 call h5gcreate_f(step_grp_id,
"PointDataOffsets", grp_id, ierr)
936 do i = 1, fields_written
937 call vtkhdf_write_i8_at(grp_id, trim(name_list(i)), &
938 time_offset, counter)
940 call h5gclose_f(grp_id, ierr)
941 call h5gclose_f(step_grp_id, ierr)
944 call h5gopen_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
946 do i = 1, fields_written
947 field_name = name_list(i)
950 if (counter .eq. 0)
then
952 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
953 precision_hdf = h5kind_to_type(precision, h5_real_kind)
956 pd_dims2 = [3_hsize_t, int(total_points, hsize_t)]
957 call h5screate_simple_f(2, pd_dims2, vds_src_space, ierr)
958 call h5sselect_all_f(vds_src_space, ierr)
960 pd_maxdims2 = [3_hsize_t, h5s_unlimited_f]
961 call h5screate_simple_f(2, pd_dims2, filespace, ierr, &
964 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
965 [0_hsize_t, 0_hsize_t], &
966 [1_hsize_t, h5s_unlimited_f], &
968 stride = [3_hsize_t, int(total_points, hsize_t)], &
969 block = [3_hsize_t, int(total_points, hsize_t)])
971 call h5pset_virtual_f(dcpl_id, filespace, trim(src_pattern), &
972 trim(field_name), vds_src_space, ierr)
973 call h5sclose_f(vds_src_space, ierr)
975 call h5dcreate_f(pointdata_grp, trim(field_name), &
976 precision_hdf, filespace, dset_id, ierr, &
978 call h5sclose_f(filespace, ierr)
980 pd_dims1 = int(total_points, hsize_t)
981 call h5screate_simple_f(1, pd_dims1, vds_src_space, ierr)
982 call h5sselect_all_f(vds_src_space, ierr)
984 pd_maxdims1(1) = h5s_unlimited_f
985 call h5screate_simple_f(1, pd_dims1, filespace, ierr, &
988 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
992 stride = [int(total_points, hsize_t)], &
993 block = [int(total_points, hsize_t)])
995 call h5pset_virtual_f(dcpl_id, filespace, trim(src_pattern), &
996 trim(field_name), vds_src_space, ierr)
997 call h5sclose_f(vds_src_space, ierr)
999 call h5dcreate_f(pointdata_grp, trim(field_name), &
1000 precision_hdf, filespace, dset_id, ierr, &
1002 call h5sclose_f(filespace, ierr)
1005 call h5pclose_f(dcpl_id, ierr)
1006 call h5dclose_f(dset_id, ierr)
1010 call h5dopen_f(pointdata_grp, trim(field_name), dset_id, ierr)
1013 pd_dims2 = [3_hsize_t, &
1014 int(counter + 1, hsize_t) * int(total_points, hsize_t)]
1015 call h5dset_extent_f(dset_id, pd_dims2, ierr)
1017 pd_dims1 = int(counter + 1, hsize_t) * int(total_points, hsize_t)
1018 call h5dset_extent_f(dset_id, pd_dims1, ierr)
1021 call h5dclose_f(dset_id, ierr)
1025 call h5gclose_f(pointdata_grp, ierr)
1031 do i = 1, fields_written
1032 field_name = name_list(i)
1034 pd_dims1 = 1_hsize_t
1036 call h5gopen_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
1037 call h5dopen_f(pointdata_grp, trim(field_name), dset_id, ierr)
1039 call h5aexists_f(dset_id,
"Attribute", exists, ierr)
1041 call h5dclose_f(dset_id, ierr)
1042 call h5gclose_f(pointdata_grp, ierr)
1047 call h5screate_f(h5s_scalar_f, filespace, ierr)
1049 call h5tcopy_f(h5t_fortran_s1, h5t_neko_string, ierr)
1050 call h5tset_size_f(h5t_neko_string, int(6, size_t), ierr)
1051 call h5tset_strpad_f(h5t_neko_string, h5t_str_nullterm_f, ierr)
1053 call h5acreate_f(dset_id,
"Attribute", h5t_neko_string, filespace, &
1056 call h5awrite_f(attr_id, h5t_neko_string, [
"Vector"], pd_dims1, ierr)
1058 call h5awrite_f(attr_id, h5t_neko_string, [
"Scalar"], pd_dims1, ierr)
1061 call h5aclose_f(attr_id, ierr)
1062 call h5tclose_f(h5t_neko_string, ierr)
1063 call h5sclose_f(filespace, ierr)
1064 call h5dclose_f(dset_id, ierr)
1065 call h5gclose_f(pointdata_grp, ierr)
1072 deallocate(name_list)
1075 end subroutine vtkhdf_write_pointdata
1092 subroutine vtkhdf_build_connectivity(conn, vtk_type, msh, dof, subdivide)
1093 integer,
intent(inout) :: conn(:)
1094 integer(kind=1),
intent(in) :: vtk_type
1095 type(mesh_t),
intent(in) :: msh
1096 type(dofmap_t),
intent(in) :: dof
1097 logical,
intent(in) :: subdivide
1098 integer :: lx, ly, lz, nelv
1099 integer :: ie, ii, n_pts_per_elem, n_conn_per_elem
1100 integer,
allocatable :: node_order(:)
1106 n_pts_per_elem = lx * ly * lz
1108 if (subdivide .and. vtk_type .eq. int(12, kind=1))
then
1110 else if (subdivide .and. vtk_type .eq. int(9, kind=1))
then
1113 node_order = vtk_ordering(vtk_type, lx, ly, lz)
1116 n_conn_per_elem =
size(node_order)
1118 do concurrent(ie = 1:nelv, ii = 1:n_conn_per_elem)
1120 integer :: idx, base
1121 idx = (ie - 1) * n_conn_per_elem
1122 base = (ie - 1) * n_pts_per_elem
1123 conn(idx + ii) = base + node_order(ii)
1127 deallocate(node_order)
1129 end subroutine vtkhdf_build_connectivity
1143 subroutine vtkhdf_write_numberof(grp, dset_name, value, offset, cnt, &
1144 dcpl, index, xf_id, ierr)
1145 integer(hid_t),
intent(in) :: grp, dcpl, xf_id
1146 character(len=*),
intent(in) :: dset_name
1147 integer(kind=i8),
intent(in) :: value
1148 integer,
intent(in):: index
1149 integer(hsize_t),
dimension(1),
intent(in) :: offset, cnt
1150 integer,
intent(out) :: ierr
1152 integer(hid_t) :: dset_id, fspace, mspace
1153 integer(hsize_t),
dimension(1) :: dims, maxdims
1154 integer(hid_t) :: H5T_NEKO_INTEGER
1157 h5t_neko_integer = h5kind_to_type(i8, h5_integer_kind)
1159 call h5lexists_f(grp, dset_name, exists, ierr)
1161 call h5dopen_f(grp, dset_name, dset_id, ierr)
1162 dims(1) = int(index + 1, hsize_t) * int(pe_size, hsize_t)
1163 call h5dset_extent_f(dset_id, dims, ierr)
1165 dims(1) = int(pe_size, hsize_t)
1166 maxdims(1) = h5s_unlimited_f
1167 call h5screate_simple_f(1, dims, fspace, ierr, maxdims)
1168 call h5dcreate_f(grp, dset_name, h5t_neko_integer, &
1169 fspace, dset_id, ierr, dcpl_id = dcpl)
1170 call h5sclose_f(fspace, ierr)
1173 call h5dget_space_f(dset_id, fspace, ierr)
1174 call h5screate_simple_f(1, cnt, mspace, ierr)
1175 call h5sselect_hyperslab_f(fspace, h5s_select_set_f, offset, cnt, ierr)
1177 call h5dwrite_f(dset_id, h5t_neko_integer,
value, cnt, ierr, &
1178 file_space_id = fspace, mem_space_id = mspace, xfer_prp = xf_id)
1180 call h5sclose_f(mspace, ierr)
1181 call h5sclose_f(fspace, ierr)
1182 call h5dclose_f(dset_id, ierr)
1183 end subroutine vtkhdf_write_numberof
1192 subroutine vtkhdf_write_i8_at(grp_id, name, value, index)
1193 integer(hid_t),
intent(in) :: grp_id
1194 character(len=*),
intent(in) :: name
1195 integer(kind=i8),
intent(in) :: value
1196 integer,
intent(in) :: index
1199 integer(hid_t) :: dset_id, dcpl_id, xf_id, filespace, memspace
1200 integer(hsize_t),
dimension(1) :: dims, maxdims, count, offset, chunkdims
1201 integer(hid_t) :: H5T_NEKO_INTEGER
1204 h5t_neko_integer = h5kind_to_type(i8, h5_integer_kind)
1207 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1208 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1210 call h5lexists_f(grp_id, name, exists, ierr)
1212 call h5dopen_f(grp_id, name, dset_id, ierr)
1213 call h5dget_space_f(dset_id, filespace, ierr)
1214 call h5sget_simple_extent_dims_f(filespace, dims, maxdims, ierr)
1215 call h5sclose_f(filespace, ierr)
1217 if (int(index, hsize_t) .eq. dims(1))
then
1218 dims(1) = int(index + 1, hsize_t)
1219 call h5dset_extent_f(dset_id, dims, ierr)
1220 else if (int(index, hsize_t) .gt. dims(1))
then
1221 call neko_error(
"VTKHDF: Values written out of order.")
1225 maxdims = h5s_unlimited_f
1226 chunkdims = 1_hsize_t
1228 call h5screate_simple_f(1, dims, filespace, ierr, maxdims)
1229 call h5pcreate_f(h5p_dataset_create_f, dcpl_id, ierr)
1230 call h5pset_chunk_f(dcpl_id, 1, chunkdims, ierr)
1231 call h5dcreate_f(grp_id, name, h5t_neko_integer, &
1232 filespace, dset_id, ierr, dcpl_id = dcpl_id)
1233 call h5sclose_f(filespace, ierr)
1234 call h5pclose_f(dcpl_id, ierr)
1238 offset = int(index, hsize_t)
1240 call h5dget_space_f(dset_id, filespace, ierr)
1241 call h5screate_simple_f(1, count, memspace, ierr)
1242 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, offset, count, ierr)
1243 call h5dwrite_f(dset_id, h5t_neko_integer,
value, count, ierr, &
1244 file_space_id = filespace, mem_space_id = memspace, xfer_prp = xf_id)
1246 call h5sclose_f(memspace, ierr)
1247 call h5sclose_f(filespace, ierr)
1248 call h5dclose_f(dset_id, ierr)
1249 call h5pclose_f(xf_id, ierr)
1251 end subroutine vtkhdf_write_i8_at
1264 subroutine write_scalar_field(hdf_root, name, x, n_local, &
1265 precision, n_total, offset)
1266 integer,
intent(in) :: n_local
1267 integer(hid_t),
intent(in) :: hdf_root
1268 character(len=*),
intent(in) :: name
1269 real(kind=rp),
dimension(n_local),
intent(in) :: x
1270 integer,
intent(in),
optional :: precision
1271 integer,
intent(in),
optional :: n_total, offset
1273 integer(hsize_t),
dimension(1) :: dims, dcount, doffset
1274 integer(hid_t) :: xf_id, dset_id, filespace, memspace, precision_hdf
1275 integer :: i, ierr, precision_local, n_tot, off
1278 dcount = int(n_local, hsize_t)
1280 if (
present(n_total))
then
1281 dims = int(n_total, hsize_t)
1283 call mpi_allreduce(n_local, n_tot, 1, mpi_integer, mpi_sum, neko_comm, &
1285 dims = int(n_tot, hsize_t)
1288 if (
present(offset))
then
1289 doffset = int(offset, hsize_t)
1291 call mpi_exscan(n_local, off, 1, mpi_integer, mpi_sum, neko_comm, &
1293 doffset = int(off, hsize_t)
1296 if (
present(precision))
then
1297 precision_local = precision
1299 precision_local = rp
1301 precision_hdf = h5kind_to_type(precision_local, h5_real_kind)
1304 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1305 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1307 call h5screate_simple_f(1, dims, filespace, ierr)
1308 call h5screate_simple_f(1, dcount, memspace, ierr)
1309 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1310 doffset, dcount, ierr)
1312 call h5dcreate_f(hdf_root, trim(name), precision_hdf, &
1313 filespace, dset_id, ierr)
1315 if (precision_local .eq. rp)
then
1316 call h5dwrite_f(dset_id, precision_hdf, x, dcount, ierr, &
1317 file_space_id = filespace, mem_space_id = memspace, &
1320 else if (precision_local .eq. sp)
then
1322 real(kind=sp),
allocatable :: x_sp(:)
1324 allocate(x_sp(n_local))
1325 do concurrent(i = 1:n_local)
1326 x_sp(i) =
real(x(i), sp)
1329 call h5dwrite_f(dset_id, precision_hdf, x_sp, dcount, ierr, &
1330 file_space_id = filespace, mem_space_id = memspace, &
1335 else if (precision_local .eq. dp)
then
1337 real(kind=dp),
allocatable :: x_dp(:)
1339 allocate(x_dp(n_local))
1340 do concurrent(i = 1:n_local)
1341 x_dp(i) =
real(x(i), dp)
1344 call h5dwrite_f(dset_id, precision_hdf, x_dp, dcount, ierr, &
1345 file_space_id = filespace, mem_space_id = memspace, &
1350 else if (precision_local .eq. qp)
then
1352 real(kind=qp),
allocatable :: x_qp(:)
1354 allocate(x_qp(n_local))
1355 do concurrent(i = 1:n_local)
1356 x_qp(i) =
real(x(i), qp)
1359 call h5dwrite_f(dset_id, precision_hdf, x_qp, dcount, ierr, &
1360 file_space_id = filespace, mem_space_id = memspace, &
1366 call neko_error(
"Unsupported precision in HDF5 write_scalar_field")
1369 call h5sclose_f(filespace, ierr)
1370 call h5sclose_f(memspace, ierr)
1371 call h5dclose_f(dset_id, ierr)
1372 call h5pclose_f(xf_id, ierr)
1373 end subroutine write_scalar_field
1388 subroutine write_vector_field(hdf_root, name, u, v, w, n_local, &
1389 precision, n_total, offset)
1390 integer,
intent(in) :: n_local
1391 integer(hid_t),
intent(in) :: hdf_root
1392 character(len=*),
intent(in) :: name
1393 real(kind=rp),
dimension(n_local),
intent(in) :: u, v, w
1394 integer,
intent(in),
optional :: precision
1395 integer,
intent(in),
optional :: n_total, offset
1397 integer(hsize_t),
dimension(2) :: dims, dcount, doffset
1398 integer(hid_t) :: xf_id, dset_id, filespace, memspace, precision_hdf
1399 integer :: i, ierr, precision_local, n_tot, off
1402 dcount = [3_hsize_t, int(n_local, hsize_t)]
1404 if (
present(n_total))
then
1405 dims = [3_hsize_t, int(n_total, hsize_t)]
1407 call mpi_allreduce(n_local, n_tot, 1, mpi_integer, mpi_sum, neko_comm, &
1409 dims = [3_hsize_t, int(n_tot, hsize_t)]
1412 if (
present(offset))
then
1413 doffset = [0_hsize_t, int(offset, hsize_t)]
1415 call mpi_exscan(n_local, off, 1, mpi_integer, mpi_sum, neko_comm, &
1417 doffset = [0_hsize_t, int(off, hsize_t)]
1420 if (
present(precision))
then
1421 precision_local = precision
1423 precision_local = rp
1425 precision_hdf = h5kind_to_type(precision_local, h5_real_kind)
1428 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1429 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1431 call h5screate_simple_f(2, dims, filespace, ierr)
1432 call h5screate_simple_f(2, dcount, memspace, ierr)
1433 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1434 doffset, dcount, ierr)
1436 call h5dcreate_f(hdf_root, trim(name), precision_hdf, filespace, dset_id, &
1439 if (precision_local .eq. sp)
then
1441 real(kind=sp),
allocatable :: f(:,:)
1443 allocate(f(3, n_local))
1444 do concurrent(i = 1:n_local)
1445 f(1, i) =
real(u(i), sp)
1446 f(2, i) =
real(v(i), sp)
1447 f(3, i) =
real(w(i), sp)
1450 call h5dwrite_f(dset_id, precision_hdf, f, dcount, ierr, &
1451 file_space_id = filespace, mem_space_id = memspace, &
1456 else if (precision_local .eq. dp)
then
1458 real(kind=dp),
allocatable :: f(:,:)
1460 allocate(f(3, n_local))
1461 do concurrent(i = 1:n_local)
1462 f(1, i) =
real(u(i), dp)
1463 f(2, i) =
real(v(i), dp)
1464 f(3, i) =
real(w(i), dp)
1467 call h5dwrite_f(dset_id, precision_hdf, f, dcount, ierr, &
1468 file_space_id = filespace, mem_space_id = memspace, &
1473 else if (precision_local .eq. qp)
then
1475 real(kind=qp),
allocatable :: f(:,:)
1477 allocate(f(3, n_local))
1478 do concurrent(i = 1:n_local)
1479 f(1, i) =
real(u(i), qp)
1480 f(2, i) =
real(v(i), qp)
1481 f(3, i) =
real(w(i), qp)
1484 call h5dwrite_f(dset_id, precision_hdf, f, dcount, ierr, &
1485 file_space_id = filespace, mem_space_id = memspace, &
1491 call neko_error(
"Unsupported precision in HDF5 write_vector_field")
1494 call h5sclose_f(filespace, ierr)
1495 call h5sclose_f(memspace, ierr)
1496 call h5dclose_f(dset_id, ierr)
1497 call h5pclose_f(xf_id, ierr)
1498 end subroutine write_vector_field
1506 class(*),
target,
intent(inout) :: data
1507 character(len=1024) :: fname
1508 integer(hid_t) :: plist_id, file_id, vtkhdf_grp
1509 integer :: mpi_info, mpi_comm, counter, ierr
1510 type(field_list_t) :: fields
1514 fname = trim(this%get_base_fname())
1515 counter = this%get_counter() - this%get_start_counter()
1516 if (counter .lt. 0) counter = 0
1518 mpi_info = mpi_info_null%mpi_val
1519 mpi_comm = neko_comm%mpi_val
1522 call h5pcreate_f(h5p_file_access_f, plist_id, ierr)
1523 call h5pset_fapl_mpio_f(plist_id, mpi_comm, mpi_info, ierr)
1525 call h5fopen_f(fname, h5f_acc_rdonly_f, file_id, ierr, &
1526 access_prp = plist_id)
1527 if (ierr .ne. 0)
then
1528 call neko_error(
'Error opening VTKHDF file: ' // trim(fname))
1531 call h5gopen_f(file_id,
"VTKHDF", vtkhdf_grp, ierr)
1532 if (ierr .ne. 0)
then
1533 call h5fclose_f(file_id, ierr)
1534 call h5pclose_f(plist_id, ierr)
1535 call neko_error(
'VTKHDF group not found in file: ' // trim(fname))
1543 call fields%assign_to_field(1, data)
1544 type is (field_list_t)
1545 call fields%assign_to_list(data)
1547 call neko_error(
"Unsupported data type in vtkhdf_file_read")
1550 do i = 1, fields%size()
1551 call vtkhdf_read_field(vtkhdf_grp, fname, counter, fields%get(i))
1553 call fields%copy_from(host_to_device, .true.)
1555 call h5gclose_f(vtkhdf_grp, ierr)
1556 call h5fclose_f(file_id, ierr)
1557 call h5pclose_f(plist_id, ierr)
1558 call h5close_f(ierr)
1573 subroutine vtkhdf_read_field(vtkhdf_grp, fname, counter, fld)
1574 integer(hid_t),
intent(in) :: vtkhdf_grp
1575 character(len=*),
intent(in) :: fname
1576 integer,
intent(in) :: counter
1577 type(field_t),
intent(inout) :: fld
1579 character(len=:),
allocatable :: field_name
1580 integer :: ierr, local_points, total_points, point_offset, component
1581 integer(hid_t) :: pointdata_grp, dset_id, filespace, memspace, xf_id
1582 integer(hid_t) :: dcpl_id, ext_file_id, ext_plist_id, attr_id
1583 integer(hid_t) :: H5T_NEKO_REAL
1584 integer(hsize_t),
dimension(1) :: dcount1, doffset1
1585 integer(hsize_t),
dimension(2) :: dcount2, doffset2
1587 integer(size_t) :: vds_count
1588 character(len=128) :: dset_name
1589 character(len=1024) :: vds_src_file, ext_fname, main_path, main_name, main_suffix
1590 logical :: exists, is_vds
1591 real(kind=rp),
allocatable :: vec_component(:,:)
1592 integer :: mpi_info, mpi_comm, pct_pos, nsteps
1593 character(len=256) :: error_message
1595 field_name = trim(fld%name)
1598 call h5lexists_f(vtkhdf_grp,
"Steps", exists, ierr)
1600 call h5aopen_by_name_f(vtkhdf_grp,
"Steps",
"NSteps", attr_id, ierr)
1601 call h5aread_f(attr_id, h5t_native_integer, nsteps, [1_hsize_t], ierr)
1602 call h5aclose_f(attr_id, ierr)
1604 if (counter .ge. nsteps)
then
1605 write(error_message,
'(A,I0,A,I0)') &
1606 'VTKHDF read: counter ', counter,
' >= NSteps ', nsteps
1607 call neko_error(trim(error_message))
1611 mpi_info = mpi_info_null%mpi_val
1612 mpi_comm = neko_comm%mpi_val
1614 local_points = fld%dof%size()
1615 total_points = fld%dof%global_size()
1617 call mpi_exscan(local_points, point_offset, 1, mpi_integer, &
1618 mpi_sum, neko_comm, ierr)
1620 h5t_neko_real = h5kind_to_type(rp, h5_real_kind)
1623 call h5gopen_f(vtkhdf_grp,
"PointData", pointdata_grp, ierr)
1626 dset_name = trim(field_name)
1627 if (trim(dset_name) .eq.
'p') dset_name =
'Pressure'
1630 call h5lexists_f(pointdata_grp, trim(dset_name), exists, ierr)
1632 if (.not. exists)
then
1633 if (trim(field_name) .eq.
'u' .or. trim(field_name) .eq.
'v' .or. &
1634 trim(field_name) .eq.
'w')
then
1635 call h5lexists_f(pointdata_grp,
"Velocity", exists, ierr)
1637 dset_name =
'Velocity'
1638 select case (trim(field_name))
1650 if (.not. exists)
then
1651 call h5gclose_f(pointdata_grp, ierr)
1652 call neko_error(
'VTKHDF PointData field not found: ' // trim(dset_name))
1656 call h5dopen_f(pointdata_grp, trim(dset_name), dset_id, ierr)
1657 call h5dget_create_plist_f(dset_id, dcpl_id, ierr)
1658 call h5pget_virtual_count_f(dcpl_id, vds_count, ierr)
1659 is_vds = (vds_count .gt. 0_size_t)
1662 call filename_split(fname, main_path, main_name, main_suffix)
1668 call h5pget_virtual_filename_f(dcpl_id, 0_size_t, vds_src_file, ierr)
1669 pct_pos = index(vds_src_file,
'%b')
1671 if (pct_pos .gt. 0)
then
1676 if (vds_src_file(1:1) .eq.
'/')
then
1677 write(ext_fname,
'(A,I0,A)') &
1678 vds_src_file(1:pct_pos-1), counter, &
1679 trim(vds_src_file(pct_pos+2:))
1681 write(ext_fname,
'(A,A,I0,A)') &
1682 trim(main_path), vds_src_file(1:pct_pos-1), counter, &
1683 trim(vds_src_file(pct_pos+2:))
1689 if (int(counter, size_t) .ge. vds_count)
then
1690 call h5pclose_f(dcpl_id, ierr)
1691 call h5dclose_f(dset_id, ierr)
1692 call h5gclose_f(pointdata_grp, ierr)
1693 write(error_message,
'(A,I0,A,I0)') &
1694 'VTKHDF: VDS counter ', counter, &
1695 ' is out of range, number of mappings: ', int(vds_count)
1696 call neko_error(trim(error_message))
1698 call h5pget_virtual_filename_f(dcpl_id, int(counter, size_t), &
1700 if (vds_src_file(1:1) .eq.
'/')
then
1701 ext_fname = trim(vds_src_file)
1703 write(ext_fname,
'(A,A)') trim(main_path), trim(vds_src_file)
1707 call h5pclose_f(dcpl_id, ierr)
1708 call h5dclose_f(dset_id, ierr)
1709 call h5gclose_f(pointdata_grp, ierr)
1711 call h5pcreate_f(h5p_file_access_f, ext_plist_id, ierr)
1712 call h5pset_fapl_mpio_f(ext_plist_id, mpi_comm, mpi_info, ierr)
1713 call h5fopen_f(trim(ext_fname), h5f_acc_rdonly_f, ext_file_id, ierr, &
1714 access_prp = ext_plist_id)
1716 if (ierr .ne. 0)
then
1717 call neko_error(
'VTKHDF: Cannot open VDS source file: ' // &
1722 call h5dopen_f(ext_file_id, trim(dset_name), dset_id, ierr)
1724 call h5pclose_f(ext_plist_id, ierr)
1726 call h5pclose_f(dcpl_id, ierr)
1731 call h5pcreate_f(h5p_dataset_xfer_f, xf_id, ierr)
1732 call h5pset_dxpl_mpio_f(xf_id, h5fd_mpio_collective_f, ierr)
1733 call h5dget_space_f(dset_id, filespace, ierr)
1735 if (trim(dset_name) .eq.
'Velocity' .and. component .ge. 0)
then
1737 dcount2 = [1_hsize_t, int(local_points, hsize_t)]
1738 doffset2 = [int(component, hsize_t), int(point_offset, hsize_t)]
1740 call h5screate_simple_f(2, dcount2, memspace, ierr)
1741 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1742 doffset2, dcount2, ierr)
1744 allocate(vec_component(1, local_points))
1745 call h5dread_f(dset_id, h5t_neko_real, vec_component, dcount2, ierr, &
1746 file_space_id = filespace, mem_space_id = memspace, &
1748 fld%x = reshape(vec_component, shape(fld%x))
1749 deallocate(vec_component)
1752 dcount1 = int(local_points, hsize_t)
1753 doffset1 = int(point_offset, hsize_t)
1755 call h5screate_simple_f(1, dcount1, memspace, ierr)
1756 call h5sselect_hyperslab_f(filespace, h5s_select_set_f, &
1757 doffset1, dcount1, ierr)
1759 call h5dread_f(dset_id, h5t_neko_real, fld%x(1,1,1,1), dcount1, ierr, &
1760 file_space_id = filespace, mem_space_id = memspace, &
1764 call h5sclose_f(memspace, ierr)
1765 call h5sclose_f(filespace, ierr)
1766 call h5dclose_f(dset_id, ierr)
1767 call h5pclose_f(xf_id, ierr)
1770 call h5fclose_f(ext_file_id, ierr)
1772 call h5gclose_f(pointdata_grp, ierr)
1775 end subroutine vtkhdf_read_field
1784 class(*),
target,
intent(in) :: data
1785 real(kind=rp),
intent(in),
optional :: t
1786 call neko_error(
'Neko needs to be built with HDF5 support')
1792 class(*),
target,
intent(inout) :: data
1793 call neko_error(
'Neko needs to be built with HDF5 support')
1810 integer,
intent(in) :: lx, ly, lz
1811 integer :: node_order(8 * (lx - 1) * (ly - 1) * (lz - 1))
1812 integer :: ii, jj, kk, idx
1819 node_order(idx + 1) = (kk - 1) * lx * ly + (jj - 1) * lx + ii - 1
1820 node_order(idx + 2) = (kk - 1) * lx * ly + (jj - 1) * lx + ii
1821 node_order(idx + 3) = (kk - 1) * lx * ly + jj * lx + ii
1822 node_order(idx + 4) = (kk - 1) * lx * ly + jj * lx + ii - 1
1823 node_order(idx + 5) = kk * lx * ly + (jj - 1) * lx + ii - 1
1824 node_order(idx + 6) = kk * lx * ly + (jj - 1) * lx + ii
1825 node_order(idx + 7) = kk * lx * ly + jj * lx + ii
1826 node_order(idx + 8) = kk * lx * ly + jj * lx + ii - 1
1842 integer,
intent(in) :: lx, ly
1843 integer :: node_order(4 * (lx - 1) * (ly - 1))
1844 integer :: ii, jj, idx
1850 node_order(idx + 1) = (jj - 1) * lx + ii - 1
1851 node_order(idx + 2) = (jj - 1) * lx + ii
1852 node_order(idx + 3) = jj * lx + ii
1853 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.
character(len=1024) function vtkhdf_file_get_next_output_fname(this)
Get the physical file name generated by the next write.
subroutine vtkhdf_file_set_precision(this, precision)
Set the precision for VTKHDF output (single or double)
subroutine vtkhdf_file_write(this, data, t)
Write data in HDF5 format (no HDF5 support)
pure integer function, dimension(8 *(lx - 1) *(ly - 1) *(lz - 1)) subdivide_to_hex_ordering(lx, ly, lz)
Build linear hexahedron sub-cell node ordering for a spectral element. Returns an array of 0-based te...
integer, dimension(2), parameter vtkhdf_version
subroutine vtkhdf_file_set_subdivide(this, subdivide)
Enable or disable subdivision of spectral elements into linear sub-cells. When subdivision is enabled...
subroutine vtkhdf_file_read(this, data)
Read data in HDF5 format (no HDF5 support)
character(len=1024) function vtkhdf_file_get_fname(this)
Return the file name with the start counter.
pure integer function, dimension(4 *(lx - 1) *(ly - 1)) subdivide_to_quad_ordering(lx, ly)
Build linear quadrilateral sub-cell node ordering for a spectral element. Returns an array of 0-based...
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.