NCEPLIBS-ip 4.0.0
ip_grid_mod.f90
Go to the documentation of this file.
1
6
10 implicit none
11
12 integer, public, parameter :: equid_cylind_grid_id_grib1 = 0
13 integer, public, parameter :: mercator_grid_id_grib1 = 1
14 integer, public, parameter :: lambert_conf_grid_id_grib1 = 3
15 integer, public, parameter :: gaussian_grid_id_grib1 = 4
16 integer, public, parameter :: polar_stereo_grid_id_grib1 = 5
17 integer, public, parameter :: rot_equid_cylind_e_grid_id_grib1 = 203
18 integer, public, parameter :: rot_equid_cylind_b_grid_id_grib1 = 205
19
20 integer, public, parameter :: equid_cylind_grid_id_grib2 = 0
21 integer, public, parameter :: rot_equid_cylind_grid_id_grib2 = 1
22 integer, public, parameter :: mercator_grid_id_grib2 = 10
23 integer, public, parameter :: polar_stereo_grid_id_grib2 = 20
24 integer, public, parameter :: lambert_conf_grid_id_grib2 = 30
25 integer, public, parameter :: gaussian_grid_id_grib2 = 40
26
27 private
28 public :: ip_grid, gdswzd_interface, operator(==)
29
45 type, abstract :: ip_grid
46 class(ip_grid_descriptor), allocatable :: descriptor
47
48 integer :: im
49 integer :: jm
50 integer :: nm
51
56 integer :: nscan
57 integer :: kscan
58
59 integer :: nscan_field_pos
60
61 integer :: iwrap
62 integer :: jwrap1
63 integer :: jwrap2
64 real :: rerth
65 real :: eccen_squared
66 contains
68 procedure(init_grib1_interface), deferred :: init_grib1
70 procedure(init_grib2_interface), deferred :: init_grib2
72 procedure(gdswzd_interface), deferred :: gdswzd
74 procedure :: field_pos
75 generic :: init => init_grib1, init_grib2
76 end type ip_grid
77
78 abstract interface
79 subroutine gdswzd_interface(self, iopt, npts, fill, xpts, ypts, rlon, rlat, nret, crot, srot, &
80 xlon, xlat, ylon, ylat, area)
81 import
82 class(ip_grid), intent(in) :: self
83 INTEGER, INTENT(IN ) :: IOPT, NPTS
84 INTEGER, INTENT( OUT) :: NRET
85 !
86 REAL, INTENT(IN ) :: FILL
87 REAL, INTENT(INOUT) :: RLON(NPTS),RLAT(NPTS)
88 REAL, INTENT(INOUT) :: XPTS(NPTS),YPTS(NPTS)
89 REAL, OPTIONAL, INTENT( OUT) :: CROT(NPTS),SROT(NPTS)
90 REAL, OPTIONAL, INTENT( OUT) :: XLON(NPTS),XLAT(NPTS)
91 REAL, OPTIONAL, INTENT( OUT) :: YLON(NPTS),YLAT(NPTS),AREA(NPTS)
92 end subroutine gdswzd_interface
93
94 subroutine init_grib1_interface(self, g1_desc)
95 import
96 class(ip_grid), intent(inout) :: self
97 type(grib1_descriptor), intent(in) :: g1_desc
98 end subroutine init_grib1_interface
99
100 subroutine init_grib2_interface(self, g2_desc)
101 import
102 class(ip_grid), intent(inout) :: self
103 type(grib2_descriptor), intent(in) :: g2_desc
104 end subroutine init_grib2_interface
105
106 end interface
107
108 interface operator (==)
109 module procedure is_same_grid
110 end interface operator (==)
111
112
113contains
114
124 logical function is_same_grid(grid1, grid2)
125 class(ip_grid), intent(in) :: grid1, grid2
126 is_same_grid = grid1%descriptor == grid2%descriptor
127 end function is_same_grid
128
139 function field_pos(self, i, j)
140 class(ip_grid), intent(in) :: self
141 integer, intent(in) :: i, j
142 integer :: field_pos
143
144 integer :: ii, jj, im, jm
145 integer :: iif, jjf, is1, iwrap
146 integer :: jwrap1, jwrap2, kscan, nscan
147
148 ! extract from navigation parameter array
149 im=self%im
150 jm=self%jm
151 iwrap=self%iwrap
152 jwrap1=self%jwrap1
153 jwrap2=self%jwrap2
154 nscan=self%nscan_field_pos
155 kscan=self%kscan
156
157 ! compute wraparounds in x and y if necessary and possible
158 ii=i
159 jj=j
160 if(iwrap.gt.0) then
161 ii=mod(i-1+iwrap,iwrap)+1
162 if(j.lt.1.and.jwrap1.gt.0) then
163 jj=jwrap1-j
164 ii=mod(ii-1+iwrap/2,iwrap)+1
165 elseif(j.gt.jm.and.jwrap2.gt.0) then
166 jj=jwrap2-j
167 ii=mod(ii-1+iwrap/2,iwrap)+1
168 endif
169 endif
170
171 ! compute position for the appropriate scanning mode
172 field_pos=0
173 if(nscan.eq.0) then
174 if(ii.ge.1.and.ii.le.im.and.jj.ge.1.and.jj.le.jm) field_pos=ii+(jj-1)*im
175 elseif(nscan.eq.1) then
176 if(ii.ge.1.and.ii.le.im.and.jj.ge.1.and.jj.le.jm) field_pos=jj+(ii-1)*jm
177 elseif(nscan.eq.2) then
178 is1=(jm+1-kscan)/2
179 iif=jj+(ii-is1)
180 jjf=jj-(ii-is1)+kscan
181 if(iif.ge.1.and.iif.le.2*im-1.and.jjf.ge.1.and.jjf.le.jm) &
182 field_pos=(iif+(jjf-1)*(2*im-1)+1-kscan)/2
183 elseif(nscan.eq.3) then
184 is1=(jm+1-kscan)/2
185 iif=jj+(ii-is1)
186 jjf=jj-(ii-is1)+kscan
187 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
188 endif
189 end function field_pos
190
191
192end module ip_grid_mod
193
Uses derived type grid descriptor objects to abstract away the raw Grib-1 and Grib-2 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:8
integer, parameter, public lambert_conf_grid_id_grib2
Integer grid number for Lambert conformal grid in grib2.
Definition: ip_grid_mod.f90:24
integer, parameter, public gaussian_grid_id_grib2
Integer grid number for Gaussian grid in grib2.
Definition: ip_grid_mod.f90:25
integer, parameter, public equid_cylind_grid_id_grib2
Integer grid number for equidistant cylindrical grid in grib2.
Definition: ip_grid_mod.f90:20
integer, parameter, public gaussian_grid_id_grib1
Integer grid number for Gaussian grid in grib1.
Definition: ip_grid_mod.f90:15
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:17
integer, parameter, public polar_stereo_grid_id_grib2
Integer grid number for polar stereo grid in grib2.
Definition: ip_grid_mod.f90:23
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:14
integer, parameter, public mercator_grid_id_grib1
Integer grid number for Mercator grid in grib1.
Definition: ip_grid_mod.f90:13
integer, parameter, public equid_cylind_grid_id_grib1
Integer grid number for equidistant cylindrical grid in grib1.
Definition: ip_grid_mod.f90:12
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:18
integer, parameter, public rot_equid_cylind_grid_id_grib2
Integer grid number for rotated equidistant cylindrical grid in grib2.
Definition: ip_grid_mod.f90:21
integer, parameter, public mercator_grid_id_grib2
Integer grid number for Mercator grid in grib2.
Definition: ip_grid_mod.f90:22
integer, parameter, public polar_stereo_grid_id_grib1
Integer grid number for polar stereo grid in grib1.
Definition: ip_grid_mod.f90:16
Abstract grid that holds fields and methods common to all grids.
Definition: ip_grid_mod.f90:45