PB3D  [2.45]
Ideal linear high-n MHD stability in 3-D
HDF5_ops.f90
Go to the documentation of this file.
1 !------------------------------------------------------------------------------!
26 !------------------------------------------------------------------------------!
27 module hdf5_ops
28 #include <PB3D_macros.h>
30  use messages
31  use str_utilities, only: i2str, r2str, r2strt
32  use hdf5_vars
33  use hdf5
34 
35  implicit none
36  private
41 #if ldebug
43 #endif
44 
45 #if ldebug
46  ! global variables
47  logical :: debug_hdf5_ops = .false.
48  logical :: debug_print_hdf5_arrs = .false.
49 #endif
50 
51  ! interfaces
52 
57  interface reset_hdf5_item
59  module procedure reset_hdf5_item_ind
61  module procedure reset_hdf5_item_arr
62  end interface
63 
64 contains
76  integer function open_hdf5_file(file_info,file_name,sym_type,descr,&
77  &ind_plot,cont_plot) result(ierr)
78  use num_vars, only: rank
79  use mpi
80  use files_utilities, only: nextunit
81  use mpi_utilities, only: broadcast_var
82 
83  character(*), parameter :: rout_name = 'open_HDF5_file'
84 
85  ! input / output
86  type(hdf5_file_type), intent(inout) :: file_info
87  character(len=*), intent(in) :: file_name
88  integer, intent(inout), optional :: sym_type
89  character(len=*), intent(in), optional :: descr
90  logical, intent(in), optional :: ind_plot
91  logical, intent(in), optional :: cont_plot
92 
93  ! local variables
94  character(len=max_str_ln) :: full_file_name ! full file name
95  character(len=max_str_ln) :: line ! line in file
96  character(len=max_str_ln) :: err_msg ! error message
97  integer(HID_T) :: hdf5_i ! file identifier
98  integer(HID_T) :: plist_id ! property list identifier
99  integer :: sym_type_loc ! local symmetry type
100  integer :: mpi_comm_loc ! MPI Communicator used
101  integer :: disable_rw ! MPI info to disable read and write
102  integer :: i_st(2) ! indices of sym_type in read string
103  integer :: id ! counter
104  logical :: ind_plot_loc ! local version of ind_plot
105  logical :: cont_plot_loc ! local version of cont_plot
106 
107  ! initialize ierr
108  ierr = 0
109 
110  ! set up local ind_plot
111  ind_plot_loc = .false.
112  if (present(ind_plot)) ind_plot_loc = ind_plot
113 
114  ! set up local cont_plot
115  cont_plot_loc = .false.
116  if (present(cont_plot)) cont_plot_loc = cont_plot
117 
118  ! set up MPI Communicator
119  if (ind_plot_loc) then
120  mpi_comm_loc = mpi_comm_self ! individual plot
121  else
122  mpi_comm_loc = mpi_comm_world ! default world communicator
123  end if
124 
125  ! set up full file name
126  full_file_name = data_dir//'/'//trim(file_name)
127 
128  ! initialize FORTRAN predefined datatypes
129  call h5open_f(ierr)
130  chckerr('Failed to initialize HDF5')
131 
132 #if lIB
133  ! disable file locking
134  call mpi_info_create(disable_rw,ierr)
135  chckerr('Failed to create MPI info')
136  call mpi_info_set(disable_rw,'romio_ds_read','disable',ierr)
137  chckerr('Failed to set MPI info')
138  call mpi_info_set(disable_rw,'romio_ds_write','disable',ierr)
139  chckerr('Failed to set MPI info')
140 #else
141  disable_rw = mpi_info_null
142 #endif
143 
144  ! setup file access property list with parallel I/O access if needed
145  call h5pcreate_f(h5p_file_access_f,plist_id,ierr)
146  chckerr('Failed to create property list')
147  call h5pset_fapl_mpio_f(plist_id,mpi_comm_loc,disable_rw,ierr)
148  chckerr('Failed to set file access property')
149 
150 #if lIB
151  ! free file locking info
152  call mpi_info_free(disable_rw,ierr)
153  chckerr('Failed to free MPI info')
154 #endif
155 
156  ! create or open the file collectively.
157  if (cont_plot_loc) then
158  call h5fopen_f(trim(full_file_name)//'.h5',h5f_acc_rdwr_f,&
159  &hdf5_i,ierr,access_prp=plist_id)
160  chckerr('Failed to open file')
161  else
162  call h5fcreate_f(trim(full_file_name)//'.h5',h5f_acc_trunc_f,&
163  &hdf5_i,ierr,access_prp=plist_id)
164  err_msg = 'Failed to create file. Is '//trim(data_dir)//'/ present?'
165  chckerr(err_msg)
166  end if
167 
168  ! close property list
169  call h5pclose_f(plist_id,ierr)
170  chckerr('Failed to close property list')
171 
172  ! update file info, converting integers and setting name
173  file_info%HDF5_i = hdf5_i
174  file_info%name = file_name
175 
176  ! XDMF operations: only master if parallel plot or current rank if
177  ! individual plot
178  if (ind_plot_loc .or. .not.ind_plot_loc.and.rank.eq.0) then
179  if (cont_plot_loc) then
180  ! open accompanying xmf file
181  open(nextunit(file_info%XDMF_i),status='old',action='read',&
182  &file=trim(full_file_name)//'.xmf',iostat=ierr)
183  chckerr('Failed to open xmf file')
184 
185  ! read symmetry type in fourth line if requested
186  if (present(sym_type)) then
187  do id = 1,4
188  read(file_info%XDMF_i,'(A)',iostat=ierr) line
189  chckerr('Failed to read file')
190  end do
191  i_st(1) = index(line,'Value="')
192  if (i_st(1).eq.0) then
193  ierr = 1
194  chckerr('Can''t find symmetry type')
195  else
196  i_st(1) = i_st(1) + 7
197  end if
198  i_st(2) = index(line(i_st(1):),'"/>') + i_st(1)
199  if (i_st(2).eq.0) then
200  ierr = 1
201  chckerr('Can''t find symmetry type')
202  else
203  i_st(2) = i_st(2) - 2
204  end if
205  read(line(i_st(1):i_st(2)),*,iostat=ierr) sym_type_loc
206  chckerr('Can''t read symmetry type')
207  if (sym_type_loc.ne.sym_type) then
208  ierr = 1
209  err_msg = 'Symmetry type of continued plot does not &
210  &match previous plot'
211  chckerr(err_msg)
212  end if
213  end if
214  else
215  ! open accompanying xmf file
216  open(nextunit(file_info%XDMF_i),status='replace',&
217  &file=trim(full_file_name)//'.xmf',iostat=ierr)
218  chckerr('Failed to create xmf file')
219 
220  ! write header if group master
221  write(unit=file_info%XDMF_i,fmt=xmf_fmt,iostat=ierr) &
222  &'<?xml version="1.0" ?>'
223  chckerr('Failed to write')
224  write(unit=file_info%XDMF_i,fmt=xmf_fmt,iostat=ierr) &
225  &'<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'
226  chckerr('Failed to write')
227  write(unit=file_info%XDMF_i,fmt=xmf_fmt,iostat=ierr) &
228  &'<Xdmf Version="2.0">'
229  chckerr('Failed to write')
230  if (present(sym_type)) then
231  write(unit=file_info%XDMF_i,fmt=xmf_fmt,iostat=ierr) &
232  &'<Information Name="sym_type" &
233  &Value="'//trim(i2str(sym_type))//'"/>'
234  chckerr('Failed to write')
235  end if
236  write(unit=file_info%XDMF_i,fmt=xmf_fmt,iostat=ierr) &
237  &'<Domain>'
238  chckerr('Failed to write')
239  if (present(descr)) then
240  write(unit=file_info%XDMF_i,fmt=xmf_fmt,iostat=ierr) &
241  &'<Information Name="Description">'
242  chckerr('Failed to write')
243  write(unit=file_info%XDMF_i,fmt=xmf_fmt,iostat=ierr) &
244  &trim(descr)
245  chckerr('Failed to write')
246  write(unit=file_info%XDMF_i,fmt=xmf_fmt,iostat=ierr) &
247  &'</Information>'
248  chckerr('Failed to write')
249  end if
250  end if
251  end if
252 
253  ! pass symmetry type to other processes if continued plot
254  if (cont_plot_loc .and. .not.ind_plot_loc .and. present(sym_type)) then
255  ierr = broadcast_var(sym_type)
256  chckerr('')
257  end if
258  end function open_hdf5_file
259 
263  integer function close_hdf5_file(file_info,ind_plot,cont_plot) result(ierr)
264  use num_vars, only: rank
265 
266  character(*), parameter :: rout_name = 'close_HDF5_file'
267 
268  ! input / output
269  type(hdf5_file_type), intent(inout) :: file_info
270  logical, intent(in), optional :: ind_plot
271  logical, intent(in), optional :: cont_plot
272 
273  ! local variables
274  character(len=max_str_ln) :: err_msg ! error message
275  character(len=max_str_ln) :: full_file_name ! full file name
276  integer(HID_T) :: hdf5_i ! file identifier
277  logical :: ind_plot_loc ! local version of ind_plot
278  logical :: cont_plot_loc ! local version of cont_plot
279 
280  ! initialize ierr
281  ierr = 0
282 
283  ! set up local ind_plot
284  ind_plot_loc = .false.
285  if (present(ind_plot)) ind_plot_loc = ind_plot
286 
287  ! set up local cont_plot
288  cont_plot_loc = .false.
289  if (present(cont_plot)) cont_plot_loc = cont_plot
290 
291  ! set full file name and HDF5_i (converting integers)
292  full_file_name = data_dir//'/'//trim(file_info%name)
293  hdf5_i = file_info%HDF5_i
294 
295  ! close the HDF5 file
296  call h5fclose_f(hdf5_i,ierr)
297  chckerr('failed to close HDF5 file')
298 
299  ! close FORTRAN interfaces and HDF5 library.
300  call h5close_f(ierr)
301  err_msg = 'Failed to close FORTRAN HDF5 interface'
302  chckerr(err_msg)
303 
304  ! only master if parallel plot or current rank if individual plot
305  if (ind_plot_loc .or. .not.ind_plot_loc.and.rank.eq.0) then
306  ! XDMF operations: only if not continued plot
307  if (.not.cont_plot_loc) then
308  ! close header
309  write(unit=file_info%XDMF_i,fmt=xmf_fmt,iostat=ierr) &
310  &'</Domain>'
311  chckerr('Failed to write')
312  write(unit=file_info%XDMF_i,fmt=xmf_fmt,iostat=ierr) &
313  &'</Xdmf>'
314  chckerr('Failed to write')
315  end if
316 
317  ! close accompanying xmf file
318  close(file_info%XDMF_i,iostat=ierr)
319  chckerr('Failed to close xmf file')
320 
321  ! user output
322  if (cont_plot_loc) then
323  call writo('Contributed to HDF5/XMF plot in output file "'//&
324  &trim(full_file_name)//'.xmf''')
325  else
326  call writo('Created HDF5/XMF plot in output file "'//&
327  &trim(full_file_name)//'.xmf''')
328  end if
329  end if
330  end function close_hdf5_file
331 
338  integer function add_hdf5_item(file_info,XDMF_item,reset,ind_plot) &
339  &result(ierr)
340  use num_vars, only: rank
341 
342  character(*), parameter :: rout_name = 'add_HDF5_item'
343 
344  ! input / output
345  type(hdf5_file_type), intent(inout) :: file_info
346  type(xml_str_type), intent(inout) :: xdmf_item
347  logical, intent(in), optional :: reset
348  logical, intent(in), optional :: ind_plot
349 
350  ! local variables
351  integer :: id ! counter
352  integer :: item_len ! length of item
353  logical :: reset_loc ! local copy of reset
354  logical :: ind_plot_loc ! local version of ind_plot
355 
356  ! initialize ierr
357  ierr = 0
358 
359  ! set up local ind_plot
360  ind_plot_loc = .false.
361  if (present(ind_plot)) ind_plot_loc = ind_plot
362 
363  ! only group master if parallel plot or current rank if individual plot
364  if (ind_plot_loc .or. .not.ind_plot_loc.and.rank.eq.0) then
365  ! set item_len
366  item_len = size(xdmf_item%xml_str)
367 
368  ! set local reset
369  if (present(reset)) then
370  reset_loc = reset
371  else
372  reset_loc = .false.
373  end if
374 
375  ! write the strings to the file
376  do id = 1,item_len
377  write(unit=file_info%XDMF_i,fmt=xmf_fmt,iostat=ierr) &
378  &trim(xdmf_item%xml_str(id))
379  chckerr('Failed to write HDF5 item')
380  end do
381 
382  ! reset if requested
383  if (reset_loc) call reset_hdf5_item(xdmf_item,ind_plot_loc)
384  end if
385  end function add_hdf5_item
386 
393  integer function print_hdf5_3d_data_item(dataitem_id,file_info,var_name,&
394  &var,dim_tot,loc_dim,loc_offset,init_val,ind_plot,cont_plot) &
395  &result(ierr)
396 
397  use num_vars, only: rank
398 
399  character(*), parameter :: rout_name = 'print_HDF5_3D_data_item'
400 
401  ! input / output
402  type(xml_str_type), intent(inout) :: dataitem_id
403  type(hdf5_file_type), intent(in) :: file_info
404  character(len=*), intent(in) :: var_name
405  real(dp), intent(in) :: var(:,:,:)
406  integer, intent(in) :: dim_tot(3)
407  integer, intent(in), optional :: loc_dim(3)
408  integer, intent(in), optional :: loc_offset(3)
409  real(dp), intent(in), optional :: init_val
410  logical, intent(in), optional :: ind_plot
411  logical, intent(in), optional :: cont_plot
412 
413  ! local variables
414  integer :: id ! counter
415  integer :: loc_dim_loc(3) ! local copy of loc_dim
416  integer :: loc_offset_loc(3) ! local copy of loc_offset
417  integer(HSIZE_T) :: dimsf(3) ! total dataset dimensions
418  integer(HSIZE_T) :: dimsm(3) ! group dataset dimensions
419  integer(HID_T) :: filespace ! dataspace identifier in file
420  integer(HID_T) :: memspace ! Dataspace identifier in memory
421  integer(HID_T) :: plist_id ! property list identifier
422  integer(HID_T) :: dset_id ! dataset identifier
423  integer(HSIZE_T) :: mem_offset(3) ! offset in memory
424  integer(HSIZE_T) :: mem_block(3) ! block size in memory
425  integer(HSIZE_T) :: mem_stride(3) ! stride in memory
426  integer(HSIZE_T) :: mem_count(3) ! nr. of repetitions of block in memory
427  character(len=max_str_ln) :: dim_str ! string with dimensions
428  character(len=max_str_ln) :: err_msg ! error message
429  logical :: ind_plot_loc ! local version of ind_plot
430  logical :: cont_plot_loc ! local version of cont_plot
431  integer(HID_T) :: hdf5_kind_64 ! HDF5 type corresponding to dp
432 #if ldebug
433  integer :: istat ! status
434 #endif
435 
436  ! initialize ierr
437  ierr = 0
438 
439  ! set up local ind_plot
440  ind_plot_loc = .false.
441  if (present(ind_plot)) ind_plot_loc = ind_plot
442 
443  ! set up local cont_plot
444  cont_plot_loc = .false.
445  if (present(cont_plot)) cont_plot_loc = cont_plot
446 
447  ! set HDF5 type corresponding to dp
448  hdf5_kind_64 = h5kind_to_type(dp,h5_real_kind)
449 
450  ! set the group dimensions and offset
451  ierr = check_for_parallel_3d(dim_tot,loc_dim_loc,loc_offset_loc,&
452  &loc_dim,loc_offset)
453  chckerr('')
454 
455  ! create the data spaces for the dataset.
456  dimsf = dim_tot
457  dimsm = loc_dim_loc
458  call h5screate_simple_f(size(dimsf),dimsf,filespace,ierr)
459  chckerr('Failed to create file space')
460  call h5screate_simple_f(size(dimsm),dimsm,memspace,ierr)
461  chckerr('Failed to create memory space')
462 
463  ! open or create data set
464  if (cont_plot_loc) then
465  ! open file data set
466  call h5dopen_f(file_info%HDF5_i,trim(var_name),dset_id,ierr)
467  chckerr('Failed to open file data set')
468 
469  ! get file data space
470  call h5dget_space_f(dset_id,filespace,ierr)
471  chckerr('Failed to get file space')
472  else
473  ! set initial fill value if provided and create data set
474  if (present(init_val)) then
475  call h5pcreate_f(h5p_dataset_create_f,plist_id,ierr)
476  err_msg = 'Failed to create property list'
477  chckerr(err_msg)
478  call h5pset_fill_value_f(plist_id,hdf5_kind_64,init_val,ierr)
479  err_msg = 'Failed to set default fill value property'
480  chckerr(err_msg)
481  call h5dcreate_f(file_info%HDF5_i,trim(var_name),hdf5_kind_64,&
482  &filespace,dset_id,ierr,plist_id)
483  chckerr('Failed to create file data set')
484  call h5pclose_f(plist_id,ierr)
485  chckerr('Failed to close property list')
486  else
487  call h5dcreate_f(file_info%HDF5_i,trim(var_name),hdf5_kind_64,&
488  &filespace,dset_id,ierr)
489  chckerr('Failed to create file data set')
490  end if
491  end if
492 
493  ! select hyperslab in the file.
494  mem_count = 1
495  mem_stride = 1
496  mem_block = loc_dim_loc
497  mem_offset = loc_offset_loc
498  call h5sselect_hyperslab_f(filespace,h5s_select_set_f,mem_offset,&
499  &mem_count,ierr,mem_stride,mem_block)
500  chckerr('Failed to select hyperslab')
501 
502  ! create property list for collective dataset write
503  call h5pcreate_f(h5p_dataset_xfer_f,plist_id,ierr)
504  chckerr('Failed to create property list')
505  if (ind_plot_loc) then
506  plist_id = h5p_default_f
507  else
508  call h5pset_dxpl_mpio_f(plist_id,h5fd_mpio_collective_f,ierr)
509  chckerr('Failed to set parallel property')
510  end if
511 
512  ! write the dataset collectively.
513  call h5dwrite_f(dset_id,hdf5_kind_64,var,dimsf,ierr,&
514  &file_space_id=filespace,mem_space_id=memspace,xfer_prp=plist_id)
515  chckerr('Failed to write data set')
516  call h5pclose_f(plist_id,ierr)
517  chckerr('Failed to close property list')
518 
519  ! close dataspaces.
520  call h5sclose_f(filespace,ierr)
521  chckerr('Unable to close file space')
522  call h5sclose_f(memspace,ierr)
523  chckerr('Unable to close memory space')
524 
525  ! close the dataset.
526  call h5dclose_f(dset_id,ierr)
527  chckerr('Failed to close data set')
528 
529  ! only group master if parallel plot or current rank if individual plot,
530  ! if not continued plot
531  if (.not.cont_plot_loc) then
532  if (ind_plot_loc .or. .not.ind_plot_loc.and.rank.eq.0) then
533  ! set up dimensions string
534  dim_str = ''
535  do id = 1,size(dim_tot)
536  !if (dim_tot(id).gt.1) then
537  dim_str = trim(dim_str)//' '//trim(i2str(dim_tot(id)))
538  !end if
539  end do
540  dataitem_id%name = 'DataItem - '//trim(var_name)
541  allocate(dataitem_id%xml_str(3))
542  dataitem_id%xml_str(1) = '<DataItem Dimensions="'//&
543  &trim(dim_str)//'" NumberType="Float" Precision="8" &
544  &Format="HDF">'
545  dataitem_id%xml_str(2) = trim(file_info%name)//'.h5:/'//&
546  &trim(var_name)
547  dataitem_id%xml_str(3) = '</DataItem>'
548 
549 #if ldebug
550  if (debug_hdf5_ops) write(*,*,iostat=istat) &
551  &'created data item "'//trim(dataitem_id%name)//'"'
552 #endif
553  end if
554  end if
555  contains
556  ! Check whether the dimensions provided are a valid parallel indicator
557  ! or not.
559  integer function check_for_parallel_3d(dim_tot,loc_dim_out,&
560  &loc_offset_out,loc_dim_in,loc_offset_in) result(ierr)
561  character(*), parameter :: rout_name = 'check_for_parallel_3D'
562 
563  ! input / output
564  integer, intent(in) :: dim_tot(3) ! total dimension
565  integer, intent(inout) :: loc_dim_out(3), loc_offset_out(3) ! output group dimension and offset
566  integer, intent(in), optional :: loc_dim_in(3), loc_offset_in(3) ! input group dimension and offset
567 
568  ! local variables
569  character(len=max_str_ln) :: err_msg ! error message
570  integer :: id ! counter
571 
572  ! initialize ierr
573  ierr = 0
574 
575  if (present(loc_dim_in)) then
576  if (.not.present(loc_offset_in)) then
577  err_msg = 'Need to specify offset as well as group &
578  &dimensions'
579  ierr = 1
580  chckerr(err_msg)
581  else
582  loc_dim_out = loc_dim_in
583  loc_offset_out = loc_offset_in
584  end if
585  do id = 1,size(dim_tot)
586  if (loc_dim_in(id).gt.dim_tot(id)) then ! error in parallel file
587  err_msg = 'Total dimension '//trim(i2str(id))//&
588  &' cannot be smaller than group dimension'
589  ierr = 1
590  chckerr(err_msg)
591  end if
592  end do
593  else
594  loc_dim_out = dim_tot
595  loc_offset_out = 0
596  end if
597  end function check_for_parallel_3d
598  end function print_hdf5_3d_data_item
599 
601  subroutine merge_hdf5_3d_data_items(merged_id,dataitem_ids,var_name,&
602  &dim_tot,reset,ind_plot,cont_plot)
603  use num_vars, only: rank
604 
605  ! input / output
606  type(xml_str_type), intent(inout) :: merged_id
607  type(xml_str_type), intent(inout) :: dataitem_ids(:)
608  character(len=*), intent(in) :: var_name
609  integer, intent(in) :: dim_tot(3)
610  logical, intent(in), optional :: reset
611  logical, intent(in), optional :: ind_plot
612  logical, intent(in), optional :: cont_plot
613 
614  ! local variables
615  integer :: dataitem_len ! length of data item
616  integer :: id, jd ! counters
617  integer :: jd_loc ! local jd
618  logical :: reset_loc ! local copy of reset
619  logical :: ind_plot_loc ! local version of ind_plot
620  logical :: cont_plot_loc ! local version of cont_plot
621  character(len=max_str_ln) :: dim_str ! string with dimensions
622  character(len=max_str_ln) :: fun_str ! string with function
623 #if ldebug
624  integer :: istat ! status
625 #endif
626 
627  ! set up local ind_plot
628  ind_plot_loc = .false.
629  if (present(ind_plot)) ind_plot_loc = ind_plot
630 
631  ! set up local cont_plot
632  cont_plot_loc = .false.
633  if (present(cont_plot)) cont_plot_loc = cont_plot
634 
635  ! set local reset
636  reset_loc = .false.
637  if (present(reset)) reset_loc = reset
638 
639  ! only group master if parallel plot or current rank if individual plot,
640  ! if not continued plot
641  if (.not.cont_plot_loc) then
642  if (ind_plot_loc .or. .not.ind_plot_loc.and.rank.eq.0) then
643  ! set dataitem_len
644  dataitem_len = 0
645  do id = 1,size(dataitem_ids)
646  dataitem_len = dataitem_len + size(dataitem_ids(id)%xml_str)
647  end do
648 
649  ! set XDMF attribute ID
650  merged_id%name = 'DataItem - '//trim(var_name)
651  allocate(merged_id%xml_str(dataitem_len+2))
652 
653  ! set up dimensions string
654  dim_str = ''
655  do id = 1,size(dim_tot)
656  !if (dim_tot(id).gt.1) then
657  dim_str = trim(dim_str)//' '//trim(i2str(dim_tot(id)))
658  !end if
659  end do
660  dim_str = trim(dim_str)//' '//trim(i2str(size(dataitem_ids)))
661 
662  ! set up function string
663  fun_str = '"JOIN('
664  do id = 1,size(dataitem_ids)
665  if (id.gt.1) fun_str = trim(fun_str)//','
666  fun_str = trim(fun_str)//' $'//trim(i2str(id-1))
667  end do
668  fun_str = trim(fun_str)//')"'
669 
670  merged_id%xml_str(1) = '<DataItem Dimensions="'//&
671  &trim(dim_str)//'" Function='//trim(fun_str)//&
672  &' ItemType="Function" >'
673  jd_loc = 2
674  do id = 1,size(dataitem_ids)
675  do jd = 1,size(dataitem_ids(id)%xml_str)
676  merged_id%xml_str(jd_loc) = dataitem_ids(id)%xml_str(jd)
677  jd_loc = jd_loc+1
678  end do
679  end do
680  merged_id%xml_str(jd_loc) = '</DataItem>'
681 
682  ! reset if requested
683  if (reset_loc) call reset_hdf5_item(dataitem_ids,ind_plot_loc)
684 
685 #if ldebug
686  if (debug_hdf5_ops) write(*,*,iostat=istat) &
687  &'merged data items into "'//trim(merged_id%name)//'"'
688 #endif
689  end if
690  end if
691  end subroutine merge_hdf5_3d_data_items
692 
694  subroutine print_hdf5_att(att_id,att_dataitem,att_name,att_center,att_type,&
695  &reset,ind_plot)
696 
697  use num_vars, only: rank
698 
699  ! input / output
700  type(xml_str_type), intent(inout) :: att_id
701  type(xml_str_type), intent(inout) :: att_dataitem
702  character(len=*), intent(in) :: att_name
703  integer, intent(in) :: att_center
704  integer, intent(in) :: att_type
705  logical, intent(in), optional :: reset
706  logical, intent(in), optional :: ind_plot
707 
708  ! local variables
709  integer :: dataitem_len ! length of data item
710  integer :: id ! counter
711  logical :: reset_loc ! local copy of reset
712  logical :: ind_plot_loc ! local version of ind_plot
713 #if ldebug
714  integer :: istat ! status
715 #endif
716 
717  ! set up local ind_plot
718  ind_plot_loc = .false.
719  if (present(ind_plot)) ind_plot_loc = ind_plot
720 
721  ! only group master if parallel plot or current rank if individual plot
722  if (ind_plot_loc .or. .not.ind_plot_loc.and.rank.eq.0) then
723  ! set dataitem_len
724  dataitem_len = size(att_dataitem%xml_str)
725 
726  ! set local reset
727  reset_loc = .false.
728  if (present(reset)) reset_loc = reset
729 
730  ! set XDMF attribute ID
731  att_id%name = 'Attribute - '//trim(att_name)
732  allocate(att_id%xml_str(dataitem_len+2))
733  att_id%xml_str(1) = '<Attribute Name="'//trim(att_name)//&
734  &'" AttributeType="'//trim(xdmf_att_types(att_type))//&
735  &'" Center="'//trim(xdmf_center_types(att_center))//'">'
736  do id = 1,dataitem_len
737  att_id%xml_str(id+1) = att_dataitem%xml_str(id)
738  end do
739  att_id%xml_str(dataitem_len+2) = '</Attribute>'
740 
741 #if ldebug
742  if (debug_hdf5_ops) write(*,*,iostat=istat) 'created attribute "'//&
743  &trim(att_id%name)//'"'
744 #endif
745 
746  ! reset if requested
747  if (reset_loc) call reset_hdf5_item(att_dataitem,ind_plot_loc)
748  end if
749  end subroutine print_hdf5_att
750 
754  subroutine print_hdf5_top(top_id,top_type,top_n_elem,ind_plot)
755  use num_vars, only: rank
756 
757  ! input / output
758  type(xml_str_type), intent(inout) :: top_id
759  integer, intent(in) :: top_type
760  integer, intent(in) :: top_n_elem(:)
761  logical, intent(in), optional :: ind_plot
762 
763  ! local variables
764  integer :: id ! counter
765  integer :: n_dims ! nr. of dimensions
766  character(len=max_str_ln) :: work_str ! work string
767  logical :: ind_plot_loc ! local version of ind_plot
768 #if ldebug
769  integer :: istat ! status
770 #endif
771 
772  ! set up local ind_plot
773  ind_plot_loc = .false.
774  if (present(ind_plot)) ind_plot_loc = ind_plot
775 
776  ! only group master if parallel plot or current rank if individual plot
777  if (ind_plot_loc .or. .not.ind_plot_loc.and.rank.eq.0) then
778  ! set n_dims
779  n_dims = size(top_n_elem)
780 
781  ! fill work string
782  work_str = ''
783  do id = n_dims,1,-1
784  !if (top_n_elem(id).gt.1) then
785  work_str = trim(work_str)//' '//trim(i2str(top_n_elem(id)))
786  !end if
787  end do
788 
789  ! set XDMF topology ID
790  top_id%name = 'Topology'
791  allocate(top_id%xml_str(1))
792  top_id%xml_str(1) = '<Topology TopologyType="'//&
793  &trim(xdmf_top_types(top_type))//'" NumberOfElements="'//&
794  &trim(work_str)//'"/>'
795 
796 #if ldebug
797  if (debug_hdf5_ops) write(*,*,iostat=istat) 'created topology "'//&
798  &trim(top_id%name)//'"'
799 #endif
800  end if
801  end subroutine print_hdf5_top
802 
804  subroutine print_hdf5_geom(geom_id,geom_type,geom_dataitems,reset,ind_plot)
805  use num_vars, only: rank
806 
807  ! input / output
808  type(xml_str_type), intent(inout) :: geom_id
809  integer, intent(in) :: geom_type
810  type(xml_str_type), intent(inout) :: geom_dataitems(:)
811  logical, intent(in), optional :: reset
812  logical, intent(in), optional :: ind_plot
813 
814  ! local variables
815  integer :: id, jd ! counters
816  integer :: id_sum ! counter
817  integer, allocatable :: dataitem_len(:) ! length of data item
818  integer :: n_dataitems ! nr. of data items
819  logical :: reset_loc ! local copy of reset
820  logical :: ind_plot_loc ! local version of ind_plot
821 #if ldebug
822  integer :: istat ! status
823 #endif
824 
825  ! set up local ind_plot
826  ind_plot_loc = .false.
827  if (present(ind_plot)) ind_plot_loc = ind_plot
828 
829  ! only group master if parallel plot or current rank if individual plot
830  if (ind_plot_loc .or. .not.ind_plot_loc.and.rank.eq.0) then
831  ! set n_dataitems
832  n_dataitems = size(geom_dataitems)
833 
834  ! set dataitem_len for every data item
835  allocate(dataitem_len(n_dataitems))
836  do id = 1,n_dataitems
837  dataitem_len(id) = size(geom_dataitems(id)%xml_str)
838  end do
839 
840  ! set local reset
841  if (present(reset)) then
842  reset_loc = reset
843  else
844  reset_loc = .false.
845  end if
846 
847  ! set XDMF geometry ID
848  geom_id%name = 'Geometry'
849  allocate(geom_id%xml_str(sum(dataitem_len)+2))
850  geom_id%xml_str(1) = '<Geometry GeometryType="'//&
851  &trim(xdmf_geom_types(geom_type))//'">'
852  id_sum = 2 ! starting index
853  do id = 1,n_dataitems
854  do jd = 1,dataitem_len(id)
855  geom_id%xml_str(id_sum) = geom_dataitems(id)%xml_str(jd)
856  id_sum = id_sum + 1
857  end do
858  end do
859  geom_id%xml_str(id_sum) = '</Geometry>'
860 
861 #if ldebug
862  if (debug_hdf5_ops) write(*,*,iostat=istat) 'created geometry "'//&
863  &trim(geom_id%name)//'"'
864 #endif
865 
866  ! reset if requested
867  if (reset_loc) call reset_hdf5_item(geom_dataitems,ind_plot_loc)
868  end if
869  end subroutine print_hdf5_geom
870 
884  integer function print_hdf5_grid(grid_id,grid_name,grid_type,grid_time,&
885  &grid_top,grid_geom,grid_atts,grid_grids,reset,ind_plot) result(ierr)
886  use num_vars, only: rank
887 
888  character(*), parameter :: rout_name = 'print_HDF5_grid'
889 
890  ! input / output
891  type(xml_str_type), intent(inout) :: grid_id
892  character(len=*), intent(in) :: grid_name
893  integer, intent(in) :: grid_type
894  real(dp), intent(in), optional :: grid_time
895  type(xml_str_type), optional :: grid_top
896  type(xml_str_type), optional :: grid_geom
897  type(xml_str_type), optional :: grid_atts(:)
898  type(xml_str_type), optional :: grid_grids(:)
899  logical, intent(in), optional :: reset
900  logical, intent(in), optional :: ind_plot
901 
902  ! local variables
903  integer :: id, jd ! counters
904  integer :: id_sum ! counter
905  integer :: n_grids ! nr. of grids
906  integer :: n_atts ! nr. of attributes
907  integer :: time_len ! length of time
908  integer :: top_len ! length of topology
909  integer :: geom_len ! length of geometry
910  integer, allocatable :: atts_len(:) ! lengths of attributes
911  integer, allocatable :: grids_len(:) ! lengths of grids
912  logical :: reset_loc ! local copy of reset
913  character(len=max_str_ln) :: err_msg ! error message
914  logical :: ind_plot_loc ! local version of ind_plot
915 #if ldebug
916  integer :: istat ! status
917 #endif
918 
919  ! initialize ierr
920  ierr = 0
921 
922  ! set up local ind_plot
923  ind_plot_loc = .false.
924  if (present(ind_plot)) ind_plot_loc = ind_plot
925 
926  ! only group master if parallel plot or current rank if individual plot
927  if (ind_plot_loc .or. .not.ind_plot_loc.and.rank.eq.0) then
928  ! test whether the correct arguments are provided
929  if (grid_type.eq.1) then ! uniform grid
930  ! no requirements: topology and/or geometry can be defined in
931  ! domain for use throughout
932  else if (grid_type.eq.2 .or. grid_type.eq.3) then ! collection grid
933  if (.not.present(grid_grids)) then
934  ierr = 1
935  err_msg = 'For grid collections, the grids in the &
936  &collection have to be specified'
937  chckerr(err_msg)
938  end if
939  else
940  ierr = 1
941  err_msg = 'Grid type '//trim(i2str(grid_type))//' not supported'
942  chckerr(err_msg)
943  end if
944 
945  ! set geom_len, atts_len and grids_len
946  time_len = 0
947  if (present(grid_time)) time_len = 1
948  top_len = 0
949  if (present(grid_top)) then
950  top_len = size(grid_top%xml_str)
951  else
952  if (grid_type.eq.1) top_len = 1 ! use of general domain topology
953  end if
954  geom_len = 0
955  if (present(grid_geom)) then
956  geom_len = size(grid_geom%xml_str)
957  else
958  if (grid_type.eq.1) geom_len = 1 ! use of general domain geometry
959  end if
960  n_atts = 0
961  if (present(grid_atts)) then
962  n_atts = size(grid_atts)
963  allocate(atts_len(n_atts))
964  atts_len = 0
965  do id = 1,n_atts
966  atts_len(id) = size(grid_atts(id)%xml_str)
967  end do
968  else
969  allocate(atts_len(0))
970  atts_len = 0
971  end if
972  n_grids = 0
973  if (present(grid_grids)) then
974  n_grids = size(grid_grids)
975  allocate(grids_len(n_grids))
976  grids_len = 0
977  do id = 1,n_grids
978  grids_len(id) = size(grid_grids(id)%xml_str)
979  end do
980  else
981  allocate(grids_len(0))
982  grids_len = 0
983  end if
984 
985  ! set local reset
986  if (present(reset)) then
987  reset_loc = reset
988  else
989  reset_loc = .false.
990  end if
991 
992  ! set XDMF grid ID
993  id_sum = 2 ! starting index
994  if (grid_type.eq.1) then ! uniform
995  grid_id%name = 'Uniform Grid - '//trim(grid_name)
996  allocate(&
997  &grid_id%xml_str(time_len+top_len+geom_len+sum(atts_len)+2))
998  grid_id%xml_str(1) = '<Grid Name="'//trim(grid_name)//&
999  &'" GridType="Uniform">'
1000  if (present(grid_time)) then ! time
1001  grid_id%xml_str(id_sum) = '<Time Value="'//&
1002  &trim(r2str(grid_time))//'" />'
1003  id_sum = id_sum + 1
1004  end if
1005  if (present(grid_top)) then
1006  do jd = 1,top_len ! topology
1007  grid_id%xml_str(id_sum) = grid_top%xml_str(jd)
1008  id_sum = id_sum + 1
1009  end do
1010  else
1011  grid_id%xml_str(id_sum) = '<Topology Reference="/Xdmf/&
1012  &Domain/Topology[1]"/>'
1013  id_sum = id_sum + 1
1014  end if
1015  if (present(grid_geom)) then
1016  do jd = 1,geom_len ! geometry
1017  grid_id%xml_str(id_sum) = grid_geom%xml_str(jd)
1018  id_sum = id_sum + 1
1019  end do
1020  else
1021  grid_id%xml_str(id_sum) = '<Geometry Reference="/Xdmf/&
1022  &Domain/Geometry[1]"/>'
1023  id_sum = id_sum + 1
1024  end if
1025  do id = 1,n_atts ! attributes
1026  do jd = 1,atts_len(id)
1027  grid_id%xml_str(id_sum) = grid_atts(id)%xml_str(jd)
1028  id_sum = id_sum + 1
1029  end do
1030  end do
1031  else ! collection
1032  grid_id%name = 'Collection Grid - '//trim(grid_name)
1033  allocate(grid_id%xml_str(time_len+sum(grids_len)+2))
1034  grid_id%xml_str(1) = '<Grid Name="'//trim(grid_name)//&
1035  &'" GridType="Collection" CollectionType="'//&
1036  &trim(xdmf_grid_types(grid_type))//'">'
1037  if (present(grid_time)) then ! time
1038  grid_id%xml_str(id_sum) = '<Time Value="'//&
1039  &trim(r2str(grid_time))//'" />'
1040  id_sum = id_sum + 1
1041  end if
1042  do id = 1,n_grids ! grids
1043  do jd = 1,grids_len(id)
1044  grid_id%xml_str(id_sum) = grid_grids(id)%xml_str(jd)
1045  id_sum = id_sum + 1
1046  end do
1047  end do
1048  end if
1049  grid_id%xml_str(id_sum) = '</Grid>'
1050 
1051 #if ldebug
1052  if (debug_hdf5_ops) write(*,*,iostat=istat) 'created grid "'//&
1053  &trim(grid_id%name)//'"'
1054 #endif
1055 
1056  ! reset if requested
1057  if (reset_loc) then
1058  if (grid_type.eq.1) then
1059  if (present(grid_top)) &
1060  &call reset_hdf5_item(grid_top,ind_plot_loc)
1061  if (present(grid_geom)) &
1062  &call reset_hdf5_item(grid_geom,ind_plot_loc)
1063  if (present(grid_atts)) &
1064  &call reset_hdf5_item(grid_atts,ind_plot_loc)
1065  else if (grid_type.eq.2 .or. grid_type.eq.3) then
1066  if (present(grid_grids)) &
1067  &call reset_hdf5_item(grid_grids,ind_plot_loc)
1068  end if
1069  end if
1070  end if
1071  end function print_hdf5_grid
1072 
1074  integer function create_output_hdf5(HDF5_name) result(ierr)
1075  character(*), parameter :: rout_name = 'create_output_HDF5'
1076 
1077  ! input / output
1078  character(len=*), intent(in) :: hdf5_name
1079 
1080  ! local variables
1081  character(len=max_str_ln) :: err_msg ! error message
1082  integer(HID_T) :: hdf5_i ! file identifier
1083 
1084  ! initialize ierr
1085  ierr = 0
1086 
1087  call lvl_ud(1)
1088 
1089  ! initialize FORTRAN predefined datatypes
1090  call h5open_f(ierr)
1091  chckerr('Failed to initialize HDF5')
1092 
1093  ! create the file by group master
1094  call h5fcreate_f(trim(hdf5_name),h5f_acc_trunc_f,hdf5_i,ierr)
1095  err_msg = 'Failed to create file "'//trim(hdf5_name)//'"'
1096  chckerr(err_msg)
1097 
1098  ! close the HDF5 file
1099  call h5fclose_f(hdf5_i,ierr)
1100  chckerr('failed to close HDF5 file')
1101 
1102  ! close FORTRAN interfaces and HDF5 library.
1103  call h5close_f(ierr)
1104  err_msg = 'Failed to close FORTRAN HDF5 interface'
1105  chckerr(err_msg)
1106 
1107  call lvl_ud(-1)
1108 
1109  ! user output
1110  call writo('HDF5 output file '//trim(hdf5_name)//' created')
1111  end function create_output_hdf5
1112 
1130  integer function print_hdf5_arrs(vars,PB3D_name,head_name,rich_lvl,&
1131  &disp_info,ind_print,remove_previous_arrs) result(ierr)
1132  use num_vars, only: n_procs, rank
1133  use mpi
1134  use mpi_vars, only: hdf5_lock
1136  use hdf5_utilities, only: set_1d_vars
1137 
1138  character(*), parameter :: rout_name = 'print_HDF5_arrs'
1139 
1140  ! input / output
1141  type(var_1d_type), intent(in) :: vars(:)
1142  character(len=*), intent(in) :: pb3d_name
1143  character(len=*), intent(in) :: head_name
1144  integer, intent(in), optional :: rich_lvl
1145  logical, intent(in), optional :: disp_info
1146  logical, intent(in), optional :: ind_print
1147  logical, intent(in), optional :: remove_previous_arrs
1148 
1149  ! local variables
1150  integer :: id, jd ! counters
1151  integer :: mpi_comm_loc ! MPI Communicator used
1152  integer :: istat ! status
1153  integer :: n_dims ! nr. of dimensions
1154  integer, allocatable :: lim_tot(:,:) ! total limits
1155  integer, allocatable :: lim_loc(:,:) ! local limits
1156  character(len=max_str_ln) :: err_msg ! error message
1157  character(len=max_str_ln) :: head_name_loc ! local head_name
1158  logical :: ind_print_loc ! local ind_print
1159  logical :: disp_info_loc ! local disp_info
1160  logical :: remove_previous_arrs_loc ! local remove_previous_arrs
1161  logical :: group_exists ! the group exists and does not have to be created
1162  integer(HID_T) :: a_plist_id ! access property list identifier
1163  integer(HID_T) :: x_plist_id ! transfer property list identifier
1164  integer(HID_T) :: chunk_c_plist_id ! chunk create property list identifier
1165  integer(HID_T) :: hdf5_i ! file identifier
1166  integer(HID_T) :: hdf5_kind_64 ! HDF5 type corresponding to dp
1167  integer(HID_T) :: filespace ! dataspace identifier in file
1168  integer(HID_T) :: memspace ! Dataspace identifier in memory
1169  integer(HID_T) :: dset_id ! dataset identifier
1170  integer(HID_T) :: group_id ! group identifier
1171  integer(HID_T) :: head_group_id ! head group identifier
1172  integer(HSIZE_T) :: dimsf(1) ! total dataset dimensions
1173  integer(HSIZE_T) :: dimsm(1) ! group dataset dimensions
1174  integer :: disable_rw ! MPI info to disable read and write
1175 #if ldebug
1176  real :: rdcc_w0 ! Preemption policy.
1177  integer(SIZE_T) :: rdcc_nslots ! Number of chunk slots in the raw data chunk cache hash table.
1178  integer(SIZE_T) :: rdcc_nbytes ! Total size of the raw data chunk cache, in bytes.
1179 #endif
1180 
1181  ! initialize ierr
1182  ierr = 0
1183 
1184  ! set local disp_info
1185  disp_info_loc = .false.
1186  if (present(disp_info)) disp_info_loc = disp_info
1187 
1188  ! set up local head_name
1189  head_name_loc = head_name
1190  if (present(rich_lvl)) then
1191  if (rich_lvl.gt.0) head_name_loc = trim(head_name_loc)//'_R_'//&
1192  &trim(i2str(rich_lvl))
1193  end if
1194 
1195  ! set local remove_previous_arrs
1196  remove_previous_arrs_loc = .false.
1197  if (present(remove_previous_arrs)) remove_previous_arrs_loc = &
1198  &remove_previous_arrs
1199 
1200  ! detect whether individual or collective print
1201  call detect_ind_print(ind_print_loc)
1202  if (present(ind_print)) ind_print_loc = ind_print
1203 
1204  ! set up MPI Communicator
1205  if (ind_print_loc) then
1206  mpi_comm_loc = mpi_comm_self ! individual print
1207  else
1208  mpi_comm_loc = mpi_comm_world ! default world communicator
1209  end if
1210 
1211  ! initialize FORTRAN predefined datatypes
1212  call h5open_f(ierr)
1213  chckerr('Failed to initialize HDF5')
1214 
1215 #if lIB
1216  ! disable file locking
1217  call mpi_info_create(disable_rw,ierr)
1218  chckerr('Failed to create MPI info')
1219  call mpi_info_set(disable_rw,'romio_ds_read','disable',ierr)
1220  chckerr('Failed to set MPI info')
1221  call mpi_info_set(disable_rw,'romio_ds_write','disable',ierr)
1222  chckerr('Failed to set MPI info')
1223 #else
1224  disable_rw = mpi_info_null
1225 #endif
1226 
1227  ! setup file access property list with parallel I/O access if needed
1228  call h5pcreate_f(h5p_file_access_f,a_plist_id,ierr)
1229  chckerr('Failed to create property list')
1230  if (ind_print_loc) then
1231  call h5pset_fapl_stdio_f(a_plist_id,ierr)
1232  else
1233  call h5pset_fapl_mpio_f(a_plist_id,mpi_comm_loc,disable_rw,ierr)
1234  end if
1235  chckerr('Failed to set file access property')
1236 
1237 #if lIB
1238  ! free file locking info
1239  call mpi_info_free(disable_rw,ierr)
1240  chckerr('Failed to free MPI info')
1241 #endif
1242 
1243  ! wait for file access if individual print and multiple processes
1244  if (n_procs.gt.1 .and. ind_print_loc) then
1245  ierr = lock_req_acc(hdf5_lock)
1246  chckerr('')
1247  end if
1248 
1249  ! open the file
1250  call h5fopen_f(trim(pb3d_name),h5f_acc_rdwr_f,hdf5_i,ierr,&
1251  &access_prp=a_plist_id)
1252  chckerr('Failed to open file')
1253  call h5pclose_f(a_plist_id,ierr)
1254  chckerr('Failed to close property list')
1255 
1256  ! set HDF5 type corresponding to dp
1257  hdf5_kind_64 = h5kind_to_type(dp,h5_real_kind)
1258 
1259  ! check if head group exists and if not create it
1260  call h5eset_auto_f(0,ierr)
1261  chckerr('Failed to disable error printing')
1262  call h5gopen_f(hdf5_i,trim(head_name_loc),head_group_id,istat)
1263  group_exists = istat.eq.0
1264  call h5eset_auto_f(1,ierr)
1265  if (group_exists .and. remove_previous_arrs_loc) then
1266  call h5gclose_f(head_group_id, ierr)
1267  chckerr('Failed to close head group')
1268  call h5ldelete_f(hdf5_i,trim(head_name_loc),ierr)
1269  chckerr('Failed to delete group')
1270  group_exists = .false.
1271 #if ldebug
1272  if (debug_print_hdf5_arrs) call writo('group "'//&
1273  &trim(head_name_loc)//'" existed and was deleted')
1274 #endif
1275  end if
1276  if (.not.group_exists) then ! group does not exist
1277  call h5gcreate_f(hdf5_i,trim(head_name_loc),head_group_id,ierr)
1278  chckerr('Failed to create group')
1279  end if
1280  chckerr('Failed to enable error printing')
1281 
1282  ! user output
1283  call writo('Write data to PB3D output "'//trim(pb3d_name)//'/'//&
1284  &trim(head_name_loc)//'"')
1285  call lvl_ud(1)
1286 
1287  ! loop over all elements in vars
1288  do id = 1,size(vars)
1289  ! user output
1290  if (disp_info_loc) then
1291  call writo('Writing '//trim(vars(id)%var_name))
1292  end if
1293 
1294  ! check if group exists and if not create it
1295  call h5eset_auto_f(0,ierr)
1296  chckerr('Failed to disable error printing')
1297  call h5gopen_f(head_group_id,trim(vars(id)%var_name),group_id,istat)
1298  group_exists = istat.eq.0
1299  call h5eset_auto_f(1,ierr)
1300  chckerr('Failed to enable error printing')
1301  if (.not.group_exists) then ! group does not exist
1302  ! create group
1303  call h5gcreate_f(head_group_id,trim(vars(id)%var_name),&
1304  &group_id,ierr)
1305  chckerr('Failed to create group')
1306  end if
1307 
1308  ! 1. Data itself
1309 
1310  ! set up local and total limits
1311  n_dims = size(vars(id)%tot_i_min)
1312  allocate(lim_tot(n_dims,2))
1313  allocate(lim_loc(n_dims,2))
1314  lim_tot = &
1315  &reshape([vars(id)%tot_i_min,vars(id)%tot_i_max],[n_dims,2])
1316  lim_loc = &
1317  &reshape([vars(id)%loc_i_min,vars(id)%loc_i_max],[n_dims,2])
1318 
1319  ! set dimsf
1320  dimsf = product(lim_tot(:,2)-lim_tot(:,1)+1) ! file space has total dimensions
1321 
1322  ! create or open data set with filespace
1323  if (.not.group_exists) then ! group did not exist
1324  ! create file data space
1325  call h5screate_simple_f(1,dimsf,filespace,ierr)
1326  chckerr('Failed to create file space')
1327 
1328  ! set up chunk creation property list
1329  ierr = set_1d_vars(lim_tot,lim_loc,c_plist_id=chunk_c_plist_id)
1330  chckerr('')
1331 
1332  ! create file data set in group
1333  call h5dcreate_f(group_id,'var',hdf5_kind_64,filespace,&
1334  &dset_id,ierr,dcpl_id=chunk_c_plist_id)
1335  chckerr('Failed to create file data set')
1336 
1337  ! close chunk property list
1338  call h5pclose_f(chunk_c_plist_id,ierr)
1339  chckerr('Failed to close property list')
1340  else ! group already exists
1341  ! open file data set
1342  call h5dopen_f(group_id,'var',dset_id,ierr)
1343  chckerr('Failed to open file data set')
1344 
1345  ! get file data space
1346  call h5dget_space_f(dset_id,filespace,ierr)
1347  chckerr('Failed to get file space')
1348  end if
1349 
1350 #if ldebug
1351  if (debug_print_hdf5_arrs) then
1352  ! get data access property list
1353  call h5dget_access_plist_f(dset_id,a_plist_id,ierr)
1354  chckerr('Failed to get property list')
1355 
1356  ! get chunk cache
1357  call h5pget_chunk_cache_f(a_plist_id,rdcc_nslots,&
1358  &rdcc_nbytes,rdcc_w0,ierr)
1359  write(*,*,iostat=istat) rank, 'Number of chunk slots in the &
1360  &raw data chunk cache hash table:', rdcc_nslots
1361  write(*,*,iostat=istat) rank, 'Total size of the raw data &
1362  &chunk cache, in Mbytes:', rdcc_nbytes*1.e-6_dp
1363  write(*,*,iostat=istat) rank, 'Preemption Policy:', rdcc_w0
1364  chckerr('Failed to get chunk cache')
1365 
1366  ! close data access property list
1367  call h5pclose_f(a_plist_id,ierr)
1368  chckerr('Failed to close property list')
1369  end if
1370 #endif
1371 
1372  ! set 1D filespace hyperslab selection
1373  ierr = set_1d_vars(lim_tot,lim_loc,space_id=filespace)
1374  chckerr('')
1375 
1376  ! create property list for collective dataset write
1377  call h5pcreate_f(h5p_dataset_xfer_f,x_plist_id,ierr)
1378  chckerr('Failed to create property list')
1379  if (ind_print_loc) then
1380  x_plist_id = h5p_default_f
1381  else
1382  call h5pset_dxpl_mpio_f(x_plist_id,h5fd_mpio_collective_f,ierr)
1383  chckerr('Failed to set parallel property')
1384  end if
1385 
1386  ! set dimsm
1387  dimsm = product(lim_loc(:,2)-lim_loc(:,1)+1) ! memory space has local dimensions
1388 
1389  ! create memory data space
1390  call h5screate_simple_f(1,dimsm,memspace,ierr)
1391  chckerr('Failed to create memory space')
1392 
1393  ! write the dataset collectively.
1394  call h5dwrite_f(dset_id,hdf5_kind_64,vars(id)%p,dimsf,ierr,&
1395  &file_space_id=filespace,mem_space_id=memspace,&
1396  &xfer_prp=x_plist_id)
1397  if (ierr.ne.0) then
1398  call writo('Did you increase max_tot_mem while restarting &
1399  &Richardson or jumping to solution with different grid &
1400  &size?',alert=.true.)
1401  call lvl_ud(1)
1402  call writo('If so, must restart from lvl = 1.')
1403  call writo('Or modify the code to use "remove_previous_arrs".')
1404  call lvl_ud(-1)
1405  end if
1406  chckerr('Failed to write data data set')
1407  call h5pclose_f(x_plist_id,ierr)
1408  chckerr('Failed to close property list')
1409 
1410  ! close dataspaces
1411  call h5sclose_f(filespace,ierr)
1412  chckerr('Unable to close file space')
1413  call h5sclose_f(memspace,ierr)
1414  chckerr('Unable to close memory space')
1415 
1416  ! close the dataset.
1417  call h5dclose_f(dset_id,ierr)
1418  chckerr('Failed to close data set')
1419 
1420  ! 2. Limit information
1421 
1422  ! set dimsf
1423  dimsf = size(lim_tot) ! min. and max. limit value per dimension
1424 
1425  ! create or open data set with filespace
1426  if (.not.group_exists) then ! group did not exist
1427  ! create file data space
1428  call h5screate_simple_f(1,dimsf,filespace,ierr)
1429  chckerr('Failed to create file space')
1430 
1431  ! create file data set in group
1432  call h5dcreate_f(group_id,'lim',h5t_native_integer,&
1433  &filespace,dset_id,ierr)
1434  chckerr('Failed to create file data set')
1435 
1436  ! close dataspace
1437  call h5sclose_f(filespace,ierr)
1438  chckerr('Unable to close file space')
1439  else ! group already exists
1440  ! open file data set
1441  call h5dopen_f(group_id,'lim',dset_id,ierr)
1442  chckerr('Failed to open file data set')
1443  end if
1444 
1445  ! only leader writes
1446  if (rank.eq.0 .or. ind_print_loc) then
1447  ! write the dataset
1448  call h5dwrite_f(dset_id,h5t_native_integer,&
1449  &[vars(id)%tot_i_min,vars(id)%tot_i_max],dimsf,ierr)
1450 
1451  chckerr('Failed to write limit data set')
1452  end if
1453 
1454  ! close the dataset.
1455  call h5dclose_f(dset_id,ierr)
1456  chckerr('Failed to close data set')
1457 
1458  ! deallocate limits
1459  deallocate(lim_tot,lim_loc)
1460 
1461  ! close the group
1462  call h5gclose_f(group_id,ierr)
1463  chckerr('Failed to close group')
1464  end do
1465 
1466  call lvl_ud(-1)
1467 
1468  ! close the head group
1469  call h5gclose_f(head_group_id,ierr)
1470  chckerr('Failed to close group')
1471 
1472  ! close the HDF5 and return lock
1473  call h5fclose_f(hdf5_i,ierr)
1474  chckerr('failed to close HDF5 file')
1475  if (n_procs.gt.1 .and. ind_print_loc) then
1476  ! return lock
1477  ierr = lock_return_acc(hdf5_lock)
1478  chckerr('')
1479  end if
1480 
1481  ! close FORTRAN interfaces and HDF5 library.
1482  call h5close_f(ierr)
1483  err_msg = 'Failed to close FORTRAN HDF5 interface'
1484  chckerr(err_msg)
1485  contains
1486  ! Detects whether individual print.
1488  subroutine detect_ind_print(ind_print)
1489  ! input / output
1490  logical, intent(inout) :: ind_print ! whether an individual or collective print
1491 
1492  ! initialize ind_print to true
1493  ind_print = .true.
1494 
1495  ! one process ensures individual print
1496  if (n_procs.eq.1) return
1497 
1498  ! loop over all elements in vars
1499  do id = 1,size(vars)
1500  do jd = 1,size(vars(id)%tot_i_min)
1501  if (vars(id)%tot_i_min(jd).ne.vars(id)%loc_i_min(jd) .or. &
1502  &vars(id)%tot_i_max(jd).ne.vars(id)%loc_i_max(jd)) then
1503  ind_print = .false.
1504  return
1505  end if
1506  end do
1507  end do
1508  end subroutine
1509  end function print_hdf5_arrs
1510 
1528  integer function read_hdf5_arr(var,PB3D_name,head_name,var_name,rich_lvl,&
1529  &disp_info,lim_loc) result(ierr)
1531  use mpi_vars, only: hdf5_lock
1533 #if ldebug
1535 #endif
1536 
1537  character(*), parameter :: rout_name = 'read_HDF5_arr_ind'
1538 
1539  ! input / output
1540  type(var_1d_type), intent(inout) :: var
1541  character(len=*), intent(in) :: pb3d_name
1542  character(len=*), intent(in) :: head_name
1543  character(len=*), intent(in) :: var_name
1544  integer, intent(in), optional :: rich_lvl
1545  logical, intent(in), optional :: disp_info
1546  integer, intent(in), optional :: lim_loc(:,:)
1547 
1548  ! local variables
1549  character(len=max_str_ln) :: err_msg ! error message
1550  integer(HID_T) :: hdf5_i ! file identifier
1551  integer(HID_T) :: dset_id ! dataset identifier
1552  integer(HID_T) :: hdf5_kind_64 ! HDF5 type corresponding to dp
1553  integer(HID_T) :: group_id ! group identifier
1554  integer(HID_T) :: head_group_id ! head group identifier
1555  integer(HID_T) :: filespace ! dataspace identifier in file
1556  integer(HID_T) :: memspace ! Dataspace identifier in memory
1557  integer(HSIZE_T) :: id ! counter
1558  integer(HSIZE_T) :: data_size ! size of data set
1559  integer(HSIZE_T) :: n_dims ! nr. of dimensions
1560  integer(SIZE_T) :: name_len ! length of name of group
1561  integer :: storage_type ! type of storage used in HDF5 file
1562  integer :: nr_lnks_head ! number of links in head group
1563  integer :: max_corder ! current maximum creation order value for group
1564  integer, allocatable :: lim_tot(:,:) ! total limits
1565  integer, allocatable :: lim_loc_loc(:,:) ! local lim_loc
1566  character(len=max_str_ln) :: name_len_loc ! local copy of name_len
1567  character(len=max_str_ln) :: group_name ! name of group
1568  character(len=max_str_ln) :: head_name_loc ! local head_name
1569  logical :: disp_info_loc ! local disp_info
1570 #if ldebug
1571  integer :: istat ! status
1572 #endif
1573 
1574  ! initialize ierr
1575  ierr = 0
1576 
1577  ! set local disp_info
1578  disp_info_loc = .false.
1579  if (present(disp_info)) disp_info_loc = disp_info
1580 
1581  ! set up local head_name
1582  head_name_loc = head_name
1583  if (present(rich_lvl)) then
1584  if (rich_lvl.gt.0) head_name_loc = trim(head_name_loc)//'_R_'//&
1585  &trim(i2str(rich_lvl))
1586  end if
1587 
1588  ! user output
1589 #if ldebug
1590  if (debug_hdf5_ops) then
1591  write(*,*,iostat=istat) 'Reading data from PB3D output "'//&
1592  &trim(pb3d_name)//'/'//trim(head_name_loc)//'/'//&
1593  &trim(var_name)//'"'
1594  end if
1595 #endif
1596 
1597  ! initialize FORTRAN predefined datatypes
1598  call h5open_f(ierr)
1599  chckerr('Failed to initialize HDF5')
1600 
1601  ! preparation
1602  hdf5_kind_64 = h5kind_to_type(dp,h5_real_kind)
1603 
1604  ! wait for file access in a non-blocking way
1605  ierr = lock_req_acc(hdf5_lock,blocking=.false.)
1606  chckerr('')
1607 
1608  ! user output
1609  if (disp_info_loc) then
1610  call writo('Opening file '//trim(pb3d_name))
1611  end if
1612 
1613  ! open the file
1614  call h5fopen_f(trim(pb3d_name),h5f_acc_rdonly_f,hdf5_i,ierr)
1615  chckerr('Failed to open file')
1616 
1617  ! user output
1618  if (disp_info_loc) then
1619  call writo('Opening variable "'//trim(head_name_loc)//'"')
1620  end if
1621 
1622  ! open head group
1623  call h5gopen_f(hdf5_i,trim(head_name_loc),head_group_id,ierr)
1624  err_msg = 'Failed to open head group "'//trim(head_name_loc)//'"'
1625  chckerr(err_msg)
1626 
1627 #if ldebug
1628  ! display all variables in group
1629  if (disp_info_loc) then
1630  ierr = list_all_vars_in_group(head_group_id)
1631  chckerr('')
1632  end if
1633 #endif
1634 
1635  ! get number of objects in group to allocate vars
1636  call h5gget_info_f(head_group_id,storage_type,nr_lnks_head,&
1637  &max_corder,ierr)
1638  chckerr('Failed to get group info')
1639 
1640  ! iterate over all elements in group to save all acceptable variables
1641  do id = 1, nr_lnks_head
1642  call h5lget_name_by_idx_f(head_group_id,'.',h5_index_name_f,&
1643  &h5_iter_native_f,id-1,group_name,ierr,size=name_len)
1644  chckerr('Failed to get name')
1645 
1646 #if ldebug
1647  ! check length
1648  if (name_len.gt.max_str_ln) then
1649  write(name_len_loc,*) name_len
1650  ierr = 1
1651  err_msg = 'Recompile with max_str_ln > '//trim(name_len_loc)
1652  chckerr(err_msg)
1653  end if
1654 #endif
1655 
1656  if (trim(group_name).ne.trim(var_name)) then ! not found
1657  cycle
1658  end if
1659 
1660  ! user output
1661  if (disp_info_loc) then
1662  call writo('Reading '//trim(group_name))
1663  end if
1664 
1665  ! set name
1666  var%var_name = trim(group_name)
1667 
1668  ! open group
1669  call h5gopen_f(head_group_id,trim(group_name),group_id,ierr)
1670 
1671  chckerr('Failed to open group')
1672 
1673  ! 1. limit information
1674 
1675  ! open limit information dataset
1676  call h5dopen_f(group_id,'lim',dset_id,ierr)
1677  chckerr('Failed to open dataset')
1678 
1679  ! get dataspace
1680  call h5dget_space_f(dset_id,filespace,ierr)
1681  chckerr('Failed to get file space')
1682 
1683  ! get size to allocate the 1D variable
1684  call h5sget_simple_extent_npoints_f(filespace,data_size,ierr)
1685 
1686  chckerr('Failed to get storage size')
1687  n_dims = data_size/2
1688  allocate(var%tot_i_min(n_dims))
1689  allocate(var%tot_i_max(n_dims))
1690 
1691  ! close dataspace
1692  call h5sclose_f(filespace,ierr)
1693  chckerr('Failed to close file space')
1694 
1695  ! allocate helper variables
1696  allocate(lim_tot(n_dims,2))
1697  allocate(lim_loc_loc(n_dims,2))
1698 
1699  ! read into 1D variable
1700  call h5dread_f(dset_id,h5t_native_integer,lim_tot,[2*n_dims],&
1701  &ierr)
1702  chckerr('Failed to read dataset')
1703 
1704  ! set up local limits
1705  if (present(lim_loc)) then
1706  lim_loc_loc = lim_loc
1707  where (lim_loc(:,1).lt.0) lim_loc_loc(:,1) = lim_tot(:,1)
1708  where (lim_loc(:,2).lt.0) lim_loc_loc(:,2) = lim_tot(:,2)
1709  else
1710  lim_loc_loc = lim_tot
1711  end if
1712 
1713  ! copy into limits of var
1714  ! Note: tot_i_min is started from 1, the actual limits in the grid,
1715  ! eq_1, eq_2, X_1, X_2 or sol variables is set by the respective
1716  ! "init" procedure.
1717  var%tot_i_min = 1
1718  var%tot_i_max = lim_loc_loc(:,2)-lim_loc_loc(:,1)+1
1719 
1720  ! close the dataset.
1721  call h5dclose_f(dset_id,ierr)
1722  chckerr('Failed to close data set')
1723 
1724  ! 2. variable
1725 
1726  ! set up local data size to allocate the 1D variable
1727  data_size = product(lim_loc_loc(:,2)-lim_loc_loc(:,1)+1)
1728  allocate(var%p(data_size))
1729 
1730  ! open variable dataset
1731  call h5dopen_f(group_id,'var',dset_id,ierr)
1732  chckerr('Failed to open dataset')
1733 
1734  ! get dataspace
1735  call h5dget_space_f(dset_id,filespace,ierr)
1736  chckerr('Failed to get file space')
1737 
1738  ! set 1D filespace hyperslab selection
1739  ierr = set_1d_vars(lim_tot,lim_loc_loc,space_id=filespace)
1740  chckerr('')
1741 
1742  ! create memory data space
1743  call h5screate_simple_f(1,[data_size],memspace,ierr)
1744  chckerr('Failed to create memory space')
1745 
1746  ! read into 1D variable
1747  call h5dread_f(dset_id,hdf5_kind_64,var%p,[data_size],&
1748  &ierr,mem_space_id=memspace,file_space_id=filespace)
1749  chckerr('Failed to read dataset')
1750 
1751  ! close dataspaces
1752  call h5sclose_f(filespace,ierr)
1753  chckerr('Failed to close file space')
1754  call h5sclose_f(memspace,ierr)
1755  chckerr('Unable to close memory space')
1756 
1757  ! close the dataset.
1758  call h5dclose_f(dset_id,ierr)
1759  chckerr('Failed to close data set')
1760 
1761  ! end of group
1762 
1763  ! deallocate limits
1764  deallocate(lim_tot,lim_loc_loc)
1765 
1766  ! close the group
1767  call h5gclose_f(group_id,ierr)
1768  chckerr('Failed to close group')
1769 
1770  ! exit loop
1771  exit
1772  end do
1773 
1774  ! close the head group
1775  call h5gclose_f(head_group_id,ierr)
1776  chckerr('Failed to close head group')
1777 
1778  ! close the HDF5 file
1779  call h5fclose_f(hdf5_i,ierr)
1780  chckerr('failed to close HDF5 file')
1781 
1782  ! return lock
1783  ierr = lock_return_acc(hdf5_lock)
1784  chckerr('')
1785 
1786  ! close FORTRAN interfaces and HDF5 library.
1787  call h5close_f(ierr)
1788  err_msg = 'Failed to close FORTRAN HDF5 interface'
1789  chckerr(err_msg)
1790  end function read_hdf5_arr
1791 
1793  subroutine reset_hdf5_item_arr(XDMF_items,ind_plot)
1794  use num_vars, only: rank
1795 
1796  ! input / output
1797  type(xml_str_type), intent(inout) :: XDMF_items(:)
1798  logical, intent(in), optional :: ind_plot
1799 
1800  ! local variables
1801  integer :: id ! counter
1802  integer :: n_items ! nr. of items
1803  logical :: ind_plot_loc ! local version of ind_plot
1804 #if ldebug
1805  integer :: istat ! status
1806 #endif
1807 
1808  ! set up local ind_plot
1809  ind_plot_loc = .false.
1810  if (present(ind_plot)) ind_plot_loc = ind_plot
1811 
1812  ! set n_items
1813  n_items = size(xdmf_items)
1814 
1815  ! only group master if parallel plot or current rank if individual plot
1816  if (ind_plot_loc .or. .not.ind_plot_loc.and.rank.eq.0) then
1817  do id = 1,n_items
1818  if (.not.allocated(xdmf_items(id)%xml_str)) then
1819  call writo('Could not reset HDF5 XDMF item "'&
1820  &//trim(xdmf_items(id)%name)//'"',warning=.true.)
1821  else
1822 #if ldebug
1823  if (debug_hdf5_ops) write(*,*,iostat=istat) 'reset "'//&
1824  &trim(xdmf_items(id)%name)//'"'
1825 #endif
1826  xdmf_items(id)%name = ''
1827  deallocate(xdmf_items(id)%xml_str)
1828  end if
1829  end do
1830  end if
1831  end subroutine reset_hdf5_item_arr
1833  subroutine reset_hdf5_item_ind(XDMF_item,ind_plot)
1834  use num_vars, only: rank
1835 
1836  ! input / output
1837  type(xml_str_type), intent(inout) :: XDMF_item
1838  logical, intent(in), optional :: ind_plot
1839 
1840  ! local variables
1841  logical :: ind_plot_loc ! local version of ind_plot
1842 #if ldebug
1843  integer :: istat ! status
1844 #endif
1845 
1846  ! set up local ind_plot
1847  ind_plot_loc = .false.
1848  if (present(ind_plot)) ind_plot_loc = ind_plot
1849 
1850  ! only group master if parallel plot or current rank if individual plot
1851  if (ind_plot_loc .or. .not.ind_plot_loc.and.rank.eq.0) then
1852  if (.not.allocated(xdmf_item%xml_str)) then
1853  call writo('Could not reset HDF5 XDMF item "'&
1854  &//trim(xdmf_item%name)//'"',warning=.true.)
1855  else
1856 #if ldebug
1857  if (debug_hdf5_ops) write(*,*,iostat=istat) 'reset "'//&
1858  &trim(xdmf_item%name)//'"'
1859 #endif
1860  xdmf_item%name = ''
1861  deallocate(xdmf_item%xml_str)
1862  end if
1863  end if
1864  end subroutine reset_hdf5_item_ind
1865 end module hdf5_ops
num_vars::dp
integer, parameter, public dp
double precision
Definition: num_vars.f90:46
num_vars::script_dir
character(len=7), public script_dir
directory where to save scripts for plots
Definition: num_vars.f90:154
mpi_utilities
Numerical utilities related to MPI.
Definition: MPI_utilities.f90:20
hdf5_ops::print_hdf5_geom
subroutine, public print_hdf5_geom(geom_id, geom_type, geom_dataitems, reset, ind_plot)
Prints an HDF5 geometry.
Definition: HDF5_ops.f90:805
num_vars
Numerical variables used by most other modules.
Definition: num_vars.f90:4
hdf5_ops::print_hdf5_3d_data_item
integer function, public print_hdf5_3d_data_item(dataitem_id, file_info, var_name, var, dim_tot, loc_dim, loc_offset, init_val, ind_plot, cont_plot)
Prints an HDF5 data item.
Definition: HDF5_ops.f90:396
num_vars::max_str_ln
integer, parameter, public max_str_ln
maximum length of strings
Definition: num_vars.f90:50
hdf5_ops::print_hdf5_top
subroutine, public print_hdf5_top(top_id, top_type, top_n_elem, ind_plot)
Prints an HDF5 topology.
Definition: HDF5_ops.f90:755
hdf5_utilities::set_1d_vars
integer function, public set_1d_vars(lim_tot, lim_loc, space_id, c_plist_id)
Sets up the chunk property list and/or the 1D hyperslabs that correspond to a local subset of lim_tot...
Definition: HDF5_utilities.f90:81
str_utilities::i2str
elemental character(len=max_str_ln) function, public i2str(k)
Convert an integer to string.
Definition: str_utilities.f90:18
mpi_utilities::lock_req_acc
integer function, public lock_req_acc(lock, blocking)
Request access to lock of a BL (blocking) or optionally a NB (non-blocking) type.
Definition: MPI_utilities.f90:765
hdf5_ops
Operations on HDF5 and XDMF variables.
Definition: HDF5_ops.f90:27
hdf5_vars::xdmf_att_types
character(len=max_str_ln), dimension(2), public xdmf_att_types
possible XDMF attribute types
Definition: HDF5_vars.f90:28
hdf5_ops::read_hdf5_arr
integer function, public read_hdf5_arr(var, PB3D_name, head_name, var_name, rich_lvl, disp_info, lim_loc)
Reads a PB3D output file in HDF5 format.
Definition: HDF5_ops.f90:1530
num_vars::n_procs
integer, public n_procs
nr. of MPI processes
Definition: num_vars.f90:69
hdf5_utilities
Utilities pertaining to HDF5 and XDMF.
Definition: HDF5_utilities.f90:6
hdf5_vars
Variables pertaining to HDF5 and XDMF.
Definition: HDF5_vars.f90:4
hdf5_ops::add_hdf5_item
integer function, public add_hdf5_item(file_info, XDMF_item, reset, ind_plot)
Add an XDMF item to a HDF5 file.
Definition: HDF5_ops.f90:340
hdf5_utilities::list_all_vars_in_group
integer function, public list_all_vars_in_group(group_id)
Lists all variables in a HDF5 group.
Definition: HDF5_utilities.f90:319
num_vars::data_dir
character(len=4), public data_dir
directory where to save data for plots
Definition: num_vars.f90:155
str_utilities
Operations on strings.
Definition: str_utilities.f90:4
str_utilities::r2strt
elemental character(len=max_str_ln) function, public r2strt(k)
Convert a real (double) to string.
Definition: str_utilities.f90:54
hdf5_ops::create_output_hdf5
integer function, public create_output_hdf5(HDF5_name)
Creates an HDF5 output file.
Definition: HDF5_ops.f90:1075
mpi_vars
Variables pertaining to MPI.
Definition: MPI_vars.f90:4
hdf5_vars::xdmf_grid_types
character(len=max_str_ln), dimension(3), public xdmf_grid_types
possible XDMF grid types
Definition: HDF5_vars.f90:30
hdf5_ops::open_hdf5_file
integer function, public open_hdf5_file(file_info, file_name, sym_type, descr, ind_plot, cont_plot)
Opens an HDF5 file and accompanying xmf file and returns the handles.
Definition: HDF5_ops.f90:78
hdf5_vars::xdmf_center_types
character(len=max_str_ln), dimension(2), public xdmf_center_types
possible XDMF attribute center types
Definition: HDF5_vars.f90:29
hdf5_vars::var_1d_type
1D equivalent of multidimensional variables, used for internal HDF5 storage.
Definition: HDF5_vars.f90:48
hdf5_ops::print_hdf5_att
subroutine, public print_hdf5_att(att_id, att_dataitem, att_name, att_center, att_type, reset, ind_plot)
Prints an HDF5 attribute.
Definition: HDF5_ops.f90:696
hdf5_ops::print_hdf5_arrs
integer function, public print_hdf5_arrs(vars, PB3D_name, head_name, rich_lvl, disp_info, ind_print, remove_previous_arrs)
Prints a series of arrays, in the form of an array of pointers, to an HDF5 file.
Definition: HDF5_ops.f90:1132
hdf5_vars::xmf_fmt
character(len=6), public xmf_fmt
format to write the xmf file
Definition: HDF5_vars.f90:20
files_utilities::nextunit
integer function, public nextunit(unit)
Search for available new unit.
Definition: files_utilities.f90:27
str_utilities::r2str
elemental character(len=max_str_ln) function, public r2str(k)
Convert a real (double) to string.
Definition: str_utilities.f90:42
messages::writo
subroutine, public writo(input_str, persistent, error, warning, alert)
Write output to file identified by output_i.
Definition: messages.f90:275
messages
Numerical utilities related to giving output.
Definition: messages.f90:4
hdf5_ops::merge_hdf5_3d_data_items
subroutine, public merge_hdf5_3d_data_items(merged_id, dataitem_ids, var_name, dim_tot, reset, ind_plot, cont_plot)
Joins dataitems in a vector.
Definition: HDF5_ops.f90:603
hdf5_ops::debug_hdf5_ops
logical, public debug_hdf5_ops
set to true to debug general information
Definition: HDF5_ops.f90:47
hdf5_vars::xdmf_geom_types
character(len=max_str_ln), dimension(2), public xdmf_geom_types
possible XDMF geometry types
Definition: HDF5_vars.f90:26
hdf5_ops::close_hdf5_file
integer function, public close_hdf5_file(file_info, ind_plot, cont_plot)
Closes an HDF5 file and writes the accompanying xmf file.
Definition: HDF5_ops.f90:264
messages::lvl_ud
subroutine, public lvl_ud(inc)
Increases/decreases lvl of output.
Definition: messages.f90:254
hdf5_vars::hdf5_file_type
HDF5 data type, containing the information about HDF5 files.
Definition: HDF5_vars.f90:40
num_vars::plot_dir
character(len=5), public plot_dir
directory where to save plots
Definition: num_vars.f90:153
hdf5_ops::reset_hdf5_item
Resets an HDF5 XDMF item.
Definition: HDF5_ops.f90:57
mpi_vars::hdf5_lock
type(lock_type), public hdf5_lock
HDF5 lock.
Definition: MPI_vars.f90:76
mpi_utilities::lock_return_acc
integer function, public lock_return_acc(lock)
Returns access to a lock.
Definition: MPI_utilities.f90:872
num_vars::rank
integer, public rank
MPI rank.
Definition: num_vars.f90:68
hdf5_ops::print_hdf5_grid
integer function, public print_hdf5_grid(grid_id, grid_name, grid_type, grid_time, grid_top, grid_geom, grid_atts, grid_grids, reset, ind_plot)
Prints an HDF5 grid.
Definition: HDF5_ops.f90:886
files_utilities
Numerical utilities related to files.
Definition: files_utilities.f90:4
hdf5_ops::debug_print_hdf5_arrs
logical, public debug_print_hdf5_arrs
set to true to debug print_HDF5_arrs
Definition: HDF5_ops.f90:48
hdf5_vars::xdmf_top_types
character(len=max_str_ln), dimension(2), public xdmf_top_types
possible XDMF topology types
Definition: HDF5_vars.f90:27
hdf5_vars::xml_str_type
XML strings used in XDMF.
Definition: HDF5_vars.f90:33
mpi_utilities::broadcast_var
Wrapper function to broadcast a single variable using MPI.
Definition: MPI_utilities.f90:87