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

Annotation of /trunk/phylmd/fisrtilp.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 61 - (hide annotations)
Fri Apr 20 14:58:43 2012 UTC (12 years ago) by guez
Original Path: trunk/libf/phylmd/fisrtilp.f90
File size: 16741 byte(s)
No more included file in LMDZE, not even "netcdf.inc".

Created a variable containing the list of common source files in
GNUmakefile. So we now also see clearly files that are specific to
each program.

Split module "histcom". Assembled resulting files in directory
"Histcom".

Removed aliasing in calls to "laplacien".

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

  ViewVC Help
Powered by ViewVC 1.1.21