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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 302 - (hide annotations)
Thu Sep 6 13:19:51 2018 UTC (5 years, 9 months ago) by guez
File size: 9928 byte(s)
In procedure physiq, rename dsens and devap to dflux_t and dflux_q so
they correspond to arguments with the same name in pbl_surface. (In
LMDZ, dsens and devap are not used in physiq, the computation of fder
is done inside pbl_surface.)

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

  ViewVC Help
Powered by ViewVC 1.1.21