Skip to content

Commit b843f2d

Browse files
authored
add cloud terminal velocity for 2M based on Stokes regime fall speed and gamma size dist assumption (#626)
1 parent 7d30216 commit b843f2d

File tree

9 files changed

+184
-12
lines changed

9 files changed

+184
-12
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "CloudMicrophysics"
22
uuid = "6a9e3e04-43cd-43ba-94b9-e8782df3c71b"
33
authors = ["Climate Modeling Alliance"]
4-
version = "0.26.2"
4+
version = "0.26.3"
55

66
[deps]
77
ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c"

docs/src/API.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ Parameters.NumberAdjustmentHorn2012
353353
Parameters.Blk1MVelType
354354
Parameters.Blk1MVelTypeRain
355355
Parameters.Blk1MVelTypeSnow
356+
Parameters.StokesRegimeVelType
356357
Parameters.SB2006VelType
357358
Parameters.Chen2022VelType
358359
Parameters.Chen2022VelTypeSmallIce

docs/src/Microphysics2M.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ The cloud droplet number distribution, as a function of mass ``x`` [kg], is assu
7272
f_c(x) = A_c x^{ν_c} \exp\left(-B_c x^{μ_c} \right),
7373
\end{align}
7474
```
75-
We assume that ``ν_c`` and ``μ_c`` are fixed constants. Our default choice for these parameters are ``ν_c = 2`` and ``μ_c = 1``.
75+
We assume that ``ν_c`` and ``μ_c`` are fixed constants. Our default choice for these parameters are ``ν_c = 1`` and ``μ_c = 1``.
7676

7777
The free parameters for cloud droplets (``A_c``, ``B_c``) can be found analytically by integrating over the assumed
7878
mass distribution to find the prognostic variables
@@ -323,7 +323,7 @@ The default free parameter values are:
323323

324324
| symbol | default value |
325325
|------------|---------------|
326-
|``ν`` | ``2`` |
326+
|``ν`` | ``1`` |
327327
|``A`` | ``400`` |
328328
|``a`` | ``0.7`` |
329329
|``b`` | ``3`` |
@@ -566,7 +566,7 @@ The number- and mass-weighted terminal velocities for rain water are obtained by
566566
\overline{v}_{r,\, k} = \frac{1}{M_r^k} \int_0^\infty x^k f_r(x) v(x) dx,
567567
\end{equation}
568568
```
569-
where the superscript ``k`` indicates the moment number, with``k=0`` for number density and ``k=1`` for mass.
569+
where the superscript ``k`` indicates the moment number, with ``k=0`` for number density and ``k=1`` for mass.
570570

571571
The individual terminal velocity of particles is approximated by
572572
```math
@@ -622,6 +622,29 @@ include("plots/TerminalVelocity2M.jl")
622622
```
623623
![](2M_terminal_velocity_comparisons.svg)
624624

625+
For cloud liquid droplets in two-moment microphysics schemes, we use the analytical Stokes-regime expression for the terminal velocity of an individual spherical particle:
626+
```math
627+
v(r) = \frac{2}{9} \frac{(\rho_{water} - \rho_{air}) g}{\mu_{air}} r^2
628+
```
629+
with ``\mu_{air} = \rho_{air} \, \nu_{air}`` and assuming constant kinematic viscosity ``\nu_{air}`` in our parameterization.
630+
When droplet sizes follow a gamma distribution (as in Seifert & Beheng 2006), integrating this equation over the size spectrum yields the number- and mass-weighted mean terminal velocities:
631+
```math
632+
\begin{align*}
633+
\overline{v}_{c,\, k} = \frac{2}{9}\, \left(\frac{3}{4\, \pi\, \rho_{water}}\right)^{2/3}\, \left(\frac{\rho_{water}}{\rho_{air}}-1\right)\, \frac{g}{\nu_{air}}\, \frac{M_{k+2/3}}{M_k}
634+
\end{align*}
635+
```
636+
where
637+
- ``M_i`` is the ``i``-th moment of the droplet size distribution.
638+
- ``k`` is the weighting moment: ``k=0`` for number-mean velocity, ``k=1`` for mass-mean velocity.
639+
640+
For a gamma distribution with shape parameters ``\nu_c`` and ``\mu_c``, the mean terminal velocities can be written analytically as:
641+
```math
642+
\begin{align*}
643+
\overline{v}_{c,\, k} = \frac{\Gamma(\frac{k+2/3+\nu_c+1}{\mu_c})}{\Gamma(\frac{k+\nu_c+1}{\mu_c})}\left[\frac{\Gamma(\frac{\nu_c+1}{\mu_c})}{\Gamma(\frac{\nu_c+2}{\mu_c})}\right]^{2/3} v_{c,\, k}(\overline{r})
644+
\end{align*}
645+
```
646+
where ``v_{c,\, k}(\overline{r})`` is the fall speed of a particle with mean radius ``\overline{r}``.
647+
625648
For the Chen et al. [Chen2022](@cite) terminal velocity parameterization,
626649
the number- and mass-weighted group terminal velocities are:
627650
```math

docs/src/TerminalVelocity.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Terminal velocity
22

3-
`CloudMicrophysics.jl` offers three parameterizations of the relationship between
4-
particle size and terminal velocity:
3+
`CloudMicrophysics.jl` offers several parameterizations of the relationship between particle size and terminal velocity:
54
- A simple power-law used in the 1-moment microphysics scheme,
5+
- An analytical Stokes-regime formulation for cloud liquid droplets in two-moment microphysics,
66
- The rain terminal velocity used in Seifert and Beheng 2006 [SeifertBeheng2006](@cite),
77
- The rain and ice terminal velocities described in Chen et. al. 2022 [Chen2022](@cite).
88

@@ -15,8 +15,7 @@ The above terminal velocities need to be averaged over the assumed
1515
and use the power-law formulation when deriving process rates such as accretion.
1616
The Chen et al. [Chen2022](@cite) terminal velocity is available in 1-moment scheme
1717
for rain and snow, but without re-deriving other process rates.
18-
- The 2-moment scheme can be run with either the Seifert and Beheng [SeifertBeheng2006](@cite)
19-
or the Chen et al. [Chen2022](@cite) terminal velocity.
18+
- In the 2-moment scheme, for rain, the Seifert and Beheng [SeifertBeheng2006] (@cite) or the Chen et al. [Chen2022](@cite) parameterizations can be used. For cloud liquid droplets, we use the analytical Stokes-regime terminal velocity formulation.
2019
- The P3 scheme can only be run with the Chen et al. [Chen2022](@cite) terminal velocity
2120
and uses it when deriving the process rates.
2221
See the relevant sections in 1M, 2M, P3 and non-equilibrium microphysics documentation
@@ -70,6 +69,15 @@ The coefficients for the snow terminal velocity are empirical.
7069
|``v_0^{sno}`` | coefficient in ``v_{term}(r)`` for snow | ``\frac{m}{s}`` | ``2^{9/4} r_0^{1/4}`` | eq (6b) [Grabowski1998](@cite) |
7170
|``v_e^{sno}`` | exponent in ``v_{term}(r)`` for snow | - | ``0.25`` | eq (6b) [Grabowski1998](@cite) |
7271

72+
## Stokes-flow terminal velocity
73+
In the Stokes regime (`Re < 1`), the analytical fall speed of a spherical particle is given by
74+
```math
75+
v_{term}(r) = \frac{2}{9} \frac{(\rho_{water} - \rho_{air}) g}{\mu_{air}} r^2
76+
```
77+
where ``\mu_{air} = \rho_{air} \, \nu_{air}`` is the dynamic viscosity of air, and ``\nu_{air}`` is the kinematic viscosity. In general, ``\nu_{air}`` depends on temperature and pressure, but in our parameterization it is treated as a constant for simplicity.
78+
79+
In two-moment cloud microphysics parameterizations (e.g., Seifert & Beheng 2006), this expression can be integrated over a gamma droplet size distribution to obtain number-weighted and mass-weighted mean fall velocities of cloud droplets.
80+
7381
## Seifert and Beheng 2006
7482

7583
Seifert and Beheng [SeifertBeheng2006](@cite) uses an empirical relationship between the rain drop size

docs/src/plots/TerminalVelocity.jl

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const SB2006 = CMP.SB2006(FT)
2020
const SB2006_no_lim = CMP.SB2006(FT, false)
2121

2222
const Chen2022 = CMP.Chen2022VelType(FT)
23+
const STVel = CMP.StokesRegimeVelType(FT)
2324
const SB2006Vel = CMP.SB2006VelType(FT)
2425
const Blk1MVel = CMP.Blk1MVelType(FT)
2526

@@ -122,11 +123,14 @@ end
122123
D_r_range = range(1e-6, stop = 6e-3, length = 1000)
123124
D_r_range_small = range(0.1 * 1e-6, stop = 100 * 1e-6, length = 1000)
124125
q_range = range(0, stop = 5 * 1e-3, length = 100)
126+
N_liq = 500e6
125127

126128
#! format: off
127129
# velocity values for cloud particle sizes
128130
v_term_rain = CMO.particle_terminal_velocity(Chen2022.rain, ρ_air)
129131
v_term_small_ice = CMO.particle_terminal_velocity(Chen2022.small_ice, ρ_air, ice.ρᵢ)
132+
v_term_stokes = CMO.particle_terminal_velocity(STVel, ρ_air)
133+
ST_cloud_small = v_term_stokes.(D_r_range_small)
130134
SB_rain_small = [rain_terminal_velocity_individual_SB(SB2006Vel, ρ_air, D_r) for D_r in D_r_range_small]
131135
M1_rain_small = [terminal_velocity_individual_1M(Blk1MVel.rain, ρ_air, D_r) for D_r in D_r_range_small]
132136
M1_snow_small = [terminal_velocity_individual_1M(Blk1MVel.snow, ρ_air, D_r) for D_r in D_r_range_small]
@@ -137,6 +141,7 @@ Ch_snow_small = [snow_terminal_velocity_individual_Chen(snow, Chen2022.large_ice
137141
Ch_snow_small_oblate = [snow_terminal_velocity_individual_Chen_oblate(snow, Chen2022.large_ice, ρ_air, D_r) for D_r in D_r_range_small]
138142
Ch_snow_small_prolate = [snow_terminal_velocity_individual_Chen_prolate(snow, Chen2022.large_ice, ρ_air, D_r) for D_r in D_r_range_small]
139143
# velocity values for precip particle sizes
144+
ST_cloud = v_term_stokes.(D_r_range)
140145
SB_rain = [rain_terminal_velocity_individual_SB(SB2006Vel, ρ_air, D_r) for D_r in D_r_range]
141146
M1_rain = [terminal_velocity_individual_1M(Blk1MVel.rain, ρ_air, D_r) for D_r in D_r_range]
142147
M1_snow = [terminal_velocity_individual_1M(Blk1MVel.snow, ρ_air, D_r) for D_r in D_r_range]
@@ -165,13 +170,16 @@ bCh_rain = [CM1.terminal_velocity(rain, Chen2022.rain, ρ_air, q) for q in q
165170
bCh_snow = [CM1.terminal_velocity(snow, Chen2022.large_ice, ρ_air, q) for q in q_range]
166171
bCh_snow_oblate = [CM1.terminal_velocity(snow, Chen2022.large_ice, ρ_air, q, oblate) for q in q_range]
167172
bCh_snow_prolate = [CM1.terminal_velocity(snow, Chen2022.large_ice, ρ_air, q, prolate) for q in q_range]
173+
bSt_N_liq = [CM2.cloud_terminal_velocity(SB2006.pdf_c, STVel, q, ρ_air, N_liq)[1] for q in q_range]
174+
bSt_liq = [CM2.cloud_terminal_velocity(SB2006.pdf_c, STVel, q, ρ_air, N_liq)[2] for q in q_range]
168175
bCh_liq = [CMNe.terminal_velocity(liquid, Chen2022.rain, ρ_air, q) for q in q_range]
169176
bCh_ice = [CMNe.terminal_velocity(ice, Chen2022.small_ice, ρ_air, q) for q in q_range]
170177

171178
# individual particle comparison - cloud size range
172179
p1 = PL.scatter(D_Gunn_Kinzer_small * 1e6, u_Gunn_Kinzer_small * 1e2, ms = 3, color = 4, label = "Gunn and Kinzer (1949)")
173180
p1 = PL.plot!(D_r_range_small * 1e6, M1_rain_small * 1e2, linewidth = 3, xlabel = "D [um]", ylabel = "terminal velocity [cm/s]", label = "Rain 1M", color = :skyblue1, margin=10mm)
174181
p1 = PL.plot!(D_r_range_small * 1e6, M1_snow_small * 1e2, linewidth = 3, xlabel = "D [um]", ylabel = "terminal velocity [cm/s]", label = "Snow 1M", color = :plum)
182+
p1 = PL.plot!(D_r_range_small * 1e6, ST_cloud_small * 1e2, linewidth = 3, xlabel = "D [um]", ylabel = "terminal velocity [cm/s]", label = "Stokes", color = :cadetblue, style = :dash)
175183
p1 = PL.plot!(D_r_range_small * 1e6, SB_rain_small * 1e2, linewidth = 3, xlabel = "D [um]", ylabel = "terminal velocity [cm/s]", label = "Rain SB", color = :cadetblue)
176184
p1 = PL.plot!(D_r_range_small * 1e6, Ch_rain_small * 1e2, linewidth = 3, xlabel = "D [um]", ylabel = "terminal velocity [cm/s]", label = "Rain Chen", color = :blue)
177185
p1 = PL.plot!(D_r_range_small * 1e6, Ch_snow_small * 1e2, linewidth = 3, xlabel = "D [um]", ylabel = "terminal velocity [cm/s]", label = "Snow Chen", color = :darkviolet)
@@ -182,18 +190,22 @@ p1 = PL.plot!(D_r_range_small * 1e6, Ch_ice_small * 1e2, linewidth = 3, xlabel
182190
p2 = PL.scatter(D_Gunn_Kinzer * 1e3, u_Gunn_Kinzer, ms = 3, color = 4, legend=false)
183191
p2 = PL.plot!(D_r_range * 1e3, M1_rain, linewidth = 3, xlabel = "D [mm]", ylabel = "terminal velocity [m/s]", legend=false, color = :skyblue1)
184192
p2 = PL.plot!(D_r_range * 1e3, M1_snow, linewidth = 3, xlabel = "D [mm]", ylabel = "terminal velocity [m/s]", legend=false, color = :plum)
193+
p2 = PL.plot!(D_r_range * 1e3, ST_cloud, linewidth = 3, xlabel = "D [um]", ylabel = "terminal velocity [m/s]", legend=false, color = :cadetblue, style = :dash)
185194
p2 = PL.plot!(D_r_range * 1e3, SB_rain, linewidth = 3, xlabel = "D [um]", ylabel = "terminal velocity [m/s]", legend=false, color = :cadetblue)
186195
p2 = PL.plot!(D_r_range * 1e3, Ch_rain, linewidth = 3, xlabel = "D [mm]", ylabel = "terminal velocity [m/s]", legend=false, color = :blue)
187196
p2 = PL.plot!(D_r_range * 1e3, Ch_snow, linewidth = 3, xlabel = "D [mm]", ylabel = "terminal velocity [m/s]", legend=false, color = :darkviolet)
188197
p2 = PL.plot!(D_r_range * 1e3, Ch_snow_oblate, linewidth = 3, xlabel = "D [mm]", ylabel = "terminal velocity [m/s]", legend=false, color = :darkviolet, style = :dash)
189198
p2 = PL.plot!(D_r_range * 1e3, Ch_snow_prolate, linewidth = 3, xlabel = "D [mm]", ylabel = "terminal velocity [m/s]", legend=false, color = :darkviolet, style = :dot)
190199
p2 = PL.plot!(D_r_range * 1e3, Ch_ice, linewidth = 3, xlabel = "D [mm]", ylabel = "terminal velocity [m/s]", legend=false, color = :orange)
200+
p2 = PL.plot!(ylim=(-1.0, 11.0))
191201
# snow aspect ratio
192202
p3 = PL.plot(D_r_range * 1e3, Aspect_Ratio_oblate, linewidth = 3, xlabel = "D [mm]", ylabel = "aspect ratio", label = "Snow aspect ratio oblate", color = :darkviolet, ylim = (0, 100), style = :dash)
193203
p3 = PL.plot!(D_r_range * 1e3, Aspect_Ratio_prolate, linewidth = 3, xlabel = "D [mm]", ylabel = "aspect ratio", label = "Snow aspect ratio prolate", color = :darkviolet, style = :dot)
194204
# group velocity comparison
195-
p4 = PL.plot(q_range * 1e3, bCh_liq * 100, linewidth = 3, xlabel = "q [g/kg]", ylabel = "terminal velocity [cm/s]", color = :green, label="Liq Chen", margin=10mm)
196-
p4 = PL.plot!(q_range * 1e3, bCh_ice * 100, linewidth = 3, xlabel = "q [g/kg]", ylabel = "terminal velocity [cm/s]", color = :orange, label="Ice Chen")
205+
p4 = PL.plot(q_range * 1e3, bSt_liq * 100, linewidth = 3, xlabel = "q [g/kg]", ylabel = "terminal velocity [cm/s]", color = :cadetblue, label="Liq Stokes", margin=10mm)
206+
p4 = PL.plot!(q_range * 1e3, bSt_N_liq * 100, linewidth = 3, xlabel = "q [g/kg]", ylabel = "terminal velocity [cm/s]", color = :cadetblue, style = :dash, label="Liq Num Stokes")
207+
p4 = PL.plot!(q_range * 1e3, bCh_liq * 100, linewidth = 3, xlabel = "q [g/kg]", ylabel = "terminal velocity [cm/s]", color = :orange, label="Liq Chen")
208+
p4 = PL.plot!(q_range * 1e3, bCh_ice * 100, linewidth = 3, xlabel = "q [g/kg]", ylabel = "terminal velocity [cm/s]", color = :blue, label="Ice Chen")
197209

198210
p5 = PL.plot(q_range * 1e3, bM1_rain, linewidth = 3, xlabel = "q [g/kg]", ylabel = "terminal velocity [m/s]", color = :skyblue1, label="Rain 1M")
199211
p5 = PL.plot!(q_range * 1e3, bM1_snow, linewidth = 3, xlabel = "q [g/kg]", ylabel = "terminal velocity [m/s]", color = :plum, label="Snow 1M")

src/Common.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,22 @@ function particle_terminal_velocity(velocity_params::CMP.TerminalVelocityType,
341341
return v_term
342342
end
343343

344+
"""
345+
particle_terminal_velocity(velocity_params::CMP.StokesRegimeVelType{FT}, ρ::FT)
346+
347+
- `velocity_params` - set with free parameters
348+
- `ρ` - air density
349+
350+
Returns a function `v_term(D)` that computes the analytical fall speed of a cloud droplet as a function of
351+
its size (diameter, `D`) in the Stokes regime (Re < 1)
352+
"""
353+
function particle_terminal_velocity(vel::CMP.StokesRegimeVelType, ρ)
354+
(; ρw, grav, ν_air) = vel
355+
FT = eltype(ρ)
356+
terminal_velocity_prefactor = FT(1 / 18) * (ρw / ρ - 1) * grav / ν_air
357+
v_term(D) = terminal_velocity_prefactor * D^2
358+
return v_term
359+
end
344360

345361
"""
346362
volume_sphere_D(D)

src/Microphysics2M.jl

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,49 @@ function rain_self_collection_and_breakup(
598598
return (; sc, br)
599599
end
600600

601+
"""
602+
cloud_terminal_velocity(pdf_c, vel_params, q_liq, ρₐ, N_liq)
603+
604+
Compute the number-averaged and mass-averaged terminal velocities of cloud droplets
605+
assuming a gamma size distribution for droplet mass and the analytical Stokes-regime terminal
606+
velocity of spherical particles.
607+
608+
# Arguments
609+
- `pdf_c`: Cloud droplet size distribution parameters, [`CMP.CloudParticlePDF_SB2006`](@ref).
610+
- `vel_params`: Terminal velocity parameters, [`CMP.StokesRegimeVelType`](@ref).
611+
- `q_liq`: Cloud liquid water specific content [kg kg⁻¹].
612+
- `ρₐ`: Air density [kg m⁻³].
613+
- `N_liq`: Cloud droplet number concentration [m⁻³].
614+
615+
# Returns
616+
A tuple containing the number- and mass-weighted mean fall velocities of cloud droplets in [m/s].
617+
Individual droplet terminal velocities follow v_{term}(D) = (1/18) (ρw - ρₐ) g D^2 / μ_air with
618+
μ_air = ρₐ * ν_air and assuming constant ν_air.
619+
"""
620+
function cloud_terminal_velocity(
621+
pdf_c::CMP.CloudParticlePDF_SB2006{FT},
622+
(; ρw, grav, ν_air)::CMP.StokesRegimeVelType{FT},
623+
q_liq, ρₐ, N_liq,
624+
) where {FT}
625+
626+
(; νc, μc) = pdf_c
627+
(; Bc) = pdf_cloud_parameters_mass(pdf_c, q_liq, ρₐ, N_liq)
628+
629+
terminal_velocity_prefactor = FT(1 / 18) * (6 / pi / ρw)^(2 / 3) * (ρw / ρₐ - 1) * grav / ν_air
630+
vt0 =
631+
N_liq < eps(FT) ? FT(0) :
632+
terminal_velocity_prefactor * DT.generalized_gamma_Mⁿ(νc, μc, Bc, N_liq, FT(2 / 3)) / N_liq
633+
vt1 =
634+
q_liq < eps(FT) ? FT(0) :
635+
terminal_velocity_prefactor * DT.generalized_gamma_Mⁿ(νc, μc, Bc, N_liq, FT(5 / 3)) / ρₐ / q_liq
636+
637+
if q_liq >= 5e-3
638+
@show terminal_velocity_prefactor, vt0, vt1
639+
end
640+
return (vt0, vt1)
641+
642+
end
643+
601644
"""
602645
rain_terminal_velocity(SB2006, vel, q_rai, ρ, N_rai)
603646

src/parameters/TerminalVelocity.jl

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export Blk1MVelType, SB2006VelType, Chen2022VelType
1+
export Blk1MVelType, StokesRegimeVelType, SB2006VelType, Chen2022VelType
22

33
"""
44
Blk1MVelTypeRain
@@ -101,12 +101,38 @@ function Blk1MVelType(toml_dict::CP.AbstractTOMLDict)
101101
return Blk1MVelType{FT, typeof(rain), typeof(snow)}(rain, snow)
102102
end
103103

104+
"""
105+
StokesRegimeVelType
106+
107+
The type for precipitation terminal velocity in the Stokes regime (Re < 1)
108+
109+
# Fields
110+
$(DocStringExtensions.FIELDS)
111+
"""
112+
Base.@kwdef struct StokesRegimeVelType{FT} <: TerminalVelocityType{FT}
113+
ρw::FT
114+
ν_air::FT
115+
grav::FT
116+
end
117+
118+
StokesRegimeVelType(::Type{FT}) where {FT <: AbstractFloat} =
119+
StokesRegimeVelType(CP.create_toml_dict(FT))
120+
121+
function StokesRegimeVelType(td::CP.AbstractTOMLDict)
122+
name_map = (;
123+
:density_liquid_water => :ρw,
124+
:kinematic_viscosity_of_air => :ν_air,
125+
:gravitational_acceleration => :grav,
126+
)
127+
parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics")
128+
FT = CP.float_type(td)
129+
return StokesRegimeVelType{FT}(; parameters...)
130+
end
104131

105132
"""
106133
SB2006VelType
107134
108135
The type for precipitation terminal velocity from Seifert and Beheng 2006
109-
(Defined only for rain)
110136
111137
# Fields
112138
$(DocStringExtensions.FIELDS)
@@ -116,6 +142,9 @@ Base.@kwdef struct SB2006VelType{FT} <: TerminalVelocityType{FT}
116142
aR::FT
117143
bR::FT
118144
cR::FT
145+
ρw::FT
146+
ν_air::FT
147+
grav::FT
119148
end
120149

121150
SB2006VelType(::Type{FT}) where {FT <: AbstractFloat} =
@@ -127,6 +156,9 @@ function SB2006VelType(td::CP.AbstractTOMLDict)
127156
:SB2006_raindrops_terminal_velocity_coeff_aR => :aR,
128157
:SB2006_raindrops_terminal_velocity_coeff_bR => :bR,
129158
:SB2006_raindrops_terminal_velocity_coeff_cR => :cR,
159+
:density_liquid_water => :ρw,
160+
:kinematic_viscosity_of_air => :ν_air,
161+
:gravitational_acceleration => :grav,
130162
)
131163
parameters = CP.get_parameter_values(td, name_map, "CloudMicrophysics")
132164
FT = CP.float_type(td)

test/microphysics2M_tests.jl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ function test_microphysics2M(FT)
3535
tps = TDI.TD.Parameters.ThermodynamicsParameters(FT)
3636

3737
# Terminal velocity parameters
38+
STVel = CMP.StokesRegimeVelType(FT)
3839
SB2006Vel = CMP.SB2006VelType(FT)
3940
Chen2022Vel = CMP.Chen2022VelTypeRain(FT)
4041

@@ -383,6 +384,42 @@ function test_microphysics2M(FT)
383384
end
384385
end
385386

387+
TT.@testset "2M_microphysics - cloud terminal velocity" begin
388+
#setup
389+
ρ = FT(1.1)
390+
q_liq = FT(1e-3)
391+
N_liq = FT(1e7)
392+
393+
(; ρw, grav, ν_air) = STVel
394+
395+
#action
396+
vt_liq = CM2.cloud_terminal_velocity(SB2006.pdf_c, STVel, q_liq, ρ, N_liq)
397+
398+
(; νc, μc, ρw) = SB2006.pdf_c
399+
(; Bc) = CM2.pdf_cloud_parameters_mass(SB2006.pdf_c, q_liq, ρ, N_liq)
400+
terminal_velocity_prefactor = FT(2 / 9) * (3 / 4 / pi / ρw)^(2 / 3) * (ρw / ρ - 1) * grav / ν_air
401+
vt0 = terminal_velocity_prefactor * DT.generalized_gamma_Mⁿ(νc, μc, Bc, N_liq, FT(2 / 3)) / N_liq
402+
vt1 = terminal_velocity_prefactor * DT.generalized_gamma_Mⁿ(νc, μc, Bc, N_liq, FT(5 / 3)) / ρ / q_liq
403+
404+
#test
405+
TT.@test vt_liq isa Tuple
406+
TT.@test vt_liq[1] vt0 rtol = 1e-6
407+
TT.@test vt_liq[2] vt1 rtol = 1e-6
408+
409+
TT.@test CM2.cloud_terminal_velocity(
410+
SB2006.pdf_c, STVel, q_liq, ρ, FT(0),
411+
)[1] 0 atol = eps(FT)
412+
TT.@test CM2.cloud_terminal_velocity(
413+
SB2006.pdf_c, STVel, FT(0), ρ, N_liq,
414+
)[2] 0 atol = eps(FT)
415+
TT.@test CM2.cloud_terminal_velocity(
416+
SB2006.pdf_c, STVel, FT(0), ρ, FT(0),
417+
)[1] 0 atol = eps(FT)
418+
TT.@test CM2.cloud_terminal_velocity(
419+
SB2006.pdf_c, STVel, FT(0), ρ, FT(0),
420+
)[2] 0 atol = eps(FT)
421+
end
422+
386423
TT.@testset "2M_microphysics - Seifert and Beheng 2006 rain terminal velocity with limiters" begin
387424
#setup
388425
ρ = FT(1.1)

0 commit comments

Comments
 (0)