Skip to content

Commit 8e17223

Browse files
committed
Fix critical point evaluation if one component has 0 composition
1 parent ef7a56a commit 8e17223

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

crates/feos-core/src/state/critical_point.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use num_dual::{
1010
implicit_derivative_binary, implicit_derivative_vec, jacobian, partial, partial2,
1111
third_derivative,
1212
};
13+
use num_traits::Zero;
1314
use quantity::{Density, Pressure, Temperature};
1415

1516
const MAX_ITER_CRIT_POINT: usize = 50;
@@ -537,7 +538,13 @@ where
537538
let n = n + sqrt_z.component_mul(&u).map(Dual3::from_re) * s;
538539
let t = Dual3::from_re(temperature);
539540
let v = Dual3::from_re(molar_volume);
540-
let ig = n.dot(&n.map(|n| (n / v).ln() - 1.0));
541+
let ig = n.dot(&n.map(|n| {
542+
if n.is_zero() {
543+
Dual3::zero()
544+
} else {
545+
(n / v).ln() - 1.0
546+
}
547+
}));
541548
eos.lift().residual_helmholtz_energy(t, v, &n) / t + ig
542549
},
543550
D::from(0.0),

crates/feos/tests/pcsaft/critical_point.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use approx::assert_relative_eq;
22
use feos::pcsaft::{PcSaft, PcSaftParameters};
3-
use feos_core::State;
43
use feos_core::parameter::IdentifierOption;
4+
use feos_core::{SolverOptions, State};
55
use nalgebra::dvector;
66
use quantity::*;
77
use std::error::Error;
8+
use std::sync::Arc;
89
use typenum::P3;
910

1011
#[test]
@@ -47,3 +48,31 @@ fn test_critical_point_mix() -> Result<(), Box<dyn Error>> {
4748
);
4849
Ok(())
4950
}
51+
52+
#[test]
53+
fn test_critical_point_limits() -> Result<(), Box<dyn Error>> {
54+
let params = PcSaftParameters::from_json(
55+
vec!["propane", "butane"],
56+
"tests/pcsaft/test_parameters.json",
57+
None,
58+
IdentifierOption::Name,
59+
)?;
60+
let options = SolverOptions {
61+
verbosity: feos_core::Verbosity::Iter,
62+
..Default::default()
63+
};
64+
let saft = Arc::new(PcSaft::new(params));
65+
let cp_pure = State::critical_point_pure(&saft, None, None, options)?;
66+
println!("{} {}", cp_pure[0], cp_pure[1]);
67+
let molefracs = dvector![0.0, 1.0];
68+
let cp_2 = State::critical_point(&saft, Some(&molefracs), None, None, options)?;
69+
println!("{}", cp_2);
70+
let molefracs = dvector![1.0, 0.0];
71+
let cp_1 = State::critical_point(&saft, Some(&molefracs), None, None, options)?;
72+
println!("{}", cp_1);
73+
assert_eq!(cp_pure[0].temperature, cp_1.temperature);
74+
assert_eq!(cp_pure[0].density, cp_1.density);
75+
assert_eq!(cp_pure[1].temperature, cp_2.temperature);
76+
assert_eq!(cp_pure[1].density, cp_2.density);
77+
Ok(())
78+
}

0 commit comments

Comments
 (0)