Skip to content

Commit 0f448e5

Browse files
committed
fix: limiting behavior of 2M and P3 PSDs
1 parent ee61e90 commit 0f448e5

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

src/Microphysics2M.jl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ Return the parameters of the rain drop diameter distribution
6464
- A `NamedTuple` with the fields `(; N₀r, Dr_mean, xr_mean)`
6565
"""
6666
function pdf_rain_parameters(pdf_r::CMP.RainParticlePDF_SB2006_notlimited, qᵣ, ρₐ, Nᵣ)
67+
(iszero(Nᵣ) && iszero(qᵣ)) && return (; N₀r = zero(Nᵣ), Dr_mean = zero(qᵣ), xr_mean = zero(qᵣ))
6768
(; ρw) = pdf_r
6869
Lᵣ = ρₐ * qᵣ
6970

@@ -75,11 +76,12 @@ function pdf_rain_parameters(pdf_r::CMP.RainParticlePDF_SB2006_notlimited, qᵣ,
7576
return (; N₀r, Dr_mean, xr_mean)
7677
end
7778
function pdf_rain_parameters(pdf_r::CMP.RainParticlePDF_SB2006_limited, qᵣ, ρₐ, Nᵣ)
79+
(iszero(Nᵣ) && iszero(qᵣ)) && return (; N₀r = zero(Nᵣ), Dr_mean = zero(qᵣ), xr_mean = zero(qᵣ))
7880
(; xr_min, xr_max, N0_min, N0_max, λ_min, λ_max, ρw) = pdf_r
7981
Lᵣ = ρₐ * max(0, qᵣ)
8082

8183
# Sequence of limiting steps in Seifert and Beheng 2006:
82-
x̃r = clamp(Lᵣ / Nᵣ, xr_min, xr_max) # Eq. (94) # TODO: Ill-defined for 0 / 0
84+
x̃r = clamp(Lᵣ / Nᵣ, xr_min, xr_max) # Eq. (94)
8385
N₀r = clamp(Nᵣ * * ρw / x̃r), N0_min, N0_max) # Eq. (95)
8486
λr = clamp(* ρw * N₀r / Lᵣ), λ_min, λ_max) # Eq. (96)
8587
xr_mean = clamp(Lᵣ * λr / N₀r, xr_min, xr_max) # Eq. (97)
@@ -153,6 +155,7 @@ That is,
153155
- `(logA, logB)`: Log of the parameters of the generalized gamma distribution
154156
"""
155157
function log_pdf_cloud_parameters_mass(pdf_c, q, ρₐ, N)
158+
(N < eps(one(N)) && q < eps(one(q))) && return (log(zero(N)), log(1 / zero(q)))
156159
(; νc, μc) = pdf_c
157160
L = ρₐ * q
158161
logx̄ = log(L / N)
@@ -242,7 +245,7 @@ Return `n(D)`, a function that computes the size distribution for rain particles
242245
"""
243246
function DT.size_distribution(pdf::CMP.RainParticlePDF_SB2006, q, ρₐ, N)
244247
(; N₀r, Dr_mean) = pdf_rain_parameters(pdf, q, ρₐ, N)
245-
return n(D) = N₀r * exp(-D / Dr_mean)
248+
return n(D) = iszero(N₀r) ? zero(D) : N₀r * exp(-D / Dr_mean)
246249
end
247250

248251
"""
@@ -263,7 +266,7 @@ The size distribution is given by:
263266
"""
264267
function DT.size_distribution(pdf::CMP.CloudParticlePDF_SB2006, q, ρₐ, N)
265268
(; logN₀c, λc, νcD, μcD) = pdf_cloud_parameters(pdf, q, ρₐ, N)
266-
return n(D) = exp(logN₀c + νcD * log(D) - λc * D^μcD)
269+
return n(D) = logN₀c == -Inf ? zero(D) : exp(logN₀c + νcD * log(D) - λc * D^μcD)
267270
end
268271

269272
"""
@@ -303,6 +306,7 @@ function get_size_distribution_bounds(
303306
q, ρₐ, N, p = eps(FT),
304307
) where {FT}
305308
(; Dr_mean) = pdf_rain_parameters(pdf, q, ρₐ, N)
309+
iszero(Dr_mean) && return (FT(0), FT(0))
306310
D_min = DT.exponential_quantile(Dr_mean, p)
307311
D_max = DT.exponential_quantile(Dr_mean, 1 - p)
308312
return D_min, D_max

src/P3_size_distribution.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ where `m(D)` is the mass of a particle at diameter `D` (see [`ice_mass`](@ref)).
225225
function get_distribution_logλ(
226226
state::P3State{FT}; logλ_min = log(1e1), logλ_max = log(1e7),
227227
) where {FT}
228+
(iszero(state.N_ice) || iszero(state.L_ice)) && return log(zero(FT))
228229
target_log_LdN = log(state.L_ice) - log(state.N_ice)
229230

230231
shape_problem(logλ) = logLdivN(state, logλ) - target_log_LdN

test/microphysics2M_tests.jl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,34 @@ function test_microphysics2M(FT)
143143
end
144144

145145
# 2M_microphysics - Seifert and Beheng 2006 double moment scheme tests
146+
TT.@testset "Seifert and Beheng 2006 - PDF parameters limiting behavior" begin
147+
N = 0.0
148+
q = 0.0
149+
ρₐ = 1.2
150+
# limited rain drop size distribution
151+
params = CM2.pdf_rain_parameters(SB2006.pdf_r, q, ρₐ, N)
152+
TT.@test all(iszero, params)
153+
n = CM2.size_distribution(SB2006.pdf_r, q, ρₐ, N)
154+
TT.@test all(iszero, (n(0), n(0.1), n(Inf)))
155+
bnds = CM2.get_size_distribution_bounds(SB2006.pdf_r, q, ρₐ, N)
156+
TT.@test all(iszero, bnds)
157+
# not limited rain drop size distribution
158+
params = CM2.pdf_rain_parameters(SB2006_no_limiters.pdf_r, q, ρₐ, N)
159+
TT.@test all(iszero, params)
160+
n = CM2.size_distribution(SB2006_no_limiters.pdf_r, q, ρₐ, N)
161+
TT.@test all(iszero, (n(0), n(0.1), n(Inf)))
162+
bnds = CM2.get_size_distribution_bounds(SB2006_no_limiters.pdf_r, q, ρₐ, N)
163+
TT.@test all(iszero, bnds)
164+
# cloud drop size distribution
165+
logA, logB = CM2.log_pdf_cloud_parameters_mass(SB2006.pdf_c, q, ρₐ, N)
166+
TT.@test logA == -Inf
167+
TT.@test logB == Inf
168+
A, B = CM2.pdf_cloud_parameters_mass(SB2006.pdf_c, q, ρₐ, N)
169+
TT.@test A == 0
170+
TT.@test B == Inf
171+
n = CM2.size_distribution(SB2006.pdf_c, q, ρₐ, N)
172+
TT.@test all(iszero, (n(0), n(0.1), n(Inf)))
173+
end
146174
TT.@testset "limiting lambda_r and x_r - Seifert and Beheng 2006" begin
147175
#setup
148176
q_rai = [FT(0), FT(1e-3), FT(1e-4), FT(1e-2)]

test/p3_tests.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ function test_shape_solver(FT)
178178
params = CMP.ParametersP3(FT; slope_law)
179179

180180
@testset "Shape parameters - nonlinear solver" begin
181+
# -- First, test limiting behavior: `N_ice = L_ice = 0` --
182+
state = P3.get_state(params; F_rim = FT(0.5), ρ_rim = FT(500), L_ice = FT(0), N_ice = FT(0))
183+
logλ = P3.get_distribution_logλ(state)
184+
@test logλ == -Inf
185+
# --
181186

182187
# initialize test values:
183188
ep = 1 #1e4 * eps(FT)

0 commit comments

Comments
 (0)