1module module_mp_tempo_main
4 use module_mp_tempo_params,
only : wp, sp, dp, &
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
8 use module_mp_tempo_diags,
only : reflectivity_10cm, effective_radius, max_hail_diam, &
10 use module_mp_tempo_aerosols,
only : init_ice_friendly_aerosols, init_water_friendly_aerosols, &
11 aerosol_collection_efficiency
12 use module_mp_tempo_ml,
only : tempo_ml_predict_cloud_number
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, is_first_step, &
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)
83 type(ty_tempo_main_diags),
intent(out) :: tempo_main_diags
85 type(ty_tempo_cfgs),
intent(in) :: tempo_cfgs
86 integer,
intent(in) :: kts, kte, ii, jj
87 real(wp),
intent(in) :: dt
88 logical,
intent(in),
optional :: is_first_step
89 real(wp),
dimension(kts:kte),
intent(inout) :: t1d
90 real(wp),
dimension(kts:kte),
intent(in) :: p1d
91 real(wp),
dimension(kts:kte),
intent(inout) :: qv1d
92 real(wp),
dimension(kts:kte),
intent(inout) :: qc1d
93 real(wp),
dimension(kts:kte),
intent(inout) :: qr1d
94 real(wp),
dimension(kts:kte),
intent(inout) :: qi1d
95 real(wp),
dimension(kts:kte),
intent(inout) :: qs1d
96 real(wp),
dimension(kts:kte),
intent(inout) :: qg1d
97 real(wp),
dimension(kts:kte),
intent(inout) :: ni1d
98 real(wp),
dimension(kts:kte),
intent(inout) :: nr1d
99 real(wp),
dimension(:),
intent(inout),
optional :: nc1d
100 real(wp),
dimension(:),
intent(inout),
optional :: nwfa1d
101 real(wp),
dimension(:),
intent(inout),
optional :: nifa1d
102 real(wp),
dimension(:),
intent(inout),
optional :: qb1d
103 real(wp),
dimension(:),
intent(inout),
optional :: ng1d
104 real(wp),
dimension(kts:kte),
intent(in) :: w1d
105 real(wp),
dimension(kts:kte),
intent(in) :: dz1d
106 integer,
intent(in),
optional :: land1d
109 real(wp),
dimension(:),
intent(inout),
optional :: qcfrac1d
110 real(wp),
dimension(:),
intent(inout),
optional :: qifrac1d
111 real(wp),
dimension(:),
intent(in),
optional :: qc_bl1d
112 real(wp),
dimension(:),
intent(in),
optional :: qcfrac_bl1d
113 real(wp),
dimension(:),
intent(in),
optional :: thten_bl1d
114 real(wp),
dimension(:),
intent(in),
optional :: qvten_bl1d
115 real(wp),
dimension(:),
intent(in),
optional :: qcten_bl1d
116 real(wp),
dimension(:),
intent(in),
optional :: qiten_bl1d
117 real(wp),
dimension(:),
intent(in),
optional :: thten_lwrad1d
118 real(wp),
dimension(:),
intent(in),
optional :: thten_swrad1d
120 real(wp),
dimension(kts:kte) :: tten, qvten, qcten, qiten, qrten, qsten, &
121 qgten, qbten, niten, nrten, ncten, ngten, nwfaten, nifaten
123 logical,
dimension(kts:kte) :: l_qc, l_qi, l_qr, l_qs, l_qg
124 integer,
dimension(kts:kte) :: idx_bg
127 real(wp),
dimension(kts:kte) :: temp, pres, qv
128 real(wp),
dimension(kts:kte) :: rho, rhof, rhof2
129 real(wp),
dimension(kts:kte) :: qvs, qvsi, delqvs
130 real(wp),
dimension(kts:kte) :: satw, sati, ssatw, ssati
131 real(wp),
dimension(kts:kte) :: diffu, visco, vsc2, tcond, lvap, ocp, lvt2
133 real(wp),
dimension(kts:kte) :: rc, ri, rr, rs, rg, rb
134 real(wp),
dimension(kts:kte) :: ni, nr, nc, ng, nwfa, nifa
136 real(dp),
dimension(kts:kte) :: ilamc, ilami, ilamr, ilamg
137 real(wp),
dimension(kts:kte) :: mvd_r, mvd_c, mvd_g
138 real(dp),
dimension(kts:kte) :: smob, smo2, smo1, smo0, smoc, smoe, smof, smog, ns, smoz
140 real(wp),
dimension(kts:kte) :: xrx, xnx
141 real(wp),
dimension(:),
allocatable :: xncx, xngx, xqbx, ncsave
143 real(wp),
dimension(kts:kte+1) :: vtrr, vtnr, vtrs, vtri, vtni, vtrg, vtng, vtrc, vtnc
144 real(wp),
dimension(kts:kte) :: vtboost
145 integer :: substeps_sedi, ktop_sedi, n
146 real(wp) :: semi_sedi_factor
148 real(dp),
target,
dimension(kts:kte, 74) :: tend_work
151 real(wp) :: tempc, tc0, odt
152 logical :: do_micro, supersaturated, local_first_step
156 local_first_step = .false.
157 if (
present(is_first_step)) local_first_step = is_first_step
160 supersaturated = .false.
167 tend%prr_wau => tend_work(:, 1)
168 tend%pnr_wau => tend_work(:, 2)
169 tend%pnc_wau => tend_work(:, 3)
170 tend%prr_rcw => tend_work(:, 4)
171 tend%pnc_rcw => tend_work(:, 5)
172 tend%pnr_rcr => tend_work(:, 6)
175 tend%prs_scw => tend_work(:, 7)
176 tend%pnc_scw => tend_work(:, 8)
177 tend%png_scw => tend_work(:, 9)
178 tend%pbg_scw => tend_work(:, 10)
179 tend%prg_gcw => tend_work(:, 11)
180 tend%pnc_gcw => tend_work(:, 12)
181 tend%pbg_gcw => tend_work(:, 13)
182 tend%pri_ihm => tend_work(:, 14)
183 tend%pni_ihm => tend_work(:, 15)
184 tend%prs_ihm => tend_work(:, 16)
185 tend%prg_ihm => tend_work(:, 17)
186 tend%prg_scw => tend_work(:, 18)
189 tend%prr_rcs => tend_work(:, 19)
190 tend%pnr_rcs => tend_work(:, 20)
191 tend%prg_rcs => tend_work(:, 21)
192 tend%png_rcs => tend_work(:, 22)
193 tend%prs_rcs => tend_work(:, 23)
194 tend%pbg_rcs => tend_work(:, 24)
197 tend%prr_rcg => tend_work(:, 25)
198 tend%pnr_rcg => tend_work(:, 26)
199 tend%prg_rcg => tend_work(:, 27)
200 tend%png_rcg => tend_work(:, 28)
201 tend%pbg_rcg => tend_work(:, 29)
204 tend%pri_inu => tend_work(:, 30)
205 tend%pni_inu => tend_work(:, 31)
206 tend%pri_iha => tend_work(:, 32)
207 tend%pni_iha => tend_work(:, 33)
210 tend%pri_wfz => tend_work(:, 34)
211 tend%pni_wfz => tend_work(:, 35)
214 tend%prg_rfz => tend_work(:, 36)
215 tend%png_rfz => tend_work(:, 37)
216 tend%pnr_rfz => tend_work(:, 38)
217 tend%pri_rfz => tend_work(:, 39)
218 tend%pni_rfz => tend_work(:, 40)
219 tend%pbg_rfz => tend_work(:, 41)
222 tend%prs_sde => tend_work(:, 42)
223 tend%pri_ide => tend_work(:, 43)
224 tend%pni_ide => tend_work(:, 44)
225 tend%prs_ide => tend_work(:, 45)
226 tend%prg_gde => tend_work(:, 46)
227 tend%png_gde => tend_work(:, 47)
230 tend%pni_iau => tend_work(:, 48)
231 tend%prs_iau => tend_work(:, 49)
234 tend%prr_sml => tend_work(:, 50)
235 tend%prr_gml => tend_work(:, 51)
236 tend%pbg_sml => tend_work(:, 52)
237 tend%pbg_gml => tend_work(:, 53)
238 tend%pnr_sml => tend_work(:, 54)
239 tend%pnr_gml => tend_work(:, 55)
242 tend%prr_rci => tend_work(:, 56)
243 tend%pnr_rci => tend_work(:, 57)
244 tend%pri_rci => tend_work(:, 58)
245 tend%pni_rci => tend_work(:, 59)
246 tend%prg_rci => tend_work(:, 60)
247 tend%png_rci => tend_work(:, 61)
248 tend%pbg_rci => tend_work(:, 62)
251 tend%pni_sci => tend_work(:, 63)
252 tend%prs_sci => tend_work(:, 64)
255 tend%prw_vcd => tend_work(:, 65)
256 tend%pnc_wcd => tend_work(:, 66)
257 tend%prv_rev => tend_work(:, 67)
258 tend%pnr_rev => tend_work(:, 68)
261 tend%pna_rca => tend_work(:, 69)
262 tend%pna_sca => tend_work(:, 70)
263 tend%pna_gca => tend_work(:, 71)
264 tend%pnd_rcd => tend_work(:, 72)
265 tend%pnd_scd => tend_work(:, 73)
266 tend%pnd_gcd => tend_work(:, 74)
313 tempo_main_diags%rain_precip = 0._wp
314 tempo_main_diags%cloud_precip = 0._wp
315 tempo_main_diags%ice_liquid_equiv_precip = 0._wp
316 tempo_main_diags%snow_liquid_equiv_precip = 0._wp
317 tempo_main_diags%graupel_liquid_equiv_precip = 0._wp
318 tempo_main_diags%frz_rain_precip = 0._wp
323 qv(k) = max(min_qv, qv1d(k))
325 rho(k) = roverrv*pres(k)/(rdry*temp(k)*(qv(k)+roverrv))
328 if (
present(nwfa1d))
then
329 if (local_first_step)
then
330 if (sum(nwfa1d) < eps)
call init_water_friendly_aerosols(dz1d, nwfa)
333 call init_water_friendly_aerosols(dz1d, nwfa)
336 if (
present(nifa1d))
then
337 if (local_first_step)
then
338 if (sum(nifa1d) < eps)
call init_ice_friendly_aerosols(dz1d, nifa)
341 call init_ice_friendly_aerosols(dz1d, nifa)
344 call aerosol_check_and_update(rho=rho, nwfa1d=nwfa1d, nifa1d=nifa1d, &
345 nwfa=nwfa, nifa=nifa, nwfaten=nwfaten, nifaten=nifaten, dt=dt)
347 call rain_check_and_update(rho, l_qr, qr1d, nr1d, rr, nr, qrten, nrten, ilamr, mvd_r, dt, odt)
349 call ice_check_and_update(rho, l_qi, qi1d, ni1d, ri, ni, qiten, niten, ilami, dt, odt)
351 call snow_check_and_update(rho, l_qs, qs1d, rs, qsten, dt, odt)
355 tc0 = min(-0.1, temp(k)-t0)
356 call snow_moments(rs=rs(k), tc=tc0, &
357 smob=smob(k), smoc=smoc(k), ns=ns(k), &
358 smo0=smo0(k), smo1=smo1(k), smo2=smo2(k), &
359 smoe=smoe(k), smof=smof(k), smog=smog(k))
364 if (.not.
present(nc1d))
then
365 if (tempo_cfgs%ml_for_nc_flag)
then
367 where(xrx <= 1.e-12_wp) xrx = 0._wp
373 if (
present(land1d))
then
376 nc = tempo_cfgs%get_nc_val(val_land=nt_c_l, val_ocean=nt_c_o)
379 allocate(ncsave(nz), source=nc)
382 call cloud_check_and_update(rho=rho, l_qc=l_qc, qc1d=qc1d, nc1d=nc1d, &
383 ncsave=ncsave, rc=rc, nc=nc, qcten=qcten, ncten=ncten, ilamc=ilamc, mvd_c=mvd_c, &
387 if (local_first_step)
then
388 if (
present(ng1d) .and.
present(qb1d))
then
389 if (sum(qg1d) > r1 .and. sum(ng1d) < eps .and. sum(qb1d) < eps)
then
390 call graupel_init(rho, qg1d, ng1d, qb1d)
394 call graupel_check_and_update(rho=rho, l_qg=l_qg, qg1d=qg1d, ng1d=ng1d, &
395 qb1d=qb1d, rg=rg, ng=ng, rb=rb, idx=idx_bg, qgten=qgten, ngten=ngten, &
396 qbten=qbten, ilamg=ilamg, mvd_g=mvd_g, dt=dt, odt=odt)
412 call thermo_vars(qv, temp, pres, rho, rhof, rhof2, qvs, delqvs, qvsi, &
413 satw, sati, ssatw, ssati, diffu, visco, vsc2, ocp, lvap, tcond, lvt2, &
417 do_micro = any(l_qc) .or. any(l_qr) .or. any(l_qi) .or. any(l_qs) .or. any(l_qg)
418 if (.not. do_micro .and. .not. supersaturated)
return
421 if (.not. tempo_cfgs%turn_off_micro_flag)
then
422 call warm_rain(rhof, l_qc, rc, nc, ilamc, mvd_c, l_qr, rr, nr, mvd_r, tend, odt)
424 if (.not. tempo_cfgs%turn_off_micro_flag)
then
425 call rain_snow_rain_graupel(temp, l_qr, rr, nr, ilamr, l_qs, rs, &
426 l_qg, rg, ng, ilamg, idx_bg, tend, odt)
428 if (.not. tempo_cfgs%turn_off_micro_flag)
then
429 call ice_nucleation(temp, rho, w1d, qv, qvsi, ssati, ssatw, &
430 nwfa1d, nifa1d, nwfa, nifa, ni, smo0, rc, nc, rr, nr, ilamr, tend, dt, odt)
432 if (.not. tempo_cfgs%turn_off_micro_flag)
then
433 call ice_processes(rhof, rhof2, rho, w1d, temp, qv, qvsi, tcond, diffu, &
434 vsc2, ssati, l_qi, ri, ni, ilami, l_qs, rs, smoe, smof, smo1, rr, nr, &
435 ilamr, mvd_r, l_qg, rg, ng, ilamg, idx_bg, tend, odt)
437 if (.not. tempo_cfgs%turn_off_micro_flag)
then
438 call riming(temp, rhof, visco, l_qc, rc, nc, ilamc, mvd_c, l_qs, rs, &
439 smo0, smob, smoc, smoe, vtboost, l_qg, rg, ng, ilamg, idx_bg, tend, odt)
441 if (.not. tempo_cfgs%turn_off_micro_flag)
then
442 call melting(rhof2, rho, temp, qvsi, tcond, diffu, vsc2, ssati, delqvs, &
443 l_qs, rs, smof, smo0, smo1, l_qg, rg, ng, ilamg, idx_bg, tend, dt, odt)
445 if (.not. tempo_cfgs%turn_off_micro_flag)
then
446 if (
present(nwfa1d) .or.
present(nifa1d))
then
447 call aerosol_scavenging(temp, rho, rhof, visco, nwfa, nifa, l_qr, nr, ilamr, &
448 mvd_r, l_qs, rs, smob, smoc, smoe, l_qg, rg, ng, ilamg, idx_bg, tend, odt)
453 call check_over_depletion(rho, temp, qvsi, qv, l_qc, rc, l_qi, ri, &
454 l_qr, rr, l_qs, rs, l_qg, rg, tend, odt)
456 call sum_tendencies(rho, temp, idx_bg, lvap, ocp, tend, tten, qvten, qcten, &
457 ncten, qiten, niten, qsten, qrten, nrten, qgten, ngten, qbten)
461 temp(k) = t1d(k) + tten(k)*dt
463 qv(k) = max(min_qv, qv1d(k) + qvten(k)*dt)
464 rho(k) = roverrv*pres(k)/(rdry*temp(k)*(qv(k)+roverrv))
465 nwfaten(k) = nwfaten(k) - (tend%pna_rca(k) + tend%pna_sca(k) + tend%pna_gca(k) + &
466 tend%pni_iha(k)) / rho(k)
467 nifaten(k) = nifaten(k) - (tend%pnd_rcd(k) + tend%pnd_scd(k) + tend%pnd_gcd(k)) / rho(k)
471 call aerosol_check_and_update(rho=rho, nwfa1d=nwfa1d, nifa1d=nifa1d, &
472 nwfa=nwfa, nifa=nifa, nwfaten=nwfaten, nifaten=nifaten, dt=dt)
476 if (
present(nc1d))
then
477 if (.not.
allocated(xncx))
allocate(xncx(nz), source=0._wp)
480 call cloud_check_and_update(rho=rho, l_qc=l_qc, qc1d=xrx, nc1d=xncx, &
481 ncsave=ncsave, rc=rc, nc=nc, qcten=qcten, ncten=ncten, ilamc=ilamc, mvd_c=mvd_c, &
486 call rain_check_and_update(rho, l_qr, xrx, xnx, rr, nr, qrten, nrten, ilamr, mvd_r, dt, odt)
490 call ice_check_and_update(rho, l_qi, xrx, xnx, ri, ni, qiten, niten, ilami, dt, odt)
493 call snow_check_and_update(rho, l_qs, xrx, rs, qsten, dt, odt)
506 tc0 = min(-0.1, temp(k)-t0)
507 call snow_moments(rs=rs(k), tc=tc0, &
508 smob=smob(k), smoc=smoc(k), &
514 if (
present(ng1d) .and.
present(qb1d))
then
515 if (.not.
allocated(xngx))
allocate(xngx(nz), source=0._wp)
516 if (.not.
allocated(xqbx))
allocate(xqbx(nz), source=0._wp)
520 call graupel_check_and_update(rho=rho, l_qg=l_qg, qg1d=xrx, ng1d=xngx, &
521 qb1d=xqbx, rg=rg, ng=ng, rb=rb, idx=idx_bg, qgten=qgten, ngten=ngten, &
522 qbten=qbten, ilamg=ilamg, mvd_g=mvd_g, dt=dt, odt=odt)
524 call thermo_vars(qv, temp, pres, rho, rhof, rhof2, qvs, delqvs, qvsi, &
525 satw, sati, ssatw, ssati, diffu, visco, vsc2, ocp, lvap, tcond, lvt2, &
530 if (.not. tempo_cfgs%turn_off_micro_flag .and. tempo_cfgs%cloud_condensation_flag)
then
531 call cloud_condensation(rho, temp, w1d, ssatw, lvap, tcond, diffu, lvt2, &
532 nwfa1d, nwfa, ncsave, qv, qvs, l_qc, rc, nc, tend, dt, odt)
535 qvten(k) = qvten(k) - tend%prw_vcd(k)
536 qcten(k) = qcten(k) + tend%prw_vcd(k)
537 ncten(k) = ncten(k) + tend%pnc_wcd(k)
538 nwfaten(k) = nwfaten(k) - tend%pnc_wcd(k)
539 tten(k) = tten(k) + lvap(k)*ocp(k)*tend%prw_vcd(k)
543 if (
present(nc1d))
then
544 if (.not.
allocated(xncx))
allocate(xncx(nz), source=0._wp)
547 call cloud_check_and_update(rho=rho, l_qc=l_qc, qc1d=xrx, nc1d=xncx, &
548 ncsave=ncsave, rc=rc, nc=nc, qcten=qcten, ncten=ncten, ilamc=ilamc, mvd_c=mvd_c, &
552 qv(k) = max(min_qv, qv1d(k) + qvten(k)*dt)
553 temp(k) = t1d(k) + tten(k)*dt
554 rho(k) = roverrv*pres(k)/(rdry*temp(k)*(qv(k)+roverrv))
557 call thermo_vars(qv, temp, pres, rho, rhof, rhof2, qvs, delqvs, qvsi, &
558 satw, sati, ssatw, ssati, diffu, visco, vsc2, ocp, lvap, tcond, lvt2, &
563 if (.not. tempo_cfgs%turn_off_micro_flag)
then
564 call rain_evaporation(rho, temp, ssatw, lvap, tcond, diffu, vsc2, rhof2, &
565 qv, qvs, l_qr, rr, nr, ilamr, tend, odt)
568 qrten(k) = qrten(k) - tend%prv_rev(k)
569 qvten(k) = qvten(k) + tend%prv_rev(k)
570 nrten(k) = nrten(k) - tend%pnr_rev(k)
571 nwfaten(k) = nwfaten(k) + tend%pnr_rev(k)
572 tten(k) = tten(k) - lvap(k)*ocp(k)*tend%prv_rev(k)
577 call rain_check_and_update(rho, l_qr, xrx, xnx, rr, nr, qrten, nrten, ilamr, mvd_r, dt, odt)
580 qv(k) = max(min_qv, qv1d(k) + qvten(k)*dt)
581 temp(k) = t1d(k) + tten(k)*dt
582 rho(k) = roverrv*pres(k)/(rdry*temp(k)*(qv(k)+roverrv))
585 call thermo_vars(qv, temp, pres, rho, rhof, rhof2, qvs, delqvs, qvsi, &
586 satw, sati, ssatw, ssati, diffu, visco, vsc2, ocp, lvap, tcond, lvt2, &
595 semi_sedi_factor = 10._wp
597 call rain_fallspeed(rhof=rhof, l_qr=l_qr, rr=rr, ilamr=ilamr, dz1d=dz1d, &
598 vt=vtrr, vtn=vtnr, substeps_sedi=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
600 if (tempo_cfgs%semi_sedi_flag)
then
601 substeps_sedi = max(int(substeps_sedi/semi_sedi_factor) + 1, 1)
602 do n = 1, substeps_sedi
603 call semilagrangian_sedimentation(dz1d=dz1d, rho=rho, xr=rr, xten=qrten, &
604 vt=vtrr, steps=substeps_sedi, limit=r1, precip=tempo_main_diags%rain_precip, dt=dt, odt=odt)
605 call semilagrangian_sedimentation(dz1d=dz1d, rho=rho, xr=nr, xten=nrten, &
606 vt=vtnr, steps=substeps_sedi, limit=r2, dt=dt, odt=odt)
611 call rain_check_and_update(rho, l_qr, xrx, xnx, rr, nr, qrten, nrten, ilamr, mvd_r, dt, odt)
612 call rain_fallspeed(rhof=rhof, l_qr=l_qr, rr=rr, ilamr=ilamr, dz1d=dz1d, &
613 vt=vtrr, vtn=vtnr, dt=dt)
616 do n = 1, substeps_sedi
617 call sedimentation(xr=rr, vt=vtrr, dz1d=dz1d, rho=rho, xten=qrten, limit=r1, &
618 steps=substeps_sedi, ktop_sedi=ktop_sedi, precip=tempo_main_diags%rain_precip, dt=dt)
619 call sedimentation(xr=nr, vt=vtnr, dz1d=dz1d, rho=rho, xten=nrten, limit=r2, &
620 steps=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
635 semi_sedi_factor = 10._wp
637 call graupel_fallspeed(rhof=rhof, rho=rho, visco=visco, &
638 l_qg=l_qg, rg=rg, rb=rb, qb1d=qb1d, idx=idx_bg, ilamg=ilamg, dz1d=dz1d, &
639 vt=vtrg, vtn=vtng, substeps_sedi=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
641 if (tempo_cfgs%semi_sedi_flag)
then
642 substeps_sedi = max(int(substeps_sedi/semi_sedi_factor) + 1, 1)
643 do n = 1, substeps_sedi
644 call semilagrangian_sedimentation(dz1d=dz1d, rho=rho, xr=rg, xten=qgten, &
645 vt=vtrg, steps=substeps_sedi, limit=r1, precip=tempo_main_diags%graupel_liquid_equiv_precip, &
647 call semilagrangian_sedimentation(dz1d=dz1d, rho=rho, xr=ng, xten=ngten, &
648 vt=vtng, steps=substeps_sedi, limit=r2, dt=dt, odt=odt)
649 call semilagrangian_sedimentation(dz1d=dz1d, rho=rho, xr=rb, xten=qbten, &
650 vt=vtrg, steps=substeps_sedi, limit=meters3_to_liters*r1/rho_g(nrhg), dt=dt, odt=odt)
654 if (
present(ng1d) .and.
present(qb1d))
then
655 if (.not.
allocated(xngx))
allocate(xngx(nz), source=0._wp)
656 if (.not.
allocated(xqbx))
allocate(xqbx(nz), source=0._wp)
660 call graupel_check_and_update(rho=rho, l_qg=l_qg, qg1d=xrx, ng1d=xngx, &
661 qb1d=xqbx, rg=rg, ng=ng, rb=rb, idx=idx_bg, qgten=qgten, ngten=ngten, &
662 qbten=qbten, ilamg=ilamg, mvd_g=mvd_g, dt=dt, odt=odt)
663 call graupel_fallspeed(rhof=rhof, rho=rho, visco=visco, &
664 l_qg=l_qg, rg=rg, rb=rb, qb1d=qb1d, idx=idx_bg, ilamg=ilamg, dz1d=dz1d, &
665 vt=vtrg, vtn=vtng, dt=dt)
668 do n = 1, substeps_sedi
669 call sedimentation(xr=rg, vt=vtrg, dz1d=dz1d, rho=rho, xten=qgten, limit=r1, &
670 steps=substeps_sedi, ktop_sedi=ktop_sedi, precip=tempo_main_diags%graupel_liquid_equiv_precip, dt=dt)
671 call sedimentation(xr=ng, vt=vtng, dz1d=dz1d, rho=rho, xten=ngten, limit=r2, &
672 steps=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
673 call sedimentation(xr=rb, vt=vtrg, dz1d=dz1d, rho=rho, xten=qbten, &
674 limit=meters3_to_liters*r1/rho_g(nrhg), steps=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
698 call snow_fallspeed(rhof=rhof, l_qs=l_qs, rs=rs, prr_sml=tend%prr_sml, smob=smob, smoc=smoc, &
699 rr=rr, vtrr=vtrr, dz1d=dz1d, vt=vtrs, vtboost=vtboost, substeps_sedi=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
700 do n = 1, substeps_sedi
701 call sedimentation(xr=rs, vt=vtrs, dz1d=dz1d, rho=rho, xten=qsten, limit=r1, &
702 steps=substeps_sedi, ktop_sedi=ktop_sedi, precip=tempo_main_diags%snow_liquid_equiv_precip, dt=dt)
710 call ice_fallspeed(rhof, l_qi, ri, ilami, dz1d, vtri, vtni, &
711 substeps_sedi, ktop_sedi, dt=dt)
712 call sedimentation(xr=ri, vt=vtri, dz1d=dz1d, rho=rho, xten=qiten, limit=r1, &
713 steps=substeps_sedi, ktop_sedi=ktop_sedi, precip=tempo_main_diags%ice_liquid_equiv_precip, dt=dt)
714 call sedimentation(xr=ni, vt=vtni, dz1d=dz1d, rho=rho, xten=niten, limit=r2, &
715 steps=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
722 call cloud_fallspeed(rhof, w1d, l_qc, rc, nc, ilamc, dz1d, vtrc, vtnc, ktop_sedi)
723 call sedimentation(xr=rc, vt=vtrc, dz1d=dz1d, rho=rho, xten=qcten, limit=r1, &
724 steps=substeps_sedi, ktop_sedi=ktop_sedi, precip=tempo_main_diags%cloud_precip, dt=dt)
725 call sedimentation(xr=nc, vt=vtnc, dz1d=dz1d, rho=rho, xten=ncten, limit=r2, &
726 steps=substeps_sedi, ktop_sedi=ktop_sedi, dt=dt)
731 if (.not. tempo_cfgs%turn_off_micro_flag)
then
732 call freeze_cloud_melt_ice(temp=temp, rho=rho, ocp=ocp, lvap=lvap, &
733 qi1d=qi1d, ni1d=ni1d, qiten=qiten, niten=niten, qc1d=qc1d, nc1d=nc1d, &
734 qcten=qcten, ncten=ncten, tten=tten, ncsave=ncsave, dt=dt, odt=odt)
739 t1d(k) = t1d(k) + tten(k)*dt
740 qv1d(k) = max(min_qv, (qv1d(k) + qvten(k)*dt))
741 rho(k) = roverrv*pres(k)/(rdry*temp(k)*(qv(k)+roverrv))
742 if (
present(nwfa1d))
then
743 nwfa1d(k) = max(nwfa_default, min(aero_max, (nwfa1d(k)+nwfaten(k)*dt)))
745 if (
present(nifa1d))
then
746 nifa1d(k) = max(nifa_default, min(aero_max, (nifa1d(k)+nifaten(k)*dt)))
750 call cloud_check_and_update(rho=rho, l_qc=l_qc, qc1d=qc1d, nc1d=nc1d, &
751 ncsave=ncsave, rc=rc, nc=nc, qcten=qcten, ncten=ncten, ilamc=ilamc, mvd_c=mvd_c, &
754 call rain_check_and_update(rho, l_qr, qr1d, nr1d, rr, nr, qrten, nrten, ilamr, mvd_r, dt, odt)
756 call ice_check_and_update(rho, l_qi, qi1d, ni1d, ri, ni, qiten, niten, ilami, dt, odt)
758 call snow_check_and_update(rho, l_qs, qs1d, rs, qsten, dt, odt)
772 tc0 = min(-0.1, temp(k)-t0)
773 call snow_moments(rs=rs(k), tc=tc0, &
774 smob=smob(k), smoc=smoc(k), &
775 smo2=smo2(k), smoz=smoz(k))
779 call graupel_check_and_update(rho=rho, l_qg=l_qg, qg1d=qg1d, ng1d=ng1d, &
780 qb1d=qb1d, rg=rg, ng=ng, rb=rb, idx=idx_bg, qgten=qgten, ngten=ngten, &
781 qbten=qbten, ilamg=ilamg, mvd_g=mvd_g, dt=dt, odt=odt)
785 tempo_main_diags%frozen_fraction = &
786 (tempo_main_diags%ice_liquid_equiv_precip + tempo_main_diags%snow_liquid_equiv_precip + &
787 tempo_main_diags%graupel_liquid_equiv_precip) / &
788 (tempo_main_diags%ice_liquid_equiv_precip + tempo_main_diags%snow_liquid_equiv_precip + &
789 tempo_main_diags%graupel_liquid_equiv_precip + tempo_main_diags%rain_precip + r1)
792 call freezing_rain(temp=temp(1), rain_precip=tempo_main_diags%rain_precip, &
793 cloud_precip=tempo_main_diags%cloud_precip, &
794 frz_rain=tempo_main_diags%frz_rain_precip)
796 if (tempo_cfgs%cloud_number_mixing_ratio_flag)
then
797 allocate(tempo_main_diags%cloud_number_mixing_ratio(nz), source=nc*rho)
801 if (tempo_cfgs%rain_med_vol_diam_flag)
then
802 allocate(tempo_main_diags%rain_med_vol_diam(nz), source=0._wp)
803 tempo_main_diags%rain_med_vol_diam = mvd_r
805 if (tempo_cfgs%graupel_med_vol_diam_flag)
then
806 allocate(tempo_main_diags%graupel_med_vol_diam(nz), source=0._wp)
807 tempo_main_diags%graupel_med_vol_diam = mvd_g
811 if (tempo_cfgs%max_hail_diameter_flag)
then
812 allocate(tempo_main_diags%max_hail_diameter(nz), source=0._wp)
813 call max_hail_diam(rho, rg, ng, ilamg, idx_bg, &
814 tempo_main_diags%max_hail_diameter)
818 if (tempo_cfgs%refl10cm_flag)
then
819 allocate(tempo_main_diags%refl10cm(nz), source=-35._wp)
820 call reflectivity_10cm(tempo_cfgs%refl10cm_from_melting_flag, &
821 temp, l_qr, rr, nr, ilamr, &
822 l_qs, rs, smoc, smob, smoz, l_qg, rg, ng, idx_bg, ilamg, &
823 tempo_main_diags%refl10cm)
827 if ((tempo_cfgs%re_cloud_flag) .and. (tempo_cfgs%re_ice_flag) .and. (tempo_cfgs%re_snow_flag))
then
828 allocate(tempo_main_diags%re_cloud(nz), source=0._wp)
829 allocate(tempo_main_diags%re_ice(nz), source=0._wp)
830 allocate(tempo_main_diags%re_snow(nz), source=0._wp)
839 if (
present(qc_bl1d) .and.
present(qcfrac_bl1d))
then
841 if (.not.
allocated(xncx))
allocate(xncx(nz), source=0._wp)
844 if ((xrx(k) <= r1) .and. &
845 (qc_bl1d(k) > 1.e-9_wp) .and. (qcfrac_bl1d(k) > 0._wp))
then
846 xrx(k) = xrx(k) + qc_bl1d(k) / qcfrac_bl1d(k)
849 where(xrx <= 1.e-12_wp) xrx = 0._wp
857 call cloud_check_and_update(rho=rho, l_qc=l_qc, qc1d=xrx, nc1d=xncx, &
858 rc=rc, nc=nc, qcten=qcten, ncten=ncten, ilamc=ilamc, mvd_c=mvd_c, &
861 call effective_radius(temp, l_qc, nc, ilamc, l_qi, ilami, l_qs, rs, &
862 tempo_main_diags%re_cloud, tempo_main_diags%re_ice, tempo_main_diags%re_snow)
864 end subroutine tempo_main
867 subroutine aerosol_check_and_update(rho, nwfa1d, nifa1d, nwfa, nifa, nwfaten, nifaten, dt)
869 use module_mp_tempo_params,
only : nwfa_default, aero_max, nifa_default
871 real(wp),
intent(in) :: dt
872 real(wp),
dimension(:),
intent(in) :: rho
873 real(wp),
dimension(:),
intent(inout) :: nwfa, nifa, nwfaten, nifaten
874 real(wp),
dimension(:),
intent(inout),
optional :: nwfa1d, nifa1d
879 if (
present(nwfa1d))
then
880 nwfa(k) = (nwfa1d(k)+nwfaten(k)*dt)*rho(k)
882 if (
present(nifa1d))
then
883 nifa(k) = (nifa1d(k)+nifaten(k)*dt)*rho(k)
885 nwfa(k) = max(nwfa_default*rho(k), min(aero_max*rho(k), nwfa(k)))
886 nifa(k) = max(nifa_default*rho(k), min(aero_max*rho(k), nifa(k)))
888 end subroutine aerosol_check_and_update
891 subroutine cloud_check_and_update(rho, l_qc, qc1d, nc1d, ncsave, rc, nc, &
892 qcten, ncten, ilamc, mvd_c, dt, odt)
894 use module_mp_tempo_params,
only : r1, nt_c_max, nt_c_min, nu_c_scale, &
895 am_r, bm_r, cce, ccg, d0c, d0r, ocg1, ocg2, obmr, nt_c_l, d0r, nt_c_l
897 real(wp),
intent(in) :: dt, odt
898 real(wp),
dimension(:),
intent(in) :: rho
899 real(wp),
dimension(:),
intent(inout) :: qc1d, qcten, ncten, rc, nc
900 real(wp),
dimension(:),
intent(out) :: mvd_c
901 real(dp),
dimension(:),
intent(out) :: ilamc
902 real(wp),
dimension(:),
intent(inout),
optional :: nc1d, ncsave
903 logical,
dimension(:),
intent(inout) :: l_qc
904 integer :: k, nz, nu_c
905 real(dp) :: lamc, xdc
911 if (qc1d(k)+qcten(k)*dt > r1)
then
914 rc(k) = (qc1d(k)+qcten(k)*dt)*rho(k)
915 qc1d(k) = qc1d(k)+qcten(k)*dt
918 if (
present(nc1d))
then
919 nc(k) = max(nt_c_min, (nc1d(k)+ncten(k)*dt)*rho(k))
922 if (nc(k) <= nt_c_min)
then
926 if (nc(k) > nt_c_max)
then
932 nu_c = get_nuc(nc(k))
933 lamc = (nc(k)*am_r*ccg(2,nu_c)*ocg1(nu_c)/rc(k))**obmr
934 xdc = (bm_r + nu_c + 1._dp) / lamc
936 lamc = cce(2,nu_c)/d0c
938 elseif (xdc > d0r*2._dp)
then
939 lamc = cce(2,nu_c)/(d0r*2._dp)
943 nc(k) = ccg(1,nu_c)*ocg2(nu_c)*rc(k) / am_r*lamc**bm_r
945 if (hit_limit) ncten(k) = (nc(k)/rho(k) - nc1d(k)) * odt
946 nc1d(k) = max(nt_c_min/rho(k), &
947 min(real(ccg(1,nu_c)*ocg2(nu_c)*qc1d(k)/am_r*lamc**bm_r, kind=wp), nt_c_max/rho(k)))
949 if (
present(ncsave))
then
955 nu_c = get_nuc(nc(k))
956 lamc = (nc(k)*am_r*ccg(2,nu_c)*ocg1(nu_c)/rc(k))**obmr
957 ilamc(k) = 1._dp / lamc
958 mvd_c(k) = max(min(real((3.0_wp + nu_c + 0.672_wp) * ilamc(k), kind=wp), d0r), d0c)
965 qcten(k) = -qc1d(k) * odt
967 if (
present(nc1d))
then
968 ncten(k) = -nc1d(k) * odt
973 end subroutine cloud_check_and_update
976 subroutine rain_check_and_update(rho, l_qr, qr1d, nr1d, rr, nr, &
977 qrten, nrten, ilamr, mvd_r, dt, odt)
979 use module_mp_tempo_params,
only : r1, r2, mu_r, crg, &
980 am_r, bm_r, obmr, d0r, d0r_max, org2, org3, rho_g
982 real(wp),
intent(in) :: dt, odt
983 real(wp),
dimension(:),
intent(in) :: rho
984 real(wp),
dimension(:),
intent(inout) :: qr1d, nr1d, qrten, nrten, rr, nr
985 real(wp),
dimension(:),
intent(out) :: mvd_r
986 real(dp),
dimension(:),
intent(out) :: ilamr
987 logical,
dimension(:),
intent(inout) :: l_qr
995 if (qr1d(k)+qrten(k)*dt > r1)
then
998 rr(k) = (qr1d(k)+qrten(k)*dt)*rho(k)
999 qr1d(k) = qr1d(k)+qrten(k)*dt
1002 nr(k) = max(r2, (nr1d(k)+nrten(k)*dt)*rho(k))
1005 if (nr(k) <= r2)
then
1007 mvd_r(k) = 1.0e-3_wp
1008 lamr = (3.0_dp + mu_r + 0.672_dp) / mvd_r(k)
1009 nr(k) = crg(2)*org3*rr(k)*lamr**bm_r / am_r
1013 lamr = (am_r*crg(3)*org2*nr(k)/rr(k))**obmr
1014 mvd_r(k) = (3.0_wp + mu_r + 0.672_wp) / lamr
1015 if (mvd_r(k) > d0r_max)
then
1018 lamr = (3.0_dp + mu_r + 0.672_dp) / mvd_r(k)
1019 nr(k) = crg(2)*org3*rr(k)*lamr**bm_r / am_r
1020 elseif (mvd_r(k) < d0r*0.75_wp)
then
1022 mvd_r(k) = d0r*0.75_wp
1023 lamr = (3.0_dp + mu_r + 0.672_dp) / mvd_r(k)
1024 nr(k) = crg(2)*org3*rr(k)*lamr**bm_r / am_r
1027 if (hit_limit) nrten(k) = (nr(k)/rho(k) - nr1d(k))*odt
1028 nr1d(k) = crg(2)*org3*qr1d(k)*lamr**bm_r / am_r
1029 ilamr(k) = 1._dp / lamr
1036 qrten(k) = -qr1d(k) * odt
1037 nrten(k) = -nr1d(k) * odt
1042 end subroutine rain_check_and_update
1045 subroutine ice_check_and_update(rho, l_qi, qi1d, ni1d, ri, ni, &
1046 qiten, niten, ilami, dt, odt)
1048 use module_mp_tempo_params,
only : max_ni, r1, r2, cie, cig, &
1049 mu_i, am_i, bm_i, oig1, oig2, obmi , d0s
1051 real(wp),
intent(in) :: dt, odt
1052 real(wp),
dimension(:),
intent(in) :: rho
1053 real(wp),
dimension(:),
intent(inout) :: qi1d, ni1d, qiten, niten, ri, ni
1054 real(dp),
dimension(:),
intent(out) :: ilami
1055 logical,
dimension(:),
intent(inout) :: l_qi
1057 real(dp) :: lami, xdi
1058 logical :: hit_limit
1063 if (qi1d(k)+qiten(k)*dt > r1)
then
1066 ri(k) = (qi1d(k)+qiten(k)*dt)*rho(k)
1067 qi1d(k) = qi1d(k)+qiten(k)*dt
1070 ni(k) = max(r2, (ni1d(k)+niten(k)*dt)*rho(k))
1073 if (ni(k) <= r2)
then
1075 lami = cie(2)/5.e-6_dp
1076 ni(k) = min(max_ni, real(cig(1)*oig2*ri(k)/am_i*lami**bm_i, kind=wp))
1080 lami = (am_i*cig(2)*oig1*ni(k)/ri(k))**obmi
1081 xdi = (bm_i + mu_i + 1._dp) / lami
1082 if (xdi < 5.e-6_dp)
then
1084 lami = cie(2)/5.e-6_dp
1085 ni(k) = min(max_ni, real(cig(1)*oig2*ri(k)/am_i*lami**bm_i, kind=wp))
1086 elseif (xdi > d0s)
then
1089 ni(k) = cig(1)*oig2*ri(k)/am_i*lami**bm_i
1092 if (hit_limit) niten(k) = (ni(k)/rho(k) - ni1d(k))*odt
1093 ni1d(k) = max(r2/rho(k), &
1094 min(real(cig(1)*oig2*qi1d(k)/am_i*lami**bm_i, kind=wp), max_ni/rho(k)))
1095 ilami(k) = 1._dp / lami
1101 qiten(k) = -qi1d(k) * odt
1102 niten(k) = -ni1d(k) * odt
1107 end subroutine ice_check_and_update
1110 subroutine snow_check_and_update(rho, l_qs, qs1d, rs, qsten, dt, odt)
1112 use module_mp_tempo_params,
only : max_ni, r1, r2
1114 real(wp),
intent(in) :: dt, odt
1115 real(wp),
dimension(:),
intent(in) :: rho
1116 real(wp),
dimension(:),
intent(inout) :: qs1d, rs, qsten
1117 logical,
dimension(:),
intent(inout) :: l_qs
1122 if (qs1d(k)+qsten(k)*dt > r1)
then
1125 rs(k) = (qs1d(k)+qsten(k)*dt)*rho(k)
1126 qs1d(k) = qs1d(k)+qsten(k)*dt
1130 qsten(k) = -qs1d(k) * odt
1134 end subroutine snow_check_and_update
1137 subroutine graupel_check_and_update(rho, l_qg, qg1d, ng1d, qb1d, rg, ng, rb, &
1138 idx, qgten, ngten, qbten, ilamg, mvd_g, dt, odt)
1140 use module_mp_tempo_params,
only : r1, r2, nrhg, rho_g, mu_g, &
1141 am_g, bm_g, ogg3, cgg, ogg2, obmg, d0r, idx_bg1, gonv_max, &
1142 gonv_min, oge1, ogg1, d0g, meters3_to_liters
1144 real(wp),
intent(in) :: dt, odt
1145 real(wp),
dimension(:),
intent(in) :: rho
1146 real(wp),
dimension(:),
intent(inout) :: qg1d, qgten, rg, ng, rb, ngten, qbten
1147 real(wp),
dimension(:),
intent(inout),
optional :: ng1d, qb1d
1148 real(dp),
dimension(:),
intent(out) :: ilamg
1149 real(wp),
dimension(:),
intent(out) :: mvd_g
1150 logical,
dimension(:),
intent(inout) :: l_qg
1151 integer,
dimension(:),
intent(inout) :: idx
1153 real(dp) :: lamg, ygra1, zans1, n0_exp, lam_exp
1154 logical :: hit_limit
1159 if (qg1d(k)+qgten(k)*dt > r1)
then
1162 rg(k) = (qg1d(k)+qgten(k)*dt)*rho(k)
1163 qg1d(k) = qg1d(k)+qgten(k)*dt
1166 if (
present(ng1d) .and.
present(qb1d))
then
1167 ng(k) = max(r2, (ng1d(k)+ngten(k)*dt)*rho(k))
1169 rb(k) = min(max(rg(k)*meters3_to_liters/rho_g(nrhg), &
1170 (qb1d(k)+qbten(k)*dt)*rho(k)), rg(k)*meters3_to_liters/rho_g(1))
1171 idx(k) = max(1, min(nint(10._wp*rg(k)/rb(k))+1, nrhg))
1174 if (ng(k) <= r2)
then
1176 mvd_g(k) = 1.5e-3_wp
1177 lamg = (3.0_dp + mu_g + 0.672_dp) / mvd_g(k)
1178 ng(k) = cgg(2,1)*ogg3*rg(k)*lamg**bm_g / am_g(idx(k))
1182 lamg = (am_g(idx(k))*cgg(3,1)*ogg2*ng(k)/rg(k))**obmg
1183 mvd_g(k) = (3.0_wp + mu_g + 0.672_wp) / lamg
1184 if (mvd_g(k) > 25.4e-3_wp)
then
1186 mvd_g(k) = 25.4e-3_wp
1187 lamg = (3.0_dp + mu_g + 0.672_dp) / mvd_g(k)
1188 ng(k) = cgg(2,1)*ogg3*rg(k)*lamg**bm_g / am_g(idx(k))
1189 elseif (mvd_g(k) < d0r)
then
1192 lamg = (3.0_dp + mu_g + 0.672_dp) / mvd_g(k)
1193 ng(k) = cgg(2,1)*ogg3*rg(k)*lamg**bm_g / am_g(idx(k))
1196 if (hit_limit) ngten(k) = (ng(k)/rho(k) - ng1d(k)) * odt
1197 ng1d(k) = cgg(2,1)*ogg3*qg1d(k)*lamg**bm_g / am_g(idx(k))
1198 qb1d(k) = min(max(qg1d(k)*meters3_to_liters/rho_g(nrhg), &
1199 qb1d(k)+qbten(k)*dt), meters3_to_liters*qg1d(k)/rho_g(1))
1200 idx(k) = max(1, min(nint(10._wp*qg1d(k)/qb1d(k))+1, nrhg))
1203 ygra1 = log10(max(1.e-9_dp, real(rg(k), kind=dp)))
1204 zans1 = 3.4_dp + 2._dp/7._dp*(ygra1+8._dp)
1205 n0_exp = max(gonv_min, min(10._dp**(zans1), gonv_max))
1206 lam_exp = (n0_exp*am_g(idx(k))*cgg(1,1)/rg(k))**oge1
1207 lamg = lam_exp * (cgg(3,1)*ogg2*ogg1)**obmg
1208 ng(k) = cgg(2,1)*ogg3*rg(k)*lamg**bm_g / am_g(idx(k))
1209 rb(k) = meters3_to_liters*rg(k)/rho_g(idx(k))
1211 ilamg(k) = 1._dp / lamg
1212 mvd_g(k) = (3.0_wp + mu_g + 0.672_wp) * ilamg(k)
1220 rb(k) = meters3_to_liters*r1/rho_g(idx(k))
1221 qgten(k) = -qg1d(k) * odt
1223 if (
present(ng1d) .and.
present(qb1d))
then
1224 ngten(k) = -ng1d(k) * odt
1225 qbten(k) = -qb1d(k) * odt
1231 end subroutine graupel_check_and_update
1234 subroutine graupel_init(rho, qg1d, ng1d, qb1d)
1237 use module_mp_tempo_params,
only : r1, meters3_to_liters, &
1238 idx_bg1, am_g, bm_g, mu_g, ogg3, cgg
1240 real(wp),
dimension(:),
intent(in) :: rho
1241 real(wp),
dimension(:),
intent(in) :: qg1d
1242 real(wp),
dimension(:),
intent(inout) :: ng1d, qb1d
1243 integer :: k, nz, idx
1245 real(wp) :: mvd_g, rg, ng, rb
1249 if (qg1d(k) > r1)
then
1251 rb = rg*meters3_to_liters/rho_g(idx_bg1)
1252 idx = max(1, min(nint(10._wp*rg/rb)+1, nrhg))
1254 lamg = (3.0_dp + mu_g + 0.672_dp) / mvd_g
1255 ng = cgg(2,1)*ogg3*rg*lamg**bm_g / am_g(idx)
1260 end subroutine graupel_init
1263 subroutine thermo_vars(qv, temp, pres, rho, rhof, rhof2, qvs, delqvs, qvsi, &
1264 satw, sati, ssatw, ssati, diffu, visco, vsc2, ocp, lvap, tcond, lvt2, &
1267 use module_mp_tempo_params,
only : t0, rho_not, eps, cp, lvap0, orv
1269 real(wp),
dimension(:),
intent(in) :: qv, temp, pres, rho
1270 real(wp),
dimension(:),
intent(out) :: rhof, rhof2, qvs, &
1271 delqvs, qvsi, satw, sati, ssatw, ssati, diffu, visco, vsc2, &
1272 ocp, lvap, tcond, lvt2
1273 logical,
intent(inout) :: supersaturated
1275 real(wp) :: tempc, otemp
1278 supersaturated = .false.
1280 otemp = 1._wp / temp(k)
1281 tempc = temp(k) - t0
1282 rhof(k) = sqrt(rho_not/rho(k))
1283 rhof2(k) = sqrt(rhof(k))
1284 qvs(k) = calc_rslf(pres(k), temp(k))
1285 delqvs(k) = max(0._wp, calc_rslf(pres(k), t0)-qv(k))
1286 if (tempc <= 0._wp)
then
1287 qvsi(k) = calc_rsif(pres(k), temp(k))
1291 satw(k) = qv(k)/qvs(k)
1292 sati(k) = qv(k)/qvsi(k)
1293 ssatw(k) = satw(k) - 1._wp
1294 ssati(k) = sati(k) - 1._wp
1295 if (abs(ssatw(k)) < eps) ssatw(k) = 0._wp
1296 if (abs(ssati(k)) < eps) ssati(k) = 0._wp
1297 if (ssati(k) > 0._wp) supersaturated = .true.
1298 diffu(k) = 2.11e-5_wp*(temp(k)/t0)**1.94_wp * (101325._wp/pres(k))
1299 if (tempc >= 0._wp)
then
1300 visco(k) = (1.718_wp+0.0049_wp*tempc)*1.0e-5_wp
1302 visco(k) = (1.718_wp+0.0049_wp*tempc-1.2e-5_wp*tempc*tempc)*1.0e-5_wp
1304 ocp(k) = 1._wp/(cp*(1._wp+0.887_wp*qv(k)))
1305 vsc2(k) = sqrt(rho(k)/visco(k))
1306 lvap(k) = lvap0 + (2106.0_wp - 4218.0_wp)*tempc
1307 tcond(k) = (5.69_wp + 0.0168_wp*tempc)*1.0e-5_wp * 418.936_wp
1308 lvt2(k) = lvap(k)*lvap(k)*ocp(k)*orv*otemp*otemp
1310 end subroutine thermo_vars
1313 subroutine check_over_depletion(rho, temp, qvsi, qv, l_qc, rc, l_qi, ri, &
1314 l_qr, rr, l_qs, rs, l_qg, rg, tend, odt)
1317 use module_mp_tempo_params,
only : eps, rho_i, t0, meters3_to_liters
1319 real(wp),
intent(in) :: odt
1320 type(ty_tend),
intent(inout) :: tend
1321 logical,
dimension(:),
intent(in) :: l_qc, l_qi, l_qr, l_qs, l_qg
1322 real(wp),
dimension(:),
intent(in) :: rho, temp, qvsi, qv, rc, ri, rr, rs, rg
1323 real(wp) :: sump, rate_max, ratio
1330 sump = tend%pri_inu(k) + tend%pri_ide(k) + tend%prs_ide(k) + &
1331 tend%prs_sde(k) + tend%prg_gde(k) + tend%pri_iha(k)
1332 rate_max = (qv(k)-qvsi(k))*rho(k)*odt*0.999_wp
1333 if ((sump > eps .and. sump > rate_max) .or. &
1334 (sump < -eps .and. sump < rate_max))
then
1335 ratio = rate_max/sump
1336 tend%pri_inu(k) = tend%pri_inu(k) * ratio
1337 tend%pri_ide(k) = tend%pri_ide(k) * ratio
1338 tend%pni_ide(k) = tend%pni_ide(k) * ratio
1339 tend%prs_ide(k) = tend%prs_ide(k) * ratio
1340 tend%prs_sde(k) = tend%prs_sde(k) * ratio
1341 tend%prg_gde(k) = tend%prg_gde(k) * ratio
1342 tend%pri_iha(k) = tend%pri_iha(k) * ratio
1347 sump = -tend%prr_wau(k) - tend%pri_wfz(k) - tend%prr_rcw(k) - &
1348 tend%prs_scw(k) - tend%prg_scw(k) - tend%prg_gcw(k)
1349 rate_max = -rc(k)*odt
1351 if (sump < rate_max)
then
1352 ratio = rate_max/sump
1353 tend%prr_wau(k) = tend%prr_wau(k) * ratio
1354 tend%pri_wfz(k) = tend%pri_wfz(k) * ratio
1355 tend%prr_rcw(k) = tend%prr_rcw(k) * ratio
1356 tend%prs_scw(k) = tend%prs_scw(k) * ratio
1357 tend%prg_scw(k) = tend%prg_scw(k) * ratio
1358 tend%prg_gcw(k) = tend%prg_gcw(k) * ratio
1364 sump = tend%pri_ide(k) - tend%prs_iau(k) - tend%prs_sci(k) - tend%pri_rci(k)
1365 rate_max = -ri(k)*odt
1367 if (sump < rate_max)
then
1368 ratio = rate_max/sump
1369 tend%pri_ide(k) = tend%pri_ide(k) * ratio
1370 tend%prs_iau(k) = tend%prs_iau(k) * ratio
1371 tend%prs_sci(k) = tend%prs_sci(k) * ratio
1372 tend%pri_rci(k) = tend%pri_rci(k) * ratio
1378 sump = -tend%prg_rfz(k) - tend%pri_rfz(k) - tend%prr_rci(k) + &
1379 tend%prr_rcs(k) + tend%prr_rcg(k)
1380 rate_max = -rr(k)*odt
1382 if (sump < rate_max)
then
1383 ratio = rate_max/sump
1384 tend%prg_rfz(k) = tend%prg_rfz(k) * ratio
1385 tend%pbg_rfz(k) = tend%pbg_rfz(k) * ratio
1386 tend%pri_rfz(k) = tend%pri_rfz(k) * ratio
1387 tend%prr_rci(k) = tend%prr_rci(k) * ratio
1388 tend%prr_rcs(k) = tend%prr_rcs(k) * ratio
1389 tend%prr_rcg(k) = tend%prr_rcg(k) * ratio
1395 sump = tend%prs_sde(k) - tend%prs_ihm(k) - tend%prr_sml(k) + &
1397 rate_max = -rs(k)*odt
1399 if (sump < rate_max)
then
1400 ratio = rate_max/sump
1401 tend%prs_sde(k) = tend%prs_sde(k) * ratio
1402 tend%prs_ihm(k) = tend%prs_ihm(k) * ratio
1403 tend%prr_sml(k) = tend%prr_sml(k) * ratio
1404 tend%prs_rcs(k) = tend%prs_rcs(k) * ratio
1410 sump = tend%prg_gde(k) - tend%prg_ihm(k) - tend%prr_gml(k) + tend%prg_rcg(k)
1411 rate_max = -rg(k)*odt
1413 if (sump < rate_max)
then
1414 ratio = rate_max/sump
1415 tend%prg_gde(k) = tend%prg_gde(k) * ratio
1416 tend%prg_ihm(k) = tend%prg_ihm(k) * ratio
1417 tend%prr_gml(k) = tend%prr_gml(k) * ratio
1418 tend%prg_rcg(k) = tend%prg_rcg(k) * ratio
1419 tend%pbg_rcg(k) = tend%pbg_rcg(k) * ratio
1425 tend%pri_ihm(k) = tend%prs_ihm(k) + tend%prg_ihm(k)
1427 ratio = min(abs(tend%prr_rcg(k)), abs(tend%prg_rcg(k)))
1428 tend%prr_rcg(k) = ratio * sign(1.0_dp, tend%prr_rcg(k))
1429 tend%prg_rcg(k) = -tend%prr_rcg(k)
1430 tend%pbg_rcg(k) = meters3_to_liters*tend%prg_rcg(k)/rho_i
1432 if (temp(k) > t0)
then
1433 ratio = min(abs(tend%prr_rcs(k)), abs(tend%prs_rcs(k)))
1434 tend%prr_rcs(k) = ratio * sign(1.0_dp, tend%prr_rcs(k))
1435 tend%prs_rcs(k) = -tend%prr_rcs(k)
1438 end subroutine check_over_depletion
1441 subroutine sum_tendencies(rho, temp, idx, lvap, ocp, tend, tten, qvten, qcten, &
1442 ncten, qiten, niten, qsten, qrten, nrten, qgten, ngten, qbten)
1444 use module_mp_tempo_params,
only : lsub, rho_g, t0, lfus, meters3_to_liters
1446 type(ty_tend),
intent(in) :: tend
1447 real(wp),
dimension(:),
intent(in) :: rho, temp, lvap, ocp
1448 integer,
dimension(:),
intent(in) :: idx
1449 real(wp),
dimension(:),
intent(inout) :: qvten, qcten, ncten, qiten, niten, &
1450 qsten, qrten, nrten, qgten, ngten, qbten, tten
1451 real(wp) :: orho, lfus2
1457 lfus2 = lsub - lvap(k)
1459 qvten(k) = qvten(k) + (-tend%pri_inu(k) - tend%pri_iha(k) - tend%pri_ide(k) - &
1460 tend%prs_ide(k) - tend%prs_sde(k) - tend%prg_gde(k)) * orho
1462 qcten(k) = qcten(k) + (-tend%prr_wau(k) - tend%pri_wfz(k) - tend%prr_rcw(k) - &
1463 tend%prs_scw(k) - tend%prg_scw(k) - tend%prg_gcw(k)) * orho
1465 ncten(k) = ncten(k) + (-tend%pnc_wau(k) - tend%pnc_rcw(k) - tend%pni_wfz(k) - &
1466 tend%pnc_scw(k) - tend%pnc_gcw(k)) * orho
1468 qiten(k) = qiten(k) + (tend%pri_inu(k) + tend%pri_iha(k) + tend%pri_ihm(k) + &
1469 tend%pri_wfz(k) + tend%pri_rfz(k) + tend%pri_ide(k) - tend%prs_iau(k) - &
1470 tend%prs_sci(k) - tend%pri_rci(k)) * orho
1472 niten(k) = niten(k) + (tend%pni_inu(k) + tend%pni_iha(k) + tend%pni_ihm(k) + &
1473 tend%pni_wfz(k) + tend%pni_rfz(k) + tend%pni_ide(k) - tend%pni_iau(k) - &
1474 tend%pni_sci(k) - tend%pni_rci(k)) * orho
1476 qrten(k) = qrten(k) + (tend%prr_wau(k) + tend%prr_rcw(k) + tend%prr_sml(k) + &
1477 tend%prr_gml(k) + tend%prr_rcs(k) + tend%prr_rcg(k) - tend%prg_rfz(k) - &
1478 tend%pri_rfz(k) - tend%prr_rci(k)) * orho
1480 nrten(k) = nrten(k) + (tend%pnr_wau(k) + tend%pnr_sml(k) + tend%pnr_gml(k) - &
1481 (tend%pnr_rfz(k) + tend%pnr_rcr(k) + tend%pnr_rcg(k) + tend%pnr_rcs(k) + &
1482 tend%pnr_rci(k) + tend%pni_rfz(k))) * orho
1484 qsten(k) = qsten(k) + (tend%prs_iau(k) + tend%prs_sde(k) + tend%prs_sci(k) + &
1485 tend%prs_scw(k) + tend%prs_rcs(k) + tend%prs_ide(k) - tend%prs_ihm(k) - &
1486 tend%prr_sml(k)) * orho
1488 qgten(k) = qgten(k) + (tend%prg_scw(k) + tend%prg_rfz(k) + tend%prg_gde(k) + &
1489 tend%prg_rcg(k) + tend%prg_gcw(k) + tend%prg_rci(k) + tend%prg_rcs(k) - &
1490 tend%prg_ihm(k) - tend%prr_gml(k)) * orho
1492 ngten(k) = ngten(k) + (tend%png_scw(k) + tend%png_rfz(k) - tend%png_rcg(k) + &
1493 tend%png_rci(k) + tend%png_rcs(k) + tend%png_gde(k) - tend%pnr_gml(k)) * orho
1495 qbten(k) = qbten(k) + (tend%pbg_scw(k) + tend%pbg_rfz(k) + tend%pbg_gcw(k) + &
1496 tend%pbg_rci(k) + tend%pbg_rcs(k) + tend%pbg_rcg(k) + tend%pbg_sml(k) - &
1497 tend%pbg_gml(k) + meters3_to_liters * (tend%prg_gde(k) - tend%prg_ihm(k)) / rho_g(idx(k))) * orho
1499 if (temp(k) < t0)
then
1500 tten(k) = tten(k) + &
1501 (lsub*ocp(k)*(tend%pri_inu(k) + tend%pri_ide(k) + &
1502 tend%prs_ide(k) + tend%prs_sde(k) + tend%prg_gde(k) + tend%pri_iha(k)) + &
1503 lfus2*ocp(k)*(tend%pri_wfz(k) + tend%pri_rfz(k) + tend%prg_rfz(k) + &
1504 tend%prs_scw(k) + tend%prg_scw(k) + tend%prg_gcw(k) + tend%prg_rcs(k) + &
1505 tend%prs_rcs(k) + tend%prr_rci(k) + tend%prg_rcg(k)))*orho
1507 tten(k) = tten(k) + &
1508 (lfus*ocp(k)*(-tend%prr_sml(k) - tend%prr_gml(k) - &
1509 tend%prr_rcg(k) - tend%prr_rcs(k)) + &
1510 lsub*ocp(k)*(tend%prs_sde(k) + tend%prg_gde(k)))*orho
1513 end subroutine sum_tendencies
1516 subroutine sedimentation(xr, vt, dz1d, rho, xten, limit, steps, ktop_sedi, precip, dt)
1519 use module_mp_tempo_params,
only : low_limit_mass_for_precip
1521 real(wp),
intent(in) :: dt
1522 integer,
intent(in) :: steps
1523 integer,
intent(in),
optional :: ktop_sedi
1524 real(wp),
dimension(:),
intent(inout) :: xr, xten
1525 real(wp),
dimension(:),
intent(in) :: dz1d, rho
1526 real(wp),
dimension(:),
intent(in) :: vt
1527 real(wp),
intent(in) :: limit
1528 real(wp),
intent(inout),
optional :: precip
1529 real(wp) :: odz, orho
1530 real(wp),
allocatable,
dimension(:) :: sed_r
1531 integer :: k, nz, ktop
1534 allocate(sed_r(nz), source=0._wp)
1536 if (
present(ktop_sedi)) ktop = ktop_sedi
1539 sed_r(k) = vt(k)*xr(k)
1544 xten(k) = xten(k) - sed_r(k)*odz*(1._wp/real(steps, kind=wp))*orho
1545 xr(k) = max(limit, xr(k) - sed_r(k)*odz*dt*(1._wp/real(steps, kind=wp)))
1550 xten(k) = xten(k) + (sed_r(k+1)-sed_r(k))*odz*(1._wp/real(steps, kind=wp))*orho
1551 xr(k) = max(limit, xr(k) + (sed_r(k+1)-sed_r(k))*odz*dt*(1._wp/real(steps, kind=wp)))
1554 if (
present(precip))
then
1555 if (xr(1) > low_limit_mass_for_precip)
then
1556 precip = precip + sed_r(1)*dt*(1._wp/real(steps, kind=wp))
1559 end subroutine sedimentation
1562 subroutine semilagrangian_sedimentation(dz1d, rho, xr, xten, vt, steps, limit, precip, dt, odt)
1569 real(wp),
intent(in) :: dt, odt
1570 integer,
intent(in) :: steps
1571 real(wp),
intent(in) :: limit
1572 real(wp),
dimension(:),
intent(in) :: dz1d, rho
1573 real(wp),
dimension(:),
intent(inout) :: xr, xten
1574 real(wp),
dimension(:),
intent(in) :: vt
1575 real(wp) :: fa1, fa2, con1, decfl, dip, dim, tl, th, tl2, th2, qqd, qqh, qql, zsum, qsum, &
1577 real(wp),
dimension(:),
allocatable :: zi, wi, za, dza, qa, qmi, qpi, net_flx, precip_flx, rr_save
1578 real(wp),
intent(out),
optional :: precip
1579 integer :: k, nz, kk, kb, kt, m
1582 allocate(zi(nz+1), source=0._wp)
1583 allocate(wi(nz+1), source=0._wp)
1584 allocate(dza(nz+1), source=0._wp)
1585 allocate(za(nz+2), source=0._wp)
1586 allocate(qa(nz+1), source=0._wp)
1587 allocate(qmi(nz+1), source=0._wp)
1588 allocate(qpi(nz+1), source=0._wp)
1589 allocate(net_flx(nz), source=0._wp)
1590 allocate(precip_flx(nz), source=0._wp)
1591 allocate(rr_save(nz), source=xr)
1595 zi(k+1) = zi(k) + dz1d(k)
1602 wi(2) = 0.5_wp*(vt(2)+vt(1))
1604 wi(k) = fa1*(vt(k)+vt(k-1))-fa2*(vt(k+1)+vt(k-2))
1606 wi(nz) = 0.5_wp*(vt(nz)+vt(nz-1))
1610 if(vt(k) == 0._wp) wi(k) = vt(k-1)
1617 decfl = (wi(k+1)-wi(k))*dt*(1._wp/real(steps, kind=wp))/dz1d(k)
1618 if(decfl > con1)
then
1619 wi(k) = wi(k+1) - con1*dz1d(k)*odt*real(steps, kind=wp)
1625 za(k) = zi(k) - wi(k)*dt*(1._wp/real(steps, kind=wp))
1629 dza(k) = za(k+1)-za(k)
1634 qa(k) = xr(k)*dz1d(k)/dza(k)
1640 dip=(qa(k+1)-qa(k))/(dza(k+1)+dza(k))
1641 dim=(qa(k)-qa(k-1))/(dza(k-1)+dza(k))
1642 if(dip*dim <= 0._wp)
then
1646 qpi(k)=qa(k)+0.5_wp*(dip+dim)*dza(k)
1647 qmi(k)=2._wp*qa(k)-qpi(k)
1648 if(qpi(k) > 0._wp .or. qmi(k) < 0._wp)
then
1656 qmi(nz+1) = qa(nz+1)
1657 qpi(nz+1) = qa(nz+1)
1666 if(zi(k) >= za(nz+1))
then
1669 find_kb :
do kk = kb, nz
1670 if(zi(k) <= za(kk+1))
then
1677 find_kt :
do kk = kt, nz+2
1678 if(zi(k+1) <= za(kk))
then
1689 tl = (zi(k)-za(kb))/dza(kb)
1690 th = (zi(k+1)-za(kb))/dza(kb)
1693 qqd = 0.5_wp*(qpi(kb)-qmi(kb))
1694 qqh = qqd*th2+qmi(kb)*th
1695 qql = qqd*tl2+qmi(kb)*tl
1696 xr(k) = (qqh-qql)/(th-tl)
1697 elseif(kt > kb)
then
1698 tl = (zi(k)-za(kb))/dza(kb)
1700 qqd = 0.5_wp*(qpi(kb)-qmi(kb))
1701 qql = qqd*tl2+qmi(kb)*tl
1703 zsum = (1._wp-tl)*dza(kb)
1707 zsum = zsum + dza(m)
1708 qsum = qsum + qa(m) * dza(m)
1711 th = (zi(k+1)-za(kt))/dza(kt)
1713 qqd = 0.5_wp*(qpi(kt)-qmi(kt))
1714 dqh = qqd*th2+qmi(kt)*th
1715 zsum = zsum + th*dza(kt)
1716 qsum = qsum + dqh*dza(kt)
1720 orho = 1._wp / rho(k)
1721 xr(k) = max(xr(k), limit)
1722 xten(k) = xten(k) + (xr(k) - rr_save(k)) * &
1726 precip_loop:
do k = 1, nz
1727 if(za(k) < 0._wp .and. za(k+1) <= 0.0_wp)
then
1728 if (
present(precip)) precip = precip + qa(k)*dza(k)
1729 net_flx(k) = qa(k)*dza(k)
1730 elseif (za(k) < 0._wp .and. za(k+1) > 0._wp)
then
1731 th = (0._wp-za(k))/dza(k)
1733 qqd = 0.5_wp*(qpi(k)-qmi(k))
1734 qqh = qqd*th2+qmi(k)*th
1735 if (
present(precip)) precip = precip + qqh*dza(k)
1736 net_flx(k) = qqh*dza(k)
1744 precip_flx(k) = net_flx(k)
1746 precip_flx(k) = precip_flx(k+1) + net_flx(k)
1749 end subroutine semilagrangian_sedimentation
1752 subroutine rain_fallspeed(rhof, l_qr, rr, ilamr, dz1d, vt, vtn, substeps_sedi, ktop_sedi, dt)
1755 use module_mp_tempo_params,
only : crg, av_r, org3, fv_r, cre
1757 real(wp),
intent(in) :: dt
1758 real(wp),
dimension(:),
intent(in) :: rhof, dz1d, rr
1759 real(dp),
dimension(:),
intent(in) :: ilamr
1760 logical,
dimension(:),
intent(in) :: l_qr
1761 real(wp),
dimension(:),
intent(inout) :: vt, vtn
1762 integer,
intent(out),
optional :: substeps_sedi, ktop_sedi
1763 real(wp) :: dz_by_vt
1768 if (
present(ktop_sedi)) ktop_sedi = 1
1769 if (
present(substeps_sedi)) substeps_sedi = 1
1771 if (rr(k) > r1)
then
1772 lamr = 1._dp / ilamr(k)
1773 vt(k) = rhof(k)*av_r*crg(6)*org3 * lamr**cre(3) *((lamr+fv_r)**(-cre(6)))
1774 vtn(k) = rhof(k)*av_r*crg(7)/crg(12) * lamr**cre(12)*((lamr+fv_r)**(-cre(7)))
1779 if (max(vt(k), vtn(k)) > 1.e-3_wp)
then
1780 if (
present(ktop_sedi)) ktop_sedi = max(ktop_sedi, k)
1781 dz_by_vt = dz1d(k) / (max(vt(k), vtn(k)))
1782 if (
present(substeps_sedi))
then
1783 substeps_sedi = max(substeps_sedi, int(dt/dz_by_vt + 1._wp))
1787 if (
present(ktop_sedi))
then
1788 if (ktop_sedi == nz) ktop_sedi = nz-1
1790 end subroutine rain_fallspeed
1793 subroutine graupel_fallspeed(rhof, rho, visco, l_qg, rg, rb, qb1d, idx, ilamg, &
1794 dz1d, vt, vtn, substeps_sedi, ktop_sedi, dt)
1797 use module_mp_tempo_params,
only : nrhg, rho_g, av_g_old, bv_g_old, &
1798 cgg, t0, mu_g, ogg2, ogg3, a_coeff, b_coeff, meters3_to_liters, earth_gravity
1800 real(wp),
intent(in) :: dt
1801 real(wp),
dimension(:),
intent(in) :: rhof, rho, visco, dz1d, rg, rb
1802 real(wp),
dimension(:),
intent(in),
optional :: qb1d
1803 real(dp),
dimension(:),
intent(in) :: ilamg
1804 logical,
dimension(:),
intent(in) :: l_qg
1805 integer,
dimension(:),
intent(in) :: idx
1806 real(wp),
dimension(:),
intent(inout) :: vt, vtn
1807 integer,
intent(out),
optional :: substeps_sedi, ktop_sedi
1808 real(wp) :: dz_by_vt, dens_g, afall, bfall
1812 if (
present(ktop_sedi)) ktop_sedi = 1
1813 if (
present(substeps_sedi)) substeps_sedi = 1
1815 if (rg(k) > r1)
then
1816 if (
present(qb1d))
then
1817 dens_g = max(rho_g(1), min(meters3_to_liters*rg(k)/rb(k), rho_g(nrhg)))
1818 afall = a_coeff*((4._wp*dens_g*earth_gravity)/(3._wp*rho(k)))**b_coeff
1819 afall = afall * visco(k)**(1._wp-2._wp*b_coeff)
1820 bfall = 3._wp*b_coeff - 1._wp
1825 vt(k) = rhof(k)*afall*cgg(6,idx(k))*ogg3 * ilamg(k)**bfall
1829 vtn(k) = rhof(k)*afall*cgg(7,idx(k))/cgg(12,idx(k)) * ilamg(k)**bfall
1831 vtn(k) = rhof(k)*afall*cgg(8,idx(k))*ogg2 * ilamg(k)**bfall
1837 if (vt(k) > 1.e-3_wp)
then
1838 if (
present(ktop_sedi)) ktop_sedi = max(ktop_sedi, k)
1839 dz_by_vt = dz1d(k) / vt(k)
1840 if (
present(substeps_sedi))
then
1841 substeps_sedi = max(substeps_sedi, int(dt/dz_by_vt + 1._wp))
1845 if (
present(ktop_sedi))
then
1846 if (ktop_sedi == nz) ktop_sedi = nz-1
1848 end subroutine graupel_fallspeed
1851 subroutine snow_fallspeed(rhof, l_qs, rs, prr_sml, smob, smoc, &
1852 rr, vtrr, dz1d, vt, vtboost, substeps_sedi, ktop_sedi, dt)
1855 use module_mp_tempo_params,
only : lam0, lam1, fv_s, kap0, kap1, mu_s, &
1858 real(wp),
intent(in) :: dt
1859 real(wp),
dimension(:),
intent(in) :: rhof, dz1d, rs, rr, vtboost
1860 real(wp),
dimension(:),
intent(in) :: vtrr
1861 logical,
dimension(:),
intent(in) :: l_qs
1862 real(wp),
dimension(:),
intent(inout) :: vt
1863 real(dp),
dimension(:),
intent(in) :: smob, smoc, prr_sml
1864 integer,
intent(out),
optional :: substeps_sedi, ktop_sedi
1865 real(wp) :: dz_by_vt, vts, sr
1866 real(dp) :: xds, mrat, ils1, ils2, t1_vts, t2_vts, t3_vts, t4_vts
1870 if (
present(ktop_sedi)) ktop_sedi = 1
1871 if (
present(substeps_sedi)) substeps_sedi = 1
1873 if (rs(k) > r1)
then
1874 xds = smoc(k) / smob(k)
1876 ils1 = 1._dp/(mrat*lam0 + fv_s)
1877 ils2 = 1._dp/(mrat*lam1 + fv_s)
1878 t1_vts = kap0*csg(4)*ils1**cse(4)
1879 t2_vts = kap1*mrat**mu_s*csg(10)*ils2**cse(10)
1880 ils1 = 1._dp/(mrat*lam0)
1881 ils2 = 1._dp/(mrat*lam1)
1882 t3_vts = kap0*csg(1)*ils1**cse(1)
1883 t4_vts = kap1*mrat**mu_s*csg(7)*ils2**cse(7)
1884 vts = rhof(k)*av_s * (t1_vts+t2_vts)/(t3_vts+t4_vts)
1886 if (prr_sml(k) > 0._dp)
then
1887 sr = rs(k)/(rs(k)+rr(k))
1888 vt(k) = vts*sr + (1._wp-sr)*vtrr(k)
1890 vt(k) = vts*vtboost(k)
1895 if (vt(k) > 1.e-3_wp)
then
1896 if (
present(ktop_sedi)) ktop_sedi = max(ktop_sedi, k)
1897 dz_by_vt = dz1d(k) / vt(k)
1898 if (
present(substeps_sedi))
then
1899 substeps_sedi = max(substeps_sedi, int(dt/dz_by_vt + 1._wp))
1903 if (
present(ktop_sedi))
then
1904 if (ktop_sedi == nz) ktop_sedi = nz-1
1906 end subroutine snow_fallspeed
1909 subroutine ice_fallspeed(rhof, l_qi, ri, ilami, dz1d, vt, vtn, &
1910 substeps_sedi, ktop_sedi, dt)
1913 use module_mp_tempo_params,
only : av_i, cig, oig2, bv_i
1915 real(wp),
intent(in) :: dt
1916 real(wp),
dimension(:),
intent(in) :: rhof, dz1d, ri
1917 real(dp),
dimension(:),
intent(in) :: ilami
1918 logical,
dimension(:),
intent(in) :: l_qi
1919 real(wp),
dimension(:),
intent(inout) :: vt, vtn
1920 integer,
intent(out) :: substeps_sedi, ktop_sedi
1921 real(wp) :: dz_by_vt
1928 if (ri(k) > r1)
then
1929 vt(k) = rhof(k)*av_i*cig(3)*oig2 * ilami(k)**bv_i
1930 vtn(k) = rhof(k)*av_i*cig(6)/cig(7) * ilami(k)**bv_i
1935 if (vt(k) > 1.e-3_wp)
then
1936 ktop_sedi = max(ktop_sedi, k)
1937 dz_by_vt = dz1d(k) / vt(k)
1938 substeps_sedi = max(substeps_sedi, int(dt/dz_by_vt + 1._wp))
1941 if (ktop_sedi == nz) ktop_sedi = nz-1
1942 end subroutine ice_fallspeed
1945 subroutine cloud_fallspeed(rhof, w1d, l_qc, rc, nc, ilamc, dz1d, vt, vtn, &
1949 use module_mp_tempo_params,
only : av_c, ccg, ocg1, ocg2, bv_c, r2
1951 real(wp),
dimension(:),
intent(in) :: rhof, w1d, dz1d, rc, nc
1952 real(dp),
dimension(:),
intent(in) :: ilamc
1953 logical,
dimension(:),
intent(in) :: l_qc
1954 real(wp),
dimension(:),
intent(inout) :: vt, vtn
1955 integer,
intent(out) :: ktop_sedi
1957 integer :: k, nz, nu_c
1964 hgt_loop :
do k = 1, nz-1
1965 if (rc(k) > r2) ktop_sedi = k
1967 if (hgt > 500._wp)
exit hgt_loop
1970 do k = ktop_sedi, 1, -1
1971 if (rc(k) > r1 .and. w1d(k) < 0.1_wp)
then
1972 nu_c = get_nuc(nc(k))
1973 vt(k) = rhof(k)*av_c*ccg(5,nu_c)*ocg2(nu_c) * ilamc(k)**bv_c
1974 vtn(k) = rhof(k)*av_c*ccg(4,nu_c)*ocg1(nu_c) * ilamc(k)**bv_c
1977 end subroutine cloud_fallspeed
1980 subroutine cloud_condensation(rho, temp, w1d, ssatw, lvap, tcond, diffu, lvt2, &
1981 nwfa1d, nwfa, ncsave, qv, qvs, l_qc, rc, nc, tend, dt, odt)
1983 use module_mp_tempo_params,
only : eps, r1, t0, orv, pi, rho_w, nbc, &
1984 tnc_wev, nt_c_min, nt_c_l
1986 real(wp),
intent(in) :: dt, odt
1987 type(ty_tend),
intent(inout) :: tend
1988 real(wp),
dimension(:),
intent(in) :: rho, temp, w1d, ssatw, lvap, tcond, diffu, lvt2, &
1989 nwfa, qv, qvs, rc, nc
1990 real(wp),
dimension(:),
intent(in),
optional :: nwfa1d, ncsave
1991 logical,
dimension(:),
intent(in) :: l_qc
1992 real(wp) :: clap, fcd, dfcd, xrc, xnc, orho, tempc, otemp, &
1993 rvs, rvs_p, rvs_pp, gamsc, alphsc, xsat, t1_evap
1995 integer :: k, nz, n, idx_d, idx_n, idx_c
1999 if (abs(ssatw(k)) < eps) cycle
2002 clap = (qv(k)-qvs(k))/(1._wp + lvt2(k)*qvs(k))
2004 fcd = qvs(k)*exp(lvt2(k)*clap) - qv(k) + clap
2005 dfcd = qvs(k)*lvt2(k)*exp(lvt2(k)*clap) + 1._wp
2006 clap = clap - fcd/dfcd
2008 xrc = rc(k) + clap*rho(k)
2013 tend%prw_vcd(k) = clap*odt
2015 if (clap > eps)
then
2016 if (
present(nwfa1d))
then
2017 xnc = max(nt_c_min, activate_cloud_number(temp(k), w1d(k), nwfa(k)))
2018 elseif (
present(ncsave))
then
2023 tend%pnc_wcd(k) = 0.5_wp*(xnc-nc(k) + abs(xnc-nc(k)))*odt*orho
2024 elseif (l_qc(k) .and. ssatw(k) < -1.e-6_wp .and. clap < -eps)
then
2025 tempc = temp(k) - t0
2026 otemp = 1._wp/temp(k)
2028 rvs_p = rvs*otemp*(lvap(k)*otemp*orv - 1._wp)
2029 rvs_pp = rvs * (otemp*(lvap(k)*otemp*orv - 1._wp) * &
2030 otemp*(lvap(k)*otemp*orv - 1._wp) + &
2031 (-2._wp*lvap(k)*otemp*otemp*otemp*orv) + otemp*otemp)
2032 gamsc = lvap(k)*diffu(k)/tcond(k) * rvs_p
2033 alphsc = 0.5_wp*(gamsc/(1._wp+gamsc))*(gamsc/(1._wp+gamsc)) * &
2034 rvs_pp/rvs_p * rvs/rvs_p
2035 alphsc = max(1.e-9_wp, alphsc)
2037 if (abs(xsat) < 1.e-9_wp) xsat = 0._wp
2038 t1_evap = 2._wp*pi*(1.0_wp - alphsc*xsat + 2._wp*alphsc*alphsc*xsat*xsat - &
2039 5._wp*alphsc*alphsc*alphsc*xsat*xsat*xsat) / (1._wp+gamsc)
2041 dc_star = sqrt(-2._dp*dt * t1_evap/(2._dp*pi) * &
2042 4._dp*diffu(k)*ssatw(k)*rvs/rho_w)
2043 idx_d = max(1, min(int(1.e6_wp*dc_star), nbc))
2044 call get_cloud_table_index(rc(k), nc(k), idx_c, idx_n)
2046 tend%prw_vcd(k) = max(real(-rc(k)*0.99_wp*orho*odt, kind=dp), &
2048 tend%pnc_wcd(k) = max(real(-nc(k)*0.99_wp*orho*odt, kind=dp), &
2049 -tnc_wev(idx_d, idx_c, idx_n)*orho*odt)
2052 tend%prw_vcd(k) = -rc(k)*orho*odt
2053 tend%pnc_wcd(k) = -nc(k)*orho*odt
2056 end subroutine cloud_condensation
2059 subroutine rain_evaporation(rho, temp, ssatw, lvap, tcond, diffu, &
2060 vsc2, rhof2, qv, qvs, l_qr, rr, nr, ilamr, tend, odt)
2063 use module_mp_tempo_params,
only : eps, r1, t0, orv, pi, rho_w, &
2064 org2, cre, t1_qr_ev, t2_qr_ev, fv_r
2066 real(wp),
intent(in) :: odt
2067 type(ty_tend),
intent(inout) :: tend
2068 real(wp),
dimension(:),
intent(in) :: rho, temp, ssatw, lvap, tcond, diffu, vsc2, rhof2, &
2070 logical,
dimension(:),
intent(in) :: l_qr
2071 real(dp),
dimension(:),
intent(in) :: ilamr
2072 real(wp) :: orho, tempc, otemp, &
2073 rvs, rvs_p, rvs_pp, gamsc, alphsc, xsat, t1_evap, rate_max, eva_factor
2074 real(dp) :: lamr, n0_r
2080 if ((ssatw(k) < -eps) .and. tend%prw_vcd(k) <= 0._dp)
then
2082 tempc = temp(k) - t0
2083 otemp = 1._wp/temp(k)
2085 rvs_p = rvs*otemp*(lvap(k)*otemp*orv - 1._wp)
2086 rvs_pp = rvs * (otemp*(lvap(k)*otemp*orv - 1._wp) * &
2087 otemp*(lvap(k)*otemp*orv - 1._wp) + &
2088 (-2._wp*lvap(k)*otemp*otemp*otemp*orv) + otemp*otemp)
2089 gamsc = lvap(k)*diffu(k)/tcond(k) * rvs_p
2090 alphsc = 0.5_wp*(gamsc/(1._wp+gamsc))*(gamsc/(1._wp+gamsc)) * &
2091 rvs_pp/rvs_p * rvs/rvs_p
2092 alphsc = max(1.e-9_wp, alphsc)
2093 xsat = min(-1.e-9_wp, ssatw(k))
2094 t1_evap = 2._wp*pi*(1.0_wp - alphsc*xsat + 2._wp*alphsc*alphsc*xsat*xsat - &
2095 5._wp*alphsc*alphsc*alphsc*xsat*xsat*xsat) / (1._wp+gamsc)
2100 if (qv(k)/qvs(k) < 0.95_wp .and. rr(k)*orho <= 1.e-8_wp)
then
2101 tend%prv_rev(k) = rr(k)*orho*odt
2103 lamr = 1._dp/ilamr(k)
2104 n0_r = nr(k)*org2*lamr**cre(2)
2105 tend%prv_rev(k) = t1_evap*diffu(k)*(-ssatw(k))*n0_r*rvs * &
2106 (t1_qr_ev*ilamr(k)**cre(10) + t2_qr_ev*vsc2(k)*rhof2(k)* &
2107 ((lamr+0.5*fv_r)**(-cre(11))))
2108 rate_max = min((rr(k)*orho*odt), &
2110 tend%prv_rev(k) = min(real(rate_max, kind=dp), tend%prv_rev(k)*orho)
2111 if (tend%prr_gml(k) > 0._dp)
then
2112 eva_factor = min(1._wp, 0.01_wp+(0.99_wp-0.01_wp)*(tempc/20._wp))
2113 tend%prv_rev(k) = tend%prv_rev(k)*eva_factor
2116 tend%pnr_rev(k) = min(real(nr(k)*0.99*orho*odt, kind=dp), &
2117 tend%prv_rev(k) * nr(k)/rr(k))
2121 end subroutine rain_evaporation
2124 subroutine freeze_cloud_melt_ice(temp, rho, ocp, lvap, qi1d, ni1d, qiten, niten, &
2125 qc1d, nc1d, qcten, ncten, tten, ncsave, dt, odt)
2127 use module_mp_tempo_params,
only : t0, lfus, lsub, hgfrz, nt_c_l
2129 real(wp),
intent(in) :: dt, odt
2130 real(wp),
dimension(:),
intent(in) :: temp, rho, ocp, lvap, qi1d, ni1d, qc1d
2131 real(wp),
dimension(:),
intent(inout) :: qiten, niten, qcten, ncten, tten
2132 real(wp),
dimension(:),
intent(in),
optional :: nc1d, ncsave
2133 real(wp) :: xri, xrc, lfus2, xnc
2139 xri = max(0._wp, qi1d(k)+qiten(k)*dt)
2140 if ((temp(k) > t0) .and. (xri > 0._wp))
then
2141 qcten(k) = qcten(k) + xri*odt
2142 ncten(k) = ncten(k) + ni1d(k)*odt
2143 qiten(k) = qiten(k) - xri*odt
2144 niten(k) = -ni1d(k)*odt
2145 tten(k) = tten(k) - lfus*ocp(k)*xri*odt
2148 xrc = max(0._wp, qc1d(k)+qcten(k)*dt)
2149 if ((temp(k) < hgfrz) .and. (xrc > 0._wp))
then
2150 lfus2 = lsub - lvap(k)
2151 if (
present(nc1d))
then
2152 xnc = nc1d(k) + ncten(k)*dt
2153 elseif (
present(ncsave))
then
2154 xnc = ncsave(k)/rho(k) + ncten(k)*dt
2156 xnc = nt_c_l/rho(k) + ncten(k)*dt
2158 qiten(k) = qiten(k) + xrc*odt
2159 niten(k) = niten(k) + xnc*odt
2160 qcten(k) = qcten(k) - xrc*odt
2161 ncten(k) = ncten(k) - xnc*odt
2162 tten(k) = tten(k) + lfus2*ocp(k)*xrc*odt
2165 end subroutine freeze_cloud_melt_ice
2168 function koop_nucleation(temp, satw, naero, dt)
result(nuc)
2173 use module_mp_tempo_params,
only : r_uni, ar_volume
2175 real(wp),
intent(in) :: temp, satw, naero, dt
2176 real(wp) :: xni, mu_diff, a_w_i, delta_aw, log_j_rate, j_rate, prob_h
2181 mu_diff = 210368._wp + (131.438_wp*temp) - &
2182 (3.32373e6_wp/temp) - (41729.1_wp*log(temp))
2183 a_w_i = exp(mu_diff/(r_uni*temp))
2184 delta_aw = satw - a_w_i
2186 log_j_rate = -906.7_wp + (8502._wp*delta_aw) - &
2187 (26924._wp*delta_aw*delta_aw) + (29180._wp*delta_aw*delta_aw*delta_aw)
2188 log_j_rate = min(20._wp, log_j_rate)
2189 j_rate = 10._wp**log_j_rate
2190 prob_h = min(1._wp-exp(-j_rate*ar_volume*dt), 1._wp)
2191 if (prob_h > 0._wp)
then
2192 xni = min(prob_h*naero, 1000.e3_wp)
2194 nuc = max(0._wp, xni)
2195 end function koop_nucleation
2198 function activate_cloud_number(temp, w1d, nwfa, land)
result(activ)
2200 use module_mp_tempo_params,
only : ta_na, ntb_arc, ta_ww, ntb_arw, &
2201 ta_tk, ntb_art, tnccn_act
2203 real(wp),
intent(in) :: temp, w1d, nwfa
2204 integer,
intent(in),
optional :: land
2205 real(wp) :: n_local, w_local
2206 real(wp) :: a, b, c, d, t, u, x1, x2, y1, y2, nx, wy, fraction
2207 real(wp) :: lower_lim_nuc_frac
2208 integer :: i, j, k, l, m, n
2212 n_local = nwfa * 1.e-6_wp
2213 if (n_local >= ta_na(ntb_arc))
then
2214 n_local = ta_na(ntb_arc) - 1.0_wp
2215 elseif (n_local <= ta_na(1))
then
2216 n_local = ta_na(1) + 1.0_wp
2218 nindex:
do n = 2, ntb_arc
2219 if (n_local >= ta_na(n-1) .and. n_local < ta_na(n))
exit nindex
2222 x1 = log(ta_na(i-1))
2227 if (w_local >= ta_ww(ntb_arw))
then
2228 w_local = ta_ww(ntb_arw) - 1.0_wp
2229 elseif (w_local <= ta_ww(1))
then
2230 w_local = ta_ww(1) + 0.001_wp
2232 windex:
do n = 2, ntb_arw
2233 if (w_local >= ta_ww(n-1) .and. w_local < ta_ww(n))
exit windex
2236 y1 = log(ta_ww(j-1))
2239 k = max(1, min(nint((temp - ta_tk(1))*0.1_wp) + 1, ntb_art))
2252 lower_lim_nuc_frac = 0.
2253 if (
present(land))
then
2255 lower_lim_nuc_frac = 0.
2256 elseif (land == 0)
then
2257 lower_lim_nuc_frac = 0.15
2259 lower_lim_nuc_frac = 0.15
2263 a = tnccn_act(i-1,j-1,k,l,m)
2264 b = tnccn_act(i,j-1,k,l,m)
2265 c = tnccn_act(i,j,k,l,m)
2266 d = tnccn_act(i-1,j,k,l,m)
2272 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
2273 fraction = max(fraction, lower_lim_nuc_frac)
2275 activ = nwfa*fraction
2276 end function activate_cloud_number
2279 subroutine warm_rain(rhof, l_qc, rc, nc, ilamc, mvd_c, l_qr, rr, nr, mvd_r, tend, odt)
2281 use module_mp_tempo_params,
only : d0r, d0c, r1, nbr, t_efrw, &
2282 t1_qr_qc, mu_r, am_r, ccg, obmr, ocg2, dr, org2, cre, fv_r, &
2285 real(wp),
intent(in) :: odt
2286 real(wp),
dimension(:),
intent(in) :: rhof, mvd_r, mvd_c, rr, nr, rc, nc
2287 real(dp),
dimension(:),
intent(in) :: ilamc
2288 logical,
dimension(:),
intent(in) :: l_qc, l_qr
2289 type(ty_tend),
intent(inout) :: tend
2291 real(dp) :: lamr, lamc, n0_r
2292 real(wp) :: ef_rr, dc_g, dc_b, xdc, zeta1, zeta, taud, tau, ef_rw
2293 integer :: k, nz, nu_c, idx
2303 if (mvd_r(k) > d0r)
then
2304 ef_rr = max(-0.1_wp, 1.0_wp - exp(2300.0_wp*(mvd_r(k)-1950.0e-6_wp)))
2305 tend%pnr_rcr(k) = ef_rr * 2.0_wp*nr(k)*rr(k)
2314 if (rc(k) > 0.01e-3_wp)
then
2315 nu_c = get_nuc(nc(k))
2316 lamc = 1._dp / ilamc(k)
2317 xdc = max(d0c*1.e6_wp, ((rc(k)/(am_r*nc(k)))**obmr) * 1.e6_wp)
2318 dc_g = ((ccg(3,nu_c)*ocg2(nu_c))**obmr / lamc) * 1.e6_wp
2319 dc_b = (xdc*xdc*xdc*dc_g*dc_g*dc_g - xdc*xdc*xdc*xdc*xdc*xdc) &
2321 zeta1 = 0.5_wp*((6.25e-6_wp*xdc*dc_b*dc_b*dc_b - 0.4_wp) &
2322 + abs(6.25e-6_wp*xdc*dc_b*dc_b*dc_b - 0.4_wp))
2323 zeta = 0.027_wp*rc(k)*zeta1
2324 taud = 0.5_wp*((0.5_wp*dc_b - 7.5_wp) + abs(0.5_wp*dc_b - 7.5_wp)) + r1
2325 tau = 3.72_wp/(rc(k)*taud)
2326 tend%prr_wau(k) = zeta/tau
2327 tend%prr_wau(k) = min(real(rc(k)*odt, kind=dp), &
2329 tend%pnr_wau(k) = tend%prr_wau(k) / (am_r*nu_c*autocon_nr_factor*d0r*d0r*d0r)
2330 tend%pnc_wau(k) = min(real(nc(k)*odt, kind=dp), &
2331 tend%prr_wau(k) / (am_r*mvd_c(k)*mvd_c(k)*mvd_c(k)))
2338 if (l_qr(k) .and. l_qc(k))
then
2339 if (mvd_r(k) > d0r .and. mvd_c(k) > d0c)
then
2340 lamr = (3.0_dp + mu_r + 0.672_dp) / mvd_r(k)
2341 idx = 1 + int(nbr*log(real(mvd_r(k)/dr(1), kind=dp)) / &
2342 log(real(dr(nbr)/dr(1), kind=dp)))
2344 ef_rw = t_efrw(idx, int(mvd_c(k)*1.e6_wp))
2345 n0_r = nr(k)*org2*lamr**cre(2)
2346 tend%prr_rcw(k) = rhof(k)*t1_qr_qc*ef_rw*rc(k)*n0_r * &
2347 ((lamr+fv_r)**(-cre(9)))
2348 tend%prr_rcw(k) = min(real(rc(k)*odt, kind=dp), tend%prr_rcw(k))
2349 tend%pnc_rcw(k) = rhof(k)*t1_qr_qc*ef_rw*nc(k)*n0_r * &
2350 ((lamr+fv_r)**(-cre(9)))
2351 tend%pnc_rcw(k) = min(real(nc(k)*odt, kind=dp), tend%pnc_rcw(k))
2355 end subroutine warm_rain
2358 subroutine riming(temp, rhof, visco, l_qc, rc, nc, ilamc, mvd_c, &
2359 l_qs, rs, smo0, smob, smoc, smoe, vtboost, l_qg, rg, ng, ilamg, idx, tend, odt)
2361 use module_mp_tempo_params,
only : d0c, d0s, nbs, ds, t_efsw, t1_qs_qc, &
2362 r_g, bm_g, mu_g, av_g, cgg, ogg3, bv_g, rho_w, t0, d0g, pi, cge, ogg2, &
2363 rime_threshold, rime_conversion, av_s, bv_s, rho_s, xm0i, eps, fv_s, &
2366 real(wp),
intent(in) :: odt
2367 type(ty_tend),
intent(inout) :: tend
2368 real(wp),
dimension(:),
intent(in) :: rhof, visco, temp, rc, nc, rs, rg, ng
2369 real(wp),
dimension(:),
intent(in) :: mvd_c
2370 real(dp),
dimension(:),
intent(in) :: smo0, smob, smoc, smoe, ilamg, ilamc
2371 logical,
dimension(:),
intent(in) :: l_qc, l_qs, l_qg
2372 integer,
dimension(:),
intent(in) :: idx
2373 real(wp),
dimension(:),
intent(out) :: vtboost
2375 real(dp) :: xds, xdg, n0_g, lamc
2376 real(wp) :: ef_sw, vtg, stoke_g, const_ri, tempc, rime_dens, ef_gw
2377 real(wp) :: t1_qg_qc, r_frac, g_frac, vts, tf, snow_dens_frac
2378 integer :: k, nz, idxs, nu_c
2382 tempc = temp(k) - t0
2384 if (l_qc(k) .and. l_qs(k))
then
2385 nu_c = get_nuc(nc(k))
2386 lamc = 1._dp / ilamc(k)
2387 xds = smoc(k) / smob(k)
2388 if ((mvd_c(k) > d0c) .and. (xds > d0s))
then
2391 idxs = 1 + int(nbs*log(real(xds/ds(1), kind=dp)) / log(real(ds(nbs)/ds(1), kind=dp)))
2392 idxs = min(idxs, nbs)
2393 ef_sw = t_efsw(idxs, int(mvd_c(k)*1.e6_wp))
2394 tend%prs_scw(k) = rhof(k)*t1_qs_qc*ef_sw*rc(k)*smoe(k)
2395 tend%prs_scw(k) = min(real(rc(k)*odt, kind=dp), tend%prs_scw(k))
2396 tend%pnc_scw(k) = rhof(k)*t1_qs_qc*ef_sw*nc(k)*smoe(k)
2397 tend%pnc_scw(k) = min(real(nc(k)*odt, kind=dp), tend%pnc_scw(k))
2403 if (temp(k) < t0)
then
2404 if (tend%prs_scw(k) > rime_threshold*tend%prs_sde(k) .and. &
2405 tend%prs_sde(k) > eps)
then
2406 r_frac = min(30.0_dp, tend%prs_scw(k)/tend%prs_sde(k))
2407 g_frac = min(rime_conversion, 0.15_wp + (r_frac-2._wp)*.028_wp)
2408 vtboost(k) = min(1.5_wp, 1.1_wp + (r_frac-2.)*.014_wp)
2409 tend%prg_scw(k) = g_frac*tend%prs_scw(k)
2410 tend%png_scw(k) = tend%prg_scw(k)*smo0(k)/rs(k)
2411 vts = av_s*xds**bv_s * exp(-fv_s*xds)
2412 const_ri = -1._wp*(mvd_c(k)*0.5e6_wp)*vts/min(-0.1_wp,tempc)
2413 const_ri = max(0.1_wp, min(const_ri, 10._wp))
2414 rime_dens = (0.051_wp + 0.114_wp*const_ri - 0.0055_wp*const_ri*const_ri)*1000._wp
2415 if(rime_dens < 150._wp)
then
2417 tend%prg_scw(k) = 0._dp
2418 tend%png_scw(k) = 0._dp
2420 snow_dens_frac = min(1._wp, max(0._wp, real(rs(k)*odt / &
2421 (rs(k)*odt + tend%prg_scw(k)), kind=wp)))
2422 tend%pbg_scw(k) = meters3_to_liters*tend%prg_scw(k) / &
2423 (rho_s * snow_dens_frac + rime_dens * (1._wp-snow_dens_frac))
2426 tend%prs_scw(k) = (1._wp - g_frac)*tend%prs_scw(k)
2432 if (l_qc(k) .and. l_qg(k))
then
2435 if (rg(k) >= r_g(1) .and. mvd_c(k) > d0c)
then
2436 xdg = (bm_g + mu_g + 1._wp) * ilamg(k)
2437 vtg = rhof(k)*av_g(idx(k))*cgg(6,idx(k))*ogg3 * ilamg(k)**bv_g(idx(k))
2438 stoke_g = mvd_c(k)*mvd_c(k)*vtg*rho_w/(9._wp*visco(k)*xdg)
2442 const_ri = -1._wp*(mvd_c(k)*0.5e6_wp)*vtg/min(-0.1_wp, tempc)
2443 const_ri = max(0.1_wp, min(const_ri, 10._wp))
2444 rime_dens = (0.051_wp + 0.114_wp*const_ri - 0.0055_wp*const_ri*const_ri)*1000._wp
2446 if (stoke_g >= 0.4_wp .and. stoke_g <= 10._wp)
then
2447 ef_gw = 0.55_wp*log10(2.51_wp*stoke_g)
2448 elseif (stoke_g < 0.4_wp)
then
2450 elseif (stoke_g > 10._wp)
then
2456 if (temp(k) > t0) ef_gw = ef_gw*0.1_wp
2457 t1_qg_qc = pi*.25_wp*av_g(idx(k)) * cgg(9,idx(k))
2458 n0_g = ng(k)*ogg2*(1._wp/ilamg(k))**cge(2,1)
2459 tend%prg_gcw(k) = rhof(k)*t1_qg_qc*ef_gw*rc(k)* &
2460 n0_g*ilamg(k)**cge(9,idx(k))
2461 tend%pnc_gcw(k) = rhof(k)*t1_qg_qc*ef_gw*nc(k)* &
2462 n0_g*ilamg(k)**cge(9,idx(k))
2463 tend%pnc_gcw(k) = min(real(nc(k)*odt, kind=dp), tend%pnc_gcw(k))
2464 if (temp(k) < t0) tend%pbg_gcw(k) = meters3_to_liters*tend%prg_gcw(k)/rime_dens
2466 if (temp(k) < t0)
then
2471 if (tend%prg_gcw(k) > eps .and. tempc > -8._wp)
then
2473 if (tempc >= -5._wp .and. tempc < -3._wp)
then
2474 tf = 0.5_wp*(-3.0_wp - tempc)
2475 elseif (tempc > -8._wp .and. tempc < -5._wp)
then
2476 tf = 0.33333333_wp*(8._wp + tempc)
2478 tend%pni_ihm(k) = 3.5e8_wp*tf*tend%prg_gcw(k)
2479 tend%pri_ihm(k) = xm0i*tend%pni_ihm(k)
2480 tend%prs_ihm(k) = tend%prs_scw(k)/(tend%prs_scw(k)+tend%prg_gcw(k)) * &
2482 tend%prg_ihm(k) = tend%prg_gcw(k)/(tend%prs_scw(k)+tend%prg_gcw(k)) * &
2490 end subroutine riming
2493 subroutine get_snow_table_index(rs, idx_s)
2495 use module_mp_tempo_params,
only : ntb_s, nis2
2497 real(wp),
intent(in) :: rs
2498 integer :: nis, nn, n
2499 integer,
intent(out) :: idx_s
2501 nis = nint(log10(rs))
2502 do_loop_rs:
do nn = nis-1, nis+1
2504 if ((rs/10._wp**nn) >= 1._wp .and. (rs/10._wp**nn) < 10._wp)
exit do_loop_rs
2506 idx_s = int(rs/10._wp**n) + 10*(n-nis2) - (n-nis2)
2507 idx_s = max(1, min(idx_s, ntb_s))
2508 end subroutine get_snow_table_index
2511 subroutine get_temperature_table_index(tempk, idx_t)
2513 use module_mp_tempo_params,
only : t0, ntb_t
2515 real(wp),
intent(in) :: tempk
2517 integer,
intent(out) :: idx_t
2520 idx_t = int((tempc-2.5_wp)/5._wp) - 1
2521 idx_t = max(1, -idx_t)
2522 idx_t = min(idx_t, ntb_t)
2523 end subroutine get_temperature_table_index
2526 subroutine get_rain_table_index(rr, ilamr, idx_r, idx_r1)
2528 use module_mp_tempo_params,
only : nir2, nir3, ntb_r, ntb_r1, &
2529 org2, org1, bm_r, am_r, crg, cre
2531 real(wp),
intent(in) :: rr
2532 real(dp),
intent(in) :: ilamr
2533 real(dp) :: lamr, lam_exp, n0_exp
2534 integer :: nir, nn, n
2535 integer,
intent(out) :: idx_r, idx_r1
2537 nir = nint(log10(rr))
2538 do_loop_rr:
do nn = nir-1, nir+1
2540 if ((rr/10._wp**nn) >= 1._wp .and. (rr/10._wp**nn) < 10._wp)
exit do_loop_rr
2542 idx_r = int(rr/10._wp**n) + 10*(n-nir2) - (n-nir2)
2543 idx_r = max(1, min(idx_r, ntb_r))
2546 lam_exp = lamr * (crg(3)*org2*org1)**bm_r
2547 n0_exp = org1*rr/am_r * lam_exp**cre(1)
2548 nir = nint(log10(real(n0_exp, kind=dp)))
2549 do_loop_nr:
do nn = nir-1, nir+1
2551 if ((n0_exp/10._wp**nn) >= 1._wp .and. (n0_exp/10._wp**nn) < 10._wp)
exit do_loop_nr
2553 idx_r1 = int(n0_exp/10._wp**n) + 10*(n-nir3) - (n-nir3)
2554 idx_r1 = max(1, min(idx_r1, ntb_r1))
2555 end subroutine get_rain_table_index
2558 subroutine get_graupel_table_index(rg, ilamg, idx, idx_g, idx_g1)
2560 use module_mp_tempo_params,
only : nig2, ntb_g, ntb_g1, ogg2, ogg1, &
2561 bm_g, cgg, ogg1, am_g, cge, nig3
2563 real(wp),
intent(in) :: rg
2564 real(dp),
intent(in) :: ilamg
2565 integer,
intent(in) :: idx
2566 real(dp) :: lamg, lam_exp, n0_exp
2567 integer :: nig, nn, n
2568 integer,
intent(out) :: idx_g, idx_g1
2570 nig = nint(log10(rg))
2571 do_loop_rg:
do nn = nig-1, nig+1
2573 if ( (rg/10._wp**nn) >= 1._wp .and. (rg/10._wp**nn).lt.10._wp)
exit do_loop_rg
2575 idx_g = int(rg/10._wp**n) + 10*(n-nig2) - (n-nig2)
2576 idx_g = max(1, min(idx_g, ntb_g))
2579 lam_exp = lamg * (cgg(3,1)*ogg2*ogg1)**bm_g
2580 n0_exp = ogg1*rg/am_g(idx) * lam_exp**cge(1,1)
2581 nig = nint(log10(real(n0_exp, kind=dp)))
2582 do_loop_ng:
do nn = nig-1, nig+1
2584 if ( (n0_exp/10._wp**nn) >= 1._wp .and. (n0_exp/10._wp**nn) < 10._wp)
exit do_loop_ng
2586 idx_g1 = int(n0_exp/10._wp**n) + 10*(n-nig3) - (n-nig3)
2587 idx_g1 = max(1, min(idx_g1, ntb_g1))
2588 end subroutine get_graupel_table_index
2591 subroutine get_cloud_table_index(rc, nc, idx_c, idx_n)
2593 use module_mp_tempo_params,
only : nbc, ntb_c, r_c, nic2, t_nc, nic1
2595 real(wp),
intent(in) :: rc, nc
2596 integer,
intent(out) :: idx_c, idx_n
2597 integer :: nic, nn, n
2599 nic = nint(log10(rc))
2600 do_loop_rc:
do nn = nic-1, nic+1
2602 if ( (rc/10._wp**nn) >= 1._wp .and. (rc/10._wp**nn) < 10._wp)
exit do_loop_rc
2604 idx_c = int(rc/10._wp**n) + 10*(n-nic2) - (n-nic2)
2605 idx_c = max(1, min(idx_c, ntb_c))
2607 idx_n = nint(1._wp + real(nbc, kind=wp) * log(real(nc/t_nc(1), kind=dp)) / nic1)
2608 idx_n = max(1, min(idx_n, nbc))
2609 end subroutine get_cloud_table_index
2612 subroutine get_ice_table_index(ri, ni, idx_i, idx_i1)
2614 use module_mp_tempo_params,
only : ntb_i, ntb_i1, nii2, nii3
2616 real(wp),
intent(in) :: ri, ni
2617 integer,
intent(out) :: idx_i, idx_i1
2618 integer :: nii, nn, n
2620 nii = nint(log10(ri))
2621 do_loop_ri:
do nn = nii-1, nii+1
2623 if ( (ri/10._wp**nn) >= 1._wp .and. (ri/10._wp**nn) < 10._wp)
exit do_loop_ri
2625 idx_i = int(ri/10._wp**n) + 10*(n-nii2) - (n-nii2)
2626 idx_i = max(1, min(idx_i, ntb_i))
2628 nii = nint(log10(ni))
2629 do_loop_ni:
do nn = nii-1, nii+1
2631 if ( (ni/10._wp**nn) >= 1._wp .and. (ni/10._wp**nn) < 10._wp)
exit do_loop_ni
2633 idx_i1 = int(ni/10._wp**n) + 10*(n-nii3) - (n-nii3)
2634 idx_i1 = max(1, min(idx_i1, ntb_i1))
2635 end subroutine get_ice_table_index
2638 subroutine rain_snow_rain_graupel(temp, l_qr, rr, nr, ilamr, l_qs, rs, &
2639 l_qg, rg, ng, ilamg, idx, tend, odt)
2641 use module_mp_tempo_params,
only : t0, r_r, r_s, r_g, rho_i, rho_g, meters3_to_liters, &
2642 tmr_racs2, tcr_sacr2, tmr_racs1, tcr_sacr1, tms_sacr1, tcs_racs1, &
2643 tnr_sacr1, tnr_sacr2, tnr_racs1, tnr_racs2, &
2644 tcr_gacr, tmr_racg, tcg_racg, tnr_gacr, tnr_racg
2646 real(wp),
intent(in) :: odt
2647 type(ty_tend),
intent(inout) :: tend
2648 real(wp),
dimension(:),
intent(in) :: temp, rr, rs, rg, nr, ng
2649 real(dp),
dimension(:),
intent(in) :: ilamr, ilamg
2650 logical,
dimension(:),
intent(in) :: l_qr, l_qs, l_qg
2651 integer,
dimension(:),
intent(in) :: idx
2652 integer :: k, nz, idx_r, idx_r1, idx_s, idx_t, &
2657 if (l_qr(k) .and. l_qs(k))
then
2658 if (rr(k) >= r_r(1) .and. rs(k) >= r_s(1))
then
2659 call get_temperature_table_index(temp(k), idx_t)
2660 call get_rain_table_index(rr(k), ilamr(k), idx_r, idx_r1)
2661 call get_snow_table_index(rs(k), idx_s)
2662 if (temp(k) < t0)
then
2663 tend%prr_rcs(k) = -(tmr_racs2(idx_s,idx_t,idx_r1,idx_r) &
2664 + tcr_sacr2(idx_s,idx_t,idx_r1,idx_r) &
2665 + tmr_racs1(idx_s,idx_t,idx_r1,idx_r) &
2666 + tcr_sacr1(idx_s,idx_t,idx_r1,idx_r))
2667 tend%prs_rcs(k) = tmr_racs2(idx_s,idx_t,idx_r1,idx_r) &
2668 + tcr_sacr2(idx_s,idx_t,idx_r1,idx_r) &
2669 - tcs_racs1(idx_s,idx_t,idx_r1,idx_r) &
2670 - tms_sacr1(idx_s,idx_t,idx_r1,idx_r)
2671 tend%prg_rcs(k) = tmr_racs1(idx_s,idx_t,idx_r1,idx_r) &
2672 + tcr_sacr1(idx_s,idx_t,idx_r1,idx_r) &
2673 + tcs_racs1(idx_s,idx_t,idx_r1,idx_r) &
2674 + tms_sacr1(idx_s,idx_t,idx_r1,idx_r)
2675 tend%prr_rcs(k) = max(real(-rr(k)*odt, kind=dp), tend%prr_rcs(k))
2676 tend%prs_rcs(k) = max(real(-rs(k)*odt, kind=dp), tend%prs_rcs(k))
2677 tend%prg_rcs(k) = min(real((rr(k)+rs(k))*odt, kind=dp), &
2679 tend%pnr_rcs(k) = tnr_racs1(idx_s,idx_t,idx_r1,idx_r) &
2680 + tnr_racs2(idx_s,idx_t,idx_r1,idx_r) &
2681 + tnr_sacr1(idx_s,idx_t,idx_r1,idx_r) &
2682 + tnr_sacr2(idx_s,idx_t,idx_r1,idx_r)
2683 tend%pnr_rcs(k) = min(real(nr(k)*odt, kind=dp), tend%pnr_rcs(k))
2684 tend%png_rcs(k) = tend%pnr_rcs(k)
2685 tend%pbg_rcs(k) = meters3_to_liters*tend%prg_rcs(k)/rho_i
2687 tend%prs_rcs(k) = -tcs_racs1(idx_s,idx_t,idx_r1,idx_r) &
2688 - tms_sacr1(idx_s,idx_t,idx_r1,idx_r) &
2689 + tmr_racs2(idx_s,idx_t,idx_r1,idx_r) &
2690 + tcr_sacr2(idx_s,idx_t,idx_r1,idx_r)
2691 tend%prs_rcs(k) = max(real(-rs(k)*odt, kind=dp), tend%prs_rcs(k))
2692 tend%prr_rcs(k) = -tend%prs_rcs(k)
2697 if (l_qr(k) .and. l_qg(k))
then
2698 if (rr(k) >= r_r(1) .and. rg(k) >= r_g(1))
then
2699 call get_temperature_table_index(temp(k), idx_t)
2700 call get_rain_table_index(rr(k), ilamr(k), idx_r, idx_r1)
2701 call get_graupel_table_index(rg(k), ilamg(k), idx(k), idx_g, idx_g1)
2702 if (temp(k) < t0)
then
2703 tend%prg_rcg(k) = tmr_racg(idx_g1,idx_g,idx(k),idx_r1,idx_r) &
2704 + tcr_gacr(idx_g1,idx_g,idx(k),idx_r1,idx_r)
2705 tend%prg_rcg(k) = min(real(rr(k)*odt, kind=dp), tend%prg_rcg(k))
2706 tend%prr_rcg(k) = -tend%prg_rcg(k)
2707 tend%pnr_rcg(k) = tnr_racg(idx_g1,idx_g,idx(k),idx_r1,idx_r) &
2708 + tnr_gacr(idx_g1,idx_g,idx(k),idx_r1,idx_r)
2709 tend%pnr_rcg(k) = min(real(nr(k)*odt, kind=dp), tend%pnr_rcg(k))
2710 tend%pbg_rcg(k) = meters3_to_liters*tend%prg_rcg(k)/rho_i
2712 tend%prr_rcg(k) = tcg_racg(idx_g1,idx_g,idx(k),idx_r1,idx_r)
2713 tend%prr_rcg(k) = min(real(rg(k)*odt, kind=dp), tend%prr_rcg(k))
2714 tend%prg_rcg(k) = -tend%prr_rcg(k)
2715 tend%png_rcg(k) = tnr_racg(idx_g1,idx_g,idx(k),idx_r1,idx_r)
2716 tend%png_rcg(k) = min(real(ng(k)*odt, kind=dp), tend%png_rcg(k))
2717 tend%pbg_rcg(k) = meters3_to_liters*tend%prg_rcg(k)/rho_g(idx(k))
2722 tend%pnr_rcg(k) = -1.5_wp*tnr_gacr(idx_g1,idx_g,idx(k),idx_r1,idx_r)
2727 end subroutine rain_snow_rain_graupel
2730 subroutine ice_nucleation(temp, rho, w1d, qv, qvsi, ssati, ssatw, &
2731 nwfa1d, nifa1d, nwfa, nifa, ni, smo0, rc, nc, rr, nr, ilamr, tend, dt, odt)
2733 use module_mp_tempo_params,
only : r_r, r_c, hgfrz, rho_i, xm0i, &
2734 tpg_qrfz, tpi_qrfz, tni_qrfz, tnr_qrfz, tpi_qcfz, tni_qcfz, &
2735 demott_nuc_ssati, eps, icenuc_max, tno, ato, max_ni, meters3_to_liters, &
2738 real(wp),
intent(in) :: dt, odt
2739 type(ty_tend),
intent(inout) :: tend
2740 real(wp),
dimension(:),
intent(in) :: qv, temp, rho, qvsi, rr, nr, rc, nc, w1d, &
2741 ssati, ssatw, ni, nwfa, nifa
2742 real(dp),
dimension(:),
intent(in) :: ilamr, smo0
2743 real(wp),
dimension(:),
intent(in),
optional :: nwfa1d, nifa1d
2744 real(wp) :: rate_max, tempc, xni, xnc
2745 integer :: k, nz, idx_in, idx_r, idx_r1, idx_tc, idx_c, idx_n
2749 if (temp(k) < t0)
then
2750 tempc = temp(k) - t0
2751 idx_tc = max(1, min(nint(-tempc), 45))
2752 rate_max = (qv(k)-qvsi(k))*rho(k)*odt*0.999_wp
2753 if (
present(nifa1d))
then
2754 xni = demott_nucleation(tempc, rho(k), nifa(k))
2756 xni = 1._wp * 1000._wp
2758 call get_in_table_index(xni, idx_in)
2763 if (rr(k) > r_r(1))
then
2764 call get_rain_table_index(rr(k), ilamr(k), idx_r, idx_r1)
2765 tend%prg_rfz(k) = tpg_qrfz(idx_r,idx_r1,idx_tc,idx_in)*odt
2766 tend%pri_rfz(k) = tpi_qrfz(idx_r,idx_r1,idx_tc,idx_in)*odt
2767 tend%pni_rfz(k) = tni_qrfz(idx_r,idx_r1,idx_tc,idx_in)*odt
2768 tend%pnr_rfz(k) = tnr_qrfz(idx_r,idx_r1,idx_tc,idx_in)*odt
2769 tend%prg_rfz(k) = min(real(rr(k)*odt, kind=dp), tend%prg_rfz(k))
2770 tend%pnr_rfz(k) = min(real(nr(k)*odt, kind=dp), tend%pnr_rfz(k))
2772 tend%png_rfz(k) = tend%pnr_rfz(k) * &
2773 max(min((10._wp**(-0.1_wp*w1d(k)) + 0.1_wp), 1._wp), 0.1_wp)
2775 elseif (rr(k) > r1 .and. temp(k) < hgfrz)
then
2776 tend%pri_rfz(k) = rr(k)*odt
2777 tend%pni_rfz(k) = nr(k)*odt
2779 tend%pbg_rfz(k) = meters3_to_liters*tend%prg_rfz(k)/rho_i
2781 if (rc(k) > r_c(1))
then
2782 call get_cloud_table_index(rc(k), nc(k), idx_c, idx_n)
2783 tend%pri_wfz(k) = tpi_qcfz(idx_c,idx_n,idx_tc,idx_in)*odt
2784 tend%pri_wfz(k) = min(real(rc(k)*odt, kind=dp), tend%pri_wfz(k))
2785 tend%pni_wfz(k) = tni_qcfz(idx_c,idx_n,idx_tc,idx_in)*odt
2786 tend%pni_wfz(k) = min(real(nc(k)*odt, kind=dp), &
2787 tend%pri_wfz(k)/(2.0_dp*xm0i), tend%pni_wfz(k))
2788 elseif (rc(k) > r1 .and. temp(k) < hgfrz)
then
2789 tend%pri_wfz(k) = rc(k)*odt
2790 tend%pni_wfz(k) = nc(k)*odt
2795 if ((ssati(k) >= demott_nuc_ssati) .or. (ssatw(k) > eps &
2796 .and. tempc < demott_nuc_tempc))
then
2797 if (
present(nifa1d))
then
2798 xnc = demott_nucleation(tempc, rho(k), nifa(k))
2800 xnc = min(icenuc_max, tno*exp(ato*(t0-temp(k))))
2802 xni = ni(k) + (tend%pni_rfz(k)+tend%pni_wfz(k))*dt
2803 tend%pni_inu(k) = 0.5_wp*(xnc-xni + abs(xnc-xni))*odt
2804 tend%pri_inu(k) = min(real(rate_max, kind=dp), xm0i*tend%pni_inu(k))
2805 tend%pni_inu(k) = tend%pri_inu(k)/xm0i
2809 xni = smo0(k)+ni(k) + (tend%pni_rfz(k)+tend%pni_wfz(k)+tend%pni_inu(k))*dt
2810 if (
present(nwfa1d))
then
2811 if ((xni <= max_ni) .and.(temp(k) < 238._wp) .and. (ssati(k) >= 0.4_wp))
then
2812 xnc = koop_nucleation(temp(k), ssatw(k), nwfa(k), dt)
2813 tend%pni_iha(k) = xnc*odt
2814 tend%pri_iha(k) = min(real(rate_max, kind=dp), xm0i*0.1_wp*tend%pni_iha(k))
2815 tend%pni_iha(k) = tend%pri_iha(k)/(xm0i*0.1_wp)
2820 end subroutine ice_nucleation
2823 function demott_nucleation(tempc, rho, nifa)
result(nuc)
2825 use module_mp_tempo_params,
only : rho_not0
2827 real(wp),
intent(in) :: tempc, rho, nifa
2828 real(wp) :: xni, nifa_cc
2832 nifa_cc = max(0.5_wp, nifa*rho_not0*1.e-6_wp/rho)
2833 xni = (5.94e-5_wp*(-tempc)**3.33_wp) * (nifa_cc**((-0.0264_wp*(tempc))+0.0033_wp))
2834 xni = xni*rho/rho_not0 * 1000._wp
2835 nuc = max(0._wp, xni)
2836 end function demott_nucleation
2839 subroutine get_in_table_index(xni, idx_in)
2841 use module_mp_tempo_params,
only : ntb_in, nt_in, niin2
2843 real(wp),
intent(in) :: xni
2844 integer,
intent(out) :: idx_in
2845 integer :: niin, nn, n
2847 if (xni > nt_in(1))
then
2848 niin = nint(log10(xni))
2849 do_loop_xni:
do nn = niin-1, niin+1
2851 if ( (xni/10._wp**nn) >= 1._wp .and. (xni/10._wp**nn) < 10._wp)
exit do_loop_xni
2853 idx_in = int(xni/10._wp**n) + 10*(n-niin2) - (n-niin2)
2854 idx_in = max(1, min(idx_in, ntb_in))
2858 end subroutine get_in_table_index
2861 subroutine get_t1_subl(rho, temp, qvsi, tcond, diffu, ssati, t1_subl)
2863 use module_mp_tempo_params,
only : t0, bm_i, mu_i, lsub, orv, &
2864 pi, c_sqrd, c_cube, d0s, ntb_i, r_s, ef_si, r_r, fv_r, ef_ri, &
2865 rho_i, eps, rho_w, rho_g
2867 real(wp),
dimension(:),
intent(in) :: rho, temp, qvsi, tcond, diffu, ssati
2868 real(wp) :: otemp, rvs, rvs_p, rvs_pp, gamsc, alphsc, xsat
2869 real(wp),
dimension(:),
intent(out) :: t1_subl
2874 otemp = 1._wp/temp(k)
2875 rvs = rho(k)*qvsi(k)
2876 rvs_p = rvs*otemp*(lsub*otemp*orv - 1._wp)
2877 rvs_pp = rvs * (otemp*(lsub*otemp*orv - 1._wp) * otemp*(lsub*otemp*orv - 1._wp) + &
2878 (-2.*lsub*otemp*otemp*otemp*orv) + otemp*otemp)
2879 gamsc = lsub*diffu(k)/tcond(k) * rvs_p
2880 alphsc = 0.5_wp*(gamsc/(1._wp+gamsc))*(gamsc/(1._wp+gamsc)) * &
2881 rvs_pp/rvs_p * rvs/rvs_p
2882 alphsc = max(1.e-9_wp, alphsc)
2884 if (abs(xsat) < 1.e-9_wp) xsat = 0._wp
2885 t1_subl(k) = 4._wp*pi*(1._wp - alphsc*xsat + 2._wp*alphsc*alphsc*xsat*xsat - &
2886 5._wp*alphsc*alphsc*alphsc*xsat*xsat*xsat) / (1._wp+gamsc)
2888 end subroutine get_t1_subl
2891 subroutine ice_processes(rhof, rhof2, rho, w1d, temp, qv, qvsi, tcond, diffu, &
2892 vsc2, ssati, l_qi, ri, ni, ilami, l_qs, rs, smoe, smof, smo1, rr, nr, ilamr, &
2893 mvd_r, l_qg, rg, ng, ilamg, idx, tend, odt)
2897 use module_mp_tempo_params,
only : t0, d0i, bm_i, mu_i, am_i, &
2898 c_sqrd, c_cube, oig1, cig, d0s, ntb_i, tpi_ide, tps_iaus, tni_iaus, &
2899 obmi, r_s, ef_si, t1_qs_qi, r_r, org2, cre, t1_qr_qi, t2_qr_qi, &
2900 fv_r, ef_ri, rho_i, t1_qs_sd, t2_qs_sd, eps, t1_qg_sd, &
2901 sc3, ogg2, cge, cgg, av_g, rho_w, rho_g
2903 real(wp),
intent(in) :: odt
2904 type(ty_tend),
intent(inout) :: tend
2905 logical,
dimension(:),
intent(in) :: l_qi, l_qs, l_qg
2906 real(wp),
dimension(:),
intent(in) :: rhof, rhof2, rho, w1d, ri, ni, rs, rr, nr, &
2907 temp, qv, qvsi, tcond, diffu, ssati, vsc2, mvd_r, rg, ng
2908 real(dp),
dimension(:),
intent(in) :: ilami, smoe, smof, smo1, ilamr, ilamg
2909 integer,
dimension(:),
intent(in) :: idx
2910 real(wp) :: xdi, xmi, oxmi, c_snow, rate_max, otemp, rvs, t2_qg_sd
2911 real(dp) :: lami, lamr, n0_r, n0_g
2912 integer :: k, nz, idx_i, idx_i1
2913 real(wp),
dimension(:),
allocatable :: t1_subl
2916 allocate(t1_subl(nz), source=0._wp)
2917 call get_t1_subl(rho, temp, qvsi, tcond, diffu, ssati, t1_subl)
2920 otemp = 1._wp/temp(k)
2921 rvs = rho(k)*qvsi(k)
2922 rate_max = (qv(k)-qvsi(k))*rho(k)*odt*0.999_wp
2924 if (temp(k) < t0)
then
2926 call get_ice_table_index(ri(k), ni(k), idx_i, idx_i1)
2927 lami = 1._dp/ilami(k)
2928 xdi = max(real(d0i, kind=dp), (bm_i + mu_i + 1.) * ilami(k))
2929 xmi = am_i*xdi**bm_i
2931 tend%pri_ide(k) = c_cube*t1_subl(k)*diffu(k)*ssati(k)*rvs &
2932 *oig1*cig(5)*ni(k)*ilami(k)
2933 if (tend%pri_ide(k) < 0._dp)
then
2934 tend%pri_ide(k) = max(real(-ri(k)*odt, kind=dp), &
2935 tend%pri_ide(k), real(rate_max, kind=dp))
2936 tend%pni_ide(k) = tend%pri_ide(k)*oxmi
2937 tend%pni_ide(k) = max(real(-ni(k)*odt, kind=dp), tend%pni_ide(k))
2939 tend%pri_ide(k) = min(tend%pri_ide(k), real(rate_max, kind=dp))
2940 tend%prs_ide(k) = (1.0_dp-tpi_ide(idx_i,idx_i1))*tend%pri_ide(k)
2941 tend%pri_ide(k) = tpi_ide(idx_i,idx_i1)*tend%pri_ide(k)
2945 if ((idx_i == ntb_i) .or. (xdi > 5.0_wp*d0s))
then
2946 tend%prs_iau(k) = ri(k)*.99_wp*odt
2947 tend%pni_iau(k) = ni(k)*.95_wp*odt
2948 elseif (xdi < 0.1_wp*d0s)
then
2949 tend%prs_iau(k) = 0._dp
2950 tend%pni_iau(k) = 0._dp
2952 tend%prs_iau(k) = tps_iaus(idx_i,idx_i1)*odt
2953 tend%prs_iau(k) = min(real(ri(k)*.99_wp*odt, kind=dp), tend%prs_iau(k))
2954 tend%pni_iau(k) = tni_iaus(idx_i,idx_i1)*odt
2955 tend%pni_iau(k) = min(real(ni(k)*.95_wp*odt, kind=dp), tend%pni_iau(k))
2959 lami = (am_i*cig(2)*oig1*ni(k)/ri(k))**obmi
2960 xdi = max(real(d0i, kind=dp), (bm_i + mu_i + 1.) * ilami(k))
2961 xmi = am_i*xdi**bm_i
2963 if (rs(k) >= r_s(1))
then
2964 tend%prs_sci(k) = t1_qs_qi*rhof(k)*ef_si*ri(k)*smoe(k)
2965 tend%pni_sci(k) = tend%prs_sci(k) * oxmi
2969 if (rr(k) >= r_r(1) .and. mvd_r(k) > 4._wp*xdi)
then
2970 lamr = 1._wp/ilamr(k)
2971 n0_r = nr(k)*org2*lamr**cre(2)
2972 tend%pri_rci(k) = rhof(k)*t1_qr_qi*ef_ri*ri(k)*n0_r * &
2973 ((lamr+fv_r)**(-cre(9)))
2974 tend%pnr_rci(k) = rhof(k)*t1_qr_qi*ef_ri*ni(k)*n0_r * &
2975 ((lamr+fv_r)**(-cre(9)))
2976 tend%pnr_rci(k) = min(real(nr(k)*odt, kind=dp), tend%pnr_rci(k))
2977 tend%png_rci(k) = tend%pnr_rci(k) * &
2978 max(min((10._wp**(-0.1*w1d(k)) + 0.1_wp), 1._wp), 0.1_wp)
2979 tend%pni_rci(k) = tend%pri_rci(k) * oxmi
2980 tend%prr_rci(k) = rhof(k)*t2_qr_qi*ef_ri*ni(k)*n0_r * &
2981 ((lamr+fv_r)**(-cre(8)))
2982 tend%prr_rci(k) = min(real(rr(k)*odt, kind=dp), tend%prr_rci(k))
2983 tend%prg_rci(k) = tend%pri_rci(k) + tend%prr_rci(k)
2984 tend%pbg_rci(k) = tend%prg_rci(k)/rho_i
2989 c_snow = c_sqrd + (temp(k)-t0+1.5_wp)*(c_cube-c_sqrd)/(-30._wp+1.5_wp)
2990 c_snow = max(c_sqrd, min(c_snow, c_cube))
2991 tend%prs_sde(k) = c_snow*t1_subl(k)*diffu(k)*ssati(k)*rvs * (t1_qs_sd*smo1(k) + &
2992 t2_qs_sd*rhof2(k)*vsc2(k)*smof(k))
2993 if (tend%prs_sde(k) < 0._dp)
then
2994 tend%prs_sde(k) = max(real(-rs(k)*odt, kind=dp), &
2995 tend%prs_sde(k), real(rate_max, kind=dp))
2997 tend%prs_sde(k) = min(tend%prs_sde(k), real(rate_max, kind=dp))
3001 if (ssati(k) < -eps)
then
3002 n0_g = ng(k)*ogg2*(1._wp/ilamg(k))**cge(2,1)
3003 t2_qg_sd = 0.28_wp*sc3*sqrt(av_g(idx(k))) * cgg(11,idx(k))
3004 tend%prg_gde(k) = c_cube*t1_subl(k)*diffu(k)*ssati(k)*rvs &
3005 * n0_g * (t1_qg_sd*ilamg(k)**cge(10,1) &
3006 + t2_qg_sd*vsc2(k)*rhof2(k)*ilamg(k)**cge(11,idx(k)))
3007 if (tend%prg_gde(k) < 0._wp)
then
3008 tend%prg_gde(k) = max(real(-rg(k)*odt, kind=dp), &
3009 tend%prg_gde(k), real(rate_max, kind=dp))
3010 tend%png_gde(k) = tend%prg_gde(k) * ng(k)/rg(k)
3012 tend%prg_gde(k) = min(tend%prg_gde(k), real(rate_max, kind=dp))
3018 end subroutine ice_processes
3021 subroutine melting(rhof2, rho, temp, qvsi, tcond, diffu, vsc2, ssati, &
3022 delqvs, l_qs, rs, smof, smo0, smo1, l_qg, rg, ng, ilamg, idx, tend, dt, odt)
3024 use module_mp_tempo_params,
only : t0, bm_i, mu_i, pi, c_sqrd, c_cube, d0s, &
3025 ntb_i, r_s, ef_si, r_r, fv_r, ef_ri, rho_i, t1_qs_sd, t2_qs_sd, eps, &
3026 t1_qg_sd, sc3, ogg2, cge, cgg, av_g, t1_qs_me, t2_qs_me, lvap0, olfus, &
3027 t1_qg_me, rho_w, rho_g, meters3_to_liters, timestep_conversion_rime_to_rain
3029 real(wp),
intent(in) :: dt, odt
3030 type(ty_tend),
intent(inout) :: tend
3031 logical,
dimension(:),
intent(in) :: l_qs, l_qg
3032 real(wp),
dimension(:),
intent(in) :: rhof2, rho, rs, &
3033 temp, qvsi, tcond, diffu, ssati, delqvs, vsc2, rg, ng
3034 real(dp),
dimension(:),
intent(in) :: smof, smo0, smo1, ilamg
3035 integer,
dimension(:),
intent(in) :: idx
3036 real(wp) :: tempc, otemp, rvs, melt_f, t2_qg_me, t2_qg_sd
3037 real(dp) :: n0_g, n0_melt, lamg
3039 real(wp),
dimension(:),
allocatable :: t1_subl
3042 allocate(t1_subl(nz), source=0._wp)
3043 call get_t1_subl(rho, temp, qvsi, tcond, diffu, ssati, t1_subl)
3046 otemp = 1._wp/temp(k)
3047 tempc = temp(k) - t0
3048 rvs = rho(k)*qvsi(k)
3050 if (temp(k) > t0)
then
3052 tend%prr_sml(k) = (tempc*tcond(k)-lvap0*diffu(k)*delqvs(k)) * &
3053 (t1_qs_me*smo1(k) + t2_qs_me*rhof2(k)*vsc2(k)*smof(k))
3055 if (tend%prr_sml(k) > 0._dp)
then
3056 tend%prr_sml(k) = tend%prr_sml(k) + 4218._wp*olfus*tempc * &
3057 (tend%prr_rcs(k)+tend%prs_scw(k))
3058 tend%prr_sml(k) = min(real(rs(k)*odt, kind=dp), &
3059 max(0._dp, tend%prr_sml(k)))
3060 tend%pnr_sml(k) = smo0(k)/rs(k)*tend%prr_sml(k) * 10.0_wp**(-0.25_wp*tempc)
3061 tend%pnr_sml(k) = min(real(smo0(k)*odt, kind=dp), tend%pnr_sml(k))
3063 tend%prr_sml(k) = 0._dp
3064 tend%pnr_sml(k) = 0._dp
3065 if (ssati(k) < 0._wp)
then
3066 tend%prs_sde(k) = c_cube*t1_subl(k)*diffu(k)*ssati(k)*rvs * &
3067 (t1_qs_sd*smo1(k) + t2_qs_sd*rhof2(k)*vsc2(k)*smof(k))
3068 tend%prs_sde(k) = max(real(-rs(k)*odt, kind=dp), tend%prs_sde(k))
3074 n0_g = ng(k)*ogg2*(1._wp/ilamg(k))**cge(2,1)
3075 n0_melt = ng(k)*ogg2*(1._dp/ilamg(k))**cge(2,1)
3076 if ((rg(k)*ng(k)) < 1.e-4_wp)
then
3078 n0_melt = (1.e-4_wp/rg(k))*ogg2*lamg**cge(2,1)
3080 t2_qg_me = pi*4._wp * c_cube*olfus * &
3081 0.28_wp*sc3*sqrt(av_g(idx(k))) * cgg(11,idx(k))
3082 tend%prr_gml(k) = (tempc*tcond(k)-lvap0*diffu(k)*delqvs(k)) * &
3083 n0_melt*(t1_qg_me*ilamg(k)**cge(10,1) + &
3084 t2_qg_me*rhof2(k)*vsc2(k)*ilamg(k)**cge(11,idx(k)))
3085 tend%prr_gml(k) = min(real(rg(k)*odt, kind=dp), max(0._dp, tend%prr_gml(k)))
3086 if (tend%prr_gml(k) > 0._dp)
then
3087 melt_f = max(0.05_wp, min(real(tend%prr_gml(k)*dt/rg(k), kind=wp),1._wp))
3089 tend%pbg_gml(k) = meters3_to_liters*tend%prr_gml(k) / &
3090 max(min(melt_f*rho_g(idx(k)), rho_w), 50._wp)
3091 tend%pnr_gml(k) = tend%prr_gml(k)*ng(k)/rg(k) * 10.0_wp**(-0.33_wp*(temp(k)-t0))
3093 tend%prr_gml(k) = 0._dp
3094 tend%pnr_gml(k) = 0._dp
3095 tend%pbg_gml(k) = 0._dp
3096 if (ssati(k) < 0._wp)
then
3097 t2_qg_sd = 0.28_wp*sc3*sqrt(av_g(idx(k))) * cgg(11,idx(k))
3098 tend%prg_gde(k) = c_cube*t1_subl(k)*diffu(k)*ssati(k)*rvs * n0_g * &
3099 (t1_qg_sd*ilamg(k)**cge(10,1) + &
3100 t2_qg_sd*vsc2(k)*rhof2(k)*ilamg(k)**cge(11,idx(k)))
3101 tend%prg_gde(k) = max(real(-rg(k)*odt, kind=dp), tend%prg_gde(k))
3102 tend%png_gde(k) = tend%prg_gde(k) * ng(k)/rg(k)
3112 if (dt > timestep_conversion_rime_to_rain)
then
3113 tend%prr_rcw(k) = tend%prr_rcw(k)+tend%prs_scw(k)+tend%prg_gcw(k)
3114 tend%prs_scw(k) = 0._dp
3115 tend%prg_gcw(k) = 0._dp
3119 end subroutine melting
3122 subroutine aerosol_scavenging(temp, rho, rhof, visco, nwfa, nifa, &
3123 l_qr, nr, ilamr, mvd_r, l_qs, rs, smob, smoc, smoe, &
3124 l_qg, rg, ng, ilamg, idx, tend, odt)
3126 use module_mp_tempo_params,
only : d0r, t1_qr_qc, fv_r, cre, &
3127 org2, r_s, t1_qs_qc, r_g, bm_g, mu_g, av_g, cge, cgg, pi, ogg2
3129 real(wp),
intent(in) :: odt
3130 real(wp),
dimension(:),
intent(in) :: temp, rho,rhof, visco, nr, mvd_r, &
3131 nwfa, nifa, rs, rg, ng
3132 real(dp),
dimension(:),
intent(in) :: smob, smoc, smoe, ilamg, ilamr
3133 integer,
dimension(:),
intent(in) :: idx
3134 logical,
dimension(:),
intent(in) :: l_qr, l_qs, l_qg
3135 type(ty_tend),
intent(inout) :: tend
3136 real(wp) :: ef_ra, ef_sa, ef_ga, t1_qg_qc
3137 real(dp) :: n0_r, xds, xdg, n0_g, lamr
3138 real(wp),
parameter :: wf_aerosol_size = 0.04e-6_wp
3139 real(wp),
parameter :: if_aerosol_size = 0.8e-6_wp
3144 if (l_qr(k) .and. mvd_r(k).gt. d0r)
then
3145 ef_ra = aerosol_collection_efficiency(real(mvd_r(k), kind=dp), &
3146 wf_aerosol_size, visco(k), rho(k), temp(k),
'r')
3147 lamr = 1._dp/ilamr(k)
3148 n0_r = nr(k)*org2*lamr**cre(2)
3149 tend%pna_rca(k) = rhof(k)*t1_qr_qc*ef_ra*nwfa(k)*n0_r * &
3150 ((lamr+fv_r)**(-cre(9)))
3151 tend%pna_rca(k) = min(real(nwfa(k)*odt, kind=dp), &
3153 ef_ra = aerosol_collection_efficiency(real(mvd_r(k), kind=dp), &
3154 if_aerosol_size, visco(k), rho(k), temp(k),
'r')
3155 tend%pnd_rcd(k) = rhof(k)*t1_qr_qc*ef_ra*nifa(k)*n0_r * &
3156 ((lamr+fv_r)**(-cre(9)))
3157 tend%pnd_rcd(k) = min(real(nifa(k)*odt, kind=dp), &
3161 if (l_qs(k) .and. rs(k) > r_s(1))
then
3162 xds = smoc(k) / smob(k)
3163 ef_sa = aerosol_collection_efficiency(xds,wf_aerosol_size, &
3164 visco(k), rho(k), temp(k),
's')
3165 tend%pna_sca(k) = rhof(k)*t1_qs_qc*ef_sa*nwfa(k)*smoe(k)
3166 tend%pna_sca(k) = min(real(nwfa(k)*odt, kind=dp), &
3168 ef_sa = aerosol_collection_efficiency(xds, if_aerosol_size, &
3169 visco(k), rho(k), temp(k),
's')
3170 tend%pnd_scd(k) = rhof(k)*t1_qs_qc*ef_sa*nifa(k)*smoe(k)
3171 tend%pnd_scd(k) = min(real(nifa(k)*odt, kind=dp), &
3175 if (l_qg(k) .and. rg(k) > r_g(1))
then
3176 xdg = (bm_g + mu_g + 1._dp) * ilamg(k)
3177 ef_ga = aerosol_collection_efficiency(xdg, wf_aerosol_size, &
3178 visco(k), rho(k), temp(k),
'g')
3179 t1_qg_qc = pi*.25_wp*av_g(idx(k)) * cgg(9,idx(k))
3180 n0_g = ng(k)*ogg2*(1._wp/ilamg(k))**cge(2,1)
3181 tend%pna_gca(k) = rhof(k)*t1_qg_qc*ef_ga*nwfa(k)*n0_g * &
3182 ilamg(k)**cge(9,idx(k))
3183 tend%pna_gca(k) = min(real(nwfa(k)*odt, kind=dp), &
3185 ef_ga = aerosol_collection_efficiency(xdg, if_aerosol_size, &
3186 visco(k), rho(k), temp(k),
'g')
3187 tend%pnd_gcd(k) = rhof(k)*t1_qg_qc*ef_ga*nifa(k)*n0_g * &
3188 ilamg(k)**cge(9,idx(k))
3189 tend%pnd_gcd(k) = min(real(nifa(k)*odt, kind=dp), &
3193 end subroutine aerosol_scavenging
3195end module module_mp_tempo_main