FMS  2026.01.01-dev
Flexible Modeling System
horiz_interp_conserve.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_conserve_mod horiz_interp_conserve_mod
19 !! @ingroup horiz_interp
20 !! @{
21 !!
22 !! @author Bruce Wyman, Zhi Liang
23 !!
24 !! @parblock
25 !! Horiz_interp_conserve_mod contains methods called from horiz_interp_mod to
26 !! interpolate data on any logically rectangular grid to any rectangular grid
27 !! with order 1 conservative method. Users are recommended to use the top-level
28 !! module horiz_interp_mod with "interp" set to "conservative for conservative
29 !! interpolation.
30 !! @endparblock
31 
32 module horiz_interp_conserve_mod
33 
34  use platform_mod, only: r4_kind, r8_kind
35  use mpp_mod, only: mpp_send, mpp_recv, mpp_pe, mpp_root_pe, mpp_npes
36  use mpp_mod, only: mpp_error, fatal, mpp_sync_self
37  use mpp_mod, only: comm_tag_1, comm_tag_2
38  use fms_mod, only: write_version_number
39  use grid2_mod, only: get_great_circle_algorithm
40  use constants_mod, only: pi
41  use horiz_interp_type_mod, only: horiz_interp_type, conserve
42 
43 
44  implicit none
45  private
46 
47 
48  !> Generic interface to compute interpolation weights and mapping indices.
49  !! Member subroutines and their main arguments are:
50  !! horiz_interp_conserve_new_1dx1d_r4:
51  !! input and output grids are provided as 1D arrays in 32-bit precision.
52  !! horiz_interp_conserve_new_1dx1d_r8:
53  !! input and output grids are provided as 1D arrays in 64-bit precision.
54  !! horiz_interp_conserve_new_2dx1d_r4:
55  !! input grid is provided as 2D arrays, output grid as 1D arrays, both in 32-bit precision.
56  !! horiz_interp_conserve_new_2dx1d_r8:
57  !! input grid is provided as 2D arrays, output grid as 1D arrays, both in 64-bit precision.
58  !! horiz_interp_conserve_new_1dx2d_r4:
59  !! input grid is provided as 1D arrays, output grid as 2D arrays, both in 32-bit precision.
60  !! horiz_interp_conserve_new_1dx2d_r8:
61  !! input grid is provided as 1D arrays, output grid as 2D arrays, both in 64-bit precision.
62  !! horiz_interp_conserve_new_2dx2d_r4:
63  !! input and output grids are provided as 2D arrays in 32-bit precision.
64  !! horiz_interp_conserve_new_2dx2d_r8:
65  !! input and output grids are provided as 2D arrays in 64-bit precision.
67  module procedure horiz_interp_conserve_new_1dx1d_r4
68  module procedure horiz_interp_conserve_new_1dx2d_r4
69  module procedure horiz_interp_conserve_new_2dx1d_r4
70  module procedure horiz_interp_conserve_new_2dx2d_r4
71  module procedure horiz_interp_conserve_new_1dx1d_r8
72  module procedure horiz_interp_conserve_new_1dx2d_r8
73  module procedure horiz_interp_conserve_new_2dx1d_r8
74  module procedure horiz_interp_conserve_new_2dx2d_r8
75  end interface
76 
77  !> Generic interface to interpolate data from source grid to target grid from the weights
78  !! stored in Interp. Calls horiz_interp_conserve_r4 if input and output data are 2D arrays
79  !! in 32-bit precision. Calls horiz_interp_conserve_r8 if input and output data are 2D
80  !! arrays in 64-bit precision. Horiz_interp_conserve_r* will subsequently call
81  !! horiz_interp_conserve_version1 or horiz_interp_conserve_version2 depending on value of
82  !! Interp%version.
84  module procedure horiz_interp_conserve_r4
85  module procedure horiz_interp_conserve_r8
86  end interface
87 
88  !> Internally used generic interface when interpolating data with Interp
89  !! generated from horiz_interp_new_1dx1d_r*. Not frequently used.
90  interface data_sum
91  module procedure data_sum_r4
92  module procedure data_sum_r8
93  end interface
94 
95  !> Internally used generic interface when interpolating data with Interp
96  !! generated from horiz_interp_new_1dx1d_r*. Not frequently used.
97  interface stats
98  module procedure stats_r4
99  module procedure stats_r8
100  end interface
101 
102  !> Generic inteface called from horiz_interp_conserve to interpolate
103  !! data using Interp populated from horiz_interp_new_1dx1d_r*.
105  module procedure horiz_interp_conserve_version1_r8
106  module procedure horiz_interp_conserve_version1_r4
107  end interface
108 
109  !> Generic interface called from horiz_interp_conserve to interpolate
110  !! 2d data. Calls horiz_interp_conserve_version2_r4 when data are 2D
111  !! arrays in 32-bit precision. Calls horiz_interp_conserve_version2_r8 when
112  !! data are 2D arrays in 64-bit precision.
114  module procedure horiz_interp_conserve_version2_r8
115  module procedure horiz_interp_conserve_version2_r4
116  end interface
117 
120 
121  integer :: pe !< is the current pe
122  integer :: root_pe !< is the root_pe
123 
124 #include<file_version.h>
125 
126  !! TODO: how to set great_circle_algorithm
127  logical :: module_is_initialized = .false. !< is a flag to prevent module re-initialization.
128  logical :: great_circle_algorithm = .false. !< turns on the great_circle_algorithm to compute grid cell areas.
129 
130 contains
131 
132  !> @parblock
133  !! Initializes horiz_interp_conserve_mod. Called from horiz_interp_init in horiz_interp_mod.
134  !! @endparblock
136 
137  if(module_is_initialized) return
138  call write_version_number("HORIZ_INTERP_CONSERVE_MOD", version)
139 
141 
142  module_is_initialized = .true.
143 
144  end subroutine horiz_interp_conserve_init
145 
146  !> @parblock
147  !! Deallocates arrays holding conservative order 1 interpolation weights and mapping indices
148  !! in Interp. Resets %is_allocated to .false. Called from horiz_interp_del in horiz_interp_mod.
149  !! @endparblock
150  subroutine horiz_interp_conserve_del ( Interp )
151 
152  type (horiz_interp_type), intent(inout) :: interp !< will be reset with deallocated memory
153 
154  select case(interp%version)
155  case (1)
156  if( interp%horizInterpReals8_type%is_allocated) then
157  if(allocated(interp%horizInterpReals8_type%area_src)) deallocate(interp%horizInterpReals8_type%area_src)
158  if(allocated(interp%horizInterpReals8_type%area_dst)) deallocate(interp%horizInterpReals8_type%area_dst)
159  if(allocated(interp%horizInterpReals8_type%facj)) deallocate(interp%horizInterpReals8_type%facj)
160  if(allocated(interp%jlat)) deallocate(interp%jlat)
161  if(allocated(interp%horizInterpReals8_type%faci)) deallocate(interp%horizInterpReals8_type%faci)
162  if(allocated(interp%ilon)) deallocate(interp%ilon)
163  else if( interp%horizInterpReals4_type%is_allocated) then
164  if(allocated(interp%horizInterpReals4_type%area_src)) deallocate(interp%horizInterpReals4_type%area_src)
165  if(allocated(interp%horizInterpReals4_type%area_dst)) deallocate(interp%horizInterpReals4_type%area_dst)
166  if(allocated(interp%horizInterpReals4_type%facj)) deallocate(interp%horizInterpReals4_type%facj)
167  if(allocated(interp%jlat)) deallocate(interp%jlat)
168  if(allocated(interp%horizInterpReals4_type%faci)) deallocate(interp%horizInterpReals4_type%faci)
169  if(allocated(interp%ilon)) deallocate(interp%ilon)
170  endif
171  case (2)
172  if( interp%horizInterpReals8_type%is_allocated) then
173  if(allocated(interp%i_src)) deallocate(interp%i_src)
174  if(allocated(interp%j_src)) deallocate(interp%j_src)
175  if(allocated(interp%i_dst)) deallocate(interp%i_dst)
176  if(allocated(interp%j_dst)) deallocate(interp%j_dst)
177  if(allocated(interp%horizInterpReals8_type%area_frac_dst)) &
178  deallocate(interp%horizInterpReals8_type%area_frac_dst)
179  else if( interp%horizInterpReals4_type%is_allocated ) then
180  if(allocated(interp%i_src)) deallocate(interp%i_src)
181  if(allocated(interp%j_src)) deallocate(interp%j_src)
182  if(allocated(interp%i_dst)) deallocate(interp%i_dst)
183  if(allocated(interp%j_dst)) deallocate(interp%j_dst)
184  if(allocated(interp%horizInterpReals4_type%area_frac_dst)) &
185  deallocate(interp%horizInterpReals4_type%area_frac_dst)
186  endif
187  end select
188  interp%horizInterpReals4_type%is_allocated = .false.
189  interp%horizInterpReals8_type%is_allocated = .false.
190 
191  end subroutine horiz_interp_conserve_del
192 
193 #include "horiz_interp_conserve_r4.fh"
194 #include "horiz_interp_conserve_r8.fh"
195 
196 end module horiz_interp_conserve_mod
197 !> @}
198 ! close documentation grouping
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
logical function, public get_great_circle_algorithm()
Determine if we are using the great circle algorithm.
Definition: grid2.F90:188
subroutine, public horiz_interp_conserve_init
integer pe
is the current pe
logical great_circle_algorithm
turns on the great_circle_algorithm to compute grid cell areas.
subroutine, public horiz_interp_conserve_del(Interp)
logical module_is_initialized
is a flag to prevent module re-initialization.
Internally used generic interface when interpolating data with Interp generated from horiz_interp_new...
Generic interface to interpolate data from source grid to target grid from the weights stored in Inte...
Generic inteface called from horiz_interp_conserve to interpolate data using Interp populated from ho...
Generic interface called from horiz_interp_conserve to interpolate 2d data. Calls horiz_interp_conser...
Internally used generic interface when interpolating data with Interp generated from horiz_interp_new...
Datatype holding interpolation weights, mapping indices, and metadata for horizontal interpolation....
subroutine mpp_sync_self(pelist, check, request, msg_size, msg_type)
This is to check if current PE's outstanding puts are complete but we can't use shmem_fence because w...
integer function mpp_npes()
Returns processor count for current pelist.
Definition: mpp_util.inc:420
integer function mpp_pe()
Returns processor ID.
Definition: mpp_util.inc:406
Error handler.
Definition: mpp.F90:385
Receive data from another PE.
Definition: mpp.F90:999
Send data to a receiving PE.
Definition: mpp.F90:1066
Generic interface to compute interpolation weights and mapping indices. Member subroutines and their ...