/[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 196 - (show annotations)
Mon May 23 13:50:39 2016 UTC (7 years, 11 months ago) by guez
File size: 11201 byte(s)
Removed argument icbmax of cv30_feed, not used in cv_driver (not used
in LMDZ either).

Clearer to have iflag1 = 0 in cv30_feed than in cv_driver. Clearer to
have iflag1 = 42 in cv30_uncompress than in cv_driver.

Removed argument iflag of cv30_compress. Since there is iflag1 = 42 in
cv30_uncompress, iflag1 that comes out of cv_driver is disconnected
from iflag1 computed by cv30_feed and cv30_trigger.

Removed some references to convect3 and convect4 in comments. This
program derives from the convect3 version, we do not need to know
about other versions.

Bug fix in cv30_undilute1: icbs1 was not made >= 2.

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

  ViewVC Help
Powered by ViewVC 1.1.21