FMS 2025.01.02-dev
Flexible Modeling System
Loading...
Searching...
No Matches
netcdf_add_restart_variable.inc
1!***********************************************************************
2!* GNU Lesser General Public License
3!*
4!* This file is part of the GFDL Flexible Modeling System (FMS).
5!*
6!* FMS is free software: you can redistribute it and/or modify it under
7!* the terms of the GNU Lesser General Public License as published by
8!* the Free Software Foundation, either version 3 of the License, or (at
9!* your option) any later version.
10!*
11!* FMS is distributed in the hope that it will be useful, but WITHOUT
12!* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13!* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14!* for more details.
15!*
16!* You should have received a copy of the GNU Lesser General Public
17!* License along with FMS. If not, see <http://www.gnu.org/licenses/>.
18!***********************************************************************
19!> @file
20!> @brief Routines to add restart variables to a netcdf file with different dimension sizes
21!! for the @ref netcdf_add_restart_variable interface
22
23!> @addtogroup netcdf_io_mod
24!> @{
25
26!> @brief Add a restart variable to a netcdf file.
27subroutine netcdf_add_restart_variable_0d(fileobj, variable_name, vdata, dimensions, &
28 is_optional, chunksizes)
29
30 class(fmsnetcdffile_t), intent(inout) :: fileobj !< File object.
31 character(len=*), intent(in) :: variable_name !< Variable name.
32 class(*), intent(in), target :: vdata !< Pointer to
33 !! variable data.
34 character(len=*), dimension(1), intent(in), optional :: dimensions !< Dimension names.
35 logical, intent(in), optional :: is_optional !< Prevent errors in read-only files
36 !! if a variable does not exist.
37 integer, intent(in), optional :: chunksizes(:) !< netcdf chunksize to use for this variable
38 !! This feature is only
39 !! available for netcdf4 files
40 character(len=8) :: buf
41
42 if (fileobj%is_readonly .and. present(is_optional)) then
43 if (is_optional .and. .not. variable_exists(fileobj, variable_name)) then
44 return
45 endif
46 endif
47 call add_restart_var_to_array(fileobj, variable_name)
48 fileobj%restart_vars(fileobj%num_restart_vars)%data0d => vdata
49 if (.not. fileobj%is_readonly) then
50 call get_data_type_string(vdata, buf)
51 if (present(dimensions)) then
52 if (.not. is_dimension_unlimited(fileobj, dimensions(1), .true.)) then
53 call error("a scalar input variable can only have an unlimited dimension.")
54 endif
55 endif
56 call netcdf_add_variable(fileobj, variable_name, buf, dimensions, &
57 chunksizes=chunksizes)
58 endif
60
61
62!> @brief Wrapper to distinguish interfaces.
63subroutine netcdf_add_restart_variable_0d_wrap(fileobj, variable_name, vdata, &
64 dimensions, is_optional, &
65 chunksizes)
66 type(fmsnetcdffile_t), intent(inout) :: fileobj !< File object.
67 character(len=*), intent(in) :: variable_name !< Variable name.
68 class(*), intent(in), target :: vdata !< Pointer to
69 !! variable data.
70 character(len=*), dimension(1), intent(in), optional :: dimensions !< Dimension names.
71 logical, intent(in), optional :: is_optional !< Prevent errors in read-only files
72 !! if a variable does not exist.
73 integer, intent(in), optional :: chunksizes(:) !< netcdf chunksize to use for this variable
74 !! This feature is only
75 !! available for netcdf4 files
76
77 call netcdf_add_restart_variable(fileobj, variable_name, vdata, dimensions, is_optional, &
78 chunksizes=chunksizes)
80
81
82!> @brief Add a restart variable to a netcdf file.
83subroutine netcdf_add_restart_variable_1d(fileobj, variable_name, vdata, &
84 dimensions, is_optional, &
85 chunksizes)
86 class(fmsnetcdffile_t), intent(inout) :: fileobj !< File object.
87 character(len=*), intent(in) :: variable_name !< Variable name.
88 class(*), dimension(:), intent(in), target :: vdata !< Pointer to
89 !! variable data.
90 character(len=*), dimension(:), intent(in), optional :: dimensions !< Dimension names.
91 logical, intent(in), optional :: is_optional !< Prevent errors in read-only files
92 !! if a variable does not exist.
93 integer, intent(in), optional :: chunksizes(:) !< netcdf chunksize to use for this variable
94 !! This feature is only
95 !! available for netcdf4 files
96 character(len=8) :: buf
97 integer :: ndims
98 integer :: vdata_rank
99
100 if (fileobj%is_readonly .and. present(is_optional)) then
101 if (is_optional .and. .not. variable_exists(fileobj, variable_name)) then
102 return
103 endif
104 endif
105 call add_restart_var_to_array(fileobj, variable_name)
106 fileobj%restart_vars(fileobj%num_restart_vars)%data1d => vdata
107 if (.not. fileobj%is_readonly) then
108 call get_data_type_string(vdata, buf)
109 if (.not. present(dimensions)) then
110 call error("dimension names required if the file is not read-only.")
111 endif
112 ndims = size(dimensions)
113 vdata_rank = size(shape(vdata))
114 if (ndims .eq. vdata_rank+1) then
115 if (.not. is_dimension_unlimited(fileobj, dimensions(ndims), .true.)) then
116 call error("the slowest dimension must be unlimited.")
117 endif
118 elseif (ndims .ne. vdata_rank) then
119 call error("rank mismatch between vdata and dimensions arrays.")
120 endif
121 call netcdf_add_variable(fileobj, variable_name, buf, dimensions, &
122 chunksizes=chunksizes)
123 endif
125
126
127!> @brief Wrapper to distinguish interfaces.
128subroutine netcdf_add_restart_variable_1d_wrap(fileobj, variable_name, vdata, &
129 dimensions, is_optional, &
130 chunksizes)
131 type(fmsnetcdffile_t), intent(inout) :: fileobj !< File object.
132 character(len=*), intent(in) :: variable_name !< Variable name.
133 class(*), dimension(:), intent(in), target :: vdata !< Pointer to
134 !! variable data.
135 character(len=*), dimension(:), intent(in), optional :: dimensions !< Dimension names.
136 logical, intent(in), optional :: is_optional !< Prevent errors in read-only files
137 !! if a variable does not exist.
138 integer, intent(in), optional :: chunksizes(:) !< netcdf chunksize to use for this variable
139 !! This feature is only
140 !! available for netcdf4 files
141
142 call netcdf_add_restart_variable(fileobj, variable_name, vdata, dimensions, is_optional, &
143 chunksizes=chunksizes)
145
146
147!> @brief Add a restart variable to a netcdf file.
148subroutine netcdf_add_restart_variable_2d(fileobj, variable_name, vdata, &
149 dimensions, is_optional, &
150 chunksizes)
151 class(fmsnetcdffile_t), intent(inout) :: fileobj !< File object.
152 character(len=*), intent(in) :: variable_name !< Variable name.
153 class(*), dimension(:,:), intent(in), target :: vdata !< Pointer to
154 !! variable data.
155 character(len=*), dimension(:), intent(in), optional :: dimensions !< Dimension names.
156 logical, intent(in), optional :: is_optional !< Prevent errors in read-only files
157 !! if a variable does not exist.
158 integer, intent(in), optional :: chunksizes(:) !< netcdf chunksize to use for this variable
159 !! This feature is only
160 !! available for netcdf4 files
161 character(len=8) :: buf
162 integer :: ndims
163 integer :: vdata_rank
164
165 if (fileobj%is_readonly .and. present(is_optional)) then
166 if (is_optional .and. .not. variable_exists(fileobj, variable_name)) then
167 return
168 endif
169 endif
170 call add_restart_var_to_array(fileobj, variable_name)
171 fileobj%restart_vars(fileobj%num_restart_vars)%data2d => vdata
172 if (.not. fileobj%is_readonly) then
173 call get_data_type_string(vdata, buf)
174 if (.not. present(dimensions)) then
175 call error("dimension names required if the file is not read-only.")
176 endif
177 ndims = size(dimensions)
178 vdata_rank = size(shape(vdata))
179 if (ndims .eq. vdata_rank+1) then
180 if (.not. is_dimension_unlimited(fileobj, dimensions(ndims), .true.)) then
181 call error("the slowest dimension must be unlimited.")
182 endif
183 elseif (ndims .ne. vdata_rank) then
184 call error("rank mismatch between vdata and dimensions arrays.")
185 endif
186 call netcdf_add_variable(fileobj, variable_name, buf, dimensions, &
187 chunksizes=chunksizes)
188 endif
190
191
192!> @brief Wrapper to distinguish interfaces.
193subroutine netcdf_add_restart_variable_2d_wrap(fileobj, variable_name, vdata, &
194 dimensions, is_optional, &
195 chunksizes)
196 type(fmsnetcdffile_t), intent(inout) :: fileobj !< File object.
197 character(len=*), intent(in) :: variable_name !< Variable name.
198 class(*), dimension(:,:), intent(in), target :: vdata !< Pointer to
199 !! variable data.
200 character(len=*), dimension(:), intent(in), optional :: dimensions !< Dimension names.
201 logical, intent(in), optional :: is_optional !< Prevent errors in read-only files
202 !! if a variable does not exist.
203 integer, intent(in), optional :: chunksizes(:) !< netcdf chunksize to use for this variable
204 !! This feature is only
205 !! available for netcdf4 files
206
207 call netcdf_add_restart_variable(fileobj, variable_name, vdata, dimensions, is_optional, &
208 chunksizes=chunksizes)
210
211
212!> @brief Add a restart variable to a netcdf file.
213subroutine netcdf_add_restart_variable_3d(fileobj, variable_name, vdata, &
214 dimensions, is_optional, &
215 chunksizes)
216 class(fmsnetcdffile_t), intent(inout) :: fileobj !< File object.
217 character(len=*), intent(in) :: variable_name !< Variable name.
218 class(*), dimension(:,:,:), intent(in), target :: vdata !< Pointer to
219 !! variable data.
220 character(len=*), dimension(:), intent(in), optional :: dimensions !< Dimension names.
221 logical, intent(in), optional :: is_optional !< Prevent errors in read-only files
222 !! if a variable does not exist.
223 integer, intent(in), optional :: chunksizes(:) !< netcdf chunksize to use for this variable
224 !! This feature is only
225 !! available for netcdf4 files
226 character(len=8) :: buf
227 integer :: ndims
228 integer :: vdata_rank
229
230 if (fileobj%is_readonly .and. present(is_optional)) then
231 if (is_optional .and. .not. variable_exists(fileobj, variable_name)) then
232 return
233 endif
234 endif
235 call add_restart_var_to_array(fileobj, variable_name)
236 fileobj%restart_vars(fileobj%num_restart_vars)%data3d => vdata
237 if (.not. fileobj%is_readonly) then
238 call get_data_type_string(vdata, buf)
239 if (.not. present(dimensions)) then
240 call error("dimension names required if the file is not read-only.")
241 endif
242 ndims = size(dimensions)
243 vdata_rank = size(shape(vdata))
244 if (ndims .eq. vdata_rank+1) then
245 if (.not. is_dimension_unlimited(fileobj, dimensions(ndims), .true.)) then
246 call error("the slowest dimension must be unlimited.")
247 endif
248 elseif (ndims .ne. vdata_rank) then
249 call error("rank mismatch between vdata and dimensions arrays.")
250 endif
251 call netcdf_add_variable(fileobj, variable_name, buf, dimensions, &
252 chunksizes=chunksizes)
253 endif
255
256
257!> @brief Wrapper to distinguish interfaces.
258subroutine netcdf_add_restart_variable_3d_wrap(fileobj, variable_name, vdata, &
259 dimensions, is_optional, &
260 chunksizes)
261 type(fmsnetcdffile_t), intent(inout) :: fileobj !< File object.
262 character(len=*), intent(in) :: variable_name !< Variable name.
263 class(*), dimension(:,:,:), intent(in), target :: vdata !< Pointer to
264 !! variable data.
265 character(len=*), dimension(:), intent(in), optional :: dimensions !< Dimension names.
266 logical, intent(in), optional :: is_optional !< Prevent errors in read-only files
267 !! if a variable does not exist.
268 integer, intent(in), optional :: chunksizes(:) !< netcdf chunksize to use for this variable
269 !! This feature is only
270 !! available for netcdf4 files
271
272 call netcdf_add_restart_variable(fileobj, variable_name, vdata, dimensions, is_optional, &
273 chunksizes=chunksizes)
275
276
277!> @brief Add a restart variable to a netcdf file.
278subroutine netcdf_add_restart_variable_4d(fileobj, variable_name, vdata, &
279 dimensions, is_optional, &
280 chunksizes)
281 class(fmsnetcdffile_t), intent(inout) :: fileobj !< File object.
282 character(len=*), intent(in) :: variable_name !< Variable name.
283 class(*), dimension(:,:,:,:), intent(in), target :: vdata !< Pointer to
284 !! variable data.
285 character(len=*), dimension(:), intent(in), optional :: dimensions !< Dimension names.
286 logical, intent(in), optional :: is_optional !< Prevent errors in read-only files
287 !! if a variable does not exist.
288 integer, intent(in), optional :: chunksizes(:) !< netcdf chunksize to use for this variable
289 !! This feature is only
290 !! available for netcdf4 files
291 character(len=8) :: buf
292 integer :: ndims
293 integer :: vdata_rank
294
295 if (fileobj%is_readonly .and. present(is_optional)) then
296 if (is_optional .and. .not. variable_exists(fileobj, variable_name)) then
297 return
298 endif
299 endif
300 call add_restart_var_to_array(fileobj, variable_name)
301 fileobj%restart_vars(fileobj%num_restart_vars)%data4d => vdata
302 if (.not. fileobj%is_readonly) then
303 call get_data_type_string(vdata, buf)
304 if (.not. present(dimensions)) then
305 call error("dimension names required if the file is not read-only.")
306 endif
307 ndims = size(dimensions)
308 vdata_rank = size(shape(vdata))
309 if (ndims .eq. vdata_rank+1) then
310 if (.not. is_dimension_unlimited(fileobj, dimensions(ndims), .true.)) then
311 call error("the slowest dimension must be unlimited.")
312 endif
313 elseif (ndims .ne. vdata_rank) then
314 call error("rank mismatch between vdata and dimensions arrays.")
315 endif
316 call netcdf_add_variable(fileobj, variable_name, buf, dimensions, &
317 chunksizes=chunksizes)
318 endif
320
321
322!> @brief Wrapper to distinguish interfaces.
323subroutine netcdf_add_restart_variable_4d_wrap(fileobj, variable_name, vdata, &
324 dimensions, is_optional, &
325 chunksizes)
326 type(fmsnetcdffile_t), intent(inout) :: fileobj !< File object.
327 character(len=*), intent(in) :: variable_name !< Variable name.
328 class(*), dimension(:,:,:,:), intent(in), target :: vdata !< Pointer to
329 !! variable data.
330 character(len=*), dimension(:), intent(in), optional :: dimensions !< Dimension names.
331 logical, intent(in), optional :: is_optional !< Prevent errors in read-only files
332 !! if a variable does not exist.
333 integer, intent(in), optional :: chunksizes(:) !< netcdf chunksize to use for this variable
334 !! This feature is only
335 !! available for netcdf4 files
336
337 call netcdf_add_restart_variable(fileobj, variable_name, vdata, dimensions, is_optional, &
338 chunksizes=chunksizes)
340
341
342!> @brief Add a restart variable to a netcdf file.
343subroutine netcdf_add_restart_variable_5d(fileobj, variable_name, vdata, &
344 dimensions, is_optional, &
345 chunksizes)
346 class(fmsnetcdffile_t), intent(inout) :: fileobj !< File object.
347 character(len=*), intent(in) :: variable_name !< Variable name.
348 class(*), dimension(:,:,:,:,:), intent(in), target :: vdata !< Pointer to
349 !! variable data.
350 character(len=*), dimension(:), intent(in), optional :: dimensions !< Dimension names.
351 logical, intent(in), optional :: is_optional !< Prevent errors in read-only files
352 !! if a variable does not exist.
353 integer, intent(in), optional :: chunksizes(:) !< netcdf chunksize to use for this variable
354 !! This feature is only
355 !! available for netcdf4 files
356 character(len=8) :: buf
357 integer :: ndims
358 integer :: vdata_rank
359
360 if (fileobj%is_readonly .and. present(is_optional)) then
361 if (is_optional .and. .not. variable_exists(fileobj, variable_name)) then
362 return
363 endif
364 endif
365 call add_restart_var_to_array(fileobj, variable_name)
366 fileobj%restart_vars(fileobj%num_restart_vars)%data5d => vdata
367 if (.not. fileobj%is_readonly) then
368 call get_data_type_string(vdata, buf)
369 if (.not. present(dimensions)) then
370 call error("dimension names required if the file is not read-only.")
371 endif
372 ndims = size(dimensions)
373 vdata_rank = size(shape(vdata))
374 if (ndims .eq. vdata_rank+1) then
375 if (.not. is_dimension_unlimited(fileobj, dimensions(ndims), .true.)) then
376 call error("the slowest dimension must be unlimited.")
377 endif
378 elseif (ndims .ne. vdata_rank) then
379 call error("rank mismatch between vdata and dimensions arrays.")
380 endif
381 call netcdf_add_variable(fileobj, variable_name, buf, dimensions, &
382 chunksizes=chunksizes)
383 endif
385
386
387!> @brief Wrapper to distinguish interfaces.
388subroutine netcdf_add_restart_variable_5d_wrap(fileobj, variable_name, vdata, &
389 dimensions, is_optional, &
390 chunksizes)
391 type(fmsnetcdffile_t), intent(inout) :: fileobj !< File object.
392 character(len=*), intent(in) :: variable_name !< Variable name.
393 class(*), dimension(:,:,:,:,:), intent(in), target :: vdata !< Pointer to
394 !! variable data.
395 character(len=*), dimension(:), intent(in), optional :: dimensions !< Dimension names.
396 logical, intent(in), optional :: is_optional !< Prevent errors in read-only files
397 !! if a variable does not exist.
398 integer, intent(in), optional :: chunksizes(:) !< netcdf chunksize to use for this variable
399 !! This feature is only
400 !! available for netcdf4 files
401
402 call netcdf_add_restart_variable(fileobj, variable_name, vdata, dimensions, is_optional, &
403 chunksizes=chunksizes)
405
406!> @brief Registers a regional 2D variable and stores the information needed
407subroutine register_restart_region_2d(fileobj, variable_name, vdata, indices, global_size, pelist, is_root_pe, &
408 x_halo, y_halo, jshift, ishift, is_optional)
409 type(fmsnetcdffile_t), intent(inout) :: fileobj !< File object.
410 character(len=*), intent(in) :: variable_name !< Variable name.
411 class(*), dimension(:,:), intent(in), target :: vdata !< Pointer to variable data
412 integer, dimension(4), intent(in) :: indices!< Indices for the halo region for the variable
413 !! (starting x, ending x, starting y, ending y)
414 integer, dimension(:), intent(in) :: global_size !> Global_size(1:2) == size of the variable in (x,y)
415 integer, dimension(:), intent(in) :: pelist !> List of pelist that have the data for
416 !! the variable
417 logical, intent(in) :: is_root_pe !> Flag indicating if this is the root_pe
418 !! from the pelist
419 integer, intent(in), optional :: x_halo !< Number of halos in x
420 integer, intent(in), optional :: y_halo !< Number of halos in y
421 integer, intent(in), optional :: jshift !< Shift in the x axis (from center)
422 integer, intent(in), optional :: ishift !< Shift in the y axis (from center)
423 logical, intent(in), optional :: is_optional !< Prevent errors in read-only files
424 !! if a variable does not exist.
425
426 integer :: current_var !> Current number of registered variables
427 character(len=7) :: dimnames(4) !> Names of the dimensions for the variable_name
428
429 !> If you reading the file and the variable is optional and not in the file, leave
430 if (fileobj%is_readonly .and. present(is_optional)) then
431 if (is_optional .and. .not. variable_exists(fileobj, variable_name)) then
432 return
433 endif
434 endif
435
436 !> Register the axis for the variable dimension and get the names of the dimensions
437 call set_dimensions(fileobj, fileobj%bc_dimensions, dimnames, global_size)
438 call netcdf_add_restart_variable_2d(fileobj, variable_name, vdata, dimnames(1:3), is_optional)
439
440 !> Save the boundary conditions information to the bc_info type for the given variable
441 current_var = fileobj%num_restart_vars
442 fileobj%restart_vars(current_var)%is_bc_variable = .true.
443 fileobj%restart_vars(current_var)%bc_info%is_root_pe = is_root_pe
444
445 allocate(fileobj%restart_vars(current_var)%bc_info%indices(4))
446 fileobj%restart_vars(current_var)%bc_info%indices = indices
447
448 allocate(fileobj%restart_vars(current_var)%bc_info%global_size(2))
449 fileobj%restart_vars(current_var)%bc_info%global_size = global_size
450
451 if (any(fileobj%io_root .eq. pelist(:))) then
452 allocate(fileobj%restart_vars(current_var)%bc_info%pelist(size(pelist)))
453 fileobj%restart_vars(current_var)%bc_info%pelist = pelist
454 fileobj%restart_vars(current_var)%bc_info%data_on_file_root = .true.
455 else
456 allocate(fileobj%restart_vars(current_var)%bc_info%pelist(size(pelist)+1))
457 fileobj%restart_vars(current_var)%bc_info%pelist = (/ fileobj%io_root, pelist(:) /)
458 fileobj%restart_vars(current_var)%bc_info%data_on_file_root = .false.
459 endif
460
461 fileobj%restart_vars(current_var)%bc_info%x_halo = 0
462 fileobj%restart_vars(current_var)%bc_info%y_halo = 0
463 fileobj%restart_vars(current_var)%bc_info%ishift = 0
464 fileobj%restart_vars(current_var)%bc_info%jshift = 0
465
466 if (present(x_halo)) fileobj%restart_vars(current_var)%bc_info%x_halo = x_halo
467 if (present(y_halo)) fileobj%restart_vars(current_var)%bc_info%y_halo = y_halo
468 if (present(ishift)) fileobj%restart_vars(current_var)%bc_info%ishift = ishift
469 if (present(jshift)) fileobj%restart_vars(current_var)%bc_info%jshift = jshift
470
471end subroutine register_restart_region_2d
472
473!> @brief Registers a regional 3D variable and stores the information needed
474subroutine register_restart_region_3d(fileobj, variable_name, vdata, indices, global_size, pelist, is_root_pe, &
475 x_halo, y_halo, jshift, ishift, is_optional)
476 type(fmsnetcdffile_t), intent(inout) :: fileobj !< File object.
477 character(len=*), intent(in) :: variable_name !< Variable name.
478 class(*), dimension(:,:,:), intent(in), target :: vdata !< Pointer to variable data
479 integer, dimension(4), intent(in) :: indices !< Indices for the halo region for the variable
480 !! (starting x, ending x, starting y, ending y)
481 integer, dimension(:), intent(in) :: global_size !> Global_size(1:3) == size of the
482 !! variable in (x,y,z)
483 integer, dimension(:), intent(in) :: pelist !> List of pelist that have the data for
484 !! the variable
485 logical, intent(in) :: is_root_pe !> Flag indicating if this is the root_pe
486 !! from the pelist
487 integer, intent(in), optional :: x_halo !< Number of halos in x
488 integer, intent(in), optional :: y_halo !< Number of halos in y
489 integer, intent(in), optional :: jshift !< Shift in the y axis (from center)
490 integer, intent(in), optional :: ishift !< Shift in the x axis (from center)
491 logical, intent(in), optional :: is_optional !< Prevent errors in read-only files
492 !! if a variable does not exist.
493
494 integer :: current_var !> Current number of registered variables
495 character(len=7) :: dimnames(4) !> Names of the dimensions for the variable_name
496
497 !> If you reading the file and the variable is optional and not in the file, leave
498 if (fileobj%is_readonly .and. present(is_optional)) then
499 if (is_optional .and. .not. variable_exists(fileobj, variable_name)) then
500 return
501 endif
502 endif
503
504 !> Register the axis for the variable dimension and get the names of the dimensions
505 call set_dimensions(fileobj, fileobj%bc_dimensions, dimnames, global_size)
506 call netcdf_add_restart_variable_3d(fileobj, variable_name, vdata, dimnames(1:4), is_optional)
507
508 !> Save the boundary conditions information to the bc_info type for the given variable
509 current_var = fileobj%num_restart_vars
510 fileobj%restart_vars(current_var)%is_bc_variable = .true.
511 fileobj%restart_vars(current_var)%bc_info%is_root_pe = is_root_pe
512
513 allocate(fileobj%restart_vars(current_var)%bc_info%indices(4))
514 fileobj%restart_vars(current_var)%bc_info%indices = indices
515
516 allocate(fileobj%restart_vars(current_var)%bc_info%global_size(3))
517 fileobj%restart_vars(current_var)%bc_info%global_size = global_size
518
519 if (any(fileobj%io_root .eq. pelist(:))) then
520 allocate(fileobj%restart_vars(current_var)%bc_info%pelist(size(pelist)))
521 fileobj%restart_vars(current_var)%bc_info%pelist = pelist
522 fileobj%restart_vars(current_var)%bc_info%data_on_file_root = .true.
523 else
524 allocate(fileobj%restart_vars(current_var)%bc_info%pelist(size(pelist)+1))
525 fileobj%restart_vars(current_var)%bc_info%pelist = (/ fileobj%io_root, pelist(:) /)
526 fileobj%restart_vars(current_var)%bc_info%data_on_file_root = .false.
527 endif
528
529 fileobj%restart_vars(current_var)%bc_info%x_halo = 0
530 fileobj%restart_vars(current_var)%bc_info%y_halo = 0
531 fileobj%restart_vars(current_var)%bc_info%ishift = 0
532 fileobj%restart_vars(current_var)%bc_info%jshift = 0
533
534 if (present(x_halo)) fileobj%restart_vars(current_var)%bc_info%x_halo = x_halo
535 if (present(y_halo)) fileobj%restart_vars(current_var)%bc_info%y_halo = y_halo
536 if (present(ishift)) fileobj%restart_vars(current_var)%bc_info%ishift = ishift
537 if (present(jshift)) fileobj%restart_vars(current_var)%bc_info%jshift = jshift
538
539end subroutine register_restart_region_3d
540
541!> @brief Updates the dimension information (bc_dimensions) for the give fileobj and outputs the
542!! dimensions name of the variable
543subroutine set_dimensions(fileobj, bc_dimensions, dimnames, global_size)
544 type(fmsnetcdffile_t), intent(inout) :: fileobj !> File object.
545 type(dimension_information), intent(inout) :: bc_dimensions !> Dimension information for the file
546 character(len=7), intent(inout) :: dimnames(4) !> List of the dimension names for the variable
547 !! dimnames(1): Name of the x dimension
548 !! dimnames(2): Name of the y dimension
549 !! dimnames(3): Name of the z dimension (or time if 2d)
550 !! dimnames(4): Name of the Time dimension (if 3d variable)
551 integer, dimension(:), intent(in) :: global_size !> Size of the variable for each dimension
552 !! global_size(1): Size of the x dimension
553 !! global_size(2): Size of the y dimension
554 !! global_size(3): Size of the z dimension (if it exists)
555 character(len=1) :: suffix !> Axis number converted to a string
556 character(len=7) :: axisname !> Name of the axis
557 integer :: i, found_index !> no description
558
559 if (.not. dimension_exists(fileobj, "Time")) call netcdf_add_dimension(fileobj, "Time", unlimited)
560 dimnames(size(global_size)+1) = "Time"
561
562 !> Check to see if a x dimension with the correct size is already registered
563 found_index = 0
564 do i = 1, bc_dimensions%cur_dim_len(1)
565 if (bc_dimensions%xlen(i) .eq. global_size(1)) then
566 found_index= i
567 write(suffix,'(I1)') i
568 axisname = 'xaxis_'//suffix
569 dimnames(1) = axisname
570 exit
571 endif
572 enddo
573
574 !> If the x dimension doesn't already exist, register it
575 if (found_index .eq. 0) then
576 bc_dimensions%cur_dim_len(1) = bc_dimensions%cur_dim_len(1) + 1
577 bc_dimensions%xlen(bc_dimensions%cur_dim_len(1)) = global_size(1)
578 write(suffix,'(I1)') bc_dimensions%cur_dim_len(1)
579 axisname = 'xaxis_'//suffix
580 call netcdf_add_dimension(fileobj, axisname, global_size(1))
581 dimnames(1) = axisname
582 endif
583
584 !> Check to see if a y dimension with the correct size is already registered
585 found_index = 0
586 do i = 1, bc_dimensions%cur_dim_len(2)
587 if (bc_dimensions%ylen(i) .eq. global_size(2)) then
588 found_index= i
589 write(suffix,'(I1)') i
590 axisname = 'yaxis_'//suffix
591 dimnames(2) = axisname
592 exit
593 endif
594 enddo
595
596 !> If the y dimension doesn't already exist, register it
597 if (found_index .eq. 0) then
598 bc_dimensions%cur_dim_len(2) = bc_dimensions%cur_dim_len(2) + 1
599 bc_dimensions%ylen(bc_dimensions%cur_dim_len(2)) = global_size(2)
600 write(suffix,'(I1)') bc_dimensions%cur_dim_len(2)
601 axisname = 'yaxis_'//suffix
602 call netcdf_add_dimension(fileobj, axisname, global_size(2))
603 dimnames(2) = axisname
604 endif
605
606 !> If the variable is 3d:
607 if (size(global_size) .eq. 3) then
608 !> Check to see if a z dimension with the correct size is already registered
609 found_index = 0
610 do i = 1, bc_dimensions%cur_dim_len(3)
611 if (bc_dimensions%zlen(i) .eq. global_size(3)) then
612 found_index= i
613 write(suffix,'(I1)') i
614 axisname = 'zaxis_'//suffix
615 dimnames(3) = axisname
616 exit
617 endif
618 enddo
619
620 !> If the z dimension doesn't already exist, register it
621 if (found_index .eq. 0) then
622 bc_dimensions%cur_dim_len(3) = bc_dimensions%cur_dim_len(3) + 1
623 bc_dimensions%zlen(bc_dimensions%cur_dim_len(3)) = global_size(3)
624 write(suffix,'(I1)') bc_dimensions%cur_dim_len(3)
625 axisname = 'zaxis_'//suffix
626 call netcdf_add_dimension(fileobj, axisname, global_size(3))
627 dimnames(3) = axisname
628 endif
629 endif
630end subroutine set_dimensions
631!> @}
subroutine netcdf_add_restart_variable_4d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a restart variable to a netcdf file.
subroutine netcdf_add_restart_variable_0d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a restart variable to a netcdf file.
subroutine set_dimensions(fileobj, bc_dimensions, dimnames, global_size)
Updates the dimension information (bc_dimensions) for the give fileobj and outputs the dimensions nam...
subroutine netcdf_add_restart_variable_3d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a restart variable to a netcdf file.
subroutine netcdf_add_restart_variable_5d_wrap(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Wrapper to distinguish interfaces.
subroutine netcdf_add_restart_variable_1d_wrap(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Wrapper to distinguish interfaces.
subroutine netcdf_add_restart_variable_0d_wrap(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Wrapper to distinguish interfaces.
subroutine netcdf_add_restart_variable_3d_wrap(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Wrapper to distinguish interfaces.
subroutine netcdf_add_restart_variable_1d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a restart variable to a netcdf file.
subroutine register_restart_region_3d(fileobj, variable_name, vdata, indices, global_size, pelist, is_root_pe, x_halo, y_halo, jshift, ishift, is_optional)
Registers a regional 3D variable and stores the information needed.
subroutine netcdf_add_restart_variable_2d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a restart variable to a netcdf file.
subroutine netcdf_add_restart_variable_4d_wrap(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Wrapper to distinguish interfaces.
subroutine netcdf_add_restart_variable_5d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a restart variable to a netcdf file.
subroutine netcdf_add_restart_variable_2d_wrap(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Wrapper to distinguish interfaces.
subroutine register_restart_region_2d(fileobj, variable_name, vdata, indices, global_size, pelist, is_root_pe, x_halo, y_halo, jshift, ishift, is_optional)
Registers a regional 2D variable and stores the information needed.