feat(GridFire): Added a number of python hooks

python hooks to make getting base composition more reliable; further, a number of small changes made to aid in my analysis in response to ref report 1
This commit is contained in:
2026-04-13 07:17:14 -04:00
parent 65297852e5
commit 84ff182717
44 changed files with 1676 additions and 2964 deletions

View File

@@ -6,10 +6,24 @@
namespace py = pybind11;
void register_config_bindings(pybind11::module &m) {
py::class_<gridfire::config::BoundaryFluxConfig>(m, "BoundaryFluxConfig")
.def(py::init<>())
.def_readwrite("relativeThreshold", &gridfire::config::BoundaryFluxConfig::relativeThreshold)
.def_readwrite("absoluteThreshold", &gridfire::config::BoundaryFluxConfig::absoluteThreshold);
py::class_<gridfire::config::TriggerConfig>(m, "TriggerConfig")
.def(py::init<>())
.def_readwrite("offDiagonalThreshold", &gridfire::config::TriggerConfig::offDiagonalThreshold)
.def_readwrite("timestepCollapseRatio", &gridfire::config::TriggerConfig::timestepCollapseRatio)
.def_readwrite("maxConvergenceFailures", &gridfire::config::TriggerConfig::maxConvergenceFailures)
.def_readwrite("boundaryFlux", &gridfire::config::TriggerConfig::boundaryFlux);
py::class_<gridfire::config::PointSolverConfig>(m, "PointSolverConfig")
.def(py::init<>())
.def_readwrite("absTol", &gridfire::config::PointSolverConfig::absTol)
.def_readwrite("relTol", &gridfire::config::PointSolverConfig::relTol);
.def_readwrite("relTol", &gridfire::config::PointSolverConfig::relTol)
.def_readwrite("trigger", &gridfire::config::PointSolverConfig::trigger);
py::class_<gridfire::config::SolverConfig>(m, "SolverConfig")
.def(py::init<>())

View File

@@ -194,6 +194,25 @@ namespace {
py::arg("ctx"),
py::arg("species"),
"Get the status of a species in the network."
)
.def("constructStateBlob",
&T::constructStateBlob,
py::arg("blob") = std::nullopt,
"Construct the state blob for this engine. Generally base engines (GraphEngine) can call this with no arguments whereas views should take an argument to an already constructed state blob which will be cloned and then the clone will be modified"
)
.def(
"getMostRecentRHSCalculation",
[](const T& self, sp::StateBlob& ctx) -> std::optional<gridfire::engine::StepDerivatives<double>> {
auto result = self.getMostRecentRHSCalculation(ctx);
if (!result.has_value()) {
return std::nullopt;
} else {
return result.value();
}
},
py::arg("ctx"),
"Retrieve the most recent RHS calculation from the engine"
);
}
@@ -529,7 +548,18 @@ void con_stype_register_graph_engine_bindings(const pybind11::module &m) {
&gridfire::engine::GraphEngine::isUsingReverseReactions,
"Check if the engine is using reverse reactions."
);
py_graph_engine_bindings.def(
"addReaction",
py::overload_cast<const gridfire::reaction::Reaction&>(&gridfire::engine::GraphEngine::addReaction),
py::arg("reaction"),
"Add a reaction to the engine's network manually."
);
py_graph_engine_bindings.def(
"addReaction",
py::overload_cast<const std::string&>(&gridfire::engine::GraphEngine::addReaction),
py::arg("reaction_id"),
"Add a reaction to the engine's network manually using a reaction identifier string."
);
// Register the general dynamic engine bindings
registerDynamicEngineDefs<gridfire::engine::GraphEngine, gridfire::engine::DynamicEngine>(py_graph_engine_bindings);
}

View File

@@ -293,6 +293,16 @@ std::optional<gridfire::engine::StepDerivatives<double>> PyDynamicEngine::getMos
);
}
std::unique_ptr<gridfire::engine::scratch::StateBlob> PyDynamicEngine::constructStateBlob(
const gridfire::engine::scratch::StateBlob *blob) const {
PYBIND11_OVERRIDE_PURE(
std::unique_ptr<gridfire::engine::scratch::StateBlob>,
gridfire::engine::DynamicEngine,
constructStateBlob,
blob
);
}
const gridfire::engine::Engine& PyEngineView::getBaseEngine() const {
PYBIND11_OVERRIDE_PURE(
const gridfire::engine::Engine&,

View File

@@ -130,6 +130,10 @@ public:
gridfire::engine::scratch::StateBlob &ctx
) const override;
std::unique_ptr<gridfire::engine::scratch::StateBlob> constructStateBlob(
const gridfire::engine::scratch::StateBlob *blob
) const override;
private:
mutable std::vector<fourdst::atomic::Species> m_species_cache;
};

View File

@@ -51,6 +51,13 @@ void register_solver_bindings(const py::module &m) {
},
py::return_value_policy::reference_internal
);
py_cvode_timestep_context.def_property_readonly(
"composition",
[](const gridfire::solver::PointSolverTimestepContext& self) -> fourdst::composition::Composition {
return self.getPhysicalComposition();
}
);
auto py_solver_context_base = py::class_<gridfire::solver::SolverContextBase>(m, "SolverContextBase");
@@ -166,6 +173,20 @@ void register_solver_bindings(const py::module &m) {
"Initialize the PointSolver object."
);
py_point_solver.def(
py::init<gridfire::engine::DynamicEngine&, gridfire::config::GridFireConfig&>(),
py::arg("engine"),
py::arg("config"),
"Initialize the PointSolver object with a configuration set."
);
py_point_solver.def(
"getConfig",
&gridfire::solver::PointSolver::getConfig,
"Get a copy of the config object"
);
py_point_solver.def(
"evaluate",
py::overload_cast<gridfire::solver::SolverContextBase&, const gridfire::NetIn&, bool, bool>(&gridfire::solver::PointSolver::evaluate, py::const_),