use vle_thermo::eos::{CubicEos, LiquidModel, VaporModel};
use vle_thermo::flash::SystemSpec;
use vle_thermo::flash::isothermal::flash_isothermal;
use vle_thermo::flash::kij_regression::{BubblePoint, fit_kij};
use vle_thermo::mixing::MixingRule;
use vle_thermo::types::Component;
fn comp(name: &str, tc: f64, pc: f64, omega: f64) -> Component {
Component {
name: name.into(),
tc,
pc,
omega,
..Component::default()
}
}
#[test]
fn chapter_iv_isothermal_flash_table_4_10() {
let comps = [
comp("n-heptane", 540.2, 2740.0, 0.350),
comp("n-butane", 425.12, 3796.0, 0.200),
];
let spec = SystemSpec {
components: &comps,
vapor: VaporModel::Cubic(CubicEos::RKS1972),
liquid: LiquidModel::Cubic(CubicEos::RKS1972),
mixing_rule: MixingRule::Classical,
kij: &[],
aij: &[],
alpha: &[],
vl: &[],
delta: &[],
sat_models: &[],
ge_model: None,
};
let res = flash_isothermal(&spec, 300.0, 100.0, &[0.5, 0.5], 1e-11, 300).unwrap();
assert!(res.two_phase, "expected a two-phase flash");
let (x1, y1, beta) = (res.x[0], res.y[0], res.beta);
let rel = |got: f64, want: f64| (got - want).abs() / want;
assert!(rel(x1, 0.6135) < 0.05, "x₁ = {x1} vs thesis 0.6135 (>5%)");
assert!(rel(y1, 0.04284) < 0.05, "y₁ = {y1} vs thesis 0.04284 (>5%)");
assert!(
rel(beta, 0.19889) < 0.05,
"β = {beta} vs thesis 0.19889 (>5%)"
);
}
#[test]
fn chapter_iv_kij_regression_table_4_11_12() {
let comps = [
comp("CO2", 304.13, 7377.0, 0.2239),
comp("n-butane", 425.12, 3796.0, 0.200),
];
let t = 357.57;
let bar_x: [(f64, f64); 6] = [
(14.824, 0.02967),
(19.029, 0.06228),
(23.511, 0.0959),
(27.441, 0.1283),
(31.164, 0.15673),
(36.404, 0.19636),
];
let data: Vec<BubblePoint> = bar_x
.iter()
.map(|&(p_bar, x1)| BubblePoint {
t,
x1,
p_exp: p_bar * 100.0, })
.collect();
let fit = fit_kij(CubicEos::PR1976, &comps, &data, -0.05, 0.30, 1e-6, 100).unwrap();
assert!(
(0.12..=0.20).contains(&fit.kij),
"fitted k₁₂ = {} outside the literature neighborhood of ~0.1357",
fit.kij
);
assert!(
fit.rmse < 0.08 * 2500.0,
"kij fit RMSE {} kPa too large on sub-critical data",
fit.rmse
);
}