@@ -392,52 +392,134 @@ cᵖᵐ - cᵖᵈ
392392```
393393
394394
395- ## The Clausius--Clapeyron relation and saturation specific humidity
395+ ## The Clausius--Clapeyron relation and saturation vapor pressure
396396
397397The [ Clausius--Clapeyron relation] ( https://en.wikipedia.org/wiki/Clausius%E2%80%93Clapeyron_relation )
398- for an ideal gas
398+ for an ideal gas describes how saturation vapor pressure changes with temperature:
399399
400400``` math
401401\frac{\mathrm{d} pᵛ⁺}{\mathrm{d} T} = \frac{pᵛ⁺ ℒ^β(T)}{Rᵛ T^2} ,
402402```
403403
404- where `` pᵛ⁺ `` is saturation vapor pressure, `` T `` is temperature, `` Rᵛ `` is the specific
405- gas constant for vapor, `` ℒ^β(T) `` is the latent heat of the transition from vapor to the
406- `` β `` phase (e.g., `` β = l `` for vapor → liquid and `` β = i `` for vapor to ice).
404+ where `` pᵛ⁺ `` is saturation vapor pressure over a surface of condensed phase `` β `` ,
405+ `` T `` is temperature, `` Rᵛ `` is the specific gas constant for vapor, and
406+ `` ℒ^β(T) `` is the latent heat of the phase transition from vapor to phase `` β `` .
407+ For atmospheric moist air, the relevant condensed phases are liquid water (`` β = l `` )
408+ and ice (`` β = i `` ).
409+
410+ ### Temperature-dependent latent heat
407411
408412For a thermodynamic formulation that uses constant (i.e. temperature-independent) specific
409- heats, the latent heat of a phase transition is linear in temperature.
410- For example, for phase change from vapor to liquid,
413+ heats, the latent heat of a phase transition is linear in temperature:
414+
415+ ``` math
416+ ℒ^β(T) = ℒ^β_0 + \Delta c^β \, T ,
417+ ```
418+
419+ where `` ℒ^β_0 ≡ ℒ^β(T=0) `` is the latent heat at absolute zero and
420+ `` \Delta c^β ≡ c_p^v - c^β `` is the constant difference between the vapor specific heat
421+ capacity at constant pressure and the specific heat capacity of the condensed phase `` β `` .
422+
423+ Note that we typically parameterize the latent heat in terms of a reference
424+ temperature `` T_r `` that is well above absolute zero. In that case,
425+ the latent heat is written
426+
427+ ``` math
428+ ℒ^β(T) = ℒ^β_r + \Delta c^β (T - T_r), \qquad \text{and} \qquad
429+ ℒ^β_0 = ℒ^β_r - \Delta c^β T_r ,
430+ ```
431+
432+ where `` ℒ^β_r `` is the latent heat at the reference temperature `` T_r `` .
433+
434+ ### Integration of the Clausius-Clapeyron relation
435+
436+ To find the saturation vapor pressure as a function of temperature, we integrate
437+ the Clausius-Clapeyron relation with the temperature-linear latent heat model
438+ from the triple point pressure and temperature `` (p^{tr}, T^{tr}) `` to a generic
439+ pressure `` pᵛ⁺ `` and temperature `` T `` :
440+
441+ ``` math
442+ \int_{p^{tr}}^{pᵛ⁺} \frac{\mathrm{d} p}{p} = \int_{T^{tr}}^{T} \frac{ℒ^β_0 + \Delta c^β T'}{Rᵛ T'^2} \, \mathrm{d} T' .
443+ ```
444+
445+ Evaluating the integrals yields
411446
412447``` math
413- ℒˡ(T ) = ℒˡ(T=0) + \big ( \underbrace{cᵖᵛ - cˡ}_{≡Δcˡ } \big ) T ,
448+ \log\left(\frac{pᵛ⁺}{p^{tr}}\right ) = -\frac{ℒ^β_0}{Rᵛ T} + \frac{ℒ^β_0}{Rᵛ T^{tr}} + \frac{\Delta c^β}{Rᵛ } \log\left(\frac{T}{T^{tr}}\right) .
414449```
415450
416- where `` ℒˡ(T=0) `` is the latent heat at absolute zero, `` T = 0 \; \mathrm{K} `` .
417- By integrating from the triple-point temperature `` Tᵗʳ `` for which `` p(Tᵗʳ) = pᵗʳ `` , we get
451+ Exponentiating both sides gives the closed-form solution:
418452
419453``` math
420- pᵛ⁺(T) = pᵗʳ \left ( \frac{T}{Tᵗʳ} \right )^{Δcˡ / Rᵛ} \exp \left [ \frac{ℒˡ(T=0) }{Rᵛ} \left (\frac{1}{Tᵗʳ } - \frac{1}{T} \right ) \right ] .
454+ pᵛ⁺(T) = p^{tr} \left ( \frac{T}{T^{tr}} \right )^{\Delta c^β / Rᵛ} \exp \left [ \frac{ℒ^β_0 }{Rᵛ} \left (\frac{1}{T^{tr} } - \frac{1}{T} \right ) \right ] .
421455```
422456
457+ ### Example: liquid water and ice parameters
458+
423459Consider parameters for liquid water,
424460
425461``` @example thermo
426462using Breeze.Thermodynamics: CondensedPhase
427463liquid_water = CondensedPhase(reference_latent_heat=2500800, heat_capacity=4181)
428464```
429465
430- or water ice,
466+ and water ice,
431467
432468``` @example thermo
433469water_ice = CondensedPhase(reference_latent_heat=2834000, heat_capacity=2108)
434470```
435471
436- The saturation vapor pressure is
472+ These represent the latent heat of vaporization at the reference temperature and
473+ the specific heat capacity of each condensed phase. We can compute the specific heat
474+ difference `` \Delta c^β `` for liquid water:
475+
476+ ``` @example thermo
477+ using Breeze.Thermodynamics: vapor_gas_constant
478+ cᵖᵛ = thermo.vapor.heat_capacity
479+ cˡ = thermo.liquid.heat_capacity
480+ Δcˡ = cᵖᵛ - cˡ
481+ ```
482+
483+ This difference `` \Delta c^l ≈ `` $(round(1885 - 4181, digits=1)) J/(kg⋅K) is negative because
484+ water vapor has a lower heat capacity than liquid water.
485+
486+ ### Mixed-phase saturation vapor pressure
487+
488+ In atmospheric conditions near the freezing point, condensate may exist as a mixture of
489+ liquid and ice. Following [ Pressel2015] ( @citet ) , we model the saturation vapor pressure
490+ over a mixed-phase surface using a liquid fraction `` λ `` that varies smoothly between
491+ 0 (pure ice) and 1 (pure liquid). The effective latent heat and specific heat difference
492+ for the mixture are computed as weighted averages:
493+
494+ ``` math
495+ ℒ^{li}_0 = λ \, ℒ^l_0 + (1 - λ) \, ℒ^i_0 ,
496+ ```
497+
498+ ``` math
499+ \Delta c^{li} = λ \, \Delta c^l + (1 - λ) \, \Delta c^i .
500+ ```
501+
502+ These effective properties are then used in the Clausius-Clapeyron formula to compute
503+ the saturation vapor pressure over the mixed-phase surface. This approach ensures
504+ thermodynamic consistency and smooth transitions between pure liquid and pure ice states.
505+
506+ We can illustrate this by computing the mixed-phase specific heat difference for a
507+ 50/50 mixture:
508+
509+ ``` @example thermo
510+ Δcⁱ = thermo.vapor.heat_capacity - thermo.ice.heat_capacity
511+ λ = 0.5
512+ Δcˡⁱ = λ * Δcˡ + (1 - λ) * Δcⁱ
513+ ```
514+
515+ ### Visualizing saturation vapor pressure
516+
517+ The saturation vapor pressure over liquid, ice, and mixed-phase surfaces can be computed
518+ and visualized:
437519
438520``` @example
439521using Breeze
440- using Breeze.Thermodynamics: saturation_vapor_pressure
522+ using Breeze.Thermodynamics: saturation_vapor_pressure, PlanarMixedPhaseSurface
441523
442524thermo = ThermodynamicConstants()
443525
@@ -446,48 +528,99 @@ pᵛˡ⁺ = [saturation_vapor_pressure(Tⁱ, thermo, thermo.liquid) for Tⁱ in
446528pᵛⁱ⁺ = [saturation_vapor_pressure(Tⁱ, thermo, thermo.ice) for Tⁱ in T]
447529pᵛⁱ⁺[T .> thermo.triple_point_temperature] .= NaN
448530
531+ # Mixed-phase surface with 50% liquid, 50% ice
532+ mixed_surface = PlanarMixedPhaseSurface(0.5)
533+ pᵛᵐ⁺ = [saturation_vapor_pressure(Tⁱ, thermo, mixed_surface) for Tⁱ in T]
534+
449535using CairoMakie
450536
451537fig = Figure()
452- ax = Axis(fig[1, 1], xlabel="Temperature (ᵒK)", ylabel="Saturation vapor pressure pᵛ⁺ (Pa)", yscale = log10, xticks=200:20:320)
453- lines!(ax, T, pᵛˡ⁺, label="vapor pressure over liquid")
454- lines!(ax, T, pᵛⁱ⁺, linestyle=:dash, label="vapor pressure over ice")
538+ ax = Axis(fig[1, 1], xlabel="Temperature (ᵒK)", ylabel="Saturation vapor pressure pᵛ⁺ (Pa)",
539+ yscale = log10, xticks=200:20:320)
540+ lines!(ax, T, pᵛˡ⁺, label="liquid", linewidth=2)
541+ lines!(ax, T, pᵛⁱ⁺, label="ice", linestyle=:dash, linewidth=2)
542+ lines!(ax, T, pᵛᵐ⁺, label="mixed (λ=0.5)", linestyle=:dot, linewidth=2, color=:purple)
455543axislegend(ax, position=:rb)
456544fig
457545```
458546
459- The saturation specific humidity is
547+ The mixed-phase saturation vapor pressure lies between the liquid and ice curves,
548+ providing a smooth interpolation between the two pure phases.
549+
550+ ## Saturation specific humidity
551+
552+ The saturation specific humidity `` qᵛ⁺ `` is the maximum amount of water vapor that
553+ can exist in equilibrium with a condensed phase at a given temperature and density.
554+ It is related to the saturation vapor pressure by:
460555
461556``` math
462- qᵛ⁺ ≡ \frac{ρᵛ⁺}{ρ} = \frac{pᵛ⁺}{ρ Rᵐ T} .
557+ qᵛ⁺ ≡ \frac{ρᵛ⁺}{ρ} = \frac{pᵛ⁺}{ρ Rᵛ T} ,
463558```
464559
465- and this is what it looks like:
560+ where `` ρᵛ⁺ `` is the vapor density at saturation, `` ρ `` is the total air density,
561+ and `` Rᵛ `` is the specific gas constant for water vapor.
562+
563+ ### Visualizing saturation vapor pressure and specific humidity
564+
565+ We can visualize how both saturation vapor pressure and saturation specific humidity
566+ vary with temperature for different liquid fractions, demonstrating the smooth
567+ interpolation provided by the mixed-phase model:
466568
467569``` @example
468570using Breeze
469- using Breeze.Thermodynamics: saturation_specific_humidity
571+ using Breeze.Thermodynamics: saturation_vapor_pressure, saturation_specific_humidity, PlanarMixedPhaseSurface
470572
471573thermo = ThermodynamicConstants()
472574
473- p₀ = 101325
575+ # Temperature range covering typical atmospheric conditions
576+ T = collect(250:0.1:320)
577+ p₀ = 101325 # Surface pressure (Pa)
474578Rᵈ = Breeze.Thermodynamics.dry_air_gas_constant(thermo)
475- T = collect(273.2:0.1:313.2)
476- qᵛ⁺ = zeros(length(T))
477579
478- for i = 1:length(T)
479- ρ = p₀ / (Rᵈ * T[i])
480- qᵛ⁺[i] = saturation_specific_humidity(T[i], ρ, thermo, thermo.liquid)
481- end
580+ # Liquid fractions to visualize
581+ λ_values = [0.0, 0.25, 0.5, 0.75, 1.0]
582+ labels = ["ice (λ=0)", "λ=0.25", "λ=0.5", "λ=0.75", "liquid (λ=1)"]
583+ colors = [:blue, :cyan, :purple, :orange, :red]
584+ linestyles = [:solid, :dash, :dot, :dashdot, :solid]
482585
483586using CairoMakie
484587
485- fig = Figure()
486- ax = Axis(fig[1, 1], xlabel="Temperature (ᵒK)", ylabel="Saturation specific humidity qᵛ⁺ (kg kg⁻¹)")
487- lines!(ax, T, qᵛ⁺)
588+ fig = Figure(size=(1000, 400))
589+
590+ # Panel 1: Saturation vapor pressure
591+ ax1 = Axis(fig[1, 1], xlabel="Temperature (K)", ylabel="Saturation vapor pressure (Pa)",
592+ yscale=log10, title="Saturation vapor pressure")
593+
594+ for (i, λ) in enumerate(λ_values)
595+ surface = PlanarMixedPhaseSurface(λ)
596+ pᵛ⁺ = [saturation_vapor_pressure(Tⁱ, thermo, surface) for Tⁱ in T]
597+ lines!(ax1, T, pᵛ⁺, label=labels[i], color=colors[i], linestyle=linestyles[i], linewidth=2)
598+ end
599+
600+ axislegend(ax1, position=:lt)
601+
602+ # Panel 2: Saturation specific humidity
603+ ax2 = Axis(fig[1, 2], xlabel="Temperature (K)", ylabel="Saturation specific humidity (kg/kg)",
604+ title="Saturation specific humidity")
605+
606+ for (i, λ) in enumerate(λ_values)
607+ surface = PlanarMixedPhaseSurface(λ)
608+ qᵛ⁺ = zeros(length(T))
609+ for (j, Tⁱ) in enumerate(T)
610+ ρ = p₀ / (Rᵈ * Tⁱ) # Approximate density using dry air
611+ qᵛ⁺[j] = saturation_specific_humidity(Tⁱ, ρ, thermo, surface)
612+ end
613+ lines!(ax2, T, qᵛ⁺, label=labels[i], color=colors[i], linestyle=linestyles[i], linewidth=2)
614+ end
615+
488616fig
489617```
490618
619+ This figure shows how the liquid fraction `` λ `` smoothly interpolates between pure ice
620+ (`` λ = 0 `` ) and pure liquid (`` λ = 1 `` ). At lower temperatures, the differences between
621+ phases are more pronounced. The mixed-phase model allows for realistic representation of
622+ conditions near the freezing point where both liquid and ice may coexist.
623+
491624## Moist static energy
492625
493626For moist air, a convenient thermodynamic invariant that couples temperature, composition, and height is the moist static energy (MSE),
0 commit comments