NCEPLIBS-ip  5.1.0
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
38  public :: unuse_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
81  procedure(init_grib1_interface), deferred :: init_grib1
83  procedure(init_grib2_interface), deferred :: init_grib2
85  procedure(gdswzd_interface), deferred :: gdswzd
88  procedure :: field_pos
90  generic :: init => init_grib1, init_grib2
91  end type ip_grid
92 
93  abstract interface
94 
125  subroutine gdswzd_interface(self, iopt, npts, fill, xpts, ypts, rlon, rlat, nret, crot, srot, &
126  xlon, xlat, ylon, ylat, area)
127  import
128  class(ip_grid), intent(in) :: self
129  INTEGER, INTENT(IN ) :: IOPT, NPTS
130  INTEGER, INTENT( OUT) :: NRET
131  !
132  REAL, INTENT(IN ) :: FILL
133  REAL, INTENT(INOUT) :: RLON(NPTS),RLAT(NPTS)
134  REAL, INTENT(INOUT) :: XPTS(NPTS),YPTS(NPTS)
135  REAL, OPTIONAL, INTENT( OUT) :: CROT(NPTS),SROT(NPTS)
136  REAL, OPTIONAL, INTENT( OUT) :: XLON(NPTS),XLAT(NPTS)
137  REAL, OPTIONAL, INTENT( OUT) :: YLON(NPTS),YLAT(NPTS),AREA(NPTS)
138  end subroutine gdswzd_interface
139 
148  subroutine init_grib1_interface(self, g1_desc)
149  import
150  class(ip_grid), intent(inout) :: self
151  type(grib1_descriptor), intent(in) :: g1_desc
152  end subroutine init_grib1_interface
153 
162  subroutine init_grib2_interface(self, g2_desc)
163  import
164  class(ip_grid), intent(inout) :: self
165  type(grib2_descriptor), intent(in) :: g2_desc
166  end subroutine init_grib2_interface
167 
168  end interface
169 
172  interface operator (==)
173  module procedure is_same_grid
174  end interface operator (==)
175 
176 
177 contains
178 
185  subroutine use_ncep_post_arakawa() bind(c)
186  ncep_post_arakawa = .true.
187  end subroutine use_ncep_post_arakawa
188 
195  subroutine unuse_ncep_post_arakawa() bind(c)
196  ncep_post_arakawa = .false.
197  end subroutine unuse_ncep_post_arakawa
198 
208  logical function is_same_grid(grid1, grid2)
209  class(ip_grid), intent(in) :: grid1, grid2
210  is_same_grid = grid1%descriptor == grid2%descriptor
211  end function is_same_grid
212 
223  function field_pos(self, i, j)
224  class(ip_grid), intent(in) :: self
225  integer, intent(in) :: i, j
226  integer :: field_pos
227 
228  integer :: ii, jj, im, jm
229  integer :: iif, jjf, is1, iwrap
230  integer :: jwrap1, jwrap2, kscan, nscan
231 
232  ! extract from navigation parameter array
233  im=self%im
234  jm=self%jm
235  iwrap=self%iwrap
236  jwrap1=self%jwrap1
237  jwrap2=self%jwrap2
238  nscan=self%nscan_field_pos
239  kscan=self%kscan
240 
241  ! compute wraparounds in x and y if necessary and possible
242  ii=i
243  jj=j
244  if(iwrap.gt.0) then
245  ii=mod(i-1+iwrap,iwrap)+1
246  if(j.lt.1.and.jwrap1.gt.0) then
247  jj=jwrap1-j
248  ii=mod(ii-1+iwrap/2,iwrap)+1
249  elseif(j.gt.jm.and.jwrap2.gt.0) then
250  jj=jwrap2-j
251  ii=mod(ii-1+iwrap/2,iwrap)+1
252  endif
253  endif
254 
255  ! compute position for the appropriate scanning mode
256  field_pos=0
257  if(nscan.eq.0) then
258  if(ii.ge.1.and.ii.le.im.and.jj.ge.1.and.jj.le.jm) field_pos=ii+(jj-1)*im
259  elseif(nscan.eq.1) then
260  if(ii.ge.1.and.ii.le.im.and.jj.ge.1.and.jj.le.jm) field_pos=jj+(ii-1)*jm
261  elseif(nscan.eq.2) then
262  is1=(jm+1-kscan)/2
263  iif=jj+(ii-is1)
264  jjf=jj-(ii-is1)+kscan
265  if(iif.ge.1.and.iif.le.2*im-1.and.jjf.ge.1.and.jjf.le.jm) &
266  field_pos=(iif+(jjf-1)*(2*im-1)+1-kscan)/2
267  elseif(nscan.eq.3) then
268  is1=(jm+1-kscan)/2
269  iif=jj+(ii-is1)
270  jjf=jj-(ii-is1)+kscan
271  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
272  endif
273  end function field_pos
274 
275 
276 end module ip_grid_mod
277 
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.
Definition: ip_grid_mod.F90:10
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)
Definition: ip_grid_mod.F90:28
integer, parameter, public lambert_conf_grid_id_grib2
Integer grid number for Lambert conformal grid in grib2.
Definition: ip_grid_mod.F90:26
integer, parameter, public gaussian_grid_id_grib2
Integer grid number for Gaussian grid in grib2.
Definition: ip_grid_mod.F90:27
integer, parameter, public equid_cylind_grid_id_grib2
Integer grid number for equidistant cylindrical grid in grib2.
Definition: ip_grid_mod.F90:22
integer, parameter, public gaussian_grid_id_grib1
Integer grid number for Gaussian grid in grib1.
Definition: ip_grid_mod.F90:17
integer, parameter, public rot_equid_cylind_e_grid_id_grib1
Integer grid number for rotated equidistant cylindrical E-stagger grid.
Definition: ip_grid_mod.F90:19
integer, parameter, public polar_stereo_grid_id_grib2
Integer grid number for polar stereo grid in grib2.
Definition: ip_grid_mod.F90:25
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...
Definition: ip_grid_mod.F90:31
integer, parameter, public lambert_conf_grid_id_grib1
Integer grid number for Lambert Conformal grid in grib1.
Definition: ip_grid_mod.F90:16
integer, parameter, public mercator_grid_id_grib1
Integer grid number for Mercator grid in grib1.
Definition: ip_grid_mod.F90:15
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.
Definition: ip_grid_mod.F90:14
integer, parameter, public rot_equid_cylind_b_grid_id_grib1
Integer grid number for rotated equidistant cylindrical B-stagger grid.
Definition: ip_grid_mod.F90:20
integer, parameter, public rot_equid_cylind_b_grid_id_grib2
Integer grid number for rotated equidistant cylindrical B-stagger grid (grib2)
Definition: ip_grid_mod.F90:29
integer, parameter, public rot_equid_cylind_grid_id_grib2
Integer grid number for rotated equidistant cylindrical grid in grib2.
Definition: ip_grid_mod.F90:23
integer, parameter, public mercator_grid_id_grib2
Integer grid number for Mercator grid in grib2.
Definition: ip_grid_mod.F90:24
integer, parameter, public polar_stereo_grid_id_grib1
Integer grid number for polar stereo grid in grib1.
Definition: ip_grid_mod.F90:18
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.
Definition: ip_grid_mod.F90:58