chore: Change version number to next development version (#874)
[FMS.git] / fms2_io / fms2_io.F90
blobd82be391482f73a8c6f02a981e5dc80315852c0e
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.
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.
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
20 !> @ingroup fms2_io
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.
28 !> @file
29 !> @brief File for @ref fms2_io_mod
31 !> @addtogroup fms2_io_mod
32 !> @{
33 module fms2_io_mod
34 use fms_io_utils_mod
35 use netcdf_io_mod
36 use fms_netcdf_domain_io_mod
37 use fms_netcdf_unstructured_domain_io_mod
38 use blackboxio
39 use mpp_mod, only: mpp_init, input_nml_file, mpp_error, FATAL
40 use mpp_domains_mod, only: mpp_domains_init
41 implicit none
42 private
44 public :: unlimited
45 public :: FmsNetcdfFile_t
46 public :: FmsNetcdfDomainFile_t
47 public :: FmsNetcdfUnstructuredDomainFile_t
48 public :: open_file
49 public :: open_virtual_file
50 public :: close_file
51 public :: register_axis
52 public :: register_field
53 public :: register_restart_field
54 public :: write_data
55 public :: read_data
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
79 public :: Valid_t
80 public :: get_valid
81 public :: is_valid
82 public :: get_unlimited_dimension_name
83 public :: get_variable_unlimited_dimension_index
84 public :: file_exists
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
90 public :: open_check
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
99 public :: ascii_read
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
106 public :: string2
107 public :: flush_file
108 !> @}
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
124 interface open_file
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
163 interface close_file
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
247 interface write_data
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
277 interface read_data
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
346 !> @{
348 logical, private :: fms2_io_is_initialized = .false. !< True after fms2_io_init is run
350 ! Namelist variables
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
357                                      !! NF__ENDDEF
358 namelist / fms2_io_nml / &
359                       ncchksz, netcdf_default_format, header_buffer_val
361 contains
363 !> @brief Reads the fms2_io_nml
364 subroutine fms2_io_init ()
365  integer :: mystat
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
370   call mpp_init()
371   call mpp_domains_init()
372 !> Read the namelist
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.")
377   endif
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.")
381   endif
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
388 !> @}
389 ! close documentation grouping