27 REAL :: TINYREAL=tiny(1.0)
96 NO,RLAT,RLON,IBO,LO,GO,IRET)
97 class(ip_grid),
intent(in) :: grid_in, grid_out
98 INTEGER,
INTENT(IN ) :: IBI(KM), IPOPT(20)
99 INTEGER,
INTENT(IN ) :: KM, MI, MO
100 INTEGER,
INTENT( OUT) :: IBO(KM), IRET, NO
102 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
103 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
105 REAL,
INTENT(IN ) :: GI(MI,KM)
106 REAL,
INTENT(INOUT) :: RLAT(MO), RLON(MO)
107 REAL,
INTENT( OUT) :: GO(MO,KM)
109 REAL,
PARAMETER :: FILL=-9999.
111 INTEGER :: I1, J1, I2, J2, IB, JB
112 INTEGER :: IX, JX, IXS, JXS
113 INTEGER :: K, KXS, KXT
114 INTEGER :: LB, LSW, MP, MSPIRAL, MX
115 INTEGER :: N, NB, NB1, NB2, NB3, NB4, NV, NX
116 INTEGER :: N11(MO),N21(MO),N12(MO),N22(MO)
118 REAL :: GB, LAT(1), LON(1)
119 REAL :: PMP, RB2, RLOB(MO), RLAB(MO), WB
120 REAL :: W11(MO), W21(MO), W12(MO), W22(MO)
121 REAL :: WO(MO,KM), XF, YF, XI, YI, XX, YY
122 REAL :: XPTS(MO),YPTS(MO),XPTB(MO),YPTB(MO)
123 REAL :: XXX(1), YYY(1)
125 logical :: to_station_points
127 class(ip_grid),
allocatable :: grid_out2
134 select type(grid_out)
135 type is(ip_station_points_grid)
136 to_station_points = .true.
137 allocate(grid_out2, source = grid_out)
138 CALL gdswzd(grid_out2, 0,mo,fill,xpts,ypts,rlon,rlat,no)
140 CALL gdswzd(grid_in,-1,no,fill,xpts,ypts,rlon,rlat,nv)
143 to_station_points = .false.
144 allocate(grid_out2, source = grid_out)
145 CALL gdswzd(grid_out2, 0,mo,fill,xpts,ypts,rlon,rlat,no)
151 IF(ipopt(1).GT.16) iret=32
152 mspiral=max(ipopt(20),1)
155 IF(iret.EQ.0.AND.nb1.LT.0) iret=32
157 IF(ipopt(2).EQ.-2) lsw=2
158 IF(ipopt(1).EQ.-1.OR.ipopt(2).EQ.-1) lsw=0
159 IF(iret.EQ.0.AND.lsw.EQ.1.AND.nb1.GT.15) iret=32
161 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
162 IF(mp.LT.0.OR.mp.GT.100) iret=32
172 ELSEIF(lsw.EQ.1)
THEN
175 nb4=nb4+8*ib*ipopt(2+ib)
193 ib=nb-(jb+nb1)*nb2-nb1-1
194 lb=max(abs(ib),abs(jb))
197 wb=(nb1+1-abs(ib))*(nb1+1-abs(jb))
198 ELSEIF(lsw.EQ.1)
THEN
201 IF(abs(wb).GT.tinyreal)
THEN
204 xptb(n)=xpts(n)+ib*rb2
205 yptb(n)=ypts(n)+jb*rb2
208 if(to_station_points)
then
209 CALL gdswzd(grid_in, 1,no,fill,xptb,yptb,rlob,rlab,nv)
210 CALL gdswzd(grid_in,-1,no,fill,xptb,yptb,rlob,rlab,nv)
212 CALL gdswzd(grid_out2, 1,no,fill,xptb,yptb,rlob,rlab,nv)
213 CALL gdswzd(grid_in,-1,no,fill,xptb,yptb,rlob,rlab,nv)
215 IF(iret.EQ.0.AND.nv.EQ.0.AND.lb.EQ.0) iret=2
220 IF(abs(xi-fill).GT.tinyreal.AND.abs(yi-fill).GT.tinyreal)
THEN
227 n11(n)=grid_in%field_pos(i1, j1)
228 n21(n)=grid_in%field_pos(i2, j1)
229 n12(n)=grid_in%field_pos(i1, j2)
230 n22(n)=grid_in%field_pos(i2, j2)
231 IF(min(n11(n),n21(n),n12(n),n22(n)).GT.0)
THEN
257 gb=w11(n)*gi(n11(n),k)+w21(n)*gi(n21(n),k) &
258 +w12(n)*gi(n12(n),k)+w22(n)*gi(n22(n),k)
259 go(n,k)=go(n,k)+wb*gb
262 IF(li(n11(n),k))
THEN
263 go(n,k)=go(n,k)+wb*w11(n)*gi(n11(n),k)
264 wo(n,k)=wo(n,k)+wb*w11(n)
266 IF(li(n21(n),k))
THEN
267 go(n,k)=go(n,k)+wb*w21(n)*gi(n21(n),k)
268 wo(n,k)=wo(n,k)+wb*w21(n)
270 IF(li(n12(n),k))
THEN
271 go(n,k)=go(n,k)+wb*w12(n)*gi(n12(n),k)
272 wo(n,k)=wo(n,k)+wb*w12(n)
274 IF(li(n22(n),k))
THEN
275 go(n,k)=go(n,k)+wb*w22(n)*gi(n22(n),k)
276 wo(n,k)=wo(n,k)+wb*w22(n)
292 lo(n,k)=wo(n,k).GE.pmp*nb4
294 go(n,k)=go(n,k)/wo(n,k)
295 ELSEIF (mspiral.GT.1)
THEN
298 CALL gdswzd(grid_in,-1,1,fill,xxx,yyy,lon,lat,nv)
304 ixs=int(sign(1.,xx-i1))
305 jxs=int(sign(1.,yy-j1))
306 spiral_loop :
DO mx=2,mspiral**2
307 kxs=int(sqrt(4*mx-2.5))
309 SELECT CASE(mod(kxs,4))
311 ix=i1-ixs*(kxs/4-kxt)
315 jx=j1-jxs*(kxs/4-kxt)
317 ix=i1+ixs*(1+kxs/4-kxt)
321 jx=j1+jxs*(kxs/4-kxt)
323 nx=grid_in%field_pos(ix, jx)
325 IF(li(nx,k).OR.ibi(k).EQ.0)
THEN
346 select type(grid_out2)
347 type is(ip_equid_cylind_grid)
348 CALL polfixs(no,mo,km,rlat,ibo,lo,go)
424 MI,MO,KM,IBI,LI,UI,VI, &
425 NO,RLAT,RLON,CROT,SROT,IBO,LO,UO,VO,IRET)
426 class(ip_grid),
intent(in) :: grid_in, grid_out
427 INTEGER,
INTENT(IN ) :: IPOPT(20), IBI(KM)
428 INTEGER,
INTENT(IN ) :: KM, MI, MO
429 INTEGER,
INTENT( OUT) :: IRET, NO, IBO(KM)
431 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
432 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
434 REAL,
INTENT(IN ) :: UI(MI,KM),VI(MI,KM)
435 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
436 REAL,
INTENT( OUT) :: UO(MO,KM),VO(MO,KM)
437 REAL,
INTENT( OUT) :: CROT(MO),SROT(MO)
439 REAL,
PARAMETER :: FILL=-9999.
441 INTEGER :: I1,I2,J1,J2,IB,JB,LSW,MP
442 INTEGER :: K,LB,N,NB,NB1,NB2,NB3,NB4,NV
443 INTEGER :: N11(MO),N21(MO),N12(MO),N22(MO)
447 REAL :: CM11,SM11,CM12,SM12
448 REAL :: CM21,SM21,CM22,SM22
450 REAL :: C11(MO),C21(MO),C12(MO),C22(MO)
451 REAL :: S11(MO),S21(MO),S12(MO),S22(MO)
452 REAL :: W11(MO),W21(MO),W12(MO),W22(MO)
453 REAL :: UB,VB,WB,UROT,VROT
454 REAL :: U11,V11,U21,V21,U12,V12,U22,V22
455 REAL :: WI1,WJ1,WI2,WJ2
456 REAL :: WO(MO,KM),XI,YI
457 REAL :: XPTS(MO),YPTS(MO)
458 REAL :: XPTB(MO),YPTB(MO),RLOB(MO),RLAB(MO)
460 logical :: to_station_points
462 class(ip_grid),
allocatable :: grid_out2
465 INTEGER,
SAVE :: MIX=-1
466 REAL,
ALLOCATABLE,
SAVE :: CROI(:),SROI(:)
467 REAL,
ALLOCATABLE,
SAVE :: XPTI(:),YPTI(:),RLOI(:),RLAI(:)
469 class(ip_grid),
allocatable,
save :: prev_grid_in
475 select type(grid_out)
476 type is(ip_station_points_grid)
477 to_station_points = .true.
478 allocate(grid_out2, source = grid_out)
479 CALL gdswzd(grid_out2, 0,mo,fill,xpts,ypts,rlon,rlat,no,crot,srot)
481 CALL gdswzd(grid_in,-1,no,fill,xpts,ypts,rlon,rlat,nv,crot,srot)
484 to_station_points = .false.
485 allocate(grid_out2, source = grid_out)
486 CALL gdswzd(grid_out2, 0,mo,fill,xpts,ypts,rlon,rlat,no,crot,srot)
489 if (.not.
allocated(prev_grid_in))
then
490 allocate(prev_grid_in, source = grid_in)
494 same_grid = grid_in == prev_grid_in
496 if (.not. same_grid)
then
497 deallocate(prev_grid_in)
498 allocate(prev_grid_in, source = grid_in)
502 IF(.NOT.same_grid)
THEN
504 IF(mix.GE.0)
DEALLOCATE(xpti,ypti,rloi,rlai,croi,sroi)
505 ALLOCATE(xpti(mi),ypti(mi),rloi(mi),rlai(mi),croi(mi),sroi(mi))
508 CALL gdswzd(grid_in, 0,mi,fill,xpti,ypti,rloi,rlai,nv,croi,sroi)
515 IF(iret.EQ.0.AND.nb1.LT.0) iret=32
517 IF(ipopt(2).EQ.-2) lsw=2
518 IF(ipopt(1).EQ.-1.OR.ipopt(2).EQ.-1) lsw=0
519 IF(iret.EQ.0.AND.lsw.EQ.1.AND.nb1.GT.15) iret=32
521 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
522 IF(mp.LT.0.OR.mp.GT.100) iret=32
532 ELSEIF(lsw.EQ.1)
THEN
535 nb4=nb4+8*ib*ipopt(2+ib)
554 ib=nb-(jb+nb1)*nb2-nb1-1
555 lb=max(abs(ib),abs(jb))
557 IF(ipopt(2).EQ.-2)
THEN
558 wb=(nb1+1-abs(ib))*(nb1+1-abs(jb))
559 ELSEIF(ipopt(2).NE.-1)
THEN
562 IF(abs(wb).GT.tinyreal)
THEN
565 xptb(n)=xpts(n)+ib*rb2
566 yptb(n)=ypts(n)+jb*rb2
569 if(to_station_points)
then
570 CALL gdswzd(grid_in, 1,no,fill,xptb,yptb,rlob,rlab,nv)
571 CALL gdswzd(grid_in,-1,no,fill,xptb,yptb,rlob,rlab,nv)
573 CALL gdswzd(grid_out2, 1,no,fill,xptb,yptb,rlob,rlab,nv)
574 CALL gdswzd(grid_in,-1,no,fill,xptb,yptb,rlob,rlab,nv)
576 IF(iret.EQ.0.AND.nv.EQ.0.AND.lb.EQ.0) iret=2
582 IF(abs(xi-fill).GT.tinyreal.AND.abs(yi-fill).GT.tinyreal)
THEN
591 n11(n) = grid_in%field_pos(i1,j1)
592 n21(n) = grid_in%field_pos(i2, j1)
593 n12(n) = grid_in%field_pos(i1, j2)
594 n22(n) = grid_in%field_pos(i2, j2)
595 IF(min(n11(n),n21(n),n12(n),n22(n)).GT.0)
THEN
600 CALL movect(rlai(n11(n)),rloi(n11(n)),rlat(n),rlon(n),cm11,sm11)
601 CALL movect(rlai(n21(n)),rloi(n21(n)),rlat(n),rlon(n),cm21,sm21)
602 CALL movect(rlai(n12(n)),rloi(n12(n)),rlat(n),rlon(n),cm12,sm12)
603 CALL movect(rlai(n22(n)),rloi(n22(n)),rlat(n),rlon(n),cm22,sm22)
604 c11(n)=cm11*croi(n11(n))+sm11*sroi(n11(n))
605 s11(n)=sm11*croi(n11(n))-cm11*sroi(n11(n))
606 c21(n)=cm21*croi(n21(n))+sm21*sroi(n21(n))
607 s21(n)=sm21*croi(n21(n))-cm21*sroi(n21(n))
608 c12(n)=cm12*croi(n12(n))+sm12*sroi(n12(n))
609 s12(n)=sm12*croi(n12(n))-cm12*sroi(n12(n))
610 c22(n)=cm22*croi(n22(n))+sm22*sroi(n22(n))
611 s22(n)=sm22*croi(n22(n))-cm22*sroi(n22(n))
634 u11=c11(n)*ui(n11(n),k)-s11(n)*vi(n11(n),k)
635 v11=s11(n)*ui(n11(n),k)+c11(n)*vi(n11(n),k)
636 u21=c21(n)*ui(n21(n),k)-s21(n)*vi(n21(n),k)
637 v21=s21(n)*ui(n21(n),k)+c21(n)*vi(n21(n),k)
638 u12=c12(n)*ui(n12(n),k)-s12(n)*vi(n12(n),k)
639 v12=s12(n)*ui(n12(n),k)+c12(n)*vi(n12(n),k)
640 u22=c22(n)*ui(n22(n),k)-s22(n)*vi(n22(n),k)
641 v22=s22(n)*ui(n22(n),k)+c22(n)*vi(n22(n),k)
642 ub=w11(n)*u11+w21(n)*u21+w12(n)*u12+w22(n)*u22
643 vb=w11(n)*v11+w21(n)*v21+w12(n)*v12+w22(n)*v22
644 uo(n,k)=uo(n,k)+wb*ub
645 vo(n,k)=vo(n,k)+wb*vb
648 IF(li(n11(n),k))
THEN
649 u11=c11(n)*ui(n11(n),k)-s11(n)*vi(n11(n),k)
650 v11=s11(n)*ui(n11(n),k)+c11(n)*vi(n11(n),k)
651 uo(n,k)=uo(n,k)+wb*w11(n)*u11
652 vo(n,k)=vo(n,k)+wb*w11(n)*v11
653 wo(n,k)=wo(n,k)+wb*w11(n)
655 IF(li(n21(n),k))
THEN
656 u21=c21(n)*ui(n21(n),k)-s21(n)*vi(n21(n),k)
657 v21=s21(n)*ui(n21(n),k)+c21(n)*vi(n21(n),k)
658 uo(n,k)=uo(n,k)+wb*w21(n)*u21
659 vo(n,k)=vo(n,k)+wb*w21(n)*v21
660 wo(n,k)=wo(n,k)+wb*w21(n)
662 IF(li(n12(n),k))
THEN
663 u12=c12(n)*ui(n12(n),k)-s12(n)*vi(n12(n),k)
664 v12=s12(n)*ui(n12(n),k)+c12(n)*vi(n12(n),k)
665 uo(n,k)=uo(n,k)+wb*w12(n)*u12
666 vo(n,k)=vo(n,k)+wb*w12(n)*v12
667 wo(n,k)=wo(n,k)+wb*w12(n)
669 IF(li(n22(n),k))
THEN
670 u22=c22(n)*ui(n22(n),k)-s22(n)*vi(n22(n),k)
671 v22=s22(n)*ui(n22(n),k)+c22(n)*vi(n22(n),k)
672 uo(n,k)=uo(n,k)+wb*w22(n)*u22
673 vo(n,k)=vo(n,k)+wb*w22(n)*v22
674 wo(n,k)=wo(n,k)+wb*w22(n)
690 lo(n,k)=wo(n,k).GE.pmp*nb4
692 uo(n,k)=uo(n,k)/wo(n,k)
693 vo(n,k)=vo(n,k)/wo(n,k)
694 urot=crot(n)*uo(n,k)-srot(n)*vo(n,k)
695 vrot=srot(n)*uo(n,k)+crot(n)*vo(n,k)
707 select type(grid_out2)
708 type is(ip_equid_cylind_grid)
709 CALL polfixv(no,mo,km,rlat,rlon,ibo,lo,uo,vo)
subroutine movect(FLAT, FLON, TLAT, TLON, CROT, SROT)
This subprogram provides the rotation parameters to move a vector along a great circle from one posit...
Budget interpolation routines for scalars and vectors.
subroutine interpolate_budget_scalar(IPOPT, grid_in, grid_out, MI, MO, KM, IBI, LI, GI, NO, RLAT, RLON, IBO, LO, GO, IRET)
Performs budget interpolation from any grid to any grid (or to random station points) for scalar fiel...
subroutine interpolate_budget_vector(IPOPT, grid_in, grid_out, MI, MO, KM, IBI, LI, UI, VI, NO, RLAT, RLON, CROT, SROT, IBO, LO, UO, VO, IRET)
This subprogram performs budget interpolation from any grid to any grid (or to random station points)...
Driver module for gdswzd routines.
Users derived type grid descriptor objects to abstract away the raw GRIB1 and GRIB2 grid definitions.
Routines for creating an ip_grid given a Grib descriptor.
Re-export the individual grids.
Make multiple pole scalar values consistent.
subroutine, public polfixs(NM, NX, KM, RLAT, IB, LO, GO)
Make multiple pole scalar values consistent.
subroutine, public polfixv(NM, NX, KM, RLAT, RLON, IB, LO, UO, VO)
Make multiple pole vector values consistent,.