77 NO,RLAT,RLON,IBO,LO,GO,IRET)
78 class(ip_grid),
intent(in) :: grid_in, grid_out
79 INTEGER,
INTENT(IN ) :: IPOPT(20)
80 INTEGER,
INTENT(IN ) :: MI,MO,KM
81 INTEGER,
INTENT(IN ) :: IBI(KM)
82 INTEGER,
INTENT(INOUT) :: NO
83 INTEGER,
INTENT( OUT) :: IRET, IBO(KM)
85 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
86 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
88 REAL,
INTENT(IN ) :: GI(MI,KM)
89 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
90 REAL,
INTENT( OUT) :: GO(MO,KM)
92 REAL,
PARAMETER :: FILL=-9999.
94 INTEGER :: IJX(4),IJY(4)
95 INTEGER :: MCON,MP,N,I,J,K
97 LOGICAL :: SAME_GRIDI, SAME_GRIDO
99 REAL :: PMP,XIJ,YIJ,XF,YF
100 REAL :: G,W,GMIN,GMAX
102 REAL :: XPTS(MO),YPTS(MO)
103 logical :: to_station_points
106 REAL,
ALLOCATABLE,
SAVE :: RLATX(:),RLONX(:)
107 REAL,
ALLOCATABLE,
SAVE :: WXY(:,:,:)
108 INTEGER,
SAVE :: NOX=-1,iretx=-1
109 INTEGER,
ALLOCATABLE,
SAVE :: NXY(:,:,:),NC(:)
110 class(ip_grid),
allocatable,
save :: prev_grid_in, prev_grid_out
117 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
118 IF(mp.LT.0.OR.mp.GT.100) iret=32
121 if (.not.
allocated(prev_grid_in) .or. .not.
allocated(prev_grid_out))
then
122 allocate(prev_grid_in, source = grid_in)
123 allocate(prev_grid_out, source = grid_out)
128 same_gridi = grid_in == prev_grid_in
129 same_grido = grid_out == prev_grid_out
131 if (.not. same_gridi .or. .not. same_grido)
then
132 deallocate(prev_grid_in)
133 deallocate(prev_grid_out)
135 allocate(prev_grid_in, source = grid_in)
136 allocate(prev_grid_out, source = grid_out)
140 select type(grid_out)
141 type is(ip_station_points_grid)
142 to_station_points = .true.
144 to_station_points = .false.
149 IF(iret.EQ.0.AND.(to_station_points.OR..NOT.same_gridi.OR..NOT.same_grido))
THEN
152 IF(.not. to_station_points)
THEN
153 CALL gdswzd(grid_out,0,mo,fill,xpts,ypts,rlon,rlat,no)
158 CALL gdswzd(grid_in,-1,no,fill,xpts,ypts,rlon,rlat,nv)
159 IF(iret.EQ.0.AND.nv.EQ.0) iret=2
163 IF(nox.GE.0)
DEALLOCATE(rlatx,rlonx,nc,nxy,wxy)
164 ALLOCATE(rlatx(no),rlonx(no),nc(no),nxy(4,4,no),wxy(4,4,no))
177 IF(xij.NE.fill.AND.yij.NE.fill)
THEN
178 ijx(1:4)=floor(xij-1)+(/0,1,2,3/)
179 ijy(1:4)=floor(yij-1)+(/0,1,2,3/)
184 nxy(i,j,n) = grid_in%field_pos(ijx(i), ijy(j))
187 IF(minval(nxy(1:4,1:4,n)).GT.0)
THEN
190 wx(1)=xf*(1-xf)*(2-xf)/(-6.)
191 wx(2)=(xf+1)*(1-xf)*(2-xf)/2.
192 wx(3)=(xf+1)*xf*(2-xf)/2.
193 wx(4)=(xf+1)*xf*(1-xf)/(-6.)
194 wy(1)=yf*(1-yf)*(2-yf)/(-6.)
195 wy(2)=(yf+1)*(1-yf)*(2-yf)/2.
196 wy(3)=(yf+1)*yf*(2-yf)/2.
197 wy(4)=(yf+1)*yf*(1-yf)/(-6.)
212 wxy(i,j,n)=wx(i)*wy(j)
223 IF(iret.EQ.0.AND.iretx.EQ.0)
THEN
224 IF(.not. to_station_points)
THEN
238 IF(mcon.GT.0) gmin=huge(gmin)
239 IF(mcon.GT.0) gmax=-huge(gmax)
242 IF(nxy(i,j,n).GT.0)
THEN
243 IF(ibi(k).EQ.0.OR.li(nxy(i,j,n),k))
THEN
244 g=g+wxy(i,j,n)*gi(nxy(i,j,n),k)
246 IF(mcon.GT.0) gmin=min(gmin,gi(nxy(i,j,n),k))
247 IF(mcon.GT.0) gmax=max(gmax,gi(nxy(i,j,n),k))
255 IF(mcon.GT.0) go(n,k)=min(max(go(n,k),gmin),gmax)
266 IF(.NOT.all(lo(1:no,k))) ibo(k)=1
268 select type(grid_out)
269 type is(ip_equid_cylind_grid)
270 CALL polfixs(no,mo,km,rlat,ibo,lo,go)
273 IF(iret.EQ.0) iret=iretx
274 IF(.not. to_station_points) no=0
335 mi, mo, km, ibi, li, ui, vi, &
336 no, rlat, rlon, crot, srot, ibo, lo, uo, vo, iret)
337 class(ip_grid),
intent(in) :: grid_in, grid_out
338 INTEGER,
INTENT(IN ) :: IPOPT(20)
339 INTEGER,
INTENT(IN ) :: IBI(KM),MI,MO,KM
340 INTEGER,
INTENT(INOUT) :: NO
341 INTEGER,
INTENT( OUT) :: IRET, IBO(KM)
343 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
344 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
346 REAL,
INTENT(IN ) :: UI(MI,KM),VI(MI,KM)
347 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO),CROT(MO),SROT(MO)
348 REAL,
INTENT( OUT) :: UO(MO,KM),VO(MO,KM)
350 REAL,
PARAMETER :: FILL=-9999.
352 INTEGER :: IJX(4),IJY(4)
353 INTEGER :: MCON,MP,N,I,J,K,NK,NV
355 LOGICAL :: SAME_GRIDI,SAME_GRIDO
357 REAL :: CM,SM,UROT,VROT
358 REAL :: PMP,XIJ,YIJ,XF,YF
359 REAL :: U,V,W,UMIN,UMAX,VMIN,VMAX
360 REAL :: XPTS(MO),YPTS(MO)
362 REAL :: XPTI(MI),YPTI(MI),RLOI(MI),RLAI(MI)
363 REAL :: CROI(MI),SROI(MI)
365 logical :: to_station_points
368 REAL,
ALLOCATABLE,
SAVE :: RLATX(:),RLONX(:),CROTX(:),SROTX(:)
369 REAL,
ALLOCATABLE,
SAVE :: WXY(:,:,:),CXY(:,:,:),SXY(:,:,:)
370 INTEGER,
SAVE :: NOX=-1,iretx=-1
371 INTEGER,
ALLOCATABLE,
SAVE :: NXY(:,:,:),NC(:)
372 class(ip_grid),
allocatable,
save :: prev_grid_in, prev_grid_out
378 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
379 IF(mp.LT.0.OR.mp.GT.100) iret=32
383 if (.not.
allocated(prev_grid_in) .or. .not.
allocated(prev_grid_out))
then
384 allocate(prev_grid_in, source = grid_in)
385 allocate(prev_grid_out, source = grid_out)
390 same_gridi = grid_in == prev_grid_in
391 same_grido = grid_out == prev_grid_out
393 if (.not. same_gridi .or. .not. same_grido)
then
394 deallocate(prev_grid_in)
395 deallocate(prev_grid_out)
397 allocate(prev_grid_in, source = grid_in)
398 allocate(prev_grid_out, source = grid_out)
402 select type(grid_out)
403 type is(ip_station_points_grid)
404 to_station_points = .true.
406 to_station_points = .false.
411 IF(iret.EQ.0.AND.(to_station_points.OR..NOT.same_gridi.OR..NOT.same_grido))
THEN
414 IF(.not. to_station_points)
then
415 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts,rlon,rlat, &
421 CALL gdswzd(grid_in,-1,no,fill,xpts,ypts,rlon,rlat,nv)
422 IF(iret.EQ.0.AND.nv.EQ.0) iret=2
423 CALL gdswzd(grid_in, 0,mi,fill,xpti,ypti,rloi,rlai, &
428 IF(nox.GE.0)
DEALLOCATE(rlatx,rlonx,crotx,srotx,nc,nxy,wxy,cxy,sxy)
429 ALLOCATE(rlatx(no),rlonx(no),crotx(no),srotx(no),nc(no), &
430 nxy(4,4,no),wxy(4,4,no),cxy(4,4,no),sxy(4,4,no))
445 IF(xij.NE.fill.AND.yij.NE.fill)
THEN
446 ijx(1:4)=floor(xij-1)+(/0,1,2,3/)
447 ijy(1:4)=floor(yij-1)+(/0,1,2,3/)
452 nxy(i,j,n) = grid_in%field_pos(ijx(i), ijy(j))
455 IF(minval(nxy(1:4,1:4,n)).GT.0)
THEN
458 wx(1)=xf*(1-xf)*(2-xf)/(-6.)
459 wx(2)=(xf+1)*(1-xf)*(2-xf)/2.
460 wx(3)=(xf+1)*xf*(2-xf)/2.
461 wx(4)=(xf+1)*xf*(1-xf)/(-6.)
462 wy(1)=yf*(1-yf)*(2-yf)/(-6.)
463 wy(2)=(yf+1)*(1-yf)*(2-yf)/2.
464 wy(3)=(yf+1)*yf*(2-yf)/2.
465 wy(4)=(yf+1)*yf*(1-yf)/(-6.)
480 wxy(i,j,n)=wx(i)*wy(j)
481 IF(nxy(i,j,n).GT.0)
THEN
482 CALL movect(rlai(nxy(i,j,n)),rloi(nxy(i,j,n)), &
483 rlat(n),rlon(n),cm,sm)
484 cxy(i,j,n)=cm*croi(nxy(i,j,n))+sm*sroi(nxy(i,j,n))
485 sxy(i,j,n)=sm*croi(nxy(i,j,n))-cm*sroi(nxy(i,j,n))
497 IF(iret.EQ.0.AND.iretx.EQ.0)
THEN
498 IF(.not. to_station_points)
THEN
515 IF(mcon.GT.0) umin=huge(umin)
516 IF(mcon.GT.0) umax=-huge(umax)
517 IF(mcon.GT.0) vmin=huge(vmin)
518 IF(mcon.GT.0) vmax=-huge(vmax)
521 IF(nxy(i,j,n).GT.0)
THEN
522 IF(ibi(k).EQ.0.OR.li(nxy(i,j,n),k))
THEN
523 urot=cxy(i,j,n)*ui(nxy(i,j,n),k)-sxy(i,j,n)*vi(nxy(i,j,n),k)
524 vrot=sxy(i,j,n)*ui(nxy(i,j,n),k)+cxy(i,j,n)*vi(nxy(i,j,n),k)
528 IF(mcon.GT.0) umin=min(umin,urot)
529 IF(mcon.GT.0) umax=max(umax,urot)
530 IF(mcon.GT.0) vmin=min(vmin,vrot)
531 IF(mcon.GT.0) vmax=max(vmax,vrot)
538 urot=crot(n)*u-srot(n)*v
539 vrot=srot(n)*u+crot(n)*v
542 IF(mcon.GT.0) uo(n,k)=min(max(uo(n,k),umin),umax)
543 IF(mcon.GT.0) vo(n,k)=min(max(vo(n,k),vmin),vmax)
556 IF(.NOT.all(lo(1:no,k))) ibo(k)=1
558 select type(grid_out)
559 type is(ip_equid_cylind_grid)
560 CALL polfixv(no,mo,km,rlat,rlon,ibo,lo,uo,vo)
564 IF(iret.EQ.0) iret=iretx
565 IF(.not. to_station_points) no=0
Bicubic interpolation routines for scalars and vectors.
subroutine interpolate_bicubic_scalar(IPOPT, grid_in, grid_out, MI, MO, KM, IBI, LI, GI, NO, RLAT, RLON, IBO, LO, GO, IRET)
This subprogram performs bicubic interpolation from any grid to any grid for scalar fields.
subroutine interpolate_bicubic_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 bicubic interpolation from any grid to any grid for vector fields.
Driver module for gdswzd routines.