Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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 .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ steps:

- label: "CPU tests"
command:
- "THERMODYNAMICS_INCLUDE_DEPRECATED=false julia --project=test/ --color=yes test/runtests.jl"
- "julia --project=test/ --color=yes test/runtests.jl"
agents:
slurm_ntasks: 1
timeout_in_minutes: 60
Expand Down
11 changes: 5 additions & 6 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
Thermodynamics.jl Release Notes
========================

v1.xxx (TODO: release once refactoring is done)
v1.0.0
--------

- ![][[badge-✨feature/enhancement]] Complete rewrite of documentation
- ![][[badge-💥breaking]] Removal of the deprecated object-oriented and state-based API (e.g., `ThermodynamicState`, `PhasePartition`, `PhaseEquil`). The package now relies exclusively on a stateless, completely functional API.
- ![][[badge-🚀performance]] Enforced zero-allocations across core routines (`air_temperature`, `air_pressure`, `saturation_adjustment` with fixed iterations) backed by explicit testing.
- ![][[badge-✨feature/enhancement]] Upgraded testing infrastructure: `Documenter.doctest` continuously checks all mathematical examples in the docstrings.
- ![][[badge-✨feature/enhancement]] Rewrite of documentation
- Restructured documentation for better organization and clarity
- Updated all function documentation to be consistent and comprehensive
- Improved code examples and usage patterns throughout documentation
Expand All @@ -17,10 +20,6 @@ v1.xxx (TODO: release once refactoring is done)
- Added comprehensive tests and physical consistency validation for these functions
PR [259](https://github.com/CliMA/Thermodynamics.jl/pull/259)
PR [263](https://github.com/CliMA/Thermodynamics.jl/pull/263)

main
----

- Renamed `specific_enthalpy*` to `enthalpy*`.
- Renamed `specific_entropy*` to `entropy*`.
- Renamed `latent_heat_liq_ice` to `humidity_weighted_latent_heat`.
Expand Down
5 changes: 2 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name = "Thermodynamics"
uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c"
authors = ["Climate Modeling Alliance"]
version = "0.15.8"
version = "1.0.0"

[deps]
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"

JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
RootSolvers = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74"

Expand All @@ -18,7 +18,6 @@ CreateParametersExt = "ClimaParams"
[compat]
ClimaParams = "1"
ForwardDiff = "1.0.1"

Random = "1"
RootSolvers = "0.4, 1"
julia = "1.6"
73 changes: 0 additions & 73 deletions docs/src/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,76 +156,3 @@ TemperatureProfiles.DryAdiabaticProfile
Thermodynamics.DataCollection
```

## Deprecated Functions

These functions are deprecated and will be removed in a future release.

### Backward Compatibility Wrappers

These wrappers exist for backward compatibility with older versions of the package.

```@docs
specific_enthalpy
specific_enthalpy_dry
specific_enthalpy_vapor
specific_enthalpy_liquid
specific_enthalpy_ice
dry_pottemp
total_specific_enthalpy
q_vap_saturation_generic
latent_heat_liq_ice
```

### Other Deprecated Functions

```@docs
air_temperature_given_hq
air_temperature_given_pρq
air_temperature_given_pθq
air_temperature_given_ρθq
air_temperature_given_ρθq_nonlinear
saturated
total_specific_humidity
liquid_specific_humidity
ice_specific_humidity
mixing_ratios
specific_volume
q_vap_from_RH_liquid
temperature_and_humidity_given_TᵥρRH
liquid_ice_pottemp_sat
PhasePartition_equil
PhasePartition_equil_given_p
```

## Thermodynamic State Constructors (Deprecated)

```@docs
ThermodynamicState
PhasePartition
PhaseDry
PhaseDry_ρe
PhaseDry_pT
PhaseDry_pθ
PhaseDry_pe
PhaseDry_ph
PhaseDry_ρθ
PhaseDry_ρT
PhaseDry_ρp
PhaseEquil
PhaseEquil_ρeq
PhaseEquil_ρTq
PhaseEquil_pTq
PhaseEquil_pθq
PhaseEquil_peq
PhaseEquil_phq
PhaseEquil_ρθq
PhaseEquil_ρpq
PhaseNonEquil
PhaseNonEquil_ρTq
PhaseNonEquil_pTq
PhaseNonEquil_ρθq
PhaseNonEquil_pθq
PhaseNonEquil_peq
PhaseNonEquil_phq
PhaseNonEquil_ρpq
```
2 changes: 1 addition & 1 deletion perf/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ using .TestedProfiles
functional_inputs(param_set, ::Type{FT}; n=256)

Construct equilibrium-consistent scalar inputs for functional benchmarks, derived from
`test/TestedProfiles.jl` (no deprecated PhasePartition/state types).
`test/TestedProfiles.jl`.
"""
function functional_inputs(param_set, ::Type{FT}; n = 256) where {FT}
ps = TestedProfiles.PhaseEquilProfiles(param_set, Array{FT})
Expand Down
4 changes: 2 additions & 2 deletions perf/common_micro_bm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ function tabulate_summary(summary)

# Create a single header row merging the two-row header logic
header_row = [
"IndepVars (+conditions)" "Memory estimate" "allocs estimate" "Time min" "Time max" "Time mean" "Time median" "N-samples"
]
"IndepVars (+conditions)" "Memory estimate" "allocs estimate" "Time min" "Time max" "Time mean" "Time median" "N-samples"
]

final_table = vcat(header_row, table_data)

Expand Down
6 changes: 3 additions & 3 deletions perf/microbenchmarks.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
include("common_micro_bm.jl")

function benchmark_thermo_states(::Type{FT}) where {FT}
function benchmark_functional_api(::Type{FT}) where {FT}
summary = OrderedCollections.OrderedDict()
ArrayType = Array{FT}
param_set = TP.ThermodynamicsParameters(FT)
Expand All @@ -25,5 +25,5 @@ function benchmark_thermo_states(::Type{FT}) where {FT}
tabulate_summary(summary)
end

benchmark_thermo_states(Float64)
benchmark_thermo_states(Float32)
benchmark_functional_api(Float64)
benchmark_functional_api(Float32)
3 changes: 2 additions & 1 deletion src/Parameters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ end
"Internal energy of vaporization at reference temperature `T_0`."
@inline e_int_v0(ps::ATP) = LH_v0(ps) - R_v(ps) * T_0(ps)

"Internal energy of fusion at reference temperature `T_0`."
"Internal energy of fusion at reference temperature `T_0`. Equal to the latent heat of fusion
because for incompressible condensed phases the `p Δv` term is negligible (`p Δv ≪ L_f`)."
@inline e_int_i0(ps::ATP) = LH_f0(ps)

"Ratio of dry air gas constant to isobaric specific heat `R_d / cp_d`."
Expand Down
9 changes: 0 additions & 9 deletions src/Thermodynamics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ const APS = TP.AbstractThermodynamicsParameters

include("ThermoTypes.jl")

include("depr_PhasePartitionTypes.jl")

@inline solution_type() = RS.CompactSolution()
include("DataCollection.jl")
import .DataCollection
Expand All @@ -80,13 +78,6 @@ include("air_entropies.jl")
include("air_dry_adiabatic.jl")
include("TemperatureProfiles.jl")

# Soon to be removed
include("depr_air_temperatures.jl")
include("depr_saturation_adjustment.jl")
include("depr_air_states.jl")
include("depr_state_methods.jl")
include("depr_phase_partition_methods.jl")

Base.broadcastable(dap::DryAdiabaticProcess) = tuple(dap)
Base.broadcastable(phase::Phase) = tuple(phase)

Expand Down
5 changes: 5 additions & 0 deletions src/air_entropies.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ The specific entropy of dry air at its partial pressure.
- `s_d`: specific entropy of dry air [J/(kg·K)]

In the dry limit (`q_tot = q_liq = q_ice = 0`, the default), the dry-air partial pressure equals the total pressure.
Note: `entropy_dry` diverges logarithmically as `q_tot → 1` (since `p_d → 0`). See also
the analogous warning in [`entropy_vapor`](@ref).
"""
@inline function entropy_dry(
param_set::APS,
Expand Down Expand Up @@ -89,6 +91,9 @@ The specific entropy of water vapor at its partial pressure.
- `s_v`: specific entropy of water vapor [J/(kg·K)]

Note: the entropy of water vapor diverges logarithmically as `q_tot → 0` (since `p_v → 0`).
The analogous divergence occurs in [`entropy_dry`](@ref) as `q_tot → 1` (since `p_d → 0`).
A small numerical regularization `ϵ_numerics(FT)` is added to the pressure before taking the
logarithm to avoid floating-point exceptions, but results should not be trusted in these limits.
"""
@inline function entropy_vapor(
param_set::APS,
Expand Down
27 changes: 5 additions & 22 deletions src/air_humidities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ export partial_pressure_vapor
export specific_humidity_to_mixing_ratio
export q_vap_from_p_vap
export q_vap_from_RH
export q_vap_from_RH_liquid
export relative_humidity

"""
vapor_specific_humidity(q_tot=0, q_liq=0, q_ice=0)

The vapor specific humidity (clamped to be non-negative).
The vapor specific humidity.

# Arguments
- `q_tot`: total specific humidity [kg/kg]
Expand All @@ -24,6 +23,8 @@ The vapor specific humidity (clamped to be non-negative).

If the specific humidities are not given, the result is zero.
The formula is `q_vap = q_tot - q_liq - q_ice`.

Note: callers must ensure `q_liq + q_ice ≤ q_tot`; no clamping is applied.
"""
@inline function vapor_specific_humidity(q_tot = 0, q_liq = 0, q_ice = 0)
return q_tot - q_liq - q_ice
Expand Down Expand Up @@ -185,6 +186,8 @@ Compute the vapor specific humidity from the relative humidity.

# Returns
- `q_vap`: vapor specific humidity [kg/kg]

Note: this function assumes all water is in vapor form (no liquid or ice condensate).
"""
@inline function q_vap_from_RH(param_set::APS, p, T, RH, phase::Phase)
p_vap_sat = saturation_vapor_pressure(param_set, T, phase)
Expand All @@ -193,26 +196,6 @@ Compute the vapor specific humidity from the relative humidity.
return p_vap / Rv_over_Rd / (p - (1 - 1 / Rv_over_Rd) * p_vap)
end

"""
q_vap_from_RH_liquid(param_set, p, T, RH)

Compute the vapor specific humidity from the relative humidity over liquid.

# Arguments
- `param_set`: thermodynamics parameter set, see [`Thermodynamics`](@ref)
- `p`: pressure [Pa]
- `T`: temperature [K]
- `RH`: relative humidity [dimensionless], 0 ≤ RH ≤ 1

# Returns
- `q_vap`: vapor specific humidity [kg/kg]

This function is deprecated. Use `q_vap_from_RH` with `Liquid()` instead.
"""
@inline function q_vap_from_RH_liquid(param_set::APS, p, T, RH)
return q_vap_from_RH(param_set, p, T, RH, Liquid())
end

"""
relative_humidity(param_set, T, p, q_tot=0, q_liq=0, q_ice=0)

Expand Down
1 change: 1 addition & 0 deletions src/air_properties.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ The specific heat capacities are assumed to be constant (calorically perfect air
cv_v = TP.cv_v(param_set)
cv_l = TP.cv_l(param_set)
cv_i = TP.cv_i(param_set)
# rearranged formula for cv_m to avoid computation of vapor specific humidity
return cv_d +
(cv_v - cv_d) * q_tot +
(cv_l - cv_v) * q_liq +
Expand Down
Loading
Loading