Skip to content

Commit d4818dc

Browse files
authored
Add the gc PC-SAFT eos and functional (#12)
* Add the gc PC-SAFT eos and functional * update README * update README even more
1 parent 47515c0 commit d4818dc

File tree

6 files changed

+190
-52
lines changed

6 files changed

+190
-52
lines changed

Cargo.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ categories = ["science"]
1616
crate-type = ["cdylib"]
1717

1818
[dependencies]
19-
quantity = { version = "0.5", features = ["python"] }
20-
feos-core = { git = "https://github.com/feos-org/feos-core", features = ["python"] }
21-
feos-dft = { git = "https://github.com/feos-org/feos-dft", features = ["python"], branch = "v0.2.0" }
19+
quantity = "0.5"
20+
feos-core = "0.2"
21+
feos-dft = "0.2"
2222
feos-pcsaft = { git = "https://github.com/feos-org/feos-pcsaft", features = ["python"] }
23-
feos-pets = { git = "https://github.com/feos-org/feos-pets", features = ["python"], branch = "new_dft_struct" }
23+
feos-gc-pcsaft = { version = "0.1", features = ["python"] }
24+
feos-pets = { git = "https://github.com/feos-org/feos-pets", features = ["python"] }
2425
numpy = { version = "0.16" }
2526
ndarray = { version = "0.15", features=["approx"] }
2627

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ The following models are currently published as part of the `FeOs` framework
1111
|name|description|eos|dft|
1212
|-|-|:-:|:-:|
1313
|[`feos-pcsaft`](https://github.com/feos-org/feos-pcsaft)|perturbed-chain (polar) statistical associating fluid theory|🗸|🗸|
14+
|[`feos-gc-pcsaft`](https://github.com/feos-org/feos-gc-pcsaft)|(heterosegmented) group contribution PC-SAFT|🗸|🗸|
1415

15-
The list is being expanded continuously. Currently under development are implementations of ePC-SAFT, (heterosegmented) group contribution PC-SAFT and equations of state/Helmholtz energy functionals for model fluids like LJ and Mie fluids.
16+
The list is being expanded continuously. Currently under development are implementations of ePC-SAFT and equations of state/Helmholtz energy functionals for model fluids like LJ and Mie fluids.
1617

1718
Other public repositories that implement models within the `FeOs` framework, but are currently not part of the `feos` Python package, are
1819

src/dft.rs

Lines changed: 95 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use feos_dft::interface::*;
55
use feos_dft::python::*;
66
use feos_dft::solvation::*;
77
use feos_dft::*;
8+
use feos_gc_pcsaft::python::PyGcPcSaftFunctionalParameters;
9+
use feos_gc_pcsaft::{GcPcSaftFunctional, GcPcSaftOptions};
810
use feos_pcsaft::python::PyPcSaftParameters;
911
use feos_pcsaft::{PcSaftFunctional, PcSaftOptions};
1012
use feos_pets::python::PyPetsParameters;
@@ -20,84 +22,89 @@ use std::collections::HashMap;
2022
use std::rc::Rc;
2123

2224
pub enum FunctionalVariant {
23-
PcSaftFunctional(PcSaftFunctional),
24-
PetsFunctional(PetsFunctional),
25-
FMTFunctional(FMTFunctional),
25+
PcSaft(PcSaftFunctional),
26+
GcPcSaft(GcPcSaftFunctional),
27+
Pets(PetsFunctional),
28+
Fmt(FMTFunctional),
2629
}
2730

2831
impl From<PcSaftFunctional> for FunctionalVariant {
2932
fn from(f: PcSaftFunctional) -> Self {
30-
Self::PcSaftFunctional(f)
33+
Self::PcSaft(f)
34+
}
35+
}
36+
37+
impl From<GcPcSaftFunctional> for FunctionalVariant {
38+
fn from(f: GcPcSaftFunctional) -> Self {
39+
Self::GcPcSaft(f)
3140
}
3241
}
3342

3443
impl From<PetsFunctional> for FunctionalVariant {
3544
fn from(f: PetsFunctional) -> Self {
36-
Self::PetsFunctional(f)
45+
Self::Pets(f)
3746
}
3847
}
3948

4049
impl From<FMTFunctional> for FunctionalVariant {
4150
fn from(f: FMTFunctional) -> Self {
42-
Self::FMTFunctional(f)
51+
Self::Fmt(f)
4352
}
4453
}
4554

4655
impl HelmholtzEnergyFunctional for FunctionalVariant {
4756
fn subset(&self, component_list: &[usize]) -> DFT<Self> {
4857
match self {
49-
FunctionalVariant::PcSaftFunctional(functional) => {
50-
functional.subset(component_list).into()
51-
}
52-
FunctionalVariant::PetsFunctional(functional) => {
53-
functional.subset(component_list).into()
54-
}
55-
FunctionalVariant::FMTFunctional(functional) => {
56-
functional.subset(component_list).into()
57-
}
58+
FunctionalVariant::PcSaft(functional) => functional.subset(component_list).into(),
59+
FunctionalVariant::GcPcSaft(functional) => functional.subset(component_list).into(),
60+
FunctionalVariant::Pets(functional) => functional.subset(component_list).into(),
61+
FunctionalVariant::Fmt(functional) => functional.subset(component_list).into(),
5862
}
5963
}
6064

6165
fn molecule_shape(&self) -> MoleculeShape {
6266
match self {
63-
FunctionalVariant::PcSaftFunctional(functional) => functional.molecule_shape(),
64-
FunctionalVariant::PetsFunctional(functional) => functional.molecule_shape(),
65-
FunctionalVariant::FMTFunctional(functional) => functional.molecule_shape(),
67+
FunctionalVariant::PcSaft(functional) => functional.molecule_shape(),
68+
FunctionalVariant::GcPcSaft(functional) => functional.molecule_shape(),
69+
FunctionalVariant::Pets(functional) => functional.molecule_shape(),
70+
FunctionalVariant::Fmt(functional) => functional.molecule_shape(),
6671
}
6772
}
6873

6974
fn compute_max_density(&self, moles: &Array1<f64>) -> f64 {
7075
match self {
71-
FunctionalVariant::PcSaftFunctional(functional) => {
72-
functional.compute_max_density(moles)
73-
}
74-
FunctionalVariant::PetsFunctional(functional) => functional.compute_max_density(moles),
75-
FunctionalVariant::FMTFunctional(functional) => functional.compute_max_density(moles),
76+
FunctionalVariant::PcSaft(functional) => functional.compute_max_density(moles),
77+
FunctionalVariant::GcPcSaft(functional) => functional.compute_max_density(moles),
78+
FunctionalVariant::Pets(functional) => functional.compute_max_density(moles),
79+
FunctionalVariant::Fmt(functional) => functional.compute_max_density(moles),
7680
}
7781
}
7882

7983
fn contributions(&self) -> &[Box<dyn FunctionalContribution>] {
8084
match self {
81-
FunctionalVariant::PcSaftFunctional(functional) => functional.contributions(),
82-
FunctionalVariant::PetsFunctional(functional) => functional.contributions(),
83-
FunctionalVariant::FMTFunctional(functional) => functional.contributions(),
85+
FunctionalVariant::PcSaft(functional) => functional.contributions(),
86+
FunctionalVariant::GcPcSaft(functional) => functional.contributions(),
87+
FunctionalVariant::Pets(functional) => functional.contributions(),
88+
FunctionalVariant::Fmt(functional) => functional.contributions(),
8489
}
8590
}
8691

8792
fn ideal_gas(&self) -> &dyn IdealGasContribution {
8893
match self {
89-
FunctionalVariant::PcSaftFunctional(functional) => functional.ideal_gas(),
90-
FunctionalVariant::PetsFunctional(functional) => functional.ideal_gas(),
91-
FunctionalVariant::FMTFunctional(functional) => functional.ideal_gas(),
94+
FunctionalVariant::PcSaft(functional) => functional.ideal_gas(),
95+
FunctionalVariant::GcPcSaft(functional) => functional.ideal_gas(),
96+
FunctionalVariant::Pets(functional) => functional.ideal_gas(),
97+
FunctionalVariant::Fmt(functional) => functional.ideal_gas(),
9298
}
9399
}
94100
}
95101

96102
impl MolarWeight<SIUnit> for FunctionalVariant {
97103
fn molar_weight(&self) -> SIArray1 {
98104
match self {
99-
FunctionalVariant::PcSaftFunctional(functional) => functional.molar_weight(),
100-
FunctionalVariant::PetsFunctional(functional) => functional.molar_weight(),
105+
FunctionalVariant::PcSaft(functional) => functional.molar_weight(),
106+
FunctionalVariant::GcPcSaft(functional) => functional.molar_weight(),
107+
FunctionalVariant::Pets(functional) => functional.molar_weight(),
101108
_ => unimplemented!(),
102109
}
103110
}
@@ -106,27 +113,30 @@ impl MolarWeight<SIUnit> for FunctionalVariant {
106113
impl FluidParameters for FunctionalVariant {
107114
fn epsilon_k_ff(&self) -> Array1<f64> {
108115
match self {
109-
FunctionalVariant::PcSaftFunctional(functional) => functional.epsilon_k_ff(),
110-
FunctionalVariant::PetsFunctional(functional) => functional.epsilon_k_ff(),
111-
FunctionalVariant::FMTFunctional(functional) => functional.epsilon_k_ff(),
116+
FunctionalVariant::PcSaft(functional) => functional.epsilon_k_ff(),
117+
FunctionalVariant::GcPcSaft(functional) => functional.epsilon_k_ff(),
118+
FunctionalVariant::Pets(functional) => functional.epsilon_k_ff(),
119+
FunctionalVariant::Fmt(functional) => functional.epsilon_k_ff(),
112120
}
113121
}
114122

115123
fn sigma_ff(&self) -> &Array1<f64> {
116124
match self {
117-
FunctionalVariant::PcSaftFunctional(functional) => functional.sigma_ff(),
118-
FunctionalVariant::PetsFunctional(functional) => functional.sigma_ff(),
119-
FunctionalVariant::FMTFunctional(functional) => functional.sigma_ff(),
125+
FunctionalVariant::PcSaft(functional) => functional.sigma_ff(),
126+
FunctionalVariant::GcPcSaft(functional) => functional.sigma_ff(),
127+
FunctionalVariant::Pets(functional) => functional.sigma_ff(),
128+
FunctionalVariant::Fmt(functional) => functional.sigma_ff(),
120129
}
121130
}
122131
}
123132

124133
impl PairPotential for FunctionalVariant {
125134
fn pair_potential(&self, r: &Array1<f64>) -> Array2<f64> {
126135
match self {
127-
FunctionalVariant::PcSaftFunctional(functional) => functional.pair_potential(r),
128-
FunctionalVariant::PetsFunctional(functional) => functional.pair_potential(r),
129-
FunctionalVariant::FMTFunctional(functional) => functional.pair_potential(r),
136+
FunctionalVariant::PcSaft(functional) => functional.pair_potential(r),
137+
FunctionalVariant::Pets(functional) => functional.pair_potential(r),
138+
FunctionalVariant::Fmt(functional) => functional.pair_potential(r),
139+
_ => unimplemented!(),
130140
}
131141
}
132142
}
@@ -187,6 +197,51 @@ impl PyFunctionalVariant {
187197
))
188198
}
189199

200+
/// (heterosegmented) group contribution PC-SAFT Helmholtz energy functional.
201+
///
202+
/// Parameters
203+
/// ----------
204+
/// parameters: GcPcSaftFunctionalParameters
205+
/// The set of PC-SAFT parameters.
206+
/// fmt_version: FMTVersion, optional
207+
/// The specific variant of the FMT term. Defaults to FMTVersion.WhiteBear
208+
/// max_eta : float, optional
209+
/// Maximum packing fraction. Defaults to 0.5.
210+
/// max_iter_cross_assoc : unsigned integer, optional
211+
/// Maximum number of iterations for cross association. Defaults to 50.
212+
/// tol_cross_assoc : float
213+
/// Tolerance for convergence of cross association. Defaults to 1e-10.
214+
///
215+
/// Returns
216+
/// -------
217+
/// Functional
218+
#[args(
219+
fmt_version = "FMTVersion::WhiteBear",
220+
max_eta = "0.5",
221+
max_iter_cross_assoc = "50",
222+
tol_cross_assoc = "1e-10"
223+
)]
224+
#[staticmethod]
225+
#[pyo3(
226+
text_signature = "(parameters, fmt_version, max_eta, max_iter_cross_assoc, tol_cross_assoc)"
227+
)]
228+
fn gc_csaft(
229+
parameters: PyGcPcSaftFunctionalParameters,
230+
fmt_version: FMTVersion,
231+
max_eta: f64,
232+
max_iter_cross_assoc: usize,
233+
tol_cross_assoc: f64,
234+
) -> Self {
235+
let options = GcPcSaftOptions {
236+
max_eta,
237+
max_iter_cross_assoc,
238+
tol_cross_assoc,
239+
};
240+
Self(Rc::new(
241+
GcPcSaftFunctional::with_options(parameters.0, fmt_version, options).into(),
242+
))
243+
}
244+
190245
/// PeTS Helmholtz energy functional without simplifications
191246
/// for pure components.
192247
///

0 commit comments

Comments
 (0)