Skip to content

Commit 4cc300d

Browse files
authored
Merge pull request #649 from CliMA/aj/new_epsilon
Change to sqrt(ftmin)
2 parents af162eb + 77f001e commit 4cc300d

File tree

9 files changed

+67
-42
lines changed

9 files changed

+67
-42
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.28.1"
4+
version = "0.29.0"
55

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

src/CloudDiagnostics.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import ..Parameters as CMP
1212
import ..Microphysics1M as CM1
1313
import ..Microphysics2M as CM2
1414
import ..DistributionTools as DT
15+
import ..Common as CO
1516

1617
"""
1718
radar_reflectivity_1M(precip, q, ρ)
@@ -119,7 +120,7 @@ function effective_radius_2M(
119120
M2_c = notvalid(Bc) ? FT(0) : DT.generalized_gamma_Mⁿ(νc, μc, Bc, N_lcl, n_mass) / C^(n_mass)
120121
M2_r = notvalid(Br) ? FT(0) : DT.generalized_gamma_Mⁿ(νr, μr, Br, N_rai, n_mass) / C^(n_mass)
121122

122-
return M2_c + M2_r <= eps(FT) ? FT(0) : (M3_c + M3_r) / (M2_c + M2_r)
123+
return M2_c + M2_r <= CO.ϵ_numerics(FT) ? FT(0) : (M3_c + M3_r) / (M2_c + M2_r)
123124
end
124125

125126
"""
@@ -147,7 +148,7 @@ function effective_radius_Liu_Hallet_97(
147148

148149
k = FT(0.8)
149150
r_vol =
150-
((N_lcl + N_rai) < eps(FT)) ? FT(0) :
151+
((N_lcl + N_rai) < CO.ϵ_numerics(FT)) ? FT(0) :
151152
(
152153
(FT(3) * (q_lcl + q_rai) * ρ_air) /
153154
(FT(4) * π * ρw * (N_lcl + N_rai))

src/Common.jl

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ export Chen2022_monodisperse_pdf
2121
export Chen2022_exponential_pdf
2222
export ventilation_factor
2323

24+
"""
25+
Smallest number that is different than zero for the purpose of microphysics
26+
computations.
27+
"""
28+
ϵ_numerics(FT) = sqrt(floatmin(FT))
29+
2430
"""
2531
G_func_liquid(air_props, tps, T)
2632
@@ -89,9 +95,9 @@ function logistic_function(x::FT, x_0::FT, k::FT) where {FT}
8995
@assert x_0 >= 0
9096
x = max(0, x)
9197

92-
if abs(x) < eps(FT)
98+
if abs(x) < ϵ_numerics(FT)
9399
return FT(0)
94-
elseif abs(x_0) < eps(FT)
100+
elseif abs(x_0) < ϵ_numerics(FT)
95101
return FT(1)
96102
end
97103

@@ -114,9 +120,9 @@ function logistic_function_integral(x::FT, x_0::FT, k::FT) where {FT}
114120
@assert x_0 >= 0
115121
x = max(0, x)
116122

117-
if abs(x) < eps(FT)
123+
if abs(x) < ϵ_numerics(FT)
118124
return FT(0)
119-
elseif abs(x_0) < eps(FT)
125+
elseif abs(x_0) < ϵ_numerics(FT)
120126
return x
121127
end
122128

src/Microphysics1M.jl

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ function lambda_inverse(
9494
(; r0, m0, me, Δm, χm) = mass
9595

9696
λ_inv = FT(0)
97-
if q > FT(0) && ρ > FT(0)
97+
if q > CO.ϵ_numerics(FT) && ρ > CO.ϵ_numerics(FT)
9898
λ_inv = exp(1 / (me + Δm + 1) *
9999
log(
100100
ρ * q * exp((me + Δm) * log(r0)) / χm / m0 / n0 / SF.gamma(me + Δm + FT(1)),
@@ -162,7 +162,7 @@ function terminal_velocity(
162162
ρ::FT,
163163
q::FT,
164164
) where {FT}
165-
if q > FT(0)
165+
if q > CO.ϵ_numerics(FT)
166166
# terminal_velocity(size)
167167
(; χv, ve, Δv) = vel
168168
v0 = get_v0(vel, ρ)
@@ -184,7 +184,7 @@ function terminal_velocity(
184184
q::FT,
185185
) where {FT}
186186
fall_w = FT(0)
187-
if q > FT(0)
187+
if q > CO.ϵ_numerics(FT)
188188
# coefficients from Table B1 from Chen et. al. 2022
189189
aiu, bi, ciu = CO.Chen2022_vel_coeffs(vel, ρₐ)
190190
# size distribution parameter
@@ -208,7 +208,7 @@ function terminal_velocity(
208208
# We assume the B4 table coeffs for snow and B2 table coeffs for cloud ice.
209209
# Instead we should do partial integrals
210210
# from D=125um to D=625um using B2 and D=625um to inf using B4.
211-
if q > FT(0)
211+
if q > CO.ϵ_numerics(FT)
212212
# coefficients from Table B4 from Chen et. al. 2022
213213
aiu, bi, ciu = CO.Chen2022_vel_coeffs(vel, ρₐ, ρᵢ)
214214
# size distribution parameter
@@ -235,7 +235,7 @@ function terminal_velocity(
235235
) where {FT}
236236
fall_w = FT(0)
237237
# see comments above about B2 vs B4 coefficients
238-
if q > FT(0)
238+
if q > CO.ϵ_numerics(FT)
239239
# coefficients from Table B4 from Chen et. al. 2022
240240
aiu, bi, ciu = CO.Chen2022_vel_coeffs(vel, ρₐ, ρᵢ)
241241
# size distribution parameter
@@ -325,7 +325,7 @@ function conv_q_icl_to_q_sno(
325325
acnv_rate = FT(0)
326326
S = TDI.supersaturation_over_ice(tps, q_tot, q_lcl + q_rai, q_icl + q_sno, ρ, T)
327327

328-
if (q_icl > FT(0) && S > FT(0))
328+
if (q_icl > CO.ϵ_numerics(FT) && S > FT(0))
329329
(; me, Δm) = mass
330330
G = CO.G_func_ice(aps, tps, T)
331331
n0 = get_n0(pdf)
@@ -364,7 +364,7 @@ function accretion(
364364
) where {FT}
365365

366366
accr_rate = FT(0)
367-
if (q_clo > FT(0) && q_pre > FT(0))
367+
if (q_clo > CO.ϵ_numerics(FT) && q_pre > CO.ϵ_numerics(FT))
368368

369369
n0::FT = get_n0(precip.pdf, q_pre, ρ)
370370
v0::FT = get_v0(vel, ρ)
@@ -407,7 +407,7 @@ function accretion_rain_sink(
407407
ρ::FT,
408408
) where {FT}
409409
accr_rate = FT(0)
410-
if (q_icl > FT(0) && q_rai > FT(0))
410+
if (q_icl > CO.ϵ_numerics(FT) && q_rai > CO.ϵ_numerics(FT))
411411

412412
n0_ice = get_n0(ice.pdf)
413413
λ_ice_inv = lambda_inverse(ice.pdf, ice.mass, q_icl, ρ)
@@ -459,7 +459,7 @@ function accretion_snow_rain(
459459
) where {FT}
460460

461461
accr_rate = FT(0)
462-
if (q_i > FT(0) && q_j > FT(0))
462+
if (q_i > CO.ϵ_numerics(FT) && q_j > CO.ϵ_numerics(FT))
463463

464464
n0_i = get_n0(type_i.pdf, q_i, ρ)
465465
n0_j = get_n0(type_j.pdf, q_j, ρ)
@@ -524,7 +524,7 @@ function evaporation_sublimation(
524524
evap_subl_rate = FT(0)
525525
S = TDI.supersaturation_over_liquid(tps, q_tot, q_lcl + q_rai, q_icl + q_sno, ρ, T)
526526

527-
if (q_rai > FT(0) && S < FT(0))
527+
if (q_rai > CO.ϵ_numerics(FT) && S < FT(0))
528528

529529
(; ν_air, D_vapor) = aps
530530
G = CO.G_func_liquid(aps, tps, T)
@@ -565,7 +565,7 @@ function evaporation_sublimation(
565565
T::FT,
566566
) where {FT}
567567
evap_subl_rate = FT(0)
568-
if q_sno > FT(0)
568+
if q_sno > CO.ϵ_numerics(FT)
569569
(; ν_air, D_vapor) = aps
570570

571571
S = TDI.supersaturation_over_ice(tps, q_tot, q_lcl + q_rai, q_icl + q_sno, ρ, T)
@@ -618,7 +618,7 @@ function snow_melt(
618618
) where {FT}
619619
snow_melt_rate = FT(0)
620620

621-
if (q_sno > FT(0) && T > T_freeze)
621+
if (q_sno > CO.ϵ_numerics(FT) && T > T_freeze)
622622
(; ν_air, D_vapor, K_therm) = aps
623623

624624
L = TDI.Lf(tps, T)

src/Microphysics2M.jl

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ function autoconversion(
365365
q_lcl, q_rai, ρ, N_lcl,
366366
) where {FT}
367367

368-
if q_lcl < eps(FT) || N_lcl < eps(FT)
368+
if q_lcl < CO.ϵ_numerics(FT) || N_lcl < CO.ϵ_numerics(FT)
369369
return LclRaiRates{FT}()
370370
end
371371

@@ -411,7 +411,7 @@ Compute accretion rate
411411
"""
412412
function accretion((; accr)::CMP.SB2006{FT}, q_lcl, q_rai, ρ, N_lcl) where {FT}
413413

414-
if q_lcl < eps(FT) || q_rai < eps(FT) || N_lcl < eps(FT)
414+
if q_lcl < CO.ϵ_numerics(FT) || q_rai < CO.ϵ_numerics(FT) || N_lcl < CO.ϵ_numerics(FT)
415415
return LclRaiRates{FT}()
416416
end
417417

@@ -456,7 +456,7 @@ function cloud_liquid_self_collection(
456456
q_lcl, ρ, dN_lcl_dt_au,
457457
) where {FT}
458458

459-
if q_lcl < eps(FT)
459+
if q_lcl < CO.ϵ_numerics(FT)
460460
return FT(0)
461461
end
462462
(; kcc, ρ0) = acnv
@@ -518,7 +518,7 @@ function rain_self_collection(
518518
q_rai, ρ, N_rai,
519519
) where {FT}
520520

521-
if q_rai < eps(FT) || N_rai < eps(FT)
521+
if q_rai < CO.ϵ_numerics(FT) || N_rai < CO.ϵ_numerics(FT)
522522
return FT(0)
523523
end
524524

@@ -554,7 +554,7 @@ function rain_breakup(
554554
q_rai, ρ, N_rai, dN_rai_dt_sc,
555555
) where {FT}
556556

557-
if q_rai < eps(FT) || N_rai < eps(FT)
557+
if q_rai < CO.ϵ_numerics(FT) || N_rai < CO.ϵ_numerics(FT)
558558
return FT(0)
559559
end
560560
(; Deq, Dr_th, kbr, κbr) = brek
@@ -624,7 +624,7 @@ function cloud_terminal_velocity(
624624
q_liq, ρₐ, N_liq,
625625
) where {FT}
626626

627-
if N_liq < eps(FT) || q_liq < eps(FT)
627+
if N_liq < CO.ϵ_numerics(FT) || q_liq < CO.ϵ_numerics(FT)
628628
return (FT(0), FT(0))
629629
end
630630

@@ -633,10 +633,10 @@ function cloud_terminal_velocity(
633633

634634
terminal_velocity_prefactor = FT(1 / 18) * (6 / ρw / π)^(2 // 3) * (ρw / ρₐ - 1) * grav / ν_air
635635
vt0 =
636-
N_liq < eps(FT) ? FT(0) :
636+
N_liq < CO.ϵ_numerics(FT) ? FT(0) :
637637
terminal_velocity_prefactor * DT.generalized_gamma_Mⁿ(νc, μc, Bc, N_liq, FT(2 / 3)) / N_liq
638638
vt1 =
639-
q_liq < eps(FT) ? FT(0) :
639+
q_liq < CO.ϵ_numerics(FT) ? FT(0) :
640640
terminal_velocity_prefactor * DT.generalized_gamma_Mⁿ(νc, μc, Bc, N_liq, FT(5 / 3)) / ρₐ / q_liq
641641

642642
return (vt0, vt1)
@@ -673,10 +673,10 @@ function rain_terminal_velocity(
673673
_sb_rain_terminal_velocity_helper(pdf_r, 1 / Dr_mean, aR, bR, cR)
674674

675675
vt0 =
676-
N_rai < eps(FT) ? FT(0) :
676+
N_rai < CO.ϵ_numerics(FT) ? FT(0) :
677677
max(FT(0), sqrt(ρ0 / ρ) * (aR * _pa0 - bR * _pb0 / (1 + cR * Dr_mean)))
678678
vt1 =
679-
q_rai < eps(FT) ? FT(0) :
679+
q_rai < CO.ϵ_numerics(FT) ? FT(0) :
680680
max(FT(0), sqrt(ρ0 / ρ) * (aR * _pa1 - bR * _pb1 / (1 + cR * Dr_mean)^4))
681681
return (vt0, vt1)
682682
end
@@ -757,7 +757,7 @@ function rain_evaporation(
757757
evap_rate_1 = FT(0)
758758
S = TDI.supersaturation_over_liquid(tps, q_tot, q_lcl + q_rai, q_icl + q_sno, ρ, T)
759759

760-
if (N_rai > eps(FT) && S < FT(0))
760+
if (N_rai > CO.ϵ_numerics(FT) && S < FT(0))
761761

762762
(; ν_air, D_vapor) = aps
763763
(; av, bv, α, β, ρ0) = evap
@@ -917,7 +917,7 @@ function conv_q_lcl_to_q_rai(
917917
N_d,
918918
smooth_transition = false,
919919
) where {FT}
920-
if q_lcl <= eps(FT)
920+
if q_lcl <= CO.ϵ_numerics(FT)
921921
return FT(0)
922922
else
923923
# Mean volume radius in microns (assuming spherical cloud droplets)

src/MicrophysicsNonEq.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ function terminal_velocity(
138138
q::FT,
139139
) where {FT}
140140
fall_w = FT(0)
141-
if q > FT(0)
141+
if q > CO.ϵ_numerics(FT)
142142
# TODO: Coefficients from Table B1 from Chen et. al. 2022 are only valid
143143
# for D > 100mm. We should look for a different parameterization
144144
# that is more suited for cloud droplets. For now I'm just multiplying
@@ -162,7 +162,7 @@ function terminal_velocity(
162162
q::FT,
163163
) where {FT}
164164
fall_w = FT(0)
165-
if q > FT(0)
165+
if q > CO.ϵ_numerics(FT)
166166
v_term = CO.particle_terminal_velocity(vel, ρₐ, ρᵢ)
167167
# See the comment for liquid droplets above
168168
N = FT(500 * 1e6)

src/P3_terminal_velocity.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
ice_particle_terminal_velocity(velocity_params, ρₐ, state::P3State; [use_aspect_ratio])
44
ice_particle_terminal_velocity(velocity_params, ρₐ, params::CMP.ParametersP3, F_rim, ρ_rim; [use_aspect_ratio])
55
6-
Returns the terminal velocity of a single ice particle as a function of its size
6+
Returns the terminal velocity of a single ice particle as a function of its size
77
(maximum dimension, `D`) using the Chen 2022 parametrization.
88
99
# Arguments
@@ -57,6 +57,7 @@ function ice_terminal_velocity_number_weighted(
5757
use_aspect_ratio = true, p = 1e-6, ∫kwargs...,
5858
)
5959
(; N_ice, L_ice) = state
60+
# TODO - do we want to swicth to ϵ_numerics(FT)
6061
if N_ice < eps(one(N_ice)) || L_ice < eps(one(L_ice))
6162
return zero(N_ice)
6263
end
@@ -101,6 +102,7 @@ function ice_terminal_velocity_mass_weighted(
101102
use_aspect_ratio = true, p = 1e-6, ∫kwargs...,
102103
)
103104
(; N_ice, L_ice) = state
105+
# TODO - do we want to swicth to ϵ_numerics(FT)
104106
if N_ice < eps(one(N_ice)) || L_ice < eps(one(L_ice))
105107
return zero(L_ice)
106108
end

test/cloud_diagnostics.jl

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,27 +46,40 @@ function test_cloud_diagnostics(FT)
4646
#setup
4747
ρₐ = FT(1)
4848

49-
q_lcl = [FT(2.128e-4), FT(2.128e-20), FT(1.6e-12), FT(0), FT(1.037e-25)]
50-
N_lcl = [FT(15053529), FT(3), FT(5512), FT(0), FT(5.225e-12)]
51-
q_rai = [FT(1.573e-4), FT(1.573e-4), FT(1.9e-15), FT(0), FT(2.448e-27)]
52-
N_rai = [FT(510859), FT(510859), FT(0), FT(0), FT(5.136e-18)]
49+
q_lcl = [FT(2.128e-4), FT(2.128e-20), FT(1.6e-12), FT(0)]
50+
N_lcl = [FT(15053529), FT(3), FT(5512), FT(0)]
51+
q_rai = [FT(1.573e-4), FT(1.573e-4), FT(1.9e-15), FT(0)]
52+
N_rai = [FT(510859), FT(510859), FT(0), FT(0)]
5353

5454
# reference values
55-
rr = [FT(-12.559725319858543), FT(-12.579899), FT(-150), FT(-150), FT(-150)]
56-
reff = [FT(2.319383e-5), FT(6.91594e-5), FT(0), FT(0), FT(0)]
55+
rr = [FT(-12.559725319858543), FT(-12.579899), FT(-150), FT(-150)]
56+
reff = [FT(2.319383e-5), FT(6.91594e-5), FT(0), FT(0)]
5757

5858
for (qₗ, Nₗ, qᵣ, Nᵣ, rₑ, Z) in zip(q_lcl, N_lcl, q_rai, N_rai, reff, rr)
5959
for SB in [SB2006, SB2006_no_limiters]
60-
6160
#action
6261
Z_val = CMD.radar_reflectivity_2M(SB, qₗ, qᵣ, Nₗ, Nᵣ, ρₐ)
6362
rₑ_val = CMD.effective_radius_2M(SB, qₗ, qᵣ, Nₗ, Nᵣ, ρₐ)
64-
6563
#test
6664
TT.@test rₑ_val rₑ atol = FT(1e-6)
6765
TT.@test Z_val Z atol = FT(1e-4)
6866
end
6967
end
68+
69+
# Additional test for small numbers
70+
qₗ = FT(1.037e-25)
71+
Nₗ = FT(5.225e-12)
72+
qᵣ = FT(2.448e-27)
73+
Nᵣ = FT(5.136e-18)
74+
Z = FT(-150)
75+
for SB in [SB2006, SB2006_no_limiters]
76+
rₑ = (FT == Float32 || SB == SB2006) ? FT(0) : FT(8e-5)
77+
Z_val = CMD.radar_reflectivity_2M(SB, qₗ, qᵣ, Nₗ, Nᵣ, ρₐ)
78+
rₑ_val = CMD.effective_radius_2M(SB, qₗ, qᵣ, Nₗ, Nᵣ, ρₐ)
79+
#test
80+
TT.@test rₑ_val rₑ atol = FT(1e-6)
81+
TT.@test Z_val Z atol = FT(1e-4)
82+
end
7083
end
7184

7285
TT.@testset "Effective radius - '1/3' power law from Liu and Hallett (1997)" begin

test/microphysics1M_tests.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ function test_microphysics1M(FT)
8282
TT.@test v_bigger > vt_sno
8383
end
8484

85+
TT.@testset "1M_microphysics - 1M snow terminal velocity Nans" begin
86+
TT.@test !isnan(CM1.terminal_velocity(snow, blk1mvel.snow, FT(0.2439843), FT(3.0f-45)))
87+
end
8588

8689
TT.@testset "RainAutoconversion" begin
8790

0 commit comments

Comments
 (0)