NCEPLIBS-ip  4.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 
29  private
30  public :: ip_grid
31  public :: gdswzd_interface
32  public :: operator(==)
33 
52  type, abstract :: ip_grid
53  class(ip_grid_descriptor), allocatable :: descriptor
54 
55  integer :: im
56  integer :: jm
57  integer :: nm
58 
63  integer :: nscan
64  integer :: kscan
65 
66  integer :: nscan_field_pos
67 
68  integer :: iwrap
69  integer :: jwrap1
70  integer :: jwrap2
71  real :: rerth
72  real :: eccen_squared
73  contains
75  procedure(init_grib1_interface), deferred :: init_grib1
77  procedure(init_grib2_interface), deferred :: init_grib2
79  procedure(gdswzd_interface), deferred :: gdswzd
82  procedure :: field_pos
84  generic :: init => init_grib1, init_grib2
85  end type ip_grid
86 
87  abstract interface
88 
119  subroutine gdswzd_interface(self, iopt, npts, fill, xpts, ypts, rlon, rlat, nret, crot, srot, &
120  xlon, xlat, ylon, ylat, area)
121  import
122  class(ip_grid), intent(in) :: self
123  INTEGER, INTENT(IN ) :: IOPT, NPTS
124  INTEGER, INTENT( OUT) :: NRET
125  !
126  REAL, INTENT(IN ) :: FILL
127  REAL, INTENT(INOUT) :: RLON(NPTS),RLAT(NPTS)
128  REAL, INTENT(INOUT) :: XPTS(NPTS),YPTS(NPTS)
129  REAL, OPTIONAL, INTENT( OUT) :: CROT(NPTS),SROT(NPTS)
130  REAL, OPTIONAL, INTENT( OUT) :: XLON(NPTS),XLAT(NPTS)
131  REAL, OPTIONAL, INTENT( OUT) :: YLON(NPTS),YLAT(NPTS),AREA(NPTS)
132  end subroutine gdswzd_interface
133 
142  subroutine init_grib1_interface(self, g1_desc)
143  import
144  class(ip_grid), intent(inout) :: self
145  type(grib1_descriptor), intent(in) :: g1_desc
146  end subroutine init_grib1_interface
147 
156  subroutine init_grib2_interface(self, g2_desc)
157  import
158  class(ip_grid), intent(inout) :: self
159  type(grib2_descriptor), intent(in) :: g2_desc
160  end subroutine init_grib2_interface
161 
162  end interface
163 
166  interface operator (==)
167  module procedure is_same_grid
168  end interface operator (==)
169 
170 
171 contains
172 
182  logical function is_same_grid(grid1, grid2)
183  class(ip_grid), intent(in) :: grid1, grid2
184  is_same_grid = grid1%descriptor == grid2%descriptor
185  end function is_same_grid
186 
197  function field_pos(self, i, j)
198  class(ip_grid), intent(in) :: self
199  integer, intent(in) :: i, j
200  integer :: field_pos
201 
202  integer :: ii, jj, im, jm
203  integer :: iif, jjf, is1, iwrap
204  integer :: jwrap1, jwrap2, kscan, nscan
205 
206  ! extract from navigation parameter array
207  im=self%im
208  jm=self%jm
209  iwrap=self%iwrap
210  jwrap1=self%jwrap1
211  jwrap2=self%jwrap2
212  nscan=self%nscan_field_pos
213  kscan=self%kscan
214 
215  ! compute wraparounds in x and y if necessary and possible
216  ii=i
217  jj=j
218  if(iwrap.gt.0) then
219  ii=mod(i-1+iwrap,iwrap)+1
220  if(j.lt.1.and.jwrap1.gt.0) then
221  jj=jwrap1-j
222  ii=mod(ii-1+iwrap/2,iwrap)+1
223  elseif(j.gt.jm.and.jwrap2.gt.0) then
224  jj=jwrap2-j
225  ii=mod(ii-1+iwrap/2,iwrap)+1
226  endif
227  endif
228 
229  ! compute position for the appropriate scanning mode
230  field_pos=0
231  if(nscan.eq.0) then
232  if(ii.ge.1.and.ii.le.im.and.jj.ge.1.and.jj.le.jm) field_pos=ii+(jj-1)*im
233  elseif(nscan.eq.1) then
234  if(ii.ge.1.and.ii.le.im.and.jj.ge.1.and.jj.le.jm) field_pos=jj+(ii-1)*jm
235  elseif(nscan.eq.2) then
236  is1=(jm+1-kscan)/2
237  iif=jj+(ii-is1)
238  jjf=jj-(ii-is1)+kscan
239  if(iif.ge.1.and.iif.le.2*im-1.and.jjf.ge.1.and.jjf.le.jm) &
240  field_pos=(iif+(jjf-1)*(2*im-1)+1-kscan)/2
241  elseif(nscan.eq.3) then
242  is1=(jm+1-kscan)/2
243  iif=jj+(ii-is1)
244  jjf=jj-(ii-is1)+kscan
245  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
246  endif
247  end function field_pos
248 
249 
250 end module ip_grid_mod
251 
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
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.
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
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_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:52