/[lmdze]/trunk/Sources/phylmd/CV30_routines/cv30_unsat.f
ViewVC logotype

Contents of /trunk/Sources/phylmd/CV30_routines/cv30_unsat.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 205 - (show annotations)
Tue Jun 21 15:16:03 2016 UTC (7 years, 10 months ago) by guez
File size: 11463 byte(s)
dnwd0 is just - mp. Compute it simply in concvl.

da, phi and mp were set to 0 in physiq before the call to
concvl. Clearer to set da1, phi1 and mp1 to 0 in cv_driver so they are
intent out.

qcheck was debugging, printed to standard output and was called
several times per time step of physics.

zxtsol was a duplicate of ztsol.

1 module cv30_unsat_m
2
3 implicit none
4
5 contains
6
7 SUBROUTINE cv30_unsat(icb, inb, t, q, qs, gz, u, v, p, ph, th, tv, lv, cpn, &
8 ep, clw, m, ment, elij, delt, plcl, mp, qp, up, vp, wt, water, evap, b)
9
10 ! Unsaturated (precipitating) downdrafts
11
12 use cv30_param_m, only: nl, sigd
13 use cv_thermo_m, only: ginv
14 use SUPHEC_M, only: rg, rcpd
15
16 integer, intent(in):: icb(:) ! (ncum)
17 ! {2 <= icb <= nl - 3}
18
19 integer, intent(in):: inb(:) ! (ncum)
20 ! first model level above the level of neutral buoyancy of the
21 ! parcel (1 <= inb <= nl - 1)
22
23 real, intent(in):: t(:, :) ! (ncum, nl) temperature (K)
24 real, intent(in):: q(:, :), qs(:, :) ! (ncum, nl)
25 real, intent(in):: gz(:, :) ! (klon, klev)
26 real, intent(in):: u(:, :), v(:, :) ! (ncum, nl)
27 real, intent(in):: p(:, :) ! (klon, klev) pressure at full level, in hPa
28 real, intent(in):: ph(:, :) ! (ncum, klev + 1)
29 real, intent(in):: th(:, :) ! (ncum, nl - 1) potential temperature, in K
30 real, intent(in):: tv(:, :) ! (klon, klev)
31
32 real, intent(in):: lv(:, :) ! (ncum, nl)
33 ! specific latent heat of vaporization of water, in J kg-1
34
35 real, intent(in):: cpn(:, :) ! (ncum, nl)
36 ! specific heat capacity at constant pressure of humid air, in J K-1 kg-1
37
38 real, intent(in):: ep(:, :) ! (ncum, klev)
39 real, intent(in):: clw(:, :) ! (ncum, klev)
40 real, intent(in):: m(:, :) ! (ncum, klev)
41 real, intent(in):: ment(:, :, :) ! (ncum, klev, klev)
42 real, intent(in):: elij(:, :, :) ! (ncum, klev, klev)
43 real, intent(in):: delt
44 real, intent(in):: plcl(:) ! (ncum)
45
46 real, intent(out):: mp(:, :)
47 ! (ncum, nl) Mass flux of the unsaturated downdraft, defined
48 ! positive downward, in kg m-2 s-1. M_p in Emanuel (1991 928).
49
50 real, intent(out):: qp(:, :), up(:, :), vp(:, :) ! (ncum, nl)
51 real, intent(out):: wt(:, :) ! (ncum, nl)
52
53 real, intent(out):: water(:, :) ! (ncum, nl)
54 ! precipitation mixing ratio, l_p in Emanuel (1991 928)
55
56 real, intent(out):: evap(:, :) ! (ncum, nl)
57 ! sigt * rate of evaporation of precipitation, in s-1
58 ! \sigma_s E in Emanuel (1991 928)
59
60 real, intent(out):: b(:, :) ! (ncum, nl - 1)
61
62 ! Local:
63
64 real, parameter:: sigp = 0.15
65 ! fraction of precipitation falling outside of cloud, \sig_s in
66 ! Emanuel (1991 928)
67
68 integer ncum
69 integer i, il, imax
70 real, parameter:: tinv = 1. / 3.
71 real delti
72 real afac, afac1, afac2, bfac
73 real pr1, sigt, b6, c6, revap, tevap
74 real xf, tf, fac2, ur, sru, fac, d, af, bf
75 real ampmax
76 real lvcp(size(icb), nl) ! (ncum, nl) L_v / C_p, in K
77 real wdtrain(size(icb)) ! (ncum)
78 logical lwork(size(icb)) ! (ncum)
79
80 !------------------------------------------------------
81
82 ncum = size(icb)
83 delti = 1. / delt
84 mp = 0.
85 b = 0.
86
87 do i = 1, nl
88 do il = 1, ncum
89 qp(il, i) = q(il, i)
90 up(il, i) = u(il, i)
91 vp(il, i) = v(il, i)
92 wt(il, i) = 0.001
93 water(il, i) = 0.
94 evap(il, i) = 0.
95 lvcp(il, i) = lv(il, i) / cpn(il, i)
96 enddo
97 enddo
98
99 ! Check whether ep(inb) = 0. If so, skip precipitating downdraft
100 ! calculation.
101
102 forall (il = 1:ncum) lwork(il) = ep(il, inb(il)) >= 1e-4
103
104 imax = nl - 1
105 do while (.not. any(inb >= imax .and. lwork) .and. imax >= 1)
106 imax = imax - 1
107 end do
108
109 downdraft_loop: DO i = imax, 1, - 1
110 ! Integrate liquid water equation to find condensed water
111 ! and condensed water flux
112
113 ! Calculate detrained precipitation
114 forall (il = 1:ncum, inb(il) >= i .and. lwork(il)) wdtrain(il) = rg &
115 * (ep(il, i) * m(il, i) * clw(il, i) &
116 + sum(max(elij(il, :i - 1, i) - (1. - ep(il, i)) * clw(il, i), 0.) &
117 * ment(il, :i - 1, i)))
118
119 ! Find rain water and evaporation using provisional
120 ! estimates of qp(i) and qp(i - 1)
121
122 loop_horizontal: do il = 1, ncum
123 if (i <= inb(il) .and. lwork(il)) then
124 wt(il, i) = 45.
125
126 if (i < inb(il)) then
127 qp(il, i) = qp(il, i + 1) + (rcpd * (t(il, i + 1) - t(il, i)) &
128 + gz(il, i + 1) - gz(il, i)) / lv(il, i)
129 qp(il, i) = 0.5 * (qp(il, i) + q(il, i))
130 endif
131
132 qp(il, i) = max(qp(il, i), 0.)
133 qp(il, i) = min(qp(il, i), qs(il, i))
134 qp(il, inb(il)) = q(il, inb(il))
135
136 if (i == 1) then
137 afac = p(il, 1) * (qs(il, 1) - qp(il, 1)) &
138 / (1e4 + 2000. * p(il, 1) * qs(il, 1))
139 else
140 qp(il, i - 1) = qp(il, i) + (rcpd * (t(il, i) - t(il, i - 1)) &
141 + gz(il, i) - gz(il, i - 1)) / lv(il, i)
142 qp(il, i - 1) = 0.5 * (qp(il, i - 1) + q(il, i - 1))
143 qp(il, i - 1) = min(qp(il, i - 1), qs(il, i - 1))
144 qp(il, i - 1) = max(qp(il, i - 1), 0.)
145 afac1 = p(il, i) * (qs(il, i) - qp(il, i)) &
146 / (1e4 + 2000. * p(il, i) * qs(il, i))
147 afac2 = p(il, i - 1) * (qs(il, i - 1) - qp(il, i - 1)) &
148 / (1e4 + 2000. * p(il, i - 1) * qs(il, i - 1))
149 afac = 0.5 * (afac1 + afac2)
150 endif
151
152 if (i == inb(il)) afac = 0.
153 afac = max(afac, 0.)
154 bfac = 1. / (sigd * wt(il, i))
155
156 if (i <= icb(il)) then
157 ! Prise en compte de la variation progressive de sigt dans
158 ! les couches icb et icb - 1 :
159 ! pour plcl <= ph(i + 1), pr1 = 0
160 ! pour plcl >= ph(i), pr1 = 1
161 ! pour ph(i + 1) < plcl < ph(i), pr1 est la proportion
162 ! \`a cheval sur le nuage.
163 pr1 = max(0., min(1., &
164 (plcl(il) - ph(il, i + 1)) / (ph(il, i) - ph(il, i + 1))))
165 sigt = sigp * pr1 + 1. - pr1
166 else
167 ! {i >= icb(il) + 1}
168 sigt = sigp
169 end if
170
171 b6 = bfac * 50. * sigd * (ph(il, i) - ph(il, i + 1)) * sigt * afac
172 c6 = water(il, i + 1) + bfac * wdtrain(il) - 50. * sigd * bfac &
173 * (ph(il, i) - ph(il, i + 1)) * evap(il, i + 1)
174
175 if (c6 > 0.) then
176 revap = 0.5 * (- b6 + sqrt(b6 * b6 + 4. * c6))
177 evap(il, i) = sigt * afac * revap
178 water(il, i) = revap * revap
179 else
180 evap(il, i) = - evap(il, i + 1) + 0.02 * (wdtrain(il) + sigd &
181 * wt(il, i) * water(il, i + 1)) / (sigd * (ph(il, i) &
182 - ph(il, i + 1)))
183 end if
184
185 ! Calculate precipitating downdraft mass flux under
186 ! hydrostatic approximation
187
188 test_above_surface: if (i /= 1) then
189 tevap = max(0., evap(il, i))
190 mp(il, i) = 100. * ginv * lvcp(il, i) * sigd * tevap &
191 * (p(il, i - 1) - p(il, i)) &
192 / max(0.001, th(il, i) - th(il, i - 1))
193
194 ! If hydrostatic assumption fails, solve cubic
195 ! difference equation for downdraft theta and mass
196 ! flux from two simultaneous differential equations
197 if (abs(mp(il, i + 1)**2 - mp(il, i)**2) > 0.1 * sigd**2 &
198 * 70. * ph(il, i) * (p(il, i - 1) - p(il, i)) &
199 * (th(il, i) - th(il, i - 1)) / (tv(il, i) * th(il, i))) &
200 then
201 xf = 100. * sigd**3 * (ph(il, i) - ph(il, i + 1))
202 tf = b(il, i) - 5. * (th(il, i) - th(il, i - 1)) &
203 * t(il, i) / (lvcp(il, i) * sigd * th(il, i))
204 af = xf * tf + mp(il, i + 1)**2 * tinv
205 bf = 2. * (tinv * mp(il, i + 1))**3 + tinv &
206 * mp(il, i + 1) * xf * tf + 50. * (p(il, i - 1) &
207 - p(il, i)) * xf * tevap
208 fac2 = 1.
209 if (bf < 0.) fac2 = - 1.
210 bf = abs(bf)
211 ur = 0.25 * bf * bf - af * af * af * tinv * tinv * tinv
212
213 if (ur >= 0.) then
214 sru = sqrt(ur)
215 fac = 1.
216 if ((0.5 * bf - sru) < 0.) fac = - 1.
217 mp(il, i) = mp(il, i + 1) * tinv + (0.5 * bf &
218 + sru)**tinv + fac * (abs(0.5 * bf - sru))**tinv
219 else
220 d = atan(2. * sqrt(- ur) / (bf + 1e-28))
221 if (fac2 < 0.) d = 3.14159 - d
222 mp(il, i) = mp(il, i + 1) * tinv + 2. * sqrt(af * tinv) &
223 * cos(d * tinv)
224 endif
225
226 mp(il, i) = max(0., mp(il, i))
227
228 ! Il y a vraisemblablement une erreur dans la ligne
229 ! suivante : il faut diviser par (mp(il, i) * sigd
230 ! * rg) et non par (mp(il, i) + sigd * 0.1). Et il
231 ! faut bien revoir les facteurs 100.
232 b(il, i - 1) = max(b(il, i) + 100. * (p(il, i - 1) &
233 - p(il, i)) * tevap / (mp(il, i) + sigd * 0.1) - 10. &
234 * (th(il, i) - th(il, i - 1)) * t(il, i) &
235 / (lvcp(il, i) * sigd * th(il, i)), 0.)
236 endif
237
238 ! Limit magnitude of mp to meet CFL condition:
239 ampmax = 2. * (ph(il, i) - ph(il, i + 1)) * delti
240 ampmax = min(ampmax, 2. * (ph(il, i - 1) - ph(il, i)) * delti)
241 mp(il, i) = min(mp(il, i), ampmax)
242
243 ! Force mp to decrease linearly to zero between cloud
244 ! base and the surface:
245 if (p(il, i) > p(il, icb(il))) mp(il, i) = mp(il, icb(il)) &
246 * (p(il, 1) - p(il, i)) / (p(il, 1) - p(il, icb(il)))
247 endif test_above_surface
248
249 ! Find mixing ratio of precipitating downdraft
250
251 if (i /= inb(il)) then
252 qp(il, i) = q(il, i)
253
254 if (mp(il, i) > mp(il, i + 1)) then
255 qp(il, i) = qp(il, i + 1) * mp(il, i + 1) + q(il, i) &
256 * (mp(il, i) - mp(il, i + 1)) + 100. * ginv * 0.5 &
257 * sigd * (ph(il, i) - ph(il, i + 1)) &
258 * (evap(il, i + 1) + evap(il, i))
259 qp(il, i) = qp(il, i) / mp(il, i)
260 up(il, i) = up(il, i + 1) * mp(il, i + 1) + u(il, i) &
261 * (mp(il, i) - mp(il, i + 1))
262 up(il, i) = up(il, i) / mp(il, i)
263 vp(il, i) = vp(il, i + 1) * mp(il, i + 1) + v(il, i) &
264 * (mp(il, i) - mp(il, i + 1))
265 vp(il, i) = vp(il, i) / mp(il, i)
266 else
267 if (mp(il, i + 1) > 1e-16) then
268 qp(il, i) = qp(il, i + 1) + 100. * ginv * 0.5 * sigd &
269 * (ph(il, i) - ph(il, i + 1)) * (evap(il, i + 1) &
270 + evap(il, i)) / mp(il, i + 1)
271 up(il, i) = up(il, i + 1)
272 vp(il, i) = vp(il, i + 1)
273 endif
274 endif
275
276 qp(il, i) = min(qp(il, i), qs(il, i))
277 qp(il, i) = max(qp(il, i), 0.)
278 endif
279 endif
280 end do loop_horizontal
281 end DO downdraft_loop
282
283 end SUBROUTINE cv30_unsat
284
285 end module cv30_unsat_m

  ViewVC Help
Powered by ViewVC 1.1.21