FV3 Bundle
horiz_interp_type.F90
Go to the documentation of this file.
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 !***********************************************************************
20 ! <CONTACT EMAIL="Zhi.Liang@noaa.gov"> Zhi Liang </CONTACT>
21 
22 ! <HISTORY SRC="http://www.gfdl.noaa.gov/fms-cgi-bin/cvsweb.cgi/FMS/"/>
23 
24 ! <OVERVIEW>
25 ! define derived data type that contains indices and weights used for subsequent
26 ! interpolations.
27 ! </OVERVIEW>
28 
29 ! <DESCRIPTION>
30 ! define derived data type that contains indices and weights used for subsequent
31 ! interpolations.
32 ! </DESCRIPTION>
33 
34 
35 use mpp_mod, only : mpp_send, mpp_recv, mpp_sync_self, mpp_error, fatal
36 use mpp_mod, only : mpp_pe, mpp_root_pe, mpp_npes
37 use mpp_mod, only : comm_tag_1, comm_tag_2
38 
39 implicit none
40 private
41 
42 
43 ! parameter to determine interpolation method
44  integer, parameter :: conserve = 1
45  integer, parameter :: bilinear = 2
46  integer, parameter :: spherica = 3
47  integer, parameter :: bicubic = 4
48 
49 public :: conserve, bilinear, spherica, bicubic
50 public :: horiz_interp_type, stats, assignment(=)
51 
52 interface assignment(=)
53  module procedure horiz_interp_type_eq
54 end interface
55 
56 !<PUBLICTYPE >
58  real, dimension(:,:), pointer :: faci =>null(), facj =>null() !weights for conservative scheme
59  integer, dimension(:,:), pointer :: ilon =>null(), jlat =>null() !indices for conservative scheme
60  real, dimension(:,:), pointer :: area_src =>null() !area of the source grid
61  real, dimension(:,:), pointer :: area_dst =>null() !area of the destination grid
62  real, dimension(:,:,:), pointer :: wti =>null(),wtj =>null() !weights for bilinear interpolation
63  !wti ist used for derivative "weights" in bicubic
64  integer, dimension(:,:,:), pointer :: i_lon =>null(), j_lat =>null() !indices for bilinear interpolation
65  !and spherical regrid
66  real, dimension(:,:,:), pointer :: src_dist =>null() !distance between destination grid and
67  !neighbor source grid.
68  logical, dimension(:,:), pointer :: found_neighbors =>null() !indicate whether destination grid
69  !has some source grid around it.
70  real :: max_src_dist
71  integer, dimension(:,:), pointer :: num_found => null()
72  integer :: nlon_src, nlat_src !size of source grid
73  integer :: nlon_dst, nlat_dst !size of destination grid
74  integer :: interp_method !interpolation method.
75  !=1, conservative scheme
76  !=2, bilinear interpolation
77  !=3, spherical regrid
78  !=4, bicubic regrid
79  real, dimension(:,:), pointer :: rat_x =>null(), rat_y =>null() !the ratio of coordinates of the dest grid
80  ! (x_dest -x_src_r)/(x_src_l -x_src_r) and (y_dest -y_src_r)/(y_src_l -y_src_r)
81  real, dimension(:), pointer :: lon_in =>null(), lat_in =>null() !the coordinates of the source grid
82  logical :: i_am_initialized=.false.
83  integer :: version !indicate conservative interpolation version with value 1 or 2
84  !--- The following are for conservative interpolation scheme version 2 ( through xgrid)
85  integer :: nxgrid !number of exchange grid between src and dst grid.
86  integer, dimension(:), pointer :: i_src=>null(), j_src=>null() !indices in source grid.
87  integer, dimension(:), pointer :: i_dst=>null(), j_dst=>null() !indices in destination grid.
88  real, dimension(:), pointer :: area_frac_dst=>null() !area fraction in destination grid.
89  real, dimension(:,:), pointer :: mask_in=>null()
90  end type
91 !</PUBLICTYPE>
92 
93 contains
94 
95 !#######################################################################
96 !---This statistics is for bilinear interpolation and spherical regrid.
97  subroutine stats ( dat, low, high, avg, miss, missing_value, mask )
98  real, intent(in) :: dat(:,:)
99  real, intent(out) :: low, high, avg
100  integer, intent(out) :: miss
101  real, intent(in), optional :: missing_value
102  real, intent(in), optional :: mask(:,:)
103 
104  real :: dsum, npts, buffer_real(3)
105  integer :: pe, root_pe, npes, p, buffer_int(2)
106 
107  pe = mpp_pe()
108  root_pe = mpp_root_pe()
109  npes = mpp_npes()
110 
111  dsum = 0.0
112  miss = 0
113 
114  if (present(missing_value)) then
115  miss = count(dat(:,:) == missing_value)
116  low = minval(dat(:,:), dat(:,:) /= missing_value)
117  high = maxval(dat(:,:), dat(:,:) /= missing_value)
118  dsum = sum(dat(:,:), dat(:,:) /= missing_value)
119  else if(present(mask)) then
120  miss = count(mask(:,:) <= 0.5)
121  low = minval(dat(:,:),mask=mask(:,:) > 0.5)
122  high = maxval(dat(:,:),mask=mask(:,:) > 0.5)
123  dsum = sum(dat(:,:), mask=mask(:,:) > 0.5)
124  else
125  miss = 0
126  low = minval(dat(:,:))
127  high = maxval(dat(:,:))
128  dsum = sum(dat(:,:))
129  endif
130  avg = 0.0
131 
132  npts = size(dat(:,:)) - miss
133  if(pe == root_pe) then
134  do p = 1, npes - 1 ! root_pe receive data from other pe
135  ! Force use of "scalar", integer pointer mpp interface
136  call mpp_recv(buffer_real(1),glen=3, from_pe=p+root_pe, tag=comm_tag_1)
137  dsum = dsum + buffer_real(1)
138  low = min(low, buffer_real(2))
139  high = max(high, buffer_real(3))
140  call mpp_recv(buffer_int(1), glen=2, from_pe=p+root_pe, tag=comm_tag_2)
141  miss = miss + buffer_int(1)
142  npts = npts + buffer_int(2)
143  enddo
144  if(npts == 0.) then
145  print*, 'Warning: no points is valid'
146  else
147  avg = dsum/real(npts)
148  endif
149  else ! other pe send data to the root_pe.
150  buffer_real(1) = dsum
151  buffer_real(2) = low
152  buffer_real(3) = high
153  ! Force use of "scalar", integer pointer mpp interface
154  call mpp_send(buffer_real(1),plen=3,to_pe=root_pe, tag=comm_tag_1)
155  buffer_int(1) = miss
156  buffer_int(2) = npts
157  call mpp_send(buffer_int(1), plen=2, to_pe=root_pe, tag=comm_tag_2)
158  endif
159 
160  call mpp_sync_self()
161 
162  return
163 
164  end subroutine stats
165 
166 !#################################################################################################################################
167  subroutine horiz_interp_type_eq(horiz_interp_out, horiz_interp_in)
168  type(horiz_interp_type), intent(inout) :: horiz_interp_out
169  type(horiz_interp_type), intent(in) :: horiz_interp_in
170 
171  if(.not.horiz_interp_in%I_am_initialized) then
172  call mpp_error(fatal,'horiz_interp_type_eq: horiz_interp_type variable on right hand side is unassigned')
173  endif
174 
175  horiz_interp_out%faci => horiz_interp_in%faci
176  horiz_interp_out%facj => horiz_interp_in%facj
177  horiz_interp_out%ilon => horiz_interp_in%ilon
178  horiz_interp_out%jlat => horiz_interp_in%jlat
179  horiz_interp_out%area_src => horiz_interp_in%area_src
180  horiz_interp_out%area_dst => horiz_interp_in%area_dst
181  horiz_interp_out%wti => horiz_interp_in%wti
182  horiz_interp_out%wtj => horiz_interp_in%wtj
183  horiz_interp_out%i_lon => horiz_interp_in%i_lon
184  horiz_interp_out%j_lat => horiz_interp_in%j_lat
185  horiz_interp_out%src_dist => horiz_interp_in%src_dist
186  horiz_interp_out%found_neighbors => horiz_interp_in%found_neighbors
187  horiz_interp_out%max_src_dist = horiz_interp_in%max_src_dist
188  horiz_interp_out%num_found => horiz_interp_in%num_found
189  horiz_interp_out%nlon_src = horiz_interp_in%nlon_src
190  horiz_interp_out%nlat_src = horiz_interp_in%nlat_src
191  horiz_interp_out%nlon_dst = horiz_interp_in%nlon_dst
192  horiz_interp_out%nlat_dst = horiz_interp_in%nlat_dst
193  horiz_interp_out%interp_method = horiz_interp_in%interp_method
194  horiz_interp_out%rat_x => horiz_interp_in%rat_x
195  horiz_interp_out%rat_y => horiz_interp_in%rat_y
196  horiz_interp_out%lon_in => horiz_interp_in%lon_in
197  horiz_interp_out%lat_in => horiz_interp_in%lat_in
198  horiz_interp_out%I_am_initialized = .true.
199  horiz_interp_out%i_src => horiz_interp_in%i_src
200  horiz_interp_out%j_src => horiz_interp_in%j_src
201  horiz_interp_out%i_dst => horiz_interp_in%i_dst
202  horiz_interp_out%j_dst => horiz_interp_in%j_dst
203  horiz_interp_out%area_frac_dst => horiz_interp_in%area_frac_dst
204  if(horiz_interp_in%interp_method == conserve) then
205  horiz_interp_out%version = horiz_interp_in%version
206  if(horiz_interp_in%version==2) horiz_interp_out%nxgrid = horiz_interp_in%nxgrid
207  end if
208 
209  end subroutine horiz_interp_type_eq
210 !#################################################################################################################################
211 
212 end module horiz_interp_type_mod
integer, parameter, public spherica
integer, parameter, public bilinear
subroutine horiz_interp_type_eq(horiz_interp_out, horiz_interp_in)
integer, parameter, public bicubic
subroutine, public stats(dat, low, high, avg, miss, missing_value, mask)
Definition: mpp.F90:39
integer, parameter, public conserve
#define max(a, b)
Definition: mosaic_util.h:33
#define min(a, b)
Definition: mosaic_util.h:32