Diagnostics

Breeze.jl provides a variety of diagnostic fields for analyzing atmospheric simulations. These diagnostics can be computed as KernelFunctionOperations, which allows them to be evaluated lazily or wrapped in Fields for storage and output.

Naming conventions

Diagnostic functions follow a naming convention that indicates their return type:

  • TitleCase names (e.g., VirtualPotentialTemperature, StaticEnergy): These functions always return a KernelFunctionOperation. These are "pure diagnostics" that are computed on-the-fly from the model state.

  • snake_case names (e.g., temperature, density): These functions may return either a Field or a KernelFunctionOperation, depending on the model formulation. When a quantity is directly stored or computed by a particular AtmosphereModel formulation, it is returned as a Field. Otherwise, it is computed on-the-fly as a KernelFunctionOperation.

This convention helps users understand whether a diagnostic is a stored model variable or a derived quantity.

Potential temperatures

Potential temperatures are conserved quantities that are useful for diagnosing atmospheric stability and identifying air masses. See the notation appendix for the symbols used ($θ$, $θᵛ$, $θᵉ$, $θˡⁱ$, $θᵇ$).

Potential temperature (mixture)

Breeze.AtmosphereModels.Diagnostics.PotentialTemperatureType
PotentialTemperature(model, flavor=:specific)

Return a KernelFunctionOperation representing the (mixture) potential temperature $θ$.

The potential temperature is defined as the temperature a parcel would have if adiabatically brought to a reference pressure $p₀$:

\[θ = \frac{T}{Π}\]

where $T$ is temperature and $Π = (p/p₀)^{Rᵐ/cᵖᵐ}$ is the mixture Exner function, computed using the moist air gas constant $Rᵐ$ and heat capacity $cᵖᵐ$.

Arguments

  • model: An AtmosphereModel instance.
  • flavor: Either :specific (default) to return $θ$, or :density to return $ρ θ$.

Examples

using Breeze

grid = RectilinearGrid(size=(1, 1, 8), extent=(1, 1, 1e3))
model = AtmosphereModel(grid)
set!(model, θ=300)

θ = PotentialTemperature(model)
Field(θ)

# output
1×1×8 Field{Center, Center, Center} on RectilinearGrid on CPU
├── grid: 1×1×8 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 1×1×3 halo
├── boundary conditions: FieldBoundaryConditions
│   └── west: Periodic, east: Periodic, south: Periodic, north: Periodic, bottom: ZeroFlux, top: ZeroFlux, immersed: Nothing
├── operand: KernelFunctionOperation at (Center, Center, Center)
├── status: time=0.0
└── data: 3×3×14 OffsetArray(::Array{Float64, 3}, 0:2, 0:2, -2:11) with eltype Float64 with indices 0:2×0:2×-2:11
    └── max=300.0, min=300.0, mean=300.0
source

Virtual potential temperature

Breeze.AtmosphereModels.Diagnostics.VirtualPotentialTemperatureType
VirtualPotentialTemperature(model, flavor=:specific)

Return a KernelFunctionOperation representing virtual potential temperature $θᵛ$.

Virtual potential temperature is the temperature that dry air would need to have in order to have the same density as moist air at the same pressure. It accounts for the effect of water vapor on air density:

\[θᵛ = θˡⁱ \left( qᵈ + ε qᵛ \right)\]

where $θˡⁱ$ is liquid-ice potential temperature, $qᵈ$ and $qᵛ$ are the specific humidities of dry air and vapor respectively, and $ε = Rᵛ / Rᵈ$ is the ratio between the vapor and dry air gas constants. $ε ≈ 1.608$ for water vapor and a dry air mixture typical to Earth's atmosphere.

using Breeze

grid = RectilinearGrid(size=(1, 1, 8), extent=(1, 1, 1e3))
model = AtmosphereModel(grid)
set!(model, θ=300, qᵗ=0.01)

θᵛ = VirtualPotentialTemperature(model)
Field(θᵛ)

# output
1×1×8 Field{Center, Center, Center} on RectilinearGrid on CPU
├── grid: 1×1×8 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 1×1×3 halo
├── boundary conditions: FieldBoundaryConditions
│   └── west: Periodic, east: Periodic, south: Periodic, north: Periodic, bottom: ZeroFlux, top: ZeroFlux, immersed: Nothing
├── operand: KernelFunctionOperation at (Center, Center, Center)
├── status: time=0.0
└── data: 3×3×14 OffsetArray(::Array{Float64, 3}, 0:2, 0:2, -2:11) with eltype Float64 with indices 0:2×0:2×-2:11
    └── max=304.824, min=304.824, mean=304.824

References

  • Emanuel, K. A. (1994). Atmospheric Convection (Oxford University Press).
source

Equivalent potential temperature

Breeze.AtmosphereModels.Diagnostics.EquivalentPotentialTemperatureType
EquivalentPotentialTemperature(model, flavor=:specific)

Return a KernelFunctionOperation representing equivalent potential temperature $θᵉ$.

Equivalent potential temperature is conserved during moist adiabatic processes (including condensation and evaporation) and is useful for identifying air masses and diagnosing moist instabilities. It is the temperature that a parcel would have if all its moisture were condensed out and the resulting latent heat used to warm the parcel, followed by adiabatic expansion to a reference pressure.

We use a formulation derived by Emanuel (1994),

\[θᵉ = T \left( \frac{p₀}{pᵈ} \right)^{Rᵈ / cᵖᵐ} \exp \left( \frac{ℒˡ qᵛ}{cᵖᵐ T} \right) ℋ^{- Rᵛ qᵛ / cᵖᵐ}\]

where $T$ is temperature, $pᵈ$ is dry air pressure, $p₀$ is the reference pressure, $ℒˡ$ is the latent heat of vaporization, $qᵛ$ is the vapor specific humidity, $ℋ$ is the relative humidity, and $cᵖᵐ$ is the heat capacity of the moist air mixture.

The formulation follows equation (34) of the paper by Bryan and Fritsch (2002), adapted from the derivation in the work by Durran and Klemp (1982).

Arguments

  • model: An AtmosphereModel instance.
  • flavor: Either :specific (default) to return $θᵉ$, or :density to return $ρ θᵉ$.

Examples

using Breeze

grid = RectilinearGrid(size=(1, 1, 8), extent=(1, 1, 1e3))
model = AtmosphereModel(grid)
set!(model, θ=300, qᵗ=0.01)

θᵉ = EquivalentPotentialTemperature(model)
Field(θᵉ)

# output
1×1×8 Field{Center, Center, Center} on RectilinearGrid on CPU
├── grid: 1×1×8 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 1×1×3 halo
├── boundary conditions: FieldBoundaryConditions
│   └── west: Periodic, east: Periodic, south: Periodic, north: Periodic, bottom: ZeroFlux, top: ZeroFlux, immersed: Nothing
├── operand: KernelFunctionOperation at (Center, Center, Center)
├── status: time=0.0
└── data: 3×3×14 OffsetArray(::Array{Float64, 3}, 0:2, 0:2, -2:11) with eltype Float64 with indices 0:2×0:2×-2:11
    └── max=326.162, min=325.849, mean=326.005

References

  • Bryan, G. H. and Fritsch, J. M. (2002). A benchmark simulation for moist nonhydrostatic numerical models. Monthly Weather Review 130, 2917–2928.
  • Durran, D. R. and Klemp, J. B. (1982). On the effects of moisture on the Brunt-Väisälä frequency. Journal of the Atmospheric Sciences 39, 2152–2158.
  • Emanuel, K. A. (1994). Atmospheric Convection (Oxford University Press).
source

Liquid-ice potential temperature

Breeze.AtmosphereModels.Diagnostics.LiquidIcePotentialTemperatureType
LiquidIcePotentialTemperature(model, flavor=:specific)

Return a KernelFunctionOperation representing liquid-ice potential temperature $θˡⁱ$.

Liquid-ice potential temperature is a conserved quantity under moist adiabatic processes that accounts for the latent heat associated with liquid water and ice:

\[θˡⁱ = θ \left (1 - \frac{ℒˡᵣ qˡ + ℒⁱᵣ qⁱ}{cᵖᵐ T} \right )\]

or

\[θˡⁱ = \frac{T}{Π} \left (1 - \frac{ℒˡᵣ qˡ + ℒⁱᵣ qⁱ}{cᵖᵐ T} \right )\]

where $θ$ is the potential temperature, $Π = (p/p₀)^{Rᵐ/cᵖᵐ}$ is the Exner function using mixture properties, $ℒˡᵣ$ and $ℒⁱᵣ$ are the reference latent heats of vaporization and sublimation, $qˡ$ and $qⁱ$ are the liquid and ice specific humidities, and $cᵖᵐ$ is the moist air heat capacity.

This is the prognostic thermodynamic variable used in LiquidIcePotentialTemperatureThermodynamics.

Arguments

  • model: An AtmosphereModel instance.
  • flavor: Either :specific (default) to return $θˡⁱ$, or :density to return $ρ θˡⁱ$.

Examples

using Breeze

grid = RectilinearGrid(size=(1, 1, 8), extent=(1, 1, 1e3))
model = AtmosphereModel(grid)
set!(model, θ=300)

θˡⁱ = LiquidIcePotentialTemperature(model)
Field(θˡⁱ)

# output
1×1×8 Field{Center, Center, Center} on RectilinearGrid on CPU
├── grid: 1×1×8 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 1×1×3 halo
├── boundary conditions: FieldBoundaryConditions
│   └── west: Periodic, east: Periodic, south: Periodic, north: Periodic, bottom: ZeroFlux, top: ZeroFlux, immersed: Nothing
├── operand: KernelFunctionOperation at (Center, Center, Center)
├── status: time=0.0
└── data: 3×3×14 OffsetArray(::Array{Float64, 3}, 0:2, 0:2, -2:11) with eltype Float64 with indices 0:2×0:2×-2:11
    └── max=300.0, min=300.0, mean=300.0
source

Stability-equivalent potential temperature

Breeze.AtmosphereModels.Diagnostics.StabilityEquivalentPotentialTemperatureType
StabilityEquivalentPotentialTemperature(model, flavor=:specific)

Return a KernelFunctionOperation representing stability-equivalent potential temperature $θᵇ$.

Stability-equivalent potential temperature is a moist-conservative variable suitable for computing the moist Brunt-Väisälä frequency. It follows from the derivation in the paper by Durran and Klemp (1982), who show that the moist Brunt-Väisälä frequency $Nᵐ$ is correctly expressed in terms of the vertical gradient of a moist-conservative variable.

The formulation is based on equation (17) by Durran and Klemp (1982):

\[θᵇ = θᵉ \left( \frac{T}{Tᵣ} \right)^{cˡ qˡ / cᵖᵐ}\]

where $θᵉ$ is the equivalent potential temperature, $T$ is temperature, $Tᵣ$ is the energy reference temperature, $cˡ$ is the heat capacity of liquid water, $qᵗ$ is the total moisture specific humidity, and $cᵖᵐ$ is the moist air heat capacity.

This quantity is conserved along moist adiabats and is appropriate for use in stability calculations in saturated atmospheres.

Arguments

  • model: An AtmosphereModel instance.
  • flavor: Either :specific (default) to return $θᵇ$, or :density to return $ρ θᵇ$.

Examples

using Breeze

grid = RectilinearGrid(size=(1, 1, 8), extent=(1, 1, 1e3))
model = AtmosphereModel(grid)
set!(model, θ=300, qᵗ=0.01)

θᵇ = StabilityEquivalentPotentialTemperature(model)
Field(θᵇ)

# output
1×1×8 Field{Center, Center, Center} on RectilinearGrid on CPU
├── grid: 1×1×8 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 1×1×3 halo
├── boundary conditions: FieldBoundaryConditions
│   └── west: Periodic, east: Periodic, south: Periodic, north: Periodic, bottom: ZeroFlux, top: ZeroFlux, immersed: Nothing
├── operand: KernelFunctionOperation at (Center, Center, Center)
├── status: time=0.0
└── data: 3×3×14 OffsetArray(::Array{Float64, 3}, 0:2, 0:2, -2:11) with eltype Float64 with indices 0:2×0:2×-2:11
    └── max=326.162, min=325.849, mean=326.005

References

  • Durran, D. R. and Klemp, J. B. (1982). On the effects of moisture on the Brunt-Väisälä frequency. Journal of the Atmospheric Sciences 39, 2152–2158.
source

Static energy

Static energy is another conserved thermodynamic variable used in atmospheric models. It combines sensible heat, gravitational potential energy, and latent heat contributions.

Breeze.AtmosphereModels.Diagnostics.StaticEnergyType
StaticEnergy(model, flavor=:specific)

Return a KernelFunctionOperation representing moist static energy $e$.

Moist static energy is a conserved quantity in adiabatic, frictionless flow that combines sensible heat, gravitational potential energy, and latent heat:

\[e = cᵖᵐ T + g z - ℒˡᵣ qˡ - ℒⁱᵣ qⁱ\]

where $cᵖᵐ$ is the moist air heat capacity, $T$ is temperature, $g$ is gravitational acceleration, $z$ is height, and $ℒˡᵣ qˡ + ℒⁱᵣ qⁱ$ is the latent heat content of condensate.

This is the prognostic thermodynamic variable used in StaticEnergyThermodynamics.

Arguments

  • model: An AtmosphereModel instance.
  • flavor: Either :specific (default) to return $e$, or :density to return $ρ e$.

Examples

using Breeze

grid = RectilinearGrid(size=(1, 1, 8), extent=(1, 1, 1e3))
model = AtmosphereModel(grid)
set!(model, θ=300)

e = StaticEnergy(model)
Field(e)

# output
1×1×8 Field{Center, Center, Center} on RectilinearGrid on CPU
├── grid: 1×1×8 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 1×1×3 halo
├── boundary conditions: FieldBoundaryConditions
│   └── west: Periodic, east: Periodic, south: Periodic, north: Periodic, bottom: ZeroFlux, top: ZeroFlux, immersed: Nothing
├── operand: KernelFunctionOperation at (Center, Center, Center)
├── status: time=0.0
└── data: 3×3×14 OffsetArray(::Array{Float64, 3}, 0:2, 0:2, -2:11) with eltype Float64 with indices 0:2×0:2×-2:11
    └── max=3.03055e5, min=3.02663e5, mean=3.02859e5
source

Saturation specific humidity

The saturation specific humidity is a key diagnostic for understanding moisture in the atmosphere. It represents the maximum amount of water vapor that air can hold at a given temperature and pressure.

Breeze.AtmosphereModels.Diagnostics.SaturationSpecificHumidityType
SaturationSpecificHumidity(
    model
) -> KernelFunctionOperation{Center, Center, Center, _A, _B, K, Tuple{}} where {_A, _B, K<:Breeze.AtmosphereModels.Diagnostics.SaturationSpecificHumidityKernelFunction}
SaturationSpecificHumidity(
    model,
    flavor_symbol
) -> KernelFunctionOperation{Center, Center, Center, _A, _B, K, Tuple{}} where {_A, _B, K<:Breeze.AtmosphereModels.Diagnostics.SaturationSpecificHumidityKernelFunction}

Return a KernelFunctionOperation representing the specified flavor of saturation specific humidity $qᵛ⁺$.

Flavor options

  • :prognostic

    Return the saturation specific humidity corresponding to the model's prognostic state. This is the same as the equilibrium saturation specific humidity for saturated conditions and a model that uses saturation adjustment microphysics.

  • :equilibrium

    Return the saturation specific humidity in potentially-saturated conditions, using the model.specific_moisture. This is equivalent to the :total_moisture flavor under saturated conditions with no condensate; or in other words, if model.specific_moisture happens to be equal to the saturation specific humidity.

  • :total_moisture

    Return saturation specific humidity in the case that the total specific moisture is equal to the saturation specific humidity and there is no condensate. This is useful for manufacturing perfectly saturated initial conditions.

source