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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 229 - (hide annotations)
Mon Nov 6 17:20:45 2017 UTC (6 years, 6 months ago) by guez
File size: 10049 byte(s)
Use iflag_pbl from module conf_phys in yamada4 instead of getting it
as argument.

In clvent, simplifications using the fact that zx_alf2 = 0 and zx_alf1
= 1 (discarding the possibility to change this).

In physiq, no need for temporary variables z[uv]strph: compute actual
arguments of aaam_bud directly.

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

  ViewVC Help
Powered by ViewVC 1.1.21