Merge pull request #65 from tboudreaux/feature/pythonInterface/eos

Python EOS interface [helm]
This commit is contained in:
2025-06-13 07:36:22 -04:00
committed by GitHub
23 changed files with 300 additions and 201 deletions

View File

@@ -1,2 +1,9 @@
hypre_sp = cmake.subproject('hypre')
hypre_cpp_cmake_options = cmake.subproject_options()
hypre_cpp_cmake_options.add_cmake_defines({
'BUILD_SHARED_LIBS': 'ON',
})
hypre_sp = cmake.subproject(
'hypre',
options: hypre_cpp_cmake_options,
)
hypre_dep = hypre_sp.dependency('HYPRE')

View File

@@ -1,5 +1,10 @@
# Get the subproject object first
opat_sub = subproject('opat-core')
opat_sub = subproject(
'opat-core',
default_options: {
'generate_pc': false
}
)
# Get the dependency variable from that subproject
opatio_dep = opat_sub.get_variable('opatio_dep')

View File

@@ -2,21 +2,22 @@
py_installation = import('python').find_installation('python3')
py_mod = py_installation.extension_module(
'fourdsse_bindings', # Name of the generated .so/.pyd file (without extension)
'serif', # Name of the generated .so/.pyd file (without extension)
sources: [
meson.project_source_root() + '/src/python/bindings.cpp',
meson.project_source_root() + '/src/python/composition/bindings.cpp',
meson.project_source_root() + '/src/python/const/bindings.cpp',
meson.project_source_root() + '/src/python/config/bindings.cpp',
meson.project_source_root() + '/src/python/eos/bindings.cpp',
],
dependencies : [
pybind11_dep,
const_dep,
config_dep,
composition_dep,
eos_dep,
species_weight_dep
],
cpp_args : ['-UNDEBUG'], # Example: Ensure assertions are enabled if needed
install : true,
subdir: 'fourdstar' # Optional: Install the module inside a 'fourdsse' Python package directory
)

View File

@@ -7,8 +7,8 @@ requires = [
build-backend = "mesonpy"
[project]
name = "fourdstar" # Choose your Python package name
version = "0.1.0" # Your project's version
name = "serif" # Choose your Python package name
version = "0.0.1a" # Your project's version
description = "Python interface for the 4DSSE C++ project"
readme = "Readme.md"
license = { file = "LICENSE.txt" } # Reference your license file [cite: 2]

View File

@@ -1,12 +1,12 @@
# Define the library
eos_sources = files(
'private/helm.cpp',
'private/eosIO.cpp'
'private/EOSio.cpp'
)
eos_headers = files(
'public/helm.h',
'public/eosIO.h'
'public/EOSio.h'
)
dependencies = [

View File

@@ -19,28 +19,29 @@
//
// *********************************************************************** */
#include <string>
#include <utility>
#include "eosIO.h"
#include "EOSio.h"
#include "helm.h"
#include "debug.h"
#include <string>
namespace serif::eos {
EosIO::EosIO(const std::string filename) : m_filename(filename) {
EOSio::EOSio(const std::string &filename) : m_filename(filename) {
load();
}
std::string EosIO::getFormat() const {
std::string EOSio::getFormat() const {
return m_format;
}
EOSTable& EosIO::getTable() {
EOSTable& EOSio::getTable() {
return m_table;
}
void EosIO::load() {
void EOSio::load() {
// Load the EOS table from the file
// For now, just set the format to HELM
@@ -50,7 +51,7 @@ namespace serif::eos {
}
}
void EosIO::loadHelm() {
void EOSio::loadHelm() {
// Load the HELM table from the file
auto helmTabptr = serif::eos::helmholtz::read_helm_table(m_filename);
m_table = std::move(helmTabptr);

View File

@@ -49,8 +49,11 @@ using namespace std;
// interpolating polynomila function definitions
namespace serif::eos::helmholtz {
double** heap_allocate_contiguous_2D_memory(int rows, int cols) {
auto array = new double*[rows];
double** heap_allocate_contiguous_2D_memory(const int rows, const int cols) {
if (rows <= 0 || cols <= 0) {
throw std::invalid_argument("Rows and columns must be positive integers.");
}
const auto array = new double*[rows];
array[0] = new double[rows * cols];
for (int i = 1; i < rows; i++) {
@@ -64,34 +67,34 @@ namespace serif::eos::helmholtz {
delete[] array[0];
delete[] array;
}
double psi0(double z) { return z*z*z * (z * (-6.0 * z + 15.0) - 10.0) + 1.0; }
double psi0(const double z) { return z*z*z * (z * (-6.0 * z + 15.0) - 10.0) + 1.0; }
double dpsi0(double z) { return z*z * ( z * (-30.0 * z + 60.0) - 30.0); }
double dpsi0(const double z) { return z*z * ( z * (-30.0 * z + 60.0) - 30.0); }
double ddpsi0(double z) { return z * ( z * (-120.0 * z + 180.0) - 60.0); }
double ddpsi0(const double z) { return z * ( z * (-120.0 * z + 180.0) - 60.0); }
double psi1(double z) { return z * ( z*z * ( z * (-3.0*z + 8.0) - 6.0) + 1.0); }
double psi1(const double z) { return z * ( z*z * ( z * (-3.0*z + 8.0) - 6.0) + 1.0); }
double dpsi1(double z) { return z*z * ( z * (-15.0*z + 32.0) - 18.0) +1.0; }
double dpsi1(const double z) { return z*z * ( z * (-15.0*z + 32.0) - 18.0) +1.0; }
double ddpsi1(double z) { return z * (z * (-60.0*z + 96.0) - 36.0); }
double ddpsi1(const double z) { return z * (z * (-60.0*z + 96.0) - 36.0); }
double psi2(double z) { return 0.5 * z*z * ( z* ( z * (-z + 3.0) - 3.0) + 1.0); }
double psi2(const double z) { return 0.5 * z*z * ( z* ( z * (-z + 3.0) - 3.0) + 1.0); }
double dpsi2(double z) { return 0.5 * z * ( z * (z * (-5.0*z + 12.0) - 9.0) + 2.0); }
double dpsi2(const double z) { return 0.5 * z * ( z * (z * (-5.0*z + 12.0) - 9.0) + 2.0); }
double ddpsi2(double z) { return 0.5*(z*( z * (-20.*z + 36.) - 18.) + 2.); }
double ddpsi2(const double z) { return 0.5*(z*( z * (-20.*z + 36.) - 18.) + 2.); }
double xpsi0(double z) { return z * z * (2.0 * z - 3.0) + 1.0; }
double xpsi0(const double z) { return z * z * (2.0 * z - 3.0) + 1.0; }
double xdpsi0(double z) { return z * (6.0*z - 6.0); }
double xdpsi0(const double z) { return z * (6.0*z - 6.0); }
double xpsi1(double z) { return z * ( z * (z - 2.0) + 1.0); }
double xpsi1(const double z) { return z * ( z * (z - 2.0) + 1.0); }
double xdpsi1(double z) { return z * (3.0 * z - 4.0) + 1.0; }
double xdpsi1(const double z) { return z * (3.0 * z - 4.0) + 1.0; }
double h3(std::array<double, 36> fi, double w0t, double w1t, double w0mt, double w1mt,
double w0d, double w1d, double w0md, double w1md) {
double h3(const std::array<double, 36> &fi, const double w0t, const double w1t, const double w0mt, const double w1mt,
const double w0d, const double w1d, const double w0md, const double w1md) {
return fi[0] * w0d * w0t + fi[1] * w0md * w0t
+ fi[2] * w0d * w0mt + fi[3] * w0md * w0mt
+ fi[4] * w0d * w1t + fi[5] * w0md * w1t
@@ -102,9 +105,9 @@ namespace serif::eos::helmholtz {
+ fi[14] * w1d * w1mt + fi[15] * w1md * w1mt;
}
double h5(std::array<double, 36> fi, double w0t, double w1t, double w2t,double w0mt,
double w1mt, double w2mt, double w0d, double w1d, double w2d,
double w0md, double w1md, double w2md) {
double h5(const std::array<double, 36> &fi, const double w0t, const double w1t, const double w2t, const double w0mt,
const double w1mt, const double w2mt, const double w0d, const double w1d, const double w2d,
const double w0md, const double w1md, const double w2md) {
return fi[0] * w0d * w0t + fi[1] * w0md * w0t
+ fi[2] * w0d * w0mt + fi[3] * w0md * w0mt
+ fi[4] * w0d * w1t + fi[5] * w0md * w1t
@@ -126,7 +129,7 @@ namespace serif::eos::helmholtz {
}
// this function reads in the HELM table and stores in the above arrays
std::unique_ptr<HELMTable> read_helm_table(const std::string filename) {
std::unique_ptr<HELMTable> read_helm_table(const std::string &filename) {
serif::config::Config& config = serif::config::Config::getInstance();
auto logFile = config.get<std::string>("EOS:Helm:LogFile", "log");
serif::probe::LogManager& logManager = serif::probe::LogManager::getInstance();
@@ -253,13 +256,13 @@ namespace serif::eos::helmholtz {
const double kergavo = kerg*avo;
const double clight2 = clight * clight;
const double ssol = 5.6704e-5;
constexpr double ssol = 5.6704e-5;
const double asol = 4 * ssol / clight;
const double asoli3 = asol / 3;
const double sioncon = (2.0 * pi * amu * kerg)/(h*h);
const double qe = 4.8032042712e-10;
const double esqu = qe * qe;
const double third = 1./3.;
constexpr double qe = 4.8032042712e-10;
constexpr double esqu = qe * qe;
constexpr double third = 1./3.;
std::array<double, 36> fi;
double T, rho, s, free, abar, zbar, ytot1, ye, ptot;
double prad, srad, erad, etot, stot;
@@ -631,14 +634,14 @@ namespace serif::eos::helmholtz {
// coulomb
const double a1 = -0.898004;
const double b1 = 0.96786;
const double c1 = 0.220703;
const double d1 = -0.86097;
const double e1 = 2.5269;
const double a2 = 0.29561;
const double b2 = 1.9885;
const double c2 = 0.288675;
constexpr double a1 = -0.898004;
constexpr double b1 = 0.96786;
constexpr double c1 = 0.220703;
constexpr double d1 = -0.86097;
constexpr double e1 = 2.5269;
constexpr double a2 = 0.29561;
constexpr double b2 = 1.9885;
constexpr double c2 = 0.288675;
z = 4 * pi * third;
s = z * xni;

View File

@@ -33,7 +33,7 @@ namespace serif::eos {
>;
/**
* @class EosIO
* @class EOSio
* @brief Handles the input/output operations for EOS tables.
*
* The EosIO class is responsible for loading and managing EOS tables from files.
@@ -46,7 +46,7 @@ namespace serif::eos {
* EOSTable& table = eosIO.getTable();
* @endcode
*/
class EosIO {
class EOSio {
private:
std::string m_filename; ///< The filename of the EOS table.
bool m_loaded = false; ///< Flag indicating if the table is loaded.
@@ -67,23 +67,26 @@ namespace serif::eos {
* @brief Constructs an EosIO object with the given filename.
* @param filename The filename of the EOS table.
*/
EosIO(const std::string filename);
explicit EOSio(const std::string &filename);
/**
* @brief Default destructor.
*/
~EosIO() = default;
~EOSio() = default;
/**
* @brief Gets the format of the EOS table.
* @return The format of the EOS table as a string.
*/
std::string getFormat() const;
[[nodiscard]] std::string getFormat() const;
/**
* @brief Gets the EOS table.
* @return A reference to the EOS table.
*/
EOSTable& getTable();
[[nodiscard]] EOSTable& getTable();
[[nodiscard]] std::string getFilename() const { return m_filename; }
};
}
}

View File

@@ -35,8 +35,8 @@
#include "debug.h"
namespace serif::eos::helmholtz {
constexpr int IMAX = 541;
constexpr int JMAX = 201;
static constexpr int IMAX = 541;
static constexpr int JMAX = 201;
/**
* @brief 2D array template alias.
* @tparam T Type of the array elements.
@@ -139,118 +139,6 @@ namespace serif::eos::helmholtz {
heap_deallocate_contiguous_2D_memory(xfdt);
}
// // Delete copy constructor and copy assignment operator to prevent accidental shallow copies
// HELMTable(const HELMTable&) = delete;
// HELMTable& operator=(const HELMTable&) = delete;
// // Move constructor
// HELMTable(HELMTable&& other) noexcept
// : loaded(other.loaded),
// f(other.f), fd(other.fd), ft(other.ft), fdd(other.fdd), ftt(other.ftt), fdt(other.fdt),
// fddt(other.fddt), fdtt(other.fdtt), fddtt(other.fddtt),
// dpdf(other.dpdf), dpdfd(other.dpdfd), dpdft(other.dpdft), dpdfdt(other.dpdfdt),
// ef(other.ef), efd(other.efd), eft(other.eft), efdt(other.efdt),
// xf(other.xf), xfd(other.xfd), xft(other.xft), xfdt(other.xfdt)
// {
// other.f = nullptr;
// other.fd = nullptr;
// other.ft = nullptr;
// other.fdd = nullptr;
// other.ftt = nullptr;
// other.fdt = nullptr;
// other.fddt = nullptr;
// other.fdtt = nullptr;
// other.fddtt = nullptr;
// other.dpdf = nullptr;
// other.dpdfd = nullptr;
// other.dpdft = nullptr;
// other.dpdfdt = nullptr;
// other.ef = nullptr;
// other.efd = nullptr;
// other.eft = nullptr;
// other.efdt = nullptr;
// other.xf = nullptr;
// other.xfd = nullptr;
// other.xft = nullptr;
// other.xfdt = nullptr;
// }
// // Move assignment operator
// HELMTable& operator=(HELMTable&& other) noexcept {
// if (this != &other) {
// // Deallocate current memory
// heap_deallocate_contiguous_2D_memory(f);
// heap_deallocate_contiguous_2D_memory(fd);
// heap_deallocate_contiguous_2D_memory(ft);
// heap_deallocate_contiguous_2D_memory(fdd);
// heap_deallocate_contiguous_2D_memory(ftt);
// heap_deallocate_contiguous_2D_memory(fdt);
// heap_deallocate_contiguous_2D_memory(fddt);
// heap_deallocate_contiguous_2D_memory(fdtt);
// heap_deallocate_contiguous_2D_memory(fddtt);
// heap_deallocate_contiguous_2D_memory(dpdf);
// heap_deallocate_contiguous_2D_memory(dpdfd);
// heap_deallocate_contiguous_2D_memory(dpdft);
// heap_deallocate_contiguous_2D_memory(dpdfdt);
// heap_deallocate_contiguous_2D_memory(ef);
// heap_deallocate_contiguous_2D_memory(efd);
// heap_deallocate_contiguous_2D_memory(eft);
// heap_deallocate_contiguous_2D_memory(efdt);
// heap_deallocate_contiguous_2D_memory(xf);
// heap_deallocate_contiguous_2D_memory(xfd);
// heap_deallocate_contiguous_2D_memory(xft);
// heap_deallocate_contiguous_2D_memory(xfdt);
// // Transfer ownership of resources
// loaded = other.loaded;
// f = other.f;
// fd = other.fd;
// ft = other.ft;
// fdd = other.fdd;
// ftt = other.ftt;
// fdt = other.fdt;
// fddt = other.fddt;
// fdtt = other.fdtt;
// fddtt = other.fddtt;
// dpdf = other.dpdf;
// dpdfd = other.dpdfd;
// dpdft = other.dpdft;
// dpdfdt = other.dpdfdt;
// ef = other.ef;
// efd = other.efd;
// eft = other.eft;
// efdt = other.efdt;
// xf = other.xf;
// xfd = other.xfd;
// xft = other.xft;
// xfdt = other.xfdt;
// // Null out the other object's pointers
// other.f = nullptr;
// other.fd = nullptr;
// other.ft = nullptr;
// other.fdd = nullptr;
// other.ftt = nullptr;
// other.fdt = nullptr;
// other.fddt = nullptr;
// other.fdtt = nullptr;
// other.fddtt = nullptr;
// other.dpdf = nullptr;
// other.dpdfd = nullptr;
// other.dpdft = nullptr;
// other.dpdfdt = nullptr;
// other.ef = nullptr;
// other.efd = nullptr;
// other.eft = nullptr;
// other.efdt = nullptr;
// other.xf = nullptr;
// other.xfd = nullptr;
// other.xft = nullptr;
// other.xfdt = nullptr;
// }
// return *this;
// }
friend std::ostream& operator<<(std::ostream& os, const helmholtz::HELMTable& table) {
if (!table.loaded) {
os << "HELMTable not loaded\n";
@@ -330,20 +218,20 @@ namespace serif::eos::helmholtz {
os << " Electron Chemical Potential: " << std::format("{0:24.16e}",eos.etaele) << "\n";
os << " Electron Number Density: " << std::format("{0:24.16e}",eos.xnefer) << "\n";
os << " Total Pressure: " << std::format("{0:24.16e}",eos.ptot) << "\n";
os << " dPres/dRho: " << std::format("{0:24.16e}",eos.dpresdd) << "\n";
os << " dPres/dT: " << std::format("{0:24.16e}",eos.dpresdt) << "\n";
os << " Gas Pressure: " << std::format("{0:24.16e}",eos.pgas) << "\n";
os << " dPres/dRho: " << std::format("{0:24.16e}",eos.dpresdd) << "\n";
os << " dPres/dT: " << std::format("{0:24.16e}",eos.dpresdt) << "\n";
os << " Gas Pressure: " << std::format("{0:24.16e}",eos.pgas) << "\n";
os << " Radiation Pressure: " << std::format("{0:24.16e}",eos.prad) << "\n";
os << " Total Energy: " << std::format("{0:24.16e}",eos.etot) << "\n";
os << " dEner/dRho: " << std::format("{0:24.16e}",eos.denerdd) << "\n";
os << " dEner/dT: " << std::format("{0:24.16e}",eos.denerdt) << "\n";
os << " dEner/dRho: " << std::format("{0:24.16e}",eos.denerdd) << "\n";
os << " dEner/dT: " << std::format("{0:24.16e}",eos.denerdt) << "\n";
os << " Gas Energy: " << std::format("{0:24.16e}",eos.egas) << "\n";
os << " Radiation Energy: " << std::format("{0:24.16e}",eos.erad) << "\n";
os << " Total Entropy: " << std::format("{0:24.16e}",eos.stot) << "\n";
os << " dEntr/dRho: " << std::format("{0:24.16e}",eos.dentrdd) << "\n";
os << " dEntr/dT: " << std::format("{0:24.16e}",eos.dentrdt) << "\n";
os << " Gas Entropy: " << std::format("{0:24.16e}",eos.sgas) << "\n";
os << " Radiation Entropy: " << std::format("{0:24.16e}",eos.srad);
os << " Radiation Energy: " << std::format("{0:24.16e}",eos.erad) << "\n";
os << " Total Entropy: " << std::format("{0:24.16e}",eos.stot) << "\n";
os << " dEntr/dRho: " << std::format("{0:24.16e}",eos.dentrdd) << "\n";
os << " dEntr/dT: " << std::format("{0:24.16e}",eos.dentrdt) << "\n";
os << " Gas Entropy: " << std::format("{0:24.16e}",eos.sgas) << "\n";
os << " Radiation Entropy: " << std::format("{0:24.16e}",eos.srad);
return os;
}
};
@@ -454,8 +342,8 @@ namespace serif::eos::helmholtz {
* @param w1md Weight 1 for density (minus).
* @return Result of the polynomial.
*/
double h3(double fi[36], double w0t, double w1t, double w0mt, double w1mt,
double w0d, double w1d, double w0md, double w1md);
double h3(const std::array<double, 36> &fi, const double w0t, const double w1t, const double w0mt, const double w1mt,
const double w0d, const double w1d, const double w0md, const double w1md);
/**
* @brief Interpolating polynomial function h5.
@@ -474,16 +362,16 @@ namespace serif::eos::helmholtz {
* @param w2md Weight 2 for density (minus).
* @return Result of the polynomial.
*/
double h5(double fi[36], double w0t, double w1t, double w2t, double w0mt,
double w1mt, double w2mt, double w0d, double w1d, double w2d,
double w0md, double w1md, double w2md);
double h5(const std::array<double, 36> &fi, const double w0t, const double w1t, const double w2t, const double w0mt,
const double w1mt, const double w2mt, const double w0d, const double w1d, const double w2d,
const double w0md, const double w1md, const double w2md);
/**
* @brief Read the Helmholtz EOS table from a file.
* @param filename Path to the file containing the table.
* @return HELMTable structure containing the table data.
*/
std::unique_ptr<HELMTable> read_helm_table(const std::string filename);
std::unique_ptr<HELMTable> read_helm_table(const std::string& filename);
/**
* @brief Calculate the Helmholtz EOS components.

View File

@@ -6,7 +6,7 @@ polyCoeff_headers = files(
'public/polyCoeff.h'
)
libPolyCoeff = static_library('polyCoeff',
libPolyCoeff = shared_library('polyCoeff',
polyCoeff_sources,
include_directories : include_directories('./public'),
cpp_args: ['-fvisibility=default'],

View File

@@ -39,7 +39,7 @@ dependencies = [
types_dep,
]
libPolySolver = static_library('polySolver',
libPolySolver = shared_library('polySolver',
polySolver_sources,
include_directories : include_directories('./public'),
cpp_args: ['-fvisibility=default'],

View File

@@ -34,7 +34,7 @@ dependencies = [
mfemanalysis_dep,
]
libpolyutils = library('polyutils',
libpolyutils = shared_library('polyutils',
polyutils_sources,
include_directories : include_directories('./public'),
cpp_args: ['-fvisibility=default'],

View File

@@ -5,9 +5,10 @@
#include "const/bindings.h"
#include "composition/bindings.h"
#include "config/bindings.h"
#include "eos/bindings.h"
PYBIND11_MODULE(fourdsse_bindings, m) {
m.doc() = "Python bindings for the 4DSSE project";
PYBIND11_MODULE(serif, m) {
m.doc() = "Python bindings for the SERiF project";
auto compMod = m.def_submodule("composition", "Composition-module bindings");
register_comp_bindings(compMod);
@@ -17,4 +18,7 @@ PYBIND11_MODULE(fourdsse_bindings, m) {
auto configMod = m.def_submodule("config", "Configuration-module bindings");
register_config_bindings(configMod);
auto eosMod = m.def_submodule("eos", "EOS-module bindings");
register_eos_bindings(eosMod);
}

162
src/python/eos/bindings.cpp Normal file
View File

@@ -0,0 +1,162 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h> // Needed for vectors, maps, sets, strings
#include <pybind11/stl_bind.h> // Needed for binding std::vector, std::map etc if needed directly
#include <pybind11/numpy.h>
#include <string>
#include "helm.h"
// #include "resourceManager.h"
#include "bindings.h"
#include "EOSio.h"
#include "helm.h"
#include "../../eos/public/EOSio.h"
#include "../../eos/public/helm.h"
namespace serif::eos {
class EOSio;
}
namespace py = pybind11;
void register_eos_bindings(pybind11::module &eos_submodule) {
py::class_<serif::eos::EOSio>(eos_submodule, "EOSio")
.def(py::init<std::string>(), py::arg("filename"))
// .def("load", &EOSio::load)
.def("getFormat", &serif::eos::EOSio::getFormat, "Get the format of the EOS table.")
.def("getTable", [](serif::eos::EOSio &self) -> serif::eos::helmholtz::HELMTable* {
auto& table_variant = self.getTable();
// Use std::get_if to safely access the contents of the variant.
// This returns a pointer to the value if the variant holds that type, otherwise nullptr.
if (auto* ptr_to_unique_ptr = std::get_if<std::unique_ptr<serif::eos::helmholtz::HELMTable>>(&table_variant)) {
return (*ptr_to_unique_ptr).get();
}
return nullptr;
}, py::return_value_policy::reference_internal, // IMPORTANT: Keep this policy!
"Get the EOS table data.")
.def("__repr__", [](const serif::eos::EOSio &eos) {
return "<EOSio(filename='" + eos.getFilename() + "', format='" + eos.getFormat() + "')>";
});
py::class_<serif::eos::EOSTable>(eos_submodule, "EOSTable");
py::class_<serif::eos::helmholtz::HELMTable>(eos_submodule, "HELMTable")
.def_readonly("loaded", &serif::eos::helmholtz::HELMTable::loaded)
.def_readonly("imax", &serif::eos::helmholtz::HELMTable::imax)
.def_readonly("jmax", &serif::eos::helmholtz::HELMTable::jmax)
.def_readonly("t", &serif::eos::helmholtz::HELMTable::t)
.def_readonly("d", &serif::eos::helmholtz::HELMTable::d)
.def("__repr__", [](const serif::eos::helmholtz::HELMTable &table) {
return "<HELMTable(loaded=" + std::to_string(table.loaded) + ", imax=" + std::to_string(table.imax) +
", jmax=" + std::to_string(table.jmax) + ")>";
})
.def_property_readonly("f", [](serif::eos::helmholtz::HELMTable &table) -> py::array_t<double> {
// --- Check Preconditions ---
// 1. Check if dimensions are valid
if (table.imax <= 0 || table.jmax <= 0) {
// Return empty array or throw error for invalid dimensions
throw std::runtime_error("HELMTable dimensions (imax, jmax) are non-positive.");
// Alternatively: return py::array_t<double>();
}
// 2. Check if pointer 'f' and the data block 'f[0]' are non-null
// (Essential check assuming f could be null if not loaded/initialized)
if (!table.f || !table.f[0]) {
throw std::runtime_error("HELMTable data buffer 'f' is null or not initialized.");
// Alternatively: return py::array_t<double>();
}
// --- Get necessary info ---
py::ssize_t rows = static_cast<py::ssize_t>(table.imax);
py::ssize_t cols = static_cast<py::ssize_t>(table.jmax);
double* data_ptr = table.f[0]; // Pointer to the start of contiguous data block
// --- Define NumPy array shape and strides ---
std::vector<py::ssize_t> shape = {rows, cols};
std::vector<py::ssize_t> strides = {
static_cast<py::ssize_t>(cols * sizeof(double)), // Stride to next row
static_cast<py::ssize_t>( sizeof(double)) // Stride to next element in row
};
// --- Create and return the py::array_t ---
// py::cast(table) creates a py::object that acts as the 'base'.
// This tells NumPy not to manage the memory of 'data_ptr' and
// ensures the 'table' object stays alive as long as the NumPy array view exists.
return py::array_t<double>(
shape, // The dimensions of the array
strides, // How many bytes to step in each dimension
data_ptr, // Pointer to the actual data
py::cast(table) // Owner object (keeps C++ object alive)
);
}, py::return_value_policy::reference_internal); // Keep parent 'table' alive
py::class_<serif::eos::helmholtz::EOS>(eos_submodule, "EOS")
.def(py::init<>())
.def_readonly("ye", &serif::eos::helmholtz::EOS::ye)
.def_readonly("etaele", &serif::eos::helmholtz::EOS::etaele)
.def_readonly("xnefer", &serif::eos::helmholtz::EOS::xnefer)
.def_readonly("ptot", &serif::eos::helmholtz::EOS::ptot)
.def_readonly("pgas", &serif::eos::helmholtz::EOS::pgas)
.def_readonly("prad", &serif::eos::helmholtz::EOS::prad)
.def_readonly("etot", &serif::eos::helmholtz::EOS::etot)
.def_readonly("egas", &serif::eos::helmholtz::EOS::egas)
.def_readonly("erad", &serif::eos::helmholtz::EOS::erad)
.def_readonly("stot", &serif::eos::helmholtz::EOS::stot)
.def_readonly("sgas", &serif::eos::helmholtz::EOS::sgas)
.def_readonly("srad", &serif::eos::helmholtz::EOS::srad)
.def_readonly("dpresdd", &serif::eos::helmholtz::EOS::dpresdd)
.def_readonly("dpresdt", &serif::eos::helmholtz::EOS::dpresdt)
.def_readonly("dpresda", &serif::eos::helmholtz::EOS::dpresda)
.def_readonly("dpresdz", &serif::eos::helmholtz::EOS::dpresdz)
// TODO: Finish adding all the derivatives to the bound class
.def_readonly("dentrdd", &serif::eos::helmholtz::EOS::dentrdd)
.def_readonly("dentrdt", &serif::eos::helmholtz::EOS::dentrdt)
.def_readonly("dentrda", &serif::eos::helmholtz::EOS::dentrda)
.def_readonly("dentrdz", &serif::eos::helmholtz::EOS::dentrdz)
.def_readonly("denerdd", &serif::eos::helmholtz::EOS::denerdd)
.def_readonly("denerdt", &serif::eos::helmholtz::EOS::denerdt)
.def_readonly("denerda", &serif::eos::helmholtz::EOS::denerda)
.def_readonly("denerdz", &serif::eos::helmholtz::EOS::denerdz)
.def_readonly("chiT", &serif::eos::helmholtz::EOS::chiT)
.def_readonly("chiRho", &serif::eos::helmholtz::EOS::chiRho)
.def_readonly("csound", &serif::eos::helmholtz::EOS::csound)
.def_readonly("grad_ad", &serif::eos::helmholtz::EOS::grad_ad)
.def_readonly("gamma1", &serif::eos::helmholtz::EOS::gamma1)
.def_readonly("gamma2", &serif::eos::helmholtz::EOS::gamma2)
.def_readonly("gamma3", &serif::eos::helmholtz::EOS::gamma3)
.def_readonly("cV", &serif::eos::helmholtz::EOS::cV)
.def_readonly("cP", &serif::eos::helmholtz::EOS::cP)
.def_readonly("dse", &serif::eos::helmholtz::EOS::dse)
.def_readonly("dpe", &serif::eos::helmholtz::EOS::dpe)
.def_readonly("dsp", &serif::eos::helmholtz::EOS::dsp)
.def("__repr__", [](const serif::eos::helmholtz::EOS &eos) {
return "<EOS (output from helmholtz eos)>";
});
py::class_<serif::eos::helmholtz::EOSInput>(eos_submodule, "EOSInput")
.def(py::init<>())
.def_readwrite("T", &serif::eos::helmholtz::EOSInput::T)
.def_readwrite("rho", &serif::eos::helmholtz::EOSInput::rho)
.def_readwrite("abar", &serif::eos::helmholtz::EOSInput::abar)
.def_readwrite("zbar", &serif::eos::helmholtz::EOSInput::zbar)
.def("__repr__", [](const serif::eos::helmholtz::EOSInput &input) {
return "<EOSInput(T=" + std::to_string(input.T) +
", rho=" + std::to_string(input.rho) +
", abar=" + std::to_string(input.abar) +
", zbar=" + std::to_string(input.zbar) + ")>";
});
eos_submodule.def("get_helm_eos",
&serif::eos::helmholtz::get_helm_EOS,
py::arg("q"), py::arg("table"),
"Calculate the Helmholtz EOS components based on input parameters and table data.");
}

View File

@@ -0,0 +1,5 @@
#pragma once
#include <pybind11/pybind11.h>
void register_eos_bindings(pybind11::module &eos_submodule);

View File

@@ -0,0 +1,19 @@
# Define the library
bindings_sources = files('bindings.cpp')
bindings_headers = files('bindings.h')
dependencies = [
eos_dep,
config_dep,
resourceManager_dep,
python3_dep,
pybind11_dep,
]
shared_module('py_eos',
bindings_sources,
include_directories: include_directories('.'),
cpp_args: ['-fvisibility=default'],
install : true,
dependencies: dependencies,
)

View File

@@ -1,3 +1,4 @@
subdir('composition')
subdir('const')
subdir('config')
subdir('config')
subdir('eos')

View File

@@ -23,7 +23,7 @@
#include "resourceManagerTypes.h"
#include "opatIO.h"
#include "meshIO.h"
#include "eosIO.h"
#include "EOSio.h"
#include "debug.h"
@@ -49,7 +49,7 @@ namespace serif::resource::types {
std::make_unique<serif::mesh::MeshIO>(p));
}},
{"eos", [](const std::string& p) { return Resource(
std::make_unique<serif::eos::EosIO>(p));
std::make_unique<serif::eos::EOSio>(p));
}}
// Add more mappings as needed
};

View File

@@ -25,7 +25,7 @@
#include "opatIO.h"
#include "helm.h"
#include "meshIO.h"
#include "eosIO.h"
#include "EOSio.h"
namespace serif::resource::types {
/**
@@ -41,7 +41,7 @@ namespace serif::resource::types {
* @brief A variant type that can hold different types of resources.
*
* The Resource type is a std::variant that can hold a unique pointer to
* an OpatIO, MeshIO, or EosIO object.
* an OpatIO, MeshIO, or EOSio object.
*
* Example usage:
* @code
@@ -51,7 +51,7 @@ namespace serif::resource::types {
using Resource = std::variant<
std::unique_ptr<opat::OPAT>,
std::unique_ptr<serif::mesh::MeshIO>,
std::unique_ptr<serif::eos::EosIO>>;
std::unique_ptr<serif::eos::EOSio>>;
/**
* @brief Extracts the first segment of a given string.

View File

@@ -1,4 +1,4 @@
[wrap-git]
url = https://github.com/4D-STAR/opat-core
revision = 0.3.1a
revision = 0.3.3a
depth = 1

View File

@@ -27,7 +27,7 @@ std::string TEST_CONFIG = std::string(getenv("MESON_SOURCE_ROOT")) + "/tests/tes
TEST_F(eosTest, read_helm_table) {
serif::config::Config::getInstance().loadConfig(TEST_CONFIG);
serif::resource::ResourceManager& rm = serif::resource::ResourceManager::getInstance();
auto& eos = std::get<std::unique_ptr<serif::eos::EosIO>>(rm.getResource("eos:helm"));
auto& eos = std::get<std::unique_ptr<serif::eos::EOSio>>(rm.getResource("eos:helm"));
auto& table = eos->getTable();
auto& helmTable = *std::get<std::unique_ptr<serif::eos::helmholtz::HELMTable>>(table);
std::stringstream ss;
@@ -58,7 +58,7 @@ TEST_F(eosTest, get_helm_EOS) {
eos1.zbar = eos1.abar*zsum;
serif::resource::ResourceManager& rm = serif::resource::ResourceManager::getInstance();
auto& eos = std::get<std::unique_ptr<serif::eos::EosIO>>(rm.getResource("eos:helm"));
auto& eos = std::get<std::unique_ptr<serif::eos::EOSio>>(rm.getResource("eos:helm"));
auto& table = eos->getTable();
auto& helmTable = *std::get<std::unique_ptr<serif::eos::helmholtz::HELMTable>>(table);
serif::eos::helmholtz::EOS helmEos = get_helm_EOS(eos1, helmTable);

View File

@@ -1,6 +1,6 @@
#include <gtest/gtest.h>
#include "config.h"
#include "eosIO.h"
#include "EOSio.h"
#include "helm.h"
#include "resourceManager.h"
#include "resourceManagerTypes.h"
@@ -47,7 +47,7 @@ TEST_F(resourceManagerTest, getResource) {
std::string name = "eos:helm";
const serif::resource::types::Resource &r = rm.getResource(name);
// BREAKPOINT();
const auto &eos = std::get<std::unique_ptr<serif::eos::EosIO>>(r);
const auto &eos = std::get<std::unique_ptr<serif::eos::EOSio>>(r);
EXPECT_EQ("helm", eos->getFormat());
serif::eos::EOSTable &table = eos->getTable();