7 public :: snow_moments, calc_gamma_p, get_nuc, get_constant_cloud_number, &
8 calc_rslf, calc_rsif, compute_efrw, compute_efsw, compute_drop_evap, qi_aut_qs
12 subroutine get_constant_cloud_number(land, nc)
17 integer,
intent(in),
optional :: land
18 real(wp),
dimension(:),
intent(out) :: nc
21 if (
present(land))
then
22 if (land /= 1) nc = nt_c_o
24 end subroutine get_constant_cloud_number
27 function calc_gamma_p(a, x)
result(gamma_p)
34 real(wp),
intent(in) :: a, x
37 if ((x < 0.0_wp) .or. (a <= 0.0_wp))
then
38 write(*,*)
"Invalid arguments for function gamma_p"
45 if (x < (a + 1.0_wp))
then
46 gamma_p = calc_gamma_series(a, x)
49 gamma_p = 1.0_wp - calc_gamma_cf(a, x)
51 end function calc_gamma_p
54 function calc_gamma_series(a, x)
result(gamma_series)
72 real(wp),
intent(in) :: a, x
74 integer,
parameter :: it_max = 100
75 real(wp),
parameter :: smallvalue = 1.e-7_wp
76 real(wp) :: aj, sum_term, sum
77 real(wp) :: gamma_series
82 sum_term = 1.0_wp / gamma(aj+1.0_wp)
86 sum_term = sum_term * x / aj
88 if (abs(sum_term) < (abs(sum) * smallvalue))
exit
91 gamma_series = sum * x**a * exp(-x)
92 end function calc_gamma_series
95 function calc_gamma_cf(a, x)
result(gamma_cf)
115 real(wp),
intent(in) :: a, x
117 integer,
parameter :: it_max = 100
118 real(wp),
parameter :: smallvalue = 1.e-7_wp
119 real(wp),
parameter :: offset = 1.e-30_wp
120 real(wp) :: b, d, f0, c, delta, f, aj
127 c = b + (1.0_wp / f0)
135 if(abs(d) < offset) d = offset
137 if(abs(c) < offset) c = offset
141 if (abs(delta-1.0_wp) < smallvalue)
exit
144 gamma_cf = exp(-x+a*log(x)) * f / gamma(a)
145 end function calc_gamma_cf
148 subroutine snow_moments(rs, tc, smob, smoc, ns, smo0, smo1, smo2, smoe, smof, smog, smoz)
162 oams, cse, csg, lam0, lam1, kap0, kap1, mu_s
164 real(wp),
intent(in) :: rs, tc
165 real(dp) :: loga_, a_, b_, smo2_, m0, mrat, slam1, slam2
166 real(dp),
intent(out) :: smob, smoc
167 real(dp),
intent(out),
optional :: ns, smo0, smo1, smo2, smoe, smof, smog, smoz
170 smob = real(rs*oams, kind=dp)
171 if (bm_s > 2.0_wp-1.e-3_wp .and. bm_s < 2.0_wp+1.e-3_wp)
then
172 loga_ = sa(1) + sa(2)*tc + sa(3)*bm_s &
173 + sa(4)*tc*bm_s + sa(5)*tc*tc &
174 + sa(6)*bm_s*bm_s + sa(7)*tc*tc*bm_s &
175 + sa(8)*tc*bm_s*bm_s + sa(9)*tc*tc*tc &
176 + sa(10)*bm_s*bm_s*bm_s
178 b_ = sb(1) + sb(2)*tc + sb(3)*bm_s &
179 + sb(4)*tc*bm_s + sb(5)*tc*tc &
180 + sb(6)*bm_s*bm_s + sb(7)*tc*tc*bm_s &
181 + sb(8)*tc*bm_s*bm_s + sb(9)*tc*tc*tc &
182 + sb(10)*bm_s*bm_s*bm_s
183 smo2_ = (smob/a_)**(1._wp/b_)
187 if (
present(smo2)) smo2 = smo2_
190 loga_ = sa(1) + sa(2)*tc + sa(3)*cse(1) &
191 + sa(4)*tc*cse(1) + sa(5)*tc*tc &
192 + sa(6)*cse(1)*cse(1) + sa(7)*tc*tc*cse(1) &
193 + sa(8)*tc*cse(1)*cse(1) + sa(9)*tc*tc*tc &
194 + sa(10)*cse(1)*cse(1)*cse(1)
196 b_ = sb(1)+sb(2)*tc+sb(3)*cse(1) + sb(4)*tc*cse(1) &
197 + sb(5)*tc*tc + sb(6)*cse(1)*cse(1) &
198 + sb(7)*tc*tc*cse(1) + sb(8)*tc*cse(1)*cse(1) &
199 + sb(9)*tc*tc*tc+sb(10)*cse(1)*cse(1)*cse(1)
200 smoc = a_ * smo2_**b_
203 loga_ = sa(1) + sa(2)*tc + sa(5)*tc*tc + sa(9)*tc*tc*tc
205 b_ = sb(1) + sb(2)*tc + sb(5)*tc*tc + sb(9)*tc*tc*tc
206 if (
present(smo0)) smo0 = a_ * smo2_**b_
209 loga_ = sa(1) + sa(2)*tc + sa(3) &
210 + sa(4)*tc + sa(5)*tc*tc &
211 + sa(6) + sa(7)*tc*tc &
212 + sa(8)*tc + sa(9)*tc*tc*tc &
215 b_ = sb(1)+ sb(2)*tc + sb(3) + sb(4)*tc &
216 + sb(5)*tc*tc + sb(6) &
217 + sb(7)*tc*tc + sb(8)*tc &
218 + sb(9)*tc*tc*tc + sb(10)
219 if (
present(smo1)) smo1 = a_ * smo2_**b_
226 if (
present(ns))
then
227 ns = mrat*kap0/slam1 + mrat*kap1*m0**mu_s*csg(15)/slam2**cse(15)
231 loga_ = sa(1) + sa(2)*tc + sa(3)*cse(13) &
232 + sa(4)*tc*cse(13) + sa(5)*tc*tc &
233 + sa(6)*cse(13)*cse(13) + sa(7)*tc*tc*cse(13) &
234 + sa(8)*tc*cse(13)*cse(13) + sa(9)*tc*tc*tc &
235 + sa(10)*cse(13)*cse(13)*cse(13)
237 b_ = sb(1)+ sb(2)*tc + sb(3)*cse(13) + sb(4)*tc*cse(13) &
238 + sb(5)*tc*tc + sb(6)*cse(13)*cse(13) &
239 + sb(7)*tc*tc*cse(13) + sb(8)*tc*cse(13)*cse(13) &
240 + sb(9)*tc*tc*tc + sb(10)*cse(13)*cse(13)*cse(13)
241 if (
present(smoe)) smoe = a_ * smo2_**b_
244 loga_ = sa(1) + sa(2)*tc + sa(3)*cse(16) &
245 + sa(4)*tc*cse(16) + sa(5)*tc*tc &
246 + sa(6)*cse(16)*cse(16) + sa(7)*tc*tc*cse(16) &
247 + sa(8)*tc*cse(16)*cse(16) + sa(9)*tc*tc*tc &
248 + sa(10)*cse(16)*cse(16)*cse(16)
250 b_ = sb(1)+ sb(2)*tc + sb(3)*cse(16) + sb(4)*tc*cse(16) &
251 + sb(5)*tc*tc + sb(6)*cse(16)*cse(16) &
252 + sb(7)*tc*tc*cse(16) + sb(8)*tc*cse(16)*cse(16) &
253 + sb(9)*tc*tc*tc + sb(10)*cse(16)*cse(16)*cse(16)
254 if (
present(smof)) smof = a_ * smo2_**b_
257 loga_ = sa(1) + sa(2)*tc + sa(3)*cse(17) &
258 + sa(4)*tc*cse(17) + sa(5)*tc*tc &
259 + sa(6)*cse(17)*cse(17) + sa(7)*tc*tc*cse(17) &
260 + sa(8)*tc*cse(17)*cse(17) + sa(9)*tc*tc*tc &
261 + sa(10)*cse(17)*cse(17)*cse(17)
263 b_ = sb(1)+ sb(2)*tc + sb(3)*cse(17) + sb(4)*tc*cse(17) &
264 + sb(5)*tc*tc + sb(6)*cse(17)*cse(17) &
265 + sb(7)*tc*tc*cse(17) + sb(8)*tc*cse(17)*cse(17) &
266 + sb(9)*tc*tc*tc + sb(10)*cse(17)*cse(17)*cse(17)
267 if (
present(smog)) smog = a_ * smo2_**b_
270 loga_ = sa(1) + sa(2)*tc + sa(3)*cse(3) &
271 + sa(4)*tc*cse(3) + sa(5)*tc*tc &
272 + sa(6)*cse(3)*cse(3) + sa(7)*tc*tc*cse(3) &
273 + sa(8)*tc*cse(3)*cse(3) + sa(9)*tc*tc*tc &
274 + sa(10)*cse(3)*cse(3)*cse(3)
276 b_ = sb(1)+ sb(2)*tc + sb(3)*cse(3) + sb(4)*tc*cse(3) &
277 + sb(5)*tc*tc + sb(6)*cse(3)*cse(3) &
278 + sb(7)*tc*tc*cse(3) + sb(8)*tc*cse(3)*cse(3) &
279 + sb(9)*tc*tc*tc + sb(10)*cse(3)*cse(3)*cse(3)
280 if (
present(smoz)) smoz = a_ * smo2**b_
282 end subroutine snow_moments
285 function calc_rslf(p, t)
result(rslf)
287 real(wp),
intent(in) :: p, t
289 real(wp),
parameter :: c0 = .611583699e03_wp
290 real(wp),
parameter :: c1 = .444606896e02_wp
291 real(wp),
parameter :: c2 = .143177157e01_wp
292 real(wp),
parameter :: c3 = .264224321e-1_wp
293 real(wp),
parameter :: c4 = .299291081e-3_wp
294 real(wp),
parameter :: c5 = .203154182e-5_wp
295 real(wp),
parameter :: c6 = .702620698e-8_wp
296 real(wp),
parameter :: c7 = .379534310e-11_wp
297 real(wp),
parameter :: c8 = -.321582393e-13_wp
300 x = max(-80._wp, t-273.16_wp)
301 esl = c0+x*(c1+x*(c2+x*(c3+x*(c4+x*(c5+x*(c6+x*(c7+x*c8)))))))
302 esl = min(esl, p*0.15)
308 rslf = .622*esl/(p-esl)
309 end function calc_rslf
312 function calc_rsif(p, t)
result(rsif)
314 real(wp),
intent(in) :: p, t
316 real(wp),
parameter :: c0 = .609868993e03_wp
317 real(wp),
parameter :: c1 = .499320233e02_wp
318 real(wp),
parameter :: c2 = .184672631e01_wp
319 real(wp),
parameter :: c3 = .402737184e-1_wp
320 real(wp),
parameter :: c4 = .565392987e-3_wp
321 real(wp),
parameter :: c5 = .521693933e-5_wp
322 real(wp),
parameter :: c6 = .307839583e-7_wp
323 real(wp),
parameter :: c7 = .105785160e-9_wp
324 real(wp),
parameter :: c8 = .161444444e-12_wp
327 x = max(-80._wp, t-273.16_wp)
328 esi = c0+x*(c1+x*(c2+x*(c3+x*(c4+x*(c5+x*(c6+x*(c7+x*c8)))))))
329 esi = min(esi, p*0.15)
330 rsif = .622*esi/max(1.e-4_wp,(p-esi))
331 end function calc_rsif
334 function get_nuc(nc)
result(nu_c)
338 real(wp),
intent(in) :: nc
341 if ((nu_c_scale/nc) >= 12.5_wp)
then
344 nu_c = min(15, nint(nu_c_scale/nc) + 2)
349 subroutine compute_efrw()
356 real(dp) :: vtr, stokes, reynolds, ef_rw
357 real(dp) :: p, yc0, f, g, h, z, k0, x
364 if (dr(i) < 50.e-6_dp .or. dc(j) < 3.e-6_dp)
then
366 elseif (p > 0.25_dp)
then
368 if (dr(i) < 75.e-6_dp)
then
369 ef_rw = 0.026794_dp*x - 0.20604_dp
370 elseif (dr(i) < 125.e-6_dp)
then
371 ef_rw = -0.00066842_dp*x*x + 0.061542_dp*x - 0.37089_dp
372 elseif (dr(i) < 175.e-6_dp)
then
373 ef_rw = 4.091e-06_dp*x*x*x*x - 0.00030908_dp*x*x*x + &
374 0.0066237_dp*x*x - 0.0013687_dp*x - 0.073022_dp
375 elseif (dr(i) < 250.e-6_dp)
then
376 ef_rw = 9.6719e-5_dp*x*x*x - 0.0068901_dp*x*x + 0.17305_dp*x - 0.65988_dp
377 elseif (dr(i) < 350.e-6_dp)
then
378 ef_rw = 9.0488e-5_dp*x*x*x - 0.006585_dp*x*x + 0.16606_dp*x - 0.56125_dp
380 ef_rw = 0.00010721_dp*x*x*x - 0.0072962_dp*x*x + 0.1704_dp*x - 0.46929_dp
383 vtr = -0.1021_dp + 4.932e3_dp*dr(i) - 0.9551e6_dp*dr(i)*dr(i) + 0.07934e9_dp*dr(i)*dr(i)*dr(i) &
384 - 0.002362e12_dp*dr(i)*dr(i)*dr(i)*dr(i)
385 stokes = dc(j) * dc(j) * vtr * rho_w / (9._dp*1.718e-5_dp*dr(i))
386 reynolds = 9._dp * stokes / (p*p*rho_w)
389 g = -0.1007_dp - 0.358_dp*f + 0.0261_dp*f*f
391 z = log(stokes / (k0+1.e-15_dp))
392 h = 0.1465_dp + 1.302_dp*z - 0.607_dp*z*z + 0.293_dp*z*z*z
393 yc0 = 2.0_dp / pi * atan(h)
394 ef_rw = (yc0+p)*(yc0+p) / ((1.+p)*(1.+p))
397 t_efrw(i,j) = max(0.0_dp, min(ef_rw, 0.95_dp))
400 end subroutine compute_efrw
403 subroutine compute_efsw()
408 nbc, dc, av_s, bv_s, ds, nbs, am_s, bm_s, am_r, obmr, fv_s, &
409 t_efsw, d0s, rho_w, pi
411 real(dp) :: ds_m, vts, vtc, stokes, reynolds, ef_sw
412 real(dp) :: p, yc0, f, g, h, z, k0
416 vtc = 1.19e4_dp * (1.0e4_dp*dc(j)*dc(j)*0.25_dp)
418 vts = av_s*ds(i)**bv_s * exp(real(-fv_s*ds(i), kind=dp)) - vtc
419 ds_m = (am_s*ds(i)**bm_s / am_r)**obmr
422 if (p > 0.25_dp .or. ds(i) < d0s .or. dc(j) < 6.e-6_dp .or. vts < 1.e-3_dp)
then
425 stokes = dc(j) * dc(j) * vts * rho_w / (9.*1.718e-5_dp*ds_m)
426 reynolds = 9._dp * stokes / (p*p*rho_w)
429 g = -0.1007_dp - 0.358_dp*f + 0.0261_dp*f*f
431 z = log(stokes / (k0+1.e-15_dp))
432 h = 0.1465_dp + 1.302_dp*z - 0.607_dp*z*z + 0.293_dp*z*z*z
433 yc0 = 2.0_dp / pi * atan(h)
434 ef_sw = (yc0+p)*(yc0+p) / ((1.+p)*(1.+p))
436 t_efsw(i,j) = max(0.0_dp, min(ef_sw, 0.95_dp))
440 end subroutine compute_efsw
443 subroutine qi_aut_qs()
451 nbi, ntb_i, ntb_i1, &
452 am_i, cie, cig, oig1, nt_i, r_i, obmi, bm_i, mu_i, d0s, d0i, &
453 tpi_ide, tps_iaus, tni_iaus, di, dti
456 real(dp),
dimension(nbi) :: n_i
457 real(dp) :: n0_i, lami, di_mean, t1, t2
458 real(wp) :: xlimit_intg
462 lami = (am_i*cig(2)*oig1*nt_i(j)/r_i(i))**obmi
463 di_mean = (bm_i + mu_i + 1.) / lami
464 n0_i = nt_i(j)*oig1 * lami**cie(1)
467 if (real(di_mean, kind=wp) > 5.*d0s)
then
471 elseif (real(di_mean, kind=wp) < d0i)
then
476 xlimit_intg = lami*d0s
477 tpi_ide(i,j) = real(calc_gamma_p(mu_i+2.0, xlimit_intg), kind=dp)
479 n_i(n2) = n0_i*di(n2)**mu_i * exp(-lami*di(n2))*dti(n2)
480 if (di(n2) >= d0s)
then
481 t1 = t1 + n_i(n2) * am_i*di(n2)**bm_i
490 end subroutine qi_aut_qs
493 subroutine compute_drop_evap()
496 nbc, am_r, dc, bm_r, nu_c_scale, nu_c_max, nu_c_min, &
497 t_nc, ntb_c, cce, ccg, ocg1, r_c, obmr, dtc, &
500 integer :: i, j, k, n
501 real(dp),
dimension(nbc) :: n_c, massc
502 real(dp) :: summ, summ2, lamc, n0_c
506 massc(n) = am_r*dc(n)**bm_r
510 nu_c = get_nuc(real(t_nc(k), kind=wp))
512 lamc = (t_nc(k)*am_r* ccg(2,nu_c)*ocg1(nu_c) / r_c(j))**obmr
513 n0_c = t_nc(k)*ocg1(nu_c) * lamc**cce(1,nu_c)
515 n_c(i) = n0_c* dc(i)**nu_c*exp(-lamc*dc(i))*dtc(i)
519 summ = summ + massc(n)*n_c(n)
520 summ2 = summ2 + n_c(n)
522 tpc_wev(i,j,k) = summ
523 tnc_wev(i,j,k) = summ2
527 end subroutine compute_drop_evap