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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 118 - (hide annotations)
Thu Dec 18 17:30:24 2014 UTC (9 years, 5 months ago) by guez
Original Path: trunk/phylmd/yamada4.f
File size: 11368 byte(s)
In file grilles_gcm.nc, renamed variable phis to orog, deleted
variable presnivs.

Removed variable bug_ozone from module clesphys.

In procedure ozonecm, moved computation of sint and cost out of the
loops on horizontal position and vertical level. Inverted the order of
the two loops. We can then move all computations from slat to aprim
out of the loop on vertical levels. Created variable slat2, following
LMDZ. Moved the limitation of column-density of ozone in cell at 1e-12
from radlwsw to ozonecm, following LMDZ.

Removed unused arguments u, albsol, rh, cldfra, rneb, diafra, cldliq,
pmflxr, pmflxs, prfl, psfl of phytrac.

In procedure yamada4, for all the arrays, replaced the dimension klon
by ngrid. At the end of the procedure, for the computation of kmn,kn,
kq and q2, changed the upper limit of the loop index from klon to ngrid.

In radlwsw, for the calculation of pozon, removed the factor
paprs(iof+i, 1)/101325, as in LMDZ. In procedure sw, removed the
factor 101325.0/PPSOL(JL), as in LMDZ.

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 118 SUBROUTINE yamada4(ngrid, dt, g, zlev, zlay, u, v, teta, cd, q2, km, kn, kq, &
12     ustar, iflag_pbl)
13 guez 3
14 guez 47 ! From LMDZ4/libf/phylmd/yamada4.F, version 1.1 2004/06/22 11:45:36
15 guez 3
16 guez 118 use nr_util, only: assert
17     USE dimphy, ONLY: klev
18 guez 3
19 guez 118 integer, intent(in):: ngrid
20 guez 47 REAL, intent(in):: dt ! pas de temps
21     real, intent(in):: g
22 guez 3
23 guez 118 REAL zlev(ngrid, klev+1)
24 guez 47 ! altitude à chaque niveau (interface inférieure de la couche de
25     ! même indice)
26 guez 3
27 guez 118 REAL zlay(ngrid, klev) ! altitude au centre de chaque couche
28 guez 3
29 guez 118 REAL u(ngrid, klev), v(ngrid, klev)
30 guez 47 ! vitesse au centre de chaque couche (en entrée : la valeur au
31     ! début du pas de temps)
32 guez 3
33 guez 118 REAL, intent(in): teta(ngrid, klev)
34 guez 47 ! température potentielle au centre de chaque couche (en entrée :
35     ! la valeur au début du pas de temps)
36 guez 3
37 guez 62 REAL, intent(in):: cd(:) ! (ngrid) cdrag, valeur au début du pas de temps
38 guez 3
39 guez 118 REAL, intent(inout):: q2(ngrid, klev+1)
40 guez 47 ! $q^2$ au bas de chaque couche
41     ! En entrée : la valeur au début du pas de temps ; en sortie : la
42     ! valeur à la fin du pas de temps.
43 guez 3
44 guez 118 REAL km(ngrid, klev+1)
45 guez 47 ! diffusivité turbulente de quantité de mouvement (au bas de
46     ! chaque couche) (en sortie : la valeur à la fin du pas de temps)
47 guez 3
48 guez 118 REAL kn(ngrid, klev+1)
49 guez 47 ! diffusivité turbulente des scalaires (au bas de chaque couche)
50     ! (en sortie : la valeur à la fin du pas de temps)
51 guez 3
52 guez 118 REAL kq(ngrid, klev+1)
53     real ustar(ngrid)
54 guez 3
55 guez 47 integer iflag_pbl
56     ! iflag_pbl doit valoir entre 6 et 9
57     ! l = 6, on prend systématiquement une longueur d'équilibre
58     ! iflag_pbl = 6 : MY 2.0
59     ! iflag_pbl = 7 : MY 2.0.Fournier
60     ! iflag_pbl = 8 : MY 2.5
61     ! iflag_pbl = 9 : un test ?
62 guez 3
63 guez 47 ! Local:
64 guez 3
65 guez 118 real kmin, qmin, pblhmin(ngrid), coriol(ngrid)
66 guez 47 real qpre
67 guez 118 REAL unsdz(ngrid, klev)
68     REAL unsdzdec(ngrid, klev+1)
69     REAL kmpre(ngrid, klev+1), tmp2
70     REAL mpre(ngrid, klev+1)
71     real delta(ngrid, klev+1)
72     real aa(ngrid, klev+1), aa0, aa1
73 guez 47 integer, PARAMETER:: nlev = klev+1
74     logical:: first = .true.
75     integer:: ipas = 0
76     integer ig, k
77     real ri
78 guez 118 real rif(ngrid, klev+1), sm(ngrid, klev+1), alpha(ngrid, klev)
79     real m2(ngrid, klev+1), dz(ngrid, klev+1), zq, n2(ngrid, klev+1)
80     real dtetadz(ngrid, klev+1)
81 guez 47 real m2cstat, mcstat, kmcstat
82 guez 118 real l(ngrid, klev+1)
83     real, save:: l0(ngrid)
84     real sq(ngrid), sqz(ngrid), zz(ngrid, klev+1)
85 guez 47 integer iter
86     real:: ric = 0.195, rifc = 0.191, b1 = 16.6, kap = 0.4
87 guez 118 real rino(ngrid, klev+1), smyam(ngrid, klev), styam(ngrid, klev)
88     real lyam(ngrid, klev), knyam(ngrid, klev)
89 guez 3
90 guez 47 !-----------------------------------------------------------------------
91 guez 3
92 guez 118 call assert(iflag_pbl >= 6 .and. iflag_pbl <= 9, "yamada4")
93 guez 3
94 guez 47 ipas = ipas+1
95 guez 3
96 guez 47 ! les increments verticaux
97     DO ig = 1, ngrid
98     ! alerte: zlev n'est pas declare a nlev
99 guez 118 zlev(ig, nlev) = zlay(ig, klev) +(zlay(ig, klev) - zlev(ig, nlev-1))
100 guez 47 ENDDO
101 guez 3
102 guez 118 DO k = 1, klev
103 guez 47 DO ig = 1, ngrid
104     unsdz(ig, k) = 1.E+0/(zlev(ig, k+1)-zlev(ig, k))
105     ENDDO
106     ENDDO
107 guez 118
108 guez 47 DO ig = 1, ngrid
109     unsdzdec(ig, 1) = 1.E+0/(zlay(ig, 1)-zlev(ig, 1))
110     ENDDO
111 guez 118
112     DO k = 2, klev
113 guez 47 DO ig = 1, ngrid
114     unsdzdec(ig, k) = 1.E+0/(zlay(ig, k)-zlay(ig, k-1))
115     ENDDO
116     ENDDO
117 guez 118
118 guez 47 DO ig = 1, ngrid
119 guez 118 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     do ig = 1, ngrid
124     dz(ig, k) = zlay(ig, k)-zlay(ig, k-1)
125     m2(ig, k) = ((u(ig, k)-u(ig, k-1))**2+(v(ig, k)-v(ig, k-1))**2) &
126     /(dz(ig, k)*dz(ig, k))
127     dtetadz(ig, k) = (teta(ig, k)-teta(ig, k-1))/dz(ig, k)
128     n2(ig, k) = g*2.*dtetadz(ig, k)/(teta(ig, k-1)+teta(ig, k))
129     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     if(rif(ig, k).lt.0.16) then
136     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 47 ! Au premier appel, on détermine l et q2 de façon itérative.
147     ! Itération pour déterminer la longueur de mélange
148 guez 3
149 guez 47 if (first .or. iflag_pbl == 6) then
150     do ig = 1, ngrid
151     l0(ig) = 10.
152     enddo
153     do k = 2, klev-1
154     do ig = 1, ngrid
155     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     do ig = 1, ngrid
162     sq(ig) = 1e-10
163     sqz(ig) = 1e-10
164     enddo
165     do k = 2, klev-1
166     do ig = 1, ngrid
167     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     do ig = 1, ngrid
176     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     do ig = 1, ngrid
185     sq(ig) = 1.e-10
186     sqz(ig) = 1.e-10
187     enddo
188     do k = 2, klev-1
189     do ig = 1, ngrid
190     zq = sqrt(q2(ig, k))
191     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     enddo
194     enddo
195     do ig = 1, ngrid
196     l0(ig) = 0.2*sqz(ig)/sq(ig)
197     enddo
198     ! calcul de l(z)
199     do k = 2, klev
200     do ig = 1, ngrid
201     l(ig, k) = fl(zlev(ig, k), l0(ig), q2(ig, k), n2(ig, k))
202     if(first) then
203     q2(ig, k) = l(ig, k)**2 * zz(ig, k)
204     endif
205     enddo
206     enddo
207 guez 3
208 guez 47 ! Yamada 2.0
209     if (iflag_pbl == 6) then
210     do k = 2, klev
211     do ig = 1, ngrid
212     q2(ig, k) = l(ig, k)**2 * zz(ig, k)
213     enddo
214     enddo
215     else if (iflag_pbl == 7) then
216     ! Yamada 2.Fournier
217 guez 3
218 guez 47 ! Calcul de l, km, au pas precedent
219     do k = 2, klev
220     do ig = 1, ngrid
221     delta(ig, k) = q2(ig, k) / (l(ig, k)**2 * sm(ig, k))
222     kmpre(ig, k) = l(ig, k) * sqrt(q2(ig, k)) * sm(ig, k)
223     mpre(ig, k) = sqrt(m2(ig, k))
224     enddo
225     enddo
226 guez 3
227 guez 47 do k = 2, klev-1
228     do ig = 1, ngrid
229     m2cstat = max(alpha(ig, k)*n2(ig, k)+delta(ig, k)/b1, 1.e-12)
230     mcstat = sqrt(m2cstat)
231 guez 3
232 guez 47 ! puis on ecrit la valeur de q qui annule l'equation de m
233     ! supposee en q3
234 guez 3
235 guez 47 IF (k == 2) THEN
236     kmcstat = 1.E+0 / mcstat &
237     *(unsdz(ig, k)*kmpre(ig, k+1) &
238     *mpre(ig, k+1) &
239     +unsdz(ig, k-1) &
240     *cd(ig) &
241     *(sqrt(u(ig, 3)**2+v(ig, 3)**2) &
242     -mcstat/unsdzdec(ig, k) &
243     -mpre(ig, k+1)/unsdzdec(ig, k+1))**2) &
244     /(unsdz(ig, k)+unsdz(ig, k-1))
245     ELSE
246     kmcstat = 1.E+0 / mcstat &
247     *(unsdz(ig, k)*kmpre(ig, k+1) &
248     *mpre(ig, k+1) &
249     +unsdz(ig, k-1)*kmpre(ig, k-1) &
250     *mpre(ig, k-1)) &
251     /(unsdz(ig, k)+unsdz(ig, k-1))
252     ENDIF
253     tmp2 = kmcstat / (sm(ig, k) / q2(ig, k)) /l(ig, k)
254     q2(ig, k) = max(tmp2, 1.e-12)**(2./3.)
255     enddo
256     enddo
257     else if (iflag_pbl >= 8) then
258     ! Yamada 2.5 a la Didi
259 guez 3
260 guez 47 ! Calcul de l, km, au pas precedent
261     do k = 2, klev
262     do ig = 1, ngrid
263     delta(ig, k) = q2(ig, k)/(l(ig, k)**2*sm(ig, k))
264     if (delta(ig, k).lt.1.e-20) then
265     delta(ig, k) = 1.e-20
266     endif
267     km(ig, k) = l(ig, k)*sqrt(q2(ig, k))*sm(ig, k)
268     aa0 = (m2(ig, k)-alpha(ig, k)*n2(ig, k)-delta(ig, k)/b1)
269     aa1 = (m2(ig, k)*(1.-rif(ig, k))-delta(ig, k)/b1)
270     aa(ig, k) = aa1*dt/(delta(ig, k)*l(ig, k))
271     qpre = sqrt(q2(ig, k))
272     if (iflag_pbl == 8) then
273     if (aa(ig, k).gt.0.) then
274     q2(ig, k) = (qpre+aa(ig, k)*qpre*qpre)**2
275     else
276     q2(ig, k) = (qpre/(1.-aa(ig, k)*qpre))**2
277     endif
278     else
279     ! iflag_pbl = 9
280     if (aa(ig, k)*qpre.gt.0.9) then
281     q2(ig, k) = (qpre*10.)**2
282     else
283     q2(ig, k) = (qpre/(1.-aa(ig, k)*qpre))**2
284     endif
285     endif
286     q2(ig, k) = min(max(q2(ig, k), 1.e-10), 1.e4)
287     enddo
288     enddo
289     endif
290 guez 3
291 guez 47 ! Calcul des coefficients de mélange
292     do k = 2, klev
293     do ig = 1, ngrid
294     zq = sqrt(q2(ig, k))
295     km(ig, k) = l(ig, k)*zq*sm(ig, k)
296     kn(ig, k) = km(ig, k)*alpha(ig, k)
297     kq(ig, k) = l(ig, k)*zq*0.2
298     enddo
299     enddo
300 guez 3
301 guez 47 ! Traitement des cas noctrunes avec l'introduction d'une longueur
302     ! minilale.
303 guez 3
304 guez 47 ! Traitement particulier pour les cas tres stables.
305     ! D'apres Holtslag Boville.
306 guez 3
307 guez 47 do ig = 1, ngrid
308     coriol(ig) = 1.e-4
309     pblhmin(ig) = 0.07*ustar(ig)/max(abs(coriol(ig)), 2.546e-5)
310     enddo
311 guez 3
312 guez 47 print *, 'pblhmin ', pblhmin
313     do k = 2, klev
314 guez 118 do ig = 1, ngrid
315 guez 47 if (teta(ig, 2).gt.teta(ig, 1)) then
316     qmin = ustar(ig)*(max(1.-zlev(ig, k)/pblhmin(ig), 0.))**2
317     kmin = kap*zlev(ig, k)*qmin
318     else
319     kmin = -1. ! kmin n'est utilise que pour les SL stables.
320     endif
321     if (kn(ig, k).lt.kmin.or.km(ig, k).lt.kmin) then
322     kn(ig, k) = kmin
323     km(ig, k) = kmin
324     kq(ig, k) = kmin
325     ! la longueur de melange est suposee etre l = kap z
326     ! K = l q Sm d'ou q2 = (K/l Sm)**2
327     q2(ig, k) = (qmin/sm(ig, k))**2
328     endif
329     enddo
330     enddo
331 guez 3
332 guez 47 ! Diagnostique pour stokage
333 guez 3
334 guez 47 rino = rif
335     smyam(:, 1:klev) = sm(:, 1:klev)
336     styam = sm(:, 1:klev)*alpha(:, 1:klev)
337 guez 118 lyam(1:ngrid, 1:klev) = l(:, 1:klev)
338 guez 3
339 guez 47 first = .false.
340 guez 3
341 guez 47 end SUBROUTINE yamada4
342 guez 3
343 guez 47 !*******************************************************************
344 guez 3
345 guez 62 real function frif(ri)
346 guez 3
347 guez 47 real, intent(in):: ri
348 guez 3
349 guez 47 frif = 0.6588*(ri+0.1776-sqrt(ri*ri-0.3221*ri+0.03156))
350 guez 3
351 guez 47 end function frif
352 guez 3
353 guez 47 !*******************************************************************
354 guez 3
355 guez 62 real function falpha(ri)
356 guez 3
357 guez 47 real, intent(in):: ri
358 guez 3
359 guez 47 falpha = 1.318*(0.2231-ri)/(0.2341-ri)
360 guez 3
361 guez 47 end function falpha
362    
363     !*******************************************************************
364    
365 guez 62 real function fsm(ri)
366 guez 47
367     real, intent(in):: ri
368    
369     fsm = 1.96*(0.1912-ri)*(0.2341-ri)/((1.-ri)*(0.2231-ri))
370    
371     end function fsm
372    
373     !*******************************************************************
374    
375 guez 62 real function fl(zzz, zl0, zq2, zn2)
376 guez 47
377     real, intent(in):: zzz, zl0, zq2, zn2
378    
379     fl = max(min(zl0 * kap * zzz / (kap * zzz + zl0), &
380     0.5 * sqrt(zq2) / sqrt(max(zn2, 1e-10))), 1.)
381    
382     end function fl
383    
384     end module yamada4_m

  ViewVC Help
Powered by ViewVC 1.1.21