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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 99 - (hide annotations)
Wed Jul 2 18:39:15 2014 UTC (9 years, 10 months ago) by guez
Original Path: trunk/phylmd/yamada4.f
File size: 11413 byte(s)
Created procedure test_disvert (following LMDZ). Added procedures
hybrid and funcd in module disvert_m. Upgraded compute_ab from
internal procedure of disvert to module procedure. Added variables y,
ya in module disvert_m. Upgraded s from local variable of procedure
disvert to module variable.

Renamed allowed value of variable vert_sampling in procedure disvert
from "read" to "read_hybrid". Added possibility to read pressure
values, value "read_pressure". Replaced vertical distribution for
value "param" by the distribution "strato_correct" from LMDZ (but kept
the value "param"). In case "tropo", replaced 1 by dsigmin (following
LMDZ). In case "strato", replaced 0.3 by dsigmin (following LMDZ).

Changed computation of bp in procedure compute_ab.

Removed debugindex case in clmain. Removed useless argument rlon of
procedure clmain. Removed useless variables ytaux, ytauy of procedure
clmain.

Removed intermediary variables tsol, qsol, tsolsrf, tslab in procedure
etat0.

Removed variable ok_veget:. coupling with the model Orchid is not
possible. Removed variable ocean: modeling an ocean slab is not
possible.

Removed useless variables tmp_rriv and tmp_rcoa from module
interface_surf.

Moved initialization of variables da, mp, phi in procedure physiq to
to inside the test iflag_con >= 3.

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

  ViewVC Help
Powered by ViewVC 1.1.21