Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/microphysics/saturation_adjustment.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ The saturation specific humidity is then
using Breeze
using Breeze.MoistAirBuoyancies: saturation_specific_humidity, HeightReferenceThermodynamicState

thermo = AtmosphereThermodynamics()
thermo = ThermodynamicConstants()
ref = ReferenceStateConstants(base_pressure=101325, potential_temperature=288)

z = 0.0 # [m] height
Expand Down
10 changes: 5 additions & 5 deletions docs/src/thermodynamics.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

```@setup thermo
using Breeze
thermo = AtmosphereThermodynamics()
thermo = ThermodynamicConstants()
```

Breeze implements thermodynamic relations for moist atmospheres --
Expand Down Expand Up @@ -148,7 +148,7 @@ using Breeze
using Breeze.Thermodynamics: reference_pressure, reference_density
using CairoMakie

thermo = AtmosphereThermodynamics()
thermo = ThermodynamicConstants()
constants = ReferenceStateConstants(base_pressure=101325, potential_temperature=288)
grid = RectilinearGrid(size=160, z=(0, 12_000), topology=(Flat, Flat, Bounded))

Expand Down Expand Up @@ -212,7 +212,7 @@ Central to Breeze's implementation of moist thermodynamics is a struct that
holds parameters like the molar gas constant and molar masses,

```@example thermo
thermo = AtmosphereThermodynamics()
thermo = ThermodynamicConstants()
```

The default parameter evince basic facts about water vapor air typical to Earth's atmosphere:
Expand Down Expand Up @@ -298,7 +298,7 @@ The saturation vapor pressure is
using Breeze
using Breeze.Thermodynamics: saturation_vapor_pressure

thermo = AtmosphereThermodynamics()
thermo = ThermodynamicConstants()

T = collect(200:0.1:320)
pᵛˡ⁺ = [saturation_vapor_pressure(Tⁱ, thermo, thermo.liquid) for Tⁱ in T]
Expand Down Expand Up @@ -327,7 +327,7 @@ and this is what it looks like:
using Breeze
using Breeze.MoistAirBuoyancies: saturation_specific_humidity

thermo = AtmosphereThermodynamics()
thermo = ThermodynamicConstants()
ref = ReferenceStateConstants(base_pressure=101325, potential_temperature=288)

z = 0
Expand Down
4 changes: 2 additions & 2 deletions examples/JRA55_saturation_specific_humidity.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using JLD2
using Breeze
using Breeze: saturation_specific_humidity, AtmosphereThermodynamics
using Breeze: saturation_specific_humidity, ThermodynamicConstants
using GLMakie

@load "JRA55_atmospheric_state_Jan_1_1991.jld2" q T p

thermo = AtmosphereThermodynamics()
thermo = ThermodynamicConstants()

ρ = 1.2
qᵛ★ = saturation_specific_humidity.(T, 1.2, Ref(thermo))
Expand Down
2 changes: 1 addition & 1 deletion examples/large_yeager_saturation_specific_humidity.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using GLMakie
using Breeze

thermo = Breeze.AtmosphereThermodynamics()
thermo = Breeze.ThermodynamicConstants()

saturation_specific_humidity_large_yeager(T, ρ) = 640380 * exp(-5107.4 / T) / ρ

Expand Down
2 changes: 1 addition & 1 deletion src/AtmosphereModels/anelastic_formulation.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using ..Thermodynamics:
AtmosphereThermodynamics,
ThermodynamicConstants,
ReferenceStateConstants,
reference_pressure,
reference_density,
Expand Down
6 changes: 3 additions & 3 deletions src/AtmosphereModels/atmosphere_model.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using ..Thermodynamics:
AtmosphereThermodynamics,
ThermodynamicConstants,
ReferenceStateConstants,
reference_pressure,
reference_density,
Expand Down Expand Up @@ -69,7 +69,7 @@ end
"""
AtmosphereModel(grid;
clock = Clock(grid),
thermodynamics = AtmosphereThermodynamics(eltype(grid)),
thermodynamics = ThermodynamicConstants(eltype(grid)),
formulation = default_formulation(grid, thermodynamics),
absolute_humidity = DefaultValue(),
tracers = tuple(),
Expand Down Expand Up @@ -109,7 +109,7 @@ Pauluis, O. (2008). Thermodynamic consistency of the anelastic approximation for
"""
function AtmosphereModel(grid;
clock = Clock(grid),
thermodynamics = AtmosphereThermodynamics(eltype(grid)),
thermodynamics = ThermodynamicConstants(eltype(grid)),
formulation = default_formulation(grid, thermodynamics),
absolute_humidity = DefaultValue(),
tracers = tuple(),
Expand Down
2 changes: 1 addition & 1 deletion src/Breeze.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module Breeze

export
MoistAirBuoyancy,
AtmosphereThermodynamics,
ThermodynamicConstants,
ReferenceStateConstants,
AnelasticFormulation,
AtmosphereModel,
Expand Down
8 changes: 4 additions & 4 deletions src/MoistAirBuoyancies.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import Oceananigans.BuoyancyFormulations: AbstractBuoyancyFormulation,
required_tracers

using ..Thermodynamics:
AtmosphereThermodynamics,
ThermodynamicConstants,
ReferenceStateConstants,
mixture_heat_capacity,
mixture_gas_constant,
Expand All @@ -38,7 +38,7 @@ end

"""
MoistAirBuoyancy(FT=Oceananigans.defaults.FloatType;
thermodynamics = AtmosphereThermodynamics(FT),
thermodynamics = ThermodynamicConstants(FT),
reference_constants = ReferenceStateConstants{FT}(101325, 290))

Return a MoistAirBuoyancy formulation that can be provided as input to an `AtmosphereModel`
Expand All @@ -56,7 +56,7 @@ julia> using Breeze, Oceananigans
julia> buoyancy = MoistAirBuoyancy()
MoistAirBuoyancy
├── reference_constants: Breeze.Thermodynamics.ReferenceStateConstants{Float64}
└── thermodynamics: AtmosphereThermodynamics
└── thermodynamics: ThermodynamicConstants

julia> model = NonhydrostaticModel(; grid = RectilinearGrid(size=(8, 8, 8), extent=(1, 2, 3)),
buoyancy, tracers = (:θ, :q))
Expand All @@ -71,7 +71,7 @@ NonhydrostaticModel{CPU, RectilinearGrid}(time = 0 seconds, iteration = 0)
```
"""
function MoistAirBuoyancy(FT=Oceananigans.defaults.FloatType;
thermodynamics = AtmosphereThermodynamics(FT),
thermodynamics = ThermodynamicConstants(FT),
reference_constants = ReferenceStateConstants{FT}(101325, 290))

AT = typeof(thermodynamics)
Expand Down
2 changes: 1 addition & 1 deletion src/Thermodynamics/Thermodynamics.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Thermodynamics

export AtmosphereThermodynamics, ReferenceStateConstants, IdealGas,
export ThermodynamicConstants, ReferenceStateConstants, IdealGas,
PhaseTransitionConstants, CondensedPhase,
mixture_gas_constant, mixture_heat_capacity

Expand Down
115 changes: 57 additions & 58 deletions src/Thermodynamics/atmosphere_thermodynamics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ end
liquid_water(FT) = CondensedPhase(FT; latent_heat=2500800, heat_capacity=4181)
water_ice(FT) = CondensedPhase(FT; latent_heat=2834000, heat_capacity=2108)

struct AtmosphereThermodynamics{FT, C, S}
struct ThermodynamicConstants{FT, C, S}
molar_gas_constant :: FT
gravitational_acceleration :: FT
energy_reference_temperature :: FT
Expand All @@ -103,9 +103,9 @@ struct AtmosphereThermodynamics{FT, C, S}
solid :: S
end

Base.summary(at::AtmosphereThermodynamics{FT}) where FT = "AtmosphereThermodynamics{$FT}"
Base.summary(at::ThermodynamicConstants{FT}) where FT = "ThermodynamicConstants{$FT}"

function Base.show(io::IO, at::AtmosphereThermodynamics)
function Base.show(io::IO, at::ThermodynamicConstants)
print(io, summary(at), ":", '\n',
"├── molar_gas_constant: ", at.molar_gas_constant, "\n",
"├── gravitational_acceleration: ", at.gravitational_acceleration, "\n",
Expand All @@ -118,9 +118,9 @@ function Base.show(io::IO, at::AtmosphereThermodynamics)
"└── solid: ", at.solid)
end

Base.eltype(::AtmosphereThermodynamics{FT}) where FT = FT
Base.eltype(::ThermodynamicConstants{FT}) where FT = FT

function Adapt.adapt_structure(to, thermo::AtmosphereThermodynamics)
function Adapt.adapt_structure(to, thermo::ThermodynamicConstants)
molar_gas_constant = adapt(to, thermo.molar_gas_constant)
gravitational_acceleration = adapt(to, thermo.gravitational_acceleration)
dry_air = adapt(to, thermo.dry_air)
Expand All @@ -133,38 +133,37 @@ function Adapt.adapt_structure(to, thermo::AtmosphereThermodynamics)
FT = typeof(molar_gas_constant)
C = typeof(liquid)
S = typeof(solid)
return AtmosphereThermodynamics{FT, C, S}(molar_gas_constant,
gravitational_acceleration,
energy_reference_temperature,
triple_point_temperature,
triple_point_pressure,
dry_air,
vapor,
liquid,
solid)
return ThermodynamicConstants{FT, C, S}(molar_gas_constant,
gravitational_acceleration,
energy_reference_temperature,
triple_point_temperature,
triple_point_pressure,
dry_air,
vapor,
liquid,
solid)
end

"""
AtmosphereThermodynamics(FT = Oceananigans.defaults.FloatType;
gravitational_acceleration = 9.81,
molar_gas_constant = 8.314462618,
energy_reference_temperature = 273.16,
triple_point_temperature = 273.16,
triple_point_pressure = 611.657,
dry_air_molar_mass = 0.02897,
dry_air_heat_capacity = 1005,
vapor_molar_mass = 0.018015,
vapor_heat_capacity = 1850,
liquid = liquid_water(FT),
solid = water_ice(FT),
condensed_phases = nothing)

Create `AtmosphereThermodynamics` with parameters that represent gaseous mixture of dry "air"
ThermodynamicConstants(FT = Oceananigans.defaults.FloatType;
molar_gas_constant = 8.314462618,
gravitational_acceleration = 9.81,
energy_reference_temperature = 273.16,
triple_point_temperature = 273.16,
triple_point_pressure = 611.657,
dry_air_molar_mass = 0.02897,
dry_air_heat_capacity = 1005,
vapor_molar_mass = 0.018015,
vapor_heat_capacity = 1850,
liquid = liquid_water(FT),
solid = water_ice(FT))

Create `ThermodynamicConstants` with parameters that represent gaseous mixture of dry "air"
and vapor, as well as condensed liquid and solid phases.
The `triple_point_temperature` and `triple_point_pressure` may be combined with
internal energy parameters for condensed phases to compute the vapor pressure
at the boundary between vapor and a homogeneous sample of the condensed phase.
The `gravitational_acceleration` parameter is included to compute reference_state
The `gravitational_acceleration` parameter is included to compute `reference_state`
quantities associated with hydrostatic balance.

The Clausius-Clapeyron relation describes the pressure-temperature relationship during phase
Expand Down Expand Up @@ -198,43 +197,43 @@ Note: any reference values for pressure and temperature can be used in principle
The advantage of using reference values at the triple point is that the same values
can then be used for both condensation (vapor → liquid) and deposition (vapor → ice).
"""
function AtmosphereThermodynamics(FT = Oceananigans.defaults.FloatType;
molar_gas_constant = 8.314462618,
gravitational_acceleration = 9.81,
energy_reference_temperature = 273.16,
triple_point_temperature = 273.16,
triple_point_pressure = 611.657,
dry_air_molar_mass = 0.02897,
dry_air_heat_capacity = 1005,
vapor_molar_mass = 0.018015,
vapor_heat_capacity = 1850,
liquid = liquid_water(FT),
solid = water_ice(FT))
function ThermodynamicConstants(FT = Oceananigans.defaults.FloatType;
molar_gas_constant = 8.314462618,
gravitational_acceleration = 9.81,
energy_reference_temperature = 273.16,
triple_point_temperature = 273.16,
triple_point_pressure = 611.657,
dry_air_molar_mass = 0.02897,
dry_air_heat_capacity = 1005,
vapor_molar_mass = 0.018015,
vapor_heat_capacity = 1850,
liquid = liquid_water(FT),
solid = water_ice(FT))

dry_air = IdealGas(FT; molar_mass = dry_air_molar_mass,
heat_capacity = dry_air_heat_capacity)

vapor = IdealGas(FT; molar_mass = vapor_molar_mass,
heat_capacity = vapor_heat_capacity)

return AtmosphereThermodynamics(convert(FT, molar_gas_constant),
convert(FT, gravitational_acceleration),
convert(FT, energy_reference_temperature),
convert(FT, triple_point_temperature),
convert(FT, triple_point_pressure),
dry_air,
vapor,
liquid,
solid)
return ThermodynamicConstants(convert(FT, molar_gas_constant),
convert(FT, gravitational_acceleration),
convert(FT, energy_reference_temperature),
convert(FT, triple_point_temperature),
convert(FT, triple_point_pressure),
dry_air,
vapor,
liquid,
solid)
end

const AT = AtmosphereThermodynamics
const TC = ThermodynamicConstants
const IG = IdealGas

@inline vapor_gas_constant(thermo::AT) = thermo.molar_gas_constant / thermo.vapor.molar_mass
@inline dry_air_gas_constant(thermo::AT) = thermo.molar_gas_constant / thermo.dry_air.molar_mass
@inline vapor_gas_constant(thermo::TC) = thermo.molar_gas_constant / thermo.vapor.molar_mass
@inline dry_air_gas_constant(thermo::TC) = thermo.molar_gas_constant / thermo.dry_air.molar_mass

const NonCondensingAtmosphereThermodynamics{FT} = AtmosphereThermodynamics{FT, Nothing, Nothing}
const NonCondensingThermodynamicConstants{FT} = ThermodynamicConstants{FT, Nothing, Nothing}

"""
mixture_gas_constant(q, thermo)
Expand All @@ -256,12 +255,12 @@ where:

# Arguments
- `q`: Specific humidity (dimensionless)
- `thermo`: `AtmosphereThermodynamics` instance containing gas constants
- `thermo`: `ThermodynamicConstants` instance containing gas constants

# Returns
- Gas constant of the moist air mixture in J/(kg·K)
"""
@inline function mixture_gas_constant(q, thermo::AT)
@inline function mixture_gas_constant(q, thermo::TC)
Rᵈ = dry_air_gas_constant(thermo)
Rᵛ = vapor_gas_constant(thermo)
return Rᵈ * (1 - q) + Rᵛ * q
Expand All @@ -274,7 +273,7 @@ Compute the heat capacity of state air given the total specific humidity q
and assuming that condensate mass ratio qᶜ ≪ q, where qℓ is the mass ratio of
liquid condensate.
"""
@inline function mixture_heat_capacity(q, thermo::AT)
@inline function mixture_heat_capacity(q, thermo::TC)
cᵖᵈ = thermo.dry_air.heat_capacity
cᵖᵛ = thermo.vapor.heat_capacity
return cᵖᵈ * (1 - q) + cᵖᵛ * q
Expand Down
4 changes: 2 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ using Oceananigans

@testset "Breeze.jl" begin
@testset "Thermodynamics" begin
thermo = AtmosphereThermodynamics()
thermo = ThermodynamicConstants()

# Test Saturation specific humidity calculation
T = 293.15 # 20°C
Expand All @@ -16,7 +16,7 @@ using Oceananigans
@testset "AtmosphereModel" begin
for FT in (Float32, Float64)
grid = RectilinearGrid(FT, size=(8, 8, 8), x=(0, 1_000), y=(0, 1_000), z=(0, 1_000))
thermo = AtmosphereThermodynamics(FT)
thermo = ThermodynamicConstants(FT)

for p₀ in (101325, 100000)
for θ₀ in (288, 300)
Expand Down
3 changes: 3 additions & 0 deletions test/runtests_setup.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using Test
using Breeze
using Oceananigans
Loading