Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1addcfd
added ePC-SAFT
Mar 5, 2024
39c1f45
added epcsaft to test.yml
Mar 6, 2024
d9b9396
removed association for epcsaft
Mar 6, 2024
08bbea6
added new standard na, nb to parameter file
Mar 6, 2024
5eead2c
Moved temperature dependent sigma to parameters so that copies of Har…
g-bauer Mar 22, 2024
4d3f639
tidied up after removal of assoc and HS from epcsaft, some formatting
Mar 22, 2024
f554331
changed content of enum PermittivityRecord to not contain an addition…
Mar 22, 2024
243525b
changed interpolation function to binary search, made sure parameters…
Mar 22, 2024
b661992
removed bug: check if permittivity model types agree only if permitti…
Mar 22, 2024
dfe64c9
added possibility of constant permittivity (only 1 data point provided)
Mar 26, 2024
73e55ee
added tests for Helmholtz energy of Born and Ionic term, added parame…
Mar 26, 2024
24825c9
moved constants to top of file and named as constants
Apr 18, 2024
9534c60
reverted some changes in ionic.rs due to Pottel that weren't supposed…
Apr 18, 2024
8f13c7f
removed transport properties from ePC-SAFT
Apr 18, 2024
99b8664
added Python documentation
Apr 18, 2024
def0b2d
removed some last remainder of transport properties
Apr 18, 2024
babf87d
changed permittivity interpolation to preserve derivative
Apr 18, 2024
6518a22
added epcsaft parameters
Apr 18, 2024
eb129ba
added documentation for parameters
Apr 18, 2024
e45db99
update CHANGELOG, Cargo.toml, README
prehner Apr 18, 2024
0400804
only one Added category in CHANGELOG
prehner Apr 18, 2024
b1725f4
add binary_path in doc example
prehner Apr 18, 2024
787f06e
removed some warnings and fixed tests
prehner Apr 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
changed interpolation function to binary search, made sure parameters…
….rs creates points in correct order and all temperatures are finite
  • Loading branch information
LisaNeumaier authored and prehner committed Apr 18, 2024
commit 243525b8d1a4af52b4a99e8af6d0f73ab3032819
15 changes: 7 additions & 8 deletions src/epcsaft/eos/ionic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ impl Ionic {
// Extract parameters
let p = &self.parameters;

// Set to zero if one of the ions is 0
let sum_mole_fraction: f64 = p.ionic_comp.iter().map(|&i| state.molefracs[i].re()).sum();
if sum_mole_fraction == 0. {
return D::zero();
}

// Calculate Bjerrum length
let lambda_b = p.bjerrum_length(state, self.variant);

Expand Down Expand Up @@ -79,14 +85,7 @@ impl Ionic {
sum_x_z_chi += chi[i] * state.molefracs[i] * p.z[i].powi(2);
}

// Set to zero if one of the ions is 0
let sum_mole_fraction: f64 = p.ionic_comp.iter().map(|&i| state.molefracs[i].re()).sum();
let mut a_ion = -kappa * lambda_b * sum_x_z_chi * state.moles.sum();
if sum_mole_fraction == 0. {
a_ion = D::zero();
}

a_ion
-kappa * lambda_b * sum_x_z_chi * state.moles.sum()
}
}

Expand Down
69 changes: 32 additions & 37 deletions src/epcsaft/eos/permittivity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ impl<D: DualNum<f64> + Copy> Permittivity<D> {
}

pub fn pure_from_experimental_data(data: &[(f64, f64)], temperature: D) -> Self {
let permittivity_pure = Self::interpolate(data.to_vec(), temperature).permittivity;
let permittivity_pure = Self::interpolate(data, temperature).permittivity;
Self {
permittivity: permittivity_pure,
}
Expand Down Expand Up @@ -218,7 +218,7 @@ impl<D: DualNum<f64> + Copy> Permittivity<D> {
let permittivity = data
.iter()
.enumerate()
.map(|(i, d)| Self::interpolate(d.to_vec(), temperature).permittivity * molefracs[i])
.map(|(i, d)| Self::interpolate(d, temperature).permittivity * molefracs[i])
.sum();
Self { permittivity }
}
Expand Down Expand Up @@ -261,43 +261,38 @@ impl<D: DualNum<f64> + Copy> Permittivity<D> {
Self { permittivity }
}

pub fn interpolate(interpolation_points: Vec<(f64, f64)>, temperature: D) -> Self {
let t_interpol = Array1::from_iter(interpolation_points.iter().map(|t| (t.0)));
let eps_interpol = Array1::from_iter(interpolation_points.iter().map(|e| e.1));
/// Structure: &[(temperature, epsilon)]
/// Assume ordered by temperature
/// and temperatures are all finite.
pub fn interpolate(interpolation_points: &[(f64, f64)], temperature: D) -> Self {
// find index where temperature could be inserted
let i = interpolation_points.binary_search_by(|&(ti, _)| {
ti.partial_cmp(&temperature.re())
.expect("Unexpected value for temperature in interpolation points.")
});
// if the result is OK we don't need to interpolate ...
if let Ok(i) = i {
return Self {
permittivity: D::one() * interpolation_points[i].1,
};
}

// Initialize permittivity
let mut permittivity_pure = D::zero();
// if not, we can unwrap safely:
let i = i.unwrap_err();
let n = interpolation_points.len();

// check cases:
// 0. : below lowest temperature
// >= n : above highest temperature
// else : regular interpolation

let (l, u) = match i {
0 => (interpolation_points[0], interpolation_points[1]),
i if i >= n => (interpolation_points[n - 2], interpolation_points[n - 1]),
_ => (interpolation_points[i - 1], interpolation_points[i]),
};
let permittivity_pure = (temperature - l.0) / (u.0 - l.0) * (u.1 - l.1) + l.1;

// Check if only 1 data point is given
if interpolation_points.len() == 1 {
permittivity_pure = D::one() * eps_interpol[0];
} else {
// Check which interval temperature is in
let temperature = temperature.re();
for i in 0..(t_interpol.len() - 1) {
// Temperature is within intervals
if temperature >= t_interpol[i] && temperature < t_interpol[i + 1] {
// Interpolate
permittivity_pure = D::one() * eps_interpol[i]
+ (temperature - t_interpol[i]) * (eps_interpol[i + 1] - eps_interpol[i])
/ (t_interpol[i + 1] - t_interpol[i]);
}
}
// Temperature is lower than lowest temperature
if temperature < t_interpol[0] {
// Extrapolate from eps_0 and eps_1
permittivity_pure = D::one() * eps_interpol[0]
+ (temperature - t_interpol[0]) * (eps_interpol[1] - eps_interpol[0])
/ (t_interpol[1] - t_interpol[0]);
// Temperature is higher than highest temperature
} else if temperature >= t_interpol[t_interpol.len() - 1] {
// extrapolate from last two epsilons
permittivity_pure = D::one() * eps_interpol[t_interpol.len() - 2]
+ (temperature - t_interpol[t_interpol.len() - 2])
* (eps_interpol[t_interpol.len() - 1] - eps_interpol[t_interpol.len() - 2])
/ (t_interpol[t_interpol.len() - 1] - t_interpol[t_interpol.len() - 2]);
}
}
Self {
permittivity: permittivity_pure,
}
Expand Down
6 changes: 6 additions & 0 deletions src/epcsaft/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,12 @@ impl Parameter for ElectrolytePcSaftParameters {
{
let mut data = data.clone();
data.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
// check if all temperatures a.0 in data are finite, if not, make them finite by rounding to four digits
data.iter_mut().for_each(|a| {
if !a.0.is_finite() {
a.0 = (a.0 * 1e4).round() / 1e4;
}
});
// save data again in record
permittivity_records[i] =
Some(PermittivityRecord::ExperimentalData { data });
Expand Down