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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 246 - (show annotations)
Wed Nov 15 13:56:45 2017 UTC (6 years, 5 months ago) by guez
File size: 9872 byte(s)
In procedure clmain, no need for intermediary variables ykmm and ykmn.

In module coefcdrag_m, remove unused procedures fsta and fins.

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

  ViewVC Help
Powered by ViewVC 1.1.21