Energy & property models¶
Ideal-gas correlations, residual/departure functions, isenthalpic and
isentropic flashes, and the molar property accessors that the energy balances
in fugacio.sim build on.
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 |
enthalpy_ig |
Ideal-gas molar enthalpy relative to |
entropy_ig |
Ideal-gas molar entropy relative to |
gibbs_ig |
Ideal-gas molar Gibbs energy |
enthalpy_ig_mixture |
Ideal-gas molar enthalpy of a mixture relative to |
entropy_ig_mixture |
Ideal-gas molar entropy of a mixture relative to |
gibbs_ig_mixture |
Ideal-gas molar Gibbs energy of a mixture |
ideal_gas_coeffs |
Stack the |
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
¶
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 |
Functions:
| Name | Description |
|---|---|
residual_properties |
All residual molar properties (G, H, S) at fixed |
residual_gibbs |
Residual molar Gibbs energy |
residual_enthalpy |
Residual molar enthalpy |
residual_entropy |
Residual molar entropy |
residual_cp |
Residual molar heat capacity |
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 |
enthalpy |
Array
|
Residual molar enthalpy |
entropy |
Array
|
Residual molar entropy |
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-balance phase equilibrium: two-phase enthalpy/entropy and PH/PS flash.
The isothermal flash in fugacio.thermo.equilibrium 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. This module supplies:
mixture_enthalpy/mixture_entropy: the molar enthalpy and entropy of an equilibrium feed at(T, P), correctly blending the vapour and liquid products of the flash (so the latent heat is included automatically);flash_ph: the isenthalpic (adiabatic) flash: solve for the temperature at which the mixture enthalpy meets a target, then return the split;flash_ps: the isentropic flash, the backbone of compressor and turbine models.
Both flashes solve a scalar, monotone energy residual (enthalpy or entropy minus
a specification) for the temperature with a safeguarded Newton iteration: the
forward pass brackets the root in [t_min, t_max] and only ever evaluates the
residual's value (never its gradient), falling back to bisection whenever a
Newton step would leave the bracket. This is robust even when a trial temperature
crosses a phase boundary, where the underlying flash gradient is ill-defined. The
converged temperature (and everything derived from it) is differentiable with
respect to the energy specification, pressure, feed, and model parameters by the
implicit function theorem (a hand-written custom_jvp rule), with no
differentiation through the iteration itself.
Classes:
| Name | Description |
|---|---|
EnergyFlashResult |
Result of an energy-specified flash (PH or PS). |
Functions:
| Name | Description |
|---|---|
mixture_enthalpy |
Molar enthalpy of an equilibrium feed |
mixture_entropy |
Molar entropy of an equilibrium feed |
flash_ph |
Isenthalpic (adiabatic) flash: find |
flash_ps |
Isentropic flash: find |
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. |
mixture_enthalpy
¶
mixture_enthalpy(
eos: CubicEOS,
t: ArrayLike,
p: ArrayLike,
z: Array,
tc: Array,
pc: Array,
omega: Array,
cp: CpCoeffs,
*,
kij: Array | None = None,
t_ref: float = T_REF,
) -> Array
Molar enthalpy of an equilibrium feed z at (T, P) (J/mol of feed).
Runs the isothermal flash and blends the phase enthalpies by vapour fraction,
H = (1 - beta) H^L(x) + beta H^V(y); in the single-phase region beta
is 0 or 1 and this reduces to the single-phase enthalpy.
mixture_entropy
¶
mixture_entropy(
eos: CubicEOS,
t: ArrayLike,
p: ArrayLike,
z: Array,
tc: Array,
pc: Array,
omega: Array,
cp: CpCoeffs,
*,
kij: Array | None = None,
t_ref: float = T_REF,
p_ref: float = P_REF,
) -> Array
Molar entropy of an equilibrium feed z at (T, P) (J/mol/K of feed).
flash_ph
¶
flash_ph(
eos: CubicEOS,
p: ArrayLike,
h_spec: ArrayLike,
z: Array,
tc: Array,
pc: Array,
omega: Array,
cp: CpCoeffs,
*,
kij: Array | None = None,
t_init: ArrayLike = 300.0,
t_min: float = 50.0,
t_max: float = 1500.0,
tol: float = 1e-08,
max_iter: int = 100,
) -> EnergyFlashResult
Isenthalpic (adiabatic) flash: find T so the feed enthalpy equals h_spec.
Returns the solved temperature together with the equilibrium split, all
differentiable with respect to (p, h_spec, z, ...). dT/d h_spec is the
reciprocal of the two-phase heat capacity, including latent effects. The
temperature is bracketed to [t_min, t_max] (raise t_max for very hot
streams, but keep it where the EOS evaluates cleanly).
flash_ps
¶
flash_ps(
eos: CubicEOS,
p: ArrayLike,
s_spec: ArrayLike,
z: Array,
tc: Array,
pc: Array,
omega: Array,
cp: CpCoeffs,
*,
kij: Array | None = None,
t_init: ArrayLike = 300.0,
t_min: float = 50.0,
t_max: float = 1500.0,
tol: float = 1e-08,
max_iter: int = 100,
) -> EnergyFlashResult
Isentropic flash: find T so the feed entropy equals s_spec.
The backbone of isentropic compressor and turbine models: given an inlet
entropy and an outlet pressure, flash_ps returns the ideal outlet state.
The temperature is bracketed to [t_min, t_max].
Molar properties¶
properties
¶
Real-fluid molar properties: ideal-gas integrals plus EOS residual functions.
This is the bridge that assembles M_real = M_ideal_gas + M_residual for a
real mixture, combining fugacio.thermo.ideal (the temperature-dependent
ideal-gas backbone) with fugacio.thermo.departure (the pressure- and
composition-dependent residual). The outputs (molar enthalpy, entropy, Gibbs
energy, and heat capacity) are exactly what energy balances need, and they are
differentiable with respect to T, P, composition, and every model
parameter just like the rest of the engine.
Enthalpy and entropy are reported relative to an ideal-gas reference state at
T_REF and P_REF (the same reference the ideal-gas integrals use). Only
differences are physically meaningful, and any consistent reference cancels in
a balance; callers that need an absolute (formation-based) enthalpy (a chemical
reactor, say) add the standard enthalpies of formation themselves.
Each function accepts an explicit phase ("vapor" or "liquid") or
"auto", which evaluates both cubic roots and selects the one with the lower
molar Gibbs energy (the thermodynamically stable single phase). The "auto"
branch is differentiable (a jax.numpy.where blend), with the usual
caveat that the gradient is one-sided exactly at a phase boundary.
Functions:
| Name | Description |
|---|---|
molar_enthalpy |
Real-fluid molar enthalpy |
molar_entropy |
Real-fluid molar entropy |
molar_gibbs |
Real-fluid molar Gibbs energy |
molar_cp |
Real-fluid molar heat capacity |
stable_phase |
Label the thermodynamically stable single phase ( |
speed_of_sound_ideal |
Ideal-gas speed of sound |
molar_enthalpy
¶
molar_enthalpy(
t: ArrayLike,
p: ArrayLike,
x: Array,
tc: Array,
pc: Array,
omega: Array,
cp: CpCoeffs,
*,
eos: CubicEOS = PR,
phase: str = "auto",
kij: Array | None = None,
t_ref: float = T_REF,
) -> Array
Real-fluid molar enthalpy H(T, P, x) (J/mol, vs. ideal gas at t_ref).
molar_entropy
¶
molar_entropy(
t: ArrayLike,
p: ArrayLike,
x: Array,
tc: Array,
pc: Array,
omega: Array,
cp: CpCoeffs,
*,
eos: CubicEOS = PR,
phase: str = "auto",
kij: Array | None = None,
t_ref: float = T_REF,
p_ref: float = P_REF,
) -> Array
Real-fluid molar entropy S(T, P, x) (J/mol/K, vs. ideal gas reference).
molar_gibbs
¶
molar_gibbs(
t: ArrayLike,
p: ArrayLike,
x: Array,
tc: Array,
pc: Array,
omega: Array,
cp: CpCoeffs,
*,
eos: CubicEOS = PR,
phase: str = "auto",
kij: Array | None = None,
t_ref: float = T_REF,
p_ref: float = P_REF,
) -> Array
Real-fluid molar Gibbs energy G = H - T S (J/mol).
molar_cp
¶
molar_cp(
t: ArrayLike,
p: ArrayLike,
x: Array,
tc: Array,
pc: Array,
omega: Array,
cp: CpCoeffs,
*,
eos: CubicEOS = PR,
phase: str = "auto",
kij: Array | None = None,
) -> Array
Real-fluid molar heat capacity Cp(T, P, x) (J/mol/K).
stable_phase
¶
stable_phase(
t: ArrayLike,
p: ArrayLike,
x: Array,
tc: Array,
pc: Array,
omega: Array,
*,
eos: CubicEOS = PR,
kij: Array | None = None,
) -> str
Label the thermodynamically stable single phase ("vapor" or "liquid").
The stable root is the one with the lower molar Gibbs energy; when only one
real root exists (a compressed liquid or a supercritical fluid, where both
cubic-root selections collapse onto it) the two Gibbs energies tie, so the
phase is then classified by the stable root's compressibility: liquid-like
below the cubic critical scale Z = 1/3, vapour-like above it. This is a
host-side convenience that materialises a Python bool; the differentiable
path is the phase="auto" option on the property functions.
speed_of_sound_ideal
¶
speed_of_sound_ideal(
t: ArrayLike,
x: Array,
tc: Array,
pc: Array,
omega: Array,
cp: CpCoeffs,
mw: Array,
) -> Array
Ideal-gas speed of sound sqrt(gamma R T / M) (m/s) for the mixture.
A lightweight, always-defined acoustic estimate (gamma = Cp/Cv with the
ideal-gas Cv = Cp - R); the full real-fluid sound speed follows once the
residual Cv and (dP/dV)_T are wired in.
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-stylemulero_cachadinasurface-tension expansion. These are plainjax.numpyfunctions 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 bywatson_hvap) and liquid heat capacity (rowlinson_bondi_cpon top of the ideal-gasCp). The name-based dispatchers (heat_of_vaporization,liquid_heat_capacity) pull per-component coefficients from the generatedfugacio.thermo._property_datatables 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 |
dippr101 |
DIPPR equation 101: |
dippr102 |
DIPPR equation 102: |
dippr105 |
DIPPR equation 105: |
dippr106 |
DIPPR equation 106: |
mulero_cachadina |
Mulero-Cachadina surface tension |
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 |
liquid_heat_capacity |
Per-component saturated-liquid heat capacity |
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
¶
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 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 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
¶
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
¶
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. |