/[lmdze]/trunk/libf/phylmd/fisrtilp.f90
ViewVC logotype

Contents of /trunk/libf/phylmd/fisrtilp.f90

Parent Directory Parent Directory | Revision Log Revision Log


Revision 68 - (show annotations)
Wed Nov 14 16:59:30 2012 UTC (11 years, 5 months ago) by guez
File size: 17930 byte(s)
Split "flincom.f90" into "flinclo.f90", "flinfindcood.f90",
"flininfo.f90" and "flinopen_nozoom.f90", in directory
"IOIPSL/Flincom".

Renamed "etat0_lim" to "ce0l", as in LMDZ.

Split "readsulfate.f" into "readsulfate.f90", "readsulfate_preind.f90"
and "getso4fromfile.f90".

In etat0, renamed variable q3d to q, as in "dynredem1". Replaced calls
to Flicom procedures by calls to NetCDF95.

In leapfrog, added call to writehist.

Extracted ASCII art from "grid_noro" into a file
"grid_noro.txt". Transformed explicit-shape local arrays into
automatic arrays, so that test on values of iim and jjm is no longer
needed. Test on weight:
          IF (weight(ii, jj) /= 0.) THEN
is useless. There is already a test before:
    if (any(weight == 0.)) stop "zero weight in grid_noro"

In "aeropt", replaced duplicated lines with different values of inu by
a loop on inu.

Removed arguments of "conf_phys". Corresponding variables are now
defined in "physiq", in a namelist. In "conf_phys", read a namelist
instead of using getin.

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

  ViewVC Help
Powered by ViewVC 1.1.21