1module neighbor_budget_interp_mod
11 module procedure interpolate_neighbor_budget_scalar
12 module procedure interpolate_neighbor_budget_vector
17 SUBROUTINE interpolate_neighbor_budget_scalar(IPOPT,grid_in,grid_out, &
19 NO,RLAT,RLON,IBO,LO,GO,IRET)
143 class(ip_grid),
intent(in) :: grid_in, grid_out
145 INTEGER,
INTENT(IN ) :: IBI(KM), IPOPT(20), KM, MI, MO
146 INTEGER,
INTENT( OUT) :: IBO(KM), IRET, NO
148 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
149 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
151 REAL,
INTENT(IN ) :: GI(MI,KM)
152 REAL,
INTENT( OUT) :: GO(MO,KM), RLAT(MO), RLON(MO)
154 REAL,
PARAMETER :: FILL=-9999.
157 INTEGER :: JB, J1, K, LB, LSW, MP, N
158 INTEGER :: N11(MO), NB, NB1, NB2, NB3, NB4, NV
160 REAL :: PMP,RLOB(MO),RLAB(MO)
161 REAL :: WB, WO(MO,KM), XI, YI
162 REAL :: XPTB(MO),YPTB(MO),XPTS(MO),YPTS(MO)
164 logical :: to_station_points
166 select type(grid_out)
167 type is(ip_station_points_grid)
168 to_station_points = .true.
170 to_station_points = .false.
176 IF(.not. to_station_points)
THEN
177 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts,rlon,rlat,no)
186 IF(iret.EQ.0.AND.nb1.LT.0) iret=32
188 IF(ipopt(1).EQ.-1.OR.ipopt(2).EQ.-1) lsw=0
189 IF(iret.EQ.0.AND.lsw.EQ.1.AND.nb1.GT.15) iret=32
191 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
192 IF(mp.LT.0.OR.mp.GT.100) iret=32
201 nb4=nb4+8*ib*ipopt(2+ib)
221 ib=nb-(jb+nb1)*nb2-nb1-1
222 lb=max(abs(ib),abs(jb))
224 IF(lsw.EQ.1) wb=ipopt(2+lb)
227 xptb(n)=xpts(n)+ib/real(nb2)
228 yptb(n)=ypts(n)+jb/real(nb2)
230 CALL gdswzd(grid_out, 1,no,fill,xptb,yptb,rlob,rlab,nv)
231 CALL gdswzd(grid_in,-1,no,fill,xptb,yptb,rlob,rlab,nv)
232 IF(iret.EQ.0.AND.nv.EQ.0.AND.lb.EQ.0) iret=2
236 IF(xi.NE.fill.AND.yi.NE.fill)
THEN
239 n11(n)=grid_in%field_pos(i1, j1)
249 IF(ibi(k).EQ.0.OR.li(n11(n),k))
THEN
250 go(n,k)=go(n,k)+wb*gi(n11(n),k)
263 lo(n,k)=wo(n,k).GE.pmp*nb4
265 go(n,k)=go(n,k)/wo(n,k)
273 select type(grid_out)
274 type is(ip_equid_cylind_grid)
275 CALL polfixs(no,mo,km,rlat,ibo,lo,go)
278 END SUBROUTINE interpolate_neighbor_budget_scalar
281 SUBROUTINE interpolate_neighbor_budget_vector(IPOPT,grid_in,grid_out, &
282 MI,MO,KM,IBI,LI,UI,VI, &
283 NO,RLAT,RLON,CROT,SROT,IBO,LO,UO,VO,IRET)
426 class(ip_grid),
intent(in) :: grid_in, grid_out
428 INTEGER,
INTENT(IN ) :: IPOPT(20), IBI(KM)
429 INTEGER,
INTENT(IN ) :: KM, MI, MO
430 INTEGER,
INTENT( OUT) :: IRET, NO, IBO(KM)
432 LOGICAL*1,
INTENT(IN ) :: LI(MI,KM)
433 LOGICAL*1,
INTENT( OUT) :: LO(MO,KM)
435 REAL,
INTENT(IN ) :: UI(MI,KM),VI(MI,KM)
436 REAL,
INTENT(INOUT) :: RLAT(MO),RLON(MO)
437 REAL,
INTENT( OUT) :: UO(MO,KM),VO(MO,KM)
438 REAL,
INTENT( OUT) :: CROT(MO),SROT(MO)
440 REAL,
PARAMETER :: FILL=-9999.
443 INTEGER :: IB, JB, I1, J1
444 INTEGER :: K, LB, LSW, MP, N, NV
445 INTEGER :: NB, NB1, NB2, NB3, NB4
449 REAL :: C11(MO),S11(MO)
450 REAL :: CM11, SM11, PMP
451 REAL :: U11, V11, UROT, VROT
452 REAL :: WB, WO(MO,KM), XI, YI
453 REAL :: RLOB(MO),RLAB(MO)
454 REAL :: XPTS(MO),YPTS(MO)
455 REAL :: XPTB(MO),YPTB(MO)
457 logical :: to_station_points
460 INTEGER,
SAVE :: MIX=-1
461 REAL,
ALLOCATABLE,
SAVE :: CROI(:),SROI(:)
462 REAL,
ALLOCATABLE,
SAVE :: XPTI(:),YPTI(:)
463 REAL,
ALLOCATABLE,
SAVE :: RLOI(:),RLAI(:)
464 class(ip_grid),
allocatable,
save :: prev_grid_in
466 select type(grid_out)
467 type is(ip_station_points_grid)
468 to_station_points = .true.
470 to_station_points = .false.
476 IF(.not. to_station_points)
THEN
477 CALL gdswzd(grid_out, 0,mo,fill,xpts,ypts, &
478 rlon,rlat,no,crot,srot)
484 if (.not.
allocated(prev_grid_in))
then
485 allocate(prev_grid_in, source = grid_in)
489 same_grid = grid_in == prev_grid_in
491 if (.not. same_grid)
then
492 deallocate(prev_grid_in)
493 allocate(prev_grid_in, source = grid_in)
497 IF(.NOT.same_grid)
THEN
499 IF(mix.GE.0)
DEALLOCATE(xpti,ypti,rloi,rlai,croi,sroi)
500 ALLOCATE(xpti(mi),ypti(mi),rloi(mi),rlai(mi),croi(mi),sroi(mi))
503 CALL gdswzd(grid_in,0,mi,fill,xpti,ypti, &
504 rloi,rlai,nv,croi,sroi)
510 IF(iret.EQ.0.AND.nb1.LT.0) iret=32
512 IF(ipopt(1).EQ.-1.OR.ipopt(2).EQ.-1) lsw=0
513 IF(iret.EQ.0.AND.lsw.EQ.1.AND.nb1.GT.15) iret=32
515 IF(mp.EQ.-1.OR.mp.EQ.0) mp=50
516 IF(mp.LT.0.OR.mp.GT.100) iret=32
525 nb4=nb4+8*ib*ipopt(2+ib)
545 ib=nb-(jb+nb1)*nb2-nb1-1
546 lb=max(abs(ib),abs(jb))
548 IF(lsw.EQ.1) wb=ipopt(2+lb)
551 xptb(n)=xpts(n)+ib/real(nb2)
552 yptb(n)=ypts(n)+jb/real(nb2)
554 CALL gdswzd(grid_out, 1,no,fill,xptb,yptb, &
556 CALL gdswzd(grid_in,-1,no,fill,xptb,yptb, &
558 IF(iret.EQ.0.AND.nv.EQ.0.AND.lb.EQ.0) iret=2
562 IF(xi.NE.fill.AND.yi.NE.fill)
THEN
565 n11(n)=grid_in%field_pos(i1, j1)
567 CALL movect(rlai(n11(n)),rloi(n11(n)),rlat(n),rlon(n),cm11,sm11)
568 c11(n)=cm11*croi(n11(n))+sm11*sroi(n11(n))
569 s11(n)=sm11*croi(n11(n))-cm11*sroi(n11(n))
580 IF(ibi(k).EQ.0.OR.li(n11(n),k))
THEN
581 u11=c11(n)*ui(n11(n),k)-s11(n)*vi(n11(n),k)
582 v11=s11(n)*ui(n11(n),k)+c11(n)*vi(n11(n),k)
583 uo(n,k)=uo(n,k)+wb*u11
584 vo(n,k)=vo(n,k)+wb*v11
597 lo(n,k)=wo(n,k).GE.pmp*nb4
599 uo(n,k)=uo(n,k)/wo(n,k)
600 vo(n,k)=vo(n,k)/wo(n,k)
601 urot=crot(n)*uo(n,k)-srot(n)*vo(n,k)
602 vrot=srot(n)*uo(n,k)+crot(n)*vo(n,k)
613 select type(grid_out)
614 type is(ip_equid_cylind_grid)
615 CALL polfixv(no,mo,km,rlat,rlon,ibo,lo,uo,vo)
619 END SUBROUTINE interpolate_neighbor_budget_vector
621end module neighbor_budget_interp_mod
Driver module for gdswzd routines.