Skip to main content

stages_thermo/
lib.rs

1//! # stages-thermo — a staged-separation (distillation) column solver
2//!
3//! `stages-thermo` is a learning library **and** a fast steady-state column
4//! engine for staged separations. It walks the full pedagogical ladder —
5//! McCabe–Thiele → Ponchon–Savarit → Fenske–Underwood–Gilliland shortcut →
6//! rigorous MESH (Wang–Henke, Burningham–Otto, Naphtali–Sandholm) — with every
7//! method implemented from scratch and anchored to its textbook equations, and
8//! it exposes a granular, batch-capable API ("numpy for distillation columns").
9//!
10//! The thermodynamics — K-values, enthalpies, and their derivatives — come
11//! **entirely** from [`vle_thermo`](https://crates.io/crates/vle-thermo). This
12//! crate adds no thermodynamics of its own; it is the first downstream consumer
13//! of vle-thermo. See `PLAN.md` §1 for the full vision.
14//!
15//! ## Status
16//!
17//! Milestone 1 (column model + McCabe–Thiele). Implemented so far:
18//!
19//! - [`thermo`] — the adapter over vle-thermo 0.9.x: [`thermo::ThermoSystem`]
20//!   with database-loaded components, φ-φ (Peng–Robinson) and γ-φ (van Laar)
21//!   routes, bubble-point evaluation.
22//! - [`column`] — the binary-sufficient column model
23//!   ([`column::BinaryColumn`], [`column::Feed`], [`column::CondenserKind`]).
24//! - [`binary`] — the equilibrium curve ([`binary::EquilibriumCurve`]) and
25//!   the full McCabe–Thiele construction ([`binary::mccabe_thiele`]):
26//!   operating lines, q-line, stage stepping, R_min with tangent-pinch
27//!   detection, total reflux (N_min), N(R), Murphree efficiency.
28//!
29//! The remaining method modules (`shortcut`, `rigorous`, `numerics`) land
30//! milestone by milestone per `ROADMAP.md`; the target module tree is
31//! documented in `PLAN.md` §6.
32//!
33//! ## Design rule (PLAN §7)
34//!
35//! **Exactly one module talks to vle-thermo:** [`thermo`]. Everything else
36//! consumes it through a provider interface, so a surrogate thermo model (the
37//! inside-out inner loop, a stretch milestone) or a test mock can slot in
38//! without touching the solvers.
39
40pub mod binary;
41pub mod column;
42pub mod thermo;
43pub mod types;
44
45// Python bindings are compiled only with the `python` feature (enabled by
46// maturin when building the wheel). `cargo add stages-thermo` gets a pure-Rust
47// crate with no PyO3 in its dependency closure.
48#[cfg(feature = "python")]
49mod py_bindings;
50
51/// Return this crate's version string (matches `Cargo.toml`).
52///
53/// Mirrors vle-thermo's `version()` so downstream Python can introspect which
54/// engine build is loaded.
55pub fn version() -> &'static str {
56    env!("CARGO_PKG_VERSION")
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62
63    #[test]
64    fn version_is_semver_shaped() {
65        let v = version();
66        let parts: Vec<&str> = v.split('.').collect();
67        assert!(parts.len() >= 3, "version {v} is not semver-shaped");
68        assert!(parts[0].parse::<u64>().is_ok(), "major of {v} not numeric");
69    }
70}