FMS 2025.01.02-dev
Flexible Modeling System
Loading...
Searching...
No Matches
fms_netcdf_unstructured_domain_io.F90
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!> @defgroup fms_netcdf_unstructured_domain_io_mod fms_netcdf_unstructured_domain_io_mod
20!> @ingroup fms2_io
21!> @brief Handles netcdf I/O for unstructured domains
22!!
23!> Mainly routines for use via interfaces in @ref fms2_io_mod
24
25module fms_netcdf_unstructured_domain_io_mod
26use netcdf
27use mpp_domains_mod
28use fms_io_utils_mod
29use netcdf_io_mod
30use platform_mod
31implicit none
32private
33
34!> @brief netcdf unstructured domain file type.
35!> @ingroup fms_netcdf_unstructured_domain_io_mod
37 type(domainug) :: domain !< Unstructured domain.
38 character(len=FMS_PATH_LEN) :: non_mangled_path !< Non-domain-mangled path.
40
41!> @addtogroup fms_netcdf_unstructured_domain_io_mod
42!> @{
66
67
68contains
69
70!> @brief Open a netcdf file that is associated with an unstructured domain.
71!! @return Flag telling if the open completed successfully.
72function open_unstructured_domain_file(fileobj, path, mode, domain, nc_format, &
73 is_restart, dont_add_res_to_filename) &
74 result(success)
75
76 type(fmsnetcdfunstructureddomainfile_t), intent(inout) :: fileobj !< File object.
77 character(len=*), intent(in) :: path !< File path.
78 character(len=*), intent(in) :: mode !< File mode. Allowed values
79 !! are "read", "append", "write", or
80 !! "overwrite".
81 type(domainug), intent(in) :: domain !< Unstructured domain.
82 character(len=*), intent(in), optional :: nc_format !< Netcdf format that
83 !! new files are written
84 !! as. Allowed values
85 !! are: "64bit", "classic",
86 !! or "netcdf4". Defaults to
87 !! "64bit".
88 logical, intent(in), optional :: is_restart !< Flag telling if this file
89 !! is a restart file. Defaults
90 !! to false.
91 logical, intent(in), optional :: dont_add_res_to_filename !< Flag indicating not to add
92 !! ".res" to the filename
93 logical :: success
94
95 type(domainug), pointer :: io_domain
96 integer :: pelist_size
97 integer, dimension(:), allocatable :: pelist
98 character(len=FMS_PATH_LEN) :: buf
99 character(len=FMS_PATH_LEN) :: buf2
100 integer :: tile_id
101
102 !Get the input domain's I/O domain pelist.
103 io_domain => mpp_get_ug_io_domain(domain)
104 if (.not. associated(io_domain)) then
105 call error("The input domain associated with the file:"//trim(fileobj%path)//" does not have an io_domain.")
106 endif
107 pelist_size = mpp_get_ug_domain_npes(io_domain)
108 allocate(pelist(pelist_size))
109 call mpp_get_ug_domain_pelist(io_domain, pelist)
110
111 !Add the domain tile id to the file name (if necessary).
112 call string_copy(buf, path)
113 if (mpp_get_ug_domain_ntiles(domain) .gt. 1) then
114 tile_id = mpp_get_ug_domain_tile_id(domain)
115 call domain_tile_filepath_mangle(buf, path, tile_id)
116 endif
117
118 success = .false.
119 if (string_compare(mode, "read", .true.) .or. string_compare(mode, "append", .true.)) then
120 !Only for reading: attempt to open non-distributed files.
121 success = netcdf_file_open(fileobj, buf, mode, nc_format, pelist, is_restart, dont_add_res_to_filename)
122 endif
123 if (.not. success) then
124 !Add the domain tile id to the file name (if necessary).
125 if (mpp_get_io_domain_ug_layout(domain) .gt. 1) then
126 tile_id = mpp_get_ug_domain_tile_id(io_domain)
127 call string_copy(buf2, buf)
128 call io_domain_tile_filepath_mangle(buf, buf2, tile_id)
129 endif
130
131 !Open distributed files.
132 success = netcdf_file_open(fileobj, buf, mode, nc_format, pelist, is_restart, dont_add_res_to_filename)
133 endif
134 deallocate(pelist)
135
136 if (.not. success) then
137 !This branch should only be entered if the file attempting to be read
138 !does not exist.
139 return
140 endif
141
142 !Store/initialize necessary properties.
143 fileobj%domain = domain
144 call string_copy(fileobj%non_mangled_path, path)
146
147
148!> @brief Wrapper to distinguish interfaces.
150
151 type(fmsnetcdfunstructureddomainfile_t), intent(inout) :: fileobj !< File object.
152
153 call netcdf_file_close(fileobj)
155
156
157!> @brief Add an unstructured dimension.
158subroutine register_unstructured_dimension(fileobj, dim_name)
159
160 type(fmsnetcdfunstructureddomainfile_t), intent(inout) :: fileobj !< File object.
161 character(len=*), intent(in) :: dim_name !< Dimension name.
162
163 type(domainug),pointer :: io_domain
164 integer, dimension(:), allocatable :: c
165 integer, dimension(:), allocatable :: e
166
167 allocate(c(size(fileobj%pelist)))
168 allocate(e(size(fileobj%pelist)))
169 io_domain => mpp_get_ug_io_domain(fileobj%domain)
170 call mpp_get_ug_compute_domains(io_domain, begin=c, size=e)
171 if (c(1) .ne. 1) then
172 c(:) = c(:) - c(1) + 1
173 endif
174 call register_compressed_dimension(fileobj, dim_name, c, e)
175 deallocate(c)
176 deallocate(e)
178
179
180!> @brief Wrapper to distinguish interfaces.
181subroutine register_unstructured_domain_variable(fileobj, variable_name, &
182 variable_type, dimensions)
183
184 type(fmsnetcdfunstructureddomainfile_t), intent(in) :: fileobj !< File object.
185 character(len=*), intent(in) :: variable_name !< Variable name.
186 character(len=*), intent(in) :: variable_type !< Variable type. Allowed
187 !! values are: "int", "int64",
188 !! "float", or "double".
189 character(len=*), dimension(:), intent(in), optional :: dimensions !< Dimension names.
190
191 call netcdf_add_variable(fileobj, variable_name, variable_type, dimensions)
193
194
195!> @brief Wrapper to distinguish interfaces.
196subroutine unstructured_write_restart(fileobj, unlim_dim_level)
197
198 type(fmsnetcdfunstructureddomainfile_t), intent(in) :: fileobj !< File object.
199 integer, intent(in), optional :: unlim_dim_level !< Unlimited dimension level.
200
201 call netcdf_save_restart(fileobj, unlim_dim_level)
202end subroutine unstructured_write_restart
203
204
205include "register_unstructured_domain_restart_variable.inc"
206include "unstructured_domain_read.inc"
207include "unstructured_domain_write.inc"
208
209
210end module fms_netcdf_unstructured_domain_io_mod
subroutine unstructured_domain_read_4d(fileobj, variable_name, buf, unlim_dim_level, corner, edge_lengths, broadcast)
Wrapper to distinguish interfaces.
subroutine unstructured_domain_write_2d(fileobj, variable_name, variable_data, unlim_dim_level, corner, edge_lengths)
Wrapper to distinguish interfaces.
subroutine register_unstructured_domain_restart_variable_4d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a domain decomposed variable.
subroutine unstructured_domain_read_3d(fileobj, variable_name, buf, unlim_dim_level, corner, edge_lengths, broadcast)
Wrapper to distinguish interfaces.
subroutine unstructured_domain_write_3d(fileobj, variable_name, variable_data, unlim_dim_level, corner, edge_lengths)
Wrapper to distinguish interfaces.
subroutine register_unstructured_domain_restart_variable_2d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a domain decomposed variable.
subroutine unstructured_domain_write_0d(fileobj, variable_name, variable_data, unlim_dim_level, corner)
Wrapper to distinguish interfaces.
subroutine unstructured_domain_read_0d(fileobj, variable_name, buf, unlim_dim_level, corner, broadcast)
Wrapper to distinguish interfaces.
subroutine unstructured_domain_write_4d(fileobj, variable_name, variable_data, unlim_dim_level, corner, edge_lengths)
Wrapper to distinguish interfaces.
subroutine register_unstructured_domain_restart_variable_3d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a domain decomposed variable.
subroutine unstructured_domain_read_5d(fileobj, variable_name, buf, unlim_dim_level, corner, edge_lengths, broadcast)
Wrapper to distinguish interfaces.
subroutine unstructured_domain_read_2d(fileobj, variable_name, buf, unlim_dim_level, corner, edge_lengths, broadcast)
Wrapper to distinguish interfaces.
subroutine register_unstructured_domain_restart_variable_1d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a domain decomposed variable.
subroutine register_unstructured_domain_restart_variable_5d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a domain decomposed variable.
subroutine unstructured_domain_write_1d(fileobj, variable_name, variable_data, unlim_dim_level, corner, edge_lengths)
Wrapper to distinguish interfaces.
subroutine unstructured_domain_write_5d(fileobj, variable_name, variable_data, unlim_dim_level, corner, edge_lengths)
Wrapper to distinguish interfaces.
subroutine register_unstructured_domain_restart_variable_0d(fileobj, variable_name, vdata, dimensions, is_optional, chunksizes)
Add a domain decomposed variable.
subroutine unstructured_domain_read_1d(fileobj, variable_name, buf, unlim_dim_level, corner, edge_lengths, broadcast)
Wrapper to distinguish interfaces.
logical function, public string_compare(string1, string2, ignore_case)
Compare strings.
subroutine, public domain_tile_filepath_mangle(dest, source, domain_tile_id)
Add the domain tile id to an input filepath.
subroutine, public error(mesg)
Print a message to stderr, then stop the program.
subroutine, public io_domain_tile_filepath_mangle(dest, source, io_domain_tile_id)
Add the I/O domain tile id to an input filepath.
subroutine, public register_unstructured_dimension(fileobj, dim_name)
Add an unstructured dimension.
subroutine, public unstructured_write_restart(fileobj, unlim_dim_level)
Wrapper to distinguish interfaces.
subroutine, public close_unstructured_domain_file(fileobj)
Wrapper to distinguish interfaces.
subroutine, public register_unstructured_domain_variable(fileobj, variable_name, variable_type, dimensions)
Wrapper to distinguish interfaces.
logical function, public open_unstructured_domain_file(fileobj, path, mode, domain, nc_format, is_restart, dont_add_res_to_filename)
Open a netcdf file that is associated with an unstructured domain.
Domain information for managing data on unstructured grids.
subroutine, public netcdf_add_variable(fileobj, variable_name, variable_type, dimensions, chunksizes)
Add a variable to a file.
subroutine, public register_compressed_dimension(fileobj, dimension_name, npes_corner, npes_nelems)
Add a compressed dimension.
logical function, public netcdf_file_open(fileobj, path, mode, nc_format, pelist, is_restart, dont_add_res_to_filename)
Open a netcdf file.
subroutine, public netcdf_save_restart(fileobj, unlim_dim_level)
Loop through registered restart variables and write them to a netcdf file.
subroutine, public netcdf_file_close(fileobj)
Close a netcdf file.