25 REAL :: TINYREAL=tiny(1.0)
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
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,.