67 subroutine interpolate_bilinear_scalar(IPOPT,grid_in,grid_out,MI,MO,KM,IBI,LI,GI,NO,RLAT,RLON,IBO,LO,GO,IRET)
68 class(ip_grid),
intent(in) :: grid_in, grid_out
69 INTEGER,
INTENT(IN ) :: IPOPT(20)
70 INTEGER,
INTENT(IN ) :: MI,MO,KM
71 INTEGER,
INTENT(IN ) :: IBI(KM)
72 INTEGER,
INTENT(INOUT) :: NO
73 INTEGER,
INTENT( OUT) :: IRET, IBO(KM)
75 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
76 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
78 REAL,
INTENT(IN ) :: GI(MI,KM)
79 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
80 REAL,
INTENT( OUT) :: GO(MO,KM)
82 REAL,
PARAMETER :: FILL=-9999.
84 INTEGER :: IJX(2),IJY(2)
87 INTEGER :: MSPIRAL,I1,J1,IXS,JXS
88 INTEGER :: MX,KXS,KXT,IX,JX,NX
90 LOGICAL :: SAME_GRIDI, SAME_GRIDO
93 REAL :: XPTS(MO),YPTS(MO)
94 REAL :: PMP,XIJ,YIJ,XF,YF,G,W
96 logical :: to_station_points
99 INTEGER,
SAVE :: NOX=-1,iretx=-1
100 INTEGER,
ALLOCATABLE,
SAVE :: NXY(:,:,:)
101 REAL,
ALLOCATABLE,
SAVE :: RLATX(:),RLONX(:)
102 REAL,
ALLOCATABLE,
SAVE :: WXY(:,:,:)
103 class(ip_grid),
allocatable,
save :: prev_grid_in, prev_grid_out
107 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
108 IF(mp.LT.0.OR.mp.GT.100) iret=32
110 mspiral=max(ipopt(2),0)
112 if (.not.
allocated(prev_grid_in) .or. .not.
allocated(prev_grid_out))
then
113 allocate(prev_grid_in, source = grid_in)
114 allocate(prev_grid_out, source = grid_out)
119 same_gridi = grid_in == prev_grid_in
120 same_grido = grid_out == prev_grid_out
122 if (.not. same_gridi .or. .not. same_grido)
then
123 deallocate(prev_grid_in)
124 deallocate(prev_grid_out)
126 allocate(prev_grid_in, source = grid_in)
127 allocate(prev_grid_out, source = grid_out)
131 select type(grid_out)
132 type is(ip_station_points_grid)
133 to_station_points = .true.
135 to_station_points = .false.
140 IF(iret==0.AND.(to_station_points.OR..NOT.same_gridi.OR..NOT.same_grido))
THEN
143 IF(.not. to_station_points)
THEN
144 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)
151 IF(iret.EQ.0.AND.nv.EQ.0) iret=2
155 IF(nox.GE.0)
DEALLOCATE(rlatx,rlonx,nxy,wxy)
156 ALLOCATE(rlatx(no),rlonx(no),nxy(2,2,no),wxy(2,2,no))
169 IF(xij.NE.fill.AND.yij.NE.fill)
THEN
170 ijx(1:2)=floor(xij)+(/0,1/)
171 ijy(1:2)=floor(yij)+(/0,1/)
180 nxy(i,j,n)=grid_in%field_pos(ijx(i), ijy(j))
181 wxy(i,j,n)=wx(i)*wy(j)
192 IF(iret.EQ.0.AND.iretx.EQ.0)
THEN
193 IF(.not. to_station_points)
THEN
210 IF(nxy(i,j,n).GT.0)
THEN
211 IF(ibi(k).EQ.0.OR.li(nxy(i,j,n),k))
THEN
212 g=g+wxy(i,j,n)*gi(nxy(i,j,n),k)
221 ELSEIF(mspiral.GT.0.AND.xpts(n).NE.fill.AND.ypts(n).NE.fill)
THEN
224 ixs=sign(1.,xpts(n)-i1)
225 jxs=sign(1.,ypts(n)-j1)
226 spiral :
DO mx=1,mspiral**2
229 SELECT CASE(mod(kxs,4))
231 ix=i1-ixs*(kxs/4-kxt)
235 jx=j1-jxs*(kxs/4-kxt)
237 ix=i1+ixs*(1+kxs/4-kxt)
241 jx=j1+jxs*(kxs/4-kxt)
243 nx=grid_in%field_pos(ix, jx)
245 IF(li(nx,k).OR.ibi(k).EQ.0)
THEN
262 IF(.NOT.all(lo(1:no,k))) ibo(k)=1
264 select type(grid_out)
265 type is(ip_equid_cylind_grid)
266 CALL polfixs(no,mo,km,rlat,ibo,lo,go)
269 IF(iret.EQ.0) iret=iretx
270 IF(.not. to_station_points) no=0
326 MI,MO,KM,IBI,LI,UI,VI, &
327 NO,RLAT,RLON,CROT,SROT,IBO,LO,UO,VO,IRET)
328 class(ip_grid),
intent(in) :: grid_in, grid_out
329 INTEGER,
INTENT(IN ) :: IPOPT(20),IBI(KM),MI,MO,KM
330 INTEGER,
INTENT(INOUT) :: NO
331 INTEGER,
INTENT( OUT) :: IRET, IBO(KM)
333 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
334 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
336 REAL,
INTENT(IN ) :: UI(MI,KM),VI(MI,KM)
337 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO),CROT(MO),SROT(MO)
338 REAL,
INTENT( OUT) :: UO(MO,KM),VO(MO,KM)
340 REAL,
PARAMETER :: FILL=-9999.
342 INTEGER :: IJX(2),IJY(2)
343 INTEGER :: MP,N,I,J,K,NK,NV
345 LOGICAL :: SAME_GRIDI, SAME_GRIDO
347 REAL :: CM,SM,UROT,VROT
348 REAL :: PMP,XIJ,YIJ,XF,YF,U,V,W
349 REAL :: XPTS(MO),YPTS(MO)
351 REAL :: XPTI(MI),YPTI(MI)
352 REAL :: RLOI(MI),RLAI(MI)
353 REAL :: CROI(MI),SROI(MI)
355 logical :: to_station_points
358 INTEGER,
SAVE :: NOX=-1,iretx=-1
359 INTEGER,
ALLOCATABLE,
SAVE :: NXY(:,:,:)
360 REAL,
ALLOCATABLE,
SAVE :: RLATX(:),RLONX(:)
361 REAL,
ALLOCATABLE,
SAVE :: CROTX(:),SROTX(:)
362 REAL,
ALLOCATABLE,
SAVE :: WXY(:,:,:),CXY(:,:,:),SXY(:,:,:)
363 class(ip_grid),
allocatable,
save :: prev_grid_in, prev_grid_out
369 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
370 IF(mp.LT.0.OR.mp.GT.100) iret=32
373 if (.not.
allocated(prev_grid_in) .or. .not.
allocated(prev_grid_out))
then
374 allocate(prev_grid_in, source = grid_in)
375 allocate(prev_grid_out, source = grid_out)
380 same_gridi = grid_in == prev_grid_in
381 same_grido = grid_out == prev_grid_out
383 if (.not. same_gridi .or. .not. same_grido)
then
384 deallocate(prev_grid_in)
385 deallocate(prev_grid_out)
387 allocate(prev_grid_in, source = grid_in)
388 allocate(prev_grid_out, source = grid_out)
392 select type(grid_out)
393 type is(ip_station_points_grid)
394 to_station_points = .true.
396 to_station_points = .false.
401 IF(iret.EQ.0.AND.(to_station_points.OR..NOT.same_gridi.OR..NOT.same_grido))
THEN
404 IF(.not. to_station_points)
THEN
405 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts,rlon,rlat, &
411 CALL gdswzd(grid_in,-1,no,fill,xpts,ypts,rlon,rlat,nv)
412 IF(iret.EQ.0.AND.nv.EQ.0) iret=2
413 CALL gdswzd(grid_in, 0,mi,fill,xpti,ypti,rloi,rlai,nv,&
418 IF(nox.GE.0)
DEALLOCATE(rlatx,rlonx,crotx,srotx,nxy,wxy,cxy,sxy)
419 ALLOCATE(rlatx(no),rlonx(no),crotx(no),srotx(no), &
420 nxy(2,2,no),wxy(2,2,no),cxy(2,2,no),sxy(2,2,no))
435 IF(xij.NE.fill.AND.yij.NE.fill)
THEN
436 ijx(1:2)=floor(xij)+(/0,1/)
437 ijy(1:2)=floor(yij)+(/0,1/)
446 nxy(i, j, n) = grid_in%field_pos(ijx(i), ijy(j))
447 wxy(i,j,n)=wx(i)*wy(j)
448 IF(nxy(i,j,n).GT.0)
THEN
449 CALL movect(rlai(nxy(i,j,n)),rloi(nxy(i,j,n)), &
450 rlat(n),rlon(n),cm,sm)
451 cxy(i,j,n)=cm*croi(nxy(i,j,n))+sm*sroi(nxy(i,j,n))
452 sxy(i,j,n)=sm*croi(nxy(i,j,n))-cm*sroi(nxy(i,j,n))
464 IF(iret.EQ.0.AND.iretx.EQ.0)
THEN
465 IF(.not. to_station_points)
THEN
483 IF(nxy(i,j,n).GT.0)
THEN
484 IF(ibi(k).EQ.0.OR.li(nxy(i,j,n),k))
THEN
485 urot=cxy(i,j,n)*ui(nxy(i,j,n),k)-sxy(i,j,n)*vi(nxy(i,j,n),k)
486 vrot=sxy(i,j,n)*ui(nxy(i,j,n),k)+cxy(i,j,n)*vi(nxy(i,j,n),k)
496 urot=crot(n)*u-srot(n)*v
497 vrot=srot(n)*u+crot(n)*v
507 IF(.NOT.all(lo(1:no,k))) ibo(k)=1
510 select type(grid_out)
511 type is(ip_equid_cylind_grid)
512 CALL polfixv(no,mo,km,rlat,rlon,ibo,lo,uo,vo)
516 IF(iret.EQ.0) iret=iretx
517 IF(.not. to_station_points) no=0
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.
Uses derived type grid descriptor objects to abstract away the raw Grib-1 and Grib-2 grid definitions...
Routines for creating an ip_grid given a Grib descriptor.