PB3D  [2.45]
Ideal linear high-n MHD stability in 3-D
HDF5_utilities.f90
Go to the documentation of this file.
1 !------------------------------------------------------------------------------!
5 !------------------------------------------------------------------------------!
7 #include <PB3D_macros.h>
9  use messages
10  use str_utilities, only: i2str, r2str, r2strt
11  use hdf5_vars
12  use hdf5
13 
14  implicit none
15  private
17 #if ldebug
18  public list_all_vars_in_group, &
20 #endif
21 
22 #if ldebug
23  ! global variables
24  logical :: debug_set_1d_vars = .false.
25 #endif
26 
27 contains
79  integer function set_1d_vars(lim_tot,lim_loc,space_id,c_plist_id) &
80  &result(ierr)
81 #if ldebug
82  use num_vars, only: rank
83 #endif
84 
85  character(*), parameter :: rout_name = 'set_1D_vars'
86 
87  ! input / output
88  integer, intent(in) :: lim_tot(:,:)
89  integer, intent(in) :: lim_loc(:,:)
90  integer(HID_T), intent(in), optional :: space_id
91  integer(HID_T), intent(inout), optional :: c_plist_id
92 
93  ! local variables
94  integer :: id, kd ! counters
95  integer :: n_dims ! nr. of dimensions
96  integer :: n_prod(2) ! n_prod(1) = n_1*n_2*..*n_(i-1), n_prod(2) = n_prod(1)*n_i
97  integer :: div_dim ! first divided dimension
98  integer :: chunk_size ! size of chunk
99  integer(HSIZE_T) :: block(1) ! block size in memory
100  integer(HSIZE_T) :: stride(1) ! stride in memory
101  integer(HSIZE_T) :: count(1) ! nr. of repetitions of block in memory
102  integer(HSIZE_T) :: offset(1) ! offset in memory
103  integer(HSIZE_T) :: chunk_dims(1) ! chunk dimensions
104  real(dp) :: max_chunk_size ! maximum 4 GB (from manual)
105  real(dp) :: min_chunk_size ! minimum 10 MB (from experience)
106  character(len=max_str_ln) :: err_msg ! error message
107 #if ldebug
108  integer :: istat ! status
109 #endif
110 
111  ! initialize ierr
112  ierr = 0
113 
114  ! set n_dims
115  n_dims = size(lim_tot,1)
116 
117 #if ldebug
118  if (size(lim_loc,1).ne.n_dims) then
119  ierr = 1
120  err_msg = 'lim_tot and lim_loc are not compatible'
121  chckerr(err_msg)
122  end if
123  if (size(lim_tot,2).ne.2 .or. size(lim_loc,2).ne.2) then
124  ierr = 1
125  err_msg = 'lim_tot and_lim_loc need to contain 2 columns'
126  chckerr(err_msg)
127  end if
128  do id = 1,n_dims
129  if (lim_tot(id,1).gt.lim_loc(id,1) .or. &
130  &lim_tot(id,2).lt.lim_loc(id,2)) then
131  write(*,*) rank, 'lim_tot = ', lim_tot
132  write(*,*) rank, 'lim_loc = ', lim_loc
133  ierr = 1
134  err_msg = 'Total limits must comprise local ones'
135  chckerr(err_msg)
136  end if
137  end do
138 
139  if (debug_set_1d_vars) then
140  write(*,*,iostat=istat) rank, 'in set_1D_vars:'
141  write(*,*,iostat=istat) rank, 'lim_tot_lo = ', lim_tot(:,1)
142  write(*,*,iostat=istat) rank, 'lim_tot_hi = ', lim_tot(:,2)
143  write(*,*,iostat=istat) rank, 'lim_loc_lo = ', lim_loc(:,1)
144  write(*,*,iostat=istat) rank, 'lim_loc_hi = ', lim_loc(:,2)
145  end if
146 #endif
147 
148  ! initialize divided dimension
149  div_dim = n_dims+1
150 
151  ! set hyperslab to be everything if requested
152  if (present(space_id)) then
153  call h5sselect_all_f(space_id,ierr)
154  chckerr('Failed to select hyperslab')
155  end if
156 
157  ! loop over dimensions to possibly restrict hyperslab and set div_dim
158  do id = 1,n_dims
159  ! only restrict hyperslab if local range differ from total one
160  if (lim_loc(id,1).gt.lim_tot(id,1) .or. &
161  &lim_loc(id,2).lt.lim_tot(id,2)) then
162  ! set divided dimension if first time
163  if (div_dim.eq.n_dims+1) div_dim = id
164 
165  ! calculations if hyperslab restriction requested
166  if (present(space_id)) then
167  ! set auxiliary variables
168  n_prod(1) = product(lim_tot(1:id-1,2)-lim_tot(1:id-1,1)+1)
169  n_prod(2) = n_prod(1)*(lim_tot(id,2)-lim_tot(id,1)+1)
170 
171 #if ldebug
172  if (debug_set_1d_vars) then
173  write(*,*,iostat=istat) rank, 'dimension', id, 'of', &
174  &n_dims
175  write(*,*,iostat=istat) rank, 'n_prod = ', n_prod
176  end if
177 #endif
178 
179  block = (lim_loc(id,2)-lim_loc(id,1)+1) * n_prod(1)
180  stride = n_prod(2)
181  offset = (lim_loc(id,1)-lim_tot(id,1)) * n_prod(1)
182  count = 1
183  do kd = id+1,n_dims
184  count = count*(lim_tot(kd,2)-lim_tot(kd,1)+1)
185  end do
186 
187 #if ldebug
188  if (debug_set_1d_vars) then
189  write(*,*,iostat=istat) rank, 'block, offset, stride, &
190  &count = ', block, offset, stride, count
191  end if
192 #endif
193 
194  call h5sselect_hyperslab_f(space_id,h5s_select_and_f,&
195  &offset,count,ierr,stride=stride,block=block)
196  chckerr('Failed to select hyperslab')
197  end if
198 #if ldebug
199  if (debug_set_1d_vars) then
200  write(*,*,iostat=istat) rank, 'total range DIFFERS from &
201  &local'
202  end if
203  else
204  if (debug_set_1d_vars) then
205  write(*,*,iostat=istat) rank, 'total range EQUAL to local'
206  end if
207 #endif
208  end if
209  end do
210 
211  ! set chunk property list if requested
212  max_chunk_size = 4.e9_dp / sizeof(1._dp) ! maximum 4 GB (from manual)
213  min_chunk_size = min(10.e6_dp/sizeof(1._dp),&
214  &product(lim_tot(:,2)-lim_tot(:,1)+1._dp)) ! maximum 10 MB (from experience), or limit to total variable size
215  if (present(c_plist_id)) then
216  ! set up variables
217  chunk_size = 1
218  id = 1
219  do while (chunk_size.le.min_chunk_size .and. id.le.size(lim_tot,1))
220  chunk_size = chunk_size * (lim_tot(id,2)-lim_tot(id,1)+1)
221  id = id + 1
222  end do
223 #if ldebug
224  if (debug_set_1d_vars) then
225  write(*,*,iostat=istat) rank, 'suggested chunk size', chunk_size
226  end if
227 #endif
228  chunk_size = chunk_size / (1 + floor(chunk_size/max_chunk_size)) ! limit to max chunk size
229 #if ldebug
230  if (debug_set_1d_vars) then
231  write(*,*,iostat=istat) rank, 'def. chunk size', chunk_size
232  end if
233 #endif
234 
235  ! set creation property list if provided
236  if (present(c_plist_id)) then
237  chunk_dims = chunk_size
238  call h5pcreate_f(h5p_dataset_create_f,c_plist_id,ierr)
239  chckerr('Failed to create property list')
240  call h5pset_chunk_f(c_plist_id,1,chunk_dims,ierr) ! one dimension for 1D chunk
241  chckerr('Failed to create chunk')
242  end if
243  end if
244  end function set_1d_vars
245 
249  integer function probe_hdf5_group(HDF5_name,group_name,group_exists) &
250  &result(ierr)
251  use mpi_vars, only: hdf5_lock
253 
254  character(*), parameter :: rout_name = 'probe_HDF5_group'
255 
256  ! input / output
257  character(len=*), intent(in) :: hdf5_name
258  character(len=*), intent(in) :: group_name
259  logical, intent(inout) :: group_exists
260 
261  ! local variables
262  integer :: istat ! status
263  integer(HID_T) :: hdf5_i ! file identifier
264  integer(HID_T) :: group_id ! group identifier
265 
266  ! initialize ierr
267  ierr = 0
268 
269  ! initialize FORTRAN predefined datatypes
270  call h5open_f(ierr)
271  chckerr('Failed to initialize HDF5')
272 
273  ! wait for file access in a non-blocking way
274  ierr = lock_req_acc(hdf5_lock,blocking=.false.)
275  chckerr('')
276 
277  ! open the file
278  call h5fopen_f(hdf5_name,h5f_acc_rdonly_f,hdf5_i,ierr)
279  chckerr('Failed to open file. Does it exist?')
280 
281  ! disable error messages
282  call h5eset_auto_f(0,ierr)
283  chckerr('Failed to disable error printing')
284 
285  ! try to open group
286  call h5gopen_f(hdf5_i,group_name,group_id,istat)
287  group_exists = istat.eq.0
288 
289  ! reenable error messages
290  call h5eset_auto_f(1,ierr)
291  chckerr('Failed to enable error printing')
292 
293  ! close group
294  if (group_exists) then
295  call h5gclose_f(group_id,ierr)
296  chckerr('Failed to close head group')
297  end if
298 
299  ! close the HDF5 file
300  call h5fclose_f(hdf5_i,ierr)
301  chckerr('failed to close HDF5 file')
302 
303  ! return lock
304  ierr = lock_return_acc(hdf5_lock)
305  chckerr('')
306 
307  ! close FORTRAN interfaces and HDF5 library.
308  call h5close_f(ierr)
309  chckerr('Failed to close FORTRAN HDF5 interface')
310  end function probe_hdf5_group
311 
312 #if ldebug
313 
318  integer function list_all_vars_in_group(group_id) result(ierr)
319  character(*), parameter :: rout_name = 'list_all_vars_in_group'
320 
321  ! input / output
322  integer(HID_T), intent(in) :: group_id
323 
324  ! local variables
325  integer :: storage_type ! type of storage used in HDF5 file
326  integer :: nr_lnks ! number of links in group
327  integer :: max_corder ! current maximum creation order value for group
328  integer(HSIZE_T) :: id ! counter
329  integer :: id_loc ! local id
330  integer(SIZE_T) :: name_len ! length of name of group
331  character(len=max_str_ln) :: var_name ! name of variable
332 
333  ! get number of objects in group
334  call h5gget_info_f(group_id,storage_type,nr_lnks,max_corder,&
335  &ierr)
336  chckerr('Failed to get group info')
337 
338  ! user output
339  call writo('The group has '//trim(i2str(nr_lnks))//' elements')
340 
341  ! loop over all elements
342  do id = 1,nr_lnks
343  ! get variable name
344  call h5lget_name_by_idx_f(group_id,'.',h5_index_name_f,&
345  &h5_iter_native_f,id-1,var_name,ierr,size=name_len)
346  chckerr('Failed to get name')
347 
348  ! user output
349  id_loc = int(id,1)
350  call writo('Element '//trim(i2str(id_loc))//'/'//&
351  &trim(i2str(nr_lnks))//': '//trim(var_name))
352  end do
353  end function list_all_vars_in_group
354 #endif
355 end module hdf5_utilities
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
num_vars
Numerical variables used by most other modules.
Definition: num_vars.f90:4
num_vars::max_str_ln
integer, parameter, public max_str_ln
maximum length of strings
Definition: num_vars.f90:50
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_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_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
mpi_vars
Variables pertaining to MPI.
Definition: MPI_vars.f90:4
hdf5_utilities::probe_hdf5_group
integer function, public probe_hdf5_group(HDF5_name, group_name, group_exists)
Probe HDF5 file for group existence.
Definition: HDF5_utilities.f90:251
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
num_vars::plot_dir
character(len=5), public plot_dir
directory where to save plots
Definition: num_vars.f90:153
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_utilities::debug_set_1d_vars
logical, public debug_set_1d_vars
set to true to debug set_1D_vars
Definition: HDF5_utilities.f90:24