1module ip_lambert_conf_grid_mod
12 real :: rlat1, rlon1, rlati1, rlati2, orient
16 procedure :: init_grib1
17 procedure :: init_grib2
18 procedure :: gdswzd => gdswzd_lambert_conf
24 REAL :: AN, DXS, DYS, H
29 subroutine init_grib1(self, g1_desc)
30 class(ip_lambert_conf_grid),
intent(inout) :: self
31 type(grib1_descriptor),
intent(in) :: g1_desc
33 real :: dx, dy, hi, hj
34 integer :: iproj, iscan, jscan
36 associate(kgds => g1_desc%gds)
38 self%eccen_squared = 0.0
43 self%RLAT1=kgds(4)*1.e-3
44 self%RLON1=kgds(5)*1.e-3
46 self%IROT=mod(kgds(6)/8,2)
47 self%ORIENT=kgds(7)*1.e-3
52 iproj=mod(kgds(10)/128,2)
53 iscan=mod(kgds(11)/128,2)
54 jscan=mod(kgds(11)/64,2)
56 self%RLATI1=kgds(12)*1.e-3
57 self%RLATI2=kgds(13)*1.e-3
68 self%nscan = mod(kgds(11) / 32, 2)
69 self%nscan_field_pos = self%nscan
73 end subroutine init_grib1
75 subroutine init_grib2(self, g2_desc)
76 class(ip_lambert_conf_grid),
intent(inout) :: self
77 type(grib2_descriptor),
intent(in) :: g2_desc
79 real :: dx, dy, hi, hj
80 integer :: iproj, iscan, jscan
83 associate(igdtmpl => g2_desc%gdt_tmpl, igdtlen => g2_desc%gdt_len)
84 call earth_radius(igdtmpl, igdtlen, self%rerth, self%eccen_squared)
89 self%RLAT1=float(igdtmpl(10))*1.0e-6
90 self%RLON1=float(igdtmpl(11))*1.0e-6
92 self%IROT=mod(igdtmpl(12)/8,2)
93 self%ORIENT=float(igdtmpl(14))*1.0e-6
95 dx=float(igdtmpl(15))*1.0e-3
96 dy=float(igdtmpl(16))*1.0e-3
98 iproj=mod(igdtmpl(17)/128,2)
99 iscan=mod(igdtmpl(18)/128,2)
100 jscan=mod(igdtmpl(18)/64,2)
102 self%RLATI1=float(igdtmpl(19))*1.0e-6
103 self%RLATI2=float(igdtmpl(20))*1.0e-6
111 self%nscan = mod(igdtmpl(18) / 32, 2)
112 self%nscan_field_pos = self%nscan
118 end subroutine init_grib2
120 SUBROUTINE gdswzd_lambert_conf(self,IOPT,NPTS,FILL, &
121 XPTS,YPTS,RLON,RLAT,NRET, &
122 CROT,SROT,XLON,XLAT,YLON,YLAT,AREA)
248 class(ip_lambert_conf_grid),
intent(in) :: self
249 INTEGER,
INTENT(IN ) :: IOPT, NPTS
250 INTEGER,
INTENT( OUT) :: NRET
252 REAL,
INTENT(IN ) :: FILL
253 REAL,
INTENT(INOUT) :: RLON(NPTS),RLAT(NPTS)
254 REAL,
INTENT(INOUT) :: XPTS(NPTS),YPTS(NPTS)
255 REAL,
OPTIONAL,
INTENT( OUT) :: CROT(NPTS),SROT(NPTS)
256 REAL,
OPTIONAL,
INTENT( OUT) :: XLON(NPTS),XLAT(NPTS)
257 REAL,
OPTIONAL,
INTENT( OUT) :: YLON(NPTS),YLAT(NPTS),AREA(NPTS)
261 LOGICAL :: LROT, LMAP, LAREA
266 REAL :: ORIENT, RLAT1, RLON1
267 REAL :: RLATI1, RLATI2
268 REAL :: XMAX, XMIN, YMAX, YMIN, XP, YP
271 IF(
PRESENT(crot)) crot=fill
272 IF(
PRESENT(srot)) srot=fill
273 IF(
PRESENT(xlon)) xlon=fill
274 IF(
PRESENT(xlat)) xlat=fill
275 IF(
PRESENT(ylon)) ylon=fill
276 IF(
PRESENT(ylat)) ylat=fill
277 IF(
PRESENT(area)) area=fill
297 IF(rlati1.EQ.rlati2)
THEN
300 an=log(cos(rlati1/dpr)/cos(rlati2/dpr))/ &
301 log(tan((90-rlati1)/2/dpr)/tan((90-rlati2)/2/dpr))
303 de=rerth*cos(rlati1/dpr)*tan((rlati1+90)/2/dpr)**an/an
304 IF(h*rlat1.EQ.90)
THEN
308 dr=de/tan((rlat1+90)/2/dpr)**an
309 dlon1=mod(rlon1-orient+180+3600,360.)-180
310 xp=1-sin(an*dlon1/dpr)*dr/dxs
311 yp=1+cos(an*dlon1/dpr)*dr/dys
320 IF(
PRESENT(crot).AND.
PRESENT(srot))
THEN
325 IF(
PRESENT(xlon).AND.
PRESENT(xlat).AND.
PRESENT(ylon).AND.
PRESENT(ylat))
THEN
330 IF(
PRESENT(area))
THEN
337 IF(iopt.EQ.0.OR.iopt.EQ.1)
THEN
340 IF(xpts(n).GE.xmin.AND.xpts(n).LE.xmax.AND. &
341 ypts(n).GE.ymin.AND.ypts(n).LE.ymax)
THEN
342 di=h*(xpts(n)-xp)*dxs
343 dj=h*(ypts(n)-yp)*dys
346 IF(dr2.LT.de2*1.e-6)
THEN
350 rlon(n)=mod(orient+1./an*dpr*atan2(di,-dj)+3600,360.)
351 rlat(n)=(2*dpr*atan((de2/dr2)**antr)-90)
354 dlon=mod(rlon(n)-orient+180+3600,360.)-180
355 IF(lrot)
CALL lambert_conf_vect_rot(dlon,crot(n),srot(n))
356 IF(lmap)
CALL lambert_conf_map_jacob(rlat(n),fill, dlon, dr, &
357 xlon(n),xlat(n),ylon(n),ylat(n))
358 IF(larea)
CALL lambert_conf_grid_area(rlat(n),fill,dr,area(n))
366 ELSEIF(iopt.EQ.-1)
THEN
369 IF(abs(rlon(n)).LE.360.AND.abs(rlat(n)).LE.90.AND. &
370 h*rlat(n).NE.-90)
THEN
371 dr=h*de*tan((90-rlat(n))/2/dpr)**an
372 dlon=mod(rlon(n)-orient+180+3600,360.)-180
373 xpts(n)=xp+h*sin(an*dlon/dpr)*dr/dxs
374 ypts(n)=yp-h*cos(an*dlon/dpr)*dr/dys
375 IF(xpts(n).GE.xmin.AND.xpts(n).LE.xmax.AND. &
376 ypts(n).GE.ymin.AND.ypts(n).LE.ymax)
THEN
378 IF(lrot)
CALL lambert_conf_vect_rot(dlon,crot(n),srot(n))
379 IF(lmap)
CALL lambert_conf_map_jacob(rlat(n),fill,dlon,dr, &
380 xlon(n),xlat(n),ylon(n),ylat(n))
381 IF(larea)
CALL lambert_conf_grid_area(rlat(n),fill,dr,area(n))
394 END SUBROUTINE gdswzd_lambert_conf
396 SUBROUTINE lambert_conf_error(IOPT,FILL,RLAT,RLON,XPTS,YPTS,NPTS)
429 INTEGER,
INTENT(IN ) :: IOPT, NPTS
431 REAL,
INTENT(IN ) :: FILL
432 REAL,
INTENT( OUT) :: RLAT(NPTS),RLON(NPTS)
433 REAL,
INTENT( OUT) :: XPTS(NPTS),YPTS(NPTS)
444 END SUBROUTINE lambert_conf_error
446 SUBROUTINE lambert_conf_vect_rot(DLON,CROT,SROT)
478 REAL,
INTENT( IN) :: DLON
479 REAL,
INTENT( OUT) :: CROT, SROT
482 crot=cos(an*dlon/dpr)
483 srot=sin(an*dlon/dpr)
489 END SUBROUTINE lambert_conf_vect_rot
491 SUBROUTINE lambert_conf_map_jacob(RLAT,FILL,DLON,DR,XLON,XLAT,YLON,YLAT)
528 REAL,
INTENT(IN ) :: RLAT, FILL, DLON, DR
529 REAL,
INTENT( OUT) :: XLON, XLAT, YLON, YLAT
534 IF(clat.LE.0.OR.dr.LE.0)
THEN
540 xlon=h*cos(an*dlon/dpr)*an/dpr*dr/dxs
541 xlat=-h*sin(an*dlon/dpr)*an/dpr*dr/dxs/clat
542 ylon=h*sin(an*dlon/dpr)*an/dpr*dr/dys
543 ylat=h*cos(an*dlon/dpr)*an/dpr*dr/dys/clat
546 END SUBROUTINE lambert_conf_map_jacob
548 SUBROUTINE lambert_conf_grid_area(RLAT,FILL,DR,AREA)
581 REAL,
INTENT(IN ) :: RLAT
582 REAL,
INTENT(IN ) :: FILL
583 REAL,
INTENT(IN ) :: DR
584 REAL,
INTENT( OUT) :: AREA
589 IF(clat.LE.0.OR.dr.LE.0)
THEN
592 area=rerth**2*clat**2*abs(dxs)*abs(dys)/(an*dr)**2
595 END SUBROUTINE lambert_conf_grid_area
597end module ip_lambert_conf_grid_mod
Module containing common constants.
Uses derived type grid descriptor objects to abstract away the raw Grib-1 and Grib-2 grid definitions...
Abstract grid that holds fields and methods common to all grids.