22 real :: dlon, rlat1, rlon1, rlon2, hi
25 procedure :: init_grib1
26 procedure :: init_grib2
31 REAL,
ALLOCATABLE :: BLAT(:)
33 REAL,
ALLOCATABLE :: YLAT_ROW(:)
50 associate(kgds => g1_desc%gds)
52 self%eccen_squared = 0.0
56 self%RLAT1=kgds(4)*1.e-3
57 self%RLON1=kgds(5)*1.e-3
58 self%RLON2=kgds(8)*1.e-3
60 iscan=mod(kgds(11)/128,2)
61 self%JSCAN=mod(kgds(11)/64,2)
63 self%JH=(-1)**self%JSCAN
64 self%DLON=self%HI*(mod(self%HI*(self%RLON2-self%RLON1)-1+3600,360.)+1)/(self%IM-1)
69 self%nscan = mod(kgds(11) / 32, 2)
70 self%nscan_field_pos = self%nscan
73 self%iwrap=nint(360 / abs(self%dlon))
74 if(self%im < self%iwrap) self%iwrap = 0
76 if(self%iwrap > 0 .and. mod(self%iwrap, 2) == 0)
then
78 if(self%jm == self%jg)
then
80 self%jwrap2 = 2 * self%jm + 1
95 type(grib2_descriptor),
intent(in) :: g2_desc
97 integer :: iscale, iscan, jg
99 associate(igdtmpl => g2_desc%gdt_tmpl, igdtlen => g2_desc%gdt_len)
100 call earth_radius(igdtmpl, igdtlen, self%rerth, self%eccen_squared)
104 iscale=igdtmpl(10)*igdtmpl(11)
105 IF(iscale==0) iscale=10**6
106 self%RLAT1=float(igdtmpl(12))/float(iscale)
107 self%RLON1=float(igdtmpl(13))/float(iscale)
108 self%RLON2=float(igdtmpl(16))/float(iscale)
109 self%JG=igdtmpl(18)*2
110 iscan=mod(igdtmpl(19)/128,2)
111 self%JSCAN=mod(igdtmpl(19)/64,2)
113 self%JH=(-1)**self%JSCAN
114 self%DLON=self%HI*(mod(self%HI*(self%RLON2-self%RLON1)-1+3600,360.)+1)/(self%IM-1)
117 self%iwrap = nint(360 / abs(self%dlon))
118 if(self%im < self%iwrap) self%iwrap = 0
121 if(self%iwrap > 0 .and. mod(self%iwrap, 2) == 0)
then
123 if(self%jm == jg)
then
125 self%jwrap2 = 2 * self%jm + 1
128 self%nscan = mod(igdtmpl(19) / 32, 2)
129 self%nscan_field_pos = self%nscan
180 XPTS,YPTS,RLON,RLAT,NRET, &
181 CROT,SROT,XLON,XLAT,YLON,YLAT,AREA)
185 INTEGER,
INTENT(IN ) :: IOPT, NPTS
186 INTEGER,
INTENT( OUT) :: NRET
188 REAL,
INTENT(IN ) :: FILL
189 REAL,
INTENT(INOUT) :: RLON(NPTS),RLAT(NPTS)
190 REAL,
INTENT(INOUT) :: XPTS(NPTS),YPTS(NPTS)
191 REAL,
OPTIONAL,
INTENT( OUT) :: CROT(NPTS),SROT(NPTS)
192 REAL,
OPTIONAL,
INTENT( OUT) :: XLON(NPTS),XLAT(NPTS)
193 REAL,
OPTIONAL,
INTENT( OUT) :: YLON(NPTS),YLAT(NPTS),AREA(NPTS)
195 INTEGER :: JSCAN, IM, JM
199 LOGICAL :: LROT, LMAP, LAREA
201 REAL,
ALLOCATABLE :: ALAT(:), ALAT_JSCAN(:)
202 REAL,
ALLOCATABLE :: ALAT_TEMP(:),BLAT_TEMP(:)
203 REAL :: HI, RLATA, RLATB, RLAT1, RLON1, RLON2
204 REAL :: XMAX, XMIN, YMAX, YMIN, YPTSA, YPTSB
207 IF(
PRESENT(crot)) crot=fill
208 IF(
PRESENT(srot)) srot=fill
209 IF(
PRESENT(xlon)) xlon=fill
210 IF(
PRESENT(xlat)) xlat=fill
211 IF(
PRESENT(ylon)) ylon=fill
212 IF(
PRESENT(ylat)) ylat=fill
213 IF(
PRESENT(area)) area=fill
216 IF(
PRESENT(crot).AND.
PRESENT(srot))
THEN
221 IF(
PRESENT(xlon).AND.
PRESENT(xlat).AND.
PRESENT(ylon).AND.
PRESENT(ylat))
THEN
226 IF(
PRESENT(area))
THEN
247 ALLOCATE(alat_temp(jg))
248 ALLOCATE(blat_temp(jg))
249 CALL splat(4,jg,alat_temp,blat_temp)
250 ALLOCATE(alat(0:jg+1))
251 ALLOCATE(blat(0:jg+1))
254 alat(ja)=dpr*asin(alat_temp(ja))
255 blat(ja)=blat_temp(ja)
258 DEALLOCATE(alat_temp,blat_temp)
264 DO WHILE(j1.LT.jg.AND.rlat1.LT.(alat(j1)+alat(j1+1))/2)
268 ALLOCATE(alat_jscan(jg))
270 alat_jscan(j1+jh*(ja-1))=alat(ja)
272 ALLOCATE(ylat_row(0:jg+1))
274 ylat_row(ja)=2.0/(alat_jscan(ja+1)-alat_jscan(ja-1))
276 ylat_row(1)=1.0/(alat_jscan(2)-alat_jscan(1))
277 ylat_row(0)=ylat_row(1)
278 ylat_row(jg)=1.0/(alat_jscan(jg)-alat_jscan(jg-1))
279 ylat_row(jg+1)=ylat_row(jg)
280 DEALLOCATE(alat_jscan)
284 IF(im.EQ.nint(360/abs(dlon))) xmax=im+2
290 IF(iopt.EQ.0.OR.iopt.EQ.1)
THEN
293 IF(xpts(n).GE.xmin.AND.xpts(n).LE.xmax.AND. &
294 ypts(n).GE.ymin.AND.ypts(n).LE.ymax)
THEN
295 rlon(n)=mod(rlon1+dlon*(xpts(n)-1)+3600,360.)
298 rlata=alat(j1+jh*(j-1))
300 rlat(n)=rlata+wb*(rlatb-rlata)
304 xlon(n),xlat(n),ylon(n),ylat(n))
314 ELSEIF(iopt.EQ.-1)
THEN
319 IF(abs(rlon(n)).LE.360.AND.abs(rlat(n)).LE.90)
THEN
320 xpts(n)=1+hi*mod(hi*(rlon(n)-rlon1)+3600,360.)/dlon
321 ja=min(int((jg+1)/180.*(90-rlat(n))),jg)
322 IF(rlat(n).GT.alat(ja)) ja=max(ja-2,0)
323 IF(rlat(n).LT.alat(ja+1)) ja=min(ja+2,jg)
324 IF(rlat(n).GT.alat(ja)) ja=ja-1
325 IF(rlat(n).LT.alat(ja+1)) ja=ja+1
328 wb=(alat(ja)-rlat(n))/(alat(ja)-alat(ja+1))
329 ypts(n)=yptsa+wb*(yptsb-yptsa)
330 IF(xpts(n).GE.xmin.AND.xpts(n).LE.xmax.AND. &
331 ypts(n).GE.ymin.AND.ypts(n).LE.ymax)
THEN
335 xlon(n),xlat(n),ylon(n),ylat(n))
345 DEALLOCATE(alat, blat)
346 IF (
ALLOCATED(ylat_row))
DEALLOCATE(ylat_row)
351 SUBROUTINE gaussian_error(IOPT,FILL,RLAT,RLON,XPTS,YPTS,NPTS)
384 INTEGER,
INTENT(IN ) :: IOPT, NPTS
386 REAL,
INTENT(IN ) :: FILL
387 REAL,
INTENT( OUT) :: RLAT(NPTS),RLON(NPTS)
388 REAL,
INTENT( OUT) :: XPTS(NPTS),YPTS(NPTS)
399 END SUBROUTINE gaussian_error
416 REAL,
INTENT( OUT) :: CROT, SROT
437 REAL,
INTENT(IN ) :: YPTS
438 REAL,
INTENT( OUT) :: XLON, XLAT, YLON, YLAT
443 ylat=ylat_row(nint(ypts))
457 REAL,
INTENT(IN ) :: YPTS
458 REAL,
INTENT( OUT) :: AREA
462 REAL :: WB, WLAT, WLATA, WLATB
466 wlata=blat(j1+jh*(j-1))
468 wlat=wlata+wb*(wlatb-wlata)
469 area=rerth**2*wlat*dlon/dpr
Module containing common constants.
Gaussian grid coordinate transformations.
subroutine gdswzd_gaussian(self, IOPT, NPTS, FILL, XPTS, YPTS, RLON, RLAT, NRET, CROT, SROT, XLON, XLAT, YLON, YLAT, AREA)
Calculates Earth coordinates (iopt = 1) or grid coorindates (iopt = -1) for Gaussian grids.
subroutine init_grib1(self, g1_desc)
Initializes a gaussian grid given a grib1_descriptor object.
subroutine gaussian_grid_area(YPTS, AREA)
Computes the grid box area for a gaussian cylindrical grid.
subroutine gaussian_vect_rot(CROT, SROT)
Computes the vector rotation sines and cosines for a gaussian cylindrical grid.
subroutine gaussian_map_jacob(YPTS, XLON, XLAT, YLON, YLAT)
Computes the map jacobians for a gaussian cylindrical grid.
subroutine init_grib2(self, g2_desc)
Initializes a gaussian grid given a grib2_descriptor object.
Uses derived type grid descriptor objects to abstract away the raw Grib-1 and Grib-2 grid definitions...
Descriptor representing a grib1 grib descriptor section (GDS) with an integer array.
Abstract grid that holds fields and methods common to all grids.