Skip to content

Commit 7335de9

Browse files
authored
Convergence improvement for tp_flash (#219)
1 parent a0221b4 commit 7335de9

File tree

5 files changed

+51
-15
lines changed

5 files changed

+51
-15
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
## [0.6.1] - 2024-01-11
10+
- Python only: Release the changes introduced in `feos-core` 0.6.1.
11+
912
## [0.6.0] - 2023-12-19
1013
### Added
1114
- Added `EquationOfState.ideal_gas()` to initialize an equation of state that only consists of an ideal gas contribution. [#204](https://github.com/feos-org/feos/pull/204)

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "feos"
3-
version = "0.6.0"
3+
version = "0.6.1"
44
authors = ["Gernot Bauer <[email protected]>", "Philipp Rehner <[email protected]>"]
55
edition = "2021"
66
readme = "README.md"

feos-core/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## Unreleased
88

9+
## [0.6.1] 2024-01-11
10+
### Fixed
11+
- Improved convergence of `tp_flash` for certain edge cases. [#219](https://github.com/feos-org/feos/pull/219)
12+
913
## [0.6.0] 2023-12-19
1014
### Added
1115
- Added `EquationOfState::ideal_gas` to initialize an equation of state that only consists of an ideal gas contribution. [#204](https://github.com/feos-org/feos/pull/204)

feos-core/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "feos-core"
3-
version = "0.6.0"
3+
version = "0.6.1"
44
authors = ["Gernot Bauer <[email protected]>",
55
"Philipp Rehner <[email protected]"]
66
edition = "2021"

feos-core/src/phase_equilibria/tp_flash.rs

+42-13
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,42 @@ impl<E: Residual> State<E> {
5151
initial_state: Option<&PhaseEquilibrium<E, 2>>,
5252
options: SolverOptions,
5353
non_volatile_components: Option<Vec<usize>>,
54+
) -> EosResult<PhaseEquilibrium<E, 2>> {
55+
// initialization
56+
if let Some(init) = initial_state {
57+
let vle = self.tp_flash_(
58+
init.clone()
59+
.update_pressure(self.temperature, self.pressure(Contributions::Total))?,
60+
options,
61+
non_volatile_components.clone(),
62+
);
63+
if vle.is_ok() {
64+
return vle;
65+
}
66+
}
67+
68+
let (init1, init2) = PhaseEquilibrium::vle_init_stability(self)?;
69+
let vle = self.tp_flash_(init1, options, non_volatile_components.clone());
70+
if vle.is_ok() {
71+
return vle;
72+
}
73+
74+
if let Some(init2) = init2 {
75+
self.tp_flash_(init2, options, non_volatile_components)
76+
} else {
77+
vle
78+
}
79+
}
80+
81+
pub fn tp_flash_(
82+
&self,
83+
mut new_vle_state: PhaseEquilibrium<E, 2>,
84+
options: SolverOptions,
85+
non_volatile_components: Option<Vec<usize>>,
5486
) -> EosResult<PhaseEquilibrium<E, 2>> {
5587
// set options
5688
let (max_iter, tol, verbosity) = options.unwrap_or(MAX_ITER_TP, TOL_TP);
5789

58-
// initialization
59-
let mut new_vle_state = match initial_state {
60-
Some(init) => init
61-
.clone()
62-
.update_pressure(self.temperature, self.pressure(Contributions::Total))?,
63-
None => PhaseEquilibrium::vle_init_stability(self)?,
64-
};
65-
6690
log_iter!(
6791
verbosity,
6892
" iter | residual | phase I mole fractions | phase II mole fractions "
@@ -297,14 +321,19 @@ impl<E: Residual> PhaseEquilibrium<E, 2> {
297321
Ok(())
298322
}
299323

300-
fn vle_init_stability(feed_state: &State<E>) -> EosResult<Self> {
324+
fn vle_init_stability(feed_state: &State<E>) -> EosResult<(Self, Option<Self>)> {
301325
let mut stable_states = feed_state.stability_analysis(SolverOptions::default())?;
302326
let state1 = stable_states.pop();
303327
let state2 = stable_states.pop();
304-
match (state1, state2) {
305-
(Some(s1), Some(s2)) => Ok(Self::from_states(s1, s2)),
306-
(Some(s1), None) => Ok(Self::from_states(s1, feed_state.clone())),
307-
_ => Err(EosError::NoPhaseSplit),
328+
if let Some(s1) = state1 {
329+
let init1 = Self::from_states(s1.clone(), feed_state.clone());
330+
if let Some(s2) = state2 {
331+
Ok((Self::from_states(s1, s2), Some(init1)))
332+
} else {
333+
Ok((init1, None))
334+
}
335+
} else {
336+
Err(EosError::NoPhaseSplit)
308337
}
309338
}
310339
}

0 commit comments

Comments
 (0)