Distillation & diagrams¶
Shortcut (Fenske-Underwood-Gilliland) column design, plus binary diagrams, azeotropes, and residue-curve maps. The full MESH column with stage energy balances lives on the rigorous distillation page.
Shortcut distillation¶
column
¶
Shortcut distillation design: Fenske-Underwood-Gilliland (FUG).
The FUG method gives the minimum stages at total reflux
(fenske_min_stages), the minimum reflux (underwood_min_reflux), the actual
stage count at a working reflux (gilliland_stages), and the feed-stage
location (kirkbride_feed_stage), tied together by shortcut_column. It is
cheap, robust, and ideal for screening or for initializing the rigorous MESH
column (fugacio.sim.distillation.rigorous_column). Every output is exactly
differentiable with respect to the design variables, so a shortcut design can
be embedded in a gradient-based optimisation alongside the rest of a flowsheet.
Component ordering convention: relative volatilities alpha are given relative
to a common reference (any component); the light key lk is more volatile
than the heavy key hk (alpha[lk] > alpha[hk]).
Classes:
| Name | Description |
|---|---|
ShortcutResult |
Summary of a Fenske-Underwood-Gilliland shortcut design. |
Functions:
| Name | Description |
|---|---|
relative_volatility |
Relative volatilities |
fenske_min_stages |
Fenske minimum number of equilibrium stages at total reflux. |
underwood_min_reflux |
Underwood minimum reflux ratio |
gilliland_stages |
Actual equilibrium-stage count from the Gilliland (Eduljee) correlation. |
kirkbride_feed_stage |
Kirkbride correlation for the number of stages above the feed. |
shortcut_column |
Full FUG shortcut design from a feed and a specified product split. |
ShortcutResult
¶
Bases: NamedTuple
Summary of a Fenske-Underwood-Gilliland shortcut design.
Attributes:
| Name | Type | Description |
|---|---|---|
n_min |
Array
|
Minimum equilibrium stages at total reflux (Fenske). |
r_min |
Array
|
Minimum reflux ratio (Underwood). |
theta |
Array
|
Underwood common root. |
r |
Array
|
Working reflux ratio used for the Gilliland step. |
n_stages |
Array
|
Actual equilibrium stages (Gilliland). |
feed_stage |
Array
|
Number of stages above the feed (Kirkbride). |
relative_volatility
¶
relative_volatility(
model: PropertyPackage,
t: ArrayLike,
p: ArrayLike,
z: Array,
*,
ref: int,
) -> Array
Relative volatilities alpha_i = K_i / K_ref at (T, P, z).
K-values are the package's phi_i^L(z) / phi_i^V(z) at the given
composition, a standard shortcut estimate that is well defined whether or
not the feed is two-phase. Differentiable in (T, P, z) and the package
parameters.
fenske_min_stages
¶
Fenske minimum number of equilibrium stages at total reflux.
N_min = ln[(d_LK/d_HK)(b_HK/b_LK)] / ln(alpha_LK/alpha_HK) where d and
b are the distillate and bottoms component molar flows. Includes the
reboiler as a stage (the classic Fenske count).
underwood_min_reflux
¶
underwood_min_reflux(
z: Array,
x_d: Array,
alpha: Array,
q: ArrayLike,
lk: int,
hk: int,
*,
tol: float = 1e-12,
max_iter: int = 200,
) -> tuple[Array, Array]
Underwood minimum reflux ratio R_min (constant relative volatility).
Solves the first Underwood equation sum_i alpha_i z_i / (alpha_i - theta) =
1 - q for the common root theta between alpha_HK and alpha_LK,
then evaluates R_min + 1 = sum_i alpha_i x_{i,D} / (alpha_i - theta).
Returns (R_min, theta); both are differentiable in (z, x_d, alpha, q)
and NaN when no root lies between the key volatilities.
gilliland_stages
¶
Actual equilibrium-stage count from the Gilliland (Eduljee) correlation.
With X = (R - R_min)/(R + 1) and Y = 0.75 (1 - X^0.5668), the stage
count follows from (N - N_min)/(N + 1) = Y, i.e. N = (N_min + Y)/(1 - Y).
kirkbride_feed_stage
¶
kirkbride_feed_stage(
n: ArrayLike,
z: Array,
x_d: Array,
x_b: Array,
d_total: ArrayLike,
b_total: ArrayLike,
lk: int,
hk: int,
) -> Array
Kirkbride correlation for the number of stages above the feed.
log10(N_R/N_S) = 0.206 log10[(z_HK/z_LK)(x_{LK,B}/x_{HK,D})^2 (B/D)];
returns N_R given the total stage count N = N_R + N_S.
shortcut_column
¶
shortcut_column(
z: Array,
d: Array,
b: Array,
alpha: Array,
q: ArrayLike,
lk: int,
hk: int,
*,
reflux: ArrayLike | None = None,
reflux_factor: ArrayLike = 1.3,
) -> ShortcutResult
Full FUG shortcut design from a feed and a specified product split.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
z
|
Array
|
Feed mole fractions. |
required |
d
|
Array
|
Distillate component molar flows (the chosen split of the feed). |
required |
b
|
Array
|
Bottoms component molar flows ( |
required |
alpha
|
Array
|
Relative volatilities (to any common reference). |
required |
q
|
ArrayLike
|
Feed thermal quality (1 = saturated liquid, 0 = saturated vapour). |
required |
lk
|
int
|
Light-key component index. |
required |
hk
|
int
|
Heavy-key component index. |
required |
reflux
|
ArrayLike | None
|
Working reflux ratio. If |
None
|
reflux_factor
|
ArrayLike
|
Multiplier on |
1.3
|
Returns:
| Type | Description |
|---|---|
ShortcutResult
|
A |
Binary diagrams & residue curves¶
diagrams
¶
Binary phase-diagram data and azeotrope finding for a property package.
Conceptual design and column screening lean on the binary picture: the P-x-y and
T-x-y envelopes and, above all, where the azeotrope is (it bounds what ordinary
distillation can reach). These helpers turn any binary property package (see
fugacio.sim.package_for) into:
pxy_diagram/txy_diagram: the bubble (liquid) and the equilibrium-vapour curves on a composition grid, from one bubble sweep each; andazeotrope_pressure/azeotrope_temperature: the azeotropic composition (wherey_1 = x_1) at fixedTorP, returned with anexistsflag and a NaN locus for a non-azeotropic system, so none is faked.
All outputs are differentiable: the diagram arrays through the bubble solves, and
the azeotrope locus through the bracketed root's implicit derivative, so an
azeotrope's pressure sensitivity to a model parameter is a single
jax.grad away.
Classes:
| Name | Description |
|---|---|
PxyDiagram |
Isothermal P-x-y data for a binary. |
TxyDiagram |
Isobaric T-x-y data for a binary. |
AzeotropeResult |
A binary azeotrope locus. |
ResidueCurve |
A simple-distillation residue curve: the still-liquid composition path. |
Functions:
| Name | Description |
|---|---|
pxy_diagram |
Isothermal P-x-y curves for a binary on an |
txy_diagram |
Isobaric T-x-y curves for a binary on an |
azeotrope_pressure |
Find the binary azeotrope at fixed temperature |
azeotrope_temperature |
Find the binary azeotrope at fixed pressure |
residue_curve |
Integrate one residue curve of open (Rayleigh) distillation at fixed |
residue_curve_map |
Trace a residue-curve map: one full curve through each starting composition. |
PxyDiagram
¶
Bases: NamedTuple
Isothermal P-x-y data for a binary.
Attributes:
| Name | Type | Description |
|---|---|---|
x1 |
Array
|
Liquid mole fraction of component 1 (the grid). |
y1 |
Array
|
Equilibrium vapour mole fraction of component 1 (the bubble vapour). |
p |
Array
|
Bubble pressure at each |
t |
Array
|
The (fixed) temperature (K). |
TxyDiagram
¶
Bases: NamedTuple
Isobaric T-x-y data for a binary.
Attributes:
| Name | Type | Description |
|---|---|---|
x1 |
Array
|
Liquid mole fraction of component 1 (the grid). |
y1 |
Array
|
Equilibrium vapour mole fraction of component 1. |
t |
Array
|
Bubble temperature at each |
p |
Array
|
The (fixed) pressure (Pa). |
AzeotropeResult
¶
Bases: NamedTuple
A binary azeotrope locus.
Attributes:
| Name | Type | Description |
|---|---|---|
exists |
Array
|
|
x1 |
Array
|
Azeotropic composition ( |
t |
Array
|
Temperature (K); NaN unless |
p |
Array
|
Pressure (Pa); NaN unless |
ResidueCurve
¶
Bases: NamedTuple
A simple-distillation residue curve: the still-liquid composition path.
Attributes:
| Name | Type | Description |
|---|---|---|
x |
Array
|
Liquid composition along the curve, shape |
t |
Array
|
Bubble (boiling) temperature at each point (K), shape |
p |
Array
|
The (fixed) pressure of the map (Pa). |
pxy_diagram
¶
pxy_diagram(
model: _BinaryModel,
t: ArrayLike,
*,
n: int = 51,
eps: float = 0.001,
) -> PxyDiagram
Isothermal P-x-y curves for a binary on an n-point composition grid.
The grid is clipped to [eps, 1 - eps] to avoid the pure-component limits.
Both curves come from a single bubble-pressure sweep: plot (x1, p) for the
liquid line and (y1, p) for the vapour line.
txy_diagram
¶
txy_diagram(
model: _BinaryModel,
p: ArrayLike,
*,
n: int = 51,
eps: float = 0.001,
t_min: float = 200.0,
t_max: float = 600.0,
) -> TxyDiagram
Isobaric T-x-y curves for a binary on an n-point composition grid.
Each grid point solves a bubble temperature (bracketed in [t_min, t_max])
and returns the equilibrium vapour, giving both the liquid line (x1, t) and
the vapour line (y1, t) from one sweep. Widen the bracket for very light or
very heavy pairs.
azeotrope_pressure
¶
azeotrope_pressure(
model: _BinaryModel,
t: ArrayLike,
*,
x_lo: float = 0.001,
x_hi: float = 1.0 - 0.001,
tol: float = 1e-10,
max_iter: int = 200,
) -> AzeotropeResult
Find the binary azeotrope at fixed temperature t (where y_1 = x_1).
Brackets the root of y_1(x_1) - x_1 from the bubble-pressure relation. The
returned x1 and p are differentiable with respect to the model
parameters, and NaN when the bracket holds no azeotrope.
azeotrope_temperature
¶
azeotrope_temperature(
model: _BinaryModel,
p: ArrayLike,
*,
x_lo: float = 0.001,
x_hi: float = 1.0 - 0.001,
t_min: float = 200.0,
t_max: float = 600.0,
tol: float = 1e-10,
max_iter: int = 200,
) -> AzeotropeResult
Find the binary azeotrope at fixed pressure p (where y_1 = x_1).
As azeotrope_pressure but at constant pressure: each residual
evaluation solves a bubble temperature (bracketed in [t_min, t_max]).
residue_curve
¶
residue_curve(
model: _BubbleTemperatureModel,
x0: Array,
p: ArrayLike,
*,
steps: int = 200,
ds: float = 0.05,
direction: float = 1.0,
t_min: float = 150.0,
t_max: float = 700.0,
) -> ResidueCurve
Integrate one residue curve of open (Rayleigh) distillation at fixed P.
Solves the residue-curve ODE dx_i/dtau = x_i - y_i(x), where y(x) is the
bubble-point vapour in equilibrium with the still liquid x. With
direction = +1 the curve advances toward the high-boiling stable node
(the still-pot residue enriches in heavy components); direction = -1 traces
it back toward the low-boiling node.
Integration is an explicit Euler march with the composition re-projected onto
the simplex each step, so the path stays a valid composition. The expensive part,
the bubble-point (T, y) at each point, is one compiled, differentiable
solve (_bubble_ty) reused across every step and every curve.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
_BubbleTemperatureModel
|
A property package (see |
required |
x0
|
Array
|
Starting liquid composition, shape |
required |
p
|
ArrayLike
|
Pressure (Pa). |
required |
steps
|
int
|
Number of integration steps. |
200
|
ds
|
float
|
Pseudo-time step size. |
0.05
|
direction
|
float
|
|
1.0
|
t_min
|
float
|
Lower bound of the bubble-temperature search bracket (K). |
150.0
|
t_max
|
float
|
Upper bound of the bubble-temperature search bracket (K). |
700.0
|
Returns:
| Type | Description |
|---|---|
ResidueCurve
|
A |
ResidueCurve
|
( |
residue_curve_map
¶
residue_curve_map(
model: _BubbleTemperatureModel,
starts: Array,
p: ArrayLike,
*,
steps: int = 150,
ds: float = 0.05,
t_min: float = 150.0,
t_max: float = 700.0,
) -> list[ResidueCurve]
Trace a residue-curve map: one full curve through each starting composition.
Each start is integrated both directions (toward the light and the heavy node) and the two halves are stitched into a single curve passing through the start. This is the ternary distillation designer's master diagram: distillation boundaries and reachable products fall out of the family of curves.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
_BubbleTemperatureModel
|
Object exposing |
required |
starts
|
Array
|
Starting compositions, shape |
required |
p
|
ArrayLike
|
Pressure (Pa). |
required |
steps
|
int
|
Steps taken in each direction (the curve has |
150
|
ds
|
float
|
Pseudo-time step size. |
0.05
|
t_min
|
float
|
Lower bound of the bubble-temperature search bracket (K). |
150.0
|
t_max
|
float
|
Upper bound of the bubble-temperature search bracket (K). |
700.0
|
Returns:
| Type | Description |
|---|---|
list[ResidueCurve]
|
A list of |