11# Warm-phase saturation adjustment
22
33Warm-phase saturation adjustment is a model for water droplet nucleation that assumes that water vapor in excess of the saturation specific humidity is instantaneously converted to liquid water.
4- Mixed-phase saturation adjustment is described by [ Chammas2023 ] ( @citet ) .
4+ Mixed-phase saturation adjustment is described by [ Pressel2015 ] ( @citet ) .
55Saturation adjustment may be formulated as a nonlinear algebraic equation that relates temperature, potential temperature, and total specific humidity, derived from the definition of liquid potential temperature,
66
77``` math
8- θ = \frac{T }{Π} \left \{1 - \frac{ℒᵥ₀}{cᵖᵐ T } \max \left [0, qᵗ - qᵛ⁺(T) \right ] \right \} ,
8+ θ = \frac{1 }{Π} \left \{T - \frac{ℒᵥ₀}{cᵖᵐ} \max \left [0, qᵗ - qᵛ⁺(T) \right ] \right \} ,
99```
1010
1111where `` Π `` is the Exner function, `` θ `` is potential temperature, `` T `` is temperature,
@@ -32,14 +32,15 @@ The saturation specific humidity is then
3232
3333``` @example microphysics
3434using Breeze
35- using Breeze.MoistAirBuoyancies : saturation_specific_humidity, HeightReferenceThermodynamicState
35+ using Breeze.Thermodynamics : saturation_specific_humidity
3636
3737thermo = ThermodynamicConstants()
38- ref = ReferenceStateConstants(base_pressure=101325, potential_temperature=288)
3938
40- z = 0.0 # [m] height
41- θ = 290.0 # [ᵒK] potential temperature
42- qᵛ⁺₀ = saturation_specific_humidity(θ, z, ref, thermo, thermo.liquid)
39+ p₀ = 101325.0
40+ θ₀ = 288.0
41+ Rᵈ = Breeze.Thermodynamics.dry_air_gas_constant(thermo)
42+ ρ₀ = p₀ / (Rᵈ * θ₀)
43+ qᵛ⁺₀ = saturation_specific_humidity(θ₀, ρ₀, thermo, thermo.liquid)
4344```
4445
4546Recall that the specific humidity is unitless, or has units "`` kg / kg `` ": kg of water vapor
@@ -49,17 +50,20 @@ given a total specific humidity slightly above saturation:
4950
5051``` @example microphysics
5152using Breeze.MoistAirBuoyancies: temperature
53+ using Breeze.Thermodynamics: PotentialTemperatureState, MoistureMassFractions
5254
55+ z = 0.0
5356qᵗ = 0.012 # [kg kg⁻¹] total specific humidity
54- U = HeightReferenceThermodynamicState(θ, qᵗ, z)
55- T = temperature(U, ref, thermo)
57+ q = MoistureMassFractions(qᵗ, zero(qᵗ), zero(qᵗ))
58+ U = PotentialTemperatureState(θ₀, q, z, p₀, p₀, ρ₀)
59+ T = temperature(U, thermo)
5660```
5761
5862Finally, we recover the amount of liquid condensate by subtracting the saturation
5963specific humidity from the total:
6064
6165``` @example microphysics
62- qᵛ⁺ = saturation_specific_humidity(T, z, ref , thermo, thermo.liquid)
66+ qᵛ⁺ = saturation_specific_humidity(T, ρ₀ , thermo, thermo.liquid)
6367qˡ = qᵗ - qᵛ⁺
6468```
6569
@@ -69,14 +73,15 @@ As a second example, we examine the dependence of temperature on total specific
6973when the potential temperature is constant:
7074
7175``` @example microphysics
72- qᵗ = 0:1e-4:0.04 # [kg kg⁻¹] total specific humidity
73- U = [HeightReferenceThermodynamicState(θ, qᵗⁱ, z) for qᵗⁱ in qᵗ]
74- T = [temperature(Uⁱ, ref, thermo) for Uⁱ in U]
76+ qᵗ = 0:1e-4:0.035 # [kg kg⁻¹] total specific humidity
77+ q = [MoistureMassFractions(qᵗⁱ, 0.0, 0.0) for qᵗⁱ in qᵗ]
78+ U = [PotentialTemperatureState(θ₀, qⁱ, z, p₀, p₀, ρ₀) for qⁱ in q]
79+ T = [temperature(Uⁱ, thermo) for Uⁱ in U]
7580
7681## Compare with a simple piecewise linear model
77- ℒᵥ₀ = thermo.liquid.latent_heat
82+ ℒᵥ₀ = thermo.liquid.reference_latent_heat
7883cᵖᵈ = thermo.dry_air.heat_capacity
79- T̃ = [290 + ℒᵥ₀ / cᵖᵈ * max(0, qᵗⁱ - qᵛ⁺₀) for qᵗⁱ in qᵗ]
84+ T̃ = [288 + ℒᵥ₀ / cᵖᵈ * max(0, qᵗⁱ - qᵛ⁺₀) for qᵗⁱ in qᵗ]
8085
8186using CairoMakie
8287
@@ -94,13 +99,32 @@ For a third example, we consider a state with constant potential temperature and
9499but at varying heights:
95100
96101``` @example microphysics
102+ grid = RectilinearGrid(size=100, z=(0, 1e4), topology=(Flat, Flat, Bounded))
103+ thermo = ThermodynamicConstants()
104+ reference_state = ReferenceState(grid, thermo)
105+
106+ θᵣ = reference_state.potential_temperature
107+ p₀ = reference_state.base_pressure
97108qᵗ = 0.005
98- z = 0:100:10e3
109+ q = MoistureMassFractions(qᵗ, 0.0, 0.0)
110+
111+ z = znodes(grid, Center())
112+ T = zeros(grid.Nz)
113+ qᵛ⁺ = zeros(grid.Nz)
114+ qˡ = zeros(grid.Nz)
115+ rh = zeros(grid.Nz)
116+
117+ for k = 1:grid.Nz
118+ ρᵣ = reference_state.density[1, 1, k]
119+ pᵣ = reference_state.pressure[1, 1, k]
120+
121+ U = PotentialTemperatureState(θᵣ, q, z[k], p₀, pᵣ, ρᵣ)
122+ T[k] = temperature(U, thermo)
99123
100- T = [temperature(HeightReferenceThermodynamicState(θ, qᵗ, zᵏ), ref, thermo) for zᵏ in z]
101- qᵛ⁺ = [saturation_specific_humidity(T[k], z [k], ref, thermo, thermo.liquid) for k = 1:length(z)]
102- qˡ = [max(0, qᵗ - qᵛ⁺ᵏ) for qᵛ⁺ᵏ in qᵛ⁺]
103- rh = [100 * min(qᵗ, qᵛ⁺ᵏ) / qᵛ⁺ᵏ for qᵛ⁺ᵏ in qᵛ⁺]
124+ qᵛ⁺[k] = saturation_specific_humidity(T[k], ρᵣ, thermo, thermo.liquid)
125+ qˡ [k] = max(0, qᵗ - qᵛ⁺[k])
126+ rh[k] = 100 * min(qᵗ, qᵛ⁺[k]) / qᵛ⁺[k ]
127+ end
104128
105129cᵖᵈ = thermo.dry_air.heat_capacity
106130g = thermo.gravitational_acceleration
0 commit comments