Metadata-Version: 2.4
Name: stages-thermo
Version: 0.3.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Education
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Rust
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Chemistry
Requires-Dist: numpy>=1.24
Requires-Dist: vle-thermo>=0.15
Requires-Dist: pytest>=7.0 ; extra == 'dev'
Requires-Dist: maturin>=1.0 ; extra == 'dev'
Requires-Dist: matplotlib>=3.7 ; extra == 'plot'
Provides-Extra: dev
Provides-Extra: plot
Summary: Staged-separation (distillation) column solver: McCabe–Thiele, Ponchon–Savarit, FUG shortcut, and rigorous MESH methods, built on vle-thermo
Keywords: distillation,separation,chemical-engineering,mccabe-thiele,mesh,column
Home-Page: https://github.com/miguelju/stages-thermo
Author-email: Miguel Jackson <admin@migueljackson.dev>
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Changelog, https://github.com/miguelju/stages-thermo/blob/main/ROADMAP.md
Project-URL: Homepage, https://github.com/miguelju/stages-thermo
Project-URL: Issues, https://github.com/miguelju/stages-thermo/issues
Project-URL: Repository, https://github.com/miguelju/stages-thermo

# stages-thermo

**A staged-separation (distillation) learning library and fast steady-state
column solver, built on [`vle-thermo`](https://pypi.org/project/vle-thermo/).**

`import stages` — walk the full pedagogical ladder of column methods
(McCabe–Thiele → Ponchon–Savarit → Fenske–Underwood–Gilliland shortcut →
rigorous MESH: bubble-point, sum-rates, inside-out, full Newton), each
implemented from scratch and anchored to its
textbook equations, with a granular, batch-capable API ("numpy for distillation
columns"). All thermodynamics come from `vle-thermo`; this package adds none of
its own.

The ladder's terminal target is an **atmospheric crude distillation unit** —
hundreds of pseudocomponents, pumparounds, steam-stripped side strippers, and
products specified on D86 95 % points and gaps rather than mole-fraction purity.

```sh
pip install stages-thermo           # import name is `stages`
pip install "stages-thermo[plot]"   # + matplotlib for the staircase diagrams
```

> **Status:** `0.3.x` ships the first three rungs of the ladder — the binary
> **McCabe–Thiele** (Milestone 1) and **Ponchon–Savarit** (Milestone 2) layers
> and the multicomponent **FUG shortcut** (Milestone 3): equilibrium and
> enthalpy–composition (H–x–y) curves from real thermodynamics, minimum reflux
> by geometric pinch detection (tangent pinches included), stage stepping with
> Murphree efficiency, total reflux, N(R), the energy-exact difference-point
> construction (with condenser/reboiler duties), the NRTL γ-φ model, per-phase
> enthalpies, Fenske–Underwood–Gilliland + Kirkbride + Winn with relative
> volatilities computed from vle-thermo K-values (`fug`), the multicomponent
> K-value / dew-point / flash surface on `ThermoSystem`, and the diagram plots
> (staircase, H–x–y, Gilliland). The rigorous MESH solvers land milestone by
> milestone — see the repo's `ROADMAP.md`. `1.0` ships **inside-out** (Boston–Britt/Russell) as the flagship
> rigorous solver alongside Wang–Henke and sum-rates; the crude-column capability
> follows at `2.0`, and Naphtali–Sandholm (the specialist for strongly nonideal
> columns) at `2.1`. The API may still move before `1.0`.

```python
import stages

# Real thermodynamics from vle-thermo: Peng–Robinson benzene–toluene at 1 atm
# (light component first; units K / kPa absolute / mole fractions).
sys = stages.ThermoSystem.peng_robinson(["benzene", "toluene"])
curve = stages.EquilibriumCurve.from_thermo(sys, 101.325)

# Minimum reflux by pinch detection — tangent pinches included …
r = stages.rmin(curve, x_distillate=0.95, x_bottoms=0.05, z_feed=0.50, q=1.0)

# … then the full construction. Rich result objects, never bare numbers:
design = stages.mccabe_thiele(curve, 0.95, 0.05, 0.50, reflux=1.5 * r.r_min)
print(f"N = {design.n_stages:.2f} stages, feed stage {design.feed_stage}, "
      f"R_min = {r.r_min:.3f}")

design.stages          # every (x, y) stage corner
design.staircase       # the full polyline, ready to plot
design.rectifying      # operating lines as slope/intercept
r.pinch, r.tangent     # where the pinch sits, and whether it's a tangent pinch

# The staircase diagram (requires the [plot] extra):
# from stages import plotting
# plotting.plot_mccabe_thiele(design, curve, show_rmin=True)
```

Strongly non-ideal systems go through the γ-φ route — the same construction,
different thermodynamics:

```python
# van Laar methanol–water (the system validated in vle's Chapter IV notebooks).
mw = stages.ThermoSystem.van_laar(["methanol", "water"], 0.5853, 0.3458)
curve_mw = stages.EquilibriumCurve.from_thermo(mw, 101.325)
```

Rung 2 — **Ponchon–Savarit** — closes the energy balance on the
enthalpy–composition (H–x–y) diagram, so it also returns the condenser and
reboiler duties (which McCabe–Thiele cannot):

```python
# H–x–y curve: saturated-liquid and -vapor enthalpies alongside y*(x).
ec = stages.EnthalpyCurve.from_thermo(sys, 101.325)
ps = stages.ponchon_savarit(ec, x_distillate=0.95, x_bottoms=0.05,
                            z_feed=0.50, reflux=1.5)
print(f"N = {ps.n_stages:.2f} stages, feed stage {ps.feed_stage}")
print(f"Q_C/F = {ps.q_condenser:,.0f}, Q_R/F = {ps.q_reboiler:,.0f} kJ/kmol feed")
ps.delta_d, ps.delta_b   # the two difference points (poles), (x, H) in kJ/kmol

# NRTL for strongly non-ideal aqueous-organic systems (a12/a21 in kJ/kmol):
aw = stages.ThermoSystem.nrtl(["ammonia", "water"], a12=-1800.0, a21=-1200.0, alpha=0.2)
# from stages import plotting; plotting.plot_ponchon_savarit(ps, ec)
```

Rung 3 — the **FUG shortcut** — is multicomponent. Every relative volatility
comes from vle-thermo K-values at the two ends of the column (the "FUG(K)"
form that a simulator uses to seed its rigorous solver), refined to
self-consistency; each rung is also callable on its own (`fenske_n_min`,
`underwood_roots`, `gilliland_stages`, `kirkbride_split`, `winn_fit`, …):

```python
# A depropanizer: propane (LK) / isobutane (HK), 98 % key recoveries, R = 1.3 R_min.
c3 = stages.ThermoSystem.peng_robinson(["ethane", "propane", "isobutane", "n-butane", "n-pentane"])
fug = stages.fug(c3, 1500.0, feed=[5, 40, 20, 25, 10], light_key=1, heavy_key=2,
                 lk_recovery=0.98, hk_recovery=0.98, q=1.0, reflux_factor=1.3)
print(fug)   # FugResult(N_min=12.95, R_min=1.885, R=2.450, N=26.47, feed_stage=15, ...)
fug.underwood_roots, fug.n_min_winn, fug.d, fug.x_d, fug.t_top   # every intermediate
# from stages import plotting; plotting.plot_gilliland(fug)
```

The executable learning path lives in the repo's `notebooks/` —
`01-mccabe-thiele.ipynb`, `02-ponchon-savarit.ipynb` and
`03-shortcut-design.ipynb` design benzene–toluene, methanol–water,
acetone–water and ammonia–water binaries (the last on a reference chart
digitized from the Pátek–Klomfar correlation) and a C2–C5 depropanizer
end-to-end, with exercises.

The native core is a Rust crate (`stages-thermo` on crates.io) with PyO3
bindings; wheels are abi3 (`cp310-abi3-*`), so one wheel per (OS, arch) covers
CPython 3.10+.

## License

MIT © Miguel Roberto Jackson Ugueto

