feos-org / feos

FeOs - A Framework for Equations of State and Classical Density Functional Theory
Other
115 stars 22 forks source link

Fix Python compatible `StateHD<D>`s and respective dual numbers #92

Closed g-bauer closed 1 year ago

g-bauer commented 1 year ago

For the python equation of state, users can define their own helmholtz_energy function that takes a StateHD object as input. In the function, properties of the state can be accessed, e.g. one can write state.moles. To make this work, there has to be a non-generic state object for each (hyper) dual number.

Currently, missing dual numbers are simply defined in feos-core. Using these definitions, for each a non-generic StateHD version is built. There are currently two issues:

  1. simply defining the dual numbers is not enough - we need arithmetic operations, etc. from num-dual (which currently does not export all variants we need to Python)
  2. we do not call impl_state_hd! (which implement the getters) for all states that are built. Hence, there will be errors in Python when one tries to call the getters.

To fix this, we

  1. have to properly export all dual numbers that are needed from num-dual. (Check class names in macros!)
  2. properly build all state definitions
  3. build state definition and implementation for HelmholtzEnergyDual in single macro?
prehner commented 1 year ago

Since we have to deal with this problem now anyways: Is there any way we can make the implementation of the Python FFI for the dual numbers more ergonomic? It's virtually impossible to make a Box<dyn DualNum<f64>> using a PyDualNumber<PyObject> and doing a (manually implemented) type check for every operation we have also seems unfeasible.

Aside from that the steps that you outline seem doable. Maybe expose ALL dual numbers that are created in the num-dual Python FFI and then in feos we can just build the States that we need. E.g., currently num-dual builds dual numbers with up to 10 derivatives but we would only need them for up to 2 in feos.

(For more than 10 derivatives backward AD should be seriously considered anyways)

g-bauer commented 1 year ago

These are things to consider:

  1. which dual numbers do we generate Python bindings for?
  2. which do we actually export in a num-dual module (the Python package)

For feos we just have to make sure that all variants we need in HelmholtzEnergy are build and public in the python (Rust) module. But I agree, we should investigate if any improvements to the way we build the bindings can be made. This is, however, an issue for num-dual.

In feos, currently two macros are used. One implements the getters for the states that are at the moment defined manually, the second one implements the HelmholtzEnergy trait. It should be possible to do that all automatically given a list of dual numbers.