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

Annotation of /trunk/phylmd/yamada4.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 178 - (hide annotations)
Fri Mar 11 18:47:26 2016 UTC (8 years, 2 months ago) by guez
Original Path: trunk/Sources/phylmd/yamada4.f
File size: 11066 byte(s)
Moved variables date0, deltat, datasz_max, ncvar_ids, point, buff_pos,
buffer, regular from module histcom_var to modules where they are
defined.

Removed procedure ioipslmpp, useless for a sequential program.

Added argument datasz_max to histwrite_real (to avoid circular
dependency with histwrite).

Removed useless variables and computations everywhere.

Changed real litteral constants from default kind to double precision
in lwb, lwu, lwvn, sw1s, swtt, swtt1, swu.

Removed unused arguments: paer of sw, sw1s, sw2s, swclr; pcldsw of
sw1s, sw2s; pdsig, prayl of swr; co2_ppm of clmain, clqh; tsol of
transp_lay; nsrf of screenp; kcrit and kknu of gwstress; pstd of
orosetup.

Added output of relative humidity.

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 178 ! altitude \`a chaque niveau (interface inf\'erieure de la couche de
25     ! m\^eme 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 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 119 REAL, intent(in):: teta(ngrid, 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 178 REAL, intent(in):: cd(:) ! (ngrid) cdrag, valeur au d\'ebut 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 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 118 REAL km(ngrid, 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 118 REAL kn(ngrid, 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 118 REAL kq(ngrid, klev+1)
53     real ustar(ngrid)
54 guez 3
55 guez 119 integer, intent(in):: iflag_pbl
56 guez 47 ! iflag_pbl doit valoir entre 6 et 9
57 guez 178 ! l = 6, on prend syst\'ematiquement une longueur d'\'equilibre
58 guez 47 ! 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 guez 178 real aa(ngrid, klev+1), 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 guez 119 real l0(ngrid)
84 guez 118 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 3
88 guez 47 !-----------------------------------------------------------------------
89 guez 3
90 guez 118 call assert(iflag_pbl >= 6 .and. iflag_pbl <= 9, "yamada4")
91 guez 3
92 guez 47 ipas = ipas+1
93 guez 3
94 guez 47 ! les increments verticaux
95     DO ig = 1, ngrid
96     ! alerte: zlev n'est pas declare a nlev
97 guez 118 zlev(ig, nlev) = zlay(ig, klev) +(zlay(ig, klev) - zlev(ig, nlev-1))
98 guez 47 ENDDO
99 guez 3
100 guez 118 DO k = 1, klev
101 guez 47 DO ig = 1, ngrid
102     unsdz(ig, k) = 1.E+0/(zlev(ig, k+1)-zlev(ig, k))
103     ENDDO
104     ENDDO
105 guez 118
106 guez 47 DO ig = 1, ngrid
107     unsdzdec(ig, 1) = 1.E+0/(zlay(ig, 1)-zlev(ig, 1))
108     ENDDO
109 guez 118
110     DO k = 2, klev
111 guez 47 DO ig = 1, ngrid
112     unsdzdec(ig, k) = 1.E+0/(zlay(ig, k)-zlay(ig, k-1))
113     ENDDO
114     ENDDO
115 guez 118
116 guez 47 DO ig = 1, ngrid
117 guez 118 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     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 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 178 ! Au premier appel, on d\'etermine l et q2 de façon it\'erative.
145     ! It\'eration pour d\'eterminer la longueur de m\'elange
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 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 ! 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     aa1 = (m2(ig, k)*(1.-rif(ig, k))-delta(ig, k)/b1)
267     aa(ig, k) = aa1*dt/(delta(ig, k)*l(ig, k))
268     qpre = sqrt(q2(ig, k))
269     if (iflag_pbl == 8) then
270     if (aa(ig, k).gt.0.) then
271     q2(ig, k) = (qpre+aa(ig, k)*qpre*qpre)**2
272     else
273     q2(ig, k) = (qpre/(1.-aa(ig, k)*qpre))**2
274     endif
275     else
276     ! iflag_pbl = 9
277     if (aa(ig, k)*qpre.gt.0.9) then
278     q2(ig, k) = (qpre*10.)**2
279     else
280     q2(ig, k) = (qpre/(1.-aa(ig, k)*qpre))**2
281     endif
282     endif
283     q2(ig, k) = min(max(q2(ig, k), 1.e-10), 1.e4)
284     enddo
285     enddo
286     endif
287 guez 3
288 guez 178 ! Calcul des coefficients de m\'elange
289 guez 47 do k = 2, klev
290     do ig = 1, ngrid
291     zq = sqrt(q2(ig, k))
292     km(ig, k) = l(ig, k)*zq*sm(ig, k)
293     kn(ig, k) = km(ig, k)*alpha(ig, k)
294     kq(ig, k) = l(ig, k)*zq*0.2
295     enddo
296     enddo
297 guez 3
298 guez 47 ! Traitement des cas noctrunes avec l'introduction d'une longueur
299     ! minilale.
300 guez 3
301 guez 47 ! Traitement particulier pour les cas tres stables.
302     ! D'apres Holtslag Boville.
303 guez 3
304 guez 47 do ig = 1, ngrid
305     coriol(ig) = 1.e-4
306     pblhmin(ig) = 0.07*ustar(ig)/max(abs(coriol(ig)), 2.546e-5)
307     enddo
308 guez 3
309 guez 47 print *, 'pblhmin ', pblhmin
310     do k = 2, klev
311 guez 118 do ig = 1, ngrid
312 guez 47 if (teta(ig, 2).gt.teta(ig, 1)) then
313     qmin = ustar(ig)*(max(1.-zlev(ig, k)/pblhmin(ig), 0.))**2
314     kmin = kap*zlev(ig, k)*qmin
315     else
316     kmin = -1. ! kmin n'est utilise que pour les SL stables.
317     endif
318     if (kn(ig, k).lt.kmin.or.km(ig, k).lt.kmin) then
319     kn(ig, k) = kmin
320     km(ig, k) = kmin
321     kq(ig, k) = kmin
322     ! la longueur de melange est suposee etre l = kap z
323     ! K = l q Sm d'ou q2 = (K/l Sm)**2
324     q2(ig, k) = (qmin/sm(ig, k))**2
325     endif
326     enddo
327     enddo
328 guez 3
329 guez 47 first = .false.
330 guez 3
331 guez 47 end SUBROUTINE yamada4
332 guez 3
333 guez 47 !*******************************************************************
334 guez 3
335 guez 62 real function frif(ri)
336 guez 3
337 guez 47 real, intent(in):: ri
338 guez 3
339 guez 47 frif = 0.6588*(ri+0.1776-sqrt(ri*ri-0.3221*ri+0.03156))
340 guez 3
341 guez 47 end function frif
342 guez 3
343 guez 47 !*******************************************************************
344 guez 3
345 guez 62 real function falpha(ri)
346 guez 3
347 guez 47 real, intent(in):: ri
348 guez 3
349 guez 47 falpha = 1.318*(0.2231-ri)/(0.2341-ri)
350 guez 3
351 guez 47 end function falpha
352    
353     !*******************************************************************
354    
355 guez 62 real function fsm(ri)
356 guez 47
357     real, intent(in):: ri
358    
359     fsm = 1.96*(0.1912-ri)*(0.2341-ri)/((1.-ri)*(0.2231-ri))
360    
361     end function fsm
362    
363     !*******************************************************************
364    
365 guez 62 real function fl(zzz, zl0, zq2, zn2)
366 guez 47
367     real, intent(in):: zzz, zl0, zq2, zn2
368    
369     fl = max(min(zl0 * kap * zzz / (kap * zzz + zl0), &
370     0.5 * sqrt(zq2) / sqrt(max(zn2, 1e-10))), 1.)
371    
372     end function fl
373    
374     end module yamada4_m

  ViewVC Help
Powered by ViewVC 1.1.21