/[lmdze]/trunk/phylmd/Conflx/flxasc.f90
ViewVC logotype

Contents of /trunk/phylmd/Conflx/flxasc.f90

Parent Directory Parent Directory | Revision Log Revision Log


Revision 78 - (show annotations)
Wed Feb 5 17:51:07 2014 UTC (10 years, 3 months ago) by guez
File size: 10613 byte(s)
Moved procedure inigeom into module comgeom.

In disvert, renamed s_sampling to vert_sampling, following
LMDZ. Removed choice strato1. In case read, read ap and bp instead of
s (following LMDZ).

Added argument phis to start_init_orog and start_init_dyn, and removed
variable phis of module start_init_orog_m. In etat0 and
start_init_orog, renamed relief to zmea_2d. In start_init_dyn, renamed
psol to ps.

In start_init_orog, renamed relief_hi to relief. No need to set
phis(iim + 1, :) = phis(1, :), already done in grid_noro.

Documentation for massbar out of SVN, in massbar.txt. Documentation
was duplicated in massdair, but not relevant in massdair.

In conflx, no need to initialize pen_[ud] and pde_[ud]. In flxasc,
used intermediary variable fact (following LMDZ).

In grid_noro, added local variable zmea0 for zmea not smoothed and
computed zphi from zmea instead of zmea0 (following LMDZ). This
changes the results of ce0l.

Removed arguments pen_u and pde_d of phytrac and nflxtr, which were
not used.

1 module flxasc_m
2
3 IMPLICIT none
4
5 contains
6
7 SUBROUTINE flxasc(pdtime, ptenh, pqenh, pten, pqen, pqsen, pgeo, pgeoh, &
8 pap, paph, pqte, pvervel, ldland, ldcum, ktype, klab, ptu, pqu, plu, &
9 pmfu, pmfub, pentr, pmfus, pmfuq, pmful, plude, pdmfup, kcbot, kctop, &
10 kctop0, kcum, pen_u, pde_u)
11
12 ! This routine does the calculations for cloud ascents for cumulus
13 ! parameterization.
14
15 USE dimphy, ONLY: klev, klon
16 use flxadjtq_m, only: flxadjtq
17 USE suphec_m, ONLY: rcpd, rd, retv, rg, rtt
18 USE yoecumf, ONLY: cmfcmin, cmfctop, cprcon, entrmid, lmfmid
19
20 REAL, intent(in):: pdtime
21 REAL, intent(in):: ptenh(klon, klev)
22 REAL, intent(in):: pqenh(klon, klev)
23 REAL, intent(in):: pten(klon, klev)
24 REAL, intent(in):: pqen(klon, klev)
25 REAL, intent(in):: pqsen(klon, klev)
26 REAL, intent(in):: pgeo(klon, klev), pgeoh(klon, klev)
27 REAL, intent(in):: pap(klon, klev), paph(klon, klev+1)
28 REAL, intent(in):: pqte(klon, klev)
29 REAL, intent(in):: pvervel(klon, klev) ! vitesse verticale en Pa/s
30 LOGICAL, intent(in):: ldland(klon)
31 LOGICAL, intent(inout):: ldcum(klon)
32 INTEGER, intent(inout):: ktype(klon)
33 integer klab(klon, klev)
34 REAL ptu(klon, klev), pqu(klon, klev), plu(klon, klev)
35 REAL pmfu(klon, klev)
36 REAL, intent(inout):: pmfub(klon)
37 real pentr(klon)
38 real pmfus(klon, klev)
39 REAL pmfuq(klon, klev), pmful(klon, klev)
40 REAL plude(klon, klev)
41 REAL pdmfup(klon, klev)
42 integer kcbot(klon), kctop(klon)
43 INTEGER kctop0(klon)
44 integer, intent(out):: kcum
45 REAL pen_u(klon, klev), pde_u(klon, klev)
46
47 ! Local:
48
49 REAL zqold(klon)
50 REAL zdland(klon)
51 LOGICAL llflag(klon)
52 INTEGER k, i, is, icall
53 REAL ztglace, zdphi, zqeen, zseen, zscde, zqude
54 REAL zmfusk, zmfuqk, zmfulk, zbuo, zdnoprc, zprcon, zlnew
55
56 REAL zpbot(klon), zptop(klon), zrho(klon)
57 REAL zdprho, zentr, zpmid, zmftest, zmfmax
58 LOGICAL llo1, llo2
59
60 REAL zwmax(klon), zzzmb
61 INTEGER klwmin(klon) ! level of maximum vertical velocity
62 real fact
63
64 !----------------------------------------------------------------------
65
66 ztglace = RTT - 13.
67
68 ! Chercher le niveau où la vitesse verticale est maximale :
69
70 DO i = 1, klon
71 klwmin(i) = klev
72 zwmax(i) = 0.0
73 ENDDO
74
75 DO k = klev, 3, -1
76 DO i = 1, klon
77 IF (pvervel(i, k) < zwmax(i)) THEN
78 zwmax(i) = pvervel(i, k)
79 klwmin(i) = k
80 ENDIF
81 ENDDO
82 ENDDO
83
84 ! Set default values:
85
86 DO i = 1, klon
87 IF (.NOT. ldcum(i)) ktype(i)=0
88 ENDDO
89
90 DO k=1, klev
91 DO i = 1, klon
92 plu(i, k)=0.
93 pmfu(i, k)=0.
94 pmfus(i, k)=0.
95 pmfuq(i, k)=0.
96 pmful(i, k)=0.
97 plude(i, k)=0.
98 pdmfup(i, k)=0.
99 IF (.NOT. ldcum(i) .OR. ktype(i) == 3) klab(i, k)=0
100 IF (.NOT. ldcum(i) .AND. paph(i, k) < 4e4) kctop0(i) = k
101 ENDDO
102 ENDDO
103
104 DO i = 1, klon
105 IF (ldland(i)) THEN
106 zdland(i)=3.0E4
107 zdphi=pgeoh(i, kctop0(i))-pgeoh(i, kcbot(i))
108 IF (ptu(i, kctop0(i)) >= ztglace) zdland(i)=zdphi
109 zdland(i)=MAX(3.0E4, zdland(i))
110 zdland(i)=MIN(5.0E4, zdland(i))
111 ENDIF
112 ENDDO
113
114 ! Initialiser les valeurs au niveau d'ascendance
115
116 DO i = 1, klon
117 kctop(i) = klev-1
118 IF (.NOT. ldcum(i)) THEN
119 kcbot(i) = klev-1
120 pmfub(i) = 0.
121 pqu(i, klev) = 0.
122 ENDIF
123 pmfu(i, klev) = pmfub(i)
124 pmfus(i, klev) = pmfub(i) * (RCPD * ptu(i, klev)+pgeoh(i, klev))
125 pmfuq(i, klev) = pmfub(i) * pqu(i, klev)
126 ENDDO
127
128 DO i = 1, klon
129 ldcum(i) = .FALSE.
130 ENDDO
131
132 ! Do ascent: subcloud layer (klab=1), clouds (klab=2) by doing
133 ! first dry-adiabatic ascent and then by adjusting t, q and l
134 ! accordingly in flxadjtq, then check for buoyancy and set flags
135 ! accordingly.
136
137 DO k = klev - 1, 3, -1
138 IF (LMFMID .AND. k < klev - 1 .AND. k > klev / 2) THEN
139 DO i = 1, klon
140 IF (.NOT. ldcum(i) .AND. klab(i, k + 1) == 0 .AND. &
141 pqen(i, k) > 0.9 * pqsen(i, k)) THEN
142 ptu(i, k+1) = pten(i, k) +(pgeo(i, k)-pgeoh(i, k+1))/RCPD
143 pqu(i, k+1) = pqen(i, k)
144 plu(i, k+1) = 0.0
145 zzzmb = MAX(CMFCMIN, -pvervel(i, k)/RG)
146 zmfmax = (paph(i, k) - paph(i, k-1)) / (RG * pdtime)
147 pmfub(i) = MIN(zzzmb, zmfmax)
148 pmfu(i, k+1) = pmfub(i)
149 pmfus(i, k+1) = pmfub(i) * (RCPD * ptu(i, k+1)+pgeoh(i, k+1))
150 pmfuq(i, k+1) = pmfub(i) * pqu(i, k+1)
151 pmful(i, k+1) = 0.0
152 pdmfup(i, k+1) = 0.0
153 kcbot(i) = k
154 klab(i, k+1) = 1
155 ktype(i) = 3
156 pentr(i) = ENTRMID
157 ENDIF
158 ENDDO
159 ENDIF
160
161 is = 0
162 DO i = 1, klon
163 is = is + klab(i, k+1)
164 IF (klab(i, k+1) == 0) klab(i, k) = 0
165 llflag(i) = .FALSE.
166 IF (klab(i, k+1) > 0) llflag(i) = .TRUE.
167 ENDDO
168 IF (is == 0) cycle
169
170 ! Calculer le taux d'entraînement et de détraînement :
171
172 DO i = 1, klon
173 pen_u(i, k) = 0.0
174 pde_u(i, k) = 0.0
175 zrho(i) = paph(i, k + 1) / (RD * ptenh(i, k + 1))
176 zpbot(i) = paph(i, kcbot(i))
177 zptop(i) = paph(i, kctop0(i))
178 ENDDO
179
180 DO i = 1, klon
181 IF (ldcum(i)) THEN
182 zdprho = (paph(i, k + 1) - paph(i, k)) / (RG * zrho(i))
183 zentr=pentr(i) * pmfu(i, k+1) * zdprho
184 llo1=k < kcbot(i)
185 IF (llo1) pde_u(i, k)=zentr
186 zpmid=0.5 * (zpbot(i)+zptop(i))
187 llo2 = llo1 .AND. ktype(i) == 2 &
188 .AND. (zpbot(i) - paph(i, k) < 0.2E5 .OR. paph(i, k) > zpmid)
189 IF (llo2) pen_u(i, k)=zentr
190 llo2 = llo1 .AND. (ktype(i) == 1 .OR. ktype(i) == 3) .AND. &
191 (k >= MAX(klwmin(i), kctop0(i) + 2) .OR. pap(i, k) > zpmid)
192 IF (llo2) pen_u(i, k)=zentr
193 llo1=pen_u(i, k) > 0. .AND. (ktype(i) == 1 .OR. ktype(i) == 2)
194 IF (llo1) THEN
195 fact = 1. + 3. * (1. - MIN(1., (zpbot(i) - pap(i, k)) / 1.5E4))
196 zentr = zentr * fact
197 pen_u(i, k)=pen_u(i, k) * fact
198 pde_u(i, k)=pde_u(i, k) * fact
199 ENDIF
200 IF (llo2 .AND. pqenh(i, k+1) > 1e-5) &
201 pen_u(i, k)=zentr+MAX(pqte(i, k), 0.)/pqenh(i, k+1) * &
202 zrho(i) * zdprho
203 ENDIF
204 end DO
205
206 ! Do adiabatic ascent for entraining/detraining plume
207
208 DO i = 1, klon
209 IF (llflag(i)) THEN
210 IF (k < kcbot(i)) THEN
211 zmftest = pmfu(i, k+1)+pen_u(i, k)-pde_u(i, k)
212 zmfmax = MIN(zmftest, &
213 (paph(i, k) - paph(i, k - 1)) / (RG * pdtime))
214 pen_u(i, k)=MAX(pen_u(i, k)-MAX(0.0, zmftest-zmfmax), 0.0)
215 ENDIF
216 pde_u(i, k)=MIN(pde_u(i, k), 0.75 * pmfu(i, k+1))
217 ! calculer le flux de masse du niveau k a partir de celui du k+1
218 pmfu(i, k)=pmfu(i, k+1)+pen_u(i, k)-pde_u(i, k)
219 ! calculer les valeurs Su, Qu et l du niveau k dans le
220 ! panache montant
221 zqeen=pqenh(i, k+1) * pen_u(i, k)
222 zseen=(RCPD * ptenh(i, k+1)+pgeoh(i, k+1)) * pen_u(i, k)
223 zscde=(RCPD * ptu(i, k+1)+pgeoh(i, k+1)) * pde_u(i, k)
224 zqude=pqu(i, k+1) * pde_u(i, k)
225 plude(i, k)=plu(i, k+1) * pde_u(i, k)
226 zmfusk=pmfus(i, k+1)+zseen-zscde
227 zmfuqk=pmfuq(i, k+1)+zqeen-zqude
228 zmfulk=pmful(i, k+1) -plude(i, k)
229 plu(i, k)=zmfulk * (1./MAX(CMFCMIN, pmfu(i, k)))
230 pqu(i, k)=zmfuqk * (1./MAX(CMFCMIN, pmfu(i, k)))
231 ptu(i, k)=(zmfusk * (1./MAX(CMFCMIN, pmfu(i, k)))- &
232 pgeoh(i, k))/RCPD
233 ptu(i, k)=MAX(100., ptu(i, k))
234 ptu(i, k)=MIN(400., ptu(i, k))
235 zqold(i)=pqu(i, k)
236 ELSE
237 zqold(i)=0.0
238 ENDIF
239 end DO
240
241 ! Do corrections for moist ascent by adjusting t, q and l
242
243 icall = 1
244 CALL flxadjtq(paph(1, k), ptu(1, k), pqu(1, k), llflag, icall)
245
246 DO i = 1, klon
247 IF (llflag(i) .AND. pqu(i, k).NE.zqold(i)) THEN
248 klab(i, k) = 2
249 plu(i, k) = plu(i, k)+zqold(i)-pqu(i, k)
250 zbuo = ptu(i, k) * (1.+RETV * pqu(i, k))- &
251 ptenh(i, k) * (1.+RETV * pqenh(i, k))
252 IF (klab(i, k+1) == 1) zbuo=zbuo+0.5
253 IF (zbuo > 0. .AND. pmfu(i, k) >= 0.1 * pmfub(i)) THEN
254 kctop(i) = k
255 ldcum(i) = .TRUE.
256 zdnoprc = 1.5E4
257 IF (ldland(i)) zdnoprc = zdland(i)
258 zprcon = CPRCON
259 IF ((zpbot(i) - paph(i, k)) < zdnoprc) zprcon = 0.
260 zlnew=plu(i, k)/(1.+zprcon * (pgeoh(i, k)-pgeoh(i, k+1)))
261 pdmfup(i, k)=MAX(0., (plu(i, k)-zlnew) * pmfu(i, k))
262 plu(i, k)=zlnew
263 ELSE
264 klab(i, k)=0
265 pmfu(i, k)=0.
266 ENDIF
267 ENDIF
268 end DO
269 DO i = 1, klon
270 IF (llflag(i)) THEN
271 pmful(i, k)=plu(i, k) * pmfu(i, k)
272 pmfus(i, k)=(RCPD * ptu(i, k)+pgeoh(i, k)) * pmfu(i, k)
273 pmfuq(i, k)=pqu(i, k) * pmfu(i, k)
274 ENDIF
275 end DO
276 end DO
277
278 ! Determine convective fluxes above non-buoyancy level (note:
279 ! cloud variables like t, q and l are not affected by detrainment
280 ! and are already known from previous calculations above).
281
282 DO i = 1, klon
283 IF (kctop(i) == klev-1) ldcum(i) = .FALSE.
284 kcbot(i) = MAX(kcbot(i), kctop(i))
285 ENDDO
286
287 ldcum(1)=ldcum(1)
288
289 is = 0
290 DO i = 1, klon
291 if (ldcum(i)) is = is + 1
292 ENDDO
293 kcum = is
294 IF (is /= 0) then
295 DO i = 1, klon
296 IF (ldcum(i)) THEN
297 k=kctop(i)-1
298 pde_u(i, k)=(1.-CMFCTOP) * pmfu(i, k+1)
299 plude(i, k)=pde_u(i, k) * plu(i, k+1)
300 pmfu(i, k)=pmfu(i, k+1)-pde_u(i, k)
301 zlnew=plu(i, k)
302 pdmfup(i, k)=MAX(0., (plu(i, k)-zlnew) * pmfu(i, k))
303 plu(i, k)=zlnew
304 pmfus(i, k)=(RCPD * ptu(i, k)+pgeoh(i, k)) * pmfu(i, k)
305 pmfuq(i, k)=pqu(i, k) * pmfu(i, k)
306 pmful(i, k)=plu(i, k) * pmfu(i, k)
307 plude(i, k-1)=pmful(i, k)
308 ENDIF
309 end DO
310 end IF
311
312 END SUBROUTINE flxasc
313
314 end module flxasc_m

  ViewVC Help
Powered by ViewVC 1.1.21