Skip to content

Phase equilibrium

Vapor-liquid equilibrium by both routes: an equation of state for both phases (phi-phi) and an activity-coefficient liquid with an EOS or ideal vapor (gamma-phi). Each calculation has a checked _with_info form that returns a SolveReport, and a value-only form that returns NaN when the report fails. Every property package exposes the same calls through one interface, so the rest of the stack switches thermodynamic models without changing call sites.

See the non-ideal phase equilibrium guide for worked examples.

EOS (phi-phi) equilibrium

equilibrium

Phase equilibrium on a cubic equation of state: flash and saturation.

This module turns the cubic equation of state (fugacio.thermo.eos) into the equilibrium calculations a process simulator calls:

  • wilson_k: the classic K-value initial guess;
  • rachford_rice: the material-balance root for the vapour fraction;
  • flash_pt_with_info: an isothermal-isobaric vapour-liquid flash;
  • psat_eos_with_info: pure-component saturation pressure by equifugacity;
  • bubble_pressure_eos_with_info / dew_pressure_eos_with_info: mixture saturation pressures and incipient-phase compositions.

Every calculation has a checked _with_info form that returns its best state together with a fugacio.thermo.diagnostics.SolveReport, and a value-only form that returns NaN whenever that report fails. A failed solve therefore never returns a finite number. Converged results carry implicit-function-theorem derivatives with respect to temperature, pressure, composition, and the model constants; failed results have nonfinite derivatives.

A two-phase flash can't detect a second liquid. Whether a feed splits at all is answered by the tangent-plane search in fugacio.thermo.stability, which every property package exposes as stability.

Classes:

Name Description
FlashResult

Result of an isothermal-isobaric flash.

FlashSolveResult

PT flash and the report of its fixed-point iteration.

SaturationResult

A saturation point and the composition of the incipient phase.

SaturationSolveResult

A saturation point and its solve report.

Functions:

Name Description
wilson_k

Wilson correlation for initial K-values K_i = y_i / x_i.

wilson_psat

Wilson's vapour-pressure estimate (Pa), an initialization only.

rachford_rice

Solve the Rachford-Rice equation for the vapour fraction beta.

classify_trivial

Vapour fraction of a single-phase feed when the K-iteration went trivial.

phase_compositions

Liquid and vapour compositions from the material balance at (K, beta).

input_report

Whether (T, P, z) is a physical state specification.

flash_pt

Isothermal flash value; NaN when flash_pt_with_info reports failure.

flash_pt_with_info

Isothermal-isobaric vapour-liquid flash by successive substitution.

psat_eos_with_info

Pure-component saturation pressure (Pa) from the EOS by equifugacity.

psat_eos

Saturation pressure (Pa); NaN when psat_eos_with_info reports failure.

psat_seeds

Finite, detached pure-component pressures for initializing mixture solves.

bubble_pressure_eos_with_info

Bubble-point pressure and incipient vapour composition at fixed T, x.

bubble_pressure_eos

Bubble pressure and incipient vapour (P, y); NaN on failure.

dew_pressure_eos_with_info

Dew-point pressure and incipient liquid composition at fixed T, y.

dew_pressure_eos

Dew pressure and incipient liquid (P, x); NaN on failure.

FlashResult

Bases: NamedTuple

Result of an isothermal-isobaric flash.

Attributes:

Name Type Description
beta Array

Vapour molar fraction (mol vapour / mol feed).

x Array

Liquid-phase mole fractions (the incipient liquid when beta == 1).

y Array

Vapour-phase mole fractions (the incipient vapour when beta == 0).

k Array

Equilibrium ratios K_i = y_i / x_i at the solution.

FlashSolveResult

Bases: NamedTuple

PT flash and the report of its fixed-point iteration.

SaturationResult

Bases: NamedTuple

A saturation point and the composition of the incipient phase.

Attributes:

Name Type Description
value Array

Saturation pressure (Pa) or temperature (K).

composition Array

Incipient-phase mole fractions: the vapour of a bubble point or the liquid of a dew point.

SaturationSolveResult

Bases: NamedTuple

A saturation point and its solve report.

wilson_k

wilson_k(
    t: ArrayLike,
    p: ArrayLike,
    tc: Array,
    pc: Array,
    omega: Array,
) -> Array

Wilson correlation for initial K-values K_i = y_i / x_i.

K_i = (Pc_i / P) * exp[5.373 (1 + omega_i)(1 - Tc_i / T)].

wilson_psat

wilson_psat(
    t: ArrayLike,
    tc: ArrayLike,
    pc: ArrayLike,
    omega: ArrayLike,
) -> Array

Wilson's vapour-pressure estimate (Pa), an initialization only.

rachford_rice

rachford_rice(z: Array, k: Array) -> Array

Solve the Rachford-Rice equation for the vapour fraction beta.

Returns beta clamped to [0, 1]: 0 for a subcooled liquid, 1 for a superheated vapour, and the interior root otherwise. The residual sum_i z_i (K_i - 1) / (1 + beta (K_i - 1)) is monotonically decreasing in beta on (0, 1), so a bisection is used for the interior root.

classify_trivial

classify_trivial(
    z: Array,
    k: Array,
    beta: Array,
    k_wilson: Array,
    z_factor: Array,
) -> Array

Vapour fraction of a single-phase feed when the K-iteration went trivial.

Successive substitution on a feed that is single phase collapses to the trivial solution K = 1 (identical trial phases), and the Rachford-Rice residual at K = 1 is zero on both ends, so beta alone cannot tell a superheated vapour from a subcooled liquid. When max |ln K| is below _TRIVIAL_LN_K, the phase is decided from the Wilson K-values instead: the feed is a vapour if it lies below its Wilson dew pressure (sum z_i (K_i - 1) / K_i >= 0) and a liquid if above its Wilson bubble pressure (sum z_i (K_i - 1) <= 0). If Wilson claims two phases where the rigorous iteration found one, the compressibility factor of the single root decides (Z > 0.5 is vapour-like). Away from the trivial solution beta is returned unchanged.

phase_compositions

phase_compositions(
    z: Array, k: Array, beta: Array
) -> tuple[Array, Array]

Liquid and vapour compositions from the material balance at (K, beta).

A present phase's composition follows from Rachford-Rice. An absent phase is the incipient trial phase, normalized so both are mole fractions.

input_report

input_report(t: ArrayLike, p: ArrayLike, z: Array) -> Array

Whether (T, P, z) is a physical state specification.

flash_pt

flash_pt(
    eos: CubicEOS,
    t: ArrayLike,
    p: ArrayLike,
    z: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    kij: Array | None = None,
    tol: float = 1e-12,
    max_iter: int = 300,
) -> FlashResult

Isothermal flash value; NaN when flash_pt_with_info reports failure.

flash_pt_with_info

flash_pt_with_info(
    eos: CubicEOS,
    t: ArrayLike,
    p: ArrayLike,
    z: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    kij: Array | None = None,
    tol: float = 1e-12,
    max_iter: int = 300,
) -> FlashSolveResult

Isothermal-isobaric vapour-liquid flash by successive substitution.

Solves the equal-fugacity conditions phi_i^L x_i = phi_i^V y_i together with the Rachford-Rice material balance, starting from Wilson K-values. A single-phase feed collapses onto the trivial solution K = 1, whose phase is decided by classify_trivial. The converged state is differentiable with respect to (T, P, z, ...) via implicit differentiation of the fixed point. This flash considers one liquid and one vapour; test the result's stability when a second liquid can form.

psat_eos_with_info

psat_eos_with_info(
    eos: CubicEOS,
    t: ArrayLike,
    tc: ArrayLike,
    pc: ArrayLike,
    omega: ArrayLike,
    *,
    tol: float = 1e-10,
    max_iter: int = 100,
) -> SolveResult

Pure-component saturation pressure (Pa) from the EOS by equifugacity.

Solves ln phi^L(T, P) = ln phi^V(T, P) for ln P by Newton's method from the Wilson estimate. A trial pressure outside the three-root region has coincident liquid and vapour roots, where the residual vanishes trivially; such a step is redirected toward the coexistence region instead of being accepted. The loop stops on its own recorded convergence flag, so scalar and vectorized evaluations follow identical arithmetic.

At or above the critical temperature no saturation pressure exists: the report is OUT_OF_DOMAIN and the value is the (differentiable) Wilson extrapolation, a usable initialization but not a property. Keeping that value finite lets a mixture model carry an absent supercritical component without poisoning derivatives. A converged value is differentiable in T and the critical constants (Clapeyron's implicit derivative); failures inside the domain have nonfinite derivatives.

Parameters:

Name Type Description Default
eos CubicEOS

Cubic equation of state.

required
t ArrayLike

Temperature (K).

required
tc ArrayLike

Critical temperature (K).

required
pc ArrayLike

Critical pressure (Pa).

required
omega ArrayLike

Acentric factor.

required
tol float

Residual tolerance on ln phi^L - ln phi^V.

1e-10
max_iter int

Newton iteration cap.

100

Returns:

Type Description
SolveResult

The saturation pressure and its report.

psat_eos

psat_eos(
    eos: CubicEOS,
    t: ArrayLike,
    tc: ArrayLike,
    pc: ArrayLike,
    omega: ArrayLike,
    *,
    tol: float = 1e-10,
    max_iter: int = 100,
) -> Array

Saturation pressure (Pa); NaN when psat_eos_with_info reports failure.

psat_seeds

psat_seeds(
    eos: CubicEOS,
    t: ArrayLike,
    tc: Array,
    pc: Array,
    omega: Array,
) -> Array

Finite, detached pure-component pressures for initializing mixture solves.

Converged EOS saturation pressures where they exist, and the Wilson extrapolation elsewhere (for example, supercritical components).

bubble_pressure_eos_with_info

bubble_pressure_eos_with_info(
    eos: CubicEOS,
    t: ArrayLike,
    x: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    kij: Array | None = None,
    tol: float = 1e-12,
    max_iter: int = 300,
) -> SaturationSolveResult

Bubble-point pressure and incipient vapour composition at fixed T, x.

Solved as a coupled fixed point in (ln P, y) from Raoult's-law seeds. A trivial solution (above the cricondenbar, where the iteration collapses onto y = x on one root) is reported as TRIVIAL.

bubble_pressure_eos

bubble_pressure_eos(
    eos: CubicEOS,
    t: ArrayLike,
    x: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    kij: Array | None = None,
    tol: float = 1e-12,
    max_iter: int = 300,
) -> SaturationResult

Bubble pressure and incipient vapour (P, y); NaN on failure.

dew_pressure_eos_with_info

dew_pressure_eos_with_info(
    eos: CubicEOS,
    t: ArrayLike,
    y: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    kij: Array | None = None,
    tol: float = 1e-12,
    max_iter: int = 300,
) -> SaturationSolveResult

Dew-point pressure and incipient liquid composition at fixed T, y.

Coupled fixed point in (ln P, x). A trivial one-root solution is reported as TRIVIAL.

dew_pressure_eos

dew_pressure_eos(
    eos: CubicEOS,
    t: ArrayLike,
    y: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    kij: Array | None = None,
    tol: float = 1e-12,
    max_iter: int = 300,
) -> SaturationResult

Dew pressure and incipient liquid (P, x); NaN on failure.

Gamma-phi equilibrium

gammaphi

Gamma-phi vapour-liquid equilibrium (activity-coefficient liquid model).

The cubic-EOS flash in fugacio.thermo.equilibrium describes both phases with one equation of state (the phi-phi approach). For the low-pressure, polar, strongly non-ideal mixtures that dominate real separations (ethanol/water and other azeotropes, alcohol/ketone/water systems), a cubic EOS with zero binary interaction parameters is simply the wrong tool. The standard answer is the gamma-phi approach: model the liquid with an activity-coefficient model and the vapour with an equation of state (or as an ideal gas at low pressure).

Equilibrium equates the component fugacities

x_i gamma_i(x, T) f_i^{0,L}(T, P) = y_i phi_i^V(y, T, P) P

so the K-values are

K_i = y_i / x_i = gamma_i f_i^{0,L} / (phi_i^V P).

With an ideal vapour (phi^V = 1) and the plain saturation reference (f^{0,L} = Psat), this collapses to modified Raoult's law K_i = gamma_i Psat_i / P, enough to reproduce azeotropes that the zero-kij cubic cannot. The richer reference (saturation fugacity coefficient + Poynting, see fugacio.thermo.reference) and an EOS vapour are available via keyword flags.

The saturation-based reference exists only below each component's critical temperature. Every calculation here reports OUT_OF_DOMAIN when a component present in the relevant phase is supercritical, instead of returning a number built on an extrapolated vapour pressure; absent components are harmless.

Each routine has a checked _with_info form and a value-only form that returns NaN on failure. Converged results are differentiable end-to-end with respect to T, P, composition, and the activity-model parameters, which turns parameter regression (fugacio.thermo.regression) into plain gradient descent.

Functions:

Name Description
reference_domain

Whether every component present in composition has a saturation reference at t.

gamma_phi_k_values

Gamma-phi K-values K_i = gamma_i f_i^{0,L} / (phi_i^V P).

bubble_pressure_gamma_with_info

Bubble-point pressure and incipient vapour composition at fixed T, x.

bubble_pressure_gamma

Bubble pressure and incipient vapour (P, y); NaN on failure.

dew_pressure_gamma_with_info

Dew-point pressure and incipient liquid composition at fixed T, y.

dew_pressure_gamma

Dew pressure and incipient liquid (P, x); NaN on failure.

default_temperature_bracket

A saturation-temperature bracket from the present components' critical points.

bubble_temperature_gamma_with_info

Bubble-point temperature and incipient vapour at fixed P, x.

bubble_temperature_gamma

Bubble temperature and incipient vapour (T, y); NaN on failure.

dew_temperature_gamma_with_info

Dew-point temperature and incipient liquid at fixed P, y.

dew_temperature_gamma

Dew temperature and incipient liquid (T, x); NaN on failure.

flash_pt_gamma

Isothermal flash value; NaN when flash_pt_gamma_with_info reports failure.

flash_pt_gamma_with_info

Isothermal-isobaric gamma-phi flash by successive substitution.

reference_domain

reference_domain(
    t: ArrayLike,
    composition: Array,
    tc: Array,
    eos: CubicEOS,
    pc: Array,
    omega: Array,
) -> Array

Whether every component present in composition has a saturation reference at t.

gamma_phi_k_values

gamma_phi_k_values(
    model: ActivityModel,
    t: ArrayLike,
    p: ArrayLike,
    x: Array,
    y: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    eos: CubicEOS = PR,
    kij: Array | None = None,
    vapor: str = "ideal",
    poynting: bool = False,
    phi_saturation: bool = False,
) -> Array

Gamma-phi K-values K_i = gamma_i f_i^{0,L} / (phi_i^V P).

Parameters:

Name Type Description Default
model ActivityModel

Liquid activity-coefficient model.

required
t ArrayLike

Temperature (K).

required
p ArrayLike

Pressure (Pa).

required
x Array

Liquid mole fractions.

required
y Array

Vapour mole fractions (only matters for an EOS vapour).

required
tc Array

Component critical temperatures (K).

required
pc Array

Component critical pressures (Pa).

required
omega Array

Component acentric factors.

required
eos CubicEOS

Cubic EOS for the saturation reference and (if selected) the vapour.

PR
kij Array | None

Optional binary interaction matrix for the vapour EOS.

None
vapor str

"ideal" (phi^V = 1) or "eos".

'ideal'
poynting bool

Include the Poynting pressure correction in the reference.

False
phi_saturation bool

Include the saturation fugacity coefficient in the reference.

False

Returns:

Type Description
Array

K-values aligned with x. Supercritical components carry values built

Array

on an extrapolated vapour pressure; see reference_domain.

bubble_pressure_gamma_with_info

bubble_pressure_gamma_with_info(
    model: ActivityModel,
    t: ArrayLike,
    x: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    eos: CubicEOS = PR,
    kij: Array | None = None,
    vapor: str = "ideal",
    poynting: bool = False,
    phi_saturation: bool = False,
    tol: float = 1e-12,
    max_iter: int = 200,
) -> SaturationSolveResult

Bubble-point pressure and incipient vapour composition at fixed T, x.

Solved as a coupled fixed point in (ln P, y): K-values give an unnormalised vapour y* = K x whose sum scales the pressure until it is one.

bubble_pressure_gamma

bubble_pressure_gamma(
    model: ActivityModel,
    t: ArrayLike,
    x: Array,
    *args: Any,
    **kwargs: Any,
) -> SaturationResult

Bubble pressure and incipient vapour (P, y); NaN on failure.

dew_pressure_gamma_with_info

dew_pressure_gamma_with_info(
    model: ActivityModel,
    t: ArrayLike,
    y: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    eos: CubicEOS = PR,
    kij: Array | None = None,
    vapor: str = "ideal",
    poynting: bool = False,
    phi_saturation: bool = False,
    tol: float = 1e-12,
    max_iter: int = 200,
) -> SaturationSolveResult

Dew-point pressure and incipient liquid composition at fixed T, y.

Coupled fixed point in (ln P, x): with x_i = y_i / K_i (and the activity coefficients re-evaluated at the updated x), the pressure is scaled until the liquid sums to one.

dew_pressure_gamma

dew_pressure_gamma(
    model: ActivityModel,
    t: ArrayLike,
    y: Array,
    *args: Any,
    **kwargs: Any,
) -> SaturationResult

Dew pressure and incipient liquid (P, x); NaN on failure.

default_temperature_bracket

default_temperature_bracket(
    tc: Array, composition: Array
) -> tuple[Array, Array]

A saturation-temperature bracket from the present components' critical points.

[0.2 min Tc, max Tc] over the components present in composition: wide enough for cryogenic and heavy systems, and scanned for the first finite sign change rather than assumed valid.

bubble_temperature_gamma_with_info

bubble_temperature_gamma_with_info(
    model: ActivityModel,
    p: ArrayLike,
    x: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    eos: CubicEOS = PR,
    kij: Array | None = None,
    vapor: str = "ideal",
    poynting: bool = False,
    phi_saturation: bool = False,
    t_min: ArrayLike | None = None,
    t_max: ArrayLike | None = None,
    tol: float = 1e-09,
    max_iter: int = 200,
    inner_iter: int | None = None,
) -> SaturationSolveResult

Bubble-point temperature and incipient vapour at fixed P, x.

The bubble temperature is the root of sum_i K_i(T) x_i = 1 (monotone in T), located by fugacio.thermo.implicit.scanned_root_with_info on [t_min, t_max] (by default default_temperature_bracket) and differentiated by the implicit function theorem. For an EOS vapour the incipient y is settled by inner_iter sweeps (default 30) at every trial temperature; an ideal vapour needs none.

bubble_temperature_gamma

bubble_temperature_gamma(
    model: ActivityModel,
    p: ArrayLike,
    x: Array,
    *args: Any,
    **kwargs: Any,
) -> SaturationResult

Bubble temperature and incipient vapour (T, y); NaN on failure.

dew_temperature_gamma_with_info

dew_temperature_gamma_with_info(
    model: ActivityModel,
    p: ArrayLike,
    y: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    eos: CubicEOS = PR,
    kij: Array | None = None,
    vapor: str = "ideal",
    poynting: bool = False,
    phi_saturation: bool = False,
    t_min: ArrayLike | None = None,
    t_max: ArrayLike | None = None,
    tol: float = 1e-09,
    max_iter: int = 200,
    inner_iter: int = 30,
) -> SaturationSolveResult

Dew-point temperature and incipient liquid at fixed P, y.

Root of sum_i (y_i / K_i(T)) = 1 in T with an inner sweep that settles the incipient liquid x (on which the activity coefficients depend) at each trial temperature, on a scanned bracket (see bubble_temperature_gamma_with_info).

dew_temperature_gamma

dew_temperature_gamma(
    model: ActivityModel,
    p: ArrayLike,
    y: Array,
    *args: Any,
    **kwargs: Any,
) -> SaturationResult

Dew temperature and incipient liquid (T, x); NaN on failure.

flash_pt_gamma

flash_pt_gamma(
    model: ActivityModel,
    t: ArrayLike,
    p: ArrayLike,
    z: Array,
    *args: Any,
    **kwargs: Any,
) -> FlashResult

Isothermal flash value; NaN when flash_pt_gamma_with_info reports failure.

flash_pt_gamma_with_info

flash_pt_gamma_with_info(
    model: ActivityModel,
    t: ArrayLike,
    p: ArrayLike,
    z: Array,
    tc: Array,
    pc: Array,
    omega: Array,
    *,
    eos: CubicEOS = PR,
    kij: Array | None = None,
    vapor: str = "ideal",
    poynting: bool = False,
    phi_saturation: bool = False,
    tol: float = 1e-12,
    max_iter: int = 300,
) -> FlashSolveResult

Isothermal-isobaric gamma-phi flash by successive substitution.

Iterates the gamma-phi K-values to a fixed point in ln K with the Rachford-Rice material balance closing the phase split at each step. The converged beta, x, y are differentiable with respect to (T, P, z) and the activity-model parameters. A present supercritical component is OUT_OF_DOMAIN.

Tangent-plane stability

stability

Tangent-plane stability analysis: does a phase split at all?

A mixture of overall composition z is stable as a single phase only if no trial phase w lies below the Gibbs-energy tangent plane at z, i.e. if the reduced tangent-plane distance

tpd(w) = sum_i w_i (ln w_i + ln coeff_i(w) - d_i),   d_i = ln z_i + ln coeff_i(z)

is non-negative at every stationary point. coeff_i is whatever turns a composition into a fugacity: the activity coefficient gamma_i of a liquid activity model, or the fugacity coefficient phi_i of any phase branch of a property package. Casting the test in terms of trial-phase functions lets one search serve every model, and lets a caller test against any reference phase (the feed's own lowest-Gibbs phase, or a returned flash phase).

tpd_search is that one search: a damped successive substitution in ln w from several starts on every trial branch, tracking the most negative distance observed. Components absent from the feed stay exactly absent, so feeds with zero entries are routine. A finite-start search can't prove a global minimum; the result reports whether every trial reached a stationary point, and a stability verdict is only established when it did.

Package-level tests live on every fugacio.thermo.package.PropertyPackage (stability); liquid_stability tests a liquid against a second liquid for activity models and seeds fugacio.thermo.lle.flash_lle.

Classes:

Name Description
StabilityResult

Outcome of a tangent-plane stability search.

Functions:

Name Description
tangent_plane_distance

Reduced tangent-plane distance of trial phase w relative to feed z.

tpd_search

Search trial phases on every branch against the reference potentials d.

enrichment_starts

Trial compositions enriched toward each pure component, plus the feed.

feed_potentials

Reference potentials of the feed's lowest-Gibbs single-phase branch.

liquid_stability

Test a liquid of composition z for splitting into two liquids at T.

StabilityResult

Bases: NamedTuple

Outcome of a tangent-plane stability search.

Attributes:

Name Type Description
stable Array

True if no trial phase reached a distance below -tol.

tpd Array

The most negative reduced tangent-plane distance observed.

trial Array

The final (normalized) composition of the most negative trial, a ready initial guess for the incipient phase of an unstable feed.

branch Array

Index of the trial branch that produced trial (for package tests, 0 is liquid-like and 1 is vapour-like).

converged Array

Whether every trial reached a finite stationary point. A verdict of stability is established only when this is also true.

tangent_plane_distance

tangent_plane_distance(
    ln_coeff_fn: LnCoeffFn, z: Array, w: Array
) -> Array

Reduced tangent-plane distance of trial phase w relative to feed z.

tpd(w) = sum_i w_i (ln w_i + ln coeff_i(w) - ln z_i - ln coeff_i(z)); a negative value means the trial phase w lies below the tangent plane at z and the feed can lower its Gibbs energy by forming it. Components absent from z must be absent from w; they contribute nothing.

tpd_search(
    branches: Sequence[LnCoeffFn],
    d: Array,
    support: Array,
    starts: Array,
    *,
    iterations: int = 160,
    tol: float = 1e-07,
) -> StabilityResult

Search trial phases on every branch against the reference potentials d.

Parameters:

Name Type Description Default
branches Sequence[LnCoeffFn]

Trial-phase functions w -> ln coeff(w), one per phase branch.

required
d Array

Reference potentials ln x_i + ln coeff_i(x) of the tested phase.

required
support Array

Components present in the tested system; others stay absent.

required
starts Array

Initial trial compositions, shape (n_starts, n).

required
iterations int

Damped successive-substitution steps per start.

160
tol float

Stationarity tolerance on trial compositions and the stability threshold on the distance.

1e-07

Returns:

Type Description
StabilityResult

The most negative distance observed and its trial phase. The search is

StabilityResult

a classification and carries no derivative.

enrichment_starts

enrichment_starts(
    z: Array, *, strength: float = 0.95
) -> Array

Trial compositions enriched toward each pure component, plus the feed.

feed_potentials

feed_potentials(
    branches: Sequence[LnCoeffFn], z: Array, support: Array
) -> Array

Reference potentials of the feed's lowest-Gibbs single-phase branch.

liquid_stability

liquid_stability(
    model: ActivityModel,
    t: ArrayLike,
    z: Array,
    *,
    iterations: int = 160,
    tol: float = 1e-07,
) -> StabilityResult

Test a liquid of composition z for splitting into two liquids at T.

Uses the activity coefficients as the trial function and starts enriched toward each pure component. A negative tpd flags a miscibility gap; the returned trial seeds fugacio.thermo.lle.flash_lle.