47
48
52
53
54
55 integer, intent(in) :: ng, tile
56 integer, intent(in) :: LBi, UBi, LBj, UBj
57 integer, intent(in) :: IminS, ImaxS, JminS, JmaxS
58
59# ifdef ASSUMED_SHAPE
60# ifdef MASKING
61 real(r8), intent(in) :: rmask(LBi:,LBj:)
62 real(r8), intent(in) :: umask(LBi:,LBj:)
63 real(r8), intent(in) :: vmask(LBi:,LBj:)
64# endif
65# ifdef WET_DRY
66 real(r8), intent(in) :: rmask_wet(LBi:,LBj:)
67 real(r8), intent(in) :: umask_wet(LBi:,LBj:)
68 real(r8), intent(in) :: vmask_wet(LBi:,LBj:)
69# endif
70 real(r8), intent(in) :: pm(LBi:,LBj:)
71 real(r8), intent(in) :: pn(LBi:,LBj:)
72 real(r8), intent(in) :: Huon(LBi:,LBj:)
73 real(r8), intent(in) :: Hvom(LBi:,LBj:)
74 real(r8), intent(in) :: oHz(IminS:,JminS:)
75 real(r8), intent(in) :: t(LBi:,LBj:)
76 real(r8), intent(out) :: FX(IminS:,JminS:)
77 real(r8), intent(out) :: FE(IminS:,JminS:)
78# else
79# ifdef MASKING
80 real(r8), intent(in) :: rmask(LBi:UBi,LBj:UBj)
81 real(r8), intent(in) :: umask(LBi:UBi,LBj:UBj)
82 real(r8), intent(in) :: vmask(LBi:UBi,LBj:UBj)
83# endif
84# ifdef WET_DRY
85 real(r8), intent(in) :: rmask_wet(LBi:UBi,LBj:UBj)
86 real(r8), intent(in) :: umask_wet(LBi:UBi,LBj:UBj)
87 real(r8), intent(in) :: vmask_wet(LBi:UBi,LBj:UBj)
88# endif
89 real(r8), intent(in) :: pm(LBi:UBi,LBj:UBj)
90 real(r8), intent(in) :: pn(LBi:UBi,LBj:UBj)
91 real(r8), intent(in) :: Huon(LBi:UBi,LBj:UBj)
92 real(r8), intent(in) :: Hvom(LBi:UBi,LBj:UBj)
93 real(r8), intent(in) :: oHz(IminS:ImaxS,JminS:JmaxS)
94 real(r8), intent(in) :: t(LBi:UBi,LBj:UBj)
95 real(r8), intent(out) :: FX(IminS:ImaxS,JminS:JmaxS)
96 real(r8), intent(out) :: FE(IminS:ImaxS,JminS:JmaxS)
97# endif
98
99
100
101 integer :: i, is, j, k, ii, jj
102
103 real(r8) :: cc1 = 0.25_r8
104 real(r8) :: cc2 = 0.5_r8
105 real(r8) :: cc3 = 1.0_r8/12.0_r8
106 real(r8) :: eps1 = 1.0e-12_r8
107
108 real(r8) :: cff, cff1
109 real(r8) :: betaL, betaR, betaD, betaU
110 real(r8) :: rL, rR, rD, rU, rkaL, rkaR, rkaD, rkaU
111 real(r8) :: a1, b1, sw_eta, sw_xi
112
113 real(r8), dimension(IminS:ImaxS) :: gradX, KaX, oKaX
114 real(r8), dimension(JminS:JmaxS) :: gradE, KaE, oKaE
115
116# include "set_bounds.h"
117
118
119
120
121
122
123 DO j=jstr,jend
124 DO i=istru-1,iendp2
125 cff=0.125_r8*(pm(i-1,j)+pm(i,j))*(pn(i-1,j)+pn(i,j))*
dt(ng)
126 cff1=cff*(ohz(i-1,j)+ohz(i,j))
127 gradx(i)=t(i,j)-t(i-1,j)
128 kax(i)=1.0_r8-abs(huon(i,j)*cff1)
129# ifdef MASKING
130 gradx(i)=gradx(i)*umask(i,j)
131 kax(i)=kax(i)*umask(i,j)
132# endif
133 END DO
135 IF (
domain(ng)%Western_Edge(tile))
THEN
136 IF (huon(istr,j).ge.0.0_r8) THEN
137 gradx(istr-1)=0.0_r8
138 kax(istr-1)=0.0_r8
139 END IF
140 END IF
141 IF (
domain(ng)%Eastern_Edge(tile))
THEN
142 IF (huon(iend+1,j).lt.0.0_r8) THEN
143 gradx(iend+2)=0.0_r8
144 kax(iend+2)=0.0_r8
145 END IF
146 END IF
147 END IF
148 DO i=istr,iend+1
149 IF (kax(i).le.eps1) THEN
150 okax(i)=0.0_r8
151 ELSE
152 okax(i)=1.0_r8/max(kax(i),eps1)
153 END IF
154 IF (huon(i,j).ge.0.0_r8) THEN
155 IF (abs(gradx(i)).le.eps1) THEN
156 rl=0.0_r8
157 rkal=0.0_r8
158 ELSE
159 rl=gradx(i-1)/gradx(i)
160 rkal=kax(i-1)*okax(i)
161 END IF
164 betal=a1+b1*rl
165 cff=0.5_r8*max(0.0_r8, &
166 & min(2.0_r8, 2.0_r8*rl*rkal, betal))* &
167 & gradx(i)*kax(i)
168# ifdef MASKING
169 ii=max(i-2,0)
170 cff=cff*rmask(ii,j)
171# endif
172 sw_xi=t(i-1,j)+cff
173 ELSE
174 IF (abs(gradx(i)).le.eps1) THEN
175 rr=0.0_r8
176 rkar=0.0_r8
177 ELSE
178 rr=gradx(i+1)/gradx(i)
179 rkar=kax(i+1)*okax(i)
180 END IF
183 betar=a1+b1*rr
184 cff=0.5_r8*max(0.0_r8, &
185 & min(2.0_r8, 2.0_r8*rr*rkar, betar))* &
186 & gradx(i)*kax(i)
187# ifdef MASKING
189 cff=cff*rmask(ii,j)
190# endif
191 sw_xi=t(i,j)-cff
192 END IF
193 fx(i,j)=sw_xi*huon(i,j)
194 END DO
195 END DO
196
197 DO i=istr,iend
198 DO j=jstrv-1,jendp2
199 cff=0.125_r8*(pn(i,j)+pn(i,j-1))*(pm(i,j)+pm(i,j-1))*
dt(ng)
200 cff1=cff*(ohz(i,j)+ohz(i,j-1))
201 grade(j)=t(i,j)-t(i,j-1)
202 kae(j)=1.0_r8-abs(hvom(i,j)*cff1)
203# ifdef MASKING
204 grade(j)=grade(j)*vmask(i,j)
205 kae(j)=kae(j)*vmask(i,j)
206# endif
207 END DO
209 IF (
domain(ng)%Southern_Edge(tile))
THEN
210 IF (hvom(i,jstr).ge.0.0_r8) THEN
211 grade(jstr-1)=0.0_r8
212 kae(jstr-1)=0.0_r8
213 END IF
214 END IF
215 IF (
domain(ng)%Northern_Edge(tile))
THEN
216 IF (hvom(i,jend+1).lt.0.0_r8) THEN
217 grade(jend+2)=0.0_r8
218 kae(jend+2)=0.0_r8
219 END IF
220 END IF
221 END IF
222 DO j=jstr,jend+1
223 IF (kae(j).le.eps1) THEN
224 okae(j)=0.0_r8
225 ELSE
226 okae(j)=1.0_r8/max(kae(j),eps1)
227 END IF
228 IF (hvom(i,j).ge.0.0_r8) THEN
229 IF (abs(grade(j)).le.eps1) THEN
230 rd=0.0_r8
231 rkad=0.0_r8
232 ELSE
233 rd=grade(j-1)/grade(j)
234 rkad=kae(j-1)*okae(j)
235 END IF
238 betad=a1+b1*rd
239 cff=0.5_r8*max(0.0_r8, &
240 & min(2.0_r8, 2.0_r8*rd*rkad, betad))* &
241 & grade(j)*kae(j)
242# ifdef MASKING
243 jj=max(j-2,0)
244 cff=cff*rmask(i,jj)
245# endif
246 sw_eta=t(i,j-1)+cff
247 ELSE
248 IF (abs(grade(j)).le.eps1) THEN
249 ru=0.0_r8
250 rkau=0.0_r8
251 ELSE
252 ru=grade(j+1)/grade(j)
253 rkau=kae(j+1)*okae(j)
254 END IF
257 betau=a1+b1*ru
258 cff=0.5*max(0.0_r8, &
259 & min(2.0_r8, 2.0_r8*ru*rkau, betau))* &
260 & grade(j)*kae(j)
261# ifdef MASKING
263 cff=cff*rmask(i,jj)
264# endif
265 sw_eta=t(i,j)-cff
266 END IF
267 fe(i,j)=sw_eta*hvom(i,j)
268 END DO
269 END DO
270
271 RETURN
type(t_domain), dimension(:), allocatable domain
integer, dimension(:), allocatable lm
integer, dimension(:), allocatable mm
real(dp), dimension(:), allocatable dt
logical, dimension(:), allocatable ewperiodic
logical, dimension(:), allocatable nsperiodic