NCEPLIBS-ip 5.2.0
Loading...
Searching...
No Matches
ip_grid_mod.F90
Go to the documentation of this file.
1
5
12 implicit none
13
14 integer, public, parameter :: equid_cylind_grid_id_grib1 = 0
15 integer, public, parameter :: mercator_grid_id_grib1 = 1
16 integer, public, parameter :: lambert_conf_grid_id_grib1 = 3
17 integer, public, parameter :: gaussian_grid_id_grib1 = 4
18 integer, public, parameter :: polar_stereo_grid_id_grib1 = 5
19 integer, public, parameter :: rot_equid_cylind_e_grid_id_grib1 = 203
20 integer, public, parameter :: rot_equid_cylind_b_grid_id_grib1 = 205
21
22 integer, public, parameter :: equid_cylind_grid_id_grib2 = 0
23 integer, public, parameter :: rot_equid_cylind_grid_id_grib2 = 1
24 integer, public, parameter :: mercator_grid_id_grib2 = 10
25 integer, public, parameter :: polar_stereo_grid_id_grib2 = 20
26 integer, public, parameter :: lambert_conf_grid_id_grib2 = 30
27 integer, public, parameter :: gaussian_grid_id_grib2 = 40
28 integer, public, parameter :: rot_equid_cylind_e_grid_id_grib2 = 32768
29 integer, public, parameter :: rot_equid_cylind_b_grid_id_grib2 = 32769
30
31 logical, public, save :: ncep_post_arakawa=.false.
32
33 private
34 public :: ip_grid
35 public :: gdswzd_interface
36 public :: operator(==)
37 public :: use_ncep_post_arakawa
39
58 type, abstract :: ip_grid
59 class(ip_grid_descriptor), allocatable :: descriptor
60
61 integer :: im
62 integer :: jm
63 integer :: nm
64
69 integer :: nscan
70 integer :: kscan
71
72 integer :: nscan_field_pos
73
74 integer :: iwrap
75 integer :: jwrap1
76 integer :: jwrap2
77 real :: rerth
78 real :: eccen_squared
79 contains
82 procedure(init_grib1_interface), deferred :: init_grib1
84 procedure(init_grib2_interface), deferred :: init_grib2
86 procedure(gdswzd_interface), deferred :: gdswzd
91 procedure :: field_pos
93 generic :: init => init_grib1, init_grib2
94 end type ip_grid
95
96 abstract interface
97
128 subroutine gdswzd_interface(self, iopt, npts, fill, xpts, ypts, rlon, rlat, nret, crot, srot, &
129 xlon, xlat, ylon, ylat, area)
130 import
131 class(ip_grid), intent(in) :: self
132 INTEGER, INTENT(IN ) :: IOPT, NPTS
133 INTEGER, INTENT( OUT) :: NRET
134 !
135 REAL, INTENT(IN ) :: FILL
136 REAL, INTENT(INOUT) :: RLON(NPTS),RLAT(NPTS)
137 REAL, INTENT(INOUT) :: XPTS(NPTS),YPTS(NPTS)
138 REAL, OPTIONAL, INTENT( OUT) :: CROT(NPTS),SROT(NPTS)
139 REAL, OPTIONAL, INTENT( OUT) :: XLON(NPTS),XLAT(NPTS)
140 REAL, OPTIONAL, INTENT( OUT) :: YLON(NPTS),YLAT(NPTS),AREA(NPTS)
141 end subroutine gdswzd_interface
142
151 subroutine init_grib1_interface(self, g1_desc)
152 import
153 class(ip_grid), intent(inout) :: self
154 type(grib1_descriptor), intent(in) :: g1_desc
155 end subroutine init_grib1_interface
156
165 subroutine init_grib2_interface(self, g2_desc)
166 import
167 class(ip_grid), intent(inout) :: self
168 type(grib2_descriptor), intent(in) :: g2_desc
169 end subroutine init_grib2_interface
170
171 end interface
172
175 interface operator (==)
176 module procedure is_same_grid
177 end interface operator (==)
178
179
180contains
181
188 subroutine use_ncep_post_arakawa() bind(c)
189 ncep_post_arakawa = .true.
190 end subroutine use_ncep_post_arakawa
191
198 subroutine unuse_ncep_post_arakawa() bind(c)
199 ncep_post_arakawa = .false.
200 end subroutine unuse_ncep_post_arakawa
201
211 logical function is_same_grid(grid1, grid2)
212 class(ip_grid), intent(in) :: grid1, grid2
213 is_same_grid = grid1%descriptor == grid2%descriptor
214 end function is_same_grid
215
226 function field_pos(self, i, j)
227 class(ip_grid), intent(in) :: self
228 integer, intent(in) :: i, j
229 integer :: field_pos
230
231 integer :: ii, jj, im, jm
232 integer :: iif, jjf, is1, iwrap
233 integer :: jwrap1, jwrap2, kscan, nscan
234
235 ! extract from navigation parameter array
236 im=self%im
237 jm=self%jm
238 iwrap=self%iwrap
239 jwrap1=self%jwrap1
240 jwrap2=self%jwrap2
241 nscan=self%nscan_field_pos
242 kscan=self%kscan
243
244 ! compute wraparounds in x and y if necessary and possible
245 ii=i
246 jj=j
247 if(iwrap.gt.0) then
248 ii=mod(i-1+iwrap,iwrap)+1
249 if(j.lt.1.and.jwrap1.gt.0) then
250 jj=jwrap1-j
251 ii=mod(ii-1+iwrap/2,iwrap)+1
252 elseif(j.gt.jm.and.jwrap2.gt.0) then
253 jj=jwrap2-j
254 ii=mod(ii-1+iwrap/2,iwrap)+1
255 endif
256 endif
257
258 ! compute position for the appropriate scanning mode
259 field_pos=0
260 if(nscan.eq.0) then
261 if(ii.ge.1.and.ii.le.im.and.jj.ge.1.and.jj.le.jm) field_pos=ii+(jj-1)*im
262 elseif(nscan.eq.1) then
263 if(ii.ge.1.and.ii.le.im.and.jj.ge.1.and.jj.le.jm) field_pos=jj+(ii-1)*jm
264 elseif(nscan.eq.2) then
265 is1=(jm+1-kscan)/2
266 iif=jj+(ii-is1)
267 jjf=jj-(ii-is1)+kscan
268 if(iif.ge.1.and.iif.le.2*im-1.and.jjf.ge.1.and.jjf.le.jm) &
269 field_pos=(iif+(jjf-1)*(2*im-1)+1-kscan)/2
270 elseif(nscan.eq.3) then
271 is1=(jm+1-kscan)/2
272 iif=jj+(ii-is1)
273 jjf=jj-(ii-is1)+kscan
274 if(iif.ge.1.and.iif.le.2*im-1.and.jjf.ge.1.and.jjf.le.jm) field_pos=(iif+1)/2+(jjf-1)*im
275 endif
276 end function field_pos
277
278
279end module ip_grid_mod
280
void gdswzd(int igdtnum, int *igdtmpl, int igdtlen, int iopt, int npts, float fill, float *xpts, float *ypts, float *rlon, float *rlat, int *nret, float *crot, float *srot, float *xlon, float *xlat, float *ylon, float *ylat, float *area)
gdswzd() interface for C for _4 build of library.
Users derived type grid descriptor objects to abstract away the raw GRIB1 and GRIB2 grid definitions.
logical function is_same_grid(grid1, grid2)
Test whether two grid descriptors are the same.
Abstract ip_grid type.
subroutine, public use_ncep_post_arakawa()
Enables ncep_post/wgrib2-compatible non-E Arakawa grib2 grids by setting 'ncep_post_arakawa=....
integer, parameter, public rot_equid_cylind_e_grid_id_grib2
Integer grid number for rotated equidistant cylindrical E-stagger grid (grib2)
integer, parameter, public lambert_conf_grid_id_grib2
Integer grid number for Lambert conformal grid in grib2.
integer, parameter, public gaussian_grid_id_grib2
Integer grid number for Gaussian grid in grib2.
integer, parameter, public equid_cylind_grid_id_grib2
Integer grid number for equidistant cylindrical grid in grib2.
integer, parameter, public gaussian_grid_id_grib1
Integer grid number for Gaussian grid in grib1.
integer, parameter, public rot_equid_cylind_e_grid_id_grib1
Integer grid number for rotated equidistant cylindrical E-stagger grid.
integer, parameter, public polar_stereo_grid_id_grib2
Integer grid number for polar stereo grid in grib2.
integer function field_pos(self, i, j)
Returns the field position for a given grid point.
logical, save, public ncep_post_arakawa
Use ncep_post/wgrib2-compatible version of init_grib2() for non-E Arakawa grids (enable with use_ncep...
integer, parameter, public lambert_conf_grid_id_grib1
Integer grid number for Lambert Conformal grid in grib1.
integer, parameter, public mercator_grid_id_grib1
Integer grid number for Mercator grid in grib1.
subroutine, public unuse_ncep_post_arakawa()
Disables ncep_post/wgrib2-compatible non-E Arakawa grib2 grids by setting 'ncep_post_arakawa=....
integer, parameter, public equid_cylind_grid_id_grib1
Integer grid number for equidistant cylindrical grid in grib1.
integer, parameter, public rot_equid_cylind_b_grid_id_grib1
Integer grid number for rotated equidistant cylindrical B-stagger grid.
integer, parameter, public rot_equid_cylind_b_grid_id_grib2
Integer grid number for rotated equidistant cylindrical B-stagger grid (grib2)
integer, parameter, public rot_equid_cylind_grid_id_grib2
Integer grid number for rotated equidistant cylindrical grid in grib2.
integer, parameter, public mercator_grid_id_grib2
Integer grid number for Mercator grid in grib2.
integer, parameter, public polar_stereo_grid_id_grib1
Integer grid number for polar stereo grid in grib1.
Descriptor representing a grib1 grib descriptor section (GDS) with an integer array.
Grib-2 descriptor containing a grib2 GDT represented by an integer array.
Abstract descriptor object which represents a grib1 or grib2 descriptor.
Abstract grid that holds fields and methods common to all grids.