/[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 188 - (show annotations)
Tue Mar 22 16:31:39 2016 UTC (8 years, 2 months ago) by guez
File size: 11343 byte(s)
Removed argument ncum of cv30_unsat, arguments nloc, ncum, nd, na of cv30_yield.

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

  ViewVC Help
Powered by ViewVC 1.1.21