FMS  2026.01.01-dev
Flexible Modeling System
horiz_interp_bilinear.F90
1 !***********************************************************************
2 !* Apache License 2.0
3 !*
4 !* This file is part of the GFDL Flexible Modeling System (FMS).
5 !*
6 !* Licensed under the Apache License, Version 2.0 (the "License");
7 !* you may not use this file except in compliance with the License.
8 !* You may obtain a copy of the License at
9 !*
10 !* http://www.apache.org/licenses/LICENSE-2.0
11 !*
12 !* FMS is distributed in the hope that it will be useful, but WITHOUT
13 !* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied;
14 !* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15 !* PARTICULAR PURPOSE. See the License for the specific language
16 !* governing permissions and limitations under the License.
17 !***********************************************************************
18 !> @defgroup horiz_interp_bilinear_mod horiz_interp_bilinear_mod
19 !! @ingroup horiz_interp
20 !! @{
21 !! @author Zhi Liang <Zhi.Liang@noaa.gov>
22 !! @parblock
23 !! Horiz_interp_bilinear_mod contains methods called from horiz_interp_mod to
24 !! interpolate data on a regular rectangular grid to a rectangular/tripolar grid.
25 !! Users are recommened to use the top-level module horiz_interp_mod with "interp"
26 !! set to "bilinear" for bilinear interpolation.
27 !! @endparblock
28 
29 module horiz_interp_bilinear_mod
30 
31  use mpp_mod, only: mpp_error, fatal, stdout, mpp_pe, mpp_root_pe
32  use fms_mod, only: write_version_number
33  use constants_mod, only: pi
34  use horiz_interp_type_mod, only: horiz_interp_type, stats, bilinear
35  use platform_mod, only: r4_kind, r8_kind
36  use axis_utils2_mod, only: nearest_index
37  use fms2_io_mod, only: open_file, close_file, read_data, fmsnetcdffile_t, get_dimension_size
38  use fms_string_utils_mod, only: string
39 
40  implicit none
41  private
42 
43 
46 
47  !> Generic interface to compute interpolation weights and mapping indices.
48  !! Member subroutines and their main arguments are:
49  !! horiz_interp_bilinear_new_1d_r4:
50  !! input grids provided as 1D arrays, output grids as 2D arrays, both in 32-bit precision.
51  !! horiz_interp_bilinear_new_1d_r8:
52  !! input grids provided as 1D arrays, output grids as 2D arrays, both in 64-bit precision.
53  !! horiz_interp_bilinear_new_2d_r4:
54  !! input and output grids provided as 2D arrays in 32-bit precision.
55  !! horiz_interp_bilinear__new_2d_r8:
56  !! input and output grids provided as 2D arrays in 64-bit precision.
58  module procedure horiz_interp_bilinear_new_1d_r4
59  module procedure horiz_interp_bilinear_new_1d_r8
60  module procedure horiz_interp_bilinear_new_2d_r4
61  module procedure horiz_interp_bilinear_new_2d_r8
62  end interface
63 
64  !> Generic interface to populate Interp from a weight file generated from fregrid.
65  !! Calls horiz_interp_read_weights_bilinear_r4 if grid arguments are provided as 32-bit precision.
66  !! Calls horiz_interp_read_weights_bilienar_r8 if grid arguments are provided as 64-bit precision.
68  module procedure horiz_interp_read_weights_bilinear_r4
69  module procedure horiz_interp_read_weights_bilinear_r8
70  end interface
71 
72  !> Generic interface to interpolate data from a source grid to target grid using the weights
73  !! stored in Interp. Calls horiz_interp_bilinear_r4 if input and output data are 2D arrays
74  !! in 32-bit precision. Calls horiz_interp_bilinear_r8 if input and output data are 2D arrays
75  !! in 64-bit precision.
77  module procedure horiz_interp_bilinear_r4
78  module procedure horiz_interp_bilinear_r8
79  end interface
80 
81  real(r8_kind), parameter :: epsln=1.e-10_r8_kind !< is a really small number
82  real(r4_kind), parameter :: epsln_r4=1.e-4_r4_kind !< is 0.0001
83  integer, parameter :: dummy = -999 !< is -999
84 
85  !> Generic interface used internally when finding nearest neighboring input cells
86  !! for an output cell. Calls intersect_r4 when grid points are in 32-bit precision.
87  !! Calls intersect_r8 when grid points are in 64-bit precision.
88  interface intersect
89  module procedure intersect_r4
90  module procedure intersect_r8
91  end interface
92 
93 #include<file_version.h>
94  logical :: module_is_initialized = .false. !< is a flag to prevent re-initialization
95 
96 contains
97 
98  !> @parblock
99  !! Initializes horiz_interp_bilinear_mod. Called from horiz_interp_init in horiz_interp_mod.
100  !! @endparblock
102 
103  if(module_is_initialized) return
104  call write_version_number("HORIZ_INTERP_BILINEAR_MOD", version)
105  module_is_initialized = .true.
106 
107  end subroutine horiz_interp_bilinear_init
108 
109  !> @brief Deallocates memory used by "horiz_interp_type" variables.
110  !!
111  !> Must be called before reinitializing with horiz_interp_bilinear_new.
112 
113  !> @parblock
114  !! Deallocates arrays holding bilinear interpolation weights and mapping indices in Interp.
115  !! Resets %is_allocated to .false. Called from horiz_interp_del in horiz_interp_mod.
116  !! @endparblock
117  subroutine horiz_interp_bilinear_del( Interp )
118 
119  type (horiz_interp_type), intent(inout) :: interp !< will be reset with deallocated memory.
120 
121  if( interp%horizInterpReals4_type%is_allocated) then
122  if(allocated(interp%horizInterpReals4_type%wti)) deallocate(interp%horizInterpReals4_type%wti)
123  if(allocated(interp%horizInterpReals4_type%wtj)) deallocate(interp%horizInterpReals4_type%wtj)
124  else if (interp%horizInterpReals8_type%is_allocated) then
125  if(allocated(interp%horizInterpReals8_type%wti)) deallocate(interp%horizInterpReals8_type%wti)
126  if(allocated(interp%horizInterpReals8_type%wtj)) deallocate(interp%horizInterpReals8_type%wtj)
127  endif
128  if(allocated(interp%i_lon)) deallocate(interp%i_lon)
129  if(allocated(interp%j_lat)) deallocate(interp%j_lat)
130 
131  interp%horizInterpReals4_type%is_allocated = .false.
132  interp%horizInterpReals8_type%is_allocated = .false.
133 
134  end subroutine horiz_interp_bilinear_del
135 
136 #include "horiz_interp_bilinear_r4.fh"
137 #include "horiz_interp_bilinear_r8.fh"
138 
139 end module horiz_interp_bilinear_mod
140 !> @}
Close a netcdf or domain file opened with open_file or open_virtual_file.
Definition: fms2_io.F90:233
Opens a NetCDF dataset on disk and initializes the file object.
Definition: fms2_io.F90:188
Read data from a defined field in a file.
Definition: fms2_io.F90:364
subroutine, public write_version_number(version, tag, unit)
Prints to the log file (or a specified unit) the version id string and tag name.
Definition: fms.F90:701
character(:) function, allocatable, public string(v, fmt)
Converts a number or a Boolean value to a string.
real(r4_kind), parameter epsln_r4
is 0.0001
subroutine, public horiz_interp_bilinear_del(Interp)
Deallocates memory used by "horiz_interp_type" variables.
integer, parameter dummy
is -999
real(r8_kind), parameter epsln
is a really small number
logical module_is_initialized
is a flag to prevent re-initialization
subroutine, public horiz_interp_bilinear_init
Generic interface to interpolate data from a source grid to target grid using the weights stored in I...
Generic interface to populate Interp from a weight file generated from fregrid. Calls horiz_interp_re...
Generic interface used internally when finding nearest neighboring input cells for an output cell....
integer, parameter, public bilinear
is an internally used parameter to mark bilinear interpolation
Generic interfaces to compute statistics for bilinear and spherical interpolation Calls stats_r4 when...
Datatype holding interpolation weights, mapping indices, and metadata for horizontal interpolation....
integer function stdout()
This function returns the current standard fortran unit numbers for output.
Definition: mpp_util.inc:42
integer function mpp_pe()
Returns processor ID.
Definition: mpp_util.inc:406
Error handler.
Definition: mpp.F90:385
Generic interface to compute interpolation weights and mapping indices. Member subroutines and their ...