FMS  2024.03
Flexible Modeling System
data_override.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 
20 ! data_override_r4 and data_override_r8 are not intended to be used directly -
21 ! they should be used through the data_override_mod API. The body of
22 ! data_override_r4 and data_override_r8 is contained in data_override.inc.
23 
24 module data_override_r4
25 #include "data_override_r4.fh"
26 end module data_override_r4
27 
28 module data_override_r8
29 #include "data_override_r8.fh"
30 end module data_override_r8
31 
32 !> @defgroup data_override_mod data_override_mod
33 !> @ingroup data_override
34 !! @brief Routines to get data in a file whose path is described in a user-provided data_table
35 !! and do spatial and temporal interpolation if necessary to convert data to model's grid and time.
36 !! @author Z. Liang, M.J. Harrison, M. Winton
37 !!
38 !! Before using @ref data_override a data_table must be created with the following entries:
39 !! gridname, fieldname_code, fieldname_file, file_name, ongrid, factor.
40 !!
41 !! More explainations about data_table entries can be found in the source code (defining data_type)
42 !!
43 !! If user wants to override fieldname_code with a const, set fieldname_file in data_table = ""
44 !! and factor = const
45 !!
46 !! If user wants to override fieldname_code with data from a file, set fieldname_file = name in
47 !! the netCDF data file, factor then will be for unit conversion (=1 if no conversion required)
48 !!
49 !! A field can be overriden globally (by default) or users can specify one or two regions in which
50 !! data_override will take place, field values outside the region will not be affected.
51 
52 module data_override_mod
53  use data_override_r4
54  use data_override_r8
55  use platform_mod, only: r4_kind, r8_kind
56  use mpp_mod, only: mpp_error, fatal
57  use mpp_domains_mod, only : domain2d, domainug
58  use time_manager_mod, only: time_type
59 
60 implicit none
61 private
62 
63 !> Interface for inserting and interpolating data into a file
64 !! for a model's grid and time. Data path must be described in
65 !! a user-provided data_table, see @ref data_override_mod "module description"
66 !! for more information.
67 !> @ingroup data_override_mod
68 interface data_override
69  module procedure data_override_0d_r4
70  module procedure data_override_0d_r8
71  module procedure data_override_2d_r4
72  module procedure data_override_2d_r8
73  module procedure data_override_3d_r4
74  module procedure data_override_3d_r8
75 end interface
76 
77 !> Version of @ref data_override for unstructured grids
78 !> @ingroup data_override_mod
80  module procedure data_override_ug_1d_r4
81  module procedure data_override_ug_1d_r8
82  module procedure data_override_ug_2d_r4
83  module procedure data_override_ug_2d_r8
84 end interface
85 
86 integer :: atm_mode = 0 !> Atmosphere mode - possible values are 0 (uninitialized), r4_kind, or r8_kind
87 integer :: ocn_mode = 0 !> Ocean mode - possible values are 0 (uninitialized), r4_kind, or r8_kind
88 integer :: lnd_mode = 0 !> Land mode - possible values are 0 (uninitialized), r4_kind, or r8_kind
89 integer :: ice_mode = 0 !> Ice mode - possible values are 0 (uninitialized), r4_kind, or r8_kind
90 
91 !> @addtogroup data_override_mod
92 !> @{
93 
95 public :: data_override_ug
96 
97 contains
98 
99 !> @brief Initialize either data_override_r4 or data_override_r8
100 !! Users should call data_override_init before calling data_override
101 !!
102 !! This subroutine should be called in coupler_init after
103 !! (ocean/atmos/land/ice)_model_init have been called.
104 !!
105 !! data_override_init can be called more than once. In one call the user can pass
106 !! up to 4 domains of component models. At least one domain must be present in
107 !! any call. The real precision of initialized domains can be specified via the
108 !! optional mode argument. If no mode is specified, r8_kind is assumed. Mixed mode
109 !! operation can be accomplished via multiple calls to data_override_init with
110 !! different mode arguments.
111 !!
112 !! Data_table is initialized with default values in DATA_OVERRIDE_INIT_IMPL_. Users should
113 !! provide "real" values that will override the default values. Real values can be
114 !! specified in either data_table or data_table.yaml. Each line of data_table contains one
115 !! data_entry. Items of data_entry are comma-separated.
116 subroutine data_override_init(Atm_domain_in, Ocean_domain_in, Ice_domain_in, Land_domain_in, Land_domainUG_in, mode)
117  type (domain2d), intent(in), optional :: atm_domain_in !< Atmosphere domain
118  type (domain2d), intent(in), optional :: ocean_domain_in !< Ocean domain
119  type (domain2d), intent(in), optional :: ice_domain_in !< Ice domain
120  type (domain2d), intent(in), optional :: land_domain_in !< Land domain
121  type(domainug) , intent(in), optional :: land_domainug_in !< Land domain, unstructured grid
122  integer, intent(in), optional :: mode !< Real precision of initialized domains. Possible values are r4_kind or
123  !! r8_kind.
124  integer :: mode_selector
125 
126  if (present(mode)) then
127  mode_selector = mode
128  else
129  mode_selector = r8_kind
130  endif
131 
132  select case (mode_selector)
133  case (r4_kind)
134  call data_override_init_r4(atm_domain_in, ocean_domain_in, ice_domain_in, land_domain_in, land_domainug_in)
135  case (r8_kind)
136  call data_override_init_r8(atm_domain_in, ocean_domain_in, ice_domain_in, land_domain_in, land_domainug_in)
137  case default
138  call mpp_error(fatal, "data_override_init: unsupported mode argument")
139  end select
140 
141  if (present(atm_domain_in)) atm_mode = mode_selector
142  if (present(ocean_domain_in)) ocn_mode = mode_selector
143  if (present(ice_domain_in)) ice_mode = mode_selector
144  if (present(land_domain_in)) lnd_mode = mode_selector
145 end subroutine data_override_init
146 
147 !> @brief Unset domains that had previously been set for use by data_override.
148 !!
149 !! This subroutine deallocates any data override domains that have been set.
150 subroutine data_override_unset_domains(unset_Atm, unset_Ocean, &
151  unset_Ice, unset_Land, must_be_set)
152  logical, intent(in), optional :: unset_atm, unset_ocean, unset_ice, unset_land !< Set to true to unset the
153  !! respective domain
154  logical, intent(in), optional :: must_be_set !< Set to false to suppress the error when attempting to unset
155  !! an uninitialized domain
156  logical :: fail_if_not_set
157 
158  fail_if_not_set = .true. ; if (present(must_be_set)) fail_if_not_set = must_be_set
159 
160  if (present(unset_atm)) then ; if (unset_atm) then
161  select case (atm_mode)
162  case (r4_kind)
163  call data_override_unset_atm_r4
164  case (r8_kind)
165  call data_override_unset_atm_r8
166  case default
167  if (fail_if_not_set) call mpp_error(fatal, &
168  "data_override_unset_domains: attempted to unset an Atm_domain that has not been set.")
169  end select
170  atm_mode = 0
171  endif ; endif
172  if (present(unset_ocean)) then ; if (unset_ocean) then
173  select case (ocn_mode)
174  case (r4_kind)
175  call data_override_unset_ocn_r4
176  case (r8_kind)
177  call data_override_unset_ocn_r8
178  case default
179  if (fail_if_not_set) call mpp_error(fatal, &
180  "data_override_unset_domains: attempted to unset an Ocn_domain that has not been set.")
181  end select
182  ocn_mode = 0
183  endif ; endif
184  if (present(unset_land)) then ; if (unset_land) then
185  select case (lnd_mode)
186  case (r4_kind)
187  call data_override_unset_lnd_r4
188  case (r8_kind)
189  call data_override_unset_lnd_r8
190  case default
191  if (fail_if_not_set) call mpp_error(fatal, &
192  "data_override_unset_domains: attempted to unset an Land_domain that has not been set.")
193  end select
194  lnd_mode = 0
195  endif ; endif
196  if (present(unset_ice)) then ; if (unset_ice) then
197  select case (ice_mode)
198  case (r4_kind)
199  call data_override_unset_ice_r4
200  case (r8_kind)
201  call data_override_unset_ice_r8
202  case default
203  if (fail_if_not_set) call mpp_error(fatal, &
204  "data_override_unset_domains: attempted to unset an Ice_domain that has not been set.")
205  end select
206  ice_mode = 0
207  endif ; endif
208 end subroutine data_override_unset_domains
209 
210 end module data_override_mod
211 !> @}
212 ! close documentation grouping
subroutine, public data_override_init(Atm_domain_in, Ocean_domain_in, Ice_domain_in, Land_domain_in, Land_domainUG_in, mode)
Initialize either data_override_r4 or data_override_r8 Users should call data_override_init before ca...
subroutine, public data_override_unset_domains(unset_Atm, unset_Ocean, unset_Ice, unset_Land, must_be_set)
Unset domains that had previously been set for use by data_override.
Interface for inserting and interpolating data into a file for a model's grid and time....
Version of Data Override for unstructured grids.
The domain2D type contains all the necessary information to define the global, compute and data domai...
Domain information for managing data on unstructured grids.
Error handler.
Definition: mpp.F90:382
Type to represent amounts of time. Implemented as seconds and days to allow for larger intervals.