Skip to content

Energy & property models

Ideal-gas correlations, residual/departure functions, the result type of the energy-specified flashes, and the property correlations that the energy balances in fugacio.sim build on. The isenthalpic and isentropic flashes themselves are property-package methods (flash_ph, flash_ps, and their _with_info forms); see property packages.

Ideal gas

ideal

Ideal-gas thermodynamic properties from heat-capacity correlations.

These functions integrate the four-parameter Cp/R = a + b*T + c*T**2 + d/T**2 correlation (see fugacio.thermo.components.CpIdeal) into the ideal-gas enthalpy, entropy, and Gibbs energy. They are the temperature-dependent backbone that the equation-of-state departure functions are added to in order to obtain real-fluid properties::

H_real(T, P) = H_ideal(T) + H_departure(T, P)

Everything is written in jax.numpy, so the coefficients a, b, c, d may themselves be differentiated through (useful when regressing Cp data).

Functions:

Name Description
cp_ig

Ideal-gas molar heat capacity Cp (J/mol/K).

enthalpy_ig

Ideal-gas molar enthalpy relative to t_ref (J/mol).

entropy_ig

Ideal-gas molar entropy relative to (t_ref, p_ref) (J/mol/K).

gibbs_ig

Ideal-gas molar Gibbs energy G = H - T*S relative to the reference state.

enthalpy_ig_mixture

Ideal-gas molar enthalpy of a mixture relative to t_ref (J/mol).

entropy_ig_mixture

Ideal-gas molar entropy of a mixture relative to (t_ref, p_ref) (J/mol/K).

gibbs_ig_mixture

Ideal-gas molar Gibbs energy of a mixture G = H - T S (J/mol).

ideal_gas_coeffs

Stack the Cp coefficients of several components into (a, b, c, d, e).

cp_ig

cp_ig(
    t: ArrayLike,
    a: ArrayLike,
    b: ArrayLike,
    c: ArrayLike,
    d: ArrayLike,
    e: ArrayLike = 0.0,
) -> Array

Ideal-gas molar heat capacity Cp (J/mol/K).

Cp = R * (a + b*T + c*T**2 + d/T**2 + e*T**3).

enthalpy_ig

enthalpy_ig(
    t: ArrayLike,
    a: ArrayLike,
    b: ArrayLike,
    c: ArrayLike,
    d: ArrayLike,
    e: ArrayLike = 0.0,
    t_ref: float = T_REF,
) -> Array

Ideal-gas molar enthalpy relative to t_ref (J/mol).

Analytic integral integral_{t_ref}^{t} Cp dT.

entropy_ig

entropy_ig(
    t: ArrayLike,
    p: ArrayLike,
    a: ArrayLike,
    b: ArrayLike,
    c: ArrayLike,
    d: ArrayLike,
    e: ArrayLike = 0.0,
    t_ref: float = T_REF,
    p_ref: float = P_REF,
) -> Array

Ideal-gas molar entropy relative to (t_ref, p_ref) (J/mol/K).

Analytic integral integral Cp/T dT minus the pressure term R * ln(P / p_ref).

gibbs_ig

gibbs_ig(
    t: ArrayLike,
    p: ArrayLike,
    a: ArrayLike,
    b: ArrayLike,
    c: ArrayLike,
    d: ArrayLike,
    e: ArrayLike = 0.0,
    t_ref: float = T_REF,
    p_ref: float = P_REF,
) -> Array

Ideal-gas molar Gibbs energy G = H - T*S relative to the reference state.

enthalpy_ig_mixture

enthalpy_ig_mixture(
    t: ArrayLike,
    x: Array,
    a: Array,
    b: Array,
    c: Array,
    d: Array,
    e: Array,
    t_ref: float = T_REF,
) -> Array

Ideal-gas molar enthalpy of a mixture relative to t_ref (J/mol).

Ideal-gas enthalpy is independent of pressure and of mixing, so the mixture value is just the mole-fraction average of the component enthalpies. a..e are 1-D coefficient arrays aligned with x (see ideal_gas_coeffs).

entropy_ig_mixture

entropy_ig_mixture(
    t: ArrayLike,
    p: ArrayLike,
    x: Array,
    a: Array,
    b: Array,
    c: Array,
    d: Array,
    e: Array,
    t_ref: float = T_REF,
    p_ref: float = P_REF,
) -> Array

Ideal-gas molar entropy of a mixture relative to (t_ref, p_ref) (J/mol/K).

Includes the ideal entropy of mixing -R sum_i x_i ln x_i (equivalently, each component is evaluated at its partial pressure x_i P).

gibbs_ig_mixture

gibbs_ig_mixture(
    t: ArrayLike,
    p: ArrayLike,
    x: Array,
    a: Array,
    b: Array,
    c: Array,
    d: Array,
    e: Array,
    t_ref: float = T_REF,
    p_ref: float = P_REF,
) -> Array

Ideal-gas molar Gibbs energy of a mixture G = H - T S (J/mol).

ideal_gas_coeffs

ideal_gas_coeffs(
    components: list[Component],
) -> tuple[Array, Array, Array, Array, Array]

Stack the Cp coefficients of several components into (a, b, c, d, e).

Raises:

Type Description
ValueError

if any component lacks ideal-gas heat-capacity data.

Residual / departure functions

departure

Residual (departure) functions of the cubic equation of state.

A residual property is the difference between the real-fluid property and the ideal-gas property at the same temperature, pressure, and composition::

M_real(T, P, x) = M_ideal_gas(T, P, x) + M_residual(T, P, x)

so the residual functions here are exactly what must be added to the ideal-gas integrals in fugacio.thermo.ideal to obtain real-fluid enthalpy, entropy, and Gibbs energy. They are the keystone that turns the property engine into one that can close energy balances (heat duties, adiabatic mixing, compression), not just material balances.

The closed forms are written in terms of the same departure log-term g that fugacio.thermo.eos.ln_phi_mixture already uses, so they are consistent by construction with the fugacity coefficients that are validated against CoolProp. Writing A = aP/(RT)^2, B = bP/(RT) and g = ln[(Z+sigma B)/(Z+epsilon B)] / (sigma - epsilon)::

G_res / (RT) = (Z - 1) - ln(Z - B) - (A / B) * g
H_res        = R T (Z - 1) + ((T a' - a) / b) * g
S_res        = R ln(Z - B) + (a' / b) * g

with a' = da/dT for the mixture (obtained by automatic differentiation of the van der Waals one-fluid mixing rule, so binary interaction parameters and any alpha(T) law are handled exactly). One can verify G_res = H_res - T S_res and H_res = G_res - T (dG_res/dT)_P directly; fugacio.thermo.tests turns those identities into graded consistency checks.

Classes:

Name Description
ResidualProperties

Residual (departure) molar properties at a given T, P, x and phase.

Functions:

Name Description
residual_properties

All residual molar properties (G, H, S) at fixed T, P, x in one pass.

residual_gibbs

Residual molar Gibbs energy G - G_ig at fixed T, P (J/mol).

residual_enthalpy

Residual molar enthalpy H - H_ig at fixed T, P (J/mol).

residual_entropy

Residual molar entropy S - S_ig at fixed T, P (J/mol/K).

residual_cp

Residual molar heat capacity Cp - Cp_ig at fixed T, P (J/mol/K).

ResidualProperties

Bases: NamedTuple

Residual (departure) molar properties at a given T, P, x and phase.

Attributes:

Name Type Description
gibbs Array

Residual molar Gibbs energy G - G_ig (J/mol).

enthalpy Array

Residual molar enthalpy H - H_ig (J/mol).

entropy Array

Residual molar entropy S - S_ig (J/mol/K).

z Array

Compressibility factor of the selected phase root.

residual_properties

residual_properties(
    eos: CubicEOS,
    t: ArrayLike,
    p: ArrayLike,
    x: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    phase: str = "vapor",
    kij: Array | None = None,
) -> ResidualProperties

All residual molar properties (G, H, S) at fixed T, P, x in one pass.

Computing them together shares the compressibility root, the departure log-term, and da/dT, which the individual accessors below simply select from. The Gibbs residual equals R T sum_i x_i ln(phi_i), the partial-molar identity tying this module to fugacio.thermo.eos.ln_phi_mixture.

residual_gibbs

residual_gibbs(
    eos: CubicEOS,
    t: ArrayLike,
    p: ArrayLike,
    x: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    phase: str = "vapor",
    kij: Array | None = None,
) -> Array

Residual molar Gibbs energy G - G_ig at fixed T, P (J/mol).

residual_enthalpy

residual_enthalpy(
    eos: CubicEOS,
    t: ArrayLike,
    p: ArrayLike,
    x: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    phase: str = "vapor",
    kij: Array | None = None,
) -> Array

Residual molar enthalpy H - H_ig at fixed T, P (J/mol).

residual_entropy

residual_entropy(
    eos: CubicEOS,
    t: ArrayLike,
    p: ArrayLike,
    x: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    phase: str = "vapor",
    kij: Array | None = None,
) -> Array

Residual molar entropy S - S_ig at fixed T, P (J/mol/K).

residual_cp

residual_cp(
    eos: CubicEOS,
    t: ArrayLike,
    p: ArrayLike,
    x: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    phase: str = "vapor",
    kij: Array | None = None,
) -> Array

Residual molar heat capacity Cp - Cp_ig at fixed T, P (J/mol/K).

Obtained as (d H_res / dT)_P by automatic differentiation of residual_enthalpy, so it needs no separately derived second-derivative formula and stays consistent with the enthalpy departure.

Energy flashes

energy

Energy-specified equilibrium: the shared result type and temperature solver.

The isothermal flash answers "what splits?" at a given temperature. Process units instead fix an energy specification (a heat duty, an adiabatic mix, an isentropic compression) and the temperature is unknown. Every property package implements flash_ph / flash_ps on top of this module:

  • EnergyFlashResult: the solved temperature and phase split;
  • _implicit_temperature: a safeguarded Newton/bisection solve of a monotone energy residual (enthalpy or entropy minus a specification) for the temperature. The forward pass brackets the root in [t_min, t_max] and only evaluates residual values, falling back to bisection whenever a Newton step would leave the bracket, so it's robust when a trial temperature crosses a phase boundary. The converged temperature is differentiated by the implicit function theorem with no differentiation through the iteration itself, and an unconverged temperature has nonfinite derivatives.

Classes:

Name Description
EnergyFlashResult

Result of an energy-specified flash (PH or PS).

EnergyFlashResult

Bases: NamedTuple

Result of an energy-specified flash (PH or PS).

Attributes:

Name Type Description
t Array

Solved temperature (K).

beta Array

Vapour molar fraction.

x Array

Liquid-phase mole fractions.

y Array

Vapour-phase mole fractions.

k Array

Equilibrium ratios at the solution.

Property correlations

correlations

Temperature-dependent pure-component property correlations.

Two layers live here:

  • Correlation kernels: the classic DIPPR-numbered functional forms (dippr100, dippr101, dippr102, dippr105, dippr106) plus the REFPROP-style mulero_cachadina surface-tension expansion. These are plain jax.numpy functions of temperature and their coefficients, so they are differentiable in both (handy when regressing coefficients to data).
  • Corresponding-states estimators and dispatchers: enthalpy of vaporization (curated DIPPR-106 table, else pitzer_hvap; rescaled between temperatures by watson_hvap) and liquid heat capacity (rowlinson_bondi_cp on top of the ideal-gas Cp). The name-based dispatchers (heat_of_vaporization, liquid_heat_capacity) pull per-component coefficients from the generated fugacio.thermo._property_data tables and fall back to the corresponding-states estimate when no curated fit exists, so they work for the whole component database.

Coefficient tables are transcribed (or least-squares refitted onto these forms) from the open chemicals dataset by scripts/gen_property_data.py; the companion oracle tests grade both the tables and the estimators against CoolProp's multiparameter reference fluids.

Functions:

Name Description
dippr100

DIPPR equation 100: plain polynomial c1 + c2*T + c3*T^2 + c4*T^3 + c5*T^4.

dippr101

DIPPR equation 101: exp(c1 + c2/T + c3*ln(T) + c4*T^c5).

dippr102

DIPPR equation 102: c1*T^c2 / (1 + c3/T + c4/T^2).

dippr105

DIPPR equation 105: c1 / c2^(1 + (1 - T/c3)^c4).

dippr106

DIPPR equation 106: c1 * (1-Tr)^(c2 + c3*Tr + c4*Tr^2 + c5*Tr^3).

mulero_cachadina

Mulero-Cachadina surface tension sum_k s_k * (1 - T/tc)^n_k (N/m).

pitzer_hvap

Pitzer acentric-factor enthalpy of vaporization (J/mol).

watson_hvap

Watson rescaling of a known enthalpy of vaporization to another temperature.

rowlinson_bondi_cp

Rowlinson-Bondi saturated-liquid heat capacity (J/mol/K).

heat_of_vaporization

Per-component enthalpy of vaporization Hvap_i(T) (J/mol).

liquid_heat_capacity

Per-component saturated-liquid heat capacity Cp_L_i(T) (J/mol/K).

dippr100

dippr100(
    t: ArrayLike,
    c1: ArrayLike,
    c2: ArrayLike = 0.0,
    c3: ArrayLike = 0.0,
    c4: ArrayLike = 0.0,
    c5: ArrayLike = 0.0,
) -> Array

DIPPR equation 100: plain polynomial c1 + c2*T + c3*T^2 + c4*T^3 + c5*T^4.

dippr101

dippr101(
    t: ArrayLike,
    c1: ArrayLike,
    c2: ArrayLike,
    c3: ArrayLike = 0.0,
    c4: ArrayLike = 0.0,
    c5: ArrayLike = 1.0,
) -> Array

DIPPR equation 101: exp(c1 + c2/T + c3*ln(T) + c4*T^c5).

The workhorse form for liquid viscosity (and vapour pressure). c5 is a fixed exponent from the source table, not usually a regression variable.

dippr102

dippr102(
    t: ArrayLike,
    c1: ArrayLike,
    c2: ArrayLike,
    c3: ArrayLike = 0.0,
    c4: ArrayLike = 0.0,
) -> Array

DIPPR equation 102: c1*T^c2 / (1 + c3/T + c4/T^2).

The standard form for dilute-gas viscosity and thermal conductivity.

dippr105

dippr105(
    t: ArrayLike,
    c1: ArrayLike,
    c2: ArrayLike,
    c3: ArrayLike,
    c4: ArrayLike,
) -> Array

DIPPR equation 105: c1 / c2^(1 + (1 - T/c3)^c4).

The Rackett-shaped form used for saturated-liquid molar density; the units of the result are the units of c1 (mol/m^3 in Fugacio's tables).

dippr106

dippr106(
    t: ArrayLike,
    tc: ArrayLike,
    c1: ArrayLike,
    c2: ArrayLike,
    c3: ArrayLike = 0.0,
    c4: ArrayLike = 0.0,
    c5: ArrayLike = 0.0,
) -> Array

DIPPR equation 106: c1 * (1-Tr)^(c2 + c3*Tr + c4*Tr^2 + c5*Tr^3).

Used for enthalpy of vaporization and surface tension; vanishes at the critical point by construction. Tr = T/tc is clipped just below one so the expression (and its temperature derivative) stays finite under autodiff.

mulero_cachadina

mulero_cachadina(
    t: ArrayLike,
    tc: ArrayLike,
    s0: ArrayLike,
    n0: ArrayLike,
    s1: ArrayLike = 0.0,
    n1: ArrayLike = 1.0,
    s2: ArrayLike = 0.0,
    n2: ArrayLike = 1.0,
) -> Array

Mulero-Cachadina surface tension sum_k s_k * (1 - T/tc)^n_k (N/m).

The three-term REFPROP fit of Mulero, Cachadina & Parra (J. Phys. Chem. Ref. Data, 2012). With a single term it reduces to the van der Waals-Guggenheim form sigma0 * (1-Tr)^1.26. Clipped at Tr = 1 so the tension is zero (not NaN) above the critical point.

pitzer_hvap

pitzer_hvap(
    t: ArrayLike, tc: ArrayLike, omega: ArrayLike
) -> Array

Pitzer acentric-factor enthalpy of vaporization (J/mol).

Hvap / (R*Tc) = 7.08*(1-Tr)^0.354 + 10.95*omega*(1-Tr)^0.456, the three-parameter corresponding-states correlation recommended by Poling et al. (5th ed., eq. 7-9.4), good to a few percent for normal fluids over 0.6 < Tr < 1. Clipped to zero above the critical temperature.

watson_hvap

watson_hvap(
    hvap_ref: ArrayLike,
    t_ref: ArrayLike,
    t: ArrayLike,
    tc: ArrayLike,
    n: float = 0.38,
) -> Array

Watson rescaling of a known enthalpy of vaporization to another temperature.

Hvap(T) = Hvap(T_ref) * ((1-Tr) / (1-Tr_ref))^n with the classic n = 0.38 exponent. Use when a single measured point (say at the normal boiling temperature) is available.

rowlinson_bondi_cp

rowlinson_bondi_cp(
    t: ArrayLike,
    tc: ArrayLike,
    omega: ArrayLike,
    cp_ideal: ArrayLike,
) -> Array

Rowlinson-Bondi saturated-liquid heat capacity (J/mol/K).

(Cp_L - Cp_ig)/R = 1.45 + 0.45/(1-Tr) + 0.25*omega*(17.11 + 25.2*(1-Tr)^(1/3)/Tr + 1.742/(1-Tr)) (Poling et al., 5th ed., eq. 6-6.1). Diverges at the critical point, as the physical Cp does; Tr is clipped just below one to keep autodiff finite.

heat_of_vaporization

heat_of_vaporization(
    components: list[str] | list[Component], t: ArrayLike
) -> Array

Per-component enthalpy of vaporization Hvap_i(T) (J/mol).

Uses the curated DIPPR-106 fit where one exists and the Pitzer corresponding-states correlation (pitzer_hvap) otherwise, so the result is defined for every database component. Values go to zero at each component's critical temperature.

liquid_heat_capacity

liquid_heat_capacity(
    components: list[str] | list[Component], t: ArrayLike
) -> Array

Per-component saturated-liquid heat capacity Cp_L_i(T) (J/mol/K).

Rowlinson-Bondi corresponding states on top of each component's ideal-gas Cp correlation.

Raises:

Type Description
ValueError

if any component lacks ideal-gas heat-capacity data.