69 subroutine interpolate_bilinear_scalar(IPOPT,grid_in,grid_out,MI,MO,KM,IBI,LI,GI,NO,RLAT,RLON,IBO,LO,GO,IRET)
70 class(ip_grid),
intent(in) :: grid_in, grid_out
71 INTEGER,
INTENT(IN ) :: IPOPT(20)
72 INTEGER,
INTENT(IN ) :: MI,MO,KM
73 INTEGER,
INTENT(IN ) :: IBI(KM)
74 INTEGER,
INTENT(INOUT) :: NO
75 INTEGER,
INTENT( OUT) :: IRET, IBO(KM)
77 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
78 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
80 REAL,
INTENT(IN ) :: GI(MI,KM)
81 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
82 REAL,
INTENT( OUT) :: GO(MO,KM)
84 REAL,
PARAMETER :: FILL=-9999.
86 INTEGER :: IJX(2),IJY(2)
89 INTEGER :: MSPIRAL,I1,J1,IXS,JXS
90 INTEGER :: MX,KXS,KXT,IX,JX,NX
92 LOGICAL :: SAME_GRIDI, SAME_GRIDO
95 REAL :: XPTS(MO),YPTS(MO)
96 REAL :: PMP,XIJ,YIJ,XF,YF,G,W
98 logical :: to_station_points
101 INTEGER,
SAVE :: NOX=-1,iretx=-1
102 INTEGER,
ALLOCATABLE,
SAVE :: NXY(:,:,:)
103 REAL,
ALLOCATABLE,
SAVE :: RLATX(:),RLONX(:)
104 REAL,
ALLOCATABLE,
SAVE :: WXY(:,:,:)
105 class(ip_grid),
allocatable,
save :: prev_grid_in, prev_grid_out
109 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
110 IF(mp.LT.0.OR.mp.GT.100) iret=32
112 mspiral=max(ipopt(2),0)
114 if (.not.
allocated(prev_grid_in) .or. .not.
allocated(prev_grid_out))
then
115 allocate(prev_grid_in, source = grid_in)
116 allocate(prev_grid_out, source = grid_out)
121 same_gridi = grid_in == prev_grid_in
122 same_grido = grid_out == prev_grid_out
124 if (.not. same_gridi .or. .not. same_grido)
then
125 deallocate(prev_grid_in)
126 deallocate(prev_grid_out)
128 allocate(prev_grid_in, source = grid_in)
129 allocate(prev_grid_out, source = grid_out)
133 select type(grid_out)
134 type is(ip_station_points_grid)
135 to_station_points = .true.
137 to_station_points = .false.
142 IF(iret==0.AND.(to_station_points.OR..NOT.same_gridi.OR..NOT.same_grido))
THEN
145 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts,rlon,rlat,no)
149 CALL gdswzd(grid_in,-1,no,fill,xpts,ypts,rlon,rlat,nv)
150 IF(iret.EQ.0.AND.nv.EQ.0) iret=2
154 IF(nox.GE.0)
DEALLOCATE(rlatx,rlonx,nxy,wxy)
155 ALLOCATE(rlatx(no),rlonx(no),nxy(2,2,no),wxy(2,2,no))
168 IF(xij.NE.fill.AND.yij.NE.fill)
THEN
169 ijx(1:2)=floor(xij)+(/0,1/)
170 ijy(1:2)=floor(yij)+(/0,1/)
179 nxy(i,j,n)=grid_in%field_pos(ijx(i), ijy(j))
180 wxy(i,j,n)=wx(i)*wy(j)
191 IF(iret.EQ.0.AND.iretx.EQ.0)
THEN
192 IF(.not. to_station_points)
THEN
209 IF(nxy(i,j,n).GT.0)
THEN
210 IF(ibi(k).EQ.0.OR.li(nxy(i,j,n),k))
THEN
211 g=g+wxy(i,j,n)*gi(nxy(i,j,n),k)
220 ELSEIF(mspiral.GT.0.AND.xpts(n).NE.fill.AND.ypts(n).NE.fill)
THEN
223 ixs=int(sign(1.,xpts(n)-i1))
224 jxs=int(sign(1.,ypts(n)-j1))
225 spiral :
DO mx=1,mspiral**2
226 kxs=int(sqrt(4*mx-2.5))
228 SELECT CASE(mod(kxs,4))
230 ix=i1-ixs*(kxs/4-kxt)
234 jx=j1-jxs*(kxs/4-kxt)
236 ix=i1+ixs*(1+kxs/4-kxt)
240 jx=j1+jxs*(kxs/4-kxt)
242 nx=grid_in%field_pos(ix, jx)
244 IF(li(nx,k).OR.ibi(k).EQ.0)
THEN
261 IF(.NOT.all(lo(1:no,k))) ibo(k)=1
263 select type(grid_out)
264 type is(ip_equid_cylind_grid)
265 CALL polfixs(no,mo,km,rlat,ibo,lo,go)
268 IF(iret.EQ.0) iret=iretx
269 IF(.not. to_station_points) no=0
327 MI,MO,KM,IBI,LI,UI,VI, &
328 NO,RLAT,RLON,CROT,SROT,IBO,LO,UO,VO,IRET)
329 class(ip_grid),
intent(in) :: grid_in, grid_out
330 INTEGER,
INTENT(IN ) :: IPOPT(20),IBI(KM),MI,MO,KM
331 INTEGER,
INTENT(INOUT) :: NO
332 INTEGER,
INTENT( OUT) :: IRET, IBO(KM)
334 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
335 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
337 REAL,
INTENT(IN ) :: UI(MI,KM),VI(MI,KM)
338 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO),CROT(MO),SROT(MO)
339 REAL,
INTENT( OUT) :: UO(MO,KM),VO(MO,KM)
341 REAL,
PARAMETER :: FILL=-9999.
343 INTEGER :: IJX(2),IJY(2)
344 INTEGER :: MP,N,I,J,K,NK,NV
346 LOGICAL :: SAME_GRIDI, SAME_GRIDO
348 REAL :: CM,SM,UROT,VROT
349 REAL :: PMP,XIJ,YIJ,XF,YF,U,V,W
350 REAL :: XPTS(MO),YPTS(MO)
352 REAL :: XPTI(MI),YPTI(MI)
353 REAL :: RLOI(MI),RLAI(MI)
354 REAL :: CROI(MI),SROI(MI)
356 logical :: to_station_points
359 INTEGER,
SAVE :: NOX=-1,iretx=-1
360 INTEGER,
ALLOCATABLE,
SAVE :: NXY(:,:,:)
361 REAL,
ALLOCATABLE,
SAVE :: RLATX(:),RLONX(:)
362 REAL,
ALLOCATABLE,
SAVE :: CROTX(:),SROTX(:)
363 REAL,
ALLOCATABLE,
SAVE :: WXY(:,:,:),CXY(:,:,:),SXY(:,:,:)
364 class(ip_grid),
allocatable,
save :: prev_grid_in, prev_grid_out
370 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
371 IF(mp.LT.0.OR.mp.GT.100) iret=32
374 if (.not.
allocated(prev_grid_in) .or. .not.
allocated(prev_grid_out))
then
375 allocate(prev_grid_in, source = grid_in)
376 allocate(prev_grid_out, source = grid_out)
381 same_gridi = grid_in == prev_grid_in
382 same_grido = grid_out == prev_grid_out
384 if (.not. same_gridi .or. .not. same_grido)
then
385 deallocate(prev_grid_in)
386 deallocate(prev_grid_out)
388 allocate(prev_grid_in, source = grid_in)
389 allocate(prev_grid_out, source = grid_out)
393 select type(grid_out)
394 type is(ip_station_points_grid)
395 to_station_points = .true.
397 to_station_points = .false.
402 IF(iret.EQ.0.AND.(to_station_points.OR..NOT.same_gridi.OR..NOT.same_grido))
THEN
405 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts,rlon,rlat,no,crot,srot)
409 CALL gdswzd(grid_in,-1,no,fill,xpts,ypts,rlon,rlat,nv)
410 IF(iret.EQ.0.AND.nv.EQ.0) iret=2
411 CALL gdswzd(grid_in, 0,mi,fill,xpti,ypti,rloi,rlai,nv,croi,sroi)
415 IF(nox.GE.0)
DEALLOCATE(rlatx,rlonx,crotx,srotx,nxy,wxy,cxy,sxy)
416 ALLOCATE(rlatx(no),rlonx(no),crotx(no),srotx(no), &
417 nxy(2,2,no),wxy(2,2,no),cxy(2,2,no),sxy(2,2,no))
432 IF(xij.NE.fill.AND.yij.NE.fill)
THEN
433 ijx(1:2)=floor(xij)+(/0,1/)
434 ijy(1:2)=floor(yij)+(/0,1/)
443 nxy(i, j, n) = grid_in%field_pos(ijx(i), ijy(j))
444 wxy(i,j,n)=wx(i)*wy(j)
445 IF(nxy(i,j,n).GT.0)
THEN
446 CALL movect(rlai(nxy(i,j,n)),rloi(nxy(i,j,n)), &
447 rlat(n),rlon(n),cm,sm)
448 cxy(i,j,n)=cm*croi(nxy(i,j,n))+sm*sroi(nxy(i,j,n))
449 sxy(i,j,n)=sm*croi(nxy(i,j,n))-cm*sroi(nxy(i,j,n))
461 IF(iret.EQ.0.AND.iretx.EQ.0)
THEN
462 IF(.not. to_station_points)
THEN
480 IF(nxy(i,j,n).GT.0)
THEN
481 IF(ibi(k).EQ.0.OR.li(nxy(i,j,n),k))
THEN
482 urot=cxy(i,j,n)*ui(nxy(i,j,n),k)-sxy(i,j,n)*vi(nxy(i,j,n),k)
483 vrot=sxy(i,j,n)*ui(nxy(i,j,n),k)+cxy(i,j,n)*vi(nxy(i,j,n),k)
493 urot=crot(n)*u-srot(n)*v
494 vrot=srot(n)*u+crot(n)*v
504 IF(.NOT.all(lo(1:no,k))) ibo(k)=1
507 select type(grid_out)
508 type is(ip_equid_cylind_grid)
509 CALL polfixv(no,mo,km,rlat,rlon,ibo,lo,uo,vo)
513 IF(iret.EQ.0) iret=iretx
514 IF(.not. to_station_points) no=0
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...
Bilinear interpolation routines for scalars and vectors.
subroutine interpolate_bilinear_scalar(IPOPT, grid_in, grid_out, MI, MO, KM, IBI, LI, GI, NO, RLAT, RLON, IBO, LO, GO, IRET)
This subprogram performs bilinear interpolation from any grid to any grid for scalar fields.
subroutine interpolate_bilinear_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 bilinear interpolation from any grid to any grid for vector fields.
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,.