1module neighbor_interp_mod
11 module procedure interpolate_neighbor_scalar
12 module procedure interpolate_neighbor_vector
17 SUBROUTINE interpolate_neighbor_scalar(IPOPT,grid_in,grid_out, &
19 NO,RLAT,RLON,IBO,LO,GO,IRET)
146 class(ip_grid),
intent(in) :: grid_in, grid_out
147 INTEGER,
INTENT(IN ) :: IPOPT(20)
148 INTEGER,
INTENT(IN ) :: MI,MO,KM
149 INTEGER,
INTENT(IN ) :: IBI(KM)
150 INTEGER,
INTENT(INOUT) :: NO
151 INTEGER,
INTENT( OUT) :: IRET, IBO(KM)
153 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
154 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
156 REAL,
INTENT(IN ) :: GI(MI,KM)
157 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
158 REAL,
INTENT( OUT) :: GO(MO,KM)
160 REAL,
PARAMETER :: FILL=-9999.
162 INTEGER :: I1,J1,IXS,JXS
163 INTEGER :: MSPIRAL,N,K,NK
165 INTEGER :: MX,KXS,KXT,IX,JX,NX
167 LOGICAL :: SAME_GRIDI, SAME_GRIDO
169 REAL :: XPTS(MO),YPTS(MO)
170 logical :: to_station_points
172 INTEGER,
SAVE :: NOX=-1,iretx=-1
173 INTEGER,
ALLOCATABLE,
SAVE :: NXY(:)
174 REAL,
ALLOCATABLE,
SAVE :: RLATX(:),RLONX(:),XPTSX(:),YPTSX(:)
175 class(ip_grid),
allocatable,
save :: prev_grid_in, prev_grid_out
179 mspiral=max(ipopt(1),1)
181 if (.not.
allocated(prev_grid_in) .or. .not.
allocated(prev_grid_out))
then
182 allocate(prev_grid_in, source = grid_in)
183 allocate(prev_grid_out, source = grid_out)
188 same_gridi = grid_in == prev_grid_in
189 same_grido = grid_out == prev_grid_out
191 if (.not. same_gridi .or. .not. same_grido)
then
192 deallocate(prev_grid_in)
193 deallocate(prev_grid_out)
195 allocate(prev_grid_in, source = grid_in)
196 allocate(prev_grid_out, source = grid_out)
200 select type(grid_out)
201 type is(ip_station_points_grid)
202 to_station_points = .true.
204 to_station_points = .false.
208 IF(iret.EQ.0.AND.(to_station_points.OR..NOT.same_gridi.OR..NOT.same_grido))
THEN
211 IF(.not. to_station_points)
THEN
212 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts,rlon,rlat,no)
217 CALL gdswzd(grid_in,-1,no,fill,xpts,ypts,rlon,rlat,nv)
218 IF(iret.EQ.0.AND.nv.EQ.0) iret=2
222 IF(nox.GE.0)
DEALLOCATE(rlatx,rlonx,xptsx,yptsx,nxy)
223 ALLOCATE(rlatx(no),rlonx(no),xptsx(no),yptsx(no),nxy(no))
236 IF(xpts(n).NE.fill.AND.ypts(n).NE.fill)
THEN
237 nxy(n) = grid_in%field_pos(nint(xpts(n)), nint(ypts(n)))
246 IF(iret.EQ.0.AND.iretx.EQ.0)
THEN
247 IF(.not. to_station_points)
THEN
265 IF(ibi(k).EQ.0.OR.li(nxy(n),k))
THEN
269 ELSEIF(mspiral.GT.1)
THEN
272 ixs=sign(1.,xpts(n)-i1)
273 jxs=sign(1.,ypts(n)-j1)
277 SELECT CASE(mod(kxs,4))
279 ix=i1-ixs*(kxs/4-kxt)
283 jx=j1-jxs*(kxs/4-kxt)
285 ix=i1+ixs*(1+kxs/4-kxt)
289 jx=j1+jxs*(kxs/4-kxt)
291 nx = grid_in%field_pos(ix, jx)
306 IF(.NOT.all(lo(1:no,k))) ibo(k)=1
309 select type(grid_out)
310 type is(ip_equid_cylind_grid)
311 CALL polfixs(no,mo,km,rlat,ibo,lo,go)
315 IF(iret.EQ.0) iret=iretx
316 IF(.not. to_station_points) no=0
319 END SUBROUTINE interpolate_neighbor_scalar
321 SUBROUTINE interpolate_neighbor_vector(IPOPT,grid_in,grid_out, &
322 MI,MO,KM,IBI,LI,UI,VI, &
323 NO,RLAT,RLON,CROT,SROT,IBO,LO,UO,VO,IRET)
471 class(ip_grid),
intent(in) :: grid_in, grid_out
472 INTEGER,
INTENT(IN ) :: IPOPT(20)
473 INTEGER,
INTENT(IN ) :: IBI(KM),MI,MO,KM
474 INTEGER,
INTENT(INOUT) :: NO
475 INTEGER,
INTENT( OUT) :: IRET, IBO(KM)
477 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
478 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
480 REAL,
INTENT(IN ) :: UI(MI,KM),VI(MI,KM)
481 REAL,
INTENT(INOUT) :: CROT(MO),SROT(MO)
482 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
483 REAL,
INTENT( OUT) :: UO(MO,KM),VO(MO,KM)
485 REAL,
PARAMETER :: FILL=-9999.
487 INTEGER :: I1,J1,IXS,JXS,MX
488 INTEGER :: KXS,KXT,IX,JX,NX
489 INTEGER :: MSPIRAL,N,K,NK,NV
491 LOGICAL :: SAME_GRIDI, SAME_GRIDO
493 REAL :: CX,SX,CM,SM,UROT,VROT
494 REAL :: XPTS(MO),YPTS(MO)
495 REAL :: CROI(MI),SROI(MI)
496 REAL :: XPTI(MI),YPTI(MI),RLOI(MI),RLAI(MI)
498 logical :: to_station_points
500 INTEGER,
SAVE :: NOX=-1,iretx=-1
501 INTEGER,
ALLOCATABLE,
SAVE :: NXY(:)
503 REAL,
ALLOCATABLE,
SAVE :: RLATX(:),RLONX(:),XPTSX(:),YPTSX(:)
504 REAL,
ALLOCATABLE,
SAVE :: CROTX(:),SROTX(:),CXY(:),SXY(:)
505 class(ip_grid),
allocatable,
save :: prev_grid_in, prev_grid_out
509 mspiral=max(ipopt(1),1)
512 if (.not.
allocated(prev_grid_in) .or. .not.
allocated(prev_grid_out))
then
513 allocate(prev_grid_in, source = grid_in)
514 allocate(prev_grid_out, source = grid_out)
519 same_gridi = grid_in == prev_grid_in
520 same_grido = grid_out == prev_grid_out
522 if (.not. same_gridi .or. .not. same_grido)
then
523 deallocate(prev_grid_in)
524 deallocate(prev_grid_out)
526 allocate(prev_grid_in, source = grid_in)
527 allocate(prev_grid_out, source = grid_out)
531 select type(grid_out)
532 type is(ip_station_points_grid)
533 to_station_points = .true.
535 to_station_points = .false.
540 IF(iret.EQ.0.AND.(to_station_points.OR..NOT.same_gridi.OR..NOT.same_grido))
THEN
543 IF(.not. to_station_points)
THEN
544 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts,rlon,rlat, &
550 CALL gdswzd(grid_in,-1,no,fill,xpts,ypts,rlon,rlat,nv)
551 IF(iret.EQ.0.AND.nv.EQ.0) iret=2
552 CALL gdswzd(grid_in, 0,mi,fill,xpti,ypti,rloi,rlai, &
557 IF(nox.GE.0)
DEALLOCATE(rlatx,rlonx,xptsx,yptsx,crotx,srotx,nxy,cxy,sxy)
558 ALLOCATE(rlatx(no),rlonx(no),xptsx(no),yptsx(no), &
559 crotx(no),srotx(no),nxy(no),cxy(no),sxy(no))
574 IF(xpts(n).NE.fill.AND.ypts(n).NE.fill)
THEN
575 nxy(n) = grid_in%field_pos(nint(xpts(n)),nint(ypts(n)))
577 CALL movect(rlai(nxy(n)),rloi(nxy(n)),rlat(n),rlon(n),cm,sm)
578 cxy(n)=cm*croi(nxy(n))+sm*sroi(nxy(n))
579 sxy(n)=sm*croi(nxy(n))-cm*sroi(nxy(n))
589 IF(iret.EQ.0.AND.iretx.EQ.0)
THEN
590 IF(.not. to_station_points)
THEN
613 IF(ibi(k).EQ.0.OR.li(nxy(n),k))
THEN
614 urot=cxy(n)*ui(nxy(n),k)-sxy(n)*vi(nxy(n),k)
615 vrot=sxy(n)*ui(nxy(n),k)+cxy(n)*vi(nxy(n),k)
616 uo(n,k)=crot(n)*urot-srot(n)*vrot
617 vo(n,k)=srot(n)*urot+crot(n)*vrot
620 ELSEIF(mspiral.GT.1)
THEN
623 ixs=sign(1.,xpts(n)-i1)
624 jxs=sign(1.,ypts(n)-j1)
628 SELECT CASE(mod(kxs,4))
630 ix=i1-ixs*(kxs/4-kxt)
634 jx=j1-jxs*(kxs/4-kxt)
636 ix=i1+ixs*(1+kxs/4-kxt)
640 jx=j1+jxs*(kxs/4-kxt)
642 nx = grid_in%field_pos(ix, jx)
645 CALL movect(rlai(nx),rloi(nx),rlat(n),rlon(n),cm,sm)
646 cx=cm*croi(nx)+sm*sroi(nx)
647 sx=sm*croi(nx)-cm*sroi(nx)
648 urot=cx*ui(nx,k)-sx*vi(nx,k)
649 vrot=sx*ui(nx,k)+cx*vi(nx,k)
650 uo(n,k)=crot(n)*urot-srot(n)*vrot
651 vo(n,k)=srot(n)*urot+crot(n)*vrot
662 IF(.NOT.all(lo(1:no,k))) ibo(k)=1
665 select type(grid_out)
666 type is(ip_equid_cylind_grid)
667 CALL polfixv(no,mo,km,rlat,rlon,ibo,lo,uo,vo)
672 IF(iret.EQ.0) iret=iretx
673 IF(.not. to_station_points) no=0
676 END SUBROUTINE interpolate_neighbor_vector
678end module neighbor_interp_mod
Driver module for gdswzd routines.