23 REAL :: TINYREAL=tiny(1.0)
82 NO,RLAT,RLON,IBO,LO,GO,IRET)
83 class(ip_grid),
intent(in) :: grid_in, grid_out
84 INTEGER,
INTENT(IN ) :: IPOPT(20)
85 INTEGER,
INTENT(IN ) :: MI,MO,KM
86 INTEGER,
INTENT(IN ) :: IBI(KM)
87 INTEGER,
INTENT(INOUT) :: NO
88 INTEGER,
INTENT( OUT) :: IRET, IBO(KM)
90 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
91 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
93 REAL,
INTENT(IN ) :: GI(MI,KM)
94 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
95 REAL,
INTENT( OUT) :: GO(MO,KM)
97 REAL,
PARAMETER :: FILL=-9999.
99 INTEGER :: IJX(4),IJY(4)
100 INTEGER :: MCON,MP,N,I,J,K
102 LOGICAL :: SAME_GRIDI, SAME_GRIDO
104 REAL :: PMP,XIJ,YIJ,XF,YF
105 REAL :: G,W,GMIN,GMAX
107 REAL :: XPTS(MO),YPTS(MO)
108 logical :: to_station_points
111 REAL,
ALLOCATABLE,
SAVE :: RLATX(:),RLONX(:)
112 REAL,
ALLOCATABLE,
SAVE :: WXY(:,:,:)
113 INTEGER,
SAVE :: NOX=-1,iretx=-1
114 INTEGER,
ALLOCATABLE,
SAVE :: NXY(:,:,:),NC(:)
115 class(ip_grid),
allocatable,
save :: prev_grid_in, prev_grid_out
122 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
123 IF(mp.LT.0.OR.mp.GT.100) iret=32
126 if (.not.
allocated(prev_grid_in) .or. .not.
allocated(prev_grid_out))
then
127 allocate(prev_grid_in, source = grid_in)
128 allocate(prev_grid_out, source = grid_out)
133 same_gridi = grid_in == prev_grid_in
134 same_grido = grid_out == prev_grid_out
136 if (.not. same_gridi .or. .not. same_grido)
then
137 deallocate(prev_grid_in)
138 deallocate(prev_grid_out)
140 allocate(prev_grid_in, source = grid_in)
141 allocate(prev_grid_out, source = grid_out)
145 select type(grid_out)
146 type is(ip_station_points_grid)
147 to_station_points = .true.
149 to_station_points = .false.
154 IF(iret.EQ.0.AND.(to_station_points.OR..NOT.same_gridi.OR..NOT.same_grido))
THEN
157 CALL gdswzd(grid_out,0,mo,fill,xpts,ypts,rlon,rlat,no)
161 CALL gdswzd(grid_in,-1,no,fill,xpts,ypts,rlon,rlat,nv)
162 IF(iret.EQ.0.AND.nv.EQ.0) iret=2
166 IF(nox.GE.0)
DEALLOCATE(rlatx,rlonx,nc,nxy,wxy)
167 ALLOCATE(rlatx(no),rlonx(no),nc(no),nxy(4,4,no),wxy(4,4,no))
180 IF(abs(xij-fill).GT.tinyreal.AND.abs(yij-fill).GT.tinyreal)
THEN
181 ijx(1:4)=floor(xij-1)+(/0,1,2,3/)
182 ijy(1:4)=floor(yij-1)+(/0,1,2,3/)
187 nxy(i,j,n) = grid_in%field_pos(ijx(i), ijy(j))
190 IF(minval(nxy(1:4,1:4,n)).GT.0)
THEN
193 wx(1)=xf*(1-xf)*(2-xf)/(-6.)
194 wx(2)=(xf+1)*(1-xf)*(2-xf)/2.
195 wx(3)=(xf+1)*xf*(2-xf)/2.
196 wx(4)=(xf+1)*xf*(1-xf)/(-6.)
197 wy(1)=yf*(1-yf)*(2-yf)/(-6.)
198 wy(2)=(yf+1)*(1-yf)*(2-yf)/2.
199 wy(3)=(yf+1)*yf*(2-yf)/2.
200 wy(4)=(yf+1)*yf*(1-yf)/(-6.)
215 wxy(i,j,n)=wx(i)*wy(j)
226 IF(iret.EQ.0.AND.iretx.EQ.0)
THEN
227 IF(.not. to_station_points)
THEN
241 IF(mcon.GT.0) gmin=huge(gmin)
242 IF(mcon.GT.0) gmax=-huge(gmax)
245 IF(nxy(i,j,n).GT.0)
THEN
246 IF(ibi(k).EQ.0.OR.li(nxy(i,j,n),k))
THEN
247 g=g+wxy(i,j,n)*gi(nxy(i,j,n),k)
249 IF(mcon.GT.0) gmin=min(gmin,gi(nxy(i,j,n),k))
250 IF(mcon.GT.0) gmax=max(gmax,gi(nxy(i,j,n),k))
258 IF(mcon.GT.0) go(n,k)=min(max(go(n,k),gmin),gmax)
269 IF(.NOT.all(lo(1:no,k))) ibo(k)=1
271 select type(grid_out)
272 type is(ip_equid_cylind_grid)
273 CALL polfixs(no,mo,km,rlat,ibo,lo,go)
276 IF(iret.EQ.0) iret=iretx
277 IF(.not. to_station_points) no=0
339 mi, mo, km, ibi, li, ui, vi, &
340 no, rlat, rlon, crot, srot, ibo, lo, uo, vo, iret)
341 class(ip_grid),
intent(in) :: grid_in, grid_out
342 INTEGER,
INTENT(IN ) :: IPOPT(20)
343 INTEGER,
INTENT(IN ) :: IBI(KM),MI,MO,KM
344 INTEGER,
INTENT(INOUT) :: NO
345 INTEGER,
INTENT( OUT) :: IRET, IBO(KM)
347 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
348 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
350 REAL,
INTENT(IN ) :: UI(MI,KM),VI(MI,KM)
351 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO),CROT(MO),SROT(MO)
352 REAL,
INTENT( OUT) :: UO(MO,KM),VO(MO,KM)
354 REAL,
PARAMETER :: FILL=-9999.
356 INTEGER :: IJX(4),IJY(4)
357 INTEGER :: MCON,MP,N,I,J,K,NK,NV
359 LOGICAL :: SAME_GRIDI,SAME_GRIDO
361 REAL :: CM,SM,UROT,VROT
362 REAL :: PMP,XIJ,YIJ,XF,YF
363 REAL :: U,V,W,UMIN,UMAX,VMIN,VMAX
364 REAL :: XPTS(MO),YPTS(MO)
366 REAL :: XPTI(MI),YPTI(MI),RLOI(MI),RLAI(MI)
367 REAL :: CROI(MI),SROI(MI)
369 logical :: to_station_points
372 REAL,
ALLOCATABLE,
SAVE :: RLATX(:),RLONX(:),CROTX(:),SROTX(:)
373 REAL,
ALLOCATABLE,
SAVE :: WXY(:,:,:),CXY(:,:,:),SXY(:,:,:)
374 INTEGER,
SAVE :: NOX=-1,iretx=-1
375 INTEGER,
ALLOCATABLE,
SAVE :: NXY(:,:,:),NC(:)
376 class(ip_grid),
allocatable,
save :: prev_grid_in, prev_grid_out
382 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
383 IF(mp.LT.0.OR.mp.GT.100) iret=32
387 if (.not.
allocated(prev_grid_in) .or. .not.
allocated(prev_grid_out))
then
388 allocate(prev_grid_in, source = grid_in)
389 allocate(prev_grid_out, source = grid_out)
394 same_gridi = grid_in == prev_grid_in
395 same_grido = grid_out == prev_grid_out
397 if (.not. same_gridi .or. .not. same_grido)
then
398 deallocate(prev_grid_in)
399 deallocate(prev_grid_out)
401 allocate(prev_grid_in, source = grid_in)
402 allocate(prev_grid_out, source = grid_out)
406 select type(grid_out)
407 type is(ip_station_points_grid)
408 to_station_points = .true.
410 to_station_points = .false.
415 IF(iret.EQ.0.AND.(to_station_points.OR..NOT.same_gridi.OR..NOT.same_grido))
THEN
418 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts,rlon,rlat,no,crot,srot)
422 CALL gdswzd(grid_in,-1,no,fill,xpts,ypts,rlon,rlat,nv)
423 IF(iret.EQ.0.AND.nv.EQ.0) iret=2
424 CALL gdswzd(grid_in, 0,mi,fill,xpti,ypti,rloi,rlai,nv,croi,sroi)
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(abs(xij-fill).GT.tinyreal.AND.abs(yij-fill).GT.tinyreal)
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
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...
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.
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,.