/[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 189 - (show annotations)
Tue Mar 29 15:20:23 2016 UTC (8 years, 1 month ago) by guez
File size: 11385 byte(s)
There was a function gr_phy_write_3d in dyn3d and a function
gr_phy_write_2d in module grid_change. Moved them into a new module
gr_phy_write_m under a generic interface gr_phy_write. Replaced calls
to gr_fi_ecrit by calls to gr_phy_write.

Removed arguments len, nloc and nd of cv30_compress.

Removed arguments wd and wd1 of cv30_uncompress, wd of cv30_yield, wd
of concvl, wd1 of cv_driver. Was just filled with 0. Removed option
ok_gust in physiq, never used.

In cv30_unsat, cv30_yield and cv_driver, we only need to define b to
level nl - 1.

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, sigp, clw, m, ment, elij, delt, plcl, mp, qp, up, vp, wt, water, &
9 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, intent(in):: t(:, :), q(:, :), qs(:, :) ! (klon, klev)
18 real, intent(in):: gz(:, :) ! (klon, klev)
19 real, intent(in):: u(:, :), 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, intent(out):: mp(klon, klev)
32 real, intent(out):: qp(:, :), up(:, :), vp(:, :) ! (ncum, nl)
33 real wt(klon, klev), water(klon, klev), evap(klon, klev)
34 real, intent(out):: b(:, :) ! (ncum, nl - 1)
35
36 ! Local:
37 integer ncum
38 integer i, j, il, num1
39 real tinv, delti
40 real awat, afac, afac1, afac2, bfac
41 real pr1, pr2, sigt, b6, c6, revap, tevap, delth
42 real amfac, amp2, xf, tf, fac2, ur, sru, fac, d, af, bf
43 real ampmax
44 real lvcp(klon, klev)
45 real wdtrain(size(icb))
46 logical lwork(size(icb))
47
48 !------------------------------------------------------
49
50 ncum = size(icb)
51 delti = 1. / delt
52 tinv = 1. / 3.
53 mp = 0.
54 b = 0.
55
56 do i = 1, nl
57 do il = 1, ncum
58 qp(il, i) = q(il, i)
59 up(il, i) = u(il, i)
60 vp(il, i) = v(il, i)
61 wt(il, i) = 0.001
62 water(il, i) = 0.
63 evap(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 qp(i) and qp(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 qp(il, i) = qp(il, i + 1) + (cpd * (t(il, i + 1) &
114 - t(il, i)) + gz(il, i + 1) - gz(il, i)) / lv(il, i)
115 qp(il, i) = 0.5 * (qp(il, i) + q(il, i))
116 endif
117
118 qp(il, i) = max(qp(il, i), 0.)
119 qp(il, i) = min(qp(il, i), qs(il, i))
120 qp(il, inb(il)) = q(il, inb(il))
121
122 if (i == 1) then
123 afac = p(il, 1) * (qs(il, 1) - qp(il, 1)) &
124 / (1e4 + 2000. * p(il, 1) * qs(il, 1))
125 else
126 qp(il, i - 1) = qp(il, i) + (cpd * (t(il, i) &
127 - t(il, i - 1)) + gz(il, i) - gz(il, i - 1)) / lv(il, i)
128 qp(il, i - 1) = 0.5 * (qp(il, i - 1) + q(il, i - 1))
129 qp(il, i - 1) = min(qp(il, i - 1), qs(il, i - 1))
130 qp(il, i - 1) = max(qp(il, i - 1), 0.)
131 afac1 = p(il, i) * (qs(il, i) - qp(il, i)) &
132 / (1e4 + 2000. * p(il, i) * qs(il, i))
133 afac2 = p(il, i - 1) * (qs(il, i - 1) - qp(il, i - 1)) &
134 / (1e4 + 2000. * p(il, i - 1) * qs(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 qp(il, i) = q(il, i)
246
247 if (mp(il, i) > mp(il, i + 1)) then
248 qp(il, i) = qp(il, i + 1) * mp(il, i + 1) + q(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 qp(il, i) = qp(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 qp(il, i) = qp(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 qp(il, i) = min(qp(il, i), qs(il, i))
270 qp(il, i) = max(qp(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