25 use iso_fortran_env,
only: real64
35 integer,
parameter ::
kd = real64
93 real(kd) :: rlat1, rlon1, rlon0, slat1, clat1, slat0, clat0, clon1
94 real(kd) :: slatr, clatr, clonr, rlatr, rlonr, dlats, dlons, hs, hi
97 integer :: is1, kscan, irot
99 associate(kgds => g1_desc%gds)
100 self%rerth = 6.3712e6_kd
101 self%eccen_squared = 0.0
106 self%nscan_field_pos = 3
107 self%nscan = mod(kgds(11)/32,2)
109 rlat1=kgds(4)*1.e-3_kd
110 rlon1=kgds(5)*1.e-3_kd
111 rlat0=kgds(7)*1.e-3_kd
112 rlon0=kgds(8)*1.e-3_kd
114 irot=mod(kgds(6)/8,2)
115 kscan=mod(kgds(11)/256,2)
116 iscan=mod(kgds(11)/128,2)
122 hs=sign(1._kd,mod(rlon1-rlon0+180+3600,360._kd)-180)
123 clon1=cos((rlon1-rlon0)/
dpr)
124 slatr=clat0*slat1-slat0*clat1*clon1
125 clatr=sqrt(1-slatr**2)
126 clonr=(clat0*clat1*clon1+slat0*slat1)/clatr
127 rlatr=
dpr*asin(slatr)
128 rlonr=hs*
dpr*acos(clonr)
129 dlats=rlatr/(-(jm-1)/2)
130 dlons=rlonr/(-((im * 2 - 1) -1)/2)
165 type(grib2_descriptor),
intent(in) :: g2_desc
167 integer :: iscale, iscan
169 integer :: i_offset_odd
171 associate(igdtmpl => g2_desc%gdt_tmpl, igdtlen => g2_desc%gdt_len)
172 CALL earth_radius(igdtmpl,igdtlen,self%rerth,self%eccen_squared)
189 self%NSCAN=mod(igdtmpl(16)/32,2)
190 self%nscan_field_pos = 3
192 iscale=igdtmpl(10)*igdtmpl(11)
193 IF(iscale==0) iscale=10**6
195 self%RLON0=float(igdtmpl(21))/float(iscale)
196 self%DLATS=float(igdtmpl(18))/float(iscale)
198 self%DLONS=float(igdtmpl(17))/float(iscale) * 0.5_kd
200 self%IROT=mod(igdtmpl(14)/8,2)
202 i_offset_odd=mod(igdtmpl(19)/8,2)
203 self%KSCAN=i_offset_odd
204 iscan=mod(igdtmpl(19)/128,2)
208 rlat0=float(igdtmpl(20))/float(iscale)
211 self%SLAT0=sin(rlat0/dpr)
212 self%CLAT0=cos(rlat0/dpr)
214 self%RLAT1=float(igdtmpl(12))/float(iscale)
215 self%RLON1=float(igdtmpl(13))/float(iscale)
268 FILL,XPTS,YPTS,RLON,RLAT,NRET, &
269 CROT,SROT,XLON,XLAT,YLON,YLAT,AREA)
274 INTEGER,
INTENT(IN ) :: IOPT, NPTS
275 INTEGER,
INTENT( OUT) :: NRET
277 REAL,
INTENT(IN ) :: FILL
278 REAL,
INTENT(INOUT) :: RLON(NPTS),RLAT(NPTS)
279 REAL,
INTENT(INOUT) :: XPTS(NPTS),YPTS(NPTS)
280 REAL,
OPTIONAL,
INTENT( OUT) :: CROT(NPTS),SROT(NPTS)
281 REAL,
OPTIONAL,
INTENT( OUT) :: XLON(NPTS),XLAT(NPTS)
282 REAL,
OPTIONAL,
INTENT( OUT) :: YLON(NPTS),YLAT(NPTS),AREA(NPTS)
284 INTEGER :: IM, JM, IS1, N
288 LOGICAL :: LROT, LMAP, LAREA
290 REAL(KIND=
kd) :: rlat1, rlon1
291 REAL(KIND=
kd) :: clonr
292 REAL(KIND=
kd) :: rlatr, rlonr, sbd, wbd, hs, hi
293 REAL :: XMAX, XMIN, YMAX, YMIN, XPTF, YPTF
295 IF(
PRESENT(crot)) crot=fill
296 IF(
PRESENT(srot)) srot=fill
297 IF(
PRESENT(xlon)) xlon=fill
298 IF(
PRESENT(xlat)) xlat=fill
299 IF(
PRESENT(ylon)) ylon=fill
300 IF(
PRESENT(ylat)) ylat=fill
301 IF(
PRESENT(area)) area=fill
327 IF (wbd > 180.0) wbd = wbd - 360.0
340 IF(
PRESENT(crot).AND.
PRESENT(srot))
THEN
345 IF(
PRESENT(xlon).AND.
PRESENT(xlat).AND.
PRESENT(ylon).AND.
PRESENT(ylat))
THEN
350 IF(
PRESENT(area))
THEN
358 IF(iopt.EQ.0.OR.iopt.EQ.1)
THEN
360 xptf=ypts(n)+(xpts(n)-is1)
361 yptf=ypts(n)-(xpts(n)-is1)+kscan
362 IF(xptf.GE.xmin.AND.xptf.LE.xmax.AND. &
363 yptf.GE.ymin.AND.yptf.LE.ymax)
THEN
364 hs=hi*sign(1.,xptf-(im+1)/2)
365 select type(desc => self%descriptor)
366 type is(grib1_descriptor)
367 rlonr=(xptf-(im+1)/2)*
dlons
368 rlatr=(yptf-(jm+1)/2)*
dlats
369 type is(grib2_descriptor)
370 rlonr=(xptf-1.0_kd)*
dlons + wbd
371 rlatr=(yptf-1.0_kd)*
dlats + sbd
382 ELSEIF(
slat.GE.1)
THEN
391 rlon(n)=real(mod(
rlon0+hs*dpr*acos(
clon)+3600,360._kd))
392 rlat(n)=real(dpr*asin(
slat))
397 xlon(n),xlat(n),ylon(n),ylat(n))
406 ELSEIF(iopt.EQ.-1)
THEN
408 IF(abs(rlon(n)).LE.360.AND.abs(rlat(n)).LE.90)
THEN
409 hs=sign(1._kd,mod(rlon(n)-
rlon0+180+3600,360._kd)-180)
411 slat=sin(rlat(n)/dpr)
412 clat=cos(rlat(n)/dpr)
418 ELSEIF(
slatr.GE.1)
THEN
425 clonr=min(max(clonr,-1._kd),1._kd)
426 rlonr=hs*dpr*acos(clonr)
427 rlatr=dpr*asin(
slatr)
429 select type(desc => self%descriptor)
430 type is(grib1_descriptor)
431 xptf=real(((rlonr-wbd)/
dlons)+1.0_kd)
432 yptf=real(((rlatr-sbd)/
dlats)+1.0_kd)
433 type is(grib2_descriptor)
434 xptf=real((im+1)/2+rlonr/
dlons)
435 yptf=real((jm+1)/2+rlatr/
dlats)
438 IF(xptf.GE.xmin.AND.xptf.LE.xmax.AND. &
439 yptf.GE.ymin.AND.yptf.LE.ymax)
THEN
440 xpts(n)=is1+(xptf-(yptf-kscan))/2
441 ypts(n)=(xptf+(yptf-kscan))/2
445 xlon(n),xlat(n),ylon(n),ylat(n))
485 INTEGER,
INTENT(IN ) :: IOPT, NPTS
487 REAL,
INTENT(IN ) :: FILL
488 REAL,
INTENT( OUT) :: RLAT(NPTS),RLON(NPTS)
489 REAL,
INTENT( OUT) :: XPTS(NPTS),YPTS(NPTS)
517 REAL ,
INTENT(IN ) :: RLON
518 REAL ,
INTENT( OUT) :: CROT, SROT
520 REAL(KIND=
kd) :: slon
527 slon=sin((rlon-
rlon0)/dpr)
550 XLON, XLAT, YLON, YLAT)
553 REAL ,
INTENT(IN ) :: FILL, RLON
554 REAL ,
INTENT( OUT) :: XLON, XLAT, YLON, YLAT
556 REAL(KIND=
kd) :: slon, term1, term2
557 REAL(KIND=
kd) :: xlatf, xlonf, ylatf, ylonf
559 IF(
clatr.LE.0._kd)
THEN
565 slon=sin((rlon-
rlon0)/dpr)
572 xlon=real(xlonf-ylonf)
573 xlat=real(xlatf-ylatf)
574 ylon=real(xlonf+ylonf)
575 ylat=real(xlatf+ylatf)
590 REAL,
INTENT(IN ) :: FILL
591 REAL,
INTENT( OUT) :: AREA
593 IF(
clatr.LE.0._kd)
THEN
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.
Determine earth radius and shape.
Module containing common constants.
real, parameter dpr
Radians to degrees.
Users derived type grid descriptor objects to abstract away the raw GRIB1 and GRIB2 grid definitions.
Rotated equidistant cylindrical GRIB decoder and grid coordinate transformations for Arakawa grid E.
real(kind=kd) dlats
Local copy of dlats.
real(kind=kd) rlon0
Local copy of rlon0.
subroutine rot_equid_cylind_egrid_map_jacob(FILL, RLON, XLON, XLAT, YLON, YLAT)
Computes the map jacobians for a rotated equidistant cylindrical grid.
real(kind=kd) slatr
Sine of the rotated latitude.
subroutine rot_equid_cylind_egrid_grid_area(FILL, AREA)
Computes the grid box area for a rotated equidistant cylindrical grid.
integer, parameter kd
Kind of reals.
real(kind=kd) clon
Cosine of the difference between rlon and rlon0.
subroutine rot_equid_cylind_egrid_error(IOPT, FILL, RLAT, RLON, XPTS, YPTS, NPTS)
Error handler.
real(kind=kd) slat0
Local copy of slat0.
real(kind=kd) clat0
Local copy of clat0.
integer irot
Local copy of irot.
subroutine rot_equid_cylind_egrid_vect_rot(RLON, CROT, SROT)
Computes the vector rotation sines and cosines for a rotated equidistant cylindrical grid.
subroutine gdswzd_rot_equid_cylind_egrid(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 rotated equidistant cylin...
subroutine init_grib1(self, g1_desc)
Initializes a rotated equidistant cylindrical grid given a grib1_descriptor object.
real(kind=kd) clat
Cosine of the latitude.
real(kind=kd) clatr
Cosine of the rotated latitude.
real(kind=kd) slat
Sine of the latitude.
real(kind=kd) rerth
Radius of the Earth.
real(kind=kd) dlons
Local copy of dlons.
subroutine init_grib2(self, g2_desc)
Initializes a rotated equidistant cylindrical grid given a grib2_descriptor object.
Descriptor representing a grib1 grib descriptor section (GDS) with an integer array.
Abstract grid that holds fields and methods common to all grids.