Skip to content

Commit df30885

Browse files
committed
started impl for yaeos interface
1 parent 7dc32ee commit df30885

File tree

4 files changed

+237
-37
lines changed

4 files changed

+237
-37
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ serde_json = "1.0"
1616
libc = "0.2"
1717
ndarray = "0.15"
1818
num-dual = "0.8"
19+
typenum = "1.17.0"
1920

2021
[build-dependencies]
2122
cbindgen = { version = "0.26", default-features = false }

src/c/test.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <stdio.h>
22
#include <stdint.h>
3-
#include <feos.h>
3+
#include "feos.h"
44
// typedef struct feos_eos feos_eos_t;
55
// extern feos_eos_t *feos_eos_from_json(const char *str);
66
// extern void feos_eos_free(feos_eos_t *);
@@ -109,25 +109,28 @@ int main(void)
109109
// feos_equation_of_state_t *eos = feos_eos_from_json(str2);
110110

111111
// state
112-
double temperature = 200.0; // K
113-
double pressure = 15.0; // bar
112+
double temperature = 300.0; // K
113+
double pressure = 1.0; // bar
114114
double moles[] = {1.0}; // mol for each component
115115
size_t n = sizeof(moles) / sizeof(size_t); // number of components
116116

117+
feos_density_initialization_t density_init = {initial_density, 0.01}; // {tag, density in mol/meter³}
118+
117119
feos_state_t *state = feos_state_new_npt(
118120
eos, // equation of state
119121
temperature, // temperature in K
120122
pressure, // pressure in bar
121123
moles, // number of mols
122124
n, // number of components
123-
"stable" // which phase to compute (stable, liquid, vapor)
125+
density_init // which density to use as starting point
124126
);
125127

126-
double pressure_calculated = feos_state_pressure(state, 2);
128+
double pressure_calculated = feos_state_pressure(state, Total);
127129
double density = feos_state_density(state);
128130

129131
printf("State stable? %s\n", feos_state_is_stable(state) ? "true" : "false");
130132
printf("pressure: %f bar\n", pressure);
133+
printf("pressure_calculated: %f bar\n", pressure_calculated);
131134
printf("density: %f mol/m3\n", density);
132135

133136
feos_state_free(state);

src/lib.rs

Lines changed: 77 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,78 @@
11
use feos::pcsaft::{PcSaft, PcSaftBinaryRecord, PcSaftParameters, PcSaftRecord};
22
use feos::{ideal_gas::IdealGasModel, ResidualModel};
33
use feos_core::parameter::{BinaryRecord, Identifier, IdentifierOption, Parameter, PureRecord};
4-
use feos_core::si::{BAR, KELVIN, KILOGRAM, METER, MOL};
5-
use feos_core::{Contributions, DensityInitialization, EquationOfState, SolverOptions, State};
4+
use feos_core::si::{Pressure, ANGSTROM, BAR, KELVIN, KILOGRAM, METER, MOL, PASCAL};
5+
use feos_core::{
6+
Contributions, DensityInitialization, Derivative, EquationOfState, SolverOptions, State, StateHD
7+
};
68
use libc::{c_char, size_t};
79
use ndarray::Array1;
10+
use num_dual::HyperDual64;
811
use serde_json::Value;
912
use std::ffi::CStr;
1013
use std::slice;
1114
use std::sync::Arc;
15+
use typenum::P3;
1216

1317
pub mod pcsaft;
18+
pub mod residual;
19+
20+
#[repr(C)]
21+
#[derive(Clone, Copy, Debug)]
22+
#[allow(non_camel_case_types)]
23+
pub enum feos_density_initialization_t {
24+
/// Calculate a vapor phase by initializing using the ideal gas.
25+
vapor,
26+
/// Calculate a liquid phase by using the `max_density`.
27+
liquid,
28+
/// Use the given density as initial value.
29+
initial_density(f64),
30+
/// Calculate the most stable phase by calculating both a vapor and a liquid
31+
/// and return the one with the lower molar Gibbs energy.
32+
none,
33+
}
34+
35+
impl From<feos_density_initialization_t> for DensityInitialization {
36+
fn from(value: feos_density_initialization_t) -> Self {
37+
match value {
38+
feos_density_initialization_t::vapor => Self::Vapor,
39+
feos_density_initialization_t::liquid => Self::Liquid,
40+
feos_density_initialization_t::initial_density(rho) => {
41+
Self::InitialDensity(rho.clone() * MOL / (METER * METER * METER))
42+
}
43+
feos_density_initialization_t::none => Self::None,
44+
}
45+
}
46+
}
47+
48+
/// Possible contributions that can be computed.
49+
#[repr(C)]
50+
#[derive(Clone, Copy)]
51+
pub enum feos_contributions_t {
52+
/// Only compute the ideal gas contribution
53+
IdealGas,
54+
/// Only compute the difference between the total and the ideal gas contribution
55+
Residual,
56+
/// Compute ideal gas and residual contributions
57+
Total,
58+
}
59+
60+
impl From<feos_contributions_t> for Contributions {
61+
fn from(value: feos_contributions_t) -> Self {
62+
match value {
63+
feos_contributions_t::IdealGas => Contributions::IdealGas,
64+
feos_contributions_t::Residual => Contributions::Residual,
65+
feos_contributions_t::Total => Contributions::Total,
66+
}
67+
}
68+
}
1469

1570
#[allow(non_camel_case_types)]
1671
pub struct feos_equation_of_state_t(Arc<EquationOfState<IdealGasModel, ResidualModel>>);
1772

1873
#[no_mangle]
1974
#[allow(non_camel_case_types)]
20-
pub extern fn feos_eos_from_json(json: *const c_char) -> *mut feos_equation_of_state_t {
75+
pub extern "C" fn feos_eos_from_json(json: *const c_char) -> *mut feos_equation_of_state_t {
2176
let c_str = unsafe {
2277
assert!(!json.is_null());
2378
CStr::from_ptr(json)
@@ -34,9 +89,10 @@ pub extern fn feos_eos_from_json(json: *const c_char) -> *mut feos_equation_of_s
3489
match residual_model_name.to_lowercase().as_str() {
3590
"pc-saft" | "pcsaft" => {
3691
let pure_records: Vec<PureRecord<PcSaftRecord>> =
37-
serde_json::from_value(v["residual_substance_parameters"].clone()).unwrap();
92+
serde_json::from_value(v["residual_substance_parameters"].clone()).unwrap();
3893
let binary_records: Vec<BinaryRecord<Identifier, PcSaftBinaryRecord>> =
39-
serde_json::from_value(v["residual_binary_parameters"].clone()).unwrap_or(Vec::new());
94+
serde_json::from_value(v["residual_binary_parameters"].clone())
95+
.unwrap_or(Vec::new());
4096
let binary_matrix = <PcSaftParameters as Parameter>::binary_matrix_from_records(
4197
&pure_records,
4298
&binary_records,
@@ -57,7 +113,7 @@ pub extern fn feos_eos_from_json(json: *const c_char) -> *mut feos_equation_of_s
57113

58114
#[no_mangle]
59115
#[allow(non_camel_case_types)]
60-
pub extern fn feos_eos_free(ptr: *mut feos_equation_of_state_t) {
116+
pub extern "C" fn feos_eos_free(ptr: *mut feos_equation_of_state_t) {
61117
if !ptr.is_null() {
62118
unsafe {
63119
drop(Box::from_raw(ptr));
@@ -71,7 +127,7 @@ pub struct feos_state_t(State<EquationOfState<IdealGasModel, ResidualModel>>);
71127

72128
#[no_mangle]
73129
#[allow(non_camel_case_types)]
74-
pub extern fn feos_state_free(ptr: *mut feos_state_t) {
130+
pub extern "C" fn feos_state_free(ptr: *mut feos_state_t) {
75131
if !ptr.is_null() {
76132
unsafe {
77133
drop(Box::from_raw(ptr));
@@ -81,64 +137,53 @@ pub extern fn feos_state_free(ptr: *mut feos_state_t) {
81137

82138
#[no_mangle]
83139
#[allow(non_camel_case_types)]
84-
pub extern fn feos_state_new_npt(
140+
pub extern "C" fn feos_state_new_npt(
85141
eos_ptr: *const feos_equation_of_state_t,
86142
t_k: f64,
87143
p_bar: f64,
88144
moles: *const f64,
89145
len: size_t,
90-
phase: *const c_char,
146+
density_initialization: feos_density_initialization_t,
91147
) -> *mut feos_state_t {
92148
let eos = unsafe {
93149
assert!(!eos_ptr.is_null());
94150
&*eos_ptr
95151
};
96-
let phase_str = unsafe {
97-
assert!(!phase.is_null());
98-
CStr::from_ptr(phase)
99-
};
152+
// let initialization = unsafe {
153+
// assert!(!density_initialization.is_null());
154+
// &*density_initialization
155+
// };
100156
let n = unsafe {
101157
assert!(!moles.is_null());
102158
Array1::from_iter(slice::from_raw_parts(moles, len).iter().cloned()) * MOL
103159
};
104-
105-
let density_initialization = match phase_str.to_str().unwrap() {
106-
"liquid" => DensityInitialization::Liquid,
107-
"vapor" => DensityInitialization::Vapor,
108-
_ => DensityInitialization::None,
109-
};
110160
let state = State::new_npt(
111161
&eos.0,
112162
t_k * KELVIN,
113163
p_bar * BAR,
114164
&n,
115-
density_initialization,
165+
density_initialization.into(),
116166
)
117167
.unwrap();
118168
Box::into_raw(Box::new(feos_state_t(state)))
119169
}
120170

121171
#[no_mangle]
122172
#[allow(non_camel_case_types)]
123-
pub extern fn feos_state_pressure(
173+
pub extern "C" fn feos_state_pressure(
124174
state_ptr: *const feos_state_t,
125-
contributions: size_t,
175+
contributions: feos_contributions_t,
126176
) -> f64 {
127177
let state = unsafe {
128178
assert!(!state_ptr.is_null());
129179
&*state_ptr
130180
};
131-
let c = match contributions {
132-
0 => Contributions::IdealGas,
133-
1 => Contributions::Residual,
134-
_ => Contributions::Total,
135-
};
136-
state.0.pressure(c).convert_into(BAR)
181+
state.0.pressure(contributions.into()).convert_into(BAR)
137182
}
138183

139184
#[no_mangle]
140185
#[allow(non_camel_case_types)]
141-
pub extern fn feos_state_density(state_ptr: *const feos_state_t) -> f64 {
186+
pub extern "C" fn feos_state_density(state_ptr: *const feos_state_t) -> f64 {
142187
let state = unsafe {
143188
assert!(!state_ptr.is_null());
144189
&*state_ptr
@@ -147,12 +192,12 @@ pub extern fn feos_state_density(state_ptr: *const feos_state_t) -> f64 {
147192
}
148193

149194
/// Mass density of the state.
150-
///
195+
///
151196
/// @params state_ptr Pointer to the state.
152197
/// @returns mass density in units of kg/m3
153198
#[no_mangle]
154199
#[allow(non_camel_case_types)]
155-
pub extern fn feos_state_mass_density(state_ptr: *const feos_state_t) -> f64 {
200+
pub extern "C" fn feos_state_mass_density(state_ptr: *const feos_state_t) -> f64 {
156201
let state = unsafe {
157202
assert!(!state_ptr.is_null());
158203
&*state_ptr
@@ -170,7 +215,7 @@ pub extern fn feos_state_mass_density(state_ptr: *const feos_state_t) -> f64 {
170215
/// @returns True if the state is stable, false otherwise.
171216
#[no_mangle]
172217
#[allow(non_camel_case_types)]
173-
pub extern fn feos_state_is_stable(state_ptr: *const feos_state_t) -> bool {
218+
pub extern "C" fn feos_state_is_stable(state_ptr: *const feos_state_t) -> bool {
174219
let state = unsafe {
175220
assert!(!state_ptr.is_null());
176221
&*state_ptr

0 commit comments

Comments
 (0)