Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Next Next commit
Replace impl_pure_record and similar macros with common Python classes
  • Loading branch information
prehner committed Feb 13, 2025
commit 63aa74ef5103131c19cf2938a8b096558b4bc1e2
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ codegen-units = 1


[features]
default = []
default = ["python"]
dft = ["feos-dft", "petgraph"]
estimator = []
association = []
Expand Down
7 changes: 5 additions & 2 deletions feos-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ num-traits = "0.2"
thiserror = "2.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
indexmap = "2.0"
indexmap = { version = "2.0", features = ["serde"] }
conv = "0.3"
numpy = { version = "0.23", optional = true }
pyo3 = { version = "0.23", features = ["multiple-pymethods"], optional = true }
pyo3 = { version = "0.23", features = [
"multiple-pymethods",
"indexmap",
], optional = true }
rayon = { version = "1.5", optional = true }
typenum = "1.16"
approx = "0.5"
Expand Down
1 change: 1 addition & 0 deletions feos-core/src/parameter/chemical_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct ChemicalRecordJSON {
#[derive(Deserialize, Serialize, Debug, Clone)]
#[serde(from = "ChemicalRecordJSON")]
#[serde(into = "ChemicalRecordJSON")]
#[cfg_attr(feature = "python", pyo3::pyclass(get_all, set_all))]
pub struct ChemicalRecord {
pub identifier: Identifier,
pub segments: Vec<String>,
Expand Down
3 changes: 2 additions & 1 deletion feos-core/src/parameter/identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ pub enum IdentifierOption {
Formula,
}

/// A collection of identifiers for a chemical structure or substance.
// /// A collection of identifiers for a chemical structure or substance.
#[cfg_attr(feature = "python", pyo3::pyclass(get_all, set_all))]
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct Identifier {
/// CAS number
Expand Down
19 changes: 8 additions & 11 deletions feos-core/src/parameter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ mod segment;
pub use chemical_record::{ChemicalRecord, SegmentCount};
pub use identifier::{Identifier, IdentifierOption};
pub use model_record::{BinaryRecord, FromSegments, FromSegmentsBinary, PureRecord};
pub use segment::SegmentRecord;
pub use segment::{BinarySegmentRecord, SegmentRecord};

/// Constructor methods for parameters.
///
Expand Down Expand Up @@ -85,7 +85,7 @@ where
#[allow(clippy::expect_fun_call)]
fn binary_matrix_from_records(
pure_records: &[PureRecord<Self::Pure>],
binary_records: &[BinaryRecord<Identifier, Self::Binary>],
binary_records: &[BinaryRecord<Self::Binary>],
identifier_option: IdentifierOption,
) -> Option<Array2<Self::Binary>> {
if binary_records.is_empty() {
Expand Down Expand Up @@ -198,7 +198,7 @@ where
fn from_segments<C: SegmentCount>(
chemical_records: Vec<C>,
segment_records: Vec<SegmentRecord<Self::Pure>>,
binary_segment_records: Option<Vec<BinaryRecord<String, f64>>>,
binary_segment_records: Option<Vec<BinarySegmentRecord>>,
) -> Result<Self, ParameterError>
where
Self::Pure: FromSegments<C::Count>,
Expand Down Expand Up @@ -315,7 +315,7 @@ where
let binary_records = file_binary
.map(|file_binary| {
let reader = BufReader::new(File::open(file_binary)?);
let binary_records: Result<Vec<BinaryRecord<String, f64>>, ParameterError> =
let binary_records: Result<Vec<BinarySegmentRecord>, ParameterError> =
Ok(serde_json::from_reader(reader)?);
binary_records
})
Expand Down Expand Up @@ -380,13 +380,12 @@ impl fmt::Display for NoBinaryModelRecord {
pub trait ParameterHetero: Sized {
type Chemical: Clone;
type Pure: Clone + DeserializeOwned;
type Binary: Clone + DeserializeOwned;

/// Creates parameters from the molecular structure and segment information.
fn from_segments<C: Clone + Into<Self::Chemical>>(
chemical_records: Vec<C>,
segment_records: Vec<SegmentRecord<Self::Pure>>,
binary_segment_records: Option<Vec<BinaryRecord<String, Self::Binary>>>,
binary_segment_records: Option<Vec<BinarySegmentRecord>>,
) -> Result<Self, ParameterError>;

/// Return the original records that were used to construct the parameters.
Expand All @@ -396,7 +395,7 @@ pub trait ParameterHetero: Sized {
) -> (
&[Self::Chemical],
&[SegmentRecord<Self::Pure>],
&Option<Vec<BinaryRecord<String, Self::Binary>>>,
&Option<Vec<BinarySegmentRecord>>,
);

/// Creates parameters from segment information stored in json files.
Expand Down Expand Up @@ -452,10 +451,8 @@ pub trait ParameterHetero: Sized {
let binary_records = file_binary
.map(|file_binary| {
let reader = BufReader::new(File::open(file_binary)?);
let binary_records: Result<
Vec<BinaryRecord<String, Self::Binary>>,
ParameterError,
> = Ok(serde_json::from_reader(reader)?);
let binary_records: Result<Vec<BinarySegmentRecord>, ParameterError> =
Ok(serde_json::from_reader(reader)?);
binary_records
})
.transpose()?;
Expand Down
20 changes: 7 additions & 13 deletions feos-core/src/parameter/model_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,21 +127,20 @@ pub trait FromSegmentsBinary<T>: Clone {
fn from_segments_binary(segments: &[(f64, T, T)]) -> Result<Self, ParameterError>;
}

/// A collection of parameters that model interactions between two
/// substances or segments.
/// A collection of parameters that model interactions between two substances.
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BinaryRecord<I, B> {
pub struct BinaryRecord<B> {
/// Identifier of the first component
pub id1: I,
pub id1: Identifier,
/// Identifier of the second component
pub id2: I,
pub id2: Identifier,
/// Binary interaction parameter(s)
pub model_record: B,
}

impl<I, B> BinaryRecord<I, B> {
impl<B> BinaryRecord<B> {
/// Crates a new `BinaryRecord`.
pub fn new(id1: I, id2: I, model_record: B) -> Self {
pub fn new(id1: Identifier, id2: Identifier, model_record: B) -> Self {
Self {
id1,
id2,
Expand All @@ -152,18 +151,13 @@ impl<I, B> BinaryRecord<I, B> {
/// Read a list of `BinaryRecord`s from a JSON file.
pub fn from_json<P: AsRef<Path>>(file: P) -> Result<Vec<Self>, ParameterError>
where
I: DeserializeOwned,
B: DeserializeOwned,
{
Ok(serde_json::from_reader(BufReader::new(File::open(file)?))?)
}
}

impl<I, B> std::fmt::Display for BinaryRecord<I, B>
where
I: std::fmt::Display,
B: std::fmt::Display,
{
impl<B: std::fmt::Display> std::fmt::Display for BinaryRecord<B> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "BinaryRecord(")?;
write!(f, "\n\tid1={},", self.id1)?;
Expand Down
38 changes: 38 additions & 0 deletions feos-core/src/parameter/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,41 @@ impl<M: std::fmt::Display> std::fmt::Display for SegmentRecord<M> {
write!(f, "\n)")
}
}

/// A collection of parameters that model interactions between two segments.
#[derive(Serialize, Deserialize, Debug, Clone)]
#[cfg_attr(feature = "python", pyo3::pyclass)]
pub struct BinarySegmentRecord {
/// Identifier of the first component
pub id1: String,
/// Identifier of the second component
pub id2: String,
/// Binary interaction parameter(s)
pub model_record: f64,
}

impl BinarySegmentRecord {
/// Crates a new `BinaryRecord`.
pub fn new(id1: String, id2: String, model_record: f64) -> Self {
Self {
id1,
id2,
model_record,
}
}

/// Read a list of `BinaryRecord`s from a JSON file.
pub fn from_json<P: AsRef<Path>>(file: P) -> Result<Vec<Self>, ParameterError> {
Ok(serde_json::from_reader(BufReader::new(File::open(file)?))?)
}
}

impl std::fmt::Display for BinarySegmentRecord {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "BinaryRecord(")?;
write!(f, "\n\tid1={},", self.id1)?;
write!(f, "\n\tid2={},", self.id2)?;
write!(f, "\n\tmodel_record={},", self.model_record)?;
write!(f, "\n)")
}
}
50 changes: 22 additions & 28 deletions feos-core/src/python/cubic.rs
Original file line number Diff line number Diff line change
@@ -1,48 +1,42 @@
use crate::cubic::{PengRobinsonParameters, PengRobinsonRecord};
use crate::parameter::{
BinaryRecord, Identifier, IdentifierOption, Parameter, ParameterError, PureRecord,
};
use crate::python::parameter::PyIdentifier;
use super::parameter::PyPureRecord;
use crate::cubic::PengRobinsonParameters;
use crate::parameter::{IdentifierOption, Parameter, ParameterError};
use crate::python::parameter::PyBinaryRecord;
use crate::*;
use numpy::{PyArray2, PyReadonlyArray2, ToPyArray};
use pyo3::exceptions::PyTypeError;
use pyo3::prelude::*;
use std::convert::{TryFrom, TryInto};
use std::sync::Arc;

/// A pure substance parameter for the Peng-Robinson equation of state.
#[pyclass(name = "PengRobinsonRecord")]
#[derive(Clone)]
pub struct PyPengRobinsonRecord(PengRobinsonRecord);
// /// A pure substance parameter for the Peng-Robinson equation of state.
// #[pyclass(name = "PengRobinsonRecord")]
// #[derive(Clone)]
// pub struct PyPengRobinsonRecord(PengRobinsonRecord);

#[pymethods]
impl PyPengRobinsonRecord {
#[new]
fn new(tc: f64, pc: f64, acentric_factor: f64) -> Self {
Self(PengRobinsonRecord::new(tc, pc, acentric_factor))
}
// #[pymethods]
// impl PyPengRobinsonRecord {
// #[new]
// fn new(tc: f64, pc: f64, acentric_factor: f64) -> Self {
// Self(PengRobinsonRecord::new(tc, pc, acentric_factor))
// }

fn __repr__(&self) -> PyResult<String> {
Ok(self.0.to_string())
}
}
// fn __repr__(&self) -> PyResult<String> {
// Ok(self.0.to_string())
// }
// }

impl_json_handling!(PyPengRobinsonRecord);
// impl_json_handling!(PyPengRobinsonRecord);

impl_pure_record!(PengRobinsonRecord, PyPengRobinsonRecord);
// impl_pure_record!(PengRobinsonRecord, PyPengRobinsonRecord);

impl_binary_record!();
// impl_binary_record!();

#[pyclass(name = "PengRobinsonParameters")]
#[derive(Clone)]
pub struct PyPengRobinsonParameters(pub Arc<PengRobinsonParameters>);

impl_parameter!(
PengRobinsonParameters,
PyPengRobinsonParameters,
PyPengRobinsonRecord,
f64
);
impl_parameter!(PengRobinsonParameters, PyPengRobinsonParameters);

#[pymethods]
impl PyPengRobinsonParameters {
Expand Down
Loading