Skip to content
This repository was archived by the owner on Jun 14, 2022. It is now read-only.

Commit 2ed2d5c

Browse files
authored
Fix state constructor for obscure specification (#26)
* Fix state constructor for obscure specification * update changelog * no latex in MD on github 😞
1 parent 94c7368 commit 2ed2d5c

File tree

5 files changed

+55
-25
lines changed

5 files changed

+55
-25
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
### Fixed
9+
- Fix state constructor for `T`, `p`, `V`, `x_i` specification. [#26](https://github.com/feos-org/feos-core/pull/26)
810

911
## [0.1.3] - 2022-01-21
1012
### Added

src/cubic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl std::fmt::Display for PengRobinsonParameters {
7272
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7373
self.pure_records
7474
.iter()
75-
.try_for_each(|pr| writeln!(f, "{}", pr.to_string()))?;
75+
.try_for_each(|pr| writeln!(f, "{}", pr))?;
7676
writeln!(f, "\nk_ij:\n{}", self.k_ij)
7777
}
7878
}

src/python/cubic.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ use std::rc::Rc;
1919
#[derive(Clone)]
2020
pub struct PyPengRobinsonRecord(PengRobinsonRecord);
2121

22+
#[pymethods]
23+
impl PyPengRobinsonRecord {
24+
#[new]
25+
fn new(tc: f64, pc: f64, acentric_factor: f64) -> Self {
26+
Self(PengRobinsonRecord::new(tc, pc, acentric_factor))
27+
}
28+
}
29+
2230
#[pyproto]
2331
impl pyo3::class::basic::PyObjectProtocol for PyPengRobinsonRecord {
2432
fn __repr__(&self) -> PyResult<String> {

src/state/mod.rs

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -355,55 +355,60 @@ impl<U: EosUnit, E: EquationOfState> State<U, E> {
355355
)));
356356
}
357357
let x = partial_density
358-
.map(|pd| pd / pd.sum())
359-
.or_else(|| moles.map(|ms| ms / ms.sum()));
358+
.map(|pd| pd.to_reduced(pd.sum()))
359+
.or_else(|| moles.map(|ms| ms.to_reduced(ms.sum())))
360+
.transpose()?;
360361
let x_u = match (x, molefracs, eos.components()) {
361362
(Some(_), Some(_), _) => {
362363
return Err(EosError::UndeterminedState(String::from(
363364
"Composition is overdetermined.",
364365
)))
365366
}
366367
(Some(x), None, _) => x,
367-
(None, Some(x), _) => x.clone().into(),
368-
(None, None, 1) => arr1(&[1.0]).into(),
368+
(None, Some(x), _) => x.clone(),
369+
(None, None, 1) => arr1(&[1.0]),
369370
_ => {
370371
return Err(EosError::UndeterminedState(String::from(
371372
"Missing composition.",
372373
)))
373374
}
374375
};
375376

376-
// If no extensive property is given, moles is set to reference moles.
377-
// Therefore, moles and composition are known from this point on.
378-
let n_t = n.unwrap_or_else(U::reference_moles);
379-
let n_i = x_u * n_t;
380-
let v = volume.or_else(|| rho.map(|d| n_t / d));
377+
// If no extensive property is given, moles is set to the reference value.
378+
if let (None, None) = (volume, n) {
379+
n = Some(U::reference_moles())
380+
}
381+
let n_i = n.map(|n| &x_u * n);
382+
let v = volume.or_else(|| rho.and_then(|d| n.map(|n| n / d)));
381383

382384
// check if new state can be created using default constructor
383-
if let (Some(v), Some(t)) = (v, temperature) {
384-
return State::new_nvt(eos, t, v, &n_i);
385+
if let (Some(v), Some(t), Some(n_i)) = (v, temperature, &n_i) {
386+
return State::new_nvt(eos, t, v, n_i);
385387
}
386388

387389
// Check if new state can be created using density iteration
388-
if let (Some(p), Some(t)) = (pressure, temperature) {
389-
return State::new_npt(eos, t, p, &n_i, density_initialization);
390+
if let (Some(p), Some(t), Some(n_i)) = (pressure, temperature, &n_i) {
391+
return State::new_npt(eos, t, p, n_i, density_initialization);
392+
}
393+
if let (Some(p), Some(t), Some(v)) = (pressure, temperature, v) {
394+
return State::new_npvx(eos, t, p, v, &x_u, density_initialization);
390395
}
391396

392397
// Check if new state can be created using molar_enthalpy and temperature
393-
if let (Some(p), Some(h)) = (pressure, molar_enthalpy) {
394-
return State::new_nph(eos, p, h, &n_i, density_initialization, initial_temperature);
398+
if let (Some(p), Some(h), Some(n_i)) = (pressure, molar_enthalpy, &n_i) {
399+
return State::new_nph(eos, p, h, n_i, density_initialization, initial_temperature);
395400
}
396-
if let (Some(p), Some(s)) = (pressure, molar_entropy) {
397-
return State::new_nps(eos, p, s, &n_i, density_initialization, initial_temperature);
401+
if let (Some(p), Some(s), Some(n_i)) = (pressure, molar_entropy, &n_i) {
402+
return State::new_nps(eos, p, s, n_i, density_initialization, initial_temperature);
398403
}
399-
if let (Some(t), Some(h)) = (temperature, molar_enthalpy) {
400-
return State::new_nth(eos, t, h, &n_i, density_initialization);
404+
if let (Some(t), Some(h), Some(n_i)) = (temperature, molar_enthalpy, &n_i) {
405+
return State::new_nth(eos, t, h, n_i, density_initialization);
401406
}
402-
if let (Some(t), Some(s)) = (temperature, molar_entropy) {
403-
return State::new_nts(eos, t, s, &n_i, density_initialization);
407+
if let (Some(t), Some(s), Some(n_i)) = (temperature, molar_entropy, &n_i) {
408+
return State::new_nts(eos, t, s, n_i, density_initialization);
404409
}
405-
if let (Some(u), Some(v)) = (molar_internal_energy, volume) {
406-
return State::new_nvu(eos, v, u, &n_i, initial_temperature);
410+
if let (Some(u), Some(v), Some(n_i)) = (molar_internal_energy, volume, &n_i) {
411+
return State::new_nvu(eos, v, u, n_i, initial_temperature);
407412
}
408413
Err(EosError::UndeterminedState(String::from(
409414
"Missing input parameters.",
@@ -478,6 +483,21 @@ impl<U: EosUnit, E: EquationOfState> State<U, E> {
478483
}
479484
}
480485

486+
/// Return a new `State` for given pressure $p$, volume $V$, temperature $T$ and composition $x_i$.
487+
pub fn new_npvx(
488+
eos: &Rc<E>,
489+
temperature: QuantityScalar<U>,
490+
pressure: QuantityScalar<U>,
491+
volume: QuantityScalar<U>,
492+
molefracs: &Array1<f64>,
493+
density_initialization: DensityInitialization<U>,
494+
) -> EosResult<Self> {
495+
let moles = molefracs * U::reference_moles();
496+
let state = Self::new_npt(eos, temperature, pressure, &moles, density_initialization)?;
497+
let moles = state.partial_density * volume;
498+
Self::new_nvt(eos, temperature, volume, &moles)
499+
}
500+
481501
/// Return a new `State` for given pressure $p$ and molar enthalpy $h$.
482502
pub fn new_nph(
483503
eos: &Rc<E>,

src/utils/estimator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ where
115115
impl<U: EosUnit, E: EquationOfState> fmt::Display for Estimator<U, E> {
116116
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117117
for d in self.data.iter() {
118-
writeln!(f, "{}", d.to_string())?;
118+
writeln!(f, "{}", d)?;
119119
}
120120
Ok(())
121121
}

0 commit comments

Comments
 (0)