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

Contents of /trunk/phylmd/fisrtilp.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 73 - (show annotations)
Fri Nov 15 17:48:30 2013 UTC (10 years, 6 months ago) by guez
Original Path: trunk/libf/phylmd/fisrtilp.f90
File size: 18028 byte(s)
Renamed tpot to teta and psol to ps in etat0.

Replaced calls to flincom by calls to NetCDF95 in startdyn. lon_ini,
lat_ini and levdyn_ini are now pointers.
1 module fisrtilp_m
2
3 IMPLICIT NONE
4
5 contains
6
7 SUBROUTINE fisrtilp(dtime, paprs, pplay, t, q, ptconv, ratqs, d_t, d_q, &
8 d_ql, rneb, radliq, rain, snow, pfrac_impa, pfrac_nucl, pfrac_1nucl, &
9 frac_impa, frac_nucl, prfl, psfl, rhcl)
10
11 ! From phylmd/fisrtilp.F, version 1.2 2004/11/09 16:55:40
12 ! Author: Z. X. Li (LMD/CNRS), 20 mars 1995
13
14 ! Objet : condensation et précipitation stratiforme, schéma de
15 ! nuage, schéma de condensation à grande échelle (pluie).
16
17 USE dimphy, ONLY: klev, klon
18 USE suphec_m, ONLY: rcpd, rd, retv, rg, rlstt, rlvtt, rtt
19 USE yoethf_m, ONLY: r2es, r5ies, r5les, rvtmp2
20 USE fcttre, ONLY: dqsatl, dqsats, foede, foeew, qsatl, qsats, thermcep
21 USE comfisrtilp, ONLY: cld_lc_con, cld_lc_lsc, cld_tau_con, &
22 cld_tau_lsc, coef_eva, ffallv_con, ffallv_lsc, iflag_pdf, reevap_ice
23 USE numer_rec_95, ONLY: nr_erf
24
25 ! Arguments:
26
27 REAL, INTENT (IN):: dtime ! intervalle du temps (s)
28 REAL, INTENT (IN):: paprs(klon, klev+1) ! pression a inter-couche
29 REAL, INTENT (IN):: pplay(klon, klev) ! pression au milieu de couche
30 REAL, INTENT (IN):: t(klon, klev) ! temperature (K)
31 REAL, INTENT (IN):: q(klon, klev) ! humidite specifique (kg/kg)
32 LOGICAL ptconv(klon, klev) ! determine la largeur de distribution de vapeur
33 REAL ratqs(klon, klev) ! determine la largeur de distribution de vapeur
34 REAL d_t(klon, klev) ! incrementation de la temperature (K)
35 REAL d_q(klon, klev) ! incrementation de la vapeur d'eau
36 REAL d_ql(klon, klev) ! incrementation de l'eau liquide
37 REAL rneb(klon, klev) ! fraction nuageuse
38 REAL radliq(klon, klev) ! eau liquide utilisee dans rayonnements
39 REAL rain(klon) ! pluies (mm/s)
40 REAL snow(klon) ! neige (mm/s)
41
42 ! Coeffients de fraction lessivee : pour OFF-LINE
43 REAL pfrac_impa(klon, klev)
44 REAL pfrac_nucl(klon, klev)
45 REAL pfrac_1nucl(klon, klev)
46
47 ! Fraction d'aerosols lessivee par impaction et par nucleation
48 ! POur ON-LINE
49 REAL frac_nucl(klon, klev)
50
51 REAL prfl(klon, klev+1) ! flux d'eau precipitante aux interfaces (kg/m2/s)
52 REAL psfl(klon, klev+1) ! flux d'eau precipitante aux interfaces (kg/m2/s)
53 REAL rhcl(klon, klev) ! humidite relative en ciel clair
54
55 ! Local:
56
57 ! Fraction d'aerosols lessivee par impaction et par nucleation
58 ! POur ON-LINE
59 REAL frac_impa(klon, klev)
60 REAL zct(klon), zcl(klon)
61 !AA
62
63 ! Options du programme:
64
65 REAL seuil_neb ! un nuage existe vraiment au-dela
66 PARAMETER (seuil_neb=0.001)
67
68 INTEGER ninter ! sous-intervals pour la precipitation
69 PARAMETER (ninter=5)
70 LOGICAL evap_prec ! evaporation de la pluie
71 PARAMETER (evap_prec=.TRUE.)
72 REAL zpdf_sig(klon), zpdf_k(klon), zpdf_delta(klon)
73 REAL zpdf_a(klon), zpdf_b(klon), zpdf_e1(klon), zpdf_e2(klon)
74
75 LOGICAL cpartiel ! condensation partielle
76 PARAMETER (cpartiel=.TRUE.)
77 REAL t_coup
78 PARAMETER (t_coup=234.0)
79
80 ! Variables locales:
81
82 INTEGER i, k, n, kk
83 REAL zqs(klon), zdqs(klon), zdelta, zcor, zcvm5
84 REAL zrfl(klon), zrfln(klon), zqev, zqevt
85 REAL zoliq(klon), zcond(klon), zq(klon), zqn(klon), zdelq
86 REAL ztglace, zt(klon)
87 INTEGER nexpo ! exponentiel pour glace/eau
88 REAL zdz(klon), zrho(klon), ztot(klon), zrhol(klon)
89 REAL zchau(klon), zfroi(klon), zfice(klon), zneb(klon)
90
91 LOGICAL appel1er
92 SAVE appel1er
93
94 !---------------------------------------------------------------
95
96 !AA Variables traceurs:
97 !AA Provisoire !!! Parametres alpha du lessivage
98 !AA A priori on a 4 scavenging numbers possibles
99
100 REAL a_tr_sca(4)
101 SAVE a_tr_sca
102
103 ! Variables intermediaires
104
105 REAL zalpha_tr
106 REAL zfrac_lessi
107 REAL zprec_cond(klon)
108 !AA
109 REAL zmair, zcpair, zcpeau
110 ! Pour la conversion eau-neige
111 REAL zlh_solid(klon), zm_solid
112 !IM
113 INTEGER klevm1
114 !---------------------------------------------------------------
115
116 ! Fonctions en ligne:
117
118 REAL fallvs, fallvc ! vitesse de chute pour crystaux de glace
119 REAL zzz
120
121 fallvc(zzz) = 3.29/2.0*((zzz)**0.16)*ffallv_con
122 fallvs(zzz) = 3.29/2.0*((zzz)**0.16)*ffallv_lsc
123
124 DATA appel1er/ .TRUE./
125 !ym
126 zdelq = 0.0
127
128 IF (appel1er) THEN
129
130 PRINT *, 'fisrtilp, ninter:', ninter
131 PRINT *, 'fisrtilp, evap_prec:', evap_prec
132 PRINT *, 'fisrtilp, cpartiel:', cpartiel
133 IF (abs(dtime / real(ninter) - 360.) > 0.001) THEN
134 PRINT *, "fisrtilp : ce n'est pas prévu, voir Z. X. Li", dtime
135 PRINT *, 'Je préfère un sous-intervalle de 6 minutes.'
136 END IF
137 appel1er = .FALSE.
138
139 !AA initialiation provisoire
140 a_tr_sca(1) = -0.5
141 a_tr_sca(2) = -0.5
142 a_tr_sca(3) = -0.5
143 a_tr_sca(4) = -0.5
144
145 !AA Initialisation a 1 des coefs des fractions lessivees
146
147 DO k = 1, klev
148 DO i = 1, klon
149 pfrac_nucl(i, k) = 1.
150 pfrac_1nucl(i, k) = 1.
151 pfrac_impa(i, k) = 1.
152 END DO
153 END DO
154
155
156 END IF ! test sur appel1er
157 !MAf Initialisation a 0 de zoliq
158 DO i = 1, klon
159 zoliq(i) = 0.
160 END DO
161 ! Determiner les nuages froids par leur temperature
162 ! nexpo regle la raideur de la transition eau liquide / eau glace.
163
164 ztglace = rtt - 15.0
165 nexpo = 6
166 !cc nexpo = 1
167
168 ! Initialiser les sorties:
169
170 DO k = 1, klev + 1
171 DO i = 1, klon
172 prfl(i, k) = 0.0
173 psfl(i, k) = 0.0
174 END DO
175 END DO
176
177 DO k = 1, klev
178 DO i = 1, klon
179 d_t(i, k) = 0.0
180 d_q(i, k) = 0.0
181 d_ql(i, k) = 0.0
182 rneb(i, k) = 0.0
183 radliq(i, k) = 0.0
184 frac_nucl(i, k) = 1.
185 frac_impa(i, k) = 1.
186 END DO
187 END DO
188 DO i = 1, klon
189 rain(i) = 0.0
190 snow(i) = 0.0
191 END DO
192
193 ! Initialiser le flux de precipitation a zero
194
195 DO i = 1, klon
196 zrfl(i) = 0.0
197 zneb(i) = seuil_neb
198 END DO
199
200
201 !AA Pour plus de securite
202
203 zalpha_tr = 0.
204 zfrac_lessi = 0.
205
206 !AA----------------------------------------------------------
207
208 ! Boucle verticale (du haut vers le bas)
209
210 !IM : klevm1
211 klevm1 = klev - 1
212 DO k = klev, 1, -1
213
214 !AA----------------------------------------------------------
215
216 DO i = 1, klon
217 zt(i) = t(i, k)
218 zq(i) = q(i, k)
219 END DO
220
221 ! Calculer la varition de temp. de l'air du a la chaleur sensible
222 ! transporter par la pluie.
223 ! Il resterait a rajouter cet effet de la chaleur sensible sur les
224 ! flux de surface, du a la diff. de temp. entre le 1er niveau et la
225 ! surface.
226
227 DO i = 1, klon
228 IF (k<=klevm1) THEN
229 zmair = (paprs(i, k)-paprs(i, k+1))/rg
230 zcpair = rcpd*(1.0+rvtmp2*zq(i))
231 zcpeau = rcpd*rvtmp2
232 zt(i) = ((t(i, k + 1) + d_t(i, k + 1)) * zrfl(i) * dtime &
233 * zcpeau + zmair * zcpair* zt(i)) &
234 / (zmair * zcpair + zrfl(i) * dtime * zcpeau)
235 END IF
236 END DO
237
238 ! Calculer l'evaporation de la precipitation
239
240
241
242 IF (evap_prec) THEN
243 DO i = 1, klon
244 IF (zrfl(i)>0.) THEN
245 IF (thermcep) THEN
246 zdelta = max(0., sign(1., rtt-zt(i)))
247 zqs(i) = r2es*foeew(zt(i), zdelta)/pplay(i, k)
248 zqs(i) = min(0.5, zqs(i))
249 zcor = 1./(1.-retv*zqs(i))
250 zqs(i) = zqs(i)*zcor
251 ELSE
252 IF (zt(i)<t_coup) THEN
253 zqs(i) = qsats(zt(i))/pplay(i, k)
254 ELSE
255 zqs(i) = qsatl(zt(i))/pplay(i, k)
256 END IF
257 END IF
258 zqev = max(0.0, (zqs(i)-zq(i))*zneb(i))
259 zqevt = coef_eva*(1.0-zq(i)/zqs(i))*sqrt(zrfl(i))* &
260 (paprs(i, k)-paprs(i, k+1))/pplay(i, k)*zt(i)*rd/rg
261 zqevt = max(0.0, min(zqevt, zrfl(i)))*rg*dtime/ &
262 (paprs(i, k)-paprs(i, k+1))
263 zqev = min(zqev, zqevt)
264 zrfln(i) = zrfl(i) - zqev*(paprs(i, k)-paprs(i, k+1))/rg/dtime
265
266 ! pour la glace, on réévapore toute la précip dans la
267 ! couche du dessous la glace venant de la couche du
268 ! dessus est simplement dans la couche du dessous.
269
270 IF (zt(i)<t_coup .AND. reevap_ice) zrfln(i) = 0.
271
272 zq(i) = zq(i) - (zrfln(i)-zrfl(i))*(rg/(paprs(i, k)-paprs(i, &
273 k+1)))*dtime
274 zt(i) = zt(i) + (zrfln(i)-zrfl(i))*(rg/(paprs(i, k)-paprs(i, &
275 k+1)))*dtime*rlvtt/rcpd/(1.0+rvtmp2*zq(i))
276 zrfl(i) = zrfln(i)
277 END IF
278 END DO
279 END IF
280
281 ! Calculer Qs et L/Cp*dQs/dT:
282
283 IF (thermcep) THEN
284 DO i = 1, klon
285 zdelta = max(0., sign(1., rtt-zt(i)))
286 zcvm5 = r5les*rlvtt*(1.-zdelta) + r5ies*rlstt*zdelta
287 zcvm5 = zcvm5/rcpd/(1.0+rvtmp2*zq(i))
288 zqs(i) = r2es*foeew(zt(i), zdelta)/pplay(i, k)
289 zqs(i) = min(0.5, zqs(i))
290 zcor = 1./(1.-retv*zqs(i))
291 zqs(i) = zqs(i)*zcor
292 zdqs(i) = foede(zt(i), zdelta, zcvm5, zqs(i), zcor)
293 END DO
294 ELSE
295 DO i = 1, klon
296 IF (zt(i)<t_coup) THEN
297 zqs(i) = qsats(zt(i))/pplay(i, k)
298 zdqs(i) = dqsats(zt(i), zqs(i))
299 ELSE
300 zqs(i) = qsatl(zt(i))/pplay(i, k)
301 zdqs(i) = dqsatl(zt(i), zqs(i))
302 END IF
303 END DO
304 END IF
305
306 ! Determiner la condensation partielle et calculer la quantite
307 ! de l'eau condensee:
308
309 IF (cpartiel) THEN
310
311 ! print*, 'Dans partiel k=', k
312
313 ! Calcul de l'eau condensee et de la fraction nuageuse et de l'eau
314 ! nuageuse a partir des PDF de Sandrine Bony.
315 ! rneb : fraction nuageuse
316 ! zqn : eau totale dans le nuage
317 ! zcond : eau condensee moyenne dans la maille.
318
319 ! on prend en compte le réchauffement qui diminue
320 ! la partie condensee
321
322 ! Version avec les raqts
323
324 IF (iflag_pdf==0) THEN
325
326 DO i = 1, klon
327 zdelq = min(ratqs(i, k), 0.99)*zq(i)
328 rneb(i, k) = (zq(i)+zdelq-zqs(i))/(2.0*zdelq)
329 zqn(i) = (zq(i)+zdelq+zqs(i))/2.0
330 END DO
331
332 ELSE
333
334 ! Version avec les nouvelles PDFs.
335 DO i = 1, klon
336 IF (zq(i)<1.E-15) THEN
337 zq(i) = 1.E-15
338 END IF
339 END DO
340 DO i = 1, klon
341 zpdf_sig(i) = ratqs(i, k)*zq(i)
342 zpdf_k(i) = -sqrt(log(1.+(zpdf_sig(i)/zq(i))**2))
343 zpdf_delta(i) = log(zq(i)/zqs(i))
344 zpdf_a(i) = zpdf_delta(i)/(zpdf_k(i)*sqrt(2.))
345 zpdf_b(i) = zpdf_k(i)/(2.*sqrt(2.))
346 zpdf_e1(i) = zpdf_a(i) - zpdf_b(i)
347 zpdf_e1(i) = sign(min(abs(zpdf_e1(i)), 5.), zpdf_e1(i))
348 zpdf_e1(i) = 1. - nr_erf(zpdf_e1(i))
349 zpdf_e2(i) = zpdf_a(i) + zpdf_b(i)
350 zpdf_e2(i) = sign(min(abs(zpdf_e2(i)), 5.), zpdf_e2(i))
351 zpdf_e2(i) = 1. - nr_erf(zpdf_e2(i))
352 IF (zpdf_e1(i)<1.E-10) THEN
353 rneb(i, k) = 0.
354 zqn(i) = zqs(i)
355 ELSE
356 rneb(i, k) = 0.5*zpdf_e1(i)
357 zqn(i) = zq(i)*zpdf_e2(i)/zpdf_e1(i)
358 END IF
359
360 END DO
361
362
363 END IF
364 ! iflag_pdf
365 DO i = 1, klon
366 IF (rneb(i, k)<=0.0) zqn(i) = 0.0
367 IF (rneb(i, k)>=1.0) zqn(i) = zq(i)
368 rneb(i, k) = max(0.0, min(1.0, rneb(i, k)))
369 ! On ne divise pas par 1+zdqs pour forcer a avoir l'eau
370 ! predite par la convection. ATTENTION !!! Il va
371 ! falloir verifier tout ca.
372 zcond(i) = max(0.0, zqn(i)-zqs(i))*rneb(i, k)
373 ! print*, 'ZDQS ', zdqs(i)
374 !--Olivier
375 rhcl(i, k) = (zqs(i)+zq(i)-zdelq)/2./zqs(i)
376 IF (rneb(i, k)<=0.0) rhcl(i, k) = zq(i)/zqs(i)
377 IF (rneb(i, k)>=1.0) rhcl(i, k) = 1.0
378 !--fin
379 END DO
380 ELSE
381 DO i = 1, klon
382 IF (zq(i)>zqs(i)) THEN
383 rneb(i, k) = 1.0
384 ELSE
385 rneb(i, k) = 0.0
386 END IF
387 zcond(i) = max(0.0, zq(i)-zqs(i))/(1.+zdqs(i))
388 END DO
389 END IF
390
391 DO i = 1, klon
392 zq(i) = zq(i) - zcond(i)
393 ! zt(i) = zt(i) + zcond(i) * RLVTT/RCPD
394 zt(i) = zt(i) + zcond(i)*rlvtt/rcpd/(1.0+rvtmp2*zq(i))
395 END DO
396
397 ! Partager l'eau condensee en precipitation et eau liquide nuageuse
398
399 DO i = 1, klon
400 IF (rneb(i, k)>0.0) THEN
401 zoliq(i) = zcond(i)
402 zrho(i) = pplay(i, k)/zt(i)/rd
403 zdz(i) = (paprs(i, k)-paprs(i, k+1))/(zrho(i)*rg)
404 zfice(i) = 1.0 - (zt(i)-ztglace)/(273.13-ztglace)
405 zfice(i) = min(max(zfice(i), 0.0), 1.0)
406 zfice(i) = zfice(i)**nexpo
407 zneb(i) = max(rneb(i, k), seuil_neb)
408 radliq(i, k) = zoliq(i)/real(ninter+1)
409 END IF
410 END DO
411
412 DO n = 1, ninter
413 DO i = 1, klon
414 IF (rneb(i, k)>0.0) THEN
415 zrhol(i) = zrho(i)*zoliq(i)/zneb(i)
416
417 IF (ptconv(i, k)) THEN
418 zcl(i) = cld_lc_con
419 zct(i) = 1./cld_tau_con
420 ELSE
421 zcl(i) = cld_lc_lsc
422 zct(i) = 1./cld_tau_lsc
423 END IF
424 ! quantité d'eau à élminier.
425 zchau(i) = zct(i)*dtime/real(ninter)*zoliq(i)* &
426 (1.0-exp(-(zoliq(i)/zneb(i)/zcl(i))**2))*(1.-zfice(i))
427 ! meme chose pour la glace.
428 IF (ptconv(i, k)) THEN
429 zfroi(i) = dtime/real(ninter)/zdz(i)*zoliq(i)* &
430 fallvc(zrhol(i))*zfice(i)
431 ELSE
432 zfroi(i) = dtime/real(ninter)/zdz(i)*zoliq(i)* &
433 fallvs(zrhol(i))*zfice(i)
434 END IF
435 ztot(i) = zchau(i) + zfroi(i)
436 IF (zneb(i)==seuil_neb) ztot(i) = 0.0
437 ztot(i) = min(max(ztot(i), 0.0), zoliq(i))
438 zoliq(i) = max(zoliq(i)-ztot(i), 0.0)
439 radliq(i, k) = radliq(i, k) + zoliq(i)/real(ninter+1)
440 END IF
441 END DO
442 END DO
443
444 DO i = 1, klon
445 IF (rneb(i, k)>0.0) THEN
446 d_ql(i, k) = zoliq(i)
447 zrfl(i) = zrfl(i) + max(zcond(i) - zoliq(i), 0.) &
448 * (paprs(i, k) - paprs(i, k + 1)) / (rg * dtime)
449 END IF
450 IF (zt(i)<rtt) THEN
451 psfl(i, k) = zrfl(i)
452 ELSE
453 prfl(i, k) = zrfl(i)
454 END IF
455 END DO
456
457 ! Calculer les tendances de q et de t:
458
459 DO i = 1, klon
460 d_q(i, k) = zq(i) - q(i, k)
461 d_t(i, k) = zt(i) - t(i, k)
462 END DO
463
464 !AA--------------- Calcul du lessivage stratiforme -------------
465
466 DO i = 1, klon
467 zprec_cond(i) = max(zcond(i)-zoliq(i), 0.0)* &
468 (paprs(i, k)-paprs(i, k+1))/rg
469 IF (rneb(i, k)>0.0 .AND. zprec_cond(i)>0.) THEN
470 !AA lessivage nucleation LMD5 dans la couche elle-meme
471 IF (t(i, k)>=ztglace) THEN
472 zalpha_tr = a_tr_sca(3)
473 ELSE
474 zalpha_tr = a_tr_sca(4)
475 END IF
476 zfrac_lessi = 1. - exp(zalpha_tr*zprec_cond(i)/zneb(i))
477 pfrac_nucl(i, k) = pfrac_nucl(i, k)*(1.-zneb(i)*zfrac_lessi)
478 frac_nucl(i, k) = 1. - zneb(i)*zfrac_lessi
479
480 ! nucleation avec un facteur -1 au lieu de -0.5
481 zfrac_lessi = 1. - exp(-zprec_cond(i)/zneb(i))
482 pfrac_1nucl(i, k) = pfrac_1nucl(i, k)*(1.-zneb(i)*zfrac_lessi)
483 END IF
484
485
486 END DO
487 !AA Lessivage par impaction dans les couches en-dessous
488 ! boucle sur i
489 DO kk = k - 1, 1, -1
490 DO i = 1, klon
491 IF (rneb(i, k)>0.0 .AND. zprec_cond(i)>0.) THEN
492 IF (t(i, kk)>=ztglace) THEN
493 zalpha_tr = a_tr_sca(1)
494 ELSE
495 zalpha_tr = a_tr_sca(2)
496 END IF
497 zfrac_lessi = 1. - exp(zalpha_tr*zprec_cond(i)/zneb(i))
498 pfrac_impa(i, kk) = pfrac_impa(i, kk)*(1.-zneb(i)*zfrac_lessi)
499 frac_impa(i, kk) = 1. - zneb(i)*zfrac_lessi
500 END IF
501 END DO
502 END DO
503
504 !AA----------------------------------------------------------
505 ! FIN DE BOUCLE SUR K
506 end DO
507
508 !AA-----------------------------------------------------------
509
510 ! Pluie ou neige au sol selon la temperature de la 1ere couche
511
512 DO i = 1, klon
513 IF ((t(i, 1)+d_t(i, 1))<rtt) THEN
514 snow(i) = zrfl(i)
515 zlh_solid(i) = rlstt - rlvtt
516 ELSE
517 rain(i) = zrfl(i)
518 zlh_solid(i) = 0.
519 END IF
520 END DO
521
522 ! For energy conservation: when snow is present, the solification
523 ! latent heat is considered.
524 DO k = 1, klev
525 DO i = 1, klon
526 zcpair = rcpd*(1.0+rvtmp2*(q(i, k)+d_q(i, k)))
527 zmair = (paprs(i, k)-paprs(i, k+1))/rg
528 zm_solid = (prfl(i, k)-prfl(i, k+1)+psfl(i, k)-psfl(i, k+1))*dtime
529 d_t(i, k) = d_t(i, k) + zlh_solid(i)*zm_solid/(zcpair*zmair)
530 END DO
531 END DO
532
533 END SUBROUTINE fisrtilp
534
535 end module fisrtilp_m

  ViewVC Help
Powered by ViewVC 1.1.21