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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 238 - (hide annotations)
Thu Nov 9 14:11:39 2017 UTC (6 years, 6 months ago) by guez
File size: 9844 byte(s)
In procedure clmain, remove local variable ykmq, not used (not used in
LMDZ either). Remove its computation in yamada4.

In procedure yamada4, remove dummy argument cd, not used.

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 238 SUBROUTINE yamada4(dt, g, zlev, zlay, u, v, teta, q2, km, kn, 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(inout):: q2(:, :) ! (knon, klev + 1)
38 guez 47 ! $q^2$ au bas de chaque couche
39 guez 178 ! 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 guez 3
42 guez 227 REAL km(:, :) ! (knon, klev + 1)
43 guez 178 ! 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 guez 3
46 guez 227 REAL kn(:, :) ! (knon, klev + 1)
47 guez 178 ! diffusivit\'e turbulente des scalaires (au bas de chaque couche)
48     ! (en sortie : la valeur \`a la fin du pas de temps)
49 guez 3
50 guez 227 real, intent(in):: ustar(:) ! (knon)
51 guez 3
52 guez 47 ! Local:
53 guez 227 integer knon
54     real kmin, qmin
55 guez 238 real pblhmin(size(ustar)), coriol(size(ustar)) ! (knon)
56 guez 47 real qpre
57 guez 227 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 guez 47 logical:: first = .true.
63     integer:: ipas = 0
64     integer ig, k
65     real ri
66 guez 227 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 guez 238 real l0(size(ustar)) ! (knon)
76     real sq(size(ustar)), sqz(size(ustar)) ! (knon)
77 guez 227 real zz(size(zlev, 1), size(zlev, 2)) ! (knon, klev + 1)
78 guez 47 integer iter
79 guez 196 real:: ric = 0.195, rifc = 0.191, b1 = 16.6
80 guez 3
81 guez 47 !-----------------------------------------------------------------------
82 guez 3
83 guez 228 call assert(any(iflag_pbl == [6, 8, 9]), "yamada4 iflag_pbl")
84 guez 227 knon = assert_eq([size(zlev, 1), size(zlay, 1), size(u, 1), size(v, 1), &
85 guez 238 size(teta, 1), size(ustar), size(q2, 1), size(km, 1), size(kn, 1)], &
86     "yamada4 knon")
87 guez 227 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 guez 238 size(kn, 2) - 1], "yamada4 klev")
90 guez 3
91 guez 227 ipas = ipas + 1
92 guez 3
93 guez 47 ! les increments verticaux
94 guez 227 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 guez 47 ENDDO
98 guez 3
99 guez 118 DO k = 1, klev
100 guez 227 DO ig = 1, knon
101     unsdz(ig, k) = 1.E+0/(zlev(ig, k + 1)-zlev(ig, k))
102 guez 47 ENDDO
103     ENDDO
104 guez 118
105 guez 227 DO ig = 1, knon
106 guez 47 unsdzdec(ig, 1) = 1.E+0/(zlay(ig, 1)-zlev(ig, 1))
107     ENDDO
108 guez 118
109     DO k = 2, klev
110 guez 227 DO ig = 1, knon
111 guez 47 unsdzdec(ig, k) = 1.E+0/(zlay(ig, k)-zlay(ig, k-1))
112     ENDDO
113     ENDDO
114 guez 118
115 guez 227 DO ig = 1, knon
116     unsdzdec(ig, klev + 1) = 1.E+0/(zlev(ig, klev + 1)-zlay(ig, klev))
117 guez 47 ENDDO
118 guez 3
119 guez 47 do k = 2, klev
120 guez 227 do ig = 1, knon
121 guez 47 dz(ig, k) = zlay(ig, k)-zlay(ig, k-1)
122 guez 227 m2(ig, k) = ((u(ig, k)-u(ig, k-1))**2 + (v(ig, k)-v(ig, k-1))**2) &
123 guez 47 /(dz(ig, k)*dz(ig, k))
124     dtetadz(ig, k) = (teta(ig, k)-teta(ig, k-1))/dz(ig, k)
125 guez 227 n2(ig, k) = g*2.*dtetadz(ig, k)/(teta(ig, k-1) + teta(ig, k))
126 guez 47 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 guez 119 if (rif(ig, k).lt.0.16) then
133 guez 47 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 guez 3
143 guez 196 ! Au premier appel, on d\'etermine l et q2 de fa\ccon it\'erative.
144 guez 178 ! It\'eration pour d\'eterminer la longueur de m\'elange
145 guez 3
146 guez 47 if (first .or. iflag_pbl == 6) then
147 guez 227 do ig = 1, knon
148 guez 47 l0(ig) = 10.
149     enddo
150     do k = 2, klev-1
151 guez 227 do ig = 1, knon
152 guez 47 l(ig, k) = l0(ig) * kap * zlev(ig, k) &
153     / (kap * zlev(ig, k) + l0(ig))
154     enddo
155     enddo
156 guez 3
157 guez 47 do iter = 1, 10
158 guez 227 do ig = 1, knon
159 guez 47 sq(ig) = 1e-10
160     sqz(ig) = 1e-10
161     enddo
162     do k = 2, klev-1
163 guez 227 do ig = 1, knon
164 guez 47 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 guez 227 do ig = 1, knon
173 guez 47 l0(ig) = 0.2 * sqz(ig) / sq(ig)
174     enddo
175     enddo
176     endif
177 guez 3
178 guez 47 ! Calcul de la longueur de melange.
179 guez 3
180 guez 47 ! Mise a jour de l0
181 guez 227 do ig = 1, knon
182 guez 47 sq(ig) = 1.e-10
183     sqz(ig) = 1.e-10
184     enddo
185     do k = 2, klev-1
186 guez 227 do ig = 1, knon
187 guez 47 zq = sqrt(q2(ig, k))
188 guez 227 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 guez 47 enddo
191     enddo
192 guez 227 do ig = 1, knon
193 guez 47 l0(ig) = 0.2*sqz(ig)/sq(ig)
194     enddo
195     ! calcul de l(z)
196     do k = 2, klev
197 guez 227 do ig = 1, knon
198 guez 47 l(ig, k) = fl(zlev(ig, k), l0(ig), q2(ig, k), n2(ig, k))
199 guez 119 if (first) then
200 guez 47 q2(ig, k) = l(ig, k)**2 * zz(ig, k)
201     endif
202     enddo
203     enddo
204 guez 3
205 guez 47 if (iflag_pbl == 6) then
206 guez 228 ! Yamada 2.0
207 guez 47 do k = 2, klev
208 guez 227 do ig = 1, knon
209 guez 47 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 guez 3
215 guez 47 ! Calcul de l, km, au pas precedent
216     do k = 2, klev
217 guez 227 do ig = 1, knon
218 guez 47 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 guez 227 q2(ig, k) = (qpre + aa(ig, k)*qpre*qpre)**2
229 guez 47 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 guez 3
245 guez 178 ! Calcul des coefficients de m\'elange
246 guez 47 do k = 2, klev
247 guez 227 do ig = 1, knon
248 guez 47 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 guez 3
254 guez 47 ! Traitement des cas noctrunes avec l'introduction d'une longueur
255     ! minilale.
256 guez 3
257 guez 47 ! Traitement particulier pour les cas tres stables.
258     ! D'apres Holtslag Boville.
259 guez 3
260 guez 227 do ig = 1, knon
261 guez 47 coriol(ig) = 1.e-4
262     pblhmin(ig) = 0.07*ustar(ig)/max(abs(coriol(ig)), 2.546e-5)
263     enddo
264 guez 3
265 guez 47 do k = 2, klev
266 guez 227 do ig = 1, knon
267 guez 47 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 guez 3
283 guez 47 first = .false.
284 guez 3
285 guez 47 end SUBROUTINE yamada4
286 guez 3
287 guez 47 !*******************************************************************
288 guez 3
289 guez 62 real function frif(ri)
290 guez 3
291 guez 47 real, intent(in):: ri
292 guez 3
293 guez 227 frif = 0.6588*(ri + 0.1776-sqrt(ri*ri-0.3221*ri + 0.03156))
294 guez 3
295 guez 47 end function frif
296 guez 3
297 guez 47 !*******************************************************************
298 guez 3
299 guez 62 real function falpha(ri)
300 guez 3
301 guez 47 real, intent(in):: ri
302 guez 3
303 guez 47 falpha = 1.318*(0.2231-ri)/(0.2341-ri)
304 guez 3
305 guez 47 end function falpha
306    
307     !*******************************************************************
308    
309 guez 62 real function fsm(ri)
310 guez 47
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 guez 62 real function fl(zzz, zl0, zq2, zn2)
320 guez 47
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