5 min_qv, roverrv, rdry, r1, r2, nt_c_max, t0, nrhg, rho_g, &
6 meters3_to_liters, eps, aero_max, nwfa_default, nifa_default, nt_c_l, nt_c_o
7 use module_mp_tempo_utils,
only : get_nuc, get_constant_cloud_number, snow_moments, calc_rslf, calc_rsif
11 aerosol_collection_efficiency
20 public :: cloud_check_and_update, ice_check_and_update, snow_check_and_update
24 public :: get_cloud_table_index, get_snow_table_index, &
25 get_temperature_table_index, get_rain_table_index, &
26 get_graupel_table_index, get_ice_table_index
30 real(wp) :: rain_precip
31 real(wp) :: cloud_precip
32 real(wp) :: ice_liquid_equiv_precip
33 real(wp) :: snow_liquid_equiv_precip
34 real(wp) :: graupel_liquid_equiv_precip
35 real(wp) :: frozen_fraction
36 real(wp) :: frz_rain_precip
37 real(wp),
dimension(:),
allocatable :: rain_med_vol_diam
38 real(wp),
dimension(:),
allocatable :: graupel_med_vol_diam
39 real(wp),
dimension(:),
allocatable :: refl10cm
40 real(wp),
dimension(:),
allocatable :: re_cloud
41 real(wp),
dimension(:),
allocatable :: re_ice
42 real(wp),
dimension(:),
allocatable :: re_snow
43 real(wp),
dimension(:),
allocatable :: max_hail_diameter
44 real(wp),
dimension(:),
allocatable :: cloud_number_mixing_ratio
48 real(dp),
pointer,
contiguous,
dimension(:) :: &
49 prr_wau, pnr_wau, pnc_wau, prr_rcw, pnc_rcw, pnr_rcr, &
50 prs_scw, pnc_scw, png_scw, pbg_scw, prg_gcw, pnc_gcw, pbg_gcw, &
51 pri_ihm, pni_ihm, prs_ihm, prg_ihm, prg_scw, &
52 prr_rcs, pnr_rcs, prg_rcs, png_rcs, prs_rcs, pbg_rcs, &
53 prr_rcg, pnr_rcg, prg_rcg, png_rcg, pbg_rcg, &
54 pri_inu, pni_inu, pri_iha, pni_iha, &
56 prg_rfz, png_rfz, pnr_rfz, pri_rfz, pni_rfz, pbg_rfz, &
57 prs_sde, pri_ide, pni_ide, prs_ide, prg_gde, png_gde, &
59 prr_sml, prr_gml, pbg_sml, pbg_gml, pnr_sml, pnr_gml, &
60 prr_rci, pnr_rci, pri_rci, pni_rci, prg_rci, png_rci, pbg_rci, &
62 prw_vcd, pnc_wcd, prv_rev, pnr_rev, &
63 pna_rca, pna_sca, pna_gca, pnd_rcd, pnd_scd, pnd_gcd
67 module procedure tempo_ml_predict_cloud_number
68 module procedure get_constant_cloud_number
73 subroutine tempo_main(tempo_cfgs, &
74 qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, qb1d, ni1d, nr1d, nc1d, ng1d, &
75 nwfa1d, nifa1d, t1d, p1d, w1d, dz1d, land1d, &
76 qcfrac1d, qifrac1d, qc_bl1d, qcfrac_bl1d, &
77 thten_bl1d, qvten_bl1d, qcten_bl1d, qiten_bl1d, &
78 thten_lwrad1d, thten_swrad1d, &
79 kts, kte, dt, ii, jj, tempo_main_diags)
86 integer,
intent(in) :: kts, kte, ii, jj
87 real(wp),
intent(in) :: dt
88 real(wp),
dimension(kts:kte),
intent(inout) :: t1d
89 real(wp),
dimension(kts:kte),
intent(in) :: p1d
90 real(wp),
dimension(kts:kte),
intent(inout) :: qv1d
91 real(wp),
dimension(kts:kte),
intent(inout) :: qc1d
92 real(wp),
dimension(kts:kte),
intent(inout) :: qr1d
93 real(wp),
dimension(kts:kte),
intent(inout) :: qi1d
94 real(wp),
dimension(kts:kte),
intent(inout) :: qs1d
95 real(wp),
dimension(kts:kte),
intent(inout) :: qg1d
96 real(wp),
dimension(kts:kte),
intent(inout) :: ni1d
97 real(wp),
dimension(kts:kte),
intent(inout) :: nr1d
98 real(wp),
dimension(:),
intent(inout),
optional :: nc1d
99 real(wp),
dimension(:),
intent(inout),
optional :: nwfa1d
100 real(wp),
dimension(:),
intent(inout),
optional :: nifa1d
101 real(wp),
dimension(:),
intent(inout),
optional :: qb1d
102 real(wp),
dimension(:),
intent(inout),
optional :: ng1d
103 real(wp),
dimension(kts:kte),
intent(in) :: w1d
104 real(wp),
dimension(kts:kte),
intent(in) :: dz1d
105 integer,
intent(in),
optional :: land1d
108 real(wp),
dimension(:),
intent(inout),
optional :: qcfrac1d
109 real(wp),
dimension(:),
intent(inout),
optional :: qifrac1d
110 real(wp),
dimension(:),
intent(in),
optional :: qc_bl1d
111 real(wp),
dimension(:),
intent(in),
optional :: qcfrac_bl1d
112 real(wp),
dimension(:),
intent(in),
optional :: thten_bl1d
113 real(wp),
dimension(:),
intent(in),
optional :: qvten_bl1d
114 real(wp),
dimension(:),
intent(in),
optional :: qcten_bl1d
115 real(wp),
dimension(:),
intent(in),
optional :: qiten_bl1d
116 real(wp),
dimension(:),
intent(in),
optional :: thten_lwrad1d
117 real(wp),
dimension(:),
intent(in),
optional :: thten_swrad1d
119 real(wp),
dimension(kts:kte) :: tten, qvten, qcten, qiten, qrten, qsten, &
120 qgten, qbten, niten, nrten, ncten, ngten, nwfaten, nifaten
122 logical,
dimension(kts:kte) :: l_qc, l_qi, l_qr, l_qs, l_qg
123 integer,
dimension(kts:kte) :: idx_bg
126 real(wp),
dimension(kts:kte) :: temp, pres, qv
127 real(wp),
dimension(kts:kte) :: rho, rhof, rhof2
128 real(wp),
dimension(kts:kte) :: qvs, qvsi, delqvs
129 real(wp),
dimension(kts:kte) :: satw, sati, ssatw, ssati
130 real(wp),
dimension(kts:kte) :: diffu, visco, vsc2, tcond, lvap, ocp, lvt2
132 real(wp),
dimension(kts:kte) :: rc, ri, rr, rs, rg, rb
133 real(wp),
dimension(kts:kte) :: ni, nr, nc, ng, nwfa, nifa
135 real(dp),
dimension(kts:kte) :: ilamc, ilami, ilamr, ilamg
136 real(wp),
dimension(kts:kte) :: mvd_r, mvd_c, mvd_g
137 real(dp),
dimension(kts:kte) :: smob, smo2, smo1, smo0, smoc, smoe, smof, smog, ns, smoz
139 real(wp),
dimension(kts:kte) :: xrx, xnx
140 real(wp),
dimension(:),
allocatable :: xncx, xngx, xqbx, ncsave
142 real(wp),
dimension(kts:kte+1) :: vtrr, vtnr, vtrs, vtri, vtni, vtrg, vtng, vtrc, vtnc
143 real(wp),
dimension(kts:kte) :: vtboost
144 integer :: substeps_sedi, ktop_sedi, n
145 real(wp) :: semi_sedi_factor
147 real(dp),
target,
dimension(kts:kte, 74) :: tend_work
150 real(wp) :: tempc, tc0, odt
151 logical :: do_micro, supersaturated
152 logical,
save :: first_call_main = .true.
157 supersaturated = .false.
164 tend%prr_wau => tend_work(:, 1)
165 tend%pnr_wau => tend_work(:, 2)
166 tend%pnc_wau => tend_work(:, 3)
167 tend%prr_rcw => tend_work(:, 4)
168 tend%pnc_rcw => tend_work(:, 5)
169 tend%pnr_rcr => tend_work(:, 6)
172 tend%prs_scw => tend_work(:, 7)
173 tend%pnc_scw => tend_work(:, 8)
174 tend%png_scw => tend_work(:, 9)
175 tend%pbg_scw => tend_work(:, 10)
176 tend%prg_gcw => tend_work(:, 11)
177 tend%pnc_gcw => tend_work(:, 12)
178 tend%pbg_gcw => tend_work(:, 13)
179 tend%pri_ihm => tend_work(:, 14)
180 tend%pni_ihm => tend_work(:, 15)
181 tend%prs_ihm => tend_work(:, 16)
182 tend%prg_ihm => tend_work(:, 17)
183 tend%prg_scw => tend_work(:, 18)
186 tend%prr_rcs => tend_work(:, 19)
187 tend%pnr_rcs => tend_work(:, 20)
188 tend%prg_rcs => tend_work(:, 21)
189 tend%png_rcs => tend_work(:, 22)
190 tend%prs_rcs => tend_work(:, 23)
191 tend%pbg_rcs => tend_work(:, 24)
194 tend%prr_rcg => tend_work(:, 25)
195 tend%pnr_rcg => tend_work(:, 26)
196 tend%prg_rcg => tend_work(:, 27)
197 tend%png_rcg => tend_work(:, 28)
198 tend%pbg_rcg => tend_work(:, 29)
201 tend%pri_inu => tend_work(:, 30)
202 tend%pni_inu => tend_work(:, 31)
203 tend%pri_iha => tend_work(:, 32)
204 tend%pni_iha => tend_work(:, 33)
207 tend%pri_wfz => tend_work(:, 34)
208 tend%pni_wfz => tend_work(:, 35)
211 tend%prg_rfz => tend_work(:, 36)
212 tend%png_rfz => tend_work(:, 37)
213 tend%pnr_rfz => tend_work(:, 38)
214 tend%pri_rfz => tend_work(:, 39)
215 tend%pni_rfz => tend_work(:, 40)
216 tend%pbg_rfz => tend_work(:, 41)
219 tend%prs_sde => tend_work(:, 42)
220 tend%pri_ide => tend_work(:, 43)
221 tend%pni_ide => tend_work(:, 44)
222 tend%prs_ide => tend_work(:, 45)
223 tend%prg_gde => tend_work(:, 46)
224 tend%png_gde => tend_work(:, 47)
227 tend%pni_iau => tend_work(:, 48)
228 tend%prs_iau => tend_work(:, 49)
231 tend%prr_sml => tend_work(:, 50)
232 tend%prr_gml => tend_work(:, 51)
233 tend%pbg_sml => tend_work(:, 52)
234 tend%pbg_gml => tend_work(:, 53)
235 tend%pnr_sml => tend_work(:, 54)
236 tend%pnr_gml => tend_work(:, 55)
239 tend%prr_rci => tend_work(:, 56)
240 tend%pnr_rci => tend_work(:, 57)
241 tend%pri_rci => tend_work(:, 58)
242 tend%pni_rci => tend_work(:, 59)
243 tend%prg_rci => tend_work(:, 60)
244 tend%png_rci => tend_work(:, 61)
245 tend%pbg_rci => tend_work(:, 62)
248 tend%pni_sci => tend_work(:, 63)
249 tend%prs_sci => tend_work(:, 64)
252 tend%prw_vcd => tend_work(:, 65)
253 tend%pnc_wcd => tend_work(:, 66)
254 tend%prv_rev => tend_work(:, 67)
255 tend%pnr_rev => tend_work(:, 68)
258 tend%pna_rca => tend_work(:, 69)
259 tend%pna_sca => tend_work(:, 70)
260 tend%pna_gca => tend_work(:, 71)
261 tend%pnd_rcd => tend_work(:, 72)
262 tend%pnd_scd => tend_work(:, 73)
263 tend%pnd_gcd => tend_work(:, 74)
310 tempo_main_diags%rain_precip = 0._wp
311 tempo_main_diags%cloud_precip = 0._wp
312 tempo_main_diags%ice_liquid_equiv_precip = 0._wp
313 tempo_main_diags%snow_liquid_equiv_precip = 0._wp
314 tempo_main_diags%graupel_liquid_equiv_precip = 0._wp
315 tempo_main_diags%frz_rain_precip = 0._wp
320 qv(k) = max(min_qv, qv1d(k))
322 rho(k) = roverrv*pres(k)/(rdry*temp(k)*(qv(k)+roverrv))
325 if (
present(nwfa1d))
then
326 if (first_call_main)
then
327 if (sum(nwfa1d) < eps)
call init_water_friendly_aerosols(dz1d, nwfa)
330 call init_water_friendly_aerosols(dz1d, nwfa)
333 if (
present(nifa1d))
then
334 if (first_call_main)
then
335 if (sum(nifa1d) < eps)
call init_ice_friendly_aerosols(dz1d, nifa)
338 call init_ice_friendly_aerosols(dz1d, nifa)
341 call aerosol_check_and_update(rho=rho, nwfa1d=nwfa1d, nifa1d=nifa1d, &
342 nwfa=nwfa, nifa=nifa, nwfaten=nwfaten, nifaten=nifaten, dt=dt)
344 call rain_check_and_update(rho, l_qr, qr1d, nr1d, rr, nr, qrten, nrten, ilamr, mvd_r, dt, odt)
346 call ice_check_and_update(rho, l_qi, qi1d, ni1d, ri, ni, qiten, niten, ilami, dt, odt)
348 call snow_check_and_update(rho, l_qs, qs1d, rs, qsten, dt, odt)
352 tc0 = min(-0.1, temp(k)-t0)
353 call snow_moments(rs=rs(k), tc=tc0, &
354 smob=smob(k), smoc=smoc(k), ns=ns(k), &
355 smo0=smo0(k), smo1=smo1(k), smo2=smo2(k), &
356 smoe=smoe(k), smof=smof(k), smog=smog(k))
361 if (.not.
present(nc1d))
then
362 if (tempo_cfgs%ml_for_nc_flag)
then
364 where(xrx <= 1.e-12_wp) xrx = 0._wp
370 if (
present(land1d))
then
373 nc = tempo_cfgs%get_nc_val(val_land=nt_c_l, val_ocean=nt_c_o)
376 allocate(ncsave(nz), source=nc)
379 call cloud_check_and_update(rho=rho, l_qc=l_qc, qc1d=qc1d, nc1d=nc1d, &
380 ncsave=ncsave, rc=rc, nc=nc, qcten=qcten, ncten=ncten, ilamc=ilamc, mvd_c=mvd_c, &
384 if (first_call_main)
then
385 if (
present(ng1d) .and.
present(qb1d))
then
386 if (sum(qg1d) > r1 .and. sum(ng1d) < eps .and. sum(qb1d) < eps)
then
387 call graupel_init(rho, qg1d, ng1d, qb1d)
391 call graupel_check_and_update(rho=rho, l_qg=l_qg, qg1d=qg1d, ng1d=ng1d, &
392 qb1d=qb1d, rg=rg, ng=ng, rb=rb, idx=idx_bg, qgten=qgten, ngten=ngten, &
393 qbten=qbten, ilamg=ilamg, mvd_g=mvd_g, dt=dt, odt=odt)
409 call thermo_vars(qv, temp, pres, rho, rhof, rhof2, qvs, delqvs, qvsi, &
410 satw, sati, ssatw, ssati, diffu, visco, vsc2, ocp, lvap, tcond, lvt2, &
413 if (first_call_main) first_call_main = .false.
416 do_micro = any(l_qc) .or. any(l_qr) .or. any(l_qi) .or. any(l_qs) .or. any(l_qg)
417 if (.not. do_micro .and. .not. supersaturated)
return
420 if (.not. tempo_cfgs%turn_off_micro_flag)
then
421 call warm_rain(rhof, l_qc, rc, nc, ilamc, mvd_c, l_qr, rr, nr, mvd_r, tend, odt)
423 if (.not. tempo_cfgs%turn_off_micro_flag)
then
424 call rain_snow_rain_graupel(temp, l_qr, rr, nr, ilamr, l_qs, rs, &
425 l_qg, rg, ng, ilamg, idx_bg, tend, odt)
427 if (.not. tempo_cfgs%turn_off_micro_flag)
then
428 call ice_nucleation(temp, rho, w1d, qv, qvsi, ssati, ssatw, &
429 nwfa1d, nifa1d, nwfa, nifa, ni, smo0, rc, nc, rr, nr, ilamr, tend, dt, odt)
431 if (.not. tempo_cfgs%turn_off_micro_flag)
then
432 call ice_processes(rhof, rhof2, rho, w1d, temp, qv, qvsi, tcond, diffu, &
433 vsc2, ssati, l_qi, ri, ni, ilami, l_qs, rs, smoe, smof, smo1, rr, nr, &
434 ilamr, mvd_r, l_qg, rg, ng, ilamg, idx_bg, tend, odt)
436 if (.not. tempo_cfgs%turn_off_micro_flag)
then
437 call riming(temp, rhof, visco, l_qc, rc, nc, ilamc, mvd_c, l_qs, rs, &
438 smo0, smob, smoc, smoe, vtboost, l_qg, rg, ng, ilamg, idx_bg, tend, odt)
440 if (.not. tempo_cfgs%turn_off_micro_flag)
then
441 call melting(rhof2, rho, temp, qvsi, tcond, diffu, vsc2, ssati, delqvs, &
442 l_qs, rs, smof, smo0, smo1, l_qg, rg, ng, ilamg, idx_bg, tend, dt, odt)
444 if (.not. tempo_cfgs%turn_off_micro_flag)
then
445 if (
present(nwfa1d) .or.
present(nifa1d))
then
446 call aerosol_scavenging(temp, rho, rhof, visco, nwfa, nifa, l_qr, nr, ilamr, &
447 mvd_r, l_qs, rs, smob, smoc, smoe, l_qg, rg, ng, ilamg, idx_bg, tend, odt)
452 call check_over_depletion(rho, temp, qvsi, qv, l_qc, rc, l_qi, ri, &
453 l_qr, rr, l_qs, rs, l_qg, rg, tend, odt)
455 call sum_tendencies(rho, temp, idx_bg, lvap, ocp, tend, tten, qvten, qcten, &
456 ncten, qiten, niten, qsten, qrten, nrten, qgten, ngten, qbten)
460 temp(k) = t1d(k) + tten(k)*dt
462 qv(k) = max(min_qv, qv1d(k) + qvten(k)*dt)
463 rho(k) = roverrv*pres(k)/(rdry*temp(k)*(qv(k)+roverrv))
464 nwfaten(k) = nwfaten(k) - (tend%pna_rca(k) + tend%pna_sca(k) + tend%pna_gca(k) + &
465 tend%pni_iha(k)) / rho(k)
466 nifaten(k) = nifaten(k) - (tend%pnd_rcd(k) + tend%pnd_scd(k) + tend%pnd_gcd(k)) / rho(k)
470 call aerosol_check_and_update(rho=rho, nwfa1d=nwfa1d, nifa1d=nifa1d, &
471 nwfa=nwfa, nifa=nifa, nwfaten=nwfaten, nifaten=nifaten, dt=dt)
475 if (
present(nc1d))
then
476 if (.not.
allocated(xncx))
allocate(xncx(nz), source=0._wp)
479 call cloud_check_and_update(rho=rho, l_qc=l_qc, qc1d=xrx, nc1d=xncx, &
480 ncsave=ncsave, rc=rc, nc=nc, qcten=qcten, ncten=ncten, ilamc=ilamc, mvd_c=mvd_c, &
485 call rain_check_and_update(rho, l_qr, xrx, xnx, rr, nr, qrten, nrten, ilamr, mvd_r, dt, odt)
489 call ice_check_and_update(rho, l_qi, xrx, xnx, ri, ni, qiten, niten, ilami, dt, odt)
492 call snow_check_and_update(rho, l_qs, xrx, rs, qsten, dt, odt)
505 tc0 = min(-0.1, temp(k)-t0)
506 call snow_moments(rs=rs(k), tc=tc0, &
507 smob=smob(k), smoc=smoc(k), &
513 if (
present(ng1d) .and.
present(qb1d))
then
514 if (.not.
allocated(xngx))
allocate(xngx(nz), source=0._wp)
515 if (.not.
allocated(xqbx))
allocate(xqbx(nz), source=0._wp)
519 call graupel_check_and_update(rho=rho, l_qg=l_qg, qg1d=xrx, ng1d=xngx, &
520 qb1d=xqbx, rg=rg, ng=ng, rb=rb, idx=idx_bg, qgten=qgten, ngten=ngten, &
521 qbten=qbten, ilamg=ilamg, mvd_g=mvd_g, dt=dt, odt=odt)
523 call thermo_vars(qv, temp, pres, rho, rhof, rhof2, qvs, delqvs, qvsi, &
524 satw, sati, ssatw, ssati, diffu, visco, vsc2, ocp, lvap, tcond, lvt2, &
529 if (.not. tempo_cfgs%turn_off_micro_flag .and. tempo_cfgs%cloud_condensation_flag)
then
530 call cloud_condensation(rho, temp, w1d, ssatw, lvap, tcond, diffu, lvt2, &
531 nwfa1d, nwfa, ncsave, qv, qvs, l_qc, rc, nc, tend, dt, odt)
534 qvten(k) = qvten(k) - tend%prw_vcd(k)
535 qcten(k) = qcten(k) + tend%prw_vcd(k)
536 ncten(k) = ncten(k) + tend%pnc_wcd(k)
537 nwfaten(k) = nwfaten(k) - tend%pnc_wcd(k)
538 tten(k) = tten(k) + lvap(k)*ocp(k)*tend%prw_vcd(k)
542 if (
present(nc1d))
then
543 if (.not.
allocated(xncx))
allocate(xncx(nz), source=0._wp)
546 call cloud_check_and_update(rho=rho, l_qc=l_qc, qc1d=xrx, nc1d=xncx, &
547 ncsave=ncsave, rc=rc, nc=nc, qcten=qcten, ncten=ncten, ilamc=ilamc, mvd_c=mvd_c, &
551 qv(k) = max(min_qv, qv1d(k) + qvten(k)*dt)
552 temp(k) = t1d(k) + tten(k)*dt
553 rho(k) = roverrv*pres(k)/(rdry*temp(k)*(qv(k)+roverrv))
556 call thermo_vars(qv, temp, pres, rho, rhof, rhof2, qvs, delqvs, qvsi, &
557 satw, sati, ssatw, ssati, diffu, visco, vsc2, ocp, lvap, tcond, lvt2, &
562 if (.not. tempo_cfgs%turn_off_micro_flag)
then
563 call rain_evaporation(rho, temp, ssatw, lvap, tcond, diffu, vsc2, rhof2, &
564 qv, qvs, l_qr, rr, nr, ilamr, tend, odt)
567 qrten(k) = qrten(k) - tend%prv_rev(k)
568 qvten(k) = qvten(k) + tend%prv_rev(k)
569 nrten(k) = nrten(k) - tend%pnr_rev(k)
570 nwfaten(k) = nwfaten(k) + tend%pnr_rev(k)
571 tten(k) = tten(k) - lvap(k)*ocp(k)*tend%prv_rev(k)
576 call rain_check_and_update(rho, l_qr, xrx, xnx, rr, nr, qrten, nrten, ilamr, mvd_r, dt, odt)
579 qv(k) = max(min_qv, qv1d(k) + qvten(k)*dt)
580 temp(k) = t1d(k) + tten(k)*dt
581 rho(k) = roverrv*pres(k)/(rdry*temp(k)*(qv(k)+roverrv))
584 call thermo_vars(qv, temp, pres, rho, rhof, rhof2, qvs, delqvs, qvsi, &
585 satw, sati, ssatw, ssati, diffu, visco, vsc2, ocp, lvap, tcond, lvt2, &
594 semi_sedi_factor = 10._wp
596 call rain_fallspeed(rhof=rhof, l_qr=l_qr, rr=rr, ilamr=ilamr, dz1d=dz1d, &
597 vt=vtrr, vtn=vtnr, substeps_sedi=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
599 if (tempo_cfgs%semi_sedi_flag)
then
600 substeps_sedi = max(int(substeps_sedi/semi_sedi_factor) + 1, 1)
601 do n = 1, substeps_sedi
602 call semilagrangian_sedimentation(dz1d=dz1d, rho=rho, xr=rr, xten=qrten, &
603 vt=vtrr, steps=substeps_sedi, limit=r1, precip=tempo_main_diags%rain_precip, dt=dt, odt=odt)
604 call semilagrangian_sedimentation(dz1d=dz1d, rho=rho, xr=nr, xten=nrten, &
605 vt=vtnr, steps=substeps_sedi, limit=r2, dt=dt, odt=odt)
610 call rain_check_and_update(rho, l_qr, xrx, xnx, rr, nr, qrten, nrten, ilamr, mvd_r, dt, odt)
611 call rain_fallspeed(rhof=rhof, l_qr=l_qr, rr=rr, ilamr=ilamr, dz1d=dz1d, &
612 vt=vtrr, vtn=vtnr, dt=dt)
615 do n = 1, substeps_sedi
616 call sedimentation(xr=rr, vt=vtrr, dz1d=dz1d, rho=rho, xten=qrten, limit=r1, &
617 steps=substeps_sedi, ktop_sedi=ktop_sedi, precip=tempo_main_diags%rain_precip, dt=dt)
618 call sedimentation(xr=nr, vt=vtnr, dz1d=dz1d, rho=rho, xten=nrten, limit=r2, &
619 steps=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
634 semi_sedi_factor = 10._wp
636 call graupel_fallspeed(rhof=rhof, rho=rho, visco=visco, &
637 l_qg=l_qg, rg=rg, rb=rb, qb1d=qb1d, idx=idx_bg, ilamg=ilamg, dz1d=dz1d, &
638 vt=vtrg, vtn=vtng, substeps_sedi=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
640 if (tempo_cfgs%semi_sedi_flag)
then
641 substeps_sedi = max(int(substeps_sedi/semi_sedi_factor) + 1, 1)
642 do n = 1, substeps_sedi
643 call semilagrangian_sedimentation(dz1d=dz1d, rho=rho, xr=rg, xten=qgten, &
644 vt=vtrg, steps=substeps_sedi, limit=r1, precip=tempo_main_diags%graupel_liquid_equiv_precip, &
646 call semilagrangian_sedimentation(dz1d=dz1d, rho=rho, xr=ng, xten=ngten, &
647 vt=vtng, steps=substeps_sedi, limit=r2, dt=dt, odt=odt)
648 call semilagrangian_sedimentation(dz1d=dz1d, rho=rho, xr=rb, xten=qbten, &
649 vt=vtrg, steps=substeps_sedi, limit=meters3_to_liters*r1/rho_g(nrhg), dt=dt, odt=odt)
653 if (
present(ng1d) .and.
present(qb1d))
then
654 if (.not.
allocated(xngx))
allocate(xngx(nz), source=0._wp)
655 if (.not.
allocated(xqbx))
allocate(xqbx(nz), source=0._wp)
659 call graupel_check_and_update(rho=rho, l_qg=l_qg, qg1d=xrx, ng1d=xngx, &
660 qb1d=xqbx, rg=rg, ng=ng, rb=rb, idx=idx_bg, qgten=qgten, ngten=ngten, &
661 qbten=qbten, ilamg=ilamg, mvd_g=mvd_g, dt=dt, odt=odt)
662 call graupel_fallspeed(rhof=rhof, rho=rho, visco=visco, &
663 l_qg=l_qg, rg=rg, rb=rb, qb1d=qb1d, idx=idx_bg, ilamg=ilamg, dz1d=dz1d, &
664 vt=vtrg, vtn=vtng, dt=dt)
667 do n = 1, substeps_sedi
668 call sedimentation(xr=rg, vt=vtrg, dz1d=dz1d, rho=rho, xten=qgten, limit=r1, &
669 steps=substeps_sedi, ktop_sedi=ktop_sedi, precip=tempo_main_diags%graupel_liquid_equiv_precip, dt=dt)
670 call sedimentation(xr=ng, vt=vtng, dz1d=dz1d, rho=rho, xten=ngten, limit=r2, &
671 steps=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
672 call sedimentation(xr=rb, vt=vtrg, dz1d=dz1d, rho=rho, xten=qbten, &
673 limit=meters3_to_liters*r1/rho_g(nrhg), steps=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
697 call snow_fallspeed(rhof=rhof, l_qs=l_qs, rs=rs, prr_sml=tend%prr_sml, smob=smob, smoc=smoc, &
698 rr=rr, vtrr=vtrr, dz1d=dz1d, vt=vtrs, vtboost=vtboost, substeps_sedi=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
699 do n = 1, substeps_sedi
700 call sedimentation(xr=rs, vt=vtrs, dz1d=dz1d, rho=rho, xten=qsten, limit=r1, &
701 steps=substeps_sedi, ktop_sedi=ktop_sedi, precip=tempo_main_diags%snow_liquid_equiv_precip, dt=dt)
709 call ice_fallspeed(rhof, l_qi, ri, ilami, dz1d, vtri, vtni, &
710 substeps_sedi, ktop_sedi, dt=dt)
711 call sedimentation(xr=ri, vt=vtri, dz1d=dz1d, rho=rho, xten=qiten, limit=r1, &
712 steps=substeps_sedi, ktop_sedi=ktop_sedi, precip=tempo_main_diags%ice_liquid_equiv_precip, dt=dt)
713 call sedimentation(xr=ni, vt=vtni, dz1d=dz1d, rho=rho, xten=niten, limit=r2, &
714 steps=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
721 call cloud_fallspeed(rhof, w1d, l_qc, rc, nc, ilamc, dz1d, vtrc, vtnc, ktop_sedi)
722 call sedimentation(xr=rc, vt=vtrc, dz1d=dz1d, rho=rho, xten=qcten, limit=r1, &
723 steps=substeps_sedi, ktop_sedi=ktop_sedi, precip=tempo_main_diags%cloud_precip, dt=dt)
724 call sedimentation(xr=nc, vt=vtnc, dz1d=dz1d, rho=rho, xten=ncten, limit=r2, &
725 steps=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
730 if (.not. tempo_cfgs%turn_off_micro_flag)
then
731 call freeze_cloud_melt_ice(temp=temp, rho=rho, ocp=ocp, lvap=lvap, &
732 qi1d=qi1d, ni1d=ni1d, qiten=qiten, niten=niten, qc1d=qc1d, nc1d=nc1d, &
733 qcten=qcten, ncten=ncten, tten=tten, ncsave=ncsave, dt=dt, odt=odt)
738 t1d(k) = t1d(k) + tten(k)*dt
739 qv1d(k) = max(min_qv, (qv1d(k) + qvten(k)*dt))
740 rho(k) = roverrv*pres(k)/(rdry*temp(k)*(qv(k)+roverrv))
741 if (
present(nwfa1d))
then
742 nwfa1d(k) = max(nwfa_default, min(aero_max, (nwfa1d(k)+nwfaten(k)*dt)))
744 if (
present(nifa1d))
then
745 nifa1d(k) = max(nifa_default, min(aero_max, (nifa1d(k)+nifaten(k)*dt)))
749 call cloud_check_and_update(rho=rho, l_qc=l_qc, qc1d=qc1d, nc1d=nc1d, &
750 ncsave=ncsave, rc=rc, nc=nc, qcten=qcten, ncten=ncten, ilamc=ilamc, mvd_c=mvd_c, &
753 call rain_check_and_update(rho, l_qr, qr1d, nr1d, rr, nr, qrten, nrten, ilamr, mvd_r, dt, odt)
755 call ice_check_and_update(rho, l_qi, qi1d, ni1d, ri, ni, qiten, niten, ilami, dt, odt)
757 call snow_check_and_update(rho, l_qs, qs1d, rs, qsten, dt, odt)
771 tc0 = min(-0.1, temp(k)-t0)
772 call snow_moments(rs=rs(k), tc=tc0, &
773 smob=smob(k), smoc=smoc(k), &
774 smo2=smo2(k), smoz=smoz(k))
778 call graupel_check_and_update(rho=rho, l_qg=l_qg, qg1d=qg1d, ng1d=ng1d, &
779 qb1d=qb1d, rg=rg, ng=ng, rb=rb, idx=idx_bg, qgten=qgten, ngten=ngten, &
780 qbten=qbten, ilamg=ilamg, mvd_g=mvd_g, dt=dt, odt=odt)
784 tempo_main_diags%frozen_fraction = &
785 (tempo_main_diags%ice_liquid_equiv_precip + tempo_main_diags%snow_liquid_equiv_precip + &
786 tempo_main_diags%graupel_liquid_equiv_precip) / &
787 (tempo_main_diags%ice_liquid_equiv_precip + tempo_main_diags%snow_liquid_equiv_precip + &
788 tempo_main_diags%graupel_liquid_equiv_precip + tempo_main_diags%rain_precip + r1)
791 call freezing_rain(temp=temp(1), rain_precip=tempo_main_diags%rain_precip, &
792 cloud_precip=tempo_main_diags%cloud_precip, &
793 frz_rain=tempo_main_diags%frz_rain_precip)
795 if (tempo_cfgs%cloud_number_mixing_ratio_flag)
then
796 allocate(tempo_main_diags%cloud_number_mixing_ratio(nz), source=nc*rho)
800 if (tempo_cfgs%rain_med_vol_diam_flag)
then
801 allocate(tempo_main_diags%rain_med_vol_diam(nz), source=0._wp)
802 tempo_main_diags%rain_med_vol_diam = mvd_r
804 if (tempo_cfgs%graupel_med_vol_diam_flag)
then
805 allocate(tempo_main_diags%graupel_med_vol_diam(nz), source=0._wp)
806 tempo_main_diags%graupel_med_vol_diam = mvd_g
810 if (tempo_cfgs%max_hail_diameter_flag)
then
811 allocate(tempo_main_diags%max_hail_diameter(nz), source=0._wp)
812 call max_hail_diam(rho, rg, ng, ilamg, idx_bg, &
813 tempo_main_diags%max_hail_diameter)
817 if (tempo_cfgs%refl10cm_flag)
then
818 allocate(tempo_main_diags%refl10cm(nz), source=-35._wp)
819 call reflectivity_10cm(tempo_cfgs%refl10cm_from_melting_flag, &
820 temp, l_qr, rr, nr, ilamr, &
821 l_qs, rs, smoc, smob, smoz, l_qg, rg, ng, idx_bg, ilamg, &
822 tempo_main_diags%refl10cm)
826 if ((tempo_cfgs%re_cloud_flag) .and. (tempo_cfgs%re_ice_flag) .and. (tempo_cfgs%re_snow_flag))
then
827 allocate(tempo_main_diags%re_cloud(nz), source=0._wp)
828 allocate(tempo_main_diags%re_ice(nz), source=0._wp)
829 allocate(tempo_main_diags%re_snow(nz), source=0._wp)
838 if (
present(qc_bl1d) .and.
present(qcfrac_bl1d))
then
840 if (.not.
allocated(xncx))
allocate(xncx(nz), source=0._wp)
843 if ((xrx(k) <= r1) .and. &
844 (qc_bl1d(k) > 1.e-9_wp) .and. (qcfrac_bl1d(k) > 0._wp))
then
845 xrx(k) = xrx(k) + qc_bl1d(k) / qcfrac_bl1d(k)
848 where(xrx <= 1.e-12_wp) xrx = 0._wp
856 call cloud_check_and_update(rho=rho, l_qc=l_qc, qc1d=xrx, nc1d=xncx, &
857 rc=rc, nc=nc, qcten=qcten, ncten=ncten, ilamc=ilamc, mvd_c=mvd_c, &
860 call effective_radius(temp, l_qc, nc, ilamc, l_qi, ilami, l_qs, rs, &
861 tempo_main_diags%re_cloud, tempo_main_diags%re_ice, tempo_main_diags%re_snow)
863 end subroutine tempo_main
866 subroutine aerosol_check_and_update(rho, nwfa1d, nifa1d, nwfa, nifa, nwfaten, nifaten, dt)
870 real(wp),
intent(in) :: dt
871 real(wp),
dimension(:),
intent(in) :: rho
872 real(wp),
dimension(:),
intent(inout) :: nwfa, nifa, nwfaten, nifaten
873 real(wp),
dimension(:),
intent(inout),
optional :: nwfa1d, nifa1d
878 if (
present(nwfa1d))
then
879 nwfa(k) = (nwfa1d(k)+nwfaten(k)*dt)*rho(k)
881 if (
present(nifa1d))
then
882 nifa(k) = (nifa1d(k)+nifaten(k)*dt)*rho(k)
884 nwfa(k) = max(nwfa_default*rho(k), min(aero_max*rho(k), nwfa(k)))
885 nifa(k) = max(nifa_default*rho(k), min(aero_max*rho(k), nifa(k)))
887 end subroutine aerosol_check_and_update
890 subroutine cloud_check_and_update(rho, l_qc, qc1d, nc1d, ncsave, rc, nc, &
891 qcten, ncten, ilamc, mvd_c, dt, odt)
894 am_r, bm_r, cce, ccg, d0c, d0r, ocg1, ocg2, obmr, nt_c_l, d0r, nt_c_l
896 real(wp),
intent(in) :: dt, odt
897 real(wp),
dimension(:),
intent(in) :: rho
898 real(wp),
dimension(:),
intent(inout) :: qc1d, qcten, ncten, rc, nc
899 real(wp),
dimension(:),
intent(out) :: mvd_c
900 real(dp),
dimension(:),
intent(out) :: ilamc
901 real(wp),
dimension(:),
intent(inout),
optional :: nc1d, ncsave
902 logical,
dimension(:),
intent(inout) :: l_qc
903 integer :: k, nz, nu_c
904 real(dp) :: lamc, xdc
910 if (qc1d(k)+qcten(k)*dt > r1)
then
913 rc(k) = (qc1d(k)+qcten(k)*dt)*rho(k)
914 qc1d(k) = qc1d(k)+qcten(k)*dt
917 if (
present(nc1d))
then
918 nc(k) = max(nt_c_min, (nc1d(k)+ncten(k)*dt)*rho(k))
921 if (nc(k) <= nt_c_min)
then
925 if (nc(k) > nt_c_max)
then
931 nu_c = get_nuc(nc(k))
932 lamc = (nc(k)*am_r*ccg(2,nu_c)*ocg1(nu_c)/rc(k))**obmr
933 xdc = (bm_r + nu_c + 1._dp) / lamc
935 lamc = cce(2,nu_c)/d0c
937 elseif (xdc > d0r*2._dp)
then
938 lamc = cce(2,nu_c)/(d0r*2._dp)
942 nc(k) = ccg(1,nu_c)*ocg2(nu_c)*rc(k) / am_r*lamc**bm_r
944 if (hit_limit) ncten(k) = (nc(k)/rho(k) - nc1d(k)) * odt
945 nc1d(k) = max(nt_c_min/rho(k), &
946 min(real(ccg(1,nu_c)*ocg2(nu_c)*qc1d(k)/am_r*lamc**bm_r, kind=wp), nt_c_max/rho(k)))
948 if (
present(ncsave))
then
954 nu_c = get_nuc(nc(k))
955 lamc = (nc(k)*am_r*ccg(2,nu_c)*ocg1(nu_c)/rc(k))**obmr
956 ilamc(k) = 1._dp / lamc
957 mvd_c(k) = max(min(real((3.0_wp + nu_c + 0.672_wp) * ilamc(k), kind=wp), d0r), d0c)
964 qcten(k) = -qc1d(k) * odt
966 if (
present(nc1d))
then
967 ncten(k) = -nc1d(k) * odt
972 end subroutine cloud_check_and_update
975 subroutine rain_check_and_update(rho, l_qr, qr1d, nr1d, rr, nr, &
976 qrten, nrten, ilamr, mvd_r, dt, odt)
979 am_r, bm_r, obmr, d0r, d0r_max, org2, org3, rho_g
981 real(wp),
intent(in) :: dt, odt
982 real(wp),
dimension(:),
intent(in) :: rho
983 real(wp),
dimension(:),
intent(inout) :: qr1d, nr1d, qrten, nrten, rr, nr
984 real(wp),
dimension(:),
intent(out) :: mvd_r
985 real(dp),
dimension(:),
intent(out) :: ilamr
986 logical,
dimension(:),
intent(inout) :: l_qr
994 if (qr1d(k)+qrten(k)*dt > r1)
then
997 rr(k) = (qr1d(k)+qrten(k)*dt)*rho(k)
998 qr1d(k) = qr1d(k)+qrten(k)*dt
1001 nr(k) = max(r2, (nr1d(k)+nrten(k)*dt)*rho(k))
1004 if (nr(k) <= r2)
then
1006 mvd_r(k) = 1.0e-3_wp
1007 lamr = (3.0_dp + mu_r + 0.672_dp) / mvd_r(k)
1008 nr(k) = crg(2)*org3*rr(k)*lamr**bm_r / am_r
1012 lamr = (am_r*crg(3)*org2*nr(k)/rr(k))**obmr
1013 mvd_r(k) = (3.0_wp + mu_r + 0.672_wp) / lamr
1014 if (mvd_r(k) > d0r_max)
then
1017 lamr = (3.0_dp + mu_r + 0.672_dp) / mvd_r(k)
1018 nr(k) = crg(2)*org3*rr(k)*lamr**bm_r / am_r
1019 elseif (mvd_r(k) < d0r*0.75_wp)
then
1021 mvd_r(k) = d0r*0.75_wp
1022 lamr = (3.0_dp + mu_r + 0.672_dp) / mvd_r(k)
1023 nr(k) = crg(2)*org3*rr(k)*lamr**bm_r / am_r
1026 if (hit_limit) nrten(k) = (nr(k)/rho(k) - nr1d(k))*odt
1027 nr1d(k) = crg(2)*org3*qr1d(k)*lamr**bm_r / am_r
1028 ilamr(k) = 1._dp / lamr
1035 qrten(k) = -qr1d(k) * odt
1036 nrten(k) = -nr1d(k) * odt
1041 end subroutine rain_check_and_update
1044 subroutine ice_check_and_update(rho, l_qi, qi1d, ni1d, ri, ni, &
1045 qiten, niten, ilami, dt, odt)
1048 mu_i, am_i, bm_i, oig1, oig2, obmi , d0s
1050 real(wp),
intent(in) :: dt, odt
1051 real(wp),
dimension(:),
intent(in) :: rho
1052 real(wp),
dimension(:),
intent(inout) :: qi1d, ni1d, qiten, niten, ri, ni
1053 real(dp),
dimension(:),
intent(out) :: ilami
1054 logical,
dimension(:),
intent(inout) :: l_qi
1056 real(dp) :: lami, xdi
1057 logical :: hit_limit
1062 if (qi1d(k)+qiten(k)*dt > r1)
then
1065 ri(k) = (qi1d(k)+qiten(k)*dt)*rho(k)
1066 qi1d(k) = qi1d(k)+qiten(k)*dt
1069 ni(k) = max(r2, (ni1d(k)+niten(k)*dt)*rho(k))
1072 if (ni(k) <= r2)
then
1074 lami = cie(2)/5.e-6_dp
1075 ni(k) = min(max_ni, real(cig(1)*oig2*ri(k)/am_i*lami**bm_i, kind=wp))
1079 lami = (am_i*cig(2)*oig1*ni(k)/ri(k))**obmi
1080 xdi = (bm_i + mu_i + 1._dp) / lami
1081 if (xdi < 5.e-6_dp)
then
1083 lami = cie(2)/5.e-6_dp
1084 ni(k) = min(max_ni, real(cig(1)*oig2*ri(k)/am_i*lami**bm_i, kind=wp))
1085 elseif (xdi > d0s)
then
1088 ni(k) = cig(1)*oig2*ri(k)/am_i*lami**bm_i
1091 if (hit_limit) niten(k) = (ni(k)/rho(k) - ni1d(k))*odt
1092 ni1d(k) = max(r2/rho(k), &
1093 min(real(cig(1)*oig2*qi1d(k)/am_i*lami**bm_i, kind=wp), max_ni/rho(k)))
1094 ilami(k) = 1._dp / lami
1100 qiten(k) = -qi1d(k) * odt
1101 niten(k) = -ni1d(k) * odt
1106 end subroutine ice_check_and_update
1109 subroutine snow_check_and_update(rho, l_qs, qs1d, rs, qsten, dt, odt)
1113 real(wp),
intent(in) :: dt, odt
1114 real(wp),
dimension(:),
intent(in) :: rho
1115 real(wp),
dimension(:),
intent(inout) :: qs1d, rs, qsten
1116 logical,
dimension(:),
intent(inout) :: l_qs
1121 if (qs1d(k)+qsten(k)*dt > r1)
then
1124 rs(k) = (qs1d(k)+qsten(k)*dt)*rho(k)
1125 qs1d(k) = qs1d(k)+qsten(k)*dt
1129 qsten(k) = -qs1d(k) * odt
1133 end subroutine snow_check_and_update
1136 subroutine graupel_check_and_update(rho, l_qg, qg1d, ng1d, qb1d, rg, ng, rb, &
1137 idx, qgten, ngten, qbten, ilamg, mvd_g, dt, odt)
1140 am_g, bm_g, ogg3, cgg, ogg2, obmg, d0r, idx_bg1, gonv_max, &
1141 gonv_min, oge1, ogg1, d0g, meters3_to_liters
1143 real(wp),
intent(in) :: dt, odt
1144 real(wp),
dimension(:),
intent(in) :: rho
1145 real(wp),
dimension(:),
intent(inout) :: qg1d, qgten, rg, ng, rb, ngten, qbten
1146 real(wp),
dimension(:),
intent(inout),
optional :: ng1d, qb1d
1147 real(dp),
dimension(:),
intent(out) :: ilamg
1148 real(wp),
dimension(:),
intent(out) :: mvd_g
1149 logical,
dimension(:),
intent(inout) :: l_qg
1150 integer,
dimension(:),
intent(inout) :: idx
1152 real(dp) :: lamg, ygra1, zans1, n0_exp, lam_exp
1153 logical :: hit_limit
1158 if (qg1d(k)+qgten(k)*dt > r1)
then
1161 rg(k) = (qg1d(k)+qgten(k)*dt)*rho(k)
1162 qg1d(k) = qg1d(k)+qgten(k)*dt
1165 if (
present(ng1d) .and.
present(qb1d))
then
1166 ng(k) = max(r2, (ng1d(k)+ngten(k)*dt)*rho(k))
1168 rb(k) = min(max(rg(k)*meters3_to_liters/rho_g(nrhg), &
1169 (qb1d(k)+qbten(k)*dt)*rho(k)), rg(k)*meters3_to_liters/rho_g(1))
1170 idx(k) = max(1, min(nint(10._wp*rg(k)/rb(k))+1, nrhg))
1173 if (ng(k) <= r2)
then
1175 mvd_g(k) = 1.5e-3_wp
1176 lamg = (3.0_dp + mu_g + 0.672_dp) / mvd_g(k)
1177 ng(k) = cgg(2,1)*ogg3*rg(k)*lamg**bm_g / am_g(idx(k))
1181 lamg = (am_g(idx(k))*cgg(3,1)*ogg2*ng(k)/rg(k))**obmg
1182 mvd_g(k) = (3.0_wp + mu_g + 0.672_wp) / lamg
1183 if (mvd_g(k) > 25.4e-3_wp)
then
1185 mvd_g(k) = 25.4e-3_wp
1186 lamg = (3.0_dp + mu_g + 0.672_dp) / mvd_g(k)
1187 ng(k) = cgg(2,1)*ogg3*rg(k)*lamg**bm_g / am_g(idx(k))
1188 elseif (mvd_g(k) < d0r)
then
1191 lamg = (3.0_dp + mu_g + 0.672_dp) / mvd_g(k)
1192 ng(k) = cgg(2,1)*ogg3*rg(k)*lamg**bm_g / am_g(idx(k))
1195 if (hit_limit) ngten(k) = (ng(k)/rho(k) - ng1d(k)) * odt
1196 ng1d(k) = cgg(2,1)*ogg3*qg1d(k)*lamg**bm_g / am_g(idx(k))
1197 qb1d(k) = min(max(qg1d(k)*meters3_to_liters/rho_g(nrhg), &
1198 qb1d(k)+qbten(k)*dt), meters3_to_liters*qg1d(k)/rho_g(1))
1199 idx(k) = max(1, min(nint(10._wp*qg1d(k)/qb1d(k))+1, nrhg))
1202 ygra1 = log10(max(1.e-9_dp, real(rg(k), kind=dp)))
1203 zans1 = 3.4_dp + 2._dp/7._dp*(ygra1+8._dp)
1204 n0_exp = max(gonv_min, min(10._dp**(zans1), gonv_max))
1205 lam_exp = (n0_exp*am_g(idx(k))*cgg(1,1)/rg(k))**oge1
1206 lamg = lam_exp * (cgg(3,1)*ogg2*ogg1)**obmg
1207 ng(k) = cgg(2,1)*ogg3*rg(k)*lamg**bm_g / am_g(idx(k))
1208 rb(k) = meters3_to_liters*rg(k)/rho_g(idx(k))
1210 ilamg(k) = 1._dp / lamg
1211 mvd_g(k) = (3.0_wp + mu_g + 0.672_wp) * ilamg(k)
1219 rb(k) = meters3_to_liters*r1/rho_g(idx(k))
1220 qgten(k) = -qg1d(k) * odt
1222 if (
present(ng1d) .and.
present(qb1d))
then
1223 ngten(k) = -ng1d(k) * odt
1224 qbten(k) = -qb1d(k) * odt
1230 end subroutine graupel_check_and_update
1233 subroutine graupel_init(rho, qg1d, ng1d, qb1d)
1237 idx_bg1, am_g, bm_g, mu_g, ogg3, cgg
1239 real(wp),
dimension(:),
intent(in) :: rho
1240 real(wp),
dimension(:),
intent(in) :: qg1d
1241 real(wp),
dimension(:),
intent(inout) :: ng1d, qb1d
1242 integer :: k, nz, idx
1244 real(wp) :: mvd_g, rg, ng, rb
1248 if (qg1d(k) > r1)
then
1250 rb = rg*meters3_to_liters/rho_g(idx_bg1)
1251 idx = max(1, min(nint(10._wp*rg/rb)+1, nrhg))
1253 lamg = (3.0_dp + mu_g + 0.672_dp) / mvd_g
1254 ng = cgg(2,1)*ogg3*rg*lamg**bm_g / am_g(idx)
1259 end subroutine graupel_init
1262 subroutine thermo_vars(qv, temp, pres, rho, rhof, rhof2, qvs, delqvs, qvsi, &
1263 satw, sati, ssatw, ssati, diffu, visco, vsc2, ocp, lvap, tcond, lvt2, &
1268 real(wp),
dimension(:),
intent(in) :: qv, temp, pres, rho
1269 real(wp),
dimension(:),
intent(out) :: rhof, rhof2, qvs, &
1270 delqvs, qvsi, satw, sati, ssatw, ssati, diffu, visco, vsc2, &
1271 ocp, lvap, tcond, lvt2
1272 logical,
intent(inout) :: supersaturated
1274 real(wp) :: tempc, otemp
1277 supersaturated = .false.
1279 otemp = 1._wp / temp(k)
1280 tempc = temp(k) - t0
1281 rhof(k) = sqrt(rho_not/rho(k))
1282 rhof2(k) = sqrt(rhof(k))
1283 qvs(k) = calc_rslf(pres(k), temp(k))
1284 delqvs(k) = max(0._wp, calc_rslf(pres(k), t0)-qv(k))
1285 if (tempc <= 0._wp)
then
1286 qvsi(k) = calc_rsif(pres(k), temp(k))
1290 satw(k) = qv(k)/qvs(k)
1291 sati(k) = qv(k)/qvsi(k)
1292 ssatw(k) = satw(k) - 1._wp
1293 ssati(k) = sati(k) - 1._wp
1294 if (abs(ssatw(k)) < eps) ssatw(k) = 0._wp
1295 if (abs(ssati(k)) < eps) ssati(k) = 0._wp
1296 if (ssati(k) > 0._wp) supersaturated = .true.
1297 diffu(k) = 2.11e-5_wp*(temp(k)/t0)**1.94_wp * (101325._wp/pres(k))
1298 if (tempc >= 0._wp)
then
1299 visco(k) = (1.718_wp+0.0049_wp*tempc)*1.0e-5_wp
1301 visco(k) = (1.718_wp+0.0049_wp*tempc-1.2e-5_wp*tempc*tempc)*1.0e-5_wp
1303 ocp(k) = 1._wp/(cp*(1._wp+0.887_wp*qv(k)))
1304 vsc2(k) = sqrt(rho(k)/visco(k))
1305 lvap(k) = lvap0 + (2106.0_wp - 4218.0_wp)*tempc
1306 tcond(k) = (5.69_wp + 0.0168_wp*tempc)*1.0e-5_wp * 418.936_wp
1307 lvt2(k) = lvap(k)*lvap(k)*ocp(k)*orv*otemp*otemp
1309 end subroutine thermo_vars
1312 subroutine check_over_depletion(rho, temp, qvsi, qv, l_qc, rc, l_qi, ri, &
1313 l_qr, rr, l_qs, rs, l_qg, rg, tend, odt)
1318 real(wp),
intent(in) :: odt
1319 type(
ty_tend),
intent(inout) :: tend
1320 logical,
dimension(:),
intent(in) :: l_qc, l_qi, l_qr, l_qs, l_qg
1321 real(wp),
dimension(:),
intent(in) :: rho, temp, qvsi, qv, rc, ri, rr, rs, rg
1322 real(wp) :: sump, rate_max, ratio
1329 sump = tend%pri_inu(k) + tend%pri_ide(k) + tend%prs_ide(k) + &
1330 tend%prs_sde(k) + tend%prg_gde(k) + tend%pri_iha(k)
1331 rate_max = (qv(k)-qvsi(k))*rho(k)*odt*0.999_wp
1332 if ((sump > eps .and. sump > rate_max) .or. &
1333 (sump < -eps .and. sump < rate_max))
then
1334 ratio = rate_max/sump
1335 tend%pri_inu(k) = tend%pri_inu(k) * ratio
1336 tend%pri_ide(k) = tend%pri_ide(k) * ratio
1337 tend%pni_ide(k) = tend%pni_ide(k) * ratio
1338 tend%prs_ide(k) = tend%prs_ide(k) * ratio
1339 tend%prs_sde(k) = tend%prs_sde(k) * ratio
1340 tend%prg_gde(k) = tend%prg_gde(k) * ratio
1341 tend%pri_iha(k) = tend%pri_iha(k) * ratio
1346 sump = -tend%prr_wau(k) - tend%pri_wfz(k) - tend%prr_rcw(k) - &
1347 tend%prs_scw(k) - tend%prg_scw(k) - tend%prg_gcw(k)
1348 rate_max = -rc(k)*odt
1350 if (sump < rate_max)
then
1351 ratio = rate_max/sump
1352 tend%prr_wau(k) = tend%prr_wau(k) * ratio
1353 tend%pri_wfz(k) = tend%pri_wfz(k) * ratio
1354 tend%prr_rcw(k) = tend%prr_rcw(k) * ratio
1355 tend%prs_scw(k) = tend%prs_scw(k) * ratio
1356 tend%prg_scw(k) = tend%prg_scw(k) * ratio
1357 tend%prg_gcw(k) = tend%prg_gcw(k) * ratio
1363 sump = tend%pri_ide(k) - tend%prs_iau(k) - tend%prs_sci(k) - tend%pri_rci(k)
1364 rate_max = -ri(k)*odt
1366 if (sump < rate_max)
then
1367 ratio = rate_max/sump
1368 tend%pri_ide(k) = tend%pri_ide(k) * ratio
1369 tend%prs_iau(k) = tend%prs_iau(k) * ratio
1370 tend%prs_sci(k) = tend%prs_sci(k) * ratio
1371 tend%pri_rci(k) = tend%pri_rci(k) * ratio
1377 sump = -tend%prg_rfz(k) - tend%pri_rfz(k) - tend%prr_rci(k) + &
1378 tend%prr_rcs(k) + tend%prr_rcg(k)
1379 rate_max = -rr(k)*odt
1381 if (sump < rate_max)
then
1382 ratio = rate_max/sump
1383 tend%prg_rfz(k) = tend%prg_rfz(k) * ratio
1384 tend%pbg_rfz(k) = tend%pbg_rfz(k) * ratio
1385 tend%pri_rfz(k) = tend%pri_rfz(k) * ratio
1386 tend%prr_rci(k) = tend%prr_rci(k) * ratio
1387 tend%prr_rcs(k) = tend%prr_rcs(k) * ratio
1388 tend%prr_rcg(k) = tend%prr_rcg(k) * ratio
1394 sump = tend%prs_sde(k) - tend%prs_ihm(k) - tend%prr_sml(k) + &
1396 rate_max = -rs(k)*odt
1398 if (sump < rate_max)
then
1399 ratio = rate_max/sump
1400 tend%prs_sde(k) = tend%prs_sde(k) * ratio
1401 tend%prs_ihm(k) = tend%prs_ihm(k) * ratio
1402 tend%prr_sml(k) = tend%prr_sml(k) * ratio
1403 tend%prs_rcs(k) = tend%prs_rcs(k) * ratio
1409 sump = tend%prg_gde(k) - tend%prg_ihm(k) - tend%prr_gml(k) + tend%prg_rcg(k)
1410 rate_max = -rg(k)*odt
1412 if (sump < rate_max)
then
1413 ratio = rate_max/sump
1414 tend%prg_gde(k) = tend%prg_gde(k) * ratio
1415 tend%prg_ihm(k) = tend%prg_ihm(k) * ratio
1416 tend%prr_gml(k) = tend%prr_gml(k) * ratio
1417 tend%prg_rcg(k) = tend%prg_rcg(k) * ratio
1418 tend%pbg_rcg(k) = tend%pbg_rcg(k) * ratio
1424 tend%pri_ihm(k) = tend%prs_ihm(k) + tend%prg_ihm(k)
1426 ratio = min(abs(tend%prr_rcg(k)), abs(tend%prg_rcg(k)))
1427 tend%prr_rcg(k) = ratio * sign(1.0_dp, tend%prr_rcg(k))
1428 tend%prg_rcg(k) = -tend%prr_rcg(k)
1429 tend%pbg_rcg(k) = meters3_to_liters*tend%prg_rcg(k)/rho_i
1431 if (temp(k) > t0)
then
1432 ratio = min(abs(tend%prr_rcs(k)), abs(tend%prs_rcs(k)))
1433 tend%prr_rcs(k) = ratio * sign(1.0_dp, tend%prr_rcs(k))
1434 tend%prs_rcs(k) = -tend%prr_rcs(k)
1437 end subroutine check_over_depletion
1440 subroutine sum_tendencies(rho, temp, idx, lvap, ocp, tend, tten, qvten, qcten, &
1441 ncten, qiten, niten, qsten, qrten, nrten, qgten, ngten, qbten)
1445 type(
ty_tend),
intent(in) :: tend
1446 real(wp),
dimension(:),
intent(in) :: rho, temp, lvap, ocp
1447 integer,
dimension(:),
intent(in) :: idx
1448 real(wp),
dimension(:),
intent(inout) :: qvten, qcten, ncten, qiten, niten, &
1449 qsten, qrten, nrten, qgten, ngten, qbten, tten
1450 real(wp) :: orho, lfus2
1456 lfus2 = lsub - lvap(k)
1458 qvten(k) = qvten(k) + (-tend%pri_inu(k) - tend%pri_iha(k) - tend%pri_ide(k) - &
1459 tend%prs_ide(k) - tend%prs_sde(k) - tend%prg_gde(k)) * orho
1461 qcten(k) = qcten(k) + (-tend%prr_wau(k) - tend%pri_wfz(k) - tend%prr_rcw(k) - &
1462 tend%prs_scw(k) - tend%prg_scw(k) - tend%prg_gcw(k)) * orho
1464 ncten(k) = ncten(k) + (-tend%pnc_wau(k) - tend%pnc_rcw(k) - tend%pni_wfz(k) - &
1465 tend%pnc_scw(k) - tend%pnc_gcw(k)) * orho
1467 qiten(k) = qiten(k) + (tend%pri_inu(k) + tend%pri_iha(k) + tend%pri_ihm(k) + &
1468 tend%pri_wfz(k) + tend%pri_rfz(k) + tend%pri_ide(k) - tend%prs_iau(k) - &
1469 tend%prs_sci(k) - tend%pri_rci(k)) * orho
1471 niten(k) = niten(k) + (tend%pni_inu(k) + tend%pni_iha(k) + tend%pni_ihm(k) + &
1472 tend%pni_wfz(k) + tend%pni_rfz(k) + tend%pni_ide(k) - tend%pni_iau(k) - &
1473 tend%pni_sci(k) - tend%pni_rci(k)) * orho
1475 qrten(k) = qrten(k) + (tend%prr_wau(k) + tend%prr_rcw(k) + tend%prr_sml(k) + &
1476 tend%prr_gml(k) + tend%prr_rcs(k) + tend%prr_rcg(k) - tend%prg_rfz(k) - &
1477 tend%pri_rfz(k) - tend%prr_rci(k)) * orho
1479 nrten(k) = nrten(k) + (tend%pnr_wau(k) + tend%pnr_sml(k) + tend%pnr_gml(k) - &
1480 (tend%pnr_rfz(k) + tend%pnr_rcr(k) + tend%pnr_rcg(k) + tend%pnr_rcs(k) + &
1481 tend%pnr_rci(k) + tend%pni_rfz(k))) * orho
1483 qsten(k) = qsten(k) + (tend%prs_iau(k) + tend%prs_sde(k) + tend%prs_sci(k) + &
1484 tend%prs_scw(k) + tend%prs_rcs(k) + tend%prs_ide(k) - tend%prs_ihm(k) - &
1485 tend%prr_sml(k)) * orho
1487 qgten(k) = qgten(k) + (tend%prg_scw(k) + tend%prg_rfz(k) + tend%prg_gde(k) + &
1488 tend%prg_rcg(k) + tend%prg_gcw(k) + tend%prg_rci(k) + tend%prg_rcs(k) - &
1489 tend%prg_ihm(k) - tend%prr_gml(k)) * orho
1491 ngten(k) = ngten(k) + (tend%png_scw(k) + tend%png_rfz(k) - tend%png_rcg(k) + &
1492 tend%png_rci(k) + tend%png_rcs(k) + tend%png_gde(k) - tend%pnr_gml(k)) * orho
1494 qbten(k) = qbten(k) + (tend%pbg_scw(k) + tend%pbg_rfz(k) + tend%pbg_gcw(k) + &
1495 tend%pbg_rci(k) + tend%pbg_rcs(k) + tend%pbg_rcg(k) + tend%pbg_sml(k) - &
1496 tend%pbg_gml(k) + meters3_to_liters * (tend%prg_gde(k) - tend%prg_ihm(k)) / rho_g(idx(k))) * orho
1498 if (temp(k) < t0)
then
1499 tten(k) = tten(k) + &
1500 (lsub*ocp(k)*(tend%pri_inu(k) + tend%pri_ide(k) + &
1501 tend%prs_ide(k) + tend%prs_sde(k) + tend%prg_gde(k) + tend%pri_iha(k)) + &
1502 lfus2*ocp(k)*(tend%pri_wfz(k) + tend%pri_rfz(k) + tend%prg_rfz(k) + &
1503 tend%prs_scw(k) + tend%prg_scw(k) + tend%prg_gcw(k) + tend%prg_rcs(k) + &
1504 tend%prs_rcs(k) + tend%prr_rci(k) + tend%prg_rcg(k)))*orho
1506 tten(k) = tten(k) + &
1507 (lfus*ocp(k)*(-tend%prr_sml(k) - tend%prr_gml(k) - &
1508 tend%prr_rcg(k) - tend%prr_rcs(k)) + &
1509 lsub*ocp(k)*(tend%prs_sde(k) + tend%prg_gde(k)))*orho
1512 end subroutine sum_tendencies
1515 subroutine sedimentation(xr, vt, dz1d, rho, xten, limit, steps, ktop_sedi, precip, dt)
1520 real(wp),
intent(in) :: dt
1521 integer,
intent(in) :: steps
1522 integer,
intent(in),
optional :: ktop_sedi
1523 real(wp),
dimension(:),
intent(inout) :: xr, xten
1524 real(wp),
dimension(:),
intent(in) :: dz1d, rho
1525 real(wp),
dimension(:),
intent(in) :: vt
1526 real(wp),
intent(in) :: limit
1527 real(wp),
intent(inout),
optional :: precip
1528 real(wp) :: odz, orho
1529 real(wp),
allocatable,
dimension(:) :: sed_r
1530 integer :: k, nz, ktop
1533 allocate(sed_r(nz), source=0._wp)
1535 if (
present(ktop_sedi)) ktop = ktop_sedi
1538 sed_r(k) = vt(k)*xr(k)
1543 xten(k) = xten(k) - sed_r(k)*odz*(1._wp/real(steps, kind=wp))*orho
1544 xr(k) = max(limit, xr(k) - sed_r(k)*odz*dt*(1._wp/real(steps, kind=wp)))
1549 xten(k) = xten(k) + (sed_r(k+1)-sed_r(k))*odz*(1._wp/real(steps, kind=wp))*orho
1550 xr(k) = max(limit, xr(k) + (sed_r(k+1)-sed_r(k))*odz*dt*(1._wp/real(steps, kind=wp)))
1553 if (
present(precip))
then
1554 if (xr(1) > low_limit_mass_for_precip)
then
1555 precip = precip + sed_r(1)*dt*(1._wp/real(steps, kind=wp))
1558 end subroutine sedimentation
1561 subroutine semilagrangian_sedimentation(dz1d, rho, xr, xten, vt, steps, limit, precip, dt, odt)
1568 real(wp),
intent(in) :: dt, odt
1569 integer,
intent(in) :: steps
1570 real(wp),
intent(in) :: limit
1571 real(wp),
dimension(:),
intent(in) :: dz1d, rho
1572 real(wp),
dimension(:),
intent(inout) :: xr, xten
1573 real(wp),
dimension(:),
intent(in) :: vt
1574 real(wp) :: fa1, fa2, con1, decfl, dip, dim, tl, th, tl2, th2, qqd, qqh, qql, zsum, qsum, &
1576 real(wp),
dimension(:),
allocatable :: zi, wi, za, dza, qa, qmi, qpi, net_flx, precip_flx, rr_save
1577 real(wp),
intent(out),
optional :: precip
1578 integer :: k, nz, kk, kb, kt, m
1581 allocate(zi(nz+1), source=0._wp)
1582 allocate(wi(nz+1), source=0._wp)
1583 allocate(dza(nz+1), source=0._wp)
1584 allocate(za(nz+2), source=0._wp)
1585 allocate(qa(nz+1), source=0._wp)
1586 allocate(qmi(nz+1), source=0._wp)
1587 allocate(qpi(nz+1), source=0._wp)
1588 allocate(net_flx(nz), source=0._wp)
1589 allocate(precip_flx(nz), source=0._wp)
1590 allocate(rr_save(nz), source=xr)
1594 zi(k+1) = zi(k) + dz1d(k)
1601 wi(2) = 0.5_wp*(vt(2)+vt(1))
1603 wi(k) = fa1*(vt(k)+vt(k-1))-fa2*(vt(k+1)+vt(k-2))
1605 wi(nz) = 0.5_wp*(vt(nz)+vt(nz-1))
1609 if(vt(k) == 0._wp) wi(k) = vt(k-1)
1616 decfl = (wi(k+1)-wi(k))*dt*(1._wp/real(steps, kind=wp))/dz1d(k)
1617 if(decfl > con1)
then
1618 wi(k) = wi(k+1) - con1*dz1d(k)*odt*real(steps, kind=wp)
1624 za(k) = zi(k) - wi(k)*dt*(1._wp/real(steps, kind=wp))
1628 dza(k) = za(k+1)-za(k)
1633 qa(k) = xr(k)*dz1d(k)/dza(k)
1639 dip=(qa(k+1)-qa(k))/(dza(k+1)+dza(k))
1640 dim=(qa(k)-qa(k-1))/(dza(k-1)+dza(k))
1641 if(dip*dim <= 0._wp)
then
1645 qpi(k)=qa(k)+0.5_wp*(dip+dim)*dza(k)
1646 qmi(k)=2._wp*qa(k)-qpi(k)
1647 if(qpi(k) > 0._wp .or. qmi(k) < 0._wp)
then
1655 qmi(nz+1) = qa(nz+1)
1656 qpi(nz+1) = qa(nz+1)
1665 if(zi(k) >= za(nz+1))
then
1668 find_kb :
do kk = kb, nz
1669 if(zi(k) <= za(kk+1))
then
1676 find_kt :
do kk = kt, nz+2
1677 if(zi(k+1) <= za(kk))
then
1688 tl = (zi(k)-za(kb))/dza(kb)
1689 th = (zi(k+1)-za(kb))/dza(kb)
1692 qqd = 0.5_wp*(qpi(kb)-qmi(kb))
1693 qqh = qqd*th2+qmi(kb)*th
1694 qql = qqd*tl2+qmi(kb)*tl
1695 xr(k) = (qqh-qql)/(th-tl)
1696 elseif(kt > kb)
then
1697 tl = (zi(k)-za(kb))/dza(kb)
1699 qqd = 0.5_wp*(qpi(kb)-qmi(kb))
1700 qql = qqd*tl2+qmi(kb)*tl
1702 zsum = (1._wp-tl)*dza(kb)
1706 zsum = zsum + dza(m)
1707 qsum = qsum + qa(m) * dza(m)
1710 th = (zi(k+1)-za(kt))/dza(kt)
1712 qqd = 0.5_wp*(qpi(kt)-qmi(kt))
1713 dqh = qqd*th2+qmi(kt)*th
1714 zsum = zsum + th*dza(kt)
1715 qsum = qsum + dqh*dza(kt)
1719 orho = 1._wp / rho(k)
1720 xr(k) = max(xr(k), limit)
1721 xten(k) = xten(k) + (xr(k) - rr_save(k)) * &
1725 precip_loop:
do k = 1, nz
1726 if(za(k) < 0._wp .and. za(k+1) <= 0.0_wp)
then
1727 if (
present(precip)) precip = precip + qa(k)*dza(k)
1728 net_flx(k) = qa(k)*dza(k)
1729 elseif (za(k) < 0._wp .and. za(k+1) > 0._wp)
then
1730 th = (0._wp-za(k))/dza(k)
1732 qqd = 0.5_wp*(qpi(k)-qmi(k))
1733 qqh = qqd*th2+qmi(k)*th
1734 if (
present(precip)) precip = precip + qqh*dza(k)
1735 net_flx(k) = qqh*dza(k)
1743 precip_flx(k) = net_flx(k)
1745 precip_flx(k) = precip_flx(k+1) + net_flx(k)
1748 end subroutine semilagrangian_sedimentation
1751 subroutine rain_fallspeed(rhof, l_qr, rr, ilamr, dz1d, vt, vtn, substeps_sedi, ktop_sedi, dt)
1756 real(wp),
intent(in) :: dt
1757 real(wp),
dimension(:),
intent(in) :: rhof, dz1d, rr
1758 real(dp),
dimension(:),
intent(in) :: ilamr
1759 logical,
dimension(:),
intent(in) :: l_qr
1760 real(wp),
dimension(:),
intent(inout) :: vt, vtn
1761 integer,
intent(out),
optional :: substeps_sedi, ktop_sedi
1762 real(wp) :: dz_by_vt
1767 if (
present(ktop_sedi)) ktop_sedi = 1
1768 if (
present(substeps_sedi)) substeps_sedi = 1
1770 if (rr(k) > r1)
then
1771 lamr = 1._dp / ilamr(k)
1772 vt(k) = rhof(k)*av_r*crg(6)*org3 * lamr**cre(3) *((lamr+fv_r)**(-cre(6)))
1773 vtn(k) = rhof(k)*av_r*crg(7)/crg(12) * lamr**cre(12)*((lamr+fv_r)**(-cre(7)))
1778 if (max(vt(k), vtn(k)) > 1.e-3_wp)
then
1779 if (
present(ktop_sedi)) ktop_sedi = max(ktop_sedi, k)
1780 dz_by_vt = dz1d(k) / (max(vt(k), vtn(k)))
1781 if (
present(substeps_sedi))
then
1782 substeps_sedi = max(substeps_sedi, int(dt/dz_by_vt + 1._wp))
1786 if (
present(ktop_sedi))
then
1787 if (ktop_sedi == nz) ktop_sedi = nz-1
1789 end subroutine rain_fallspeed
1792 subroutine graupel_fallspeed(rhof, rho, visco, l_qg, rg, rb, qb1d, idx, ilamg, &
1793 dz1d, vt, vtn, substeps_sedi, ktop_sedi, dt)
1797 cgg, t0, mu_g, ogg2, ogg3, a_coeff, b_coeff, meters3_to_liters, earth_gravity
1799 real(wp),
intent(in) :: dt
1800 real(wp),
dimension(:),
intent(in) :: rhof, rho, visco, dz1d, rg, rb
1801 real(wp),
dimension(:),
intent(in),
optional :: qb1d
1802 real(dp),
dimension(:),
intent(in) :: ilamg
1803 logical,
dimension(:),
intent(in) :: l_qg
1804 integer,
dimension(:),
intent(in) :: idx
1805 real(wp),
dimension(:),
intent(inout) :: vt, vtn
1806 integer,
intent(out),
optional :: substeps_sedi, ktop_sedi
1807 real(wp) :: dz_by_vt, dens_g, afall, bfall
1811 if (
present(ktop_sedi)) ktop_sedi = 1
1812 if (
present(substeps_sedi)) substeps_sedi = 1
1814 if (rg(k) > r1)
then
1815 if (
present(qb1d))
then
1816 dens_g = max(rho_g(1), min(meters3_to_liters*rg(k)/rb(k), rho_g(nrhg)))
1817 afall = a_coeff*((4._wp*dens_g*earth_gravity)/(3._wp*rho(k)))**b_coeff
1818 afall = afall * visco(k)**(1._wp-2._wp*b_coeff)
1819 bfall = 3._wp*b_coeff - 1._wp
1824 vt(k) = rhof(k)*afall*cgg(6,idx(k))*ogg3 * ilamg(k)**bfall
1828 vtn(k) = rhof(k)*afall*cgg(7,idx(k))/cgg(12,idx(k)) * ilamg(k)**bfall
1830 vtn(k) = rhof(k)*afall*cgg(8,idx(k))*ogg2 * ilamg(k)**bfall
1836 if (vt(k) > 1.e-3_wp)
then
1837 if (
present(ktop_sedi)) ktop_sedi = max(ktop_sedi, k)
1838 dz_by_vt = dz1d(k) / vt(k)
1839 if (
present(substeps_sedi))
then
1840 substeps_sedi = max(substeps_sedi, int(dt/dz_by_vt + 1._wp))
1844 if (
present(ktop_sedi))
then
1845 if (ktop_sedi == nz) ktop_sedi = nz-1
1847 end subroutine graupel_fallspeed
1850 subroutine snow_fallspeed(rhof, l_qs, rs, prr_sml, smob, smoc, &
1851 rr, vtrr, dz1d, vt, vtboost, substeps_sedi, ktop_sedi, dt)
1857 real(wp),
intent(in) :: dt
1858 real(wp),
dimension(:),
intent(in) :: rhof, dz1d, rs, rr, vtboost
1859 real(wp),
dimension(:),
intent(in) :: vtrr
1860 logical,
dimension(:),
intent(in) :: l_qs
1861 real(wp),
dimension(:),
intent(inout) :: vt
1862 real(dp),
dimension(:),
intent(in) :: smob, smoc, prr_sml
1863 integer,
intent(out),
optional :: substeps_sedi, ktop_sedi
1864 real(wp) :: dz_by_vt, vts, sr
1865 real(dp) :: xds, mrat, ils1, ils2, t1_vts, t2_vts, t3_vts, t4_vts
1869 if (
present(ktop_sedi)) ktop_sedi = 1
1870 if (
present(substeps_sedi)) substeps_sedi = 1
1872 if (rs(k) > r1)
then
1873 xds = smoc(k) / smob(k)
1875 ils1 = 1._dp/(mrat*lam0 + fv_s)
1876 ils2 = 1._dp/(mrat*lam1 + fv_s)
1877 t1_vts = kap0*csg(4)*ils1**cse(4)
1878 t2_vts = kap1*mrat**mu_s*csg(10)*ils2**cse(10)
1879 ils1 = 1._dp/(mrat*lam0)
1880 ils2 = 1._dp/(mrat*lam1)
1881 t3_vts = kap0*csg(1)*ils1**cse(1)
1882 t4_vts = kap1*mrat**mu_s*csg(7)*ils2**cse(7)
1883 vts = rhof(k)*av_s * (t1_vts+t2_vts)/(t3_vts+t4_vts)
1885 if (prr_sml(k) > 0._dp)
then
1886 sr = rs(k)/(rs(k)+rr(k))
1887 vt(k) = vts*sr + (1._wp-sr)*vtrr(k)
1889 vt(k) = vts*vtboost(k)
1894 if (vt(k) > 1.e-3_wp)
then
1895 if (
present(ktop_sedi)) ktop_sedi = max(ktop_sedi, k)
1896 dz_by_vt = dz1d(k) / vt(k)
1897 if (
present(substeps_sedi))
then
1898 substeps_sedi = max(substeps_sedi, int(dt/dz_by_vt + 1._wp))
1902 if (
present(ktop_sedi))
then
1903 if (ktop_sedi == nz) ktop_sedi = nz-1
1905 end subroutine snow_fallspeed
1908 subroutine ice_fallspeed(rhof, l_qi, ri, ilami, dz1d, vt, vtn, &
1909 substeps_sedi, ktop_sedi, dt)
1914 real(wp),
intent(in) :: dt
1915 real(wp),
dimension(:),
intent(in) :: rhof, dz1d, ri
1916 real(dp),
dimension(:),
intent(in) :: ilami
1917 logical,
dimension(:),
intent(in) :: l_qi
1918 real(wp),
dimension(:),
intent(inout) :: vt, vtn
1919 integer,
intent(out) :: substeps_sedi, ktop_sedi
1920 real(wp) :: dz_by_vt
1927 if (ri(k) > r1)
then
1928 vt(k) = rhof(k)*av_i*cig(3)*oig2 * ilami(k)**bv_i
1929 vtn(k) = rhof(k)*av_i*cig(6)/cig(7) * ilami(k)**bv_i
1934 if (vt(k) > 1.e-3_wp)
then
1935 ktop_sedi = max(ktop_sedi, k)
1936 dz_by_vt = dz1d(k) / vt(k)
1937 substeps_sedi = max(substeps_sedi, int(dt/dz_by_vt + 1._wp))
1940 if (ktop_sedi == nz) ktop_sedi = nz-1
1941 end subroutine ice_fallspeed
1944 subroutine cloud_fallspeed(rhof, w1d, l_qc, rc, nc, ilamc, dz1d, vt, vtn, &
1950 real(wp),
dimension(:),
intent(in) :: rhof, w1d, dz1d, rc, nc
1951 real(dp),
dimension(:),
intent(in) :: ilamc
1952 logical,
dimension(:),
intent(in) :: l_qc
1953 real(wp),
dimension(:),
intent(inout) :: vt, vtn
1954 integer,
intent(out) :: ktop_sedi
1956 integer :: k, nz, nu_c
1963 hgt_loop :
do k = 1, nz-1
1964 if (rc(k) > r2) ktop_sedi = k
1966 if (hgt > 500._wp)
exit hgt_loop
1969 do k = ktop_sedi, 1, -1
1970 if (rc(k) > r1 .and. w1d(k) < 0.1_wp)
then
1971 nu_c = get_nuc(nc(k))
1972 vt(k) = rhof(k)*av_c*ccg(5,nu_c)*ocg2(nu_c) * ilamc(k)**bv_c
1973 vtn(k) = rhof(k)*av_c*ccg(4,nu_c)*ocg1(nu_c) * ilamc(k)**bv_c
1976 end subroutine cloud_fallspeed
1979 subroutine cloud_condensation(rho, temp, w1d, ssatw, lvap, tcond, diffu, lvt2, &
1980 nwfa1d, nwfa, ncsave, qv, qvs, l_qc, rc, nc, tend, dt, odt)
1983 tnc_wev, nt_c_min, nt_c_l
1985 real(wp),
intent(in) :: dt, odt
1986 type(
ty_tend),
intent(inout) :: tend
1987 real(wp),
dimension(:),
intent(in) :: rho, temp, w1d, ssatw, lvap, tcond, diffu, lvt2, &
1988 nwfa, qv, qvs, rc, nc
1989 real(wp),
dimension(:),
intent(in),
optional :: nwfa1d, ncsave
1990 logical,
dimension(:),
intent(in) :: l_qc
1991 real(wp) :: clap, fcd, dfcd, xrc, xnc, orho, tempc, otemp, &
1992 rvs, rvs_p, rvs_pp, gamsc, alphsc, xsat, t1_evap
1994 integer :: k, nz, n, idx_d, idx_n, idx_c
1998 if (abs(ssatw(k)) < eps) cycle
2001 clap = (qv(k)-qvs(k))/(1._wp + lvt2(k)*qvs(k))
2003 fcd = qvs(k)*exp(lvt2(k)*clap) - qv(k) + clap
2004 dfcd = qvs(k)*lvt2(k)*exp(lvt2(k)*clap) + 1._wp
2005 clap = clap - fcd/dfcd
2007 xrc = rc(k) + clap*rho(k)
2012 tend%prw_vcd(k) = clap*odt
2014 if (clap > eps)
then
2015 if (
present(nwfa1d))
then
2016 xnc = max(nt_c_min, activate_cloud_number(temp(k), w1d(k), nwfa(k)))
2017 elseif (
present(ncsave))
then
2022 tend%pnc_wcd(k) = 0.5_wp*(xnc-nc(k) + abs(xnc-nc(k)))*odt*orho
2023 elseif (l_qc(k) .and. ssatw(k) < -1.e-6_wp .and. clap < -eps)
then
2024 tempc = temp(k) - t0
2025 otemp = 1._wp/temp(k)
2027 rvs_p = rvs*otemp*(lvap(k)*otemp*orv - 1._wp)
2028 rvs_pp = rvs * (otemp*(lvap(k)*otemp*orv - 1._wp) * &
2029 otemp*(lvap(k)*otemp*orv - 1._wp) + &
2030 (-2._wp*lvap(k)*otemp*otemp*otemp*orv) + otemp*otemp)
2031 gamsc = lvap(k)*diffu(k)/tcond(k) * rvs_p
2032 alphsc = 0.5_wp*(gamsc/(1._wp+gamsc))*(gamsc/(1._wp+gamsc)) * &
2033 rvs_pp/rvs_p * rvs/rvs_p
2034 alphsc = max(1.e-9_wp, alphsc)
2036 if (abs(xsat) < 1.e-9_wp) xsat = 0._wp
2037 t1_evap = 2._wp*pi*(1.0_wp - alphsc*xsat + 2._wp*alphsc*alphsc*xsat*xsat - &
2038 5._wp*alphsc*alphsc*alphsc*xsat*xsat*xsat) / (1._wp+gamsc)
2040 dc_star = sqrt(-2._dp*dt * t1_evap/(2._dp*pi) * &
2041 4._dp*diffu(k)*ssatw(k)*rvs/rho_w)
2042 idx_d = max(1, min(int(1.e6_wp*dc_star), nbc))
2043 call get_cloud_table_index(rc(k), nc(k), idx_c, idx_n)
2045 tend%prw_vcd(k) = max(real(-rc(k)*0.99_wp*orho*odt, kind=dp), &
2047 tend%pnc_wcd(k) = max(real(-nc(k)*0.99_wp*orho*odt, kind=dp), &
2048 -tnc_wev(idx_d, idx_c, idx_n)*orho*odt)
2051 tend%prw_vcd(k) = -rc(k)*orho*odt
2052 tend%pnc_wcd(k) = -nc(k)*orho*odt
2055 end subroutine cloud_condensation
2058 subroutine rain_evaporation(rho, temp, ssatw, lvap, tcond, diffu, &
2059 vsc2, rhof2, qv, qvs, l_qr, rr, nr, ilamr, tend, odt)
2063 org2, cre, t1_qr_ev, t2_qr_ev, fv_r
2065 real(wp),
intent(in) :: odt
2066 type(
ty_tend),
intent(inout) :: tend
2067 real(wp),
dimension(:),
intent(in) :: rho, temp, ssatw, lvap, tcond, diffu, vsc2, rhof2, &
2069 logical,
dimension(:),
intent(in) :: l_qr
2070 real(dp),
dimension(:),
intent(in) :: ilamr
2071 real(wp) :: orho, tempc, otemp, &
2072 rvs, rvs_p, rvs_pp, gamsc, alphsc, xsat, t1_evap, rate_max, eva_factor
2073 real(dp) :: lamr, n0_r
2079 if ((ssatw(k) < -eps) .and. tend%prw_vcd(k) <= 0._dp)
then
2081 tempc = temp(k) - t0
2082 otemp = 1._wp/temp(k)
2084 rvs_p = rvs*otemp*(lvap(k)*otemp*orv - 1._wp)
2085 rvs_pp = rvs * (otemp*(lvap(k)*otemp*orv - 1._wp) * &
2086 otemp*(lvap(k)*otemp*orv - 1._wp) + &
2087 (-2._wp*lvap(k)*otemp*otemp*otemp*orv) + otemp*otemp)
2088 gamsc = lvap(k)*diffu(k)/tcond(k) * rvs_p
2089 alphsc = 0.5_wp*(gamsc/(1._wp+gamsc))*(gamsc/(1._wp+gamsc)) * &
2090 rvs_pp/rvs_p * rvs/rvs_p
2091 alphsc = max(1.e-9_wp, alphsc)
2092 xsat = min(-1.e-9_wp, ssatw(k))
2093 t1_evap = 2._wp*pi*(1.0_wp - alphsc*xsat + 2._wp*alphsc*alphsc*xsat*xsat - &
2094 5._wp*alphsc*alphsc*alphsc*xsat*xsat*xsat) / (1._wp+gamsc)
2099 if (qv(k)/qvs(k) < 0.95_wp .and. rr(k)*orho <= 1.e-8_wp)
then
2100 tend%prv_rev(k) = rr(k)*orho*odt
2102 lamr = 1._dp/ilamr(k)
2103 n0_r = nr(k)*org2*lamr**cre(2)
2104 tend%prv_rev(k) = t1_evap*diffu(k)*(-ssatw(k))*n0_r*rvs * &
2105 (t1_qr_ev*ilamr(k)**cre(10) + t2_qr_ev*vsc2(k)*rhof2(k)* &
2106 ((lamr+0.5*fv_r)**(-cre(11))))
2107 rate_max = min((rr(k)*orho*odt), &
2109 tend%prv_rev(k) = min(real(rate_max, kind=dp), tend%prv_rev(k)*orho)
2110 if (tend%prr_gml(k) > 0._dp)
then
2111 eva_factor = min(1._wp, 0.01_wp+(0.99_wp-0.01_wp)*(tempc/20._wp))
2112 tend%prv_rev(k) = tend%prv_rev(k)*eva_factor
2115 tend%pnr_rev(k) = min(real(nr(k)*0.99*orho*odt, kind=dp), &
2116 tend%prv_rev(k) * nr(k)/rr(k))
2120 end subroutine rain_evaporation
2123 subroutine freeze_cloud_melt_ice(temp, rho, ocp, lvap, qi1d, ni1d, qiten, niten, &
2124 qc1d, nc1d, qcten, ncten, tten, ncsave, dt, odt)
2128 real(wp),
intent(in) :: dt, odt
2129 real(wp),
dimension(:),
intent(in) :: temp, rho, ocp, lvap, qi1d, ni1d, qc1d
2130 real(wp),
dimension(:),
intent(inout) :: qiten, niten, qcten, ncten, tten
2131 real(wp),
dimension(:),
intent(in),
optional :: nc1d, ncsave
2132 real(wp) :: xri, xrc, lfus2, xnc
2138 xri = max(0._wp, qi1d(k)+qiten(k)*dt)
2139 if ((temp(k) > t0) .and. (xri > 0._wp))
then
2140 qcten(k) = qcten(k) + xri*odt
2141 ncten(k) = ncten(k) + ni1d(k)*odt
2142 qiten(k) = qiten(k) - xri*odt
2143 niten(k) = -ni1d(k)*odt
2144 tten(k) = tten(k) - lfus*ocp(k)*xri*odt
2147 xrc = max(0._wp, qc1d(k)+qcten(k)*dt)
2148 if ((temp(k) < hgfrz) .and. (xrc > 0._wp))
then
2149 lfus2 = lsub - lvap(k)
2150 if (
present(nc1d))
then
2151 xnc = nc1d(k) + ncten(k)*dt
2152 elseif (
present(ncsave))
then
2153 xnc = ncsave(k)/rho(k) + ncten(k)*dt
2155 xnc = nt_c_l/rho(k) + ncten(k)*dt
2157 qiten(k) = qiten(k) + xrc*odt
2158 niten(k) = niten(k) + xnc*odt
2159 qcten(k) = qcten(k) - xrc*odt
2160 ncten(k) = ncten(k) - xnc*odt
2161 tten(k) = tten(k) + lfus2*ocp(k)*xrc*odt
2164 end subroutine freeze_cloud_melt_ice
2167 function koop_nucleation(temp, satw, naero, dt)
result(nuc)
2174 real(wp),
intent(in) :: temp, satw, naero, dt
2175 real(wp) :: xni, mu_diff, a_w_i, delta_aw, log_j_rate, j_rate, prob_h
2180 mu_diff = 210368._wp + (131.438_wp*temp) - &
2181 (3.32373e6_wp/temp) - (41729.1_wp*log(temp))
2182 a_w_i = exp(mu_diff/(r_uni*temp))
2183 delta_aw = satw - a_w_i
2185 log_j_rate = -906.7_wp + (8502._wp*delta_aw) - &
2186 (26924._wp*delta_aw*delta_aw) + (29180._wp*delta_aw*delta_aw*delta_aw)
2187 log_j_rate = min(20._wp, log_j_rate)
2188 j_rate = 10._wp**log_j_rate
2189 prob_h = min(1._wp-exp(-j_rate*ar_volume*dt), 1._wp)
2190 if (prob_h > 0._wp)
then
2191 xni = min(prob_h*naero, 1000.e3_wp)
2193 nuc = max(0._wp, xni)
2194 end function koop_nucleation
2197 function activate_cloud_number(temp, w1d, nwfa, land)
result(activ)
2200 ta_tk, ntb_art, tnccn_act
2202 real(wp),
intent(in) :: temp, w1d, nwfa
2203 integer,
intent(in),
optional :: land
2204 real(wp) :: n_local, w_local
2205 real(wp) :: a, b, c, d, t, u, x1, x2, y1, y2, nx, wy, fraction
2206 real(wp) :: lower_lim_nuc_frac
2207 integer :: i, j, k, l, m, n
2211 n_local = nwfa * 1.e-6_wp
2212 if (n_local >= ta_na(ntb_arc))
then
2213 n_local = ta_na(ntb_arc) - 1.0_wp
2214 elseif (n_local <= ta_na(1))
then
2215 n_local = ta_na(1) + 1.0_wp
2217 nindex:
do n = 2, ntb_arc
2218 if (n_local >= ta_na(n-1) .and. n_local < ta_na(n))
exit nindex
2221 x1 = log(ta_na(i-1))
2226 if (w_local >= ta_ww(ntb_arw))
then
2227 w_local = ta_ww(ntb_arw) - 1.0_wp
2228 elseif (w_local <= ta_ww(1))
then
2229 w_local = ta_ww(1) + 0.001_wp
2231 windex:
do n = 2, ntb_arw
2232 if (w_local >= ta_ww(n-1) .and. w_local < ta_ww(n))
exit windex
2235 y1 = log(ta_ww(j-1))
2238 k = max(1, min(nint((temp - ta_tk(1))*0.1_wp) + 1, ntb_art))
2251 lower_lim_nuc_frac = 0.
2252 if (
present(land))
then
2254 lower_lim_nuc_frac = 0.
2255 elseif (land == 0)
then
2256 lower_lim_nuc_frac = 0.15
2258 lower_lim_nuc_frac = 0.15
2262 a = tnccn_act(i-1,j-1,k,l,m)
2263 b = tnccn_act(i,j-1,k,l,m)
2264 c = tnccn_act(i,j,k,l,m)
2265 d = tnccn_act(i-1,j,k,l,m)
2271 fraction = (1.0_wp-t)*(1.0_wp-u)*a + t*(1.0_wp-u)*b + t*u*c + (1.0_wp-t)*u*d
2272 fraction = max(fraction, lower_lim_nuc_frac)
2274 activ = nwfa*fraction
2275 end function activate_cloud_number
2278 subroutine warm_rain(rhof, l_qc, rc, nc, ilamc, mvd_c, l_qr, rr, nr, mvd_r, tend, odt)
2281 t1_qr_qc, mu_r, am_r, ccg, obmr, ocg2, dr, org2, cre, fv_r, &
2284 real(wp),
intent(in) :: odt
2285 real(wp),
dimension(:),
intent(in) :: rhof, mvd_r, mvd_c, rr, nr, rc, nc
2286 real(dp),
dimension(:),
intent(in) :: ilamc
2287 logical,
dimension(:),
intent(in) :: l_qc, l_qr
2288 type(
ty_tend),
intent(inout) :: tend
2290 real(dp) :: lamr, lamc, n0_r
2291 real(wp) :: ef_rr, dc_g, dc_b, xdc, zeta1, zeta, taud, tau, ef_rw
2292 integer :: k, nz, nu_c, idx
2302 if (mvd_r(k) > d0r)
then
2303 ef_rr = max(-0.1_wp, 1.0_wp - exp(2300.0_wp*(mvd_r(k)-1950.0e-6_wp)))
2304 tend%pnr_rcr(k) = ef_rr * 2.0_wp*nr(k)*rr(k)
2313 if (rc(k) > 0.01e-3_wp)
then
2314 nu_c = get_nuc(nc(k))
2315 lamc = 1._dp / ilamc(k)
2316 xdc = max(d0c*1.e6_wp, ((rc(k)/(am_r*nc(k)))**obmr) * 1.e6_wp)
2317 dc_g = ((ccg(3,nu_c)*ocg2(nu_c))**obmr / lamc) * 1.e6_wp
2318 dc_b = (xdc*xdc*xdc*dc_g*dc_g*dc_g - xdc*xdc*xdc*xdc*xdc*xdc) &
2320 zeta1 = 0.5_wp*((6.25e-6_wp*xdc*dc_b*dc_b*dc_b - 0.4_wp) &
2321 + abs(6.25e-6_wp*xdc*dc_b*dc_b*dc_b - 0.4_wp))
2322 zeta = 0.027_wp*rc(k)*zeta1
2323 taud = 0.5_wp*((0.5_wp*dc_b - 7.5_wp) + abs(0.5_wp*dc_b - 7.5_wp)) + r1
2324 tau = 3.72_wp/(rc(k)*taud)
2325 tend%prr_wau(k) = zeta/tau
2326 tend%prr_wau(k) = min(real(rc(k)*odt, kind=dp), &
2328 tend%pnr_wau(k) = tend%prr_wau(k) / (am_r*nu_c*autocon_nr_factor*d0r*d0r*d0r)
2329 tend%pnc_wau(k) = min(real(nc(k)*odt, kind=dp), &
2330 tend%prr_wau(k) / (am_r*mvd_c(k)*mvd_c(k)*mvd_c(k)))
2337 if (l_qr(k) .and. l_qc(k))
then
2338 if (mvd_r(k) > d0r .and. mvd_c(k) > d0c)
then
2339 lamr = (3.0_dp + mu_r + 0.672_dp) / mvd_r(k)
2340 idx = 1 + int(nbr*log(real(mvd_r(k)/dr(1), kind=dp)) / &
2341 log(real(dr(nbr)/dr(1), kind=dp)))
2343 ef_rw = t_efrw(idx, int(mvd_c(k)*1.e6_wp))
2344 n0_r = nr(k)*org2*lamr**cre(2)
2345 tend%prr_rcw(k) = rhof(k)*t1_qr_qc*ef_rw*rc(k)*n0_r * &
2346 ((lamr+fv_r)**(-cre(9)))
2347 tend%prr_rcw(k) = min(real(rc(k)*odt, kind=dp), tend%prr_rcw(k))
2348 tend%pnc_rcw(k) = rhof(k)*t1_qr_qc*ef_rw*nc(k)*n0_r * &
2349 ((lamr+fv_r)**(-cre(9)))
2350 tend%pnc_rcw(k) = min(real(nc(k)*odt, kind=dp), tend%pnc_rcw(k))
2354 end subroutine warm_rain
2357 subroutine riming(temp, rhof, visco, l_qc, rc, nc, ilamc, mvd_c, &
2358 l_qs, rs, smo0, smob, smoc, smoe, vtboost, l_qg, rg, ng, ilamg, idx, tend, odt)
2361 r_g, bm_g, mu_g, av_g, cgg, ogg3, bv_g, rho_w, t0, d0g, pi, cge, ogg2, &
2362 rime_threshold, rime_conversion, av_s, bv_s, rho_s, xm0i, eps, fv_s, &
2365 real(wp),
intent(in) :: odt
2366 type(
ty_tend),
intent(inout) :: tend
2367 real(wp),
dimension(:),
intent(in) :: rhof, visco, temp, rc, nc, rs, rg, ng
2368 real(wp),
dimension(:),
intent(in) :: mvd_c
2369 real(dp),
dimension(:),
intent(in) :: smo0, smob, smoc, smoe, ilamg, ilamc
2370 logical,
dimension(:),
intent(in) :: l_qc, l_qs, l_qg
2371 integer,
dimension(:),
intent(in) :: idx
2372 real(wp),
dimension(:),
intent(out) :: vtboost
2374 real(dp) :: xds, xdg, n0_g, lamc
2375 real(wp) :: ef_sw, vtg, stoke_g, const_ri, tempc, rime_dens, ef_gw
2376 real(wp) :: t1_qg_qc, r_frac, g_frac, vts, tf, snow_dens_frac
2377 integer :: k, nz, idxs, nu_c
2381 tempc = temp(k) - t0
2383 if (l_qc(k) .and. l_qs(k))
then
2384 nu_c = get_nuc(nc(k))
2385 lamc = 1._dp / ilamc(k)
2386 xds = smoc(k) / smob(k)
2387 if ((mvd_c(k) > d0c) .and. (xds > d0s))
then
2390 idxs = 1 + int(nbs*log(real(xds/ds(1), kind=dp)) / log(real(ds(nbs)/ds(1), kind=dp)))
2391 idxs = min(idxs, nbs)
2392 ef_sw = t_efsw(idxs, int(mvd_c(k)*1.e6_wp))
2393 tend%prs_scw(k) = rhof(k)*t1_qs_qc*ef_sw*rc(k)*smoe(k)
2394 tend%prs_scw(k) = min(real(rc(k)*odt, kind=dp), tend%prs_scw(k))
2395 tend%pnc_scw(k) = rhof(k)*t1_qs_qc*ef_sw*nc(k)*smoe(k)
2396 tend%pnc_scw(k) = min(real(nc(k)*odt, kind=dp), tend%pnc_scw(k))
2402 if (temp(k) < t0)
then
2403 if (tend%prs_scw(k) > rime_threshold*tend%prs_sde(k) .and. &
2404 tend%prs_sde(k) > eps)
then
2405 r_frac = min(30.0_dp, tend%prs_scw(k)/tend%prs_sde(k))
2406 g_frac = min(rime_conversion, 0.15_wp + (r_frac-2._wp)*.028_wp)
2407 vtboost(k) = min(1.5_wp, 1.1_wp + (r_frac-2.)*.014_wp)
2408 tend%prg_scw(k) = g_frac*tend%prs_scw(k)
2409 tend%png_scw(k) = tend%prg_scw(k)*smo0(k)/rs(k)
2410 vts = av_s*xds**bv_s * exp(-fv_s*xds)
2411 const_ri = -1._wp*(mvd_c(k)*0.5e6_wp)*vts/min(-0.1_wp,tempc)
2412 const_ri = max(0.1_wp, min(const_ri, 10._wp))
2413 rime_dens = (0.051_wp + 0.114_wp*const_ri - 0.0055_wp*const_ri*const_ri)*1000._wp
2414 if(rime_dens < 150._wp)
then
2416 tend%prg_scw(k) = 0._dp
2417 tend%png_scw(k) = 0._dp
2419 snow_dens_frac = min(1._wp, max(0._wp, real(rs(k)*odt / &
2420 (rs(k)*odt + tend%prg_scw(k)), kind=wp)))
2421 tend%pbg_scw(k) = meters3_to_liters*tend%prg_scw(k) / &
2422 (rho_s * snow_dens_frac + rime_dens * (1._wp-snow_dens_frac))
2425 tend%prs_scw(k) = (1._wp - g_frac)*tend%prs_scw(k)
2431 if (l_qc(k) .and. l_qg(k))
then
2434 if (rg(k) >= r_g(1) .and. mvd_c(k) > d0c)
then
2435 xdg = (bm_g + mu_g + 1._wp) * ilamg(k)
2436 vtg = rhof(k)*av_g(idx(k))*cgg(6,idx(k))*ogg3 * ilamg(k)**bv_g(idx(k))
2437 stoke_g = mvd_c(k)*mvd_c(k)*vtg*rho_w/(9._wp*visco(k)*xdg)
2441 const_ri = -1._wp*(mvd_c(k)*0.5e6_wp)*vtg/min(-0.1_wp, tempc)
2442 const_ri = max(0.1_wp, min(const_ri, 10._wp))
2443 rime_dens = (0.051_wp + 0.114_wp*const_ri - 0.0055_wp*const_ri*const_ri)*1000._wp
2445 if (stoke_g >= 0.4_wp .and. stoke_g <= 10._wp)
then
2446 ef_gw = 0.55_wp*log10(2.51_wp*stoke_g)
2447 elseif (stoke_g < 0.4_wp)
then
2449 elseif (stoke_g > 10._wp)
then
2455 if (temp(k) > t0) ef_gw = ef_gw*0.1_wp
2456 t1_qg_qc = pi*.25_wp*av_g(idx(k)) * cgg(9,idx(k))
2457 n0_g = ng(k)*ogg2*(1._wp/ilamg(k))**cge(2,1)
2458 tend%prg_gcw(k) = rhof(k)*t1_qg_qc*ef_gw*rc(k)* &
2459 n0_g*ilamg(k)**cge(9,idx(k))
2460 tend%pnc_gcw(k) = rhof(k)*t1_qg_qc*ef_gw*nc(k)* &
2461 n0_g*ilamg(k)**cge(9,idx(k))
2462 tend%pnc_gcw(k) = min(real(nc(k)*odt, kind=dp), tend%pnc_gcw(k))
2463 if (temp(k) < t0) tend%pbg_gcw(k) = meters3_to_liters*tend%prg_gcw(k)/rime_dens
2465 if (temp(k) < t0)
then
2470 if (tend%prg_gcw(k) > eps .and. tempc > -8._wp)
then
2472 if (tempc >= -5._wp .and. tempc < -3._wp)
then
2473 tf = 0.5_wp*(-3.0_wp - tempc)
2474 elseif (tempc > -8._wp .and. tempc < -5._wp)
then
2475 tf = 0.33333333_wp*(8._wp + tempc)
2477 tend%pni_ihm(k) = 3.5e8_wp*tf*tend%prg_gcw(k)
2478 tend%pri_ihm(k) = xm0i*tend%pni_ihm(k)
2479 tend%prs_ihm(k) = tend%prs_scw(k)/(tend%prs_scw(k)+tend%prg_gcw(k)) * &
2481 tend%prg_ihm(k) = tend%prg_gcw(k)/(tend%prs_scw(k)+tend%prg_gcw(k)) * &
2489 end subroutine riming
2492 subroutine get_snow_table_index(rs, idx_s)
2496 real(wp),
intent(in) :: rs
2497 integer :: nis, nn, n
2498 integer,
intent(out) :: idx_s
2500 nis = nint(log10(rs))
2501 do_loop_rs:
do nn = nis-1, nis+1
2503 if ((rs/10._wp**nn) >= 1._wp .and. (rs/10._wp**nn) < 10._wp)
exit do_loop_rs
2505 idx_s = int(rs/10._wp**n) + 10*(n-nis2) - (n-nis2)
2506 idx_s = max(1, min(idx_s, ntb_s))
2507 end subroutine get_snow_table_index
2510 subroutine get_temperature_table_index(tempk, idx_t)
2514 real(wp),
intent(in) :: tempk
2516 integer,
intent(out) :: idx_t
2519 idx_t = int((tempc-2.5_wp)/5._wp) - 1
2520 idx_t = max(1, -idx_t)
2521 idx_t = min(idx_t, ntb_t)
2522 end subroutine get_temperature_table_index
2525 subroutine get_rain_table_index(rr, ilamr, idx_r, idx_r1)
2528 org2, org1, bm_r, am_r, crg, cre
2530 real(wp),
intent(in) :: rr
2531 real(dp),
intent(in) :: ilamr
2532 real(dp) :: lamr, lam_exp, n0_exp
2533 integer :: nir, nn, n
2534 integer,
intent(out) :: idx_r, idx_r1
2536 nir = nint(log10(rr))
2537 do_loop_rr:
do nn = nir-1, nir+1
2539 if ((rr/10._wp**nn) >= 1._wp .and. (rr/10._wp**nn) < 10._wp)
exit do_loop_rr
2541 idx_r = int(rr/10._wp**n) + 10*(n-nir2) - (n-nir2)
2542 idx_r = max(1, min(idx_r, ntb_r))
2545 lam_exp = lamr * (crg(3)*org2*org1)**bm_r
2546 n0_exp = org1*rr/am_r * lam_exp**cre(1)
2547 nir = nint(log10(real(n0_exp, kind=dp)))
2548 do_loop_nr:
do nn = nir-1, nir+1
2550 if ((n0_exp/10._wp**nn) >= 1._wp .and. (n0_exp/10._wp**nn) < 10._wp)
exit do_loop_nr
2552 idx_r1 = int(n0_exp/10._wp**n) + 10*(n-nir3) - (n-nir3)
2553 idx_r1 = max(1, min(idx_r1, ntb_r1))
2554 end subroutine get_rain_table_index
2557 subroutine get_graupel_table_index(rg, ilamg, idx, idx_g, idx_g1)
2560 bm_g, cgg, ogg1, am_g, cge, nig3
2562 real(wp),
intent(in) :: rg
2563 real(dp),
intent(in) :: ilamg
2564 integer,
intent(in) :: idx
2565 real(dp) :: lamg, lam_exp, n0_exp
2566 integer :: nig, nn, n
2567 integer,
intent(out) :: idx_g, idx_g1
2569 nig = nint(log10(rg))
2570 do_loop_rg:
do nn = nig-1, nig+1
2572 if ( (rg/10._wp**nn) >= 1._wp .and. (rg/10._wp**nn).lt.10._wp)
exit do_loop_rg
2574 idx_g = int(rg/10._wp**n) + 10*(n-nig2) - (n-nig2)
2575 idx_g = max(1, min(idx_g, ntb_g))
2578 lam_exp = lamg * (cgg(3,1)*ogg2*ogg1)**bm_g
2579 n0_exp = ogg1*rg/am_g(idx) * lam_exp**cge(1,1)
2580 nig = nint(log10(real(n0_exp, kind=dp)))
2581 do_loop_ng:
do nn = nig-1, nig+1
2583 if ( (n0_exp/10._wp**nn) >= 1._wp .and. (n0_exp/10._wp**nn) < 10._wp)
exit do_loop_ng
2585 idx_g1 = int(n0_exp/10._wp**n) + 10*(n-nig3) - (n-nig3)
2586 idx_g1 = max(1, min(idx_g1, ntb_g1))
2587 end subroutine get_graupel_table_index
2590 subroutine get_cloud_table_index(rc, nc, idx_c, idx_n)
2594 real(wp),
intent(in) :: rc, nc
2595 integer,
intent(out) :: idx_c, idx_n
2596 integer :: nic, nn, n
2598 nic = nint(log10(rc))
2599 do_loop_rc:
do nn = nic-1, nic+1
2601 if ( (rc/10._wp**nn) >= 1._wp .and. (rc/10._wp**nn) < 10._wp)
exit do_loop_rc
2603 idx_c = int(rc/10._wp**n) + 10*(n-nic2) - (n-nic2)
2604 idx_c = max(1, min(idx_c, ntb_c))
2606 idx_n = nint(1._wp + real(nbc, kind=wp) * log(real(nc/t_nc(1), kind=dp)) / nic1)
2607 idx_n = max(1, min(idx_n, nbc))
2608 end subroutine get_cloud_table_index
2611 subroutine get_ice_table_index(ri, ni, idx_i, idx_i1)
2615 real(wp),
intent(in) :: ri, ni
2616 integer,
intent(out) :: idx_i, idx_i1
2617 integer :: nii, nn, n
2619 nii = nint(log10(ri))
2620 do_loop_ri:
do nn = nii-1, nii+1
2622 if ( (ri/10._wp**nn) >= 1._wp .and. (ri/10._wp**nn) < 10._wp)
exit do_loop_ri
2624 idx_i = int(ri/10._wp**n) + 10*(n-nii2) - (n-nii2)
2625 idx_i = max(1, min(idx_i, ntb_i))
2627 nii = nint(log10(ni))
2628 do_loop_ni:
do nn = nii-1, nii+1
2630 if ( (ni/10._wp**nn) >= 1._wp .and. (ni/10._wp**nn) < 10._wp)
exit do_loop_ni
2632 idx_i1 = int(ni/10._wp**n) + 10*(n-nii3) - (n-nii3)
2633 idx_i1 = max(1, min(idx_i1, ntb_i1))
2634 end subroutine get_ice_table_index
2637 subroutine rain_snow_rain_graupel(temp, l_qr, rr, nr, ilamr, l_qs, rs, &
2638 l_qg, rg, ng, ilamg, idx, tend, odt)
2641 tmr_racs2, tcr_sacr2, tmr_racs1, tcr_sacr1, tms_sacr1, tcs_racs1, &
2642 tnr_sacr1, tnr_sacr2, tnr_racs1, tnr_racs2, &
2643 tcr_gacr, tmr_racg, tcg_racg, tnr_gacr, tnr_racg
2645 real(wp),
intent(in) :: odt
2646 type(
ty_tend),
intent(inout) :: tend
2647 real(wp),
dimension(:),
intent(in) :: temp, rr, rs, rg, nr, ng
2648 real(dp),
dimension(:),
intent(in) :: ilamr, ilamg
2649 logical,
dimension(:),
intent(in) :: l_qr, l_qs, l_qg
2650 integer,
dimension(:),
intent(in) :: idx
2651 integer :: k, nz, idx_r, idx_r1, idx_s, idx_t, &
2656 if (l_qr(k) .and. l_qs(k))
then
2657 if (rr(k) >= r_r(1) .and. rs(k) >= r_s(1))
then
2658 call get_temperature_table_index(temp(k), idx_t)
2659 call get_rain_table_index(rr(k), ilamr(k), idx_r, idx_r1)
2660 call get_snow_table_index(rs(k), idx_s)
2661 if (temp(k) < t0)
then
2662 tend%prr_rcs(k) = -(tmr_racs2(idx_s,idx_t,idx_r1,idx_r) &
2663 + tcr_sacr2(idx_s,idx_t,idx_r1,idx_r) &
2664 + tmr_racs1(idx_s,idx_t,idx_r1,idx_r) &
2665 + tcr_sacr1(idx_s,idx_t,idx_r1,idx_r))
2666 tend%prs_rcs(k) = tmr_racs2(idx_s,idx_t,idx_r1,idx_r) &
2667 + tcr_sacr2(idx_s,idx_t,idx_r1,idx_r) &
2668 - tcs_racs1(idx_s,idx_t,idx_r1,idx_r) &
2669 - tms_sacr1(idx_s,idx_t,idx_r1,idx_r)
2670 tend%prg_rcs(k) = tmr_racs1(idx_s,idx_t,idx_r1,idx_r) &
2671 + tcr_sacr1(idx_s,idx_t,idx_r1,idx_r) &
2672 + tcs_racs1(idx_s,idx_t,idx_r1,idx_r) &
2673 + tms_sacr1(idx_s,idx_t,idx_r1,idx_r)
2674 tend%prr_rcs(k) = max(real(-rr(k)*odt, kind=dp), tend%prr_rcs(k))
2675 tend%prs_rcs(k) = max(real(-rs(k)*odt, kind=dp), tend%prs_rcs(k))
2676 tend%prg_rcs(k) = min(real((rr(k)+rs(k))*odt, kind=dp), &
2678 tend%pnr_rcs(k) = tnr_racs1(idx_s,idx_t,idx_r1,idx_r) &
2679 + tnr_racs2(idx_s,idx_t,idx_r1,idx_r) &
2680 + tnr_sacr1(idx_s,idx_t,idx_r1,idx_r) &
2681 + tnr_sacr2(idx_s,idx_t,idx_r1,idx_r)
2682 tend%pnr_rcs(k) = min(real(nr(k)*odt, kind=dp), tend%pnr_rcs(k))
2683 tend%png_rcs(k) = tend%pnr_rcs(k)
2684 tend%pbg_rcs(k) = meters3_to_liters*tend%prg_rcs(k)/rho_i
2686 tend%prs_rcs(k) = -tcs_racs1(idx_s,idx_t,idx_r1,idx_r) &
2687 - tms_sacr1(idx_s,idx_t,idx_r1,idx_r) &
2688 + tmr_racs2(idx_s,idx_t,idx_r1,idx_r) &
2689 + tcr_sacr2(idx_s,idx_t,idx_r1,idx_r)
2690 tend%prs_rcs(k) = max(real(-rs(k)*odt, kind=dp), tend%prs_rcs(k))
2691 tend%prr_rcs(k) = -tend%prs_rcs(k)
2696 if (l_qr(k) .and. l_qg(k))
then
2697 if (rr(k) >= r_r(1) .and. rg(k) >= r_g(1))
then
2698 call get_temperature_table_index(temp(k), idx_t)
2699 call get_rain_table_index(rr(k), ilamr(k), idx_r, idx_r1)
2700 call get_graupel_table_index(rg(k), ilamg(k), idx(k), idx_g, idx_g1)
2701 if (temp(k) < t0)
then
2702 tend%prg_rcg(k) = tmr_racg(idx_g1,idx_g,idx(k),idx_r1,idx_r) &
2703 + tcr_gacr(idx_g1,idx_g,idx(k),idx_r1,idx_r)
2704 tend%prg_rcg(k) = min(real(rr(k)*odt, kind=dp), tend%prg_rcg(k))
2705 tend%prr_rcg(k) = -tend%prg_rcg(k)
2706 tend%pnr_rcg(k) = tnr_racg(idx_g1,idx_g,idx(k),idx_r1,idx_r) &
2707 + tnr_gacr(idx_g1,idx_g,idx(k),idx_r1,idx_r)
2708 tend%pnr_rcg(k) = min(real(nr(k)*odt, kind=dp), tend%pnr_rcg(k))
2709 tend%pbg_rcg(k) = meters3_to_liters*tend%prg_rcg(k)/rho_i
2711 tend%prr_rcg(k) = tcg_racg(idx_g1,idx_g,idx(k),idx_r1,idx_r)
2712 tend%prr_rcg(k) = min(real(rg(k)*odt, kind=dp), tend%prr_rcg(k))
2713 tend%prg_rcg(k) = -tend%prr_rcg(k)
2714 tend%png_rcg(k) = tnr_racg(idx_g1,idx_g,idx(k),idx_r1,idx_r)
2715 tend%png_rcg(k) = min(real(ng(k)*odt, kind=dp), tend%png_rcg(k))
2716 tend%pbg_rcg(k) = meters3_to_liters*tend%prg_rcg(k)/rho_g(idx(k))
2721 tend%pnr_rcg(k) = -1.5_wp*tnr_gacr(idx_g1,idx_g,idx(k),idx_r1,idx_r)
2726 end subroutine rain_snow_rain_graupel
2729 subroutine ice_nucleation(temp, rho, w1d, qv, qvsi, ssati, ssatw, &
2730 nwfa1d, nifa1d, nwfa, nifa, ni, smo0, rc, nc, rr, nr, ilamr, tend, dt, odt)
2733 tpg_qrfz, tpi_qrfz, tni_qrfz, tnr_qrfz, tpi_qcfz, tni_qcfz, &
2734 demott_nuc_ssati, eps, icenuc_max, tno, ato, max_ni, meters3_to_liters, &
2737 real(wp),
intent(in) :: dt, odt
2738 type(
ty_tend),
intent(inout) :: tend
2739 real(wp),
dimension(:),
intent(in) :: qv, temp, rho, qvsi, rr, nr, rc, nc, w1d, &
2740 ssati, ssatw, ni, nwfa, nifa
2741 real(dp),
dimension(:),
intent(in) :: ilamr, smo0
2742 real(wp),
dimension(:),
intent(in),
optional :: nwfa1d, nifa1d
2743 real(wp) :: rate_max, tempc, xni, xnc
2744 integer :: k, nz, idx_in, idx_r, idx_r1, idx_tc, idx_c, idx_n
2748 if (temp(k) < t0)
then
2749 tempc = temp(k) - t0
2750 idx_tc = max(1, min(nint(-tempc), 45))
2751 rate_max = (qv(k)-qvsi(k))*rho(k)*odt*0.999_wp
2752 if (
present(nifa1d))
then
2753 xni = demott_nucleation(tempc, rho(k), nifa(k))
2755 xni = 1._wp * 1000._wp
2757 call get_in_table_index(xni, idx_in)
2762 if (rr(k) > r_r(1))
then
2763 call get_rain_table_index(rr(k), ilamr(k), idx_r, idx_r1)
2764 tend%prg_rfz(k) = tpg_qrfz(idx_r,idx_r1,idx_tc,idx_in)*odt
2765 tend%pri_rfz(k) = tpi_qrfz(idx_r,idx_r1,idx_tc,idx_in)*odt
2766 tend%pni_rfz(k) = tni_qrfz(idx_r,idx_r1,idx_tc,idx_in)*odt
2767 tend%pnr_rfz(k) = tnr_qrfz(idx_r,idx_r1,idx_tc,idx_in)*odt
2768 tend%prg_rfz(k) = min(real(rr(k)*odt, kind=dp), tend%prg_rfz(k))
2769 tend%pnr_rfz(k) = min(real(nr(k)*odt, kind=dp), tend%pnr_rfz(k))
2771 tend%png_rfz(k) = tend%pnr_rfz(k) * &
2772 max(min((10._wp**(-0.1_wp*w1d(k)) + 0.1_wp), 1._wp), 0.1_wp)
2774 elseif (rr(k) > r1 .and. temp(k) < hgfrz)
then
2775 tend%pri_rfz(k) = rr(k)*odt
2776 tend%pni_rfz(k) = nr(k)*odt
2778 tend%pbg_rfz(k) = meters3_to_liters*tend%prg_rfz(k)/rho_i
2780 if (rc(k) > r_c(1))
then
2781 call get_cloud_table_index(rc(k), nc(k), idx_c, idx_n)
2782 tend%pri_wfz(k) = tpi_qcfz(idx_c,idx_n,idx_tc,idx_in)*odt
2783 tend%pri_wfz(k) = min(real(rc(k)*odt, kind=dp), tend%pri_wfz(k))
2784 tend%pni_wfz(k) = tni_qcfz(idx_c,idx_n,idx_tc,idx_in)*odt
2785 tend%pni_wfz(k) = min(real(nc(k)*odt, kind=dp), &
2786 tend%pri_wfz(k)/(2.0_dp*xm0i), tend%pni_wfz(k))
2787 elseif (rc(k) > r1 .and. temp(k) < hgfrz)
then
2788 tend%pri_wfz(k) = rc(k)*odt
2789 tend%pni_wfz(k) = nc(k)*odt
2794 if ((ssati(k) >= demott_nuc_ssati) .or. (ssatw(k) > eps &
2795 .and. tempc < demott_nuc_tempc))
then
2796 if (
present(nifa1d))
then
2797 xnc = demott_nucleation(tempc, rho(k), nifa(k))
2799 xnc = min(icenuc_max, tno*exp(ato*(t0-temp(k))))
2801 xni = ni(k) + (tend%pni_rfz(k)+tend%pni_wfz(k))*dt
2802 tend%pni_inu(k) = 0.5_wp*(xnc-xni + abs(xnc-xni))*odt
2803 tend%pri_inu(k) = min(real(rate_max, kind=dp), xm0i*tend%pni_inu(k))
2804 tend%pni_inu(k) = tend%pri_inu(k)/xm0i
2808 xni = smo0(k)+ni(k) + (tend%pni_rfz(k)+tend%pni_wfz(k)+tend%pni_inu(k))*dt
2809 if (
present(nwfa1d))
then
2810 if ((xni <= max_ni) .and.(temp(k) < 238._wp) .and. (ssati(k) >= 0.4_wp))
then
2811 xnc = koop_nucleation(temp(k), ssatw(k), nwfa(k), dt)
2812 tend%pni_iha(k) = xnc*odt
2813 tend%pri_iha(k) = min(real(rate_max, kind=dp), xm0i*0.1_wp*tend%pni_iha(k))
2814 tend%pni_iha(k) = tend%pri_iha(k)/(xm0i*0.1_wp)
2819 end subroutine ice_nucleation
2822 function demott_nucleation(tempc, rho, nifa)
result(nuc)
2826 real(wp),
intent(in) :: tempc, rho, nifa
2827 real(wp) :: xni, nifa_cc
2831 nifa_cc = max(0.5_wp, nifa*rho_not0*1.e-6_wp/rho)
2832 xni = (5.94e-5_wp*(-tempc)**3.33_wp) * (nifa_cc**((-0.0264_wp*(tempc))+0.0033_wp))
2833 xni = xni*rho/rho_not0 * 1000._wp
2834 nuc = max(0._wp, xni)
2835 end function demott_nucleation
2838 subroutine get_in_table_index(xni, idx_in)
2842 real(wp),
intent(in) :: xni
2843 integer,
intent(out) :: idx_in
2844 integer :: niin, nn, n
2846 if (xni > nt_in(1))
then
2847 niin = nint(log10(xni))
2848 do_loop_xni:
do nn = niin-1, niin+1
2850 if ( (xni/10._wp**nn) >= 1._wp .and. (xni/10._wp**nn) < 10._wp)
exit do_loop_xni
2852 idx_in = int(xni/10._wp**n) + 10*(n-niin2) - (n-niin2)
2853 idx_in = max(1, min(idx_in, ntb_in))
2857 end subroutine get_in_table_index
2860 subroutine get_t1_subl(rho, temp, qvsi, tcond, diffu, ssati, t1_subl)
2863 pi, c_sqrd, c_cube, d0s, ntb_i, r_s, ef_si, r_r, fv_r, ef_ri, &
2864 rho_i, eps, rho_w, rho_g
2866 real(wp),
dimension(:),
intent(in) :: rho, temp, qvsi, tcond, diffu, ssati
2867 real(wp) :: otemp, rvs, rvs_p, rvs_pp, gamsc, alphsc, xsat
2868 real(wp),
dimension(:),
intent(out) :: t1_subl
2873 otemp = 1._wp/temp(k)
2874 rvs = rho(k)*qvsi(k)
2875 rvs_p = rvs*otemp*(lsub*otemp*orv - 1._wp)
2876 rvs_pp = rvs * (otemp*(lsub*otemp*orv - 1._wp) * otemp*(lsub*otemp*orv - 1._wp) + &
2877 (-2.*lsub*otemp*otemp*otemp*orv) + otemp*otemp)
2878 gamsc = lsub*diffu(k)/tcond(k) * rvs_p
2879 alphsc = 0.5_wp*(gamsc/(1._wp+gamsc))*(gamsc/(1._wp+gamsc)) * &
2880 rvs_pp/rvs_p * rvs/rvs_p
2881 alphsc = max(1.e-9_wp, alphsc)
2883 if (abs(xsat) < 1.e-9_wp) xsat = 0._wp
2884 t1_subl(k) = 4._wp*pi*(1._wp - alphsc*xsat + 2._wp*alphsc*alphsc*xsat*xsat - &
2885 5._wp*alphsc*alphsc*alphsc*xsat*xsat*xsat) / (1._wp+gamsc)
2887 end subroutine get_t1_subl
2890 subroutine ice_processes(rhof, rhof2, rho, w1d, temp, qv, qvsi, tcond, diffu, &
2891 vsc2, ssati, l_qi, ri, ni, ilami, l_qs, rs, smoe, smof, smo1, rr, nr, ilamr, &
2892 mvd_r, l_qg, rg, ng, ilamg, idx, tend, odt)
2897 c_sqrd, c_cube, oig1, cig, d0s, ntb_i, tpi_ide, tps_iaus, tni_iaus, &
2898 obmi, r_s, ef_si, t1_qs_qi, r_r, org2, cre, t1_qr_qi, t2_qr_qi, &
2899 fv_r, ef_ri, rho_i, t1_qs_sd, t2_qs_sd, eps, t1_qg_sd, &
2900 sc3, ogg2, cge, cgg, av_g, rho_w, rho_g
2902 real(wp),
intent(in) :: odt
2903 type(
ty_tend),
intent(inout) :: tend
2904 logical,
dimension(:),
intent(in) :: l_qi, l_qs, l_qg
2905 real(wp),
dimension(:),
intent(in) :: rhof, rhof2, rho, w1d, ri, ni, rs, rr, nr, &
2906 temp, qv, qvsi, tcond, diffu, ssati, vsc2, mvd_r, rg, ng
2907 real(dp),
dimension(:),
intent(in) :: ilami, smoe, smof, smo1, ilamr, ilamg
2908 integer,
dimension(:),
intent(in) :: idx
2909 real(wp) :: xdi, xmi, oxmi, c_snow, rate_max, otemp, rvs, t2_qg_sd
2910 real(dp) :: lami, lamr, n0_r, n0_g
2911 integer :: k, nz, idx_i, idx_i1
2912 real(wp),
dimension(:),
allocatable :: t1_subl
2915 allocate(t1_subl(nz), source=0._wp)
2916 call get_t1_subl(rho, temp, qvsi, tcond, diffu, ssati, t1_subl)
2919 otemp = 1._wp/temp(k)
2920 rvs = rho(k)*qvsi(k)
2921 rate_max = (qv(k)-qvsi(k))*rho(k)*odt*0.999_wp
2923 if (temp(k) < t0)
then
2925 call get_ice_table_index(ri(k), ni(k), idx_i, idx_i1)
2926 lami = 1._dp/ilami(k)
2927 xdi = max(real(d0i, kind=dp), (bm_i + mu_i + 1.) * ilami(k))
2928 xmi = am_i*xdi**bm_i
2930 tend%pri_ide(k) = c_cube*t1_subl(k)*diffu(k)*ssati(k)*rvs &
2931 *oig1*cig(5)*ni(k)*ilami(k)
2932 if (tend%pri_ide(k) < 0._dp)
then
2933 tend%pri_ide(k) = max(real(-ri(k)*odt, kind=dp), &
2934 tend%pri_ide(k), real(rate_max, kind=dp))
2935 tend%pni_ide(k) = tend%pri_ide(k)*oxmi
2936 tend%pni_ide(k) = max(real(-ni(k)*odt, kind=dp), tend%pni_ide(k))
2938 tend%pri_ide(k) = min(tend%pri_ide(k), real(rate_max, kind=dp))
2939 tend%prs_ide(k) = (1.0_dp-tpi_ide(idx_i,idx_i1))*tend%pri_ide(k)
2940 tend%pri_ide(k) = tpi_ide(idx_i,idx_i1)*tend%pri_ide(k)
2944 if ((idx_i == ntb_i) .or. (xdi > 5.0_wp*d0s))
then
2945 tend%prs_iau(k) = ri(k)*.99_wp*odt
2946 tend%pni_iau(k) = ni(k)*.95_wp*odt
2947 elseif (xdi < 0.1_wp*d0s)
then
2948 tend%prs_iau(k) = 0._dp
2949 tend%pni_iau(k) = 0._dp
2951 tend%prs_iau(k) = tps_iaus(idx_i,idx_i1)*odt
2952 tend%prs_iau(k) = min(real(ri(k)*.99_wp*odt, kind=dp), tend%prs_iau(k))
2953 tend%pni_iau(k) = tni_iaus(idx_i,idx_i1)*odt
2954 tend%pni_iau(k) = min(real(ni(k)*.95_wp*odt, kind=dp), tend%pni_iau(k))
2958 lami = (am_i*cig(2)*oig1*ni(k)/ri(k))**obmi
2959 xdi = max(real(d0i, kind=dp), (bm_i + mu_i + 1.) * ilami(k))
2960 xmi = am_i*xdi**bm_i
2962 if (rs(k) >= r_s(1))
then
2963 tend%prs_sci(k) = t1_qs_qi*rhof(k)*ef_si*ri(k)*smoe(k)
2964 tend%pni_sci(k) = tend%prs_sci(k) * oxmi
2968 if (rr(k) >= r_r(1) .and. mvd_r(k) > 4._wp*xdi)
then
2969 lamr = 1._wp/ilamr(k)
2970 n0_r = nr(k)*org2*lamr**cre(2)
2971 tend%pri_rci(k) = rhof(k)*t1_qr_qi*ef_ri*ri(k)*n0_r * &
2972 ((lamr+fv_r)**(-cre(9)))
2973 tend%pnr_rci(k) = rhof(k)*t1_qr_qi*ef_ri*ni(k)*n0_r * &
2974 ((lamr+fv_r)**(-cre(9)))
2975 tend%pnr_rci(k) = min(real(nr(k)*odt, kind=dp), tend%pnr_rci(k))
2976 tend%png_rci(k) = tend%pnr_rci(k) * &
2977 max(min((10._wp**(-0.1*w1d(k)) + 0.1_wp), 1._wp), 0.1_wp)
2978 tend%pni_rci(k) = tend%pri_rci(k) * oxmi
2979 tend%prr_rci(k) = rhof(k)*t2_qr_qi*ef_ri*ni(k)*n0_r * &
2980 ((lamr+fv_r)**(-cre(8)))
2981 tend%prr_rci(k) = min(real(rr(k)*odt, kind=dp), tend%prr_rci(k))
2982 tend%prg_rci(k) = tend%pri_rci(k) + tend%prr_rci(k)
2983 tend%pbg_rci(k) = tend%prg_rci(k)/rho_i
2988 c_snow = c_sqrd + (temp(k)-t0+1.5_wp)*(c_cube-c_sqrd)/(-30._wp+1.5_wp)
2989 c_snow = max(c_sqrd, min(c_snow, c_cube))
2990 tend%prs_sde(k) = c_snow*t1_subl(k)*diffu(k)*ssati(k)*rvs * (t1_qs_sd*smo1(k) + &
2991 t2_qs_sd*rhof2(k)*vsc2(k)*smof(k))
2992 if (tend%prs_sde(k) < 0._dp)
then
2993 tend%prs_sde(k) = max(real(-rs(k)*odt, kind=dp), &
2994 tend%prs_sde(k), real(rate_max, kind=dp))
2996 tend%prs_sde(k) = min(tend%prs_sde(k), real(rate_max, kind=dp))
3000 if (ssati(k) < -eps)
then
3001 n0_g = ng(k)*ogg2*(1._wp/ilamg(k))**cge(2,1)
3002 t2_qg_sd = 0.28_wp*sc3*sqrt(av_g(idx(k))) * cgg(11,idx(k))
3003 tend%prg_gde(k) = c_cube*t1_subl(k)*diffu(k)*ssati(k)*rvs &
3004 * n0_g * (t1_qg_sd*ilamg(k)**cge(10,1) &
3005 + t2_qg_sd*vsc2(k)*rhof2(k)*ilamg(k)**cge(11,idx(k)))
3006 if (tend%prg_gde(k) < 0._wp)
then
3007 tend%prg_gde(k) = max(real(-rg(k)*odt, kind=dp), &
3008 tend%prg_gde(k), real(rate_max, kind=dp))
3009 tend%png_gde(k) = tend%prg_gde(k) * ng(k)/rg(k)
3011 tend%prg_gde(k) = min(tend%prg_gde(k), real(rate_max, kind=dp))
3017 end subroutine ice_processes
3020 subroutine melting(rhof2, rho, temp, qvsi, tcond, diffu, vsc2, ssati, &
3021 delqvs, l_qs, rs, smof, smo0, smo1, l_qg, rg, ng, ilamg, idx, tend, dt, odt)
3024 ntb_i, r_s, ef_si, r_r, fv_r, ef_ri, rho_i, t1_qs_sd, t2_qs_sd, eps, &
3025 t1_qg_sd, sc3, ogg2, cge, cgg, av_g, t1_qs_me, t2_qs_me, lvap0, olfus, &
3026 t1_qg_me, rho_w, rho_g, meters3_to_liters, timestep_conversion_rime_to_rain
3028 real(wp),
intent(in) :: dt, odt
3029 type(
ty_tend),
intent(inout) :: tend
3030 logical,
dimension(:),
intent(in) :: l_qs, l_qg
3031 real(wp),
dimension(:),
intent(in) :: rhof2, rho, rs, &
3032 temp, qvsi, tcond, diffu, ssati, delqvs, vsc2, rg, ng
3033 real(dp),
dimension(:),
intent(in) :: smof, smo0, smo1, ilamg
3034 integer,
dimension(:),
intent(in) :: idx
3035 real(wp) :: tempc, otemp, rvs, melt_f, t2_qg_me, t2_qg_sd
3036 real(dp) :: n0_g, n0_melt, lamg
3038 real(wp),
dimension(:),
allocatable :: t1_subl
3041 allocate(t1_subl(nz), source=0._wp)
3042 call get_t1_subl(rho, temp, qvsi, tcond, diffu, ssati, t1_subl)
3045 otemp = 1._wp/temp(k)
3046 tempc = temp(k) - t0
3047 rvs = rho(k)*qvsi(k)
3049 if (temp(k) > t0)
then
3051 tend%prr_sml(k) = (tempc*tcond(k)-lvap0*diffu(k)*delqvs(k)) * &
3052 (t1_qs_me*smo1(k) + t2_qs_me*rhof2(k)*vsc2(k)*smof(k))
3054 if (tend%prr_sml(k) > 0._dp)
then
3055 tend%prr_sml(k) = tend%prr_sml(k) + 4218._wp*olfus*tempc * &
3056 (tend%prr_rcs(k)+tend%prs_scw(k))
3057 tend%prr_sml(k) = min(real(rs(k)*odt, kind=dp), &
3058 max(0._dp, tend%prr_sml(k)))
3059 tend%pnr_sml(k) = smo0(k)/rs(k)*tend%prr_sml(k) * 10.0_wp**(-0.25_wp*tempc)
3060 tend%pnr_sml(k) = min(real(smo0(k)*odt, kind=dp), tend%pnr_sml(k))
3062 tend%prr_sml(k) = 0._dp
3063 tend%pnr_sml(k) = 0._dp
3064 if (ssati(k) < 0._wp)
then
3065 tend%prs_sde(k) = c_cube*t1_subl(k)*diffu(k)*ssati(k)*rvs * &
3066 (t1_qs_sd*smo1(k) + t2_qs_sd*rhof2(k)*vsc2(k)*smof(k))
3067 tend%prs_sde(k) = max(real(-rs(k)*odt, kind=dp), tend%prs_sde(k))
3073 n0_g = ng(k)*ogg2*(1._wp/ilamg(k))**cge(2,1)
3074 n0_melt = ng(k)*ogg2*(1._dp/ilamg(k))**cge(2,1)
3075 if ((rg(k)*ng(k)) < 1.e-4_wp)
then
3077 n0_melt = (1.e-4_wp/rg(k))*ogg2*lamg**cge(2,1)
3079 t2_qg_me = pi*4._wp * c_cube*olfus * &
3080 0.28_wp*sc3*sqrt(av_g(idx(k))) * cgg(11,idx(k))
3081 tend%prr_gml(k) = (tempc*tcond(k)-lvap0*diffu(k)*delqvs(k)) * &
3082 n0_melt*(t1_qg_me*ilamg(k)**cge(10,1) + &
3083 t2_qg_me*rhof2(k)*vsc2(k)*ilamg(k)**cge(11,idx(k)))
3084 tend%prr_gml(k) = min(real(rg(k)*odt, kind=dp), max(0._dp, tend%prr_gml(k)))
3085 if (tend%prr_gml(k) > 0._dp)
then
3086 melt_f = max(0.05_wp, min(real(tend%prr_gml(k)*dt/rg(k), kind=wp),1._wp))
3088 tend%pbg_gml(k) = meters3_to_liters*tend%prr_gml(k) / &
3089 max(min(melt_f*rho_g(idx(k)), rho_w), 50._wp)
3090 tend%pnr_gml(k) = tend%prr_gml(k)*ng(k)/rg(k) * 10.0_wp**(-0.33_wp*(temp(k)-t0))
3092 tend%prr_gml(k) = 0._dp
3093 tend%pnr_gml(k) = 0._dp
3094 tend%pbg_gml(k) = 0._dp
3095 if (ssati(k) < 0._wp)
then
3096 t2_qg_sd = 0.28_wp*sc3*sqrt(av_g(idx(k))) * cgg(11,idx(k))
3097 tend%prg_gde(k) = c_cube*t1_subl(k)*diffu(k)*ssati(k)*rvs * n0_g * &
3098 (t1_qg_sd*ilamg(k)**cge(10,1) + &
3099 t2_qg_sd*vsc2(k)*rhof2(k)*ilamg(k)**cge(11,idx(k)))
3100 tend%prg_gde(k) = max(real(-rg(k)*odt, kind=dp), tend%prg_gde(k))
3101 tend%png_gde(k) = tend%prg_gde(k) * ng(k)/rg(k)
3111 if (dt > timestep_conversion_rime_to_rain)
then
3112 tend%prr_rcw(k) = tend%prr_rcw(k)+tend%prs_scw(k)+tend%prg_gcw(k)
3113 tend%prs_scw(k) = 0._dp
3114 tend%prg_gcw(k) = 0._dp
3118 end subroutine melting
3121 subroutine aerosol_scavenging(temp, rho, rhof, visco, nwfa, nifa, &
3122 l_qr, nr, ilamr, mvd_r, l_qs, rs, smob, smoc, smoe, &
3123 l_qg, rg, ng, ilamg, idx, tend, odt)
3126 org2, r_s, t1_qs_qc, r_g, bm_g, mu_g, av_g, cge, cgg, pi, ogg2
3128 real(wp),
intent(in) :: odt
3129 real(wp),
dimension(:),
intent(in) :: temp, rho,rhof, visco, nr, mvd_r, &
3130 nwfa, nifa, rs, rg, ng
3131 real(dp),
dimension(:),
intent(in) :: smob, smoc, smoe, ilamg, ilamr
3132 integer,
dimension(:),
intent(in) :: idx
3133 logical,
dimension(:),
intent(in) :: l_qr, l_qs, l_qg
3134 type(
ty_tend),
intent(inout) :: tend
3135 real(wp) :: ef_ra, ef_sa, ef_ga, t1_qg_qc
3136 real(dp) :: n0_r, xds, xdg, n0_g, lamr
3137 real(wp),
parameter :: wf_aerosol_size = 0.04e-6_wp
3138 real(wp),
parameter :: if_aerosol_size = 0.8e-6_wp
3143 if (l_qr(k) .and. mvd_r(k).gt. d0r)
then
3144 ef_ra = aerosol_collection_efficiency(real(mvd_r(k), kind=dp), &
3145 wf_aerosol_size, visco(k), rho(k), temp(k),
'r')
3146 lamr = 1._dp/ilamr(k)
3147 n0_r = nr(k)*org2*lamr**cre(2)
3148 tend%pna_rca(k) = rhof(k)*t1_qr_qc*ef_ra*nwfa(k)*n0_r * &
3149 ((lamr+fv_r)**(-cre(9)))
3150 tend%pna_rca(k) = min(real(nwfa(k)*odt, kind=dp), &
3152 ef_ra = aerosol_collection_efficiency(real(mvd_r(k), kind=dp), &
3153 if_aerosol_size, visco(k), rho(k), temp(k),
'r')
3154 tend%pnd_rcd(k) = rhof(k)*t1_qr_qc*ef_ra*nifa(k)*n0_r * &
3155 ((lamr+fv_r)**(-cre(9)))
3156 tend%pnd_rcd(k) = min(real(nifa(k)*odt, kind=dp), &
3160 if (l_qs(k) .and. rs(k) > r_s(1))
then
3161 xds = smoc(k) / smob(k)
3162 ef_sa = aerosol_collection_efficiency(xds,wf_aerosol_size, &
3163 visco(k), rho(k), temp(k),
's')
3164 tend%pna_sca(k) = rhof(k)*t1_qs_qc*ef_sa*nwfa(k)*smoe(k)
3165 tend%pna_sca(k) = min(real(nwfa(k)*odt, kind=dp), &
3167 ef_sa = aerosol_collection_efficiency(xds, if_aerosol_size, &
3168 visco(k), rho(k), temp(k),
's')
3169 tend%pnd_scd(k) = rhof(k)*t1_qs_qc*ef_sa*nifa(k)*smoe(k)
3170 tend%pnd_scd(k) = min(real(nifa(k)*odt, kind=dp), &
3174 if (l_qg(k) .and. rg(k) > r_g(1))
then
3175 xdg = (bm_g + mu_g + 1._dp) * ilamg(k)
3176 ef_ga = aerosol_collection_efficiency(xdg, wf_aerosol_size, &
3177 visco(k), rho(k), temp(k),
'g')
3178 t1_qg_qc = pi*.25_wp*av_g(idx(k)) * cgg(9,idx(k))
3179 n0_g = ng(k)*ogg2*(1._wp/ilamg(k))**cge(2,1)
3180 tend%pna_gca(k) = rhof(k)*t1_qg_qc*ef_ga*nwfa(k)*n0_g * &
3181 ilamg(k)**cge(9,idx(k))
3182 tend%pna_gca(k) = min(real(nwfa(k)*odt, kind=dp), &
3184 ef_ga = aerosol_collection_efficiency(xdg, if_aerosol_size, &
3185 visco(k), rho(k), temp(k),
'g')
3186 tend%pnd_gcd(k) = rhof(k)*t1_qg_qc*ef_ga*nifa(k)*n0_g * &
3187 ilamg(k)**cge(9,idx(k))
3188 tend%pnd_gcd(k) = min(real(nifa(k)*odt, kind=dp), &
3192 end subroutine aerosol_scavenging