FMS 2025.01-dev
Flexible Modeling System
Loading...
Searching...
No Matches
horiz_interp.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 horiz_interp_mod horiz_interp_mod
20!> @ingroup horiz_interp
21!> @brief Performs spatial interpolation between grids.
22!!
23!> @author Zhi Liang, Bruce Wyman
24!!
25!! This module can interpolate data from any logically rectangular grid
26!! to any logically rectangular grid. Four interpolation schems are used here:
27!! conservative, bilinear, bicubic and inverse of square distance weighted.
28!! The four interpolation schemes are implemented seperately in
29!! horiz_interp_conserver_mod, horiz_interp_blinear_mod, horiz_interp_bicubic_mod
30!! and horiz_interp_spherical_mod. bicubic interpolation requires the source grid
31!! is regular lon/lat grid. User can choose the interpolation method in the
32!! public interface horiz_interp_new through optional argument interp_method,
33!! with acceptable value "conservative", "bilinear", "bicubic" and "spherical".
34!! The default value is "conservative". There is an optional mask field for
35!! missing input data. An optional output mask field may be used in conjunction with
36!! the input mask to show where output data exists.
37
38module horiz_interp_mod
39
40!-----------------------------------------------------------------------
41!
42! Performs spatial interpolation between grids.
43!
44!-----------------------------------------------------------------------
45
46use fms_mod, only: write_version_number, fms_error_handler
47use fms_mod, only: check_nml_error
48use mpp_mod, only: mpp_error, fatal, stdout, stdlog, mpp_min
49use mpp_mod, only: input_nml_file, warning, mpp_pe, mpp_root_pe
50use constants_mod, only: pi
51use horiz_interp_type_mod, only: horiz_interp_type, assignment(=)
52use horiz_interp_type_mod, only: conserve, bilinear, spherical, bicubic
53use horiz_interp_conserve_mod, only: horiz_interp_conserve_init, horiz_interp_conserve
54use horiz_interp_conserve_mod, only: horiz_interp_conserve_new, horiz_interp_conserve_del
55use horiz_interp_bilinear_mod, only: horiz_interp_bilinear_init, horiz_interp_bilinear
56use horiz_interp_bilinear_mod, only: horiz_interp_bilinear_new, horiz_interp_bilinear_del
57use horiz_interp_bilinear_mod, only: horiz_interp_read_weights_bilinear
58use horiz_interp_bicubic_mod, only: horiz_interp_bicubic_init, horiz_interp_bicubic
59use horiz_interp_bicubic_mod, only: horiz_interp_bicubic_new, horiz_interp_bicubic_del
60use horiz_interp_spherical_mod, only: horiz_interp_spherical_init, horiz_interp_spherical
61use horiz_interp_spherical_mod, only: horiz_interp_spherical_new, horiz_interp_spherical_del
62use platform_mod, only: r4_kind, r8_kind
63
64 implicit none
65 private
66
67!---- interfaces ----
68
71
72!> Allocates space and initializes a derived-type variable
73!! that contains pre-computed interpolation indices and weights.
74!!
75!> Allocates space and initializes a derived-type variable
76!! that contains pre-computed interpolation indices and weights
77!! for improved performance of multiple interpolations between
78!! the same grids. This routine does not need to be called if you
79!! are doing a single grid-to-grid interpolation.
80!!
81!! @param lon_in
82!! Longitude (in radians) for source data grid. You can pass 1-D lon_in to
83!! represent the geographical longitude of regular lon/lat grid, or just
84!! pass geographical longitude(lon_in is 2-D). The grid location may be
85!! located at grid cell edge or center, decided by optional argument "grid_at_center".
86!!
87!! @param lat_in
88!! Latitude (in radians) for source data grid. You can pass 1-D lat_in to
89!! represent the geographical latitude of regular lon/lat grid, or just
90!! pass geographical latitude(lat_in is 2-D). The grid location may be
91!! located at grid cell edge or center, decided by optional argument "grid_at_center".
92!!
93!! @param lon_out
94!! Longitude (in radians) for destination data grid. You can pass 1-D lon_out to
95!! represent the geographical longitude of regular lon/lat grid, or just
96!! pass geographical longitude(lon_out is 2-D). The grid location may be
97!! located at grid cell edge or center, decided by optional argument "grid_at_center".
98!!
99!! @param lat_out
100!! Latitude (in radians) for destination data grid. You can pass 1-D lat_out to
101!! represent the geographical latitude of regular lon/lat grid, or just
102!! pass geographical latitude(lat_out is 2-D). The grid location may be
103!! located at grid cell edge or center, decided by optional argument "grid_at_center".
104!!
105!! @param verbose
106!! Integer flag that controls the amount of printed output.
107!! verbose = 0, no output; = 1, min,max,means; = 2, still more
108!!
109!! @param interp_method
110!! interpolation method, = "conservative", using conservation scheme,
111!! = "bilinear", using bilinear interpolation, = "spherical",using spherical regrid.
112!! = "bicubic", using bicubic interpolation. The default value is "convervative".
113!!
114!! @param src_modulo
115!! Indicate the source data grid is cyclic or not.
116!!
117!! @param grid_at_center
118!! Indicate the data is on the center of grid box or the edge of grid box.
119!! When true, the data is on the center of grid box. default vaule is false.
120!! This option is only available when interp_method = "bilinear" or "bicubic".
121!!
122!! @param Interp
123!! A derived-type variable containing indices and weights used for subsequent
124!! interpolations. To reinitialize this variable for a different grid-to-grid
125!! interpolation you must first use the "horiz_interp_del" interface.
127 ! Source grid is 1d, destination grid is 1d
128 module procedure horiz_interp_new_1d_r4
129 module procedure horiz_interp_new_1d_r8
130 ! Source grid is 1d, destination grid is 2d
131 module procedure horiz_interp_new_1d_src_r4
132 module procedure horiz_interp_new_1d_src_r8
133 ! Source grid is 2d, destination grid is 2d
134 module procedure horiz_interp_new_2d_r4
135 module procedure horiz_interp_new_2d_r8
136 ! Source grid is 2d, destination grid is 1d
137 module procedure horiz_interp_new_1d_dst_r4
138 module procedure horiz_interp_new_1d_dst_r8
139 end interface
140
141 !> Subroutines for reading in weight files and using that to fill in the horiz_interp type instead
142 !! calculating it
144 module procedure horiz_interp_read_weights_r4
145 module procedure horiz_interp_read_weights_r8
146 end interface horiz_interp_read_weights
147
148!> Subroutine for performing the horizontal interpolation between two grids.
149!!
150!> Subroutine for performing the horizontal interpolation between
151!! two grids. There are two forms of this interface.
152!! Form A requires first calling horiz_interp_new, while Form B
153!! requires no initialization.
154!!
155!! @param Interp
156!! Derived-type variable containing interpolation indices and weights.
157!! Returned by a previous call to horiz_interp_new.
158!!
159!! @param data_in
160!! Input data on source grid.
161!!
162!! @param verbose
163!! flag for the amount of print output.
164!! verbose = 0, no output; = 1, min,max,means; = 2, still more
165!!
166!! @param mask_in
167!! Input mask, must be the same size as the input data. The real value of
168!! mask_in must be in the range (0.,1.). Set mask_in=0.0 for data points
169!! that should not be used or have missing data. It is Not needed for
170!! spherical regrid.
171!!
172!! @param missing_value
173!! Use the missing_value to indicate missing data.
174!!
175!! @param missing_permit
176!! numbers of points allowed to miss for the bilinear interpolation. The value
177!! should be between 0 and 3.
178!!
179!! @param lon_in, lat_in
180!! longitude and latitude (in radians) of source grid. More explanation can
181!! be found in the documentation of horiz_interp_new.
182!!
183!! @param lon_out, lat_out
184!! longitude and latitude (in radians) of destination grid. More explanation can
185!! be found in the documentation of horiz_interp_new.
186!!
187!! @param data_out
188!! Output data on destination grid.
189!!
190!! @param mask_out
191!! Output mask that specifies whether data was computed.
192!!
193!!
194!! @throws FATAL, size of input array incorrect
195!! The input data array does not match the size of the input grid edges
196!! specified. If you are using the initialization interface make sure you
197!! have the correct grid size.
198!!
199!! @throws FATAL, size of output array incorrect
200!! The output data array does not match the size of the input grid
201!! edges specified. If you are using the initialization interface make
202!! sure you have the correct grid size.
203!> @ingroup horiz_interp_mod
204 interface horiz_interp
205 module procedure horiz_interp_base_2d_r4
206 module procedure horiz_interp_base_2d_r8
207 module procedure horiz_interp_base_3d_r4
208 module procedure horiz_interp_base_3d_r8
209 module procedure horiz_interp_solo_1d_r4
210 module procedure horiz_interp_solo_1d_r8
211 module procedure horiz_interp_solo_1d_src_r4
212 module procedure horiz_interp_solo_1d_src_r8
213 module procedure horiz_interp_solo_2d_r4
214 module procedure horiz_interp_solo_2d_r8
215 module procedure horiz_interp_solo_1d_dst_r4
216 module procedure horiz_interp_solo_1d_dst_r8
217 module procedure horiz_interp_solo_old_r4
218 module procedure horiz_interp_solo_old_r8
219 end interface
220
221!> Private helper routines
222interface is_lat_lon
223 module procedure is_lat_lon_r4
224 module procedure is_lat_lon_r8
225end interface
226
228 module procedure horiz_interp_solo_1d_r4
229 module procedure horiz_interp_solo_1d_r8
230end interface
231
232
233!> @addtogroup horiz_interp_mod
234!> @{
235
236 logical :: reproduce_siena = .false. !< Set reproduce_siena = .true. to reproduce siena results.
237 !! Set reproduce_siena = .false. to decrease truncation error
238 !! in routine poly_area in file mosaic_util.c. The truncation error of
239 !! second order conservative remapping might be big for high resolution
240 !! grid.
241
242 namelist /horiz_interp_nml/ reproduce_siena
243
244!-----------------------------------------------------------------------
245! Include variable "version" to be written to log file.
246#include<file_version.h>
247 logical :: module_is_initialized = .false.
248!-----------------------------------------------------------------------
249
250contains
251
252!#######################################################################
253
254 !> Initialize module and writes version number to logfile.out
256 integer :: iunit, ierr, io
257
258 if(module_is_initialized) return
259 call write_version_number("HORIZ_INTERP_MOD", version)
260
261 read (input_nml_file, horiz_interp_nml, iostat=io)
262 ierr = check_nml_error(io,'horiz_interp_nml')
263 if (mpp_pe() == mpp_root_pe() ) then
264 iunit = stdlog()
265 write (iunit, nml=horiz_interp_nml)
266 endif
267
268 if (reproduce_siena) then
269 call mpp_error(fatal, "horiz_interp_mod: You have overridden the default value of " // &
270 "reproduce_siena and set it to .true. in horiz_interp_nml. This was a temporary workaround to " // &
271 "allow for consistency in continuing experiments and is no longer supported. " // &
272 "Please remove this namelist.")
273 endif
274
279
280 module_is_initialized = .true.
281
282 end subroutine horiz_interp_init
283
284!> Deallocates memory used by "horiz_interp_type" variables.
285!! Must be called before reinitializing with horiz_interp_new.
286 subroutine horiz_interp_del ( Interp )
287
288 type (horiz_interp_type), intent(inout) :: interp !< A derived-type variable returned by previous
289 !! call to horiz_interp_new. The input variable must have
290 !! allocated arrays. The returned variable will contain
291 !! deallocated arrays
292
293!-----------------------------------------------------------------------
294! releases space used by horiz_interp_type variables
295! must be called before re-initializing the same variable
296!-----------------------------------------------------------------------
297 select case(interp % interp_method)
298 case (conserve)
299 call horiz_interp_conserve_del(interp )
300 case (bilinear)
301 call horiz_interp_bilinear_del(interp )
302 case (bicubic)
303 call horiz_interp_bicubic_del(interp )
304 case (spherical)
305 call horiz_interp_spherical_del(interp )
306 end select
307
308 interp%I_am_initialized = .false.
309!-----------------------------------------------------------------------
310
311 end subroutine horiz_interp_del
312
313 !#####################################################################
314
315 !> Dummy routine
317 return
318 end subroutine horiz_interp_end
319
320#include "horiz_interp_r4.fh"
321#include "horiz_interp_r8.fh"
322
323end module horiz_interp_mod
324!> @}
325! close documentation grouping
subroutine, public horiz_interp_bicubic_init
Initializes module and writes version number to logfile.out.
subroutine, public horiz_interp_bicubic_del(interp)
Free memory from a horiz_interp_type used for bicubic interpolation (allocated via horiz_bicubic_new)
Creates a new horiz_interp_type for bicubic interpolation. Allocates space and initializes a derived-...
subroutine, public horiz_interp_bilinear_del(interp)
Deallocates memory used by "horiz_interp_type" variables.
subroutine, public horiz_interp_bilinear_init
Initialize this module and writes version number to logfile.
Creates a horiz_interp_type for bilinear interpolation.
Subroutines for reading in weight files and using that to fill in the horiz_interp type instead calcu...
subroutine, public horiz_interp_conserve_del(interp)
Deallocates memory used by "HI_KIND_TYPE" variables. Must be called before reinitializing with horiz_...
subroutine, public horiz_interp_conserve_init
Writes version number to logfile.
Allocates space and initializes a derived-type variable that contains pre-computed interpolation indi...
subroutine, public horiz_interp_end
Dummy routine.
subroutine, public horiz_interp_init
Initialize module and writes version number to logfile.out.
logical reproduce_siena
Set reproduce_siena = .true. to reproduce siena results. Set reproduce_siena = .false....
subroutine, public horiz_interp_del(interp)
Deallocates memory used by "horiz_interp_type" variables. Must be called before reinitializing with h...
Subroutine for performing the horizontal interpolation between two grids.
subroutine, public horiz_interp_spherical_del(interp)
Deallocates memory used by "HI_KIND_TYPE" variables. Must be called before reinitializing with horiz_...
subroutine, public horiz_interp_spherical_init
Initializes module and writes version number to logfile.out.
Holds data pointers and metadata for horizontal interpolations, passed between the horiz_interp modul...
Error handler.
Definition mpp.F90:382
Reduction operations. Find the min of scalar a from the PEs in pelist result is also automatically br...
Definition mpp.F90:560
Perform bicubic horizontal interpolation.
Allocates space and initializes a derived-type variable that contains pre-computed interpolation indi...
Subroutines for reading in weight files and using that to fill in the horiz_interp type instead calcu...
Private helper routines.