1 !***********************************************************************
2 !* GNU Lesser General Public License
4 !* This file is part of the GFDL Flexible Modeling System (FMS).
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.
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
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 !> @defgroup fms2_io_mod fms2_io_mod
21 !> @brief An updated library for parallel IO to replace @ref mpp_io_mod. This module contains
22 !! the public API for fms2 I/O interfaces and routines defined throughout this directory.
24 !> Provides public interfaces for routines within @ref fms2_io.
25 !! Interfaces and example usages are listed below, see individual routine
26 !! documentation for more specific argument information.
29 !> @brief File for @ref fms2_io_mod
31 !> @addtogroup fms2_io_mod
36 use fms_netcdf_domain_io_mod
37 use fms_netcdf_unstructured_domain_io_mod
39 use mpp_mod, only: mpp_init, input_nml_file, mpp_error, FATAL
40 use mpp_domains_mod, only: mpp_domains_init
45 public :: FmsNetcdfFile_t
46 public :: FmsNetcdfDomainFile_t
47 public :: FmsNetcdfUnstructuredDomainFile_t
49 public :: open_virtual_file
51 public :: register_axis
52 public :: register_field
53 public :: register_restart_field
56 public :: write_restart
57 public :: write_new_restart
58 public :: read_restart
59 public :: read_new_restart
60 public :: global_att_exists
61 public :: variable_att_exists
62 public :: register_global_attribute
63 public :: register_variable_attribute
64 public :: get_global_attribute
65 public :: get_variable_attribute
66 public :: get_num_dimensions
67 public :: get_dimension_names
68 public :: dimension_exists
69 public :: is_dimension_unlimited
70 public :: get_dimension_size
71 public :: get_num_variables
72 public :: get_variable_names
73 public :: variable_exists
74 public :: get_variable_num_dimensions
75 public :: get_variable_dimension_names
76 public :: get_variable_size
77 public :: get_compute_domain_dimension_indices
78 public :: get_global_io_domain_indices
82 public :: get_unlimited_dimension_name
83 public :: get_variable_unlimited_dimension_index
85 public :: compressed_start_and_count
86 public :: get_variable_sense
87 public :: get_variable_missing
88 public :: get_variable_units
89 public :: get_time_calendar
91 public :: is_registered_to_restart
92 public :: check_if_open
93 public :: set_fileobj_time_name
94 public :: is_dimension_registered
95 public :: fms2_io_init
96 public :: write_restart_bc
97 public :: read_restart_bc
98 public :: get_mosaic_tile_grid
100 public :: get_mosaic_tile_file
101 public :: parse_mask_table
102 public :: get_filename_appendix
103 public :: set_filename_appendix
104 public :: get_instance_filename
105 public :: nullify_filename_appendix
110 !> @brief Opens a given netcdf or domain file.
112 !> <br>Example usage:
114 !! io_success = open_file(fileobj, "filename", "write")
116 !! Opens a netcdf file of type @ref fmsnetcdffile_t at the given file path string.
117 !! File mode is set to one of "read"/"write"/"overwrite"/"append"
119 !! io_success = open_file(fileobj, "filename", "overwrite", domain)
121 !! Opens a domain netcdf file of type @ref fmsnetcdfdomainfile_t or
122 !! @ref fmsnetcdfunstructureddomainfile_t at the given file path name and 2D or unstructured domain.
123 !> @ingroup fms2_io_mod
125 module procedure netcdf_file_open_wrap
126 module procedure open_domain_file
127 module procedure open_unstructured_domain_file
128 end interface open_file
131 !> @brief Creates a diskless netcdf or domain file
133 !> @return true if successful, false otherwise
135 !> <br>Example usage:
137 !! io_success = open_virtual_file(fileobj, "filename", pelist)
139 !! Opens a virtual file through @ref fmsnetcdffile_t at an optional file path and pelist
141 !! io_success = open_virtual_file(fileobj, domain, "filename")
143 !! Opens a virtual domain file through @ref fmsnetcdfdomainfile_t or
144 !! - @ref fmsnetcdfunstructureddomainfile_t for a given 2D domain at an optional path <br>
146 !> @ingroup fms2_io_mod
147 interface open_virtual_file
148 module procedure create_diskless_netcdf_file_wrap
149 module procedure create_diskless_domain_file
150 module procedure create_diskless_unstructured_domain_file
151 end interface open_virtual_file
153 !> @brief Close a netcdf or domain file opened with @ref open_file or
154 !! @ref open_virtual_file
156 !> <br>Example usage:
158 !! call close_file(fileobj)
160 !! Closes any given fileobj opened via @ref open_file or @ref open_virtual_file
162 !> @ingroup fms2_io_mod
164 module procedure netcdf_file_close_wrap
165 module procedure close_domain_file
166 module procedure close_unstructured_domain_file
167 end interface close_file
169 !> @brief Add a dimension to a given file
171 !> <br>Example usage:
173 !! call register_axis(fileobj, "lon", "x")
175 !! Adds a dimension named "lon" associated with the x axis of the 2D domain file. For unstructured
176 !! domains no x or y axis character is provided.
178 !! call register_axis(fileobj, "lon", n)
180 !! Adds a dimension named "lon" with length n to a given netcdf file.<br>
182 !> @ingroup fms2_io_mod
183 interface register_axis
184 module procedure netcdf_add_dimension
185 module procedure register_compressed_dimension
186 module procedure register_domain_decomposed_dimension
187 module procedure register_unstructured_dimension
188 end interface register_axis
190 !> @brief Defines a new field within the given file
191 !> <br>Example usage:
193 !! call register_field(fileobj, "lon", "double", (/"lon"/) )
195 !! Adds a double variable named "lon" to the given file, corresponding to the
196 !! list of dimension names (which must be previously defined in the fileobj).
197 !! The size of dimension name list provided is the amount of ranks for the created
198 !! field, scalar if list not provided.
200 !> @ingroup fms2_io_mod
201 interface register_field
202 module procedure netcdf_add_variable_wrap
203 module procedure register_domain_variable
204 module procedure register_unstructured_domain_variable
205 end interface register_field
207 !> @brief Similar to @ref register_field, but occupies the field with data for restarts
208 !> <br>Example usage:
210 !! call register_restart_field(fileobj, "temperature", data_ptr, (/"lon", "time"/) )
212 !! Creates a restart variable and sets it to the values from data_ptr, corresponding to
213 !! the list of dimension names. Rank of data_ptr must equal the amount of corresponding dimensions.
215 !> @ingroup fms2_io_mod
216 interface register_restart_field
217 module procedure netcdf_add_restart_variable_0d_wrap
218 module procedure netcdf_add_restart_variable_1d_wrap
219 module procedure netcdf_add_restart_variable_2d_wrap
220 module procedure netcdf_add_restart_variable_3d_wrap
221 module procedure netcdf_add_restart_variable_4d_wrap
222 module procedure netcdf_add_restart_variable_5d_wrap
223 module procedure register_domain_restart_variable_0d
224 module procedure register_domain_restart_variable_1d
225 module procedure register_domain_restart_variable_2d
226 module procedure register_domain_restart_variable_3d
227 module procedure register_domain_restart_variable_4d
228 module procedure register_domain_restart_variable_5d
229 module procedure register_unstructured_domain_restart_variable_0d
230 module procedure register_unstructured_domain_restart_variable_1d
231 module procedure register_unstructured_domain_restart_variable_2d
232 module procedure register_unstructured_domain_restart_variable_3d
233 module procedure register_unstructured_domain_restart_variable_4d
234 module procedure register_unstructured_domain_restart_variable_5d
235 module procedure register_restart_region_2d
236 module procedure register_restart_region_3d
237 end interface register_restart_field
239 !> @brief Write data to a defined field within a file
240 !> <br>Example usage:
242 !! call write_data(fileobj, "lon", data)
244 !! Write the value(s) in data to the field named "lon"
246 !> @ingroup fms2_io_mod
248 module procedure compressed_write_0d_wrap
249 module procedure compressed_write_1d_wrap
250 module procedure compressed_write_2d_wrap
251 module procedure compressed_write_3d_wrap
252 module procedure compressed_write_4d_wrap
253 module procedure compressed_write_5d_wrap
254 module procedure domain_write_0d
255 module procedure domain_write_1d
256 module procedure domain_write_2d
257 module procedure domain_write_3d
258 module procedure domain_write_4d
259 module procedure domain_write_5d
260 module procedure unstructured_domain_write_0d
261 module procedure unstructured_domain_write_1d
262 module procedure unstructured_domain_write_2d
263 module procedure unstructured_domain_write_3d
264 module procedure unstructured_domain_write_4d
265 module procedure unstructured_domain_write_5d
266 end interface write_data
268 !> @brief Read data from a defined field in a file
270 !> <br>Example usage:
272 !! call read_data(fileobj, "lat", data)
274 !! Read the values for the field "lat" from the file and write them onto data <br>
276 !> @ingroup fms2_io_mod
278 module procedure compressed_read_0d
279 module procedure compressed_read_1d
280 module procedure compressed_read_2d
281 module procedure compressed_read_3d
282 module procedure compressed_read_4d
283 module procedure compressed_read_5d
284 module procedure domain_read_0d
285 module procedure domain_read_1d
286 module procedure domain_read_2d
287 module procedure domain_read_3d
288 module procedure domain_read_4d
289 module procedure domain_read_5d
290 module procedure unstructured_domain_read_0d
291 module procedure unstructured_domain_read_1d
292 module procedure unstructured_domain_read_2d
293 module procedure unstructured_domain_read_3d
294 module procedure unstructured_domain_read_4d
295 module procedure unstructured_domain_read_5d
296 end interface read_data
298 !> @brief Writes all restart fields registered within a given restart file
299 !> <br>Example usage:
301 !! call write_restart(fileobj)
303 !! Writes previously registered restart fields to the given restart file
305 !> @ingroup fms2_io_mod
306 interface write_restart
307 module procedure netcdf_save_restart_wrap
308 module procedure save_domain_restart
309 module procedure unstructured_write_restart
310 end interface write_restart
312 !> @brief Writes all restart fields in a given restart file to a new restart file
313 !> <br>Example usage:
315 !! call write_new_restart(fileobj, timestamp="tstring", filename="new_restartfilename")
317 !! Creates a new restart file, with the provided timestamp and filename, out of the registered
318 !! restart fields in the given restart file.
320 !> @ingroup fms2_io_mod
321 interface write_new_restart
322 module procedure netcdf_save_restart_wrap2
323 module procedure save_domain_restart_wrap
324 module procedure unstructured_write_restart_wrap
325 end interface write_new_restart
327 !> @brief Reads in restart variables from a given file
328 !> <br>Example usage:
329 !! call read_restart(fileobj)
330 !! Reads registered restart variables from fileobj
332 !> @ingroup fms2_io_mod
333 interface read_restart
334 module procedure netcdf_restore_state
335 module procedure restore_domain_state
336 end interface read_restart
338 !> @brief Read registered restarts from a new file
339 !> @ingroup fms2_io_mod
340 interface read_new_restart
341 module procedure netcdf_restore_state_wrap
342 module procedure restore_domain_state_wrap
343 end interface read_new_restart
345 !> @addtogroup fms2_io_mod
348 logical, private :: fms2_io_is_initialized = .false. !< True after fms2_io_init is run
351 integer :: ncchksz = 64*1024 !< User defined chunksize (in bytes) argument in netcdf file
352 !! creation calls. Replaces setting the NC_CHKSZ environment variable.
353 character (len = 10) :: netcdf_default_format = "64bit" !< User defined netcdf file format, acceptable values
354 !! are: "64bit", "classic", "netcdf4". This can be overwritten if you specify
355 !! "nc_format" in the open_file call
356 integer :: header_buffer_val = 16384 !< Use defined netCDF header buffer size(in bytes) used in
358 namelist / fms2_io_nml / &
359 ncchksz, netcdf_default_format, header_buffer_val
363 !> @brief Reads the fms2_io_nml
364 subroutine fms2_io_init ()
367 !> Check if the module has already been initialized
368 if (fms2_io_is_initialized) return
369 !> Call initialization routines that this module depends on
371 call mpp_domains_init()
373 READ (input_nml_file, NML=fms2_io_nml, IOSTAT=mystat)
374 !>Send the namelist variables to their respective modules
375 if (ncchksz .le. 0) then
376 call mpp_error(FATAL, "ncchksz in fms2_io_nml must be a positive number.")
378 call netcdf_io_init (ncchksz,header_buffer_val,netcdf_default_format)
379 if (header_buffer_val .le. 0) then
380 call mpp_error(FATAL, "header_buffer_val in fms2_io_nml must be a positive number.")
382 call blackboxio_init (ncchksz)
383 !> Mark the fms2_io as initialized
384 fms2_io_is_initialized = .true.
385 end subroutine fms2_io_init
387 end module fms2_io_mod
389 ! close documentation grouping