Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Breaking]
### Added
- Added `PoreSpecification` enum to specify the state of the fluid in the pore (currently chemical potential or moles). [#371](https://github.com/feos-org/feos/pull/371)
- Added the `Grid` and `PoreProfile` classes as an entry points to DFT in various coordinate systems in Python. [#376](https://github.com/feos-org/feos/pull/376)

### Changed
- Changed data type of initial temperatures or pressure for phase equilibrium calculations (`TemperatureOrPressure::Other`) from `D` to `f64`. [#369](https://github.com/feos-org/feos/pull/369)
- Reworked DFT solution algorithms slightly for the cases in which additional specifications are given. [#371](https://github.com/feos-org/feos/pull/371)
- External potentials are passed and returned as quantities (energies) instead of reduced units. [#372](https://github.com/feos-org/feos/pull/372)
- Merged the `Adsorption1D` and `Adsorption3D` classes in Python into `Adsorption` using dynamically dimensioned arrays. [#376](https://github.com/feos-org/feos/pull/376)

### Removed
- Removed the `DFTSpecification` trait in favor of only using the `DFTSpecification` enum (renamed from `DFTSpecifications`). [#371](https://github.com/feos-org/feos/pull/371)
- Removed the `Pore2D` and `Pore3D` interfaces including the (limited) calculation of external potentials for complex pore grometries. [#376](https://github.com/feos-org/feos/pull/376)
- Removed the free energy-averaged external (FEA) potential. [#376](https://github.com/feos-org/feos/pull/376)

### Packaging
- Removed the `gauss-quad` dependency which was only used in the FEA potential calculation. [#376](https://github.com/feos-org/feos/pull/376)

## [Unreleased]

## [0.10.0] - 2026-07-15
Expand Down
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ keywords = [
categories = ["science"]

[workspace.dependencies]
quantity = "0.14"
num-dual = "0.14"
quantity = "0.15"
num-dual = "0.15"
ndarray = "0.17"
nalgebra = "0.35"
thiserror = "2.0"
Expand All @@ -38,7 +38,6 @@ petgraph = "0.8"
rustdct = "0.7"
rustfft = "6.0"
libm = "0.2"
gauss-quad = "0.3"
approx = "0.5"
criterion = "0.8"
paste = "1.0"
Expand Down
7 changes: 3 additions & 4 deletions crates/feos-core/src/ad/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mod properties;
pub use dataset::*;
pub use properties::*;

pub(crate) type Gradient<const P: usize> = DualSVec<f64, f64, P>;
pub(crate) type Gradient<const P: usize> = DualSVec<f64, P>;

/// A model that can be evaluated with derivatives of its parameters.
pub trait ParametersAD<N: Dim>: Residual<N>
Expand All @@ -23,7 +23,7 @@ where
/// defines the canonical parameter order.
///
/// Set `differentiable` to `false` for fixed parameters.
fn build<D: DualNum<f64, Inner = f64> + Copy>(
fn build<D: DualNum<Primitive = f64, Inner = f64> + Copy>(
f: impl FnMut(&'static str, bool) -> D,
) -> Self::Lifted<D>;

Expand Down Expand Up @@ -66,8 +66,7 @@ where
idx += 1;
let mut d = Gradient::<P>::from(parameter_values[i]);
if let Some(seed_idx) = derivative_names.iter().position(|&n| n == name) {
d.eps =
Derivative::<_, _, Const<P>, _>::derivative_generic(Const::<P>, U1, seed_idx);
d.eps = Derivative::<_, Const<P>, _>::derivative_generic(Const::<P>, U1, seed_idx);
}
d
})
Expand Down
2 changes: 1 addition & 1 deletion crates/feos-core/src/ad/properties/boiling_temperature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ where
type Unit = _Temperature;
const REFERENCE: Temperature = KELVIN;

fn evaluate<E: Residual<N, D>, D: DualNum<f64, Inner = f64> + Copy>(
fn evaluate<E: Residual<N, D>, D: DualNum<Primitive = f64, Inner = f64> + Copy>(
&self,
eos: &E,
) -> FeosResult<Temperature<D>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ where
type Unit = _Pressure;
const REFERENCE: Pressure = PASCAL;

fn evaluate<E: Residual<N, D>, D: DualNum<f64, Inner = f64> + Copy>(
fn evaluate<E: Residual<N, D>, D: DualNum<Primitive = f64, Inner = f64> + Copy>(
&self,
eos: &E,
) -> FeosResult<Pressure<D>>
Expand Down
2 changes: 1 addition & 1 deletion crates/feos-core/src/ad/properties/dew_point_pressure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ where
type Unit = _Pressure;
const REFERENCE: Pressure = PASCAL;

fn evaluate<E: Residual<N, D>, D: DualNum<f64, Inner = f64> + Copy>(
fn evaluate<E: Residual<N, D>, D: DualNum<Primitive = f64, Inner = f64> + Copy>(
&self,
eos: &E,
) -> FeosResult<Pressure<D>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ where
type Unit = _MolarEnergy;
const REFERENCE: MolarEnergy = MolarEnergy::new(1.0);

fn evaluate<E: Residual<N, D>, D: DualNum<f64, Inner = f64> + Copy>(
fn evaluate<E: Residual<N, D>, D: DualNum<Primitive = f64, Inner = f64> + Copy>(
&self,
eos: &E,
) -> FeosResult<MolarEnergy<D>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ where
type Unit = _Density;
const REFERENCE: Density = Density::new(1000.0);

fn evaluate<E: Residual<N, D>, D: DualNum<f64, Inner = f64> + Copy>(
fn evaluate<E: Residual<N, D>, D: DualNum<Primitive = f64, Inner = f64> + Copy>(
&self,
eos: &E,
) -> FeosResult<Density<D>> {
Expand Down
2 changes: 1 addition & 1 deletion crates/feos-core/src/ad/properties/liquid_density.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ where
type Unit = _Density;
const REFERENCE: Density = Density::new(1000.0);

fn evaluate<E: Residual<N, D>, D: DualNum<f64, Inner = f64> + Copy>(
fn evaluate<E: Residual<N, D>, D: DualNum<Primitive = f64, Inner = f64> + Copy>(
&self,
eos: &E,
) -> FeosResult<Density<D>> {
Expand Down
2 changes: 1 addition & 1 deletion crates/feos-core/src/ad/properties/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ where
const REFERENCE: Quantity<f64, Self::Unit>;

/// Evaluate the property for an arbitrary derivative.
fn evaluate<E: Residual<N, D>, D: DualNum<f64, Inner = f64> + Copy>(
fn evaluate<E: Residual<N, D>, D: DualNum<Primitive = f64, Inner = f64> + Copy>(
&self,
eos: &E,
) -> FeosResult<Quantity<D, Self::Unit>>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ where
type Unit = _MolarEntropy;
const REFERENCE: MolarEntropy = MolarEntropy::new(1.0);

fn evaluate<E: Residual<N, D>, D: DualNum<f64, Inner = f64> + Copy>(
fn evaluate<E: Residual<N, D>, D: DualNum<Primitive = f64, Inner = f64> + Copy>(
&self,
eos: &E,
) -> FeosResult<MolarEntropy<D>> {
Expand Down
2 changes: 1 addition & 1 deletion crates/feos-core/src/ad/properties/vapor_pressure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ where
type Unit = _Pressure;
const REFERENCE: Pressure = PASCAL;

fn evaluate<E: Residual<N, D>, D: DualNum<f64, Inner = f64> + Copy>(
fn evaluate<E: Residual<N, D>, D: DualNum<Primitive = f64, Inner = f64> + Copy>(
&self,
eos: &E,
) -> FeosResult<Pressure<D>> {
Expand Down
4 changes: 2 additions & 2 deletions crates/feos-core/src/cubic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ impl ResidualDyn for PengRobinson {
self.tc.len()
}

fn compute_max_density<D: DualNum<f64> + Copy>(&self, molefracs: &DVector<D>) -> D {
fn compute_max_density<D: DualNum<Primitive = f64> + Copy>(&self, molefracs: &DVector<D>) -> D {
D::from(0.9) / molefracs.dot(&self.b.map(D::from))
}

fn reduced_helmholtz_energy_density_contributions<D: DualNum<f64> + Copy>(
fn reduced_helmholtz_energy_density_contributions<D: DualNum<Primitive = f64> + Copy>(
&self,
state: &StateHD<D>,
) -> Vec<(&'static str, D)> {
Expand Down
2 changes: 1 addition & 1 deletion crates/feos-core/src/density_iteration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use nalgebra::{DefaultAllocator, Dim, OVector};
use num_dual::{Dual, DualNum, first_derivative};
use quantity::{Density, Pressure, Temperature};

pub fn density_iteration<E: Residual<N, D>, N: Dim, D: DualNum<f64> + Copy>(
pub fn density_iteration<E: Residual<N, D>, N: Dim, D: DualNum<Primitive = f64> + Copy>(
eos: &E,
temperature: Temperature<D>,
pressure: Pressure<D>,
Expand Down
35 changes: 18 additions & 17 deletions crates/feos-core/src/equation_of_state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ impl<I, R: ResidualDyn> ResidualDyn for EquationOfState<Vec<I>, R> {
self.residual.components()
}

fn compute_max_density<D: DualNum<f64> + Copy>(&self, molefracs: &DVector<D>) -> D {
fn compute_max_density<D: DualNum<Primitive = f64> + Copy>(&self, molefracs: &DVector<D>) -> D {
self.residual.compute_max_density(molefracs)
}

fn reduced_helmholtz_energy_density_contributions<D: DualNum<f64> + Copy>(
fn reduced_helmholtz_energy_density_contributions<D: DualNum<Primitive = f64> + Copy>(
&self,
state: &StateHD<D>,
) -> Vec<(&'static str, D)> {
Expand All @@ -79,19 +79,20 @@ impl<I: Clone, R: Subset> Subset for EquationOfState<Vec<I>, R> {
}
}

impl<I: Clone, R: Residual<Const<N>, D>, D: DualNum<f64> + Copy, const N: usize>
impl<I: Clone, R: Residual<Const<N>, D>, D: DualNum<Primitive = f64> + Copy, const N: usize>
Residual<Const<N>, D> for EquationOfState<[I; N], R>
{
fn components(&self) -> usize {
N
}

type Real = EquationOfState<[I; N], R::Real>;
type Lifted<D2: DualNum<f64, Inner = D> + Copy> = EquationOfState<[I; N], R::Lifted<D2>>;
type Lifted<D2: DualNum<Primitive = f64, Inner = D> + Copy> =
EquationOfState<[I; N], R::Lifted<D2>>;
fn re(&self) -> Self::Real {
EquationOfState::new(self.ideal_gas.clone(), self.residual.re())
}
fn lift<D2: DualNum<f64, Inner = D> + Copy>(&self) -> Self::Lifted<D2> {
fn lift<D2: DualNum<Primitive = f64, Inner = D> + Copy>(&self) -> Self::Lifted<D2> {
EquationOfState::new(self.ideal_gas.clone(), self.residual.lift())
}

Expand All @@ -118,7 +119,7 @@ pub trait IdealGas {
/// Implementation of an ideal gas model in terms of the
/// logarithm of the cubic thermal de Broglie wavelength
/// in units ln(A³) for each component in the system.
fn ln_lambda3<D: DualNum<f64> + Copy>(&self, temperature: D) -> D;
fn ln_lambda3<D: DualNum<Primitive = f64> + Copy>(&self, temperature: D) -> D;

/// The name of the ideal gas model.
fn ideal_gas_model(&self) -> &'static str;
Expand All @@ -128,9 +129,9 @@ pub trait IdealGas {
/// respect to parameters.
pub trait IdealGasAD<D = f64>: Clone {
type Real: IdealGasAD;
type Lifted<D2: DualNum<f64, Inner = D> + Copy>: IdealGasAD<D2>;
type Lifted<D2: DualNum<Primitive = f64, Inner = D> + Copy>: IdealGasAD<D2>;
fn re(&self) -> Self::Real;
fn lift<D2: DualNum<f64, Inner = D> + Copy>(&self) -> Self::Lifted<D2>;
fn lift<D2: DualNum<Primitive = f64, Inner = D> + Copy>(&self) -> Self::Lifted<D2>;

/// Implementation of an ideal gas model in terms of the
/// logarithm of the cubic thermal de Broglie wavelength
Expand All @@ -142,14 +143,14 @@ pub trait IdealGasAD<D = f64>: Clone {
}

/// A total Helmholtz energy model consisting of a [Residual] model and an [IdealGas] part.
pub trait Total<N: Dim = Dyn, D: DualNum<f64> + Copy = f64>: Residual<N, D>
pub trait Total<N: Dim = Dyn, D: DualNum<Primitive = f64> + Copy = f64>: Residual<N, D>
where
DefaultAllocator: Allocator<N>,
{
type RealTotal: Total<N, f64>;
type LiftedTotal<D2: DualNum<f64, Inner = D> + Copy>: Total<N, D2>;
type LiftedTotal<D2: DualNum<Primitive = f64, Inner = D> + Copy>: Total<N, D2>;
fn re_total(&self) -> Self::RealTotal;
fn lift_total<D2: DualNum<f64, Inner = D> + Copy>(&self) -> Self::LiftedTotal<D2>;
fn lift_total<D2: DualNum<Primitive = f64, Inner = D> + Copy>(&self) -> Self::LiftedTotal<D2>;

fn ideal_gas_model(&self) -> &'static str;

Expand Down Expand Up @@ -199,15 +200,15 @@ impl<
I: IdealGas + 'static,
C: Deref<Target = EquationOfState<Vec<I>, R>> + Clone,
R: ResidualDyn + 'static,
D: DualNum<f64> + Copy,
D: DualNum<Primitive = f64> + Copy,
> Total<Dyn, D> for C
{
type RealTotal = Self;
type LiftedTotal<D2: DualNum<f64, Inner = D> + Copy> = Self;
type LiftedTotal<D2: DualNum<Primitive = f64, Inner = D> + Copy> = Self;
fn re_total(&self) -> Self::RealTotal {
self.clone()
}
fn lift_total<D2: DualNum<f64, Inner = D> + Copy>(&self) -> Self::LiftedTotal<D2> {
fn lift_total<D2: DualNum<Primitive = f64, Inner = D> + Copy>(&self) -> Self::LiftedTotal<D2> {
self.clone()
}

Expand All @@ -225,19 +226,19 @@ impl<
}
}

impl<I: IdealGasAD<D>, R: Residual<Const<N>, D>, D: DualNum<f64> + Copy, const N: usize>
impl<I: IdealGasAD<D>, R: Residual<Const<N>, D>, D: DualNum<Primitive = f64> + Copy, const N: usize>
Total<Const<N>, D> for EquationOfState<[I; N], R>
{
type RealTotal = EquationOfState<[I::Real; N], R::Real>;
type LiftedTotal<D2: DualNum<f64, Inner = D> + Copy> =
type LiftedTotal<D2: DualNum<Primitive = f64, Inner = D> + Copy> =
EquationOfState<[I::Lifted<D2>; N], R::Lifted<D2>>;
fn re_total(&self) -> Self::RealTotal {
EquationOfState::new(
self.ideal_gas.each_ref().map(|i| i.re()),
self.residual.re(),
)
}
fn lift_total<D2: DualNum<f64, Inner = D> + Copy>(&self) -> Self::LiftedTotal<D2> {
fn lift_total<D2: DualNum<Primitive = f64, Inner = D> + Copy>(&self) -> Self::LiftedTotal<D2> {
EquationOfState::new(
self.ideal_gas.each_ref().map(|i| i.lift()),
self.residual.lift(),
Expand Down
Loading