-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathmod.rs
More file actions
140 lines (119 loc) · 4.29 KB
/
mod.rs
File metadata and controls
140 lines (119 loc) · 4.29 KB
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
use crate::hard_sphere::{FMTContribution, FMTVersion, HardSphereProperties, MonomerShape};
use crate::saftvrqmie::eos::SaftVRQMieOptions;
use crate::saftvrqmie::parameters::SaftVRQMieParameters;
use dispersion::AttractiveFunctional;
use feos_core::joback::Joback;
use feos_core::parameter::Parameter;
use feos_core::{IdealGasContribution, MolarWeight};
use feos_dft::adsorption::FluidParameters;
use feos_dft::solvation::PairPotential;
use feos_dft::{FunctionalContribution, HelmholtzEnergyFunctional, MoleculeShape, DFT};
use ndarray::{Array, Array1, Array2};
use non_additive_hs::NonAddHardSphereFunctional;
use num_dual::DualNum;
use quantity::si::*;
use std::f64::consts::FRAC_PI_6;
use std::sync::Arc;
mod dispersion;
mod non_additive_hs;
/// SAFT-VRQ Mie Helmholtz energy functional.
pub struct SaftVRQMieFunctional {
pub parameters: Arc<SaftVRQMieParameters>,
fmt_version: FMTVersion,
options: SaftVRQMieOptions,
contributions: Vec<Box<dyn FunctionalContribution>>,
joback: Joback,
}
impl SaftVRQMieFunctional {
pub fn new(parameters: Arc<SaftVRQMieParameters>) -> DFT<Self> {
Self::with_options(
parameters,
FMTVersion::WhiteBear,
SaftVRQMieOptions::default(),
)
}
pub fn new_full(parameters: Arc<SaftVRQMieParameters>, fmt_version: FMTVersion) -> DFT<Self> {
Self::with_options(parameters, fmt_version, SaftVRQMieOptions::default())
}
pub fn with_options(
parameters: Arc<SaftVRQMieParameters>,
fmt_version: FMTVersion,
saft_options: SaftVRQMieOptions,
) -> DFT<Self> {
let mut contributions: Vec<Box<dyn FunctionalContribution>> = Vec::with_capacity(3);
// Hard sphere contribution
let hs = FMTContribution::new(¶meters, fmt_version);
contributions.push(Box::new(hs));
// Non-additive hard-sphere contribution
if saft_options.inc_nonadd_term {
let non_add_hs = NonAddHardSphereFunctional::new(parameters.clone());
contributions.push(Box::new(non_add_hs));
}
// Dispersion
let att = AttractiveFunctional::new(parameters.clone());
contributions.push(Box::new(att));
let joback = match ¶meters.joback_records {
Some(joback_records) => Joback::new(joback_records.clone()),
None => Joback::default(parameters.m.len()),
};
(Self {
parameters,
fmt_version,
options: saft_options,
contributions,
joback,
})
.into()
}
}
impl HelmholtzEnergyFunctional for SaftVRQMieFunctional {
fn subset(&self, component_list: &[usize]) -> DFT<Self> {
Self::with_options(
Arc::new(self.parameters.subset(component_list)),
self.fmt_version,
self.options,
)
}
fn compute_max_density(&self, moles: &Array1<f64>) -> f64 {
self.options.max_eta * moles.sum()
/ (FRAC_PI_6 * &self.parameters.m * self.parameters.sigma.mapv(|v| v.powi(3)) * moles)
.sum()
}
fn contributions(&self) -> &[Box<dyn FunctionalContribution>] {
&self.contributions
}
fn ideal_gas(&self) -> &dyn IdealGasContribution {
&self.joback
}
fn molecule_shape(&self) -> MoleculeShape {
MoleculeShape::NonSpherical(&self.parameters.m)
}
}
impl MolarWeight for SaftVRQMieFunctional {
fn molar_weight(&self) -> SIArray1 {
self.parameters.molarweight.clone() * GRAM / MOL
}
}
impl HardSphereProperties for SaftVRQMieParameters {
fn monomer_shape<N: DualNum<f64>>(&self, _: N) -> MonomerShape<N> {
MonomerShape::Spherical(self.m.len())
}
fn hs_diameter<D: DualNum<f64>>(&self, temperature: D) -> Array1<D> {
self.hs_diameter(temperature)
}
}
impl FluidParameters for SaftVRQMieFunctional {
fn epsilon_k_ff(&self) -> Array1<f64> {
self.parameters.epsilon_k.clone()
}
fn sigma_ff(&self) -> &Array1<f64> {
&self.parameters.sigma
}
}
impl PairPotential for SaftVRQMieFunctional {
fn pair_potential(&self, i: usize, r: &Array1<f64>, temperature: f64) -> Array2<f64> {
Array::from_shape_fn((self.parameters.m.len(), r.len()), |(j, k)| {
self.parameters.qmie_potential_ij(i, j, r[k], temperature)[0]
})
}
}