/[lmdze]/trunk/Sources/phylmd/yamada4.f
ViewVC logotype

Contents of /trunk/Sources/phylmd/yamada4.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 196 - (show annotations)
Mon May 23 13:50:39 2016 UTC (8 years ago) by guez
File size: 11057 byte(s)
Removed argument icbmax of cv30_feed, not used in cv_driver (not used
in LMDZ either).

Clearer to have iflag1 = 0 in cv30_feed than in cv_driver. Clearer to
have iflag1 = 42 in cv30_uncompress than in cv_driver.

Removed argument iflag of cv30_compress. Since there is iflag1 = 42 in
cv30_uncompress, iflag1 that comes out of cv_driver is disconnected
from iflag1 computed by cv30_feed and cv30_trigger.

Removed some references to convect3 and convect4 in comments. This
program derives from the convect3 version, we do not need to know
about other versions.

Bug fix in cv30_undilute1: icbs1 was not made >= 2.

1 module yamada4_m
2
3 IMPLICIT NONE
4
5 private
6 public yamada4
7 real, parameter:: kap = 0.4
8
9 contains
10
11 SUBROUTINE yamada4(ngrid, dt, g, zlev, zlay, u, v, teta, cd, q2, km, kn, kq, &
12 ustar, iflag_pbl)
13
14 ! From LMDZ4/libf/phylmd/yamada4.F, version 1.1 2004/06/22 11:45:36
15
16 use nr_util, only: assert
17 USE dimphy, ONLY: klev
18
19 integer, intent(in):: ngrid
20 REAL, intent(in):: dt ! pas de temps
21 real, intent(in):: g
22
23 REAL zlev(ngrid, klev+1)
24 ! altitude \`a chaque niveau (interface inf\'erieure de la couche de
25 ! m\^eme indice)
26
27 REAL zlay(ngrid, klev) ! altitude au centre de chaque couche
28
29 REAL u(ngrid, klev), v(ngrid, klev)
30 ! vitesse au centre de chaque couche (en entr\'ee : la valeur au
31 ! d\'ebut du pas de temps)
32
33 REAL, intent(in):: teta(ngrid, klev)
34 ! temp\'erature potentielle au centre de chaque couche (en entr\'ee :
35 ! la valeur au d\'ebut du pas de temps)
36
37 REAL, intent(in):: cd(:) ! (ngrid) cdrag, valeur au d\'ebut du pas de temps
38
39 REAL, intent(inout):: q2(ngrid, klev+1)
40 ! $q^2$ au bas de chaque couche
41 ! En entr\'ee : la valeur au d\'ebut du pas de temps ; en sortie : la
42 ! valeur \`a la fin du pas de temps.
43
44 REAL km(ngrid, klev+1)
45 ! diffusivit\'e turbulente de quantit\'e de mouvement (au bas de
46 ! chaque couche) (en sortie : la valeur \`a la fin du pas de temps)
47
48 REAL kn(ngrid, klev+1)
49 ! diffusivit\'e turbulente des scalaires (au bas de chaque couche)
50 ! (en sortie : la valeur \`a la fin du pas de temps)
51
52 REAL kq(ngrid, klev+1)
53 real ustar(ngrid)
54
55 integer, intent(in):: iflag_pbl
56 ! iflag_pbl doit valoir entre 6 et 9
57 ! l = 6, on prend syst\'ematiquement une longueur d'\'equilibre
58 ! iflag_pbl = 6 : MY 2.0
59 ! iflag_pbl = 7 : MY 2.0.Fournier
60 ! iflag_pbl = 8 : MY 2.5
61 ! iflag_pbl = 9 : un test ?
62
63 ! Local:
64
65 real kmin, qmin, pblhmin(ngrid), coriol(ngrid)
66 real qpre
67 REAL unsdz(ngrid, klev)
68 REAL unsdzdec(ngrid, klev+1)
69 REAL kmpre(ngrid, klev+1), tmp2
70 REAL mpre(ngrid, klev+1)
71 real delta(ngrid, klev+1)
72 real aa(ngrid, klev+1), aa1
73 integer, PARAMETER:: nlev = klev+1
74 logical:: first = .true.
75 integer:: ipas = 0
76 integer ig, k
77 real ri
78 real rif(ngrid, klev+1), sm(ngrid, klev+1), alpha(ngrid, klev)
79 real m2(ngrid, klev+1), dz(ngrid, klev+1), zq, n2(ngrid, klev+1)
80 real dtetadz(ngrid, klev+1)
81 real m2cstat, mcstat, kmcstat
82 real l(ngrid, klev+1)
83 real l0(ngrid)
84 real sq(ngrid), sqz(ngrid), zz(ngrid, klev+1)
85 integer iter
86 real:: ric = 0.195, rifc = 0.191, b1 = 16.6
87
88 !-----------------------------------------------------------------------
89
90 call assert(iflag_pbl >= 6 .and. iflag_pbl <= 9, "yamada4")
91
92 ipas = ipas+1
93
94 ! les increments verticaux
95 DO ig = 1, ngrid
96 ! alerte: zlev n'est pas declare a nlev
97 zlev(ig, nlev) = zlay(ig, klev) +(zlay(ig, klev) - zlev(ig, nlev-1))
98 ENDDO
99
100 DO k = 1, klev
101 DO ig = 1, ngrid
102 unsdz(ig, k) = 1.E+0/(zlev(ig, k+1)-zlev(ig, k))
103 ENDDO
104 ENDDO
105
106 DO ig = 1, ngrid
107 unsdzdec(ig, 1) = 1.E+0/(zlay(ig, 1)-zlev(ig, 1))
108 ENDDO
109
110 DO k = 2, klev
111 DO ig = 1, ngrid
112 unsdzdec(ig, k) = 1.E+0/(zlay(ig, k)-zlay(ig, k-1))
113 ENDDO
114 ENDDO
115
116 DO ig = 1, ngrid
117 unsdzdec(ig, klev+1) = 1.E+0/(zlev(ig, klev+1)-zlay(ig, klev))
118 ENDDO
119
120 do k = 2, klev
121 do ig = 1, ngrid
122 dz(ig, k) = zlay(ig, k)-zlay(ig, k-1)
123 m2(ig, k) = ((u(ig, k)-u(ig, k-1))**2+(v(ig, k)-v(ig, k-1))**2) &
124 /(dz(ig, k)*dz(ig, k))
125 dtetadz(ig, k) = (teta(ig, k)-teta(ig, k-1))/dz(ig, k)
126 n2(ig, k) = g*2.*dtetadz(ig, k)/(teta(ig, k-1)+teta(ig, k))
127 ri = n2(ig, k)/max(m2(ig, k), 1.e-10)
128 if (ri.lt.ric) then
129 rif(ig, k) = frif(ri)
130 else
131 rif(ig, k) = rifc
132 endif
133 if (rif(ig, k).lt.0.16) then
134 alpha(ig, k) = falpha(rif(ig, k))
135 sm(ig, k) = fsm(rif(ig, k))
136 else
137 alpha(ig, k) = 1.12
138 sm(ig, k) = 0.085
139 endif
140 zz(ig, k) = b1*m2(ig, k)*(1.-rif(ig, k))*sm(ig, k)
141 enddo
142 enddo
143
144 ! Au premier appel, on d\'etermine l et q2 de fa\ccon it\'erative.
145 ! It\'eration pour d\'eterminer la longueur de m\'elange
146
147 if (first .or. iflag_pbl == 6) then
148 do ig = 1, ngrid
149 l0(ig) = 10.
150 enddo
151 do k = 2, klev-1
152 do ig = 1, ngrid
153 l(ig, k) = l0(ig) * kap * zlev(ig, k) &
154 / (kap * zlev(ig, k) + l0(ig))
155 enddo
156 enddo
157
158 do iter = 1, 10
159 do ig = 1, ngrid
160 sq(ig) = 1e-10
161 sqz(ig) = 1e-10
162 enddo
163 do k = 2, klev-1
164 do ig = 1, ngrid
165 q2(ig, k) = l(ig, k)**2 * zz(ig, k)
166 l(ig, k) = fl(zlev(ig, k), l0(ig), q2(ig, k), n2(ig, k))
167 zq = sqrt(q2(ig, k))
168 sqz(ig) = sqz(ig) + zq * zlev(ig, k) &
169 * (zlay(ig, k) - zlay(ig, k-1))
170 sq(ig) = sq(ig) + zq * (zlay(ig, k) - zlay(ig, k-1))
171 enddo
172 enddo
173 do ig = 1, ngrid
174 l0(ig) = 0.2 * sqz(ig) / sq(ig)
175 enddo
176 enddo
177 endif
178
179 ! Calcul de la longueur de melange.
180
181 ! Mise a jour de l0
182 do ig = 1, ngrid
183 sq(ig) = 1.e-10
184 sqz(ig) = 1.e-10
185 enddo
186 do k = 2, klev-1
187 do ig = 1, ngrid
188 zq = sqrt(q2(ig, k))
189 sqz(ig) = sqz(ig)+zq*zlev(ig, k)*(zlay(ig, k)-zlay(ig, k-1))
190 sq(ig) = sq(ig)+zq*(zlay(ig, k)-zlay(ig, k-1))
191 enddo
192 enddo
193 do ig = 1, ngrid
194 l0(ig) = 0.2*sqz(ig)/sq(ig)
195 enddo
196 ! calcul de l(z)
197 do k = 2, klev
198 do ig = 1, ngrid
199 l(ig, k) = fl(zlev(ig, k), l0(ig), q2(ig, k), n2(ig, k))
200 if (first) then
201 q2(ig, k) = l(ig, k)**2 * zz(ig, k)
202 endif
203 enddo
204 enddo
205
206 ! Yamada 2.0
207 if (iflag_pbl == 6) then
208 do k = 2, klev
209 do ig = 1, ngrid
210 q2(ig, k) = l(ig, k)**2 * zz(ig, k)
211 enddo
212 enddo
213 else if (iflag_pbl == 7) then
214 ! Yamada 2.Fournier
215
216 ! Calcul de l, km, au pas precedent
217 do k = 2, klev
218 do ig = 1, ngrid
219 delta(ig, k) = q2(ig, k) / (l(ig, k)**2 * sm(ig, k))
220 kmpre(ig, k) = l(ig, k) * sqrt(q2(ig, k)) * sm(ig, k)
221 mpre(ig, k) = sqrt(m2(ig, k))
222 enddo
223 enddo
224
225 do k = 2, klev-1
226 do ig = 1, ngrid
227 m2cstat = max(alpha(ig, k)*n2(ig, k)+delta(ig, k)/b1, 1.e-12)
228 mcstat = sqrt(m2cstat)
229
230 ! puis on ecrit la valeur de q qui annule l'equation de m
231 ! supposee en q3
232
233 IF (k == 2) THEN
234 kmcstat = 1.E+0 / mcstat &
235 *(unsdz(ig, k)*kmpre(ig, k+1) &
236 *mpre(ig, k+1) &
237 +unsdz(ig, k-1) &
238 *cd(ig) &
239 *(sqrt(u(ig, 3)**2+v(ig, 3)**2) &
240 -mcstat/unsdzdec(ig, k) &
241 -mpre(ig, k+1)/unsdzdec(ig, k+1))**2) &
242 /(unsdz(ig, k)+unsdz(ig, k-1))
243 ELSE
244 kmcstat = 1.E+0 / mcstat &
245 *(unsdz(ig, k)*kmpre(ig, k+1) &
246 *mpre(ig, k+1) &
247 +unsdz(ig, k-1)*kmpre(ig, k-1) &
248 *mpre(ig, k-1)) &
249 /(unsdz(ig, k)+unsdz(ig, k-1))
250 ENDIF
251 tmp2 = kmcstat / (sm(ig, k) / q2(ig, k)) /l(ig, k)
252 q2(ig, k) = max(tmp2, 1.e-12)**(2./3.)
253 enddo
254 enddo
255 else if (iflag_pbl >= 8) then
256 ! Yamada 2.5 a la Didi
257
258 ! Calcul de l, km, au pas precedent
259 do k = 2, klev
260 do ig = 1, ngrid
261 delta(ig, k) = q2(ig, k)/(l(ig, k)**2*sm(ig, k))
262 if (delta(ig, k).lt.1.e-20) then
263 delta(ig, k) = 1.e-20
264 endif
265 km(ig, k) = l(ig, k)*sqrt(q2(ig, k))*sm(ig, k)
266 aa1 = (m2(ig, k)*(1.-rif(ig, k))-delta(ig, k)/b1)
267 aa(ig, k) = aa1*dt/(delta(ig, k)*l(ig, k))
268 qpre = sqrt(q2(ig, k))
269 if (iflag_pbl == 8) then
270 if (aa(ig, k).gt.0.) then
271 q2(ig, k) = (qpre+aa(ig, k)*qpre*qpre)**2
272 else
273 q2(ig, k) = (qpre/(1.-aa(ig, k)*qpre))**2
274 endif
275 else
276 ! iflag_pbl = 9
277 if (aa(ig, k)*qpre.gt.0.9) then
278 q2(ig, k) = (qpre*10.)**2
279 else
280 q2(ig, k) = (qpre/(1.-aa(ig, k)*qpre))**2
281 endif
282 endif
283 q2(ig, k) = min(max(q2(ig, k), 1.e-10), 1.e4)
284 enddo
285 enddo
286 endif
287
288 ! Calcul des coefficients de m\'elange
289 do k = 2, klev
290 do ig = 1, ngrid
291 zq = sqrt(q2(ig, k))
292 km(ig, k) = l(ig, k)*zq*sm(ig, k)
293 kn(ig, k) = km(ig, k)*alpha(ig, k)
294 kq(ig, k) = l(ig, k)*zq*0.2
295 enddo
296 enddo
297
298 ! Traitement des cas noctrunes avec l'introduction d'une longueur
299 ! minilale.
300
301 ! Traitement particulier pour les cas tres stables.
302 ! D'apres Holtslag Boville.
303
304 do ig = 1, ngrid
305 coriol(ig) = 1.e-4
306 pblhmin(ig) = 0.07*ustar(ig)/max(abs(coriol(ig)), 2.546e-5)
307 enddo
308
309 print *, 'pblhmin ', pblhmin
310 do k = 2, klev
311 do ig = 1, ngrid
312 if (teta(ig, 2).gt.teta(ig, 1)) then
313 qmin = ustar(ig)*(max(1.-zlev(ig, k)/pblhmin(ig), 0.))**2
314 kmin = kap*zlev(ig, k)*qmin
315 else
316 kmin = -1. ! kmin n'est utilise que pour les SL stables.
317 endif
318 if (kn(ig, k).lt.kmin.or.km(ig, k).lt.kmin) then
319 kn(ig, k) = kmin
320 km(ig, k) = kmin
321 kq(ig, k) = kmin
322 ! la longueur de melange est suposee etre l = kap z
323 ! K = l q Sm d'ou q2 = (K/l Sm)**2
324 q2(ig, k) = (qmin/sm(ig, k))**2
325 endif
326 enddo
327 enddo
328
329 first = .false.
330
331 end SUBROUTINE yamada4
332
333 !*******************************************************************
334
335 real function frif(ri)
336
337 real, intent(in):: ri
338
339 frif = 0.6588*(ri+0.1776-sqrt(ri*ri-0.3221*ri+0.03156))
340
341 end function frif
342
343 !*******************************************************************
344
345 real function falpha(ri)
346
347 real, intent(in):: ri
348
349 falpha = 1.318*(0.2231-ri)/(0.2341-ri)
350
351 end function falpha
352
353 !*******************************************************************
354
355 real function fsm(ri)
356
357 real, intent(in):: ri
358
359 fsm = 1.96*(0.1912-ri)*(0.2341-ri)/((1.-ri)*(0.2231-ri))
360
361 end function fsm
362
363 !*******************************************************************
364
365 real function fl(zzz, zl0, zq2, zn2)
366
367 real, intent(in):: zzz, zl0, zq2, zn2
368
369 fl = max(min(zl0 * kap * zzz / (kap * zzz + zl0), &
370 0.5 * sqrt(zq2) / sqrt(max(zn2, 1e-10))), 1.)
371
372 end function fl
373
374 end module yamada4_m

  ViewVC Help
Powered by ViewVC 1.1.21