51 & LBi, UBi, LBj, UBj, UBk, &
52 & IminS, ImaxS, JminS, JmaxS, &
66 integer,
intent(in) :: ng, tile
67 integer,
intent(in) :: lbi, ubi, lbj, ubj, ubk
68 integer,
intent(in) :: imins, imaxs, jmins, jmaxs
69 integer,
intent(in) :: nstp, nout
72 real(r8),
intent(inout) :: v(lbi:,lbj:,:,:)
74 real(r8),
intent(inout) :: v(lbi:ubi,lbj:ubj,ubk,2)
82 real(r8),
parameter :: eps = 1.0e-20_r8
84 real(r8) :: ce, cx, cff, dvde, dvdt, dvdx
85 real(r8) :: obc_in, obc_out, phi, tau
87 real(r8),
dimension(IminS:ImaxS,JminS:JmaxS) :: grad
89# include "set_bounds.h"
95 IF (
domain(ng)%Southern_Edge(tile))
THEN
102 grad(i,jstr )=v(i ,jstr ,k,nstp)- &
103 & v(i-1,jstr ,k,nstp)
104 grad(i,jstr+1)=v(i ,jstr+1,k,nstp)- &
105 & v(i-1,jstr+1,k,nstp)
109 dvdt=v(i,jstr+1,k,nstp)-v(i,jstr+1,k,nout)
110 dvde=v(i,jstr+1,k,nout)-v(i,jstr+2,k,nout)
115 & (
clima(ng)%M3nudgcof(i,jstr-1,k)+ &
116 &
clima(ng)%M3nudgcof(i,jstr ,k))
117 obc_in =
obcfac(ng)*obc_out
122 IF ((dvdt*dvde).lt.0.0_r8)
THEN
127# ifdef IMPLICIT_NUDGING
128 IF (tau.gt.0.0_r8) tau=1.0_r8/tau
134 IF ((dvdt*dvde).lt.0.0_r8) dvdt=0.0_r8
135 IF ((dvdt*(grad(i ,jstr+1)+ &
136 & grad(i+1,jstr+1))).gt.0.0_r8)
THEN
139 dvdx=grad(i+1,jstr+1)
141 cff=max(dvdx*dvdx+dvde*dvde,eps)
143 cx=min(cff,max(dvdt*dvdx,-cff))
148# if defined CELERITY_WRITE && defined FORWARD_WRITE
153 v(i,jstr,k,nout)=(cff*v(i,jstr ,k,nstp)+ &
154 & ce *v(i,jstr+1,k,nout)- &
155 & max(cx,0.0_r8)*grad(i ,jstr)- &
156 & min(cx,0.0_r8)*grad(i+1,jstr))/ &
160# ifdef IMPLICIT_NUDGING
161 phi=
dt(ng)/(tau+
dt(ng))
162 v(i,jstr,k,nout)=(1.0_r8-phi)*v(i,jstr,k,nout)+ &
165 v(i,jstr,k,nout)=v(i,jstr,k,nout)+ &
171 v(i,jstr,k,nout)=v(i,jstr,k,nout)* &
172 &
grid(ng)%vmask(i,jstr)
175 v(i,jstr,k,nout)=v(i,jstr,k,nout)* &
176 &
grid(ng)%vmask_wet(i,jstr)
188 v(i,jstr,k,nout)=
boundary(ng)%v_south(i,k)
190 v(i,jstr,k,nout)=v(i,jstr,k,nout)* &
191 &
grid(ng)%vmask(i,jstr)
194 v(i,jstr,k,nout)=v(i,jstr,k,nout)* &
195 &
grid(ng)%vmask_wet(i,jstr)
207 v(i,jstr,k,nout)=v(i,jstr+1,k,nout)
209 v(i,jstr,k,nout)=v(i,jstr,k,nout)* &
210 &
grid(ng)%vmask(i,jstr)
213 v(i,jstr,k,nout)=v(i,jstr,k,nout)* &
214 &
grid(ng)%vmask_wet(i,jstr)
226 v(i,jstr,k,nout)=0.0_r8
237 IF (
domain(ng)%Northern_Edge(tile))
THEN
244 grad(i,jend )=v(i ,jend ,k,nstp)- &
245 & v(i-1,jend ,k,nstp)
246 grad(i,jend+1)=v(i ,jend+1,k,nstp)- &
247 & v(i-1,jend+1,k,nstp)
251 dvdt=v(i,jend,k,nstp)-v(i,jend ,k,nout)
252 dvde=v(i,jend,k,nout)-v(i,jend-1,k,nout)
257 & (
clima(ng)%M3nudgcof(i,jend ,k)+ &
258 &
clima(ng)%M3nudgcof(i,jend+1,k))
259 obc_in =
obcfac(ng)*obc_out
264 IF ((dvdt*dvde).lt.0.0_r8)
THEN
269# ifdef IMPLICIT_NUDGING
270 IF (tau.gt.0.0_r8) tau=1.0_r8/tau
276 IF ((dvdt*dvde).lt.0.0_r8) dvdt=0.0_r8
277 IF ((dvdt*(grad(i ,jend)+ &
278 & grad(i+1,jend))).gt.0.0_r8)
THEN
283 cff=max(dvdx*dvdx+dvde*dvde,eps)
285 cx=min(cff,max(dvdt*dvdx,-cff))
290# if defined CELERITY_WRITE && defined FORWARD_WRITE
295 v(i,jend+1,k,nout)=(cff*v(i,jend+1,k,nstp)+ &
296 & ce *v(i,jend ,k,nout)- &
297 & max(cx,0.0_r8)*grad(i ,jend+1)- &
298 & min(cx,0.0_r8)*grad(i+1,jend+1))/ &
302# ifdef IMPLICIT_NUDGING
303 phi=
dt(ng)/(tau+
dt(ng))
304 v(i,jend+1,k,nout)=(1.0_r8-phi)*v(i,jend+1,k,nout)+ &
307 v(i,jend+1,k,nout)=v(i,jend+1,k,nout)+ &
309 & v(i,jend+1,k,nstp))
313 v(i,jend+1,k,nout)=v(i,jend+1,k,nout)* &
314 &
grid(ng)%vmask(i,jend+1)
317 v(i,jend+1,k,nout)=v(i,jend+1,k,nout)* &
318 &
grid(ng)%vmask_wet(i,jend+1)
330 v(i,jend+1,k,nout)=
boundary(ng)%v_north(i,k)
332 v(i,jend+1,k,nout)=v(i,jend+1,k,nout)* &
333 &
grid(ng)%vmask(i,jend+1)
336 v(i,jend+1,k,nout)=v(i,jend+1,k,nout)* &
337 &
grid(ng)%vmask_wet(i,jend+1)
349 v(i,jend+1,k,nout)=v(i,jend,k,nout)
351 v(i,jend+1,k,nout)=v(i,jend+1,k,nout)* &
352 &
grid(ng)%vmask(i,jend+1)
355 v(i,jend+1,k,nout)=v(i,jend+1,k,nout)* &
356 &
grid(ng)%vmask_wet(i,jend+1)
368 v(i,jend+1,k,nout)=0.0_r8
379 IF (
domain(ng)%Western_Edge(tile))
THEN
386 grad(istr-1,j)=v(istr-1,j+1,k,nstp)- &
387 & v(istr-1,j ,k,nstp)
388 grad(istr ,j)=v(istr ,j+1,k,nstp)- &
393 dvdt=v(istr,j,k,nstp)-v(istr ,j,k,nout)
394 dvdx=v(istr,j,k,nout)-v(istr+1,j,k,nout)
399 & (
clima(ng)%M3nudgcof(istr-1,j-1,k)+ &
400 &
clima(ng)%M3nudgcof(istr-1,j ,k))
401 obc_in =
obcfac(ng)*obc_out
406 IF ((dvdt*dvdx).lt.0.0_r8)
THEN
411# ifdef IMPLICIT_NUDGING
412 IF (tau.gt.0.0_r8) tau=1.0_r8/tau
418 IF ((dvdt*dvdx).lt.0.0_r8) dvdt=0.0_r8
419 IF ((dvdt*(grad(istr,j-1)+ &
420 & grad(istr,j ))).gt.0.0_r8)
THEN
425 cff=max(dvdx*dvdx+dvde*dvde,eps)
428 ce=min(cff,max(dvdt*dvde,-cff))
432# if defined CELERITY_WRITE && defined FORWARD_WRITE
437 v(istr-1,j,k,nout)=(cff*v(istr-1,j,k,nstp)+ &
438 & cx *v(istr ,j,k,nout)- &
439 & max(ce,0.0_r8)*grad(istr-1,j-1)- &
440 & min(ce,0.0_r8)*grad(istr-1,j ))/ &
444# ifdef IMPLICIT_NUDGING
445 phi=
dt(ng)/(tau+
dt(ng))
446 v(istr-1,j,k,nout)=(1.0_r8-phi)*v(istr-1,j,k,nout)+ &
449 v(istr-1,j,k,nout)=v(istr-1,j,k,nout)+ &
451 & v(istr-1,j,k,nstp))
455 v(istr-1,j,k,nout)=v(istr-1,j,k,nout)* &
456 &
grid(ng)%vmask(istr-1,j)
459 v(istr-1,j,k,nout)=v(istr-1,j,k,nout)* &
460 &
grid(ng)%vmask_wet(istr-1,j)
472 v(istr-1,j,k,nout)=
boundary(ng)%v_west(j,k)
474 v(istr-1,j,k,nout)=v(istr-1,j,k,nout)* &
475 &
grid(ng)%vmask(istr-1,j)
478 v(istr-1,j,k,nout)=v(istr-1,j,k,nout)* &
479 &
grid(ng)%vmask_wet(istr-1,j)
491 v(istr-1,j,k,nout)=v(istr,j,k,nout)
493 v(istr-1,j,k,nout)=v(istr-1,j,k,nout)* &
494 &
grid(ng)%vmask(istr-1,j)
497 v(istr-1,j,k,nout)=v(istr-1,j,k,nout)* &
498 &
grid(ng)%vmask_wet(istr-1,j)
518 v(istr-1,j,k,nout)=
gamma2(ng)*v(istr,j,k,nout)
520 v(istr-1,j,k,nout)=v(istr-1,j,k,nout)* &
521 &
grid(ng)%vmask(istr-1,j)
524 v(istr-1,j,k,nout)=v(istr-1,j,k,nout)* &
525 &
grid(ng)%vmask_wet(istr-1,j)
537 IF (
domain(ng)%Eastern_Edge(tile))
THEN
544 grad(iend ,j)=v(iend ,j+1,k,nstp)- &
546 grad(iend+1,j)=v(iend+1,j+1,k,nstp)- &
547 & v(iend+1,j ,k,nstp)
551 dvdt=v(iend,j,k,nstp)-v(iend ,j,k,nout)
552 dvdx=v(iend,j,k,nout)-v(iend-1,j,k,nout)
557 & (
clima(ng)%M3nudgcof(iend+1,j-1,k)+ &
558 &
clima(ng)%M3nudgcof(iend+1,j ,k))
559 obc_in =
obcfac(ng)*obc_out
564 IF ((dvdt*dvdx).lt.0.0_r8)
THEN
569# ifdef IMPLICIT_NUDGING
570 IF (tau.gt.0.0_r8) tau=1.0_r8/tau
576 IF ((dvdt*dvdx).lt.0.0_r8) dvdt=0.0_r8
577 IF ((dvdt*(grad(iend,j-1)+ &
578 & grad(iend,j ))).gt.0.0_r8)
THEN
583 cff=max(dvdx*dvdx+dvde*dvde,eps)
586 ce=min(cff,max(dvdt*dvde,-cff))
590# if defined CELERITY_WRITE && defined FORWARD_WRITE
595 v(iend+1,j,k,nout)=(cff*v(iend+1,j,k,nstp)+ &
596 & cx *v(iend ,j,k,nout)- &
597 & max(ce,0.0_r8)*grad(iend+1,j-1)- &
598 & min(ce,0.0_r8)*grad(iend+1,j ))/ &
602# ifdef IMPLICIT_NUDGING
603 phi=
dt(ng)/(tau+
dt(ng))
604 v(iend+1,j,k,nout)=(1.0_r8-phi)*v(iend+1,j,k,nout)+ &
607 v(iend+1,j,k,nout)=v(iend+1,j,k,nout)+ &
609 & v(iend+1,j,k,nstp))
613 v(iend+1,j,k,nout)=v(iend+1,j,k,nout)* &
614 &
grid(ng)%vmask(iend+1,j)
617 v(iend+1,j,k,nout)=v(iend+1,j,k,nout)* &
618 &
grid(ng)%vmask_wet(iend+1,j)
630 v(iend+1,j,k,nout)=
boundary(ng)%v_east(j,k)
632 v(iend+1,j,k,nout)=v(iend+1,j,k,nout)* &
633 &
grid(ng)%vmask(iend+1,j)
636 v(iend+1,j,k,nout)=v(iend+1,j,k,nout)* &
637 &
grid(ng)%vmask_wet(iend+1,j)
649 v(iend+1,j,k,nout)=v(iend,j,k,nout)
651 v(iend+1,j,k,nout)=v(iend+1,j,k,nout)* &
652 &
grid(ng)%vmask(iend+1,j)
655 v(iend+1,j,k,nout)=v(iend+1,j,k,nout)* &
656 &
grid(ng)%vmask_wet(iend+1,j)
676 v(iend+1,j,k,nout)=
gamma2(ng)*v(iend,j,k,nout)
678 v(iend+1,j,k,nout)=v(iend+1,j,k,nout)* &
679 &
grid(ng)%vmask(iend+1,j)
682 v(iend+1,j,k,nout)=v(iend+1,j,k,nout)* &
683 &
grid(ng)%vmask_wet(iend+1,j)
696 IF (
domain(ng)%SouthWest_Corner(tile))
THEN
700 v(istr-1,jstr,k,nout)=0.5_r8*(v(istr ,jstr ,k,nout)+ &
701 & v(istr-1,jstr+1,k,nout))
705 IF (
domain(ng)%SouthEast_Corner(tile))
THEN
709 v(iend+1,jstr,k,nout)=0.5_r8*(v(iend ,jstr ,k,nout)+ &
710 & v(iend+1,jstr+1,k,nout))
714 IF (
domain(ng)%NorthWest_Corner(tile))
THEN
718 v(istr-1,jend+1,k,nout)=0.5_r8*(v(istr-1,jend ,k,nout)+ &
719 & v(istr ,jend+1,k,nout))
723 IF (
domain(ng)%NorthEast_Corner(tile))
THEN
727 v(iend+1,jend+1,k,nout)=0.5_r8*(v(iend+1,jend ,k,nout)+ &
728 & v(iend ,jend+1,k,nout))