1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! Saturation pressure models.
//!
//! Saturation (vapor) pressure Psat(T) is the pressure at which a pure component
//! boils at temperature T. These correlations are essential for:
//!
//! 1. **Initial K-value estimates** in flash calculations — Ki ≈ Psat_i(T) / P_system
//! gives a starting point for iterative convergence.
//! 2. **Bubble/dew point initialization** — correlating Psat across components
//! gives initial temperature or pressure guesses.
//! 3. **Validation** — comparing EOS-predicted saturation with correlation values
//! confirms the EOS parameterization is correct.
//!
//! The models range from simple empirical (Antoine, 3 parameters) to thermodynamically
//! consistent (Maxwell equal-area, derived directly from the EOS).
//!
//! # References
//! - (4) Da Silva & Báez (1989) — Antoine correlation
/// Saturation (vapor) pressure correlation model.
///
/// Used to estimate pure-component saturation pressure Psat(T) in **kPa**
/// from temperature in **K**.
// ===========================================================================
// M7.5 — Antoine saturation pressure (only).
//
// The four remaining models (Riedel, Müller, RPM, polynomial, Maxwell) are
// M7.4 deferred. Their dispatch branches in `psat` panic with
// `unimplemented!` and a pointer to the legacy source.
// ===========================================================================
use crateComponent;
use Error;
/// Errors raised by the saturation-pressure layer.
/// Antoine vapor pressure: `ln(P_sat/Pc) = a1 − a2/(a3 + T)`.
///
/// # Arguments
/// * `comp` — Component (uses `pc` and `psat_coeffs`).
/// * `t` — Temperature in **K**.
///
/// # Returns
/// Saturation pressure in **kPa absolute**.
///
/// # Errors
/// `BadCoefficients` if `psat_coeffs` does not have exactly 3 entries.
/// `OutOfRange` if `a3 + T ≤ 0` (would produce inf/NaN in the exp).
///
/// # Source
/// Reference (4): Da Silva & Báez (1989), `legacy/pascal/TERMOI.PAS`. The
/// form `ln(P/Pc) = a1 − a2/(a3 + T)` is the "reduced" Antoine the
/// Pascal program uses — coefficients are tabulated against the
/// component's own Pc, not against 1 atm. Some external Antoine tables
/// use `log10(P) = A − B/(C + T)` with a different sign on `C`; convert
/// before calling this function.
/// Analytical derivative `dPsat/dT` for the Antoine form.
///
/// `Psat = Pc · exp(a1 − a2/(a3 + T))`
/// `dPsat/dT = Psat · a2 / (a3 + T)²`
///
/// Returns `dPsat/dT` in **kPa/K**.
/// Generic dispatch: compute saturation pressure for any model.
///
/// Only the [`SatPressureModel::Antoine`] branch is implemented in M7.1.
/// All others panic via [`SatError::NotImplemented`] so callers get a
/// runtime error instead of an undetected zero — covers M7.4.