Unit operations¶
Energy-balanced unit operations (flash drum, heater, valve, pump, compressor, turbine, mixer, splitter, component separator) and the non-ideal separation units (two-phase flash, decanter, three-phase flash).
Core unit operations¶
units
¶
Differentiable unit operations with rigorous material and energy balances.
Every block here is built on the equation-of-state phase equilibrium and the
energy core in fugacio.thermo, so each one is differentiable end-to-end
with respect to its operating conditions and feed. That is the headline Fugacio
claim made concrete: you can take a gradient of a product purity, a duty, or a
shaft power with respect to a drum temperature, an outlet pressure, a split
fraction, or a feed flow: the basis for gradient-based flowsheet optimisation.
The library covers the staples of a process flowsheet:
flash_drum: isothermal-isobaric vapour/liquid separator;heater: heater/cooler on either a temperature or a duty spec;valve: isenthalpic (Joule-Thomson) pressure letdown;pump: incompressible-liquid pump with an efficiency;compressor/turbine: isentropic machines with an efficiency;mix: adiabatic mixer (energy-balanced);splitter: flow splitter;component_separator: idealised component split.
Outlet temperatures of the energy-specified blocks are found with the
differentiable flash_ph / flash_ps
solves, whose temperatures carry implicit-function gradients.
Classes:
| Name | Description |
|---|---|
HeaterResult |
Outlet of a heater/cooler together with the heat duty. |
PumpResult |
Outlet of a pump together with the shaft work. |
WorkResult |
Outlet of a compressor/turbine with actual and ideal shaft work. |
Functions:
| Name | Description |
|---|---|
flash_drum |
Flash a feed stream at temperature |
heater |
Heat or cool a stream on either a temperature or a duty specification. |
valve |
Isenthalpic (Joule-Thomson) pressure letdown to |
pump |
Pump an (incompressible) liquid from |
compressor |
Compress a stream to |
turbine |
Expand a stream to |
splitter |
Split |
component_separator |
Idealised separator with a per-component recovery to the top product. |
mix |
Combine streams with an exact material balance and an adiabatic energy balance. |
HeaterResult
¶
Bases: NamedTuple
Outlet of a heater/cooler together with the heat duty.
Attributes:
| Name | Type | Description |
|---|---|---|
outlet |
Stream
|
Product |
duty |
Array
|
Heat duty (W). Positive means heat added; negative means cooling. |
PumpResult
¶
Bases: NamedTuple
Outlet of a pump together with the shaft work.
Attributes:
| Name | Type | Description |
|---|---|---|
outlet |
Stream
|
Product |
work |
Array
|
Shaft power delivered to the fluid (W). |
WorkResult
¶
Bases: NamedTuple
Outlet of a compressor/turbine with actual and ideal shaft work.
Attributes:
| Name | Type | Description |
|---|---|---|
outlet |
Stream
|
Product |
work |
Array
|
Actual shaft power into the fluid (W); negative for a turbine (the fluid does work on the surroundings). |
ideal_work |
Array
|
Reversible (isentropic) shaft power into the fluid (W). |
flash_drum
¶
flash_drum(
feed: Stream,
t: ArrayLike,
p: ArrayLike,
*,
eos: CubicEOS = PR,
kij: Array | None = None,
) -> tuple[Stream, Stream]
Flash a feed stream at temperature t and pressure p.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
feed
|
Stream
|
Inlet |
required |
t
|
ArrayLike
|
Drum temperature (K). |
required |
p
|
ArrayLike
|
Drum pressure (Pa). |
required |
eos
|
CubicEOS
|
Cubic equation of state to use (defaults to Peng-Robinson). |
PR
|
kij
|
Array | None
|
Optional binary interaction matrix. |
None
|
Returns:
| Type | Description |
|---|---|
Stream
|
|
Stream
|
respect to |
heater
¶
heater(
feed: Stream,
*,
t_out: ArrayLike | None = None,
duty: ArrayLike | None = None,
dp: ArrayLike = 0.0,
eos: CubicEOS = PR,
kij: Array | None = None,
t_init: float = 300.0,
) -> HeaterResult
Heat or cool a stream on either a temperature or a duty specification.
Provide exactly one of t_out (target outlet temperature) or duty
(signed heat added, W). With t_out the duty is computed from the enthalpy
change; with duty the outlet temperature is found by an isenthalpic solve,
so the block correctly handles partial vaporisation/condensation. dp is the
pressure drop across the block.
Raises:
| Type | Description |
|---|---|
ValueError
|
if not exactly one of |
valve
¶
valve(
feed: Stream,
p_out: ArrayLike,
*,
eos: CubicEOS = PR,
kij: Array | None = None,
t_init: float = 300.0,
) -> Stream
Isenthalpic (Joule-Thomson) pressure letdown to p_out.
Enthalpy is conserved, so the outlet temperature (and any flashing that results from the pressure drop) follows from an isenthalpic solve. The outlet may be two-phase; it is returned as a single bulk stream at the solved temperature.
pump
¶
pump(
feed: Stream,
p_out: ArrayLike,
*,
efficiency: ArrayLike = 0.75,
eos: CubicEOS = PR,
kij: Array | None = None,
t_init: float = 300.0,
) -> PumpResult
Pump an (incompressible) liquid from feed.p to p_out.
The reversible work is v_L (p_out - p_in) per mole using the liquid molar
volume; the actual work is divided by efficiency and the inefficiency is
deposited as heat, so the outlet temperature is found from an isenthalpic
balance on H_out = H_in + W_actual.
compressor
¶
compressor(
feed: Stream,
p_out: ArrayLike,
*,
efficiency: ArrayLike = 0.75,
eos: CubicEOS = PR,
kij: Array | None = None,
t_init: float = 300.0,
) -> WorkResult
Compress a stream to p_out with an isentropic efficiency (< 1).
The reversible outlet is the isentropic state at p_out; the actual work is
W_ideal / efficiency and the extra enthalpy sets the (higher) real outlet
temperature via an isenthalpic solve.
turbine
¶
turbine(
feed: Stream,
p_out: ArrayLike,
*,
efficiency: ArrayLike = 0.85,
eos: CubicEOS = PR,
kij: Array | None = None,
t_init: float = 300.0,
) -> WorkResult
Expand a stream to p_out with an isentropic efficiency (< 1).
The fluid recovers efficiency of the reversible work; the returned
work is negative (power delivered to the shaft) and the real outlet is
warmer than the isentropic outlet because of the lost work.
splitter
¶
Split feed into multiple outlets that share its composition and state.
fractions is a sequence of split fractions (one per outlet); each outlet
carries that fraction of every component flow. The fractions should sum to one
for a conservative split. Temperature and pressure are passed through.
component_separator
¶
component_separator(
feed: Stream,
split_to_top: ArrayLike,
*,
top_t: ArrayLike | None = None,
top_p: ArrayLike | None = None,
bottom_t: ArrayLike | None = None,
bottom_p: ArrayLike | None = None,
) -> tuple[Stream, Stream]
Idealised separator with a per-component recovery to the top product.
split_to_top is a per-component fraction (aligned with feed.components)
sent to the top outlet; the remainder leaves in the bottom. This is the
workhorse "spec" separator for conceptual flowsheets, a stand-in for a column
or absorber whose recoveries are known. Product temperatures and pressures
default to the feed's.
mix
¶
mix(
streams: list[Stream],
*,
t: ArrayLike | None = None,
p: ArrayLike | None = None,
eos: CubicEOS = PR,
kij: Array | None = None,
t_init: float = 300.0,
) -> Stream
Combine streams with an exact material balance and an adiabatic energy balance.
Flows add component-by-component. By default the outlet temperature is found
from an adiabatic energy balance (total enthalpy in equals total enthalpy
out) via an isenthalpic solve, so heat of mixing and any phase change are
accounted for; pass t to fix the outlet temperature instead. Outlet
pressure defaults to the lowest inlet pressure.
Raises:
| Type | Description |
|---|---|
ValueError
|
if the streams are empty or do not share a component list. |
Non-ideal separations¶
separations
¶
Non-ideal separation units: model-driven flash, decanter, three-phase flash.
These complement the equation-of-state blocks in fugacio.sim.units with the
non-ideal phase behaviour the gamma-phi property system unlocks:
flash_vle: a two-phase V-L flash driven by anyEquilibriumModel(EOS or gamma-phi), so the same drum works on Peng-Robinson or NRTL/UNIQUAC/UNIFAC;decanter: a liquid-liquid separator (settling tank) that splits one feed into two conjugate liquid products via the isoactivity LLE flash; andthree_phase_flash: a vapour + two-liquid (V-L-L) separator for heterogeneous systems (water/organic decantation, heteroazeotropic columns).
Every product is a differentiable Stream; flows carry
gradients with respect to the operating T, P, the feed, and (through the
model object) the thermodynamic parameters themselves.
Functions:
| Name | Description |
|---|---|
flash_vle |
Two-phase vapour-liquid flash of |
decanter |
Liquid-liquid settler: split |
three_phase_flash |
Vapour-liquid-liquid (V-L-L) flash of |
flash_vle
¶
Two-phase vapour-liquid flash of feed at (T, P) using model.
Works with any EquilibriumModel (an
EOSModel for the phi-phi route or a
GammaPhiModel for the activity-coefficient route)
so the drum's thermodynamics are chosen by the model passed in.
Returns:
| Type | Description |
|---|---|
tuple[Stream, Stream]
|
|
decanter
¶
decanter(
feed: Stream,
model: GammaPhiModel,
*,
t: ArrayLike | None = None,
tol: float = 1e-12,
max_iter: int = 400,
) -> tuple[Stream, Stream]
Liquid-liquid settler: split feed into two conjugate liquid products.
Solves the isoactivity LLE flash (fugacio.thermo.flash_lle) with the
model's activity description at temperature t (default: the feed
temperature) and the feed pressure. For a feed outside any miscibility gap the
LLE flash collapses to the trivial split and one product carries essentially
the whole feed; check with fugacio.thermo.liquid_stability upstream
if that matters.
Returns:
| Type | Description |
|---|---|
Stream
|
|
Stream
|
are symmetric, so which phase the solver labels |
tuple[Stream, Stream]
|
stable across platforms/precision; the order here is made deterministic by |
tuple[Stream, Stream]
|
returning the product richest in the first component (index 0) as |
tuple[Stream, Stream]
|
|
three_phase_flash
¶
three_phase_flash(
feed: Stream,
t: ArrayLike,
p: ArrayLike,
model: GammaPhiModel,
*,
tol: float = 1e-11,
max_iter: int = 300,
) -> tuple[Stream, Stream, Stream]
Vapour-liquid-liquid (V-L-L) flash of feed at (T, P).
Drives the three-phase flash (fugacio.thermo.flash_vlle) with the
model's activity liquid and its EOS/ideal vapour. Use for heterogeneous
systems (water/organic decantation and heteroazeotropic distillation) where
a vapour coexists with two liquids.
Returns:
| Type | Description |
|---|---|
Stream
|
|
Stream
|
genuinely three-phase one of the liquid flows collapses to (near) zero. |