72 subroutine interpolate_bilinear_scalar(IPOPT,grid_in,grid_out,MI,MO,KM,IBI,LI,GI,NO,RLAT,RLON,IBO,LO,GO,IRET)
73 class(ip_grid),
intent(in) :: grid_in, grid_out
74 INTEGER,
INTENT(IN ) :: IPOPT(20)
75 INTEGER,
INTENT(IN ) :: MI,MO,KM
76 INTEGER,
INTENT(IN ) :: IBI(KM)
77 INTEGER,
INTENT(INOUT) :: NO
78 INTEGER,
INTENT( OUT) :: IRET, IBO(KM)
80 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
81 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
83 REAL,
INTENT(IN ) :: GI(MI,KM)
84 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
85 REAL,
INTENT( OUT) :: GO(MO,KM)
87 REAL,
PARAMETER :: FILL=-9999.
89 INTEGER :: IJX(2),IJY(2)
92 INTEGER :: MSPIRAL,I1,J1,IXS,JXS
93 INTEGER :: MX,KXS,KXT,IX,JX,NX
95 LOGICAL :: SAME_GRIDI, SAME_GRIDO
98 REAL :: XPTS(MO),YPTS(MO)
99 REAL :: PMP,XIJ,YIJ,XF,YF,G,W
101 logical :: to_station_points
104 INTEGER,
SAVE :: NOX=-1,iretx=-1
105 INTEGER,
ALLOCATABLE,
SAVE :: NXY(:,:,:)
106 REAL,
ALLOCATABLE,
SAVE :: RLATX(:),RLONX(:)
107 REAL,
ALLOCATABLE,
SAVE :: WXY(:,:,:)
108 class(ip_grid),
allocatable,
save :: prev_grid_in, prev_grid_out
112 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
113 IF(mp.LT.0.OR.mp.GT.100) iret=32
115 mspiral=max(ipopt(2),0)
117 if (.not.
allocated(prev_grid_in) .or. .not.
allocated(prev_grid_out))
then
118 allocate(prev_grid_in, source = grid_in)
119 allocate(prev_grid_out, source = grid_out)
124 same_gridi = grid_in == prev_grid_in
125 same_grido = grid_out == prev_grid_out
127 if (.not. same_gridi .or. .not. same_grido)
then
128 deallocate(prev_grid_in)
129 deallocate(prev_grid_out)
131 allocate(prev_grid_in, source = grid_in)
132 allocate(prev_grid_out, source = grid_out)
136 select type(grid_out)
137 type is(ip_station_points_grid)
138 to_station_points = .true.
140 to_station_points = .false.
145 IF(iret==0.AND.(to_station_points.OR..NOT.same_gridi.OR..NOT.same_grido))
THEN
148 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts,rlon,rlat,no)
152 CALL gdswzd(grid_in,-1,no,fill,xpts,ypts,rlon,rlat,nv)
153 IF(iret.EQ.0.AND.nv.EQ.0) iret=2
157 IF(nox.GE.0)
DEALLOCATE(rlatx,rlonx,nxy,wxy)
158 ALLOCATE(rlatx(no),rlonx(no),nxy(2,2,no),wxy(2,2,no))
171 IF(abs(xij-fill).GT.tinyreal.AND.abs(yij-fill).GT.tinyreal)
THEN
172 ijx(1:2)=floor(xij)+(/0,1/)
173 ijy(1:2)=floor(yij)+(/0,1/)
182 nxy(i,j,n)=grid_in%field_pos(ijx(i), ijy(j))
183 wxy(i,j,n)=wx(i)*wy(j)
194 IF(iret.EQ.0.AND.iretx.EQ.0)
THEN
195 IF(.not. to_station_points)
THEN
212 IF(nxy(i,j,n).GT.0)
THEN
213 IF(ibi(k).EQ.0.OR.li(nxy(i,j,n),k))
THEN
214 g=g+wxy(i,j,n)*gi(nxy(i,j,n),k)
223 ELSEIF(mspiral.GT.0.AND.abs(xpts(n)-fill).GT.tinyreal.AND.abs(ypts(n)-fill).GT.tinyreal)
THEN
226 ixs=int(sign(1.,xpts(n)-i1))
227 jxs=int(sign(1.,ypts(n)-j1))
228 spiral :
DO mx=1,mspiral**2
229 kxs=int(sqrt(4*mx-2.5))
231 SELECT CASE(mod(kxs,4))
233 ix=i1-ixs*(kxs/4-kxt)
237 jx=j1-jxs*(kxs/4-kxt)
239 ix=i1+ixs*(1+kxs/4-kxt)
243 jx=j1+jxs*(kxs/4-kxt)
245 nx=grid_in%field_pos(ix, jx)
247 IF(li(nx,k).OR.ibi(k).EQ.0)
THEN
264 IF(.NOT.all(lo(1:no,k))) ibo(k)=1
266 select type(grid_out)
267 type is(ip_equid_cylind_grid)
268 CALL polfixs(no,mo,km,rlat,ibo,lo,go)
271 IF(iret.EQ.0) iret=iretx
272 IF(.not. to_station_points) no=0
330 MI,MO,KM,IBI,LI,UI,VI, &
331 NO,RLAT,RLON,CROT,SROT,IBO,LO,UO,VO,IRET)
332 class(ip_grid),
intent(in) :: grid_in, grid_out
333 INTEGER,
INTENT(IN ) :: IPOPT(20),IBI(KM),MI,MO,KM
334 INTEGER,
INTENT(INOUT) :: NO
335 INTEGER,
INTENT( OUT) :: IRET, IBO(KM)
337 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
338 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
340 REAL,
INTENT(IN ) :: UI(MI,KM),VI(MI,KM)
341 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO),CROT(MO),SROT(MO)
342 REAL,
INTENT( OUT) :: UO(MO,KM),VO(MO,KM)
344 REAL,
PARAMETER :: FILL=-9999.
346 INTEGER :: IJX(2),IJY(2)
347 INTEGER :: MP,N,I,J,K,NK,NV
349 LOGICAL :: SAME_GRIDI, SAME_GRIDO
351 REAL :: CM,SM,UROT,VROT
352 REAL :: PMP,XIJ,YIJ,XF,YF,U,V,W
353 REAL :: XPTS(MO),YPTS(MO)
355 REAL :: XPTI(MI),YPTI(MI)
356 REAL :: RLOI(MI),RLAI(MI)
357 REAL :: CROI(MI),SROI(MI)
359 logical :: to_station_points
362 INTEGER,
SAVE :: NOX=-1,iretx=-1
363 INTEGER,
ALLOCATABLE,
SAVE :: NXY(:,:,:)
364 REAL,
ALLOCATABLE,
SAVE :: RLATX(:),RLONX(:)
365 REAL,
ALLOCATABLE,
SAVE :: CROTX(:),SROTX(:)
366 REAL,
ALLOCATABLE,
SAVE :: WXY(:,:,:),CXY(:,:,:),SXY(:,:,:)
367 class(ip_grid),
allocatable,
save :: prev_grid_in, prev_grid_out
373 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
374 IF(mp.LT.0.OR.mp.GT.100) iret=32
377 if (.not.
allocated(prev_grid_in) .or. .not.
allocated(prev_grid_out))
then
378 allocate(prev_grid_in, source = grid_in)
379 allocate(prev_grid_out, source = grid_out)
384 same_gridi = grid_in == prev_grid_in
385 same_grido = grid_out == prev_grid_out
387 if (.not. same_gridi .or. .not. same_grido)
then
388 deallocate(prev_grid_in)
389 deallocate(prev_grid_out)
391 allocate(prev_grid_in, source = grid_in)
392 allocate(prev_grid_out, source = grid_out)
396 select type(grid_out)
397 type is(ip_station_points_grid)
398 to_station_points = .true.
400 to_station_points = .false.
405 IF(iret.EQ.0.AND.(to_station_points.OR..NOT.same_gridi.OR..NOT.same_grido))
THEN
408 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts,rlon,rlat,no,crot,srot)
412 CALL gdswzd(grid_in,-1,no,fill,xpts,ypts,rlon,rlat,nv)
413 IF(iret.EQ.0.AND.nv.EQ.0) iret=2
414 CALL gdswzd(grid_in, 0,mi,fill,xpti,ypti,rloi,rlai,nv,croi,sroi)
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(abs(xij-fill).GT.tinyreal.AND.abs(yij-fill).GT.tinyreal)
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