Merge pull request #45 from tboudreaux/feature/pythonInterface/composition
Python Interface for composition module
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -64,6 +64,8 @@ subprojects/yaml-cpp/
|
|||||||
subprojects/quill/
|
subprojects/quill/
|
||||||
subprojects/googletest-1.15.2/
|
subprojects/googletest-1.15.2/
|
||||||
subprojects/opat-core/
|
subprojects/opat-core/
|
||||||
|
subprojects/pybind11*/
|
||||||
|
subprojects/packagecache/
|
||||||
|
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef SPECIES_MASS_DATA_H
|
#pragma once
|
||||||
#define SPECIES_MASS_DATA_H
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -7205,4 +7204,3 @@ namespace chemSpecies {
|
|||||||
{"Og-295", Og_295},
|
{"Og-295", Og_295},
|
||||||
};
|
};
|
||||||
}; // namespace chemSpecies
|
}; // namespace chemSpecies
|
||||||
#endif // SPECIES_MASS_DATA_H
|
|
||||||
|
|||||||
@@ -5,3 +5,17 @@ subdir('yaml-cpp')
|
|||||||
subdir('quill')
|
subdir('quill')
|
||||||
subdir('boost')
|
subdir('boost')
|
||||||
subdir('opatIO')
|
subdir('opatIO')
|
||||||
|
subdir('pybind')
|
||||||
|
|
||||||
|
# Set the config file error handling options
|
||||||
|
configErr = get_option('config_error_handling')
|
||||||
|
|
||||||
|
# build up any -D flags we need
|
||||||
|
commonCppArgs = []
|
||||||
|
if configErr == 'warn'
|
||||||
|
commonCppArgs += ['-DCONFIG_WARN']
|
||||||
|
elif configErr == 'harsh'
|
||||||
|
commonCppArgs += ['-DCONFIG_HARSH']
|
||||||
|
endif
|
||||||
|
|
||||||
|
add_project_arguments(commonCppArgs, language: 'cpp')
|
||||||
@@ -4,10 +4,11 @@ mfem_cmake_options.add_cmake_defines({
|
|||||||
'MFEM_ENABLE_TESTING': 'OFF',
|
'MFEM_ENABLE_TESTING': 'OFF',
|
||||||
'MFEM_ENABLE_MINIAPPS': 'OFF',
|
'MFEM_ENABLE_MINIAPPS': 'OFF',
|
||||||
'MFEM_USE_BENCMARK': 'OFF',
|
'MFEM_USE_BENCMARK': 'OFF',
|
||||||
|
'BUILD_SHARED_LIBS': 'ON',
|
||||||
|
'CMAKE_SKIP_INSTALL_RULES': 'ON'
|
||||||
})
|
})
|
||||||
|
|
||||||
mfem_sp = cmake.subproject(
|
mfem_sp = cmake.subproject(
|
||||||
'mfem',
|
'mfem',
|
||||||
options: mfem_cmake_options)
|
options: mfem_cmake_options)
|
||||||
mfem_dep = mfem_sp.dependency('mfem')
|
mfem_dep = mfem_sp.dependency('mfem')
|
||||||
add_project_arguments('-I' + meson.current_build_dir() + '/subprojects/mfem/__CMake_build/config', language: 'cpp')
|
|
||||||
|
|||||||
5
build-config/pybind/meson.build
Normal file
5
build-config/pybind/meson.build
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
if get_option('build_python')
|
||||||
|
pybind11_proj = subproject('pybind11')
|
||||||
|
pybind11_dep = pybind11_proj.get_variable('pybind11_dep')
|
||||||
|
python3_dep = dependency('python3')
|
||||||
|
endif
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
|
quill_cmake_options = cmake.subproject_options()
|
||||||
|
quill_cmake_options.add_cmake_defines({
|
||||||
|
'BUILD_SHARED_LIBS': 'ON',
|
||||||
|
'CMAKE_SKIP_INSTALL_RULES': 'ON'
|
||||||
|
})
|
||||||
quill_sp = cmake.subproject(
|
quill_sp = cmake.subproject(
|
||||||
'quill'
|
'quill',
|
||||||
|
options: quill_cmake_options,
|
||||||
)
|
)
|
||||||
quill_dep = quill_sp.dependency('quill')
|
quill_dep = quill_sp.dependency('quill')
|
||||||
add_project_arguments('-I' + meson.current_build_dir() + '/subprojects/quill/__CMake_build', language: 'cpp')
|
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
yaml_cpp_cmake_options = cmake.subproject_options()
|
yaml_cpp_cmake_options = cmake.subproject_options()
|
||||||
yaml_cpp_cmake_options.add_cmake_defines({
|
yaml_cpp_cmake_options.add_cmake_defines({
|
||||||
'CMAKE_POLICY_VERSION_MINIMUM': '3.5'
|
'CMAKE_POLICY_VERSION_MINIMUM': '3.5',
|
||||||
|
'BUILD_SHARED_LIBS': 'ON',
|
||||||
|
'CMAKE_SKIP_INSTALL_RULES': 'ON'
|
||||||
})
|
})
|
||||||
yaml_cpp_sp = cmake.subproject(
|
yaml_cpp_sp = cmake.subproject(
|
||||||
'yaml-cpp',
|
'yaml-cpp',
|
||||||
options: yaml_cpp_cmake_options,
|
options: yaml_cpp_cmake_options,
|
||||||
)
|
)
|
||||||
yaml_cpp_dep = yaml_cpp_sp.dependency('yaml-cpp')
|
yaml_cpp_dep = yaml_cpp_sp.dependency('yaml-cpp')
|
||||||
add_project_arguments('-I' + meson.current_build_dir() + '/subprojects/yaml-cpp/__CMake_build', language: 'cpp')
|
|
||||||
17
build-python/meson.build
Normal file
17
build-python/meson.build
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# --- Python Extension Setup ---
|
||||||
|
py_installation = import('python').find_installation('python3')
|
||||||
|
|
||||||
|
py_mod = py_installation.extension_module(
|
||||||
|
'fourdsse_bindings', # Name of the generated .so/.pyd file (without extension)
|
||||||
|
sources: [
|
||||||
|
meson.project_source_root() + '/src/python/composition/bindings.cpp',
|
||||||
|
],
|
||||||
|
dependencies : [
|
||||||
|
pybind11_dep,
|
||||||
|
composition_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
|
||||||
|
)
|
||||||
@@ -28,3 +28,7 @@ subdir('src')
|
|||||||
if get_option('build_tests')
|
if get_option('build_tests')
|
||||||
subdir('tests')
|
subdir('tests')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if get_option('build_python')
|
||||||
|
subdir('build-python')
|
||||||
|
endif
|
||||||
@@ -1,2 +1,10 @@
|
|||||||
option('build_tests', type: 'boolean', value: true, description: 'Build tests')
|
option('build_tests', type: 'boolean', value: true, description: 'Build tests')
|
||||||
option('user_mode', type: 'boolean', value: false, description: 'Enable user mode (set mode = 0)')
|
option('user_mode', type: 'boolean', value: false, description: 'Enable user mode (set mode = 0)')
|
||||||
|
option('build_python', type: 'boolean', value: true, description: 'Build Python bindings')
|
||||||
|
option(
|
||||||
|
'config_error_handling',
|
||||||
|
type: 'combo',
|
||||||
|
choices: [ 'none', 'warn', 'harsh' ],
|
||||||
|
value: 'none',
|
||||||
|
description: 'What to do if a config file fails to load: silent (none), warning (warn), or error (harsh)'
|
||||||
|
)
|
||||||
|
|||||||
21
pyproject.toml
Normal file
21
pyproject.toml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = [
|
||||||
|
"meson-python>=0.15.0", # Use a recent version
|
||||||
|
"meson>=1.6.0", # Specify your Meson version requirement
|
||||||
|
"pybind11>=2.10" # pybind11 headers needed at build time
|
||||||
|
]
|
||||||
|
build-backend = "mesonpy"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "fourdstar" # Choose your Python package name
|
||||||
|
version = "0.1.0" # 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]
|
||||||
|
|
||||||
|
authors = [
|
||||||
|
{name = "Emily M. Boudreaux", email = "emily@boudreauxmail.com"},
|
||||||
|
]
|
||||||
|
maintainers = [
|
||||||
|
{name = "Emily M. Boudreaux", email = "emily@boudreauxmail.com"}
|
||||||
|
]
|
||||||
@@ -9,13 +9,12 @@ composition_headers = files(
|
|||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
probe_dep,
|
probe_dep,
|
||||||
config_dep,
|
|
||||||
quill_dep,
|
quill_dep,
|
||||||
species_weight_dep
|
species_weight_dep
|
||||||
]
|
]
|
||||||
|
|
||||||
# Define the libcomposition library so it can be linked against by other parts of the build system
|
# Define the libcomposition library so it can be linked against by other parts of the build system
|
||||||
libcomposition = static_library('composition',
|
libcomposition = library('composition',
|
||||||
composition_sources,
|
composition_sources,
|
||||||
include_directories: include_directories('public'),
|
include_directories: include_directories('public'),
|
||||||
cpp_args: ['-fvisibility=default'],
|
cpp_args: ['-fvisibility=default'],
|
||||||
|
|||||||
@@ -190,7 +190,6 @@ namespace composition{
|
|||||||
*/
|
*/
|
||||||
class Composition {
|
class Composition {
|
||||||
private:
|
private:
|
||||||
Config& m_config = Config::getInstance();
|
|
||||||
Probe::LogManager& m_logManager = Probe::LogManager::getInstance();
|
Probe::LogManager& m_logManager = Probe::LogManager::getInstance();
|
||||||
quill::Logger* m_logger = m_logManager.getLogger("log");
|
quill::Logger* m_logger = m_logManager.getLogger("log");
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ config_headers = files(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Define the libconfig library so it can be linked against by other parts of the build system
|
# Define the libconfig library so it can be linked against by other parts of the build system
|
||||||
libconfig = static_library('config',
|
libconfig = library('config',
|
||||||
config_sources,
|
config_sources,
|
||||||
include_directories: include_directories('public'),
|
include_directories: include_directories('public'),
|
||||||
cpp_args: ['-fvisibility=default'],
|
cpp_args: ['-fvisibility=default'],
|
||||||
|
|||||||
@@ -156,7 +156,12 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
T get(const std::string &key, T defaultValue) {
|
T get(const std::string &key, T defaultValue) {
|
||||||
if (!m_loaded) {
|
if (!m_loaded) {
|
||||||
throw std::runtime_error("Error! Config file not loaded");
|
// ONLY THROW ERROR IF HARSH OR WARN CONFIGURATION
|
||||||
|
#if defined(CONFIG_HARSH)
|
||||||
|
throw std::runtime_error("Error! Config file not loaded. To disable this error, recompile with CONFIG_HARSH=0");
|
||||||
|
#elif defined(CONFIG_WARN)
|
||||||
|
std::cerr << "Warning! Config file not loaded. This instance of 4DSSE was compiled with CONFIG_WARN so the code will continue using only default values" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
// --- Check if the key has already been checked for existence
|
// --- Check if the key has already been checked for existence
|
||||||
if (std::find(unknownKeys.begin(), unknownKeys.end(), key) != unknownKeys.end()) {
|
if (std::find(unknownKeys.begin(), unknownKeys.end(), key) != unknownKeys.end()) {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ dependencies = [
|
|||||||
macros_dep,
|
macros_dep,
|
||||||
]
|
]
|
||||||
# Define the libconst library so it can be linked against by other parts of the build system
|
# Define the libconst library so it can be linked against by other parts of the build system
|
||||||
libeos = static_library('eos',
|
libeos = library('eos',
|
||||||
eos_sources,
|
eos_sources,
|
||||||
include_directories: include_directories('public'),
|
include_directories: include_directories('public'),
|
||||||
cpp_args: ['-fvisibility=default'],
|
cpp_args: ['-fvisibility=default'],
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ dependencies = [
|
|||||||
mfem_dep
|
mfem_dep
|
||||||
]
|
]
|
||||||
# Define the libmeshIO library so it can be linked against by other parts of the build system
|
# Define the libmeshIO library so it can be linked against by other parts of the build system
|
||||||
libmeshIO = static_library('meshIO',
|
libmeshIO = library('meshIO',
|
||||||
meshIO_sources,
|
meshIO_sources,
|
||||||
include_directories: include_directories('public'),
|
include_directories: include_directories('public'),
|
||||||
cpp_args: ['-fvisibility=default'],
|
cpp_args: ['-fvisibility=default'],
|
||||||
|
|||||||
@@ -23,3 +23,6 @@ subdir('resource')
|
|||||||
# Physics Libraries
|
# Physics Libraries
|
||||||
subdir('network')
|
subdir('network')
|
||||||
subdir('poly')
|
subdir('poly')
|
||||||
|
|
||||||
|
# Python Bindings
|
||||||
|
subdir('python')
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Define the libnetwork library so it can be linked against by other parts of the build system
|
# Define the libnetwork library so it can be linked against by other parts of the build system
|
||||||
libnetwork = static_library('network',
|
libnetwork = library('network',
|
||||||
network_sources,
|
network_sources,
|
||||||
include_directories: include_directories('public'),
|
include_directories: include_directories('public'),
|
||||||
dependencies: dependencies,
|
dependencies: dependencies,
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ dependencies = [
|
|||||||
types_dep,
|
types_dep,
|
||||||
]
|
]
|
||||||
|
|
||||||
libpolyutils = static_library('polyutils',
|
libpolyutils = library('polyutils',
|
||||||
polyutils_sources,
|
polyutils_sources,
|
||||||
include_directories : include_directories('./public'),
|
include_directories : include_directories('./public'),
|
||||||
cpp_args: ['-fvisibility=default'],
|
cpp_args: ['-fvisibility=default'],
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Define the liblogger library so it can be linked against by other parts of the build system
|
# Define the liblogger library so it can be linked against by other parts of the build system
|
||||||
libprobe = static_library('probe',
|
libprobe = library('probe',
|
||||||
probe_sources,
|
probe_sources,
|
||||||
include_directories: include_directories('public'),
|
include_directories: include_directories('public'),
|
||||||
cpp_args: ['-fvisibility=default'],
|
cpp_args: ['-fvisibility=default'],
|
||||||
|
|||||||
162
src/python/composition/bindings.cpp
Normal file
162
src/python/composition/bindings.cpp
Normal 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 <string>
|
||||||
|
|
||||||
|
#include "composition.h"
|
||||||
|
#include "atomicSpecies.h"
|
||||||
|
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
std::string sv_to_string(std::string_view sv) {
|
||||||
|
return std::string(sv);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_ostream_str(const composition::Composition& comp) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << comp;
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
PYBIND11_MODULE(fourdsse_bindings, m) { // Module name must match meson.build
|
||||||
|
m.doc() = "Python bindings for the 4DSSE project"; // Optional module docstring
|
||||||
|
|
||||||
|
auto comp_submodule = m.def_submodule("composition", "Bindings for the Composition module");
|
||||||
|
auto chem_submodule = m.def_submodule("species", "Bindings for the Chemical Species module");
|
||||||
|
|
||||||
|
// --- Bindings for composition and species module ---
|
||||||
|
py::class_<composition::GlobalComposition>(comp_submodule, "GlobalComposition")
|
||||||
|
.def_readonly("specificNumberDensity", &composition::GlobalComposition::specificNumberDensity)
|
||||||
|
.def_readonly("meanParticleMass", &composition::GlobalComposition::meanParticleMass)
|
||||||
|
.def("__repr__", // Add a string representation for easy printing in Python
|
||||||
|
[](const composition::GlobalComposition &gc) {
|
||||||
|
return "<GlobalComposition(specNumDens=" + std::to_string(gc.specificNumberDensity) +
|
||||||
|
", meanMass=" + std::to_string(gc.meanParticleMass) + ")>";
|
||||||
|
});
|
||||||
|
|
||||||
|
py::class_<composition::CompositionEntry>(comp_submodule, "CompositionEntry")
|
||||||
|
.def("symbol", &composition::CompositionEntry::symbol)
|
||||||
|
.def("mass_fraction",
|
||||||
|
py::overload_cast<>(&composition::CompositionEntry::mass_fraction, py::const_),
|
||||||
|
"Gets the mass fraction of the species.")
|
||||||
|
.def("mass_fraction",
|
||||||
|
py::overload_cast<double>(&composition::CompositionEntry::mass_fraction, py::const_),
|
||||||
|
py::arg("meanMolarMass"), // Name the argument in Python
|
||||||
|
"Gets the mass fraction of the species given the mean molar mass.")
|
||||||
|
.def("number_fraction",
|
||||||
|
py::overload_cast<>(&composition::CompositionEntry::number_fraction, py::const_),
|
||||||
|
"Gets the number fraction of the species.")
|
||||||
|
.def("number_fraction",
|
||||||
|
py::overload_cast<double>(&composition::CompositionEntry::number_fraction, py::const_),
|
||||||
|
py::arg("totalMoles"),
|
||||||
|
"Gets the number fraction of the species given the total moles.")
|
||||||
|
|
||||||
|
.def("rel_abundance", &composition::CompositionEntry::rel_abundance)
|
||||||
|
.def("isotope", &composition::CompositionEntry::isotope) // Assuming Species is bound or convertible
|
||||||
|
.def("getMassFracMode", &composition::CompositionEntry::getMassFracMode)
|
||||||
|
|
||||||
|
.def("__repr__", // Optional: nice string representation
|
||||||
|
[](const composition::CompositionEntry &ce) {
|
||||||
|
// You might want to include more info here now
|
||||||
|
return "<CompositionEntry(symbol='" + ce.symbol() + "', " +
|
||||||
|
"mass_frac=" + std::to_string(ce.mass_fraction()) + ", " +
|
||||||
|
"num_frac=" + std::to_string(ce.number_fraction()) + ")>";
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- Binding for the main Composition class ---
|
||||||
|
py::class_<composition::Composition>(comp_submodule, "Composition")
|
||||||
|
// Constructors
|
||||||
|
.def(py::init<>(), "Default constructor")
|
||||||
|
.def(py::init<const std::vector<std::string>&>(),
|
||||||
|
py::arg("symbols"),
|
||||||
|
"Constructor taking a list of symbols to register (defaults to mass fraction mode)")
|
||||||
|
// .def(py::init<const std::set<std::string>&>(), py::arg("symbols")) // Binding std::set constructor is possible but often less convenient from Python
|
||||||
|
.def(py::init<const std::vector<std::string>&, const std::vector<double>&, bool>(),
|
||||||
|
py::arg("symbols"), py::arg("fractions"), py::arg("massFracMode") = true,
|
||||||
|
"Constructor taking symbols, fractions, and mode (True=Mass, False=Number)")
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
.def("finalize", &composition::Composition::finalize, py::arg("norm") = false,
|
||||||
|
"Finalize the composition, optionally normalizing fractions to sum to 1.")
|
||||||
|
|
||||||
|
.def("registerSymbol", py::overload_cast<const std::string&, bool>(&composition::Composition::registerSymbol),
|
||||||
|
py::arg("symbol"), py::arg("massFracMode") = true, "Register a single symbol.")
|
||||||
|
.def("registerSymbol", py::overload_cast<const std::vector<std::string>&, bool>(&composition::Composition::registerSymbol),
|
||||||
|
py::arg("symbols"), py::arg("massFracMode") = true, "Register multiple symbols.")
|
||||||
|
|
||||||
|
.def("getRegisteredSymbols", &composition::Composition::getRegisteredSymbols,
|
||||||
|
"Get the set of registered symbols.")
|
||||||
|
|
||||||
|
.def("setMassFraction", py::overload_cast<const std::string&, const double&>(&composition::Composition::setMassFraction),
|
||||||
|
py::arg("symbol"), py::arg("mass_fraction"), "Set mass fraction for a single symbol (requires massFracMode). Returns old value.")
|
||||||
|
.def("setMassFraction", py::overload_cast<const std::vector<std::string>&, const std::vector<double>&>(&composition::Composition::setMassFraction),
|
||||||
|
py::arg("symbols"), py::arg("mass_fractions"), "Set mass fractions for multiple symbols (requires massFracMode). Returns list of old values.")
|
||||||
|
|
||||||
|
.def("setNumberFraction", py::overload_cast<const std::string&, const double&>(&composition::Composition::setNumberFraction),
|
||||||
|
py::arg("symbol"), py::arg("number_fraction"), "Set number fraction for a single symbol (requires !massFracMode). Returns old value.")
|
||||||
|
.def("setNumberFraction", py::overload_cast<const std::vector<std::string>&, const std::vector<double>&>(&composition::Composition::setNumberFraction),
|
||||||
|
py::arg("symbols"), py::arg("number_fractions"), "Set number fractions for multiple symbols (requires !massFracMode). Returns list of old values.")
|
||||||
|
|
||||||
|
.def("mix", &composition::Composition::mix, py::arg("other"), py::arg("fraction"),
|
||||||
|
"Mix with another composition. Returns new Composition.")
|
||||||
|
|
||||||
|
.def("getMassFraction", py::overload_cast<const std::string&>(&composition::Composition::getMassFraction, py::const_),
|
||||||
|
py::arg("symbol"), "Get mass fraction for a symbol (calculates if needed). Requires finalization.")
|
||||||
|
.def("getMassFraction", py::overload_cast<>(&composition::Composition::getMassFraction, py::const_),
|
||||||
|
"Get dictionary of all mass fractions. Requires finalization.")
|
||||||
|
|
||||||
|
.def("getNumberFraction", py::overload_cast<const std::string&>(&composition::Composition::getNumberFraction, py::const_),
|
||||||
|
py::arg("symbol"), "Get number fraction for a symbol (calculates if needed). Requires finalization.")
|
||||||
|
.def("getNumberFraction", py::overload_cast<>(&composition::Composition::getNumberFraction, py::const_),
|
||||||
|
"Get dictionary of all number fractions. Requires finalization.")
|
||||||
|
|
||||||
|
// Note: pybind11 automatically converts std::pair to a Python tuple
|
||||||
|
.def("getComposition", py::overload_cast<const std::string&>(&composition::Composition::getComposition, py::const_),
|
||||||
|
py::arg("symbol"), "Returns a tuple (CompositionEntry, GlobalComposition) for the symbol. Requires finalization.")
|
||||||
|
// Binding the version returning map<string, Entry> requires a bit more care or helper function
|
||||||
|
// to convert the map to a Python dict if needed directly. Let's bind the pair version for now.
|
||||||
|
.def("getComposition", py::overload_cast<>(&composition::Composition::getComposition, py::const_),
|
||||||
|
"Returns a tuple (dict[str, CompositionEntry], GlobalComposition) for all symbols. Requires finalization.")
|
||||||
|
|
||||||
|
|
||||||
|
.def("subset", &composition::Composition::subset, py::arg("symbols"), py::arg("method") = "norm",
|
||||||
|
"Create a new Composition containing only the specified symbols.")
|
||||||
|
.def("hasSymbol", &composition::Composition::hasSymbol, py::arg("symbol"),
|
||||||
|
"Check if a symbol is registered.")
|
||||||
|
.def("setCompositionMode", &composition::Composition::setCompositionMode, py::arg("massFracMode"),
|
||||||
|
"Set the mode (True=Mass, False=Number). Requires finalization before switching.")
|
||||||
|
|
||||||
|
// Operator overload
|
||||||
|
.def(py::self + py::self, "Mix equally with another composition.") // Binds operator+
|
||||||
|
|
||||||
|
// Add __repr__ or __str__
|
||||||
|
.def("__repr__", [](const composition::Composition &comp) {
|
||||||
|
return get_ostream_str(comp); // Use helper for C++ operator<<
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- Bindings for species module ---
|
||||||
|
py::class_<chemSpecies::Species>(chem_submodule, "Species")
|
||||||
|
.def("mass", &chemSpecies::Species::mass, "Get atomic mass (amu)")
|
||||||
|
.def("massUnc", &chemSpecies::Species::massUnc, "Get atomic mass uncertainty (amu)")
|
||||||
|
.def("bindingEnergy", &chemSpecies::Species::bindingEnergy, "Get binding energy (keV/nucleon?)") // Check units
|
||||||
|
.def("betaDecayEnergy", &chemSpecies::Species::betaDecayEnergy, "Get beta decay energy (keV?)") // Check units
|
||||||
|
.def("betaCode", [](const chemSpecies::Species& s){ return sv_to_string(s.betaCode()); }, "Get beta decay code") // Convert string_view
|
||||||
|
.def("name", [](const chemSpecies::Species& s){ return sv_to_string(s.name()); }, "Get species name (e.g., 'H-1')") // Convert string_view
|
||||||
|
.def("el", [](const chemSpecies::Species& s){ return sv_to_string(s.el()); }, "Get element symbol (e.g., 'H')") // Convert string_view
|
||||||
|
.def("nz", &chemSpecies::Species::nz, "Get NZ value")
|
||||||
|
.def("n", &chemSpecies::Species::n, "Get neutron number N")
|
||||||
|
.def("z", &chemSpecies::Species::z, "Get proton number Z")
|
||||||
|
.def("a", &chemSpecies::Species::a, "Get mass number A")
|
||||||
|
|
||||||
|
.def("__repr__",
|
||||||
|
[](const chemSpecies::Species &s) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << s;
|
||||||
|
return oss.str();
|
||||||
|
});
|
||||||
|
|
||||||
|
chem_submodule.attr("species") = py::cast(chemSpecies::species); // Expose the species map
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
16
src/python/composition/meson.build
Normal file
16
src/python/composition/meson.build
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Define the library
|
||||||
|
bindings_sources = files('bindings.cpp')
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
composition_dep,
|
||||||
|
species_weight_dep,
|
||||||
|
python3_dep,
|
||||||
|
pybind11_dep,
|
||||||
|
]
|
||||||
|
|
||||||
|
libPYcomposition = shared_module('py_composition',
|
||||||
|
bindings_sources,
|
||||||
|
cpp_args: ['-fvisibility=default'],
|
||||||
|
install : true,
|
||||||
|
dependencies: dependencies,
|
||||||
|
)
|
||||||
0
src/python/fourdstar/__init__.py
Normal file
0
src/python/fourdstar/__init__.py
Normal file
1
src/python/meson.build
Normal file
1
src/python/meson.build
Normal file
@@ -0,0 +1 @@
|
|||||||
|
subdir('composition')
|
||||||
@@ -23,7 +23,7 @@ dependencies = [
|
|||||||
|
|
||||||
libResourceHeader_dep = declare_dependency(include_directories: include_directories('public'))
|
libResourceHeader_dep = declare_dependency(include_directories: include_directories('public'))
|
||||||
# Define the libresourceManager library so it can be linked against by other parts of the build system
|
# Define the libresourceManager library so it can be linked against by other parts of the build system
|
||||||
libresourceManager = static_library('resourceManager',
|
libresourceManager = library('resourceManager',
|
||||||
resourceManager_sources,
|
resourceManager_sources,
|
||||||
include_directories: include_directories('public'),
|
include_directories: include_directories('public'),
|
||||||
cpp_args: ['-fvisibility=default'],
|
cpp_args: ['-fvisibility=default'],
|
||||||
|
|||||||
13
subprojects/pybind11.wrap
Normal file
13
subprojects/pybind11.wrap
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = pybind11-2.13.5
|
||||||
|
source_url = https://github.com/pybind/pybind11/archive/refs/tags/v2.13.5.tar.gz
|
||||||
|
source_filename = pybind11-2.13.5.tar.gz
|
||||||
|
source_hash = b1e209c42b3a9ed74da3e0b25a4f4cd478d89d5efbb48f04b277df427faf6252
|
||||||
|
patch_filename = pybind11_2.13.5-1_patch.zip
|
||||||
|
patch_url = https://wrapdb.mesonbuild.com/v2/pybind11_2.13.5-1/get_patch
|
||||||
|
patch_hash = ecb031b830481560b3d8487ed63ba4f5509a074be42f5d19af64d844c795e15b
|
||||||
|
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/pybind11_2.13.5-1/pybind11-2.13.5.tar.gz
|
||||||
|
wrapdb_version = 2.13.5-1
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
pybind11 = pybind11_dep
|
||||||
@@ -9,7 +9,6 @@ int main(int argv, char* argc[]) {
|
|||||||
} else {
|
} else {
|
||||||
pathToConfigFile = "config.json";
|
pathToConfigFile = "config.json";
|
||||||
}
|
}
|
||||||
Config::getInstance().loadConfig(pathToConfigFile);
|
|
||||||
composition::Composition comp;
|
composition::Composition comp;
|
||||||
std::vector<std::string> symbols = {"H-1", "He-4"};
|
std::vector<std::string> symbols = {"H-1", "He-4"};
|
||||||
comp.registerSymbol(symbols);
|
comp.registerSymbol(symbols);
|
||||||
|
|||||||
Reference in New Issue
Block a user