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

Contents of /trunk/phylmd/yamada4.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 99 - (show annotations)
Wed Jul 2 18:39:15 2014 UTC (9 years, 10 months ago) by guez
File size: 11413 byte(s)
Created procedure test_disvert (following LMDZ). Added procedures
hybrid and funcd in module disvert_m. Upgraded compute_ab from
internal procedure of disvert to module procedure. Added variables y,
ya in module disvert_m. Upgraded s from local variable of procedure
disvert to module variable.

Renamed allowed value of variable vert_sampling in procedure disvert
from "read" to "read_hybrid". Added possibility to read pressure
values, value "read_pressure". Replaced vertical distribution for
value "param" by the distribution "strato_correct" from LMDZ (but kept
the value "param"). In case "tropo", replaced 1 by dsigmin (following
LMDZ). In case "strato", replaced 0.3 by dsigmin (following LMDZ).

Changed computation of bp in procedure compute_ab.

Removed debugindex case in clmain. Removed useless argument rlon of
procedure clmain. Removed useless variables ytaux, ytauy of procedure
clmain.

Removed intermediary variables tsol, qsol, tsolsrf, tslab in procedure
etat0.

Removed variable ok_veget:. coupling with the model Orchid is not
possible. Removed variable ocean: modeling an ocean slab is not
possible.

Removed useless variables tmp_rriv and tmp_rcoa from module
interface_surf.

Moved initialization of variables da, mp, phi in procedure physiq to
to inside the test iflag_con >= 3.

1 module yamada4_m
2
3 IMPLICIT NONE
4
5 real, parameter, private:: kap = 0.4
6
7 contains
8
9 SUBROUTINE yamada4(ngrid, dt, g, zlev, zlay, u, v, teta, cd, q2, km, kn, &
10 kq, ustar, iflag_pbl)
11
12 ! From LMDZ4/libf/phylmd/yamada4.F, version 1.1 2004/06/22 11:45:36
13
14 USE dimphy, ONLY : klev, klon
15
16 integer ngrid
17 REAL, intent(in):: dt ! pas de temps
18 real, intent(in):: g
19
20 REAL zlev(klon, klev+1)
21 ! altitude à chaque niveau (interface inférieure de la couche de
22 ! même indice)
23
24 REAL zlay(klon, klev) ! altitude au centre de chaque couche
25
26 REAL u(klon, klev), v(klon, klev)
27 ! vitesse au centre de chaque couche (en entrée : la valeur au
28 ! début du pas de temps)
29
30 REAL teta(klon, klev)
31 ! température potentielle au centre de chaque couche (en entrée :
32 ! la valeur au début du pas de temps)
33
34 REAL, intent(in):: cd(:) ! (ngrid) cdrag, valeur au début du pas de temps
35
36 REAL, intent(inout):: q2(klon, klev+1)
37 ! $q^2$ au bas de chaque couche
38 ! En entrée : la valeur au début du pas de temps ; en sortie : la
39 ! valeur à la fin du pas de temps.
40
41 REAL km(klon, klev+1)
42 ! diffusivité turbulente de quantité de mouvement (au bas de
43 ! chaque couche) (en sortie : la valeur à la fin du pas de temps)
44
45 REAL kn(klon, klev+1)
46 ! diffusivité turbulente des scalaires (au bas de chaque couche)
47 ! (en sortie : la valeur à la fin du pas de temps)
48
49 REAL kq(klon, klev+1)
50 real ustar(klon)
51
52 integer iflag_pbl
53 ! iflag_pbl doit valoir entre 6 et 9
54 ! l = 6, on prend systématiquement une longueur d'équilibre
55 ! iflag_pbl = 6 : MY 2.0
56 ! iflag_pbl = 7 : MY 2.0.Fournier
57 ! iflag_pbl = 8 : MY 2.5
58 ! iflag_pbl = 9 : un test ?
59
60 ! Local:
61
62 real kmin, qmin, pblhmin(klon), coriol(klon)
63 real qpre
64 REAL unsdz(klon, klev)
65 REAL unsdzdec(klon, klev+1)
66 REAL kmpre(klon, klev+1), tmp2
67 REAL mpre(klon, klev+1)
68 real delta(klon, klev+1)
69 real aa(klon, klev+1), aa0, aa1
70 integer, PARAMETER:: nlay = klev
71 integer, PARAMETER:: nlev = klev+1
72 logical:: first = .true.
73 integer:: ipas = 0
74 integer ig, k
75 real ri
76 real rif(klon, klev+1), sm(klon, klev+1), alpha(klon, klev)
77 real m2(klon, klev+1), dz(klon, klev+1), zq, n2(klon, klev+1)
78 real dtetadz(klon, klev+1)
79 real m2cstat, mcstat, kmcstat
80 real l(klon, klev+1)
81 real, save:: l0(klon)
82 real sq(klon), sqz(klon), zz(klon, klev+1)
83 integer iter
84 real:: ric = 0.195, rifc = 0.191, b1 = 16.6, kap = 0.4
85 real rino(klon, klev+1), smyam(klon, klev), styam(klon, klev)
86 real lyam(klon, klev), knyam(klon, klev)
87
88 !-----------------------------------------------------------------------
89
90 if (.not. (iflag_pbl >= 6 .and. iflag_pbl <= 9)) then
91 print *, 'probleme de coherence dans appel a MY'
92 stop 1
93 endif
94
95 ipas = ipas+1
96
97 ! les increments verticaux
98 DO ig = 1, ngrid
99 ! alerte: zlev n'est pas declare a nlev
100 zlev(ig, nlev) = zlay(ig, nlay) +(zlay(ig, nlay) - zlev(ig, nlev-1))
101 ENDDO
102
103 DO k = 1, nlay
104 DO ig = 1, ngrid
105 unsdz(ig, k) = 1.E+0/(zlev(ig, k+1)-zlev(ig, k))
106 ENDDO
107 ENDDO
108 DO ig = 1, ngrid
109 unsdzdec(ig, 1) = 1.E+0/(zlay(ig, 1)-zlev(ig, 1))
110 ENDDO
111 DO k = 2, nlay
112 DO ig = 1, ngrid
113 unsdzdec(ig, k) = 1.E+0/(zlay(ig, k)-zlay(ig, k-1))
114 ENDDO
115 ENDDO
116 DO ig = 1, ngrid
117 unsdzdec(ig, nlay+1) = 1.E+0/(zlev(ig, nlay+1)-zlay(ig, nlay))
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étermine l et q2 de façon itérative.
145 ! Itération pour déterminer la longueur de mélange
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 aa0 = (m2(ig, k)-alpha(ig, k)*n2(ig, k)-delta(ig, k)/b1)
267 aa1 = (m2(ig, k)*(1.-rif(ig, k))-delta(ig, k)/b1)
268 aa(ig, k) = aa1*dt/(delta(ig, k)*l(ig, k))
269 qpre = sqrt(q2(ig, k))
270 if (iflag_pbl == 8) then
271 if (aa(ig, k).gt.0.) then
272 q2(ig, k) = (qpre+aa(ig, k)*qpre*qpre)**2
273 else
274 q2(ig, k) = (qpre/(1.-aa(ig, k)*qpre))**2
275 endif
276 else
277 ! iflag_pbl = 9
278 if (aa(ig, k)*qpre.gt.0.9) then
279 q2(ig, k) = (qpre*10.)**2
280 else
281 q2(ig, k) = (qpre/(1.-aa(ig, k)*qpre))**2
282 endif
283 endif
284 q2(ig, k) = min(max(q2(ig, k), 1.e-10), 1.e4)
285 enddo
286 enddo
287 endif
288
289 ! Calcul des coefficients de mélange
290 do k = 2, klev
291 do ig = 1, ngrid
292 zq = sqrt(q2(ig, k))
293 km(ig, k) = l(ig, k)*zq*sm(ig, k)
294 kn(ig, k) = km(ig, k)*alpha(ig, k)
295 kq(ig, k) = l(ig, k)*zq*0.2
296 enddo
297 enddo
298
299 ! Traitement des cas noctrunes avec l'introduction d'une longueur
300 ! minilale.
301
302 ! Traitement particulier pour les cas tres stables.
303 ! D'apres Holtslag Boville.
304
305 do ig = 1, ngrid
306 coriol(ig) = 1.e-4
307 pblhmin(ig) = 0.07*ustar(ig)/max(abs(coriol(ig)), 2.546e-5)
308 enddo
309
310 print *, 'pblhmin ', pblhmin
311 do k = 2, klev
312 do ig = 1, klon
313 if (teta(ig, 2).gt.teta(ig, 1)) then
314 qmin = ustar(ig)*(max(1.-zlev(ig, k)/pblhmin(ig), 0.))**2
315 kmin = kap*zlev(ig, k)*qmin
316 else
317 kmin = -1. ! kmin n'est utilise que pour les SL stables.
318 endif
319 if (kn(ig, k).lt.kmin.or.km(ig, k).lt.kmin) then
320 kn(ig, k) = kmin
321 km(ig, k) = kmin
322 kq(ig, k) = kmin
323 ! la longueur de melange est suposee etre l = kap z
324 ! K = l q Sm d'ou q2 = (K/l Sm)**2
325 q2(ig, k) = (qmin/sm(ig, k))**2
326 endif
327 enddo
328 enddo
329
330 ! Diagnostique pour stokage
331
332 rino = rif
333 smyam(:, 1:klev) = sm(:, 1:klev)
334 styam = sm(:, 1:klev)*alpha(:, 1:klev)
335 lyam(1:klon, 1:klev) = l(:, 1:klev)
336 knyam(1:klon, 1:klev) = kn(:, 1:klev)
337
338 first = .false.
339
340 end SUBROUTINE yamada4
341
342 !*******************************************************************
343
344 real function frif(ri)
345
346 real, intent(in):: ri
347
348 frif = 0.6588*(ri+0.1776-sqrt(ri*ri-0.3221*ri+0.03156))
349
350 end function frif
351
352 !*******************************************************************
353
354 real function falpha(ri)
355
356 real, intent(in):: ri
357
358 falpha = 1.318*(0.2231-ri)/(0.2341-ri)
359
360 end function falpha
361
362 !*******************************************************************
363
364 real function fsm(ri)
365
366 real, intent(in):: ri
367
368 fsm = 1.96*(0.1912-ri)*(0.2341-ri)/((1.-ri)*(0.2231-ri))
369
370 end function fsm
371
372 !*******************************************************************
373
374 real function fl(zzz, zl0, zq2, zn2)
375
376 real, intent(in):: zzz, zl0, zq2, zn2
377
378 fl = max(min(zl0 * kap * zzz / (kap * zzz + zl0), &
379 0.5 * sqrt(zq2) / sqrt(max(zn2, 1e-10))), 1.)
380
381 end function fl
382
383 end module yamada4_m

  ViewVC Help
Powered by ViewVC 1.1.21