Fast, differentiable moist thermodynamics for Earth system models.
93
stars
583
commits
Julia
primary language
Sep 1, 2026
updated
The Thermodynamics.jl package implements the thermodynamic formulation of the CliMA Earth System Model (Yatunin et al., 2026). It provides a consistent framework for moist thermodynamics based on the Rankine-Kirchhoff approximations (Romps, 2021), and thermodynamic functions for moist air including all phases of water (vapor, liquid, and ice).
using Pkg
Pkg.add("Thermodynamics")
Pkg.add("ClimaParams")
Pkg.add("RootSolvers") # needed to select a solver for saturation adjustment
Thermodynamics.jl provides a functional, stateless API. You import the package (TD) and pass a parameter set plus thermodynamic variables (e.g., density, internal energy, specific humidities) directly to functions.
import Thermodynamics as TD
# Use RootSolvers for the saturation adjustment method
import RootSolvers as RS
using ClimaParams
# 1. Create thermodynamic parameters
# (requires a definition of the parameter set, e.g. from ClimaParams)
params = TD.Parameters.ThermodynamicsParameters(Float64)
# 2. Define your thermodynamic variables
ρ = 1.1 # Density [kg/m³]
e_int = -36000.0 # Internal energy [J/kg, can be negative]
q_tot = 0.015 # Total specific humidity [kg/kg]
q_liq = 0.005 # Liquid specific humidity [kg/kg]
q_ice = 0.001 # Ice specific humidity [kg/kg]
# 3. Compute properties directly
T = TD.air_temperature(params, e_int, q_tot, q_liq, q_ice)
p = TD.air_pressure(params, T, ρ, q_tot, q_liq, q_ice)
To find the phase equilibrium temperature and phase partition from thermodynamic variables (e.g., given ρ, e_int, q_tot), use saturation_adjustment:
# Solve for phase equilibrium (T, q_liq, q_ice) given (ρ, e_int, q_tot)
# using SecantMethod
sol = TD.saturation_adjustment(
RS.SecantMethod, # Root-solving method
params, # Parameter set
TD.ρe(), # Formulation: Density & Internal Energy
ρ, e_int, q_tot, # Input variables
10, # Max iterations
1e-3 # Relative tolerance
)
println("Equilibrium T: ", sol.T)
println("Liquid q: ", sol.q_liq)
println("Ice q: ", sol.q_ice)
println("Converged: ", sol.converged)
(ρ, e_int), (p, e_int), (p, h), (p, ρ), (p, θ_li), or (ρ, θ_li).ClimaParams.Functions in Thermodynamics.jl are stateless. They take a ThermodynamicsParameters struct and the necessary thermodynamic variables (e.g., T, ρ, q...) as arguments. This design fits naturally into large-scale simulations (e.g., with ClimaAtmos.jl).
The working fluid is moist air (dry air + water vapor + liquid water + ice, which may include precipitation). We treat it as a mixture of ideal gases and condensed phases, ensuring rigorous mass and energy conservation.
All quantities are derived from the calorically perfect gas assumption with constant specific heat capacities. This provides a consistent, closed set of equations for saturation vapor pressures (the so-called Rankine-Kirchhoff approximation), latent heats, and other derived quantities.
Contributors should follow the shared CliMA engineering standards in docs/dev-guides/, which cover architecture, performance, code quality, documentation, and workflows. These are vendored from CliMA/DeveloperGuides. The repo's AGENTS.md is a starting point for AI agents with repo-specific guidance.
Thermodynamics.jl is the thermodynamic core for the CliMA ecosystem, including:
If you use Thermodynamics.jl in your research, please cite the paper describing the formulation it implements:
Yatunin, D., Byrne, S., Kawczynski, C., Kandala, S., Bozzola, G., Sridhar, A., Shen, Z., Jaruga, A., Sloan, J., He, J., Huang, D. Z., Barra, V., Chew, R., Boral, A., Chen, Y.-F., Knoth, O., Ullrich, P., Mbengue, C., and Schneider, T. (2026). The Climate Modeling Alliance Atmosphere Dynamical Core: Concepts, Numerics, and Scaling. Journal of Advances in Modeling Earth Systems. doi:10.1029/2025MS005014
Machine-readable metadata is in CITATION.cff.
For questions, check the documentation or open an issue on GitHub.
Julia
100.0%
Fast, differentiable moist thermodynamics for Earth system models.
93
stars
583
commits
Julia
primary language
Sep 1, 2026
updated
The Thermodynamics.jl package implements the thermodynamic formulation of the CliMA Earth System Model (Yatunin et al., 2026). It provides a consistent framework for moist thermodynamics based on the Rankine-Kirchhoff approximations (Romps, 2021), and thermodynamic functions for moist air including all phases of water (vapor, liquid, and ice).
using Pkg
Pkg.add("Thermodynamics")
Pkg.add("ClimaParams")
Pkg.add("RootSolvers") # needed to select a solver for saturation adjustment
Thermodynamics.jl provides a functional, stateless API. You import the package (TD) and pass a parameter set plus thermodynamic variables (e.g., density, internal energy, specific humidities) directly to functions.
import Thermodynamics as TD
# Use RootSolvers for the saturation adjustment method
import RootSolvers as RS
using ClimaParams
# 1. Create thermodynamic parameters
# (requires a definition of the parameter set, e.g. from ClimaParams)
params = TD.Parameters.ThermodynamicsParameters(Float64)
# 2. Define your thermodynamic variables
ρ = 1.1 # Density [kg/m³]
e_int = -36000.0 # Internal energy [J/kg, can be negative]
q_tot = 0.015 # Total specific humidity [kg/kg]
q_liq = 0.005 # Liquid specific humidity [kg/kg]
q_ice = 0.001 # Ice specific humidity [kg/kg]
# 3. Compute properties directly
T = TD.air_temperature(params, e_int, q_tot, q_liq, q_ice)
p = TD.air_pressure(params, T, ρ, q_tot, q_liq, q_ice)
To find the phase equilibrium temperature and phase partition from thermodynamic variables (e.g., given ρ, e_int, q_tot), use saturation_adjustment:
# Solve for phase equilibrium (T, q_liq, q_ice) given (ρ, e_int, q_tot)
# using SecantMethod
sol = TD.saturation_adjustment(
RS.SecantMethod, # Root-solving method
params, # Parameter set
TD.ρe(), # Formulation: Density & Internal Energy
ρ, e_int, q_tot, # Input variables
10, # Max iterations
1e-3 # Relative tolerance
)
println("Equilibrium T: ", sol.T)
println("Liquid q: ", sol.q_liq)
println("Ice q: ", sol.q_ice)
println("Converged: ", sol.converged)
(ρ, e_int), (p, e_int), (p, h), (p, ρ), (p, θ_li), or (ρ, θ_li).ClimaParams.Functions in Thermodynamics.jl are stateless. They take a ThermodynamicsParameters struct and the necessary thermodynamic variables (e.g., T, ρ, q...) as arguments. This design fits naturally into large-scale simulations (e.g., with ClimaAtmos.jl).
The working fluid is moist air (dry air + water vapor + liquid water + ice, which may include precipitation). We treat it as a mixture of ideal gases and condensed phases, ensuring rigorous mass and energy conservation.
All quantities are derived from the calorically perfect gas assumption with constant specific heat capacities. This provides a consistent, closed set of equations for saturation vapor pressures (the so-called Rankine-Kirchhoff approximation), latent heats, and other derived quantities.
Contributors should follow the shared CliMA engineering standards in docs/dev-guides/, which cover architecture, performance, code quality, documentation, and workflows. These are vendored from CliMA/DeveloperGuides. The repo's AGENTS.md is a starting point for AI agents with repo-specific guidance.
Thermodynamics.jl is the thermodynamic core for the CliMA ecosystem, including:
If you use Thermodynamics.jl in your research, please cite the paper describing the formulation it implements:
Yatunin, D., Byrne, S., Kawczynski, C., Kandala, S., Bozzola, G., Sridhar, A., Shen, Z., Jaruga, A., Sloan, J., He, J., Huang, D. Z., Barra, V., Chew, R., Boral, A., Chen, Y.-F., Knoth, O., Ullrich, P., Mbengue, C., and Schneider, T. (2026). The Climate Modeling Alliance Atmosphere Dynamical Core: Concepts, Numerics, and Scaling. Journal of Advances in Modeling Earth Systems. doi:10.1029/2025MS005014
Machine-readable metadata is in CITATION.cff.
For questions, check the documentation or open an issue on GitHub.
Julia
100.0%