feat(python): Repaired python bindings

Python bindings have now been brought back up to feature pairity with
C++. Further, stubs have been added for all python features so that code
completion will work
This commit is contained in:
2025-11-25 14:08:58 -05:00
parent 22b52abc30
commit bb1d6bbb24
51 changed files with 3798 additions and 460 deletions

View File

@@ -5,8 +5,8 @@
#include "bindings.h"
#include "gridfire/engine/engine.h"
#include "gridfire/engine/diagnostics/dynamic_engine_diagnostics.h"
#include "gridfire/exceptions/exceptions.h"
#include "pybind11/numpy.h"
#include "trampoline/py_engine.h"
@@ -15,21 +15,21 @@ namespace py = pybind11;
namespace {
template <typename T>
concept IsDynamicEngine = std::is_base_of_v<gridfire::DynamicEngine, T>;
concept IsDynamicEngine = std::is_base_of_v<gridfire::engine::DynamicEngine, T>;
template <IsDynamicEngine T, IsDynamicEngine BaseT>
void registerDynamicEngineDefs(py::class_<T, BaseT> pyClass) {
pyClass.def(
"calculateRHSAndEnergy",
[](
const gridfire::DynamicEngine& self,
const gridfire::engine::DynamicEngine& self,
const fourdst::composition::Composition& comp,
const double T9,
const double rho
) {
auto result = self.calculateRHSAndEnergy(comp, T9, rho);
if (!result.has_value()) {
throw gridfire::exceptions::StaleEngineError("Engine reports stale state, call update().");
throw gridfire::exceptions::EngineError(std::format("calculateRHSAndEnergy returned a potentially recoverable error {}", gridfire::engine::EngineStatus_to_string(result.error())));
}
return result.value();
},
@@ -39,21 +39,32 @@ namespace {
"Calculate the right-hand side (dY/dt) and energy generation rate."
)
.def("calculateEpsDerivatives",
&gridfire::DynamicEngine::calculateEpsDerivatives,
&gridfire::engine::DynamicEngine::calculateEpsDerivatives,
py::arg("comp"),
py::arg("T9"),
py::arg("rho"),
"Calculate deps/dT and deps/drho"
)
.def("generateJacobianMatrix",
py::overload_cast<const fourdst::composition::Composition&, double, double>(&T::generateJacobianMatrix, py::const_),
[](const gridfire::engine::DynamicEngine& self,
const fourdst::composition::Composition& comp,
const double T9,
const double rho) -> gridfire::engine::NetworkJacobian {
return self.generateJacobianMatrix(comp, T9, rho);
},
py::arg("comp"),
py::arg("T9"),
py::arg("rho"),
"Generate the Jacobian matrix for the current state."
)
.def("generateJacobianMatrix",
py::overload_cast<const fourdst::composition::Composition&, double, double, const std::vector<fourdst::atomic::Species>&>(&T::generateJacobianMatrix, py::const_),
[](const gridfire::engine::DynamicEngine& self,
const fourdst::composition::Composition& comp,
const double T9,
const double rho,
const std::vector<fourdst::atomic::Species>& activeSpecies) -> gridfire::engine::NetworkJacobian {
return self.generateJacobianMatrix(comp, T9, rho, activeSpecies);
},
py::arg("comp"),
py::arg("T9"),
py::arg("rho"),
@@ -61,7 +72,13 @@ namespace {
"Generate the jacobian matrix only for the subset of the matrix representing the active species."
)
.def("generateJacobianMatrix",
py::overload_cast<const fourdst::composition::Composition&, double, double, const gridfire::SparsityPattern&>(&T::generateJacobianMatrix, py::const_),
[](const gridfire::engine::DynamicEngine& self,
const fourdst::composition::Composition& comp,
const double T9,
const double rho,
const gridfire::engine::SparsityPattern& sparsityPattern) -> gridfire::engine::NetworkJacobian {
return self.generateJacobianMatrix(comp, T9, rho, sparsityPattern);
},
py::arg("comp"),
py::arg("T9"),
py::arg("rho"),
@@ -73,7 +90,7 @@ namespace {
)
.def("calculateMolarReactionFlow",
[](
const gridfire::DynamicEngine& self,
const gridfire::engine::DynamicEngine& self,
const gridfire::reaction::Reaction& reaction,
const fourdst::composition::Composition& comp,
const double T9,
@@ -97,11 +114,6 @@ namespace {
py::arg("reactions"),
"Set the network reactions to a new set of reactions."
)
.def("getJacobianMatrixEntry", &T::getJacobianMatrixEntry,
py::arg("rowSpecies"),
py::arg("colSpecies"),
"Get an entry from the previously generated Jacobian matrix."
)
.def("getStoichiometryMatrixEntry", &T::getStoichiometryMatrixEntry,
py::arg("species"),
py::arg("reaction"),
@@ -109,14 +121,14 @@ namespace {
)
.def("getSpeciesTimescales",
[](
const gridfire::DynamicEngine& self,
const gridfire::engine::DynamicEngine& self,
const fourdst::composition::Composition& comp,
const double T9,
const double rho
) -> std::unordered_map<fourdst::atomic::Species, double> {
const auto result = self.getSpeciesTimescales(comp, T9, rho);
if (!result.has_value()) {
throw gridfire::exceptions::StaleEngineError("Engine reports stale state, call update().");
throw gridfire::exceptions::EngineError(std::format("getSpeciesTimescales has returned a potentially recoverable error {}", gridfire::engine::EngineStatus_to_string(result.error())));
}
return result.value();
},
@@ -127,14 +139,14 @@ namespace {
)
.def("getSpeciesDestructionTimescales",
[](
const gridfire::DynamicEngine& self,
const gridfire::engine::DynamicEngine& self,
const fourdst::composition::Composition& comp,
const double T9,
const double rho
) -> std::unordered_map<fourdst::atomic::Species, double> {
const auto result = self.getSpeciesDestructionTimescales(comp, T9, rho);
if (!result.has_value()) {
throw gridfire::exceptions::StaleEngineError("Engine reports stale state, call update().");
throw gridfire::exceptions::EngineError(std::format("getSpeciesDestructionTimescales has returned a potentially recoverable error {}", gridfire::engine::EngineStatus_to_string(result.error())));
}
return result.value();
},
@@ -179,7 +191,7 @@ namespace {
.def("rebuild",
&T::rebuild,
py::arg("composition"),
py::arg("depth") = gridfire::NetworkBuildDepth::Full,
py::arg("depth") = gridfire::engine::NetworkBuildDepth::Full,
"Rebuild the engine with a new composition and build depth."
)
.def("isStale",
@@ -190,7 +202,14 @@ namespace {
.def("collectComposition",
&T::collectComposition,
py::arg("composition"),
py::arg("T9"),
py::arg("rho"),
"Recursively collect composition from current engine and any sub engines if they exist."
)
.def("getSpeciesStatus",
&T::getSpeciesStatus,
py::arg("species"),
"Get the status of a species in the network."
);
}
@@ -206,11 +225,11 @@ void register_engine_bindings(py::module &m) {
void register_base_engine_bindings(const pybind11::module &m) {
py::class_<gridfire::StepDerivatives<double>>(m, "StepDerivatives")
.def_readonly("dYdt", &gridfire::StepDerivatives<double>::dydt, "The right-hand side (dY/dt) of the ODE system.")
.def_readonly("energy", &gridfire::StepDerivatives<double>::nuclearEnergyGenerationRate, "The energy generation rate.");
py::class_<gridfire::engine::StepDerivatives<double>>(m, "StepDerivatives")
.def_readonly("dYdt", &gridfire::engine::StepDerivatives<double>::dydt, "The right-hand side (dY/dt) of the ODE system.")
.def_readonly("energy", &gridfire::engine::StepDerivatives<double>::nuclearEnergyGenerationRate, "The energy generation rate.");
py::class_<gridfire::SparsityPattern> py_sparsity_pattern(m, "SparsityPattern");
py::class_<gridfire::engine::SparsityPattern> py_sparsity_pattern(m, "SparsityPattern");
abs_stype_register_engine_bindings(m);
abs_stype_register_dynamic_engine_bindings(m);
@@ -218,148 +237,219 @@ void register_base_engine_bindings(const pybind11::module &m) {
}
void abs_stype_register_engine_bindings(const pybind11::module &m) {
py::class_<gridfire::Engine, PyEngine>(m, "Engine");
py::class_<gridfire::engine::Engine, PyEngine>(m, "Engine");
}
void abs_stype_register_dynamic_engine_bindings(const pybind11::module &m) {
const auto a = py::class_<gridfire::DynamicEngine, PyDynamicEngine>(m, "DynamicEngine");
const auto a = py::class_<gridfire::engine::DynamicEngine, PyDynamicEngine>(m, "DynamicEngine");
}
void register_engine_procedural_bindings(pybind11::module &m) {
auto procedures = m.def_submodule("procedures", "Procedural functions associated with engine module");
register_engine_construction_bindings(procedures);
register_engine_construction_bindings(procedures);
register_engine_construction_bindings(m);
register_engine_priming_bindings(m);
}
void register_engine_diagnostic_bindings(pybind11::module &m) {
auto diagnostics = m.def_submodule("diagnostics", "A submodule for engine diagnostics");
diagnostics.def("report_limiting_species",
&gridfire::diagnostics::report_limiting_species,
&gridfire::engine::diagnostics::report_limiting_species,
py::arg("engine"),
py::arg("Y_full"),
py::arg("E_full"),
py::arg("dydt_full"),
py::arg("relTol"),
py::arg("absTol"),
py::arg("top_n") = 10
py::arg("top_n"),
py::arg("json")
);
diagnostics.def("inspect_species_balance",
&gridfire::diagnostics::inspect_species_balance,
&gridfire::engine::diagnostics::inspect_species_balance,
py::arg("engine"),
py::arg("species_name"),
py::arg("comp"),
py::arg("T9"),
py::arg("rho")
py::arg("rho"),
py::arg("json")
);
diagnostics.def("inspect_jacobian_stiffness",
&gridfire::diagnostics::inspect_jacobian_stiffness,
&gridfire::engine::diagnostics::inspect_jacobian_stiffness,
py::arg("engine"),
py::arg("comp"),
py::arg("T9"),
py::arg("rho")
py::arg("rho"),
py::arg("json")
);
}
void register_engine_construction_bindings(pybind11::module &m) {
m.def("build_nuclear_network", &gridfire::build_nuclear_network,
py::enum_<gridfire::engine::NetworkConstructionFlags>(m, "NetworkConstructionFlags")
.value("NONE", gridfire::engine::NetworkConstructionFlags::NONE, "No special construction flags.")
.value("REACLIB_STRONG", gridfire::engine::NetworkConstructionFlags::REACLIB_STRONG, "Include strong reactions from reaclib.")
.value("WRL_BETA_MINUS", gridfire::engine::NetworkConstructionFlags::WRL_BETA_MINUS, "Include beta-minus decay reactions from weak rate library.")
.value("WRL_BETA_PLUS", gridfire::engine::NetworkConstructionFlags::WRL_BETA_PLUS, "Include beta-plus decay reactions from weak rate library.")
.value("WRL_ELECTRON_CAPTURE", gridfire::engine::NetworkConstructionFlags::WRL_ELECTRON_CAPTURE, "Include electron capture reactions from weak rate library.")
.value("WRL_POSITRON_CAPTURE", gridfire::engine::NetworkConstructionFlags::WRL_POSITRON_CAPTURE, "Include positron capture reactions from weak rate library.")
.value("REACLIB_WEAK", gridfire::engine::NetworkConstructionFlags::REACLIB_WEAK, "Include weak reactions from reaclib.")
.value("WRL_WEAK", gridfire::engine::NetworkConstructionFlags::WRL_WEAK, "Include all weak reactions from weak rate library.")
.value("REACLIB", gridfire::engine::NetworkConstructionFlags::REACLIB, "Include all reactions from reaclib.")
.value("DEFAULT", gridfire::engine::NetworkConstructionFlags::DEFAULT, "Default construction flags (Reaclib strong and weak).")
.export_values()
.def("__repr__", [](const gridfire::engine::NetworkConstructionFlags& flags) {
return gridfire::engine::NetworkConstructionFlagsToString(flags);
});
m.def("build_nuclear_network", &gridfire::engine::build_nuclear_network,
py::arg("composition"),
py::arg("weakInterpolator"),
py::arg("maxLayers") = gridfire::NetworkBuildDepth::Full,
py::arg("reverse") = false,
py::arg("maxLayers") = gridfire::engine::NetworkBuildDepth::Full,
py::arg("ReactionTypes") = gridfire::engine::NetworkConstructionFlags::DEFAULT,
"Build a nuclear network from a composition using all archived reaction data."
);
}
void register_engine_priming_bindings(pybind11::module &m) {
m.def("calculateDestructionRateConstant",
&gridfire::calculateDestructionRateConstant,
m.def("primeNetwork",
&gridfire::engine::primeNetwork,
py::arg("netIn"),
py::arg("engine"),
py::arg("species"),
py::arg("composition"),
py::arg("T9"),
py::arg("rho"),
py::arg("reactionTypesToIgnore")
);
m.def("calculateCreationRate",
&gridfire::calculateCreationRate,
py::arg("engine"),
py::arg("species"),
py::arg("composition"),
py::arg("T9"),
py::arg("rho"),
py::arg("reactionTypesToIgnore")
py::arg("ignoredReactionTypes") = std::nullopt,
"Prime a network with a short timescale ignition"
);
}
void register_engine_type_bindings(pybind11::module &m) {
auto types = m.def_submodule("types", "Types associated with engine module");
register_engine_building_type_bindings(types);
register_engine_reporting_type_bindings(types);
register_engine_building_type_bindings(m);
register_engine_reporting_type_bindings(m);
register_engine_types_bindings(m);
register_jacobian_type_bindings(m);
}
void register_engine_building_type_bindings(pybind11::module &m) {
py::enum_<gridfire::NetworkBuildDepth>(m, "NetworkBuildDepth")
.value("Full", gridfire::NetworkBuildDepth::Full, "Full network build depth")
.value("Shallow", gridfire::NetworkBuildDepth::Shallow, "Shallow network build depth")
.value("SecondOrder", gridfire::NetworkBuildDepth::SecondOrder, "Second order network build depth")
.value("ThirdOrder", gridfire::NetworkBuildDepth::ThirdOrder, "Third order network build depth")
.value("FourthOrder", gridfire::NetworkBuildDepth::FourthOrder, "Fourth order network build depth")
.value("FifthOrder", gridfire::NetworkBuildDepth::FifthOrder, "Fifth order network build depth")
void register_engine_building_type_bindings(const pybind11::module &m) {
py::enum_<gridfire::engine::NetworkBuildDepth>(m, "NetworkBuildDepth")
.value("Full", gridfire::engine::NetworkBuildDepth::Full, "Full network build depth")
.value("Shallow", gridfire::engine::NetworkBuildDepth::Shallow, "Shallow network build depth")
.value("SecondOrder", gridfire::engine::NetworkBuildDepth::SecondOrder, "Second order network build depth")
.value("ThirdOrder", gridfire::engine::NetworkBuildDepth::ThirdOrder, "Third order network build depth")
.value("FourthOrder", gridfire::engine::NetworkBuildDepth::FourthOrder, "Fourth order network build depth")
.value("FifthOrder", gridfire::engine::NetworkBuildDepth::FifthOrder, "Fifth order network build depth")
.export_values();
py::class_<gridfire::BuildDepthType> py_build_depth_type(m, "BuildDepthType");
py::class_<gridfire::engine::BuildDepthType> py_build_depth_type(m, "BuildDepthType");
}
void register_engine_reporting_type_bindings(pybind11::module &m) {
py::enum_<gridfire::PrimingReportStatus>(m, "PrimingReportStatus")
.value("FULL_SUCCESS", gridfire::PrimingReportStatus::FULL_SUCCESS, "Priming was full successful.")
.value("NO_SPECIES_TO_PRIME", gridfire::PrimingReportStatus::NO_SPECIES_TO_PRIME, "No species to prime.")
.value("MAX_ITERATIONS_REACHED", gridfire::PrimingReportStatus::MAX_ITERATIONS_REACHED, "Maximum iterations reached during priming.")
.value("FAILED_TO_FINALIZE_COMPOSITION", gridfire::PrimingReportStatus::FAILED_TO_FINALIZE_COMPOSITION, "Failed to finalize the composition after priming.")
.value("FAILED_TO_FIND_CREATION_CHANNEL", gridfire::PrimingReportStatus::FAILED_TO_FIND_CREATION_CHANNEL, "Failed to find a creation channel for the priming species.")
.value("FAILED_TO_FIND_PRIMING_REACTIONS", gridfire::PrimingReportStatus::FAILED_TO_FIND_PRIMING_REACTIONS, "Failed to find priming reactions for the species.")
.value("BASE_NETWORK_TOO_SHALLOW", gridfire::PrimingReportStatus::BASE_NETWORK_TOO_SHALLOW, "The base network is too shallow for priming.")
void register_engine_reporting_type_bindings(const pybind11::module &m) {
py::enum_<gridfire::engine::PrimingReportStatus>(m, "PrimingReportStatus")
.value("FULL_SUCCESS", gridfire::engine::PrimingReportStatus::SUCCESS, "Priming was full successful.")
.value("NO_SPECIES_TO_PRIME", gridfire::engine::PrimingReportStatus::SOLVER_FAILURE, "Solver Failed to converge during priming.")
.value("MAX_ITERATIONS_REACHED", gridfire::engine::PrimingReportStatus::ALREADY_PRIMED, "Engine has already been primed.")
.export_values()
.def("__repr__", [](const gridfire::PrimingReportStatus& status) {
.def("__repr__", [](const gridfire::engine::PrimingReportStatus& status) {
std::stringstream ss;
ss << gridfire::PrimingReportStatusStrings.at(status) << "\n";
ss << gridfire::engine::PrimingReportStatusStrings.at(status) << "\n";
return ss.str();
},
"String representation of the PrimingReport."
);
py::class_<gridfire::PrimingReport>(m, "PrimingReport")
.def_readonly("success", &gridfire::PrimingReport::success, "Indicates if the priming was successful.")
.def_readonly("massFractionChanges", &gridfire::PrimingReport::massFractionChanges, "Map of species to their mass fraction changes after priming.")
.def_readonly("primedComposition", &gridfire::PrimingReport::primedComposition, "The composition after priming.")
.def_readonly("status", &gridfire::PrimingReport::status, "Status message from the priming process.")
.def("__repr__", [](const gridfire::PrimingReport& report) {
py::class_<gridfire::engine::PrimingReport>(m, "PrimingReport")
.def_readonly("success", &gridfire::engine::PrimingReport::success, "Indicates if the priming was successful.")
.def_readonly("primedComposition", &gridfire::engine::PrimingReport::primedComposition, "The composition after priming.")
.def_readonly("status", &gridfire::engine::PrimingReport::status, "Status message from the priming process.")
.def("__repr__", [](const gridfire::engine::PrimingReport& report) {
std::stringstream ss;
ss << report;
return ss.str();
}
);
py::enum_<gridfire::engine::SpeciesStatus>(m, "SpeciesStatus")
.value("ACTIVE", gridfire::engine::SpeciesStatus::ACTIVE, "Species is active in the network.")
.value("EQUILIBRIUM", gridfire::engine::SpeciesStatus::EQUILIBRIUM, "Species is in equilibrium.")
.value("INACTIVE_FLOW", gridfire::engine::SpeciesStatus::INACTIVE_FLOW, "Species is inactive due to flow.")
.value("NOT_PRESENT", gridfire::engine::SpeciesStatus::NOT_PRESENT, "Species is not present in the network.")
.export_values()
.def("__repr__", [](const gridfire::engine::SpeciesStatus& status) {
return gridfire::engine::SpeciesStatus_to_string(status);
});
}
void register_engine_types_bindings(const pybind11::module &m) {
py::enum_<gridfire::engine::EngineTypes>(m, "EngineTypes")
.value("GRAPH_ENGINE", gridfire::engine::EngineTypes::GRAPH_ENGINE, "The standard graph-based engine.")
.value("ADAPTIVE_ENGINE_VIEW", gridfire::engine::EngineTypes::ADAPTIVE_ENGINE_VIEW, "An engine that adapts based on certain criteria.")
.value("MULTISCALE_PARTITIONING_ENGINE_VIEW", gridfire::engine::EngineTypes::MULTISCALE_PARTITIONING_ENGINE_VIEW, "An engine that partitions the system at multiple scales.")
.value("PRIMING_ENGINE_VIEW", gridfire::engine::EngineTypes::PRIMING_ENGINE_VIEW, "An engine that uses a priming strategy for simulations.")
.value("DEFINED_ENGINE_VIEW", gridfire::engine::EngineTypes::DEFINED_ENGINE_VIEW, "An engine defined by user specifications.")
.value("FILE_DEFINED_ENGINE_VIEW", gridfire::engine::EngineTypes::FILE_DEFINED_ENGINE_VIEW, "An engine defined through external files.")
.export_values()
.def("__repr__", [](const gridfire::engine::EngineTypes& type) {
return std::string(gridfire::engine::engine_type_to_string(type));
},
"String representation of the EngineTypes."
);
}
void register_jacobian_type_bindings(pybind11::module &m) {
py::class_<gridfire::engine::NetworkJacobian>(m, "NetworkJacobian")
.def("rank", &gridfire::engine::NetworkJacobian::rank, "Get the rank of the Jacobian matrix.")
.def("nnz", &gridfire::engine::NetworkJacobian::nnz, "Get the number of non-zero entries in the Jacobian matrix.")
.def("singular", &gridfire::engine::NetworkJacobian::singular, "Check if the Jacobian matrix is singular.")
.def("infs", &gridfire::engine::NetworkJacobian::infs, "Get all infinite entries in the Jacobian matrix.")
.def("nans", &gridfire::engine::NetworkJacobian::nans, "Get all NaN entries in the Jacobian matrix.")
.def("data", &gridfire::engine::NetworkJacobian::data, "Get the underlying sparse matrix data.")
.def("mapping", &gridfire::engine::NetworkJacobian::mapping, "Get the species-to-index mapping.")
.def("shape", &gridfire::engine::NetworkJacobian::shape, "Get the shape of the Jacobian matrix as (rows, columns).")
.def("to_csv", &gridfire::engine::NetworkJacobian::to_csv, py::arg("filename"), "Export the Jacobian matrix to a CSV file.")
.def("__getitem__", [](const gridfire::engine::NetworkJacobian &self, const std::pair<fourdst::atomic::Species, fourdst::atomic::Species>& speciesPair) {
return self(speciesPair.first, speciesPair.second);
}, py::arg("key"), "Get an entry from the Jacobian matrix using species identifiers.")
.def("__getitem__", [](const gridfire::engine::NetworkJacobian &self, const std::pair<size_t, size_t>& indexPair) {
return self(indexPair.first, indexPair.second);
}, py::arg("key"), "Get an entry from the Jacobian matrix using indices.")
.def("__setitem__", [](gridfire::engine::NetworkJacobian &self, const std::pair<fourdst::atomic::Species, fourdst::atomic::Species>& speciesPair, double value) {
self.set(speciesPair.first, speciesPair.second, value);
}, py::arg("key"), py::arg("value"), "Set an entry in the Jacobian matrix using species identifiers.")
.def("__setitem__", [](gridfire::engine::NetworkJacobian &self, const std::pair<size_t, size_t>& indexPair, double value) {
self.set(indexPair.first, indexPair.second, value);
}, py::arg("key"), py::arg("value"), "Set an entry in the Jacobian matrix using indices.")
.def("to_numpy", [](const gridfire::engine::NetworkJacobian &self) {
auto denseMatrix = Eigen::MatrixXd(self.data());
return pybind11::array_t<double>(
{std::get<0>(self.shape()), std::get<1>(self.shape())},
{sizeof(double) * std::get<1>(self.shape()), sizeof(double)},
denseMatrix.data()
);
}, "Convert the Jacobian matrix to a NumPy array.");
m.def(
"regularize_jacobian",
[](const gridfire::engine::NetworkJacobian& jac, const fourdst::composition::Composition& comp) {
return regularize_jacobian(jac, comp, std::nullopt);
},
py::arg("jacobian"),
py::arg("composition"),
"regularize_jacobian"
);
}
void con_stype_register_graph_engine_bindings(const pybind11::module &m) {
auto py_graph_engine_bindings = py::class_<gridfire::GraphEngine, gridfire::DynamicEngine>(m, "GraphEngine");
auto py_graph_engine_bindings = py::class_<gridfire::engine::GraphEngine, gridfire::engine::DynamicEngine>(m, "GraphEngine");
// Register the Graph Engine Specific Bindings
py_graph_engine_bindings.def(py::init<const fourdst::composition::Composition &, const gridfire::BuildDepthType>(),
py_graph_engine_bindings.def(py::init<const fourdst::composition::Composition &, const gridfire::engine::BuildDepthType>(),
py::arg("composition"),
py::arg("depth") = gridfire::NetworkBuildDepth::Full,
py::arg("depth") = gridfire::engine::NetworkBuildDepth::Full,
"Initialize GraphEngine with a composition and build depth."
);
py_graph_engine_bindings.def(py::init<const fourdst::composition::Composition &,const gridfire::partition::PartitionFunction &, const gridfire::BuildDepthType>(),
py_graph_engine_bindings.def(py::init<const fourdst::composition::Composition &,const gridfire::partition::PartitionFunction &, const gridfire::engine::BuildDepthType>(),
py::arg("composition"),
py::arg("partitionFunction"),
py::arg("depth") = gridfire::NetworkBuildDepth::Full,
py::arg("depth") = gridfire::engine::NetworkBuildDepth::Full,
"Initialize GraphEngine with a composition, partition function and build depth."
);
py_graph_engine_bindings.def(py::init<const gridfire::reaction::ReactionSet &>(),
@@ -367,54 +457,66 @@ void con_stype_register_graph_engine_bindings(const pybind11::module &m) {
"Initialize GraphEngine with a set of reactions."
);
py_graph_engine_bindings.def_static("getNetReactionStoichiometry",
&gridfire::GraphEngine::getNetReactionStoichiometry,
&gridfire::engine::GraphEngine::getNetReactionStoichiometry,
py::arg("reaction"),
"Get the net stoichiometry for a given reaction."
);
py_graph_engine_bindings.def("getSpeciesTimescales",
py::overload_cast<const fourdst::composition::Composition&, double, double, const gridfire::reaction::ReactionSet&>(&gridfire::GraphEngine::getSpeciesTimescales, py::const_),
[](const gridfire::engine::GraphEngine& self,
const fourdst::composition::Composition& composition,
const double T9,
const double rho,
const gridfire::reaction::ReactionSet& activeReactions) {
return self.getSpeciesTimescales(composition, T9, rho, activeReactions);
},
py::arg("composition"),
py::arg("T9"),
py::arg("rho"),
py::arg("activeReactions")
);
py_graph_engine_bindings.def("getSpeciesDestructionTimescales",
py::overload_cast<const fourdst::composition::Composition&, double, double, const gridfire::reaction::ReactionSet&>(&gridfire::GraphEngine::getSpeciesDestructionTimescales, py::const_),
[](const gridfire::engine::GraphEngine& self,
const fourdst::composition::Composition& composition,
const double T9,
const double rho,
const gridfire::reaction::ReactionSet& activeReactions) {
return self.getSpeciesDestructionTimescales(composition, T9, rho, activeReactions);
},
py::arg("composition"),
py::arg("T9"),
py::arg("rho"),
py::arg("activeReactions")
);
py_graph_engine_bindings.def("involvesSpecies",
&gridfire::GraphEngine::involvesSpecies,
&gridfire::engine::GraphEngine::involvesSpecies,
py::arg("species"),
"Check if a given species is involved in the network."
);
py_graph_engine_bindings.def("exportToDot",
&gridfire::GraphEngine::exportToDot,
&gridfire::engine::GraphEngine::exportToDot,
py::arg("filename"),
"Export the network to a DOT file for visualization."
);
py_graph_engine_bindings.def("exportToCSV",
&gridfire::GraphEngine::exportToCSV,
&gridfire::engine::GraphEngine::exportToCSV,
py::arg("filename"),
"Export the network to a CSV file for analysis."
);
py_graph_engine_bindings.def("setPrecomputation",
&gridfire::GraphEngine::setPrecomputation,
&gridfire::engine::GraphEngine::setPrecomputation,
py::arg("precompute"),
"Enable or disable precomputation for the engine."
);
py_graph_engine_bindings.def("isPrecomputationEnabled",
&gridfire::GraphEngine::isPrecomputationEnabled,
&gridfire::engine::GraphEngine::isPrecomputationEnabled,
"Check if precomputation is enabled for the engine."
);
py_graph_engine_bindings.def("getPartitionFunction",
&gridfire::GraphEngine::getPartitionFunction,
&gridfire::engine::GraphEngine::getPartitionFunction,
"Get the partition function used by the engine."
);
py_graph_engine_bindings.def("calculateReverseRate",
&gridfire::GraphEngine::calculateReverseRate,
&gridfire::engine::GraphEngine::calculateReverseRate,
py::arg("reaction"),
py::arg("T9"),
py::arg("rho"),
@@ -422,7 +524,7 @@ void con_stype_register_graph_engine_bindings(const pybind11::module &m) {
"Calculate the reverse rate for a given reaction at a specific temperature, density, and composition."
);
py_graph_engine_bindings.def("calculateReverseRateTwoBody",
&gridfire::GraphEngine::calculateReverseRateTwoBody,
&gridfire::engine::GraphEngine::calculateReverseRateTwoBody,
py::arg("reaction"),
py::arg("T9"),
py::arg("forwardRate"),
@@ -430,7 +532,7 @@ void con_stype_register_graph_engine_bindings(const pybind11::module &m) {
"Calculate the reverse rate for a two-body reaction at a specific temperature."
);
py_graph_engine_bindings.def("calculateReverseRateTwoBodyDerivative",
&gridfire::GraphEngine::calculateReverseRateTwoBodyDerivative,
&gridfire::engine::GraphEngine::calculateReverseRateTwoBodyDerivative,
py::arg("reaction"),
py::arg("T9"),
py::arg("rho"),
@@ -439,126 +541,96 @@ void con_stype_register_graph_engine_bindings(const pybind11::module &m) {
"Calculate the derivative of the reverse rate for a two-body reaction at a specific temperature."
);
py_graph_engine_bindings.def("isUsingReverseReactions",
&gridfire::GraphEngine::isUsingReverseReactions,
&gridfire::engine::GraphEngine::isUsingReverseReactions,
"Check if the engine is using reverse reactions."
);
py_graph_engine_bindings.def("setUseReverseReactions",
&gridfire::GraphEngine::setUseReverseReactions,
&gridfire::engine::GraphEngine::setUseReverseReactions,
py::arg("useReverse"),
"Enable or disable the use of reverse reactions in the engine."
);
// Register the general dynamic engine bindings
registerDynamicEngineDefs<gridfire::GraphEngine, gridfire::DynamicEngine>(py_graph_engine_bindings);
registerDynamicEngineDefs<gridfire::engine::GraphEngine, gridfire::engine::DynamicEngine>(py_graph_engine_bindings);
}
void register_engine_view_bindings(const pybind11::module &m) {
auto py_defined_engine_view_bindings = py::class_<gridfire::DefinedEngineView, gridfire::DynamicEngine>(m, "DefinedEngineView");
auto py_defined_engine_view_bindings = py::class_<gridfire::engine::DefinedEngineView, gridfire::engine::DynamicEngine>(m, "DefinedEngineView");
py_defined_engine_view_bindings.def(py::init<std::vector<std::string>, gridfire::GraphEngine&>(),
py_defined_engine_view_bindings.def(py::init<std::vector<std::string>, gridfire::engine::GraphEngine&>(),
py::arg("peNames"),
py::arg("baseEngine"),
"Construct a defined engine view with a list of tracked reactions and a base engine."
);
py_defined_engine_view_bindings.def("getBaseEngine", &gridfire::DefinedEngineView::getBaseEngine,
py_defined_engine_view_bindings.def("getBaseEngine", &gridfire::engine::DefinedEngineView::getBaseEngine,
"Get the base engine associated with this defined engine view.");
registerDynamicEngineDefs<gridfire::DefinedEngineView, gridfire::DynamicEngine>(py_defined_engine_view_bindings);
registerDynamicEngineDefs<gridfire::engine::DefinedEngineView, gridfire::engine::DynamicEngine>(py_defined_engine_view_bindings);
auto py_file_defined_engine_view_bindings = py::class_<gridfire::FileDefinedEngineView, gridfire::DefinedEngineView>(m, "FileDefinedEngineView");
auto py_file_defined_engine_view_bindings = py::class_<gridfire::engine::FileDefinedEngineView, gridfire::engine::DefinedEngineView>(m, "FileDefinedEngineView");
py_file_defined_engine_view_bindings.def(
py::init<gridfire::GraphEngine&, const std::string&, const gridfire::io::NetworkFileParser&>(),
py::init<gridfire::engine::GraphEngine&, const std::string&, const gridfire::io::NetworkFileParser&>(),
py::arg("baseEngine"),
py::arg("fileName"),
py::arg("parser"),
"Construct a defined engine view from a file and a base engine."
);
py_file_defined_engine_view_bindings.def("getNetworkFile", &gridfire::FileDefinedEngineView::getNetworkFile,
py_file_defined_engine_view_bindings.def("getNetworkFile", &gridfire::engine::FileDefinedEngineView::getNetworkFile,
"Get the network file associated with this defined engine view."
);
py_file_defined_engine_view_bindings.def("getParser", &gridfire::FileDefinedEngineView::getParser,
py_file_defined_engine_view_bindings.def("getParser", &gridfire::engine::FileDefinedEngineView::getParser,
"Get the parser used for this defined engine view."
);
py_file_defined_engine_view_bindings.def("getBaseEngine", &gridfire::FileDefinedEngineView::getBaseEngine,
py_file_defined_engine_view_bindings.def("getBaseEngine", &gridfire::engine::FileDefinedEngineView::getBaseEngine,
"Get the base engine associated with this file defined engine view.");
registerDynamicEngineDefs<gridfire::FileDefinedEngineView, gridfire::DefinedEngineView>(py_file_defined_engine_view_bindings);
registerDynamicEngineDefs<gridfire::engine::FileDefinedEngineView, gridfire::engine::DefinedEngineView>(py_file_defined_engine_view_bindings);
auto py_priming_engine_view_bindings = py::class_<gridfire::NetworkPrimingEngineView, gridfire::DefinedEngineView>(m, "NetworkPrimingEngineView");
py_priming_engine_view_bindings.def(py::init<const std::string&, gridfire::GraphEngine&>(),
auto py_priming_engine_view_bindings = py::class_<gridfire::engine::NetworkPrimingEngineView, gridfire::engine::DefinedEngineView>(m, "NetworkPrimingEngineView");
py_priming_engine_view_bindings.def(py::init<const std::string&, gridfire::engine::GraphEngine&>(),
py::arg("primingSymbol"),
py::arg("baseEngine"),
"Construct a priming engine view with a priming symbol and a base engine.");
py_priming_engine_view_bindings.def(py::init<const fourdst::atomic::Species&, gridfire::GraphEngine&>(),
py_priming_engine_view_bindings.def(py::init<const fourdst::atomic::Species&, gridfire::engine::GraphEngine&>(),
py::arg("primingSpecies"),
py::arg("baseEngine"),
"Construct a priming engine view with a priming species and a base engine.");
py_priming_engine_view_bindings.def("getBaseEngine", &gridfire::NetworkPrimingEngineView::getBaseEngine,
py_priming_engine_view_bindings.def("getBaseEngine", &gridfire::engine::NetworkPrimingEngineView::getBaseEngine,
"Get the base engine associated with this priming engine view.");
registerDynamicEngineDefs<gridfire::NetworkPrimingEngineView, gridfire::DefinedEngineView>(py_priming_engine_view_bindings);
registerDynamicEngineDefs<gridfire::engine::NetworkPrimingEngineView, gridfire::engine::DefinedEngineView>(py_priming_engine_view_bindings);
auto py_adaptive_engine_view_bindings = py::class_<gridfire::AdaptiveEngineView, gridfire::DynamicEngine>(m, "AdaptiveEngineView");
py_adaptive_engine_view_bindings.def(py::init<gridfire::DynamicEngine&>(),
auto py_adaptive_engine_view_bindings = py::class_<gridfire::engine::AdaptiveEngineView, gridfire::engine::DynamicEngine>(m, "AdaptiveEngineView");
py_adaptive_engine_view_bindings.def(py::init<gridfire::engine::DynamicEngine&>(),
py::arg("baseEngine"),
"Construct an adaptive engine view with a base engine.");
py_adaptive_engine_view_bindings.def("getBaseEngine",
&gridfire::AdaptiveEngineView::getBaseEngine,
&gridfire::engine::AdaptiveEngineView::getBaseEngine,
"Get the base engine associated with this adaptive engine view."
);
registerDynamicEngineDefs<gridfire::AdaptiveEngineView, gridfire::DynamicEngine>(py_adaptive_engine_view_bindings);
registerDynamicEngineDefs<gridfire::engine::AdaptiveEngineView, gridfire::engine::DynamicEngine>(py_adaptive_engine_view_bindings);
auto py_qse_cache_config = py::class_<gridfire::QSECacheConfig>(m, "QSECacheConfig");
auto py_qse_cache_key = py::class_<gridfire::QSECacheKey>(m, "QSECacheKey");
py_qse_cache_key.def(py::init<double, double, const std::vector<double>&>(),
py::arg("T9"),
py::arg("rho"),
py::arg("Y")
);
py_qse_cache_key.def("hash", &gridfire::QSECacheKey::hash,
"Get the pre-computed hash value of the key");
py_qse_cache_key.def_static("bin", &gridfire::QSECacheKey::bin,
py::arg("value"),
py::arg("tol"),
"bin a value based on a tolerance");
py_qse_cache_key.def("__eq__", &gridfire::QSECacheKey::operator==,
py::arg("other"),
"Check if two QSECacheKeys are equal");
auto py_multiscale_engine_view_bindings = py::class_<gridfire::MultiscalePartitioningEngineView, gridfire::DynamicEngine>(m, "MultiscalePartitioningEngineView");
py_multiscale_engine_view_bindings.def(py::init<gridfire::GraphEngine&>(),
auto py_multiscale_engine_view_bindings = py::class_<gridfire::engine::MultiscalePartitioningEngineView, gridfire::engine::DynamicEngine>(m, "MultiscalePartitioningEngineView");
py_multiscale_engine_view_bindings.def(py::init<gridfire::engine::GraphEngine&>(),
py::arg("baseEngine"),
"Construct a multiscale partitioning engine view with a base engine."
);
py_multiscale_engine_view_bindings.def("getBaseEngine",
&gridfire::MultiscalePartitioningEngineView::getBaseEngine,
&gridfire::engine::MultiscalePartitioningEngineView::getBaseEngine,
"Get the base engine associated with this multiscale partitioning engine view."
);
py_multiscale_engine_view_bindings.def("analyzeTimescalePoolConnectivity",
&gridfire::MultiscalePartitioningEngineView::analyzeTimescalePoolConnectivity,
py::arg("timescale_pools"),
py::arg("comp"),
py::arg("T9"),
py::arg("rho"),
"Analyze the connectivity of timescale pools in the network."
);
py_multiscale_engine_view_bindings.def("partitionNetwork",
py::overload_cast<const fourdst::composition::Composition&, double, double>(&gridfire::MultiscalePartitioningEngineView::partitionNetwork),
py::arg("comp"),
py::arg("T9"),
py::arg("rho"),
&gridfire::engine::MultiscalePartitioningEngineView::partitionNetwork,
py::arg("netIn"),
"Partition the network based on species timescales and connectivity.");
py_multiscale_engine_view_bindings.def("partitionNetwork",
py::overload_cast<const gridfire::NetIn&>(&gridfire::MultiscalePartitioningEngineView::partitionNetwork),
py::overload_cast<const gridfire::NetIn&>(&gridfire::engine::MultiscalePartitioningEngineView::partitionNetwork),
py::arg("netIn"),
"Partition the network based on a NetIn object."
);
py_multiscale_engine_view_bindings.def("exportToDot",
&gridfire::MultiscalePartitioningEngineView::exportToDot,
&gridfire::engine::MultiscalePartitioningEngineView::exportToDot,
py::arg("filename"),
py::arg("comp"),
py::arg("T9"),
@@ -566,26 +638,37 @@ void register_engine_view_bindings(const pybind11::module &m) {
"Export the network to a DOT file for visualization."
);
py_multiscale_engine_view_bindings.def("getFastSpecies",
&gridfire::MultiscalePartitioningEngineView::getFastSpecies,
&gridfire::engine::MultiscalePartitioningEngineView::getFastSpecies,
"Get the list of fast species in the network."
);
py_multiscale_engine_view_bindings.def("getDynamicSpecies",
&gridfire::MultiscalePartitioningEngineView::getDynamicSpecies,
&gridfire::engine::MultiscalePartitioningEngineView::getDynamicSpecies,
"Get the list of dynamic species in the network."
);
py_multiscale_engine_view_bindings.def("equilibrateNetwork",
py::overload_cast<const fourdst::composition::Composition&, double, double>(&gridfire::MultiscalePartitioningEngineView::equilibrateNetwork),
py_multiscale_engine_view_bindings.def("involvesSpecies",
&gridfire::engine::MultiscalePartitioningEngineView::involvesSpecies,
py::arg("species"),
"Check if a given species is involved in the network (in either the algebraic or dynamic set)."
);
py_multiscale_engine_view_bindings.def("involvesSpeciesInQSE",
&gridfire::engine::MultiscalePartitioningEngineView::involvesSpeciesInQSE,
py::arg("species"),
"Check if a given species is involved in the network's algebraic set."
);
py_multiscale_engine_view_bindings.def("involvesSpeciesInDynamic",
&gridfire::engine::MultiscalePartitioningEngineView::involvesSpeciesInDynamic,
py::arg("species"),
"Check if a given species is involved in the network's dynamic set."
);
py_multiscale_engine_view_bindings.def("getNormalizedEquilibratedComposition",
&gridfire::engine::MultiscalePartitioningEngineView::getNormalizedEquilibratedComposition,
py::arg("comp"),
py::arg("T9"),
py::arg("rho"),
"Equilibrate the network based on species abundances and conditions.");
py_multiscale_engine_view_bindings.def("equilibrateNetwork",
py::overload_cast<const gridfire::NetIn&>(&gridfire::MultiscalePartitioningEngineView::equilibrateNetwork),
py::arg("netIn"),
"Equilibrate the network based on a NetIn object."
"Get the normalized equilibrated composition for the algebraic species."
);
registerDynamicEngineDefs<gridfire::MultiscalePartitioningEngineView, gridfire::DynamicEngine>(
registerDynamicEngineDefs<gridfire::engine::MultiscalePartitioningEngineView, gridfire::engine::DynamicEngine>(
py_multiscale_engine_view_bindings
);

View File

@@ -20,7 +20,9 @@ void register_engine_construction_bindings(pybind11::module &m);
void register_engine_priming_bindings(pybind11::module &m);
void register_engine_type_bindings(pybind11::module &m);
void register_engine_building_type_bindings(pybind11::module &m);
void register_engine_reporting_type_bindings(pybind11::module &m);
void register_engine_building_type_bindings(const pybind11::module &m);
void register_engine_reporting_type_bindings(const pybind11::module &m);
void register_engine_types_bindings(const pybind11::module &m);
void register_jacobian_type_bindings(pybind11::module &m);

View File

@@ -33,10 +33,14 @@ const std::vector<fourdst::atomic::Species>& PyEngine::getNetworkSpecies() const
py::pybind11_fail("Tried to call pure virtual function \"DynamicEngine::getNetworkSpecies\"");
}
std::expected<gridfire::StepDerivatives<double>, gridfire::expectations::StaleEngineError> PyEngine::calculateRHSAndEnergy(const fourdst::composition::Composition &comp, double T9, double rho) const {
std::expected<gridfire::engine::StepDerivatives<double>, gridfire::engine::EngineStatus> PyEngine::calculateRHSAndEnergy(
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
) const {
PYBIND11_OVERRIDE_PURE(
PYBIND11_TYPE(std::expected<gridfire::StepDerivatives<double>, gridfire::expectations::StaleEngineError>),
gridfire::Engine,
PYBIND11_TYPE(std::expected<gridfire::engine::StepDerivatives<double>, gridfire::engine::EngineStatus>),
gridfire::engine::Engine,
calculateRHSAndEnergy,
comp, T9, rho
);
@@ -65,19 +69,29 @@ const std::vector<fourdst::atomic::Species>& PyDynamicEngine::getNetworkSpecies(
py::pybind11_fail("Tried to call pure virtual function \"DynamicEngine::getNetworkSpecies\"");
}
std::expected<gridfire::StepDerivatives<double>, gridfire::expectations::StaleEngineError> PyDynamicEngine::calculateRHSAndEnergy(const fourdst::composition::Composition &comp, double T9, double rho) const {
std::expected<gridfire::engine::StepDerivatives<double>, gridfire::engine::EngineStatus> PyDynamicEngine::calculateRHSAndEnergy(
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
) const {
PYBIND11_OVERRIDE_PURE(
PYBIND11_TYPE(std::expected<gridfire::StepDerivatives<double>, gridfire::expectations::StaleEngineError>),
gridfire::Engine,
PYBIND11_TYPE(std::expected<gridfire::engine::StepDerivatives<double>, gridfire::engine::EngineStatus>),
gridfire::engine::DynamicEngine,
calculateRHSAndEnergy,
comp, T9, rho
);
}
void PyDynamicEngine::generateJacobianMatrix(const fourdst::composition::Composition& comp, double T9, double rho) const {
gridfire::engine::NetworkJacobian PyDynamicEngine::generateJacobianMatrix(
const fourdst::composition::CompositionAbstract& comp,
double T9,
double rho
) const {
PYBIND11_OVERRIDE_PURE(
void,
gridfire::DynamicEngine,
gridfire::engine::NetworkJacobian,
gridfire::engine::DynamicEngine,
generateJacobianMatrix,
comp,
T9,
@@ -85,15 +99,15 @@ void PyDynamicEngine::generateJacobianMatrix(const fourdst::composition::Composi
);
}
void PyDynamicEngine::generateJacobianMatrix(
const fourdst::composition::Composition &comp,
gridfire::engine::NetworkJacobian PyDynamicEngine::generateJacobianMatrix(
const fourdst::composition::CompositionAbstract &comp,
const double T9,
const double rho,
const std::vector<fourdst::atomic::Species> &activeSpecies
) const {
PYBIND11_OVERRIDE_PURE(
void,
gridfire::DynamicEngine,
gridfire::engine::NetworkJacobian,
gridfire::engine::DynamicEngine,
generateJacobianMatrix,
comp,
T9,
@@ -102,10 +116,15 @@ void PyDynamicEngine::generateJacobianMatrix(
);
}
void PyDynamicEngine::generateJacobianMatrix(const fourdst::composition::Composition &comp, double T9, double rho, const gridfire::SparsityPattern &sparsityPattern) const {
gridfire::engine::NetworkJacobian PyDynamicEngine::generateJacobianMatrix(
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho,
const gridfire::engine::SparsityPattern &sparsityPattern
) const {
PYBIND11_OVERRIDE_PURE(
void,
gridfire::DynamicEngine,
gridfire::engine::NetworkJacobian,
gridfire::engine::DynamicEngine,
generateJacobianMatrix,
comp,
T9,
@@ -114,38 +133,36 @@ void PyDynamicEngine::generateJacobianMatrix(const fourdst::composition::Composi
);
}
double PyDynamicEngine::getJacobianMatrixEntry(const fourdst::atomic::Species& rowSpecies, const fourdst::atomic::Species& colSpecies) const {
PYBIND11_OVERRIDE_PURE(
double,
gridfire::DynamicEngine,
getJacobianMatrixEntry,
rowSpecies,
colSpecies
);
}
void PyDynamicEngine::generateStoichiometryMatrix() {
PYBIND11_OVERRIDE_PURE(
void,
gridfire::DynamicEngine,
gridfire::engine::DynamicEngine,
generateStoichiometryMatrix
);
}
int PyDynamicEngine::getStoichiometryMatrixEntry(const fourdst::atomic::Species& species, const gridfire::reaction::Reaction& reaction) const {
int PyDynamicEngine::getStoichiometryMatrixEntry(
const fourdst::atomic::Species& species,
const gridfire::reaction::Reaction& reaction
) const {
PYBIND11_OVERRIDE_PURE(
int,
gridfire::DynamicEngine,
gridfire::engine::DynamicEngine,
getStoichiometryMatrixEntry,
species,
reaction
);
}
double PyDynamicEngine::calculateMolarReactionFlow(const gridfire::reaction::Reaction &reaction, const fourdst::composition::Composition &comp, double T9, double rho) const {
double PyDynamicEngine::calculateMolarReactionFlow(
const gridfire::reaction::Reaction &reaction,
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
) const {
PYBIND11_OVERRIDE_PURE(
double,
gridfire::DynamicEngine,
gridfire::engine::DynamicEngine,
calculateMolarReactionFlow,
reaction,
comp,
@@ -157,7 +174,7 @@ double PyDynamicEngine::calculateMolarReactionFlow(const gridfire::reaction::Rea
const gridfire::reaction::ReactionSet& PyDynamicEngine::getNetworkReactions() const {
PYBIND11_OVERRIDE_PURE(
const gridfire::reaction::ReactionSet&,
gridfire::DynamicEngine,
gridfire::engine::DynamicEngine,
getNetworkReactions
);
}
@@ -165,16 +182,20 @@ const gridfire::reaction::ReactionSet& PyDynamicEngine::getNetworkReactions() co
void PyDynamicEngine::setNetworkReactions(const gridfire::reaction::ReactionSet& reactions) {
PYBIND11_OVERRIDE_PURE(
void,
gridfire::DynamicEngine,
gridfire::engine::DynamicEngine,
setNetworkReactions,
reactions
);
}
std::expected<std::unordered_map<fourdst::atomic::Species, double>, gridfire::expectations::StaleEngineError> PyDynamicEngine::getSpeciesTimescales(const fourdst::composition::Composition &comp, double T9, double rho) const {
std::expected<std::unordered_map<fourdst::atomic::Species, double>, gridfire::engine::EngineStatus> PyDynamicEngine::getSpeciesTimescales(
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
) const {
PYBIND11_OVERRIDE_PURE(
PYBIND11_TYPE(std::expected<std::unordered_map<fourdst::atomic::Species, double>, gridfire::expectations::StaleEngineError>),
gridfire::DynamicEngine,
PYBIND11_TYPE(std::expected<std::unordered_map<fourdst::atomic::Species, double>, gridfire::engine::EngineStatus>),
gridfire::engine::DynamicEngine,
getSpeciesTimescales,
comp,
T9,
@@ -182,10 +203,14 @@ std::expected<std::unordered_map<fourdst::atomic::Species, double>, gridfire::ex
);
}
std::expected<std::unordered_map<fourdst::atomic::Species, double>, gridfire::expectations::StaleEngineError> PyDynamicEngine::getSpeciesDestructionTimescales(const fourdst::composition::Composition &comp, double T9, double rho) const {
std::expected<std::unordered_map<fourdst::atomic::Species, double>, gridfire::engine::EngineStatus> PyDynamicEngine::getSpeciesDestructionTimescales(
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
) const {
PYBIND11_OVERRIDE_PURE(
PYBIND11_TYPE(std::expected<std::unordered_map<fourdst::atomic::Species, double>, gridfire::expectations::StaleEngineError>),
gridfire::DynamicEngine,
PYBIND11_TYPE(std::expected<std::unordered_map<fourdst::atomic::Species, double>, gridfire::engine::EngineStatus>),
gridfire::engine::DynamicEngine,
getSpeciesDestructionTimescales,
comp, T9, rho
);
@@ -194,7 +219,7 @@ std::expected<std::unordered_map<fourdst::atomic::Species, double>, gridfire::ex
fourdst::composition::Composition PyDynamicEngine::update(const gridfire::NetIn &netIn) {
PYBIND11_OVERRIDE_PURE(
fourdst::composition::Composition,
gridfire::DynamicEngine,
gridfire::engine::DynamicEngine,
update,
netIn
);
@@ -203,7 +228,7 @@ fourdst::composition::Composition PyDynamicEngine::update(const gridfire::NetIn
bool PyDynamicEngine::isStale(const gridfire::NetIn &netIn) {
PYBIND11_OVERRIDE_PURE(
bool,
gridfire::DynamicEngine,
gridfire::engine::DynamicEngine,
isStale,
netIn
);
@@ -212,7 +237,7 @@ bool PyDynamicEngine::isStale(const gridfire::NetIn &netIn) {
void PyDynamicEngine::setScreeningModel(gridfire::screening::ScreeningType model) {
PYBIND11_OVERRIDE_PURE(
void,
gridfire::DynamicEngine,
gridfire::engine::DynamicEngine,
setScreeningModel,
model
);
@@ -221,7 +246,7 @@ void PyDynamicEngine::setScreeningModel(gridfire::screening::ScreeningType model
gridfire::screening::ScreeningType PyDynamicEngine::getScreeningModel() const {
PYBIND11_OVERRIDE_PURE(
gridfire::screening::ScreeningType,
gridfire::DynamicEngine,
gridfire::engine::DynamicEngine,
getScreeningModel
);
}
@@ -229,7 +254,7 @@ gridfire::screening::ScreeningType PyDynamicEngine::getScreeningModel() const {
size_t PyDynamicEngine::getSpeciesIndex(const fourdst::atomic::Species &species) const {
PYBIND11_OVERRIDE_PURE(
int,
gridfire::DynamicEngine,
gridfire::engine::DynamicEngine,
getSpeciesIndex,
species
);
@@ -238,28 +263,28 @@ size_t PyDynamicEngine::getSpeciesIndex(const fourdst::atomic::Species &species)
std::vector<double> PyDynamicEngine::mapNetInToMolarAbundanceVector(const gridfire::NetIn &netIn) const {
PYBIND11_OVERRIDE_PURE(
std::vector<double>,
gridfire::DynamicEngine,
gridfire::engine::DynamicEngine,
mapNetInToMolarAbundanceVector,
netIn
);
}
gridfire::PrimingReport PyDynamicEngine::primeEngine(const gridfire::NetIn &netIn) {
gridfire::engine::PrimingReport PyDynamicEngine::primeEngine(const gridfire::NetIn &netIn) {
PYBIND11_OVERRIDE_PURE(
gridfire::PrimingReport,
gridfire::DynamicEngine,
gridfire::engine::PrimingReport,
gridfire::engine::DynamicEngine,
primeEngine,
netIn
);
}
gridfire::EnergyDerivatives PyDynamicEngine::calculateEpsDerivatives(
const fourdst::composition::Composition &comp,
gridfire::engine::EnergyDerivatives PyDynamicEngine::calculateEpsDerivatives(
const fourdst::composition::CompositionAbstract &comp,
const double T9,
const double rho) const {
PYBIND11_OVERRIDE_PURE(
gridfire::EnergyDerivatives,
gridfire::DynamicEngine,
gridfire::engine::EnergyDerivatives,
gridfire::engine::DynamicEngine,
calculateEpsDerivatives,
comp,
T9,
@@ -268,28 +293,41 @@ gridfire::EnergyDerivatives PyDynamicEngine::calculateEpsDerivatives(
}
fourdst::composition::Composition PyDynamicEngine::collectComposition(
fourdst::composition::Composition &comp
const fourdst::composition::CompositionAbstract &comp,
const double T9,
const double rho
) const {
PYBIND11_OVERRIDE_PURE(
fourdst::composition::Composition,
gridfire::DynamicEngine,
gridfire::engine::DynamicEngine,
collectComposition,
comp
comp,
T9,
rho
);
}
const gridfire::Engine& PyEngineView::getBaseEngine() const {
gridfire::engine::SpeciesStatus PyDynamicEngine::getSpeciesStatus(const fourdst::atomic::Species &species) const {
PYBIND11_OVERRIDE_PURE(
const gridfire::Engine&,
gridfire::EngineView<gridfire::Engine>,
gridfire::engine::SpeciesStatus,
gridfire::engine::DynamicEngine,
getSpeciesStatus,
species
);
}
const gridfire::engine::Engine& PyEngineView::getBaseEngine() const {
PYBIND11_OVERRIDE_PURE(
const gridfire::engine::Engine&,
gridfire::engine::EngineView<gridfire::engine::Engine>,
getBaseEngine
);
}
const gridfire::DynamicEngine& PyDynamicEngineView::getBaseEngine() const {
const gridfire::engine::DynamicEngine& PyDynamicEngineView::getBaseEngine() const {
PYBIND11_OVERRIDE_PURE(
const gridfire::DynamicEngine&,
gridfire::EngineView<gridfire::DynamicEngine>,
const gridfire::engine::DynamicEngine&,
gridfire::engine::EngineView<gridfire::engine::DynamicEngine>,
getBaseEngine
);
}

View File

@@ -1,7 +1,6 @@
#pragma once
#include "gridfire/engine/engine.h"
#include "gridfire/expectations/expected_engine.h"
#include "fourdst/atomic/atomicSpecies.h"
@@ -9,11 +8,11 @@
#include <expected>
class PyEngine final : public gridfire::Engine {
class PyEngine final : public gridfire::engine::Engine {
public:
const std::vector<fourdst::atomic::Species>& getNetworkSpecies() const override;
std::expected<gridfire::StepDerivatives<double>,gridfire::expectations::StaleEngineError> calculateRHSAndEnergy(
std::expected<gridfire::engine::StepDerivatives<double>, gridfire::engine::EngineStatus> calculateRHSAndEnergy(
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
@@ -22,39 +21,34 @@ private:
mutable std::vector<fourdst::atomic::Species> m_species_cache;
};
class PyDynamicEngine final : public gridfire::DynamicEngine {
class PyDynamicEngine final : public gridfire::engine::DynamicEngine {
public:
const std::vector<fourdst::atomic::Species>& getNetworkSpecies() const override;
std::expected<gridfire::StepDerivatives<double>, gridfire::expectations::StaleEngineError> calculateRHSAndEnergy(
std::expected<gridfire::engine::StepDerivatives<double>, gridfire::engine::EngineStatus> calculateRHSAndEnergy(
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
) const override;
void generateJacobianMatrix(
const fourdst::composition::Composition& comp,
gridfire::engine::NetworkJacobian generateJacobianMatrix(
const fourdst::composition::CompositionAbstract& comp,
double T9,
double rho
) const override;
void generateJacobianMatrix(
gridfire::engine::NetworkJacobian generateJacobianMatrix(
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho,
const std::vector<fourdst::atomic::Species> &activeSpecies
) const override;
void generateJacobianMatrix(
const fourdst::composition::Composition& comp,
gridfire::engine::NetworkJacobian generateJacobianMatrix(
const fourdst::composition::CompositionAbstract& comp,
double T9,
double rho,
const gridfire::SparsityPattern &sparsityPattern
) const override;
double getJacobianMatrixEntry(
const fourdst::atomic::Species& rowSpecies,
const fourdst::atomic::Species& colSpecies
const gridfire::engine::SparsityPattern &sparsityPattern
) const override;
void generateStoichiometryMatrix() override;
@@ -77,14 +71,14 @@ public:
const gridfire::reaction::ReactionSet& reactions
) override;
std::expected<std::unordered_map<fourdst::atomic::Species, double>, gridfire::expectations::StaleEngineError> getSpeciesTimescales(
std::expected<std::unordered_map<fourdst::atomic::Species, double>, gridfire::engine::EngineStatus> getSpeciesTimescales(
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
) const override;
std::expected<std::unordered_map<fourdst::atomic::Species, double>, gridfire::expectations::StaleEngineError> getSpeciesDestructionTimescales(
const fourdst::composition::Composition &comp,
std::expected<std::unordered_map<fourdst::atomic::Species, double>, gridfire::engine::EngineStatus> getSpeciesDestructionTimescales(
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
) const override;
@@ -111,38 +105,44 @@ public:
const gridfire::NetIn &netIn
) const override;
gridfire::PrimingReport primeEngine(
gridfire::engine::PrimingReport primeEngine(
const gridfire::NetIn &netIn
) override;
gridfire::BuildDepthType getDepth() const override {
gridfire::engine::BuildDepthType getDepth() const override {
throw std::logic_error("Network depth not supported by this engine.");
}
void rebuild(
const fourdst::composition::CompositionAbstract &comp,
gridfire::BuildDepthType depth
gridfire::engine::BuildDepthType depth
) override {
throw std::logic_error("Setting network depth not supported by this engine.");
}
[[nodiscard]] gridfire::EnergyDerivatives calculateEpsDerivatives(
const fourdst::composition::Composition &comp,
[[nodiscard]] gridfire::engine::EnergyDerivatives calculateEpsDerivatives(
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
) const override;
fourdst::composition::Composition collectComposition(
fourdst::composition::Composition &comp
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
) const override;
gridfire::engine::SpeciesStatus getSpeciesStatus(
const fourdst::atomic::Species &species
) const override;
private:
mutable std::vector<fourdst::atomic::Species> m_species_cache;
};
class PyEngineView final : public gridfire::EngineView<gridfire::Engine> {
[[nodiscard]] const gridfire::Engine& getBaseEngine() const override;
class PyEngineView final : public gridfire::engine::EngineView<gridfire::engine::Engine> {
[[nodiscard]] const gridfire::engine::Engine& getBaseEngine() const override;
};
class PyDynamicEngineView final : public gridfire::EngineView<gridfire::DynamicEngine> {
[[nodiscard]] const gridfire::DynamicEngine& getBaseEngine() const override;
class PyDynamicEngineView final : public gridfire::engine::EngineView<gridfire::engine::DynamicEngine> {
[[nodiscard]] const gridfire::engine::DynamicEngine& getBaseEngine() const override;
};