fix(python-bindings): Updated python bindings to new interface

The python bindings now work with the polymorphic reaction class and the CVODE solver
This commit is contained in:
2025-10-30 15:05:08 -04:00
parent 23df87f915
commit 7fded59814
27 changed files with 962 additions and 255 deletions

View File

@@ -112,7 +112,8 @@ namespace gridfire {
* @param comp Composition object containing current abundances.
* @param T9 Temperature in units of 10^9 K.
* @param rho Density in g/cm^3.
* @return StepDerivatives<double> containing dY/dt and energy generation rate.
* @return expected<StepDerivatives<double>> containing either dY/dt and energy generation rate or a stale engine
* error indicating that the engine must be updated
*
* This function must be implemented by derived classes to compute the
* time derivatives of all species and the specific nuclear energy generation
@@ -394,5 +395,21 @@ namespace gridfire {
// ReSharper disable once CppDFAUnreachableCode
}
/**
* @brief Recursively collect composition from current engine and any sub engines if they exist.
* @details If species i is defined in comp and in any sub engine or self composition then the molar abundance of
* species i in the returned composition will be that defined in comp. If there are species defined in sub engine
* compositions which are not defined in comp then their molar abundances will be based on the reported values
* from each sub engine.
* @note It is up to each engine to decide how to handle filling in the return composition.
* @note These methods return an unfinalized composition which must then be finalized by the caller
* @param comp Input composition to "normalize".
* @return An updated composition which is a superset of comp. This may contain species which were culled, for
* example, by either QSE partitioning or reaction flow rate culling
*/
virtual fourdst::composition::Composition collectComposition(
fourdst::composition::Composition& comp
) const = 0;
};
}

View File

@@ -730,7 +730,18 @@ namespace gridfire {
BuildDepthType depth
) override;
void lumpReactions();
/**
* @brief This will return the input comp with the molar abundances of any species not registered in that but
* registered in the engine active species set to 0.0.
* @note Effectively this method does not change input composition; rather it ensures that all species which
* can be tracked by an instance of GraphEngine are registered in the composition object.
* @note If a species is in the input comp but not in the network
* @param comp Input Composition
* @return A new composition where all members of the active species set are registered. And any members not in comp
* have a molar abundance set to 0.
* @throws BadCollectionError If the input composition contains species not present in the network species set
*/
fourdst::composition::Composition collectComposition(fourdst::composition::Composition &comp) const override;
private:

View File

@@ -23,7 +23,7 @@ namespace gridfire {
*
* @param composition Mapping of isotopic species to their mass fractions; species with positive
* mass fraction seed the network.
* @param weakInterpolator
* @param weakInterpolator Interpolator to build weak rates from. Must be constructed and owned by the caller.
* @param maxLayers Variant specifying either a predefined NetworkBuildDepth or a custom integer depth;
* negative depth (Full) collects all reactions, zero is invalid.
* @param reverse If true, collects reverse reactions (decays or back-reactions); if false, uses forward reactions.
@@ -36,6 +36,7 @@ namespace gridfire {
reaction::ReactionSet build_nuclear_network(
const fourdst::composition::Composition &composition,
const rates::weak::WeakRateInterpolator &weakInterpolator,
BuildDepthType maxLayers = NetworkBuildDepth::Full, bool reverse = false
BuildDepthType maxLayers = NetworkBuildDepth::Full,
bool reverse = false
);
}

View File

@@ -53,8 +53,8 @@ namespace gridfire {
const fourdst::atomic::Species& species,
const fourdst::composition::Composition& composition,
double T9,
double rho, const std::optional<std::vector<reaction::ReactionType>> &
reactionTypesToIgnore
double rho,
const std::optional<std::vector<reaction::ReactionType>> &reactionTypesToIgnore
);
/**
@@ -78,6 +78,7 @@ namespace gridfire {
const fourdst::atomic::Species& species,
const fourdst::composition::Composition& composition,
double T9,
double rho, const std::optional<std::vector<reaction::ReactionType>> &reactionTypesToIgnore
double rho,
const std::optional<std::vector<reaction::ReactionType>> &reactionTypesToIgnore
);
}

View File

@@ -302,6 +302,8 @@ namespace gridfire {
[[nodiscard]] std::vector<double> mapNetInToMolarAbundanceVector(const NetIn &netIn) const override;
[[nodiscard]] PrimingReport primeEngine(const NetIn &netIn) override;
fourdst::composition::Composition collectComposition(fourdst::composition::Composition &comp) const override;
private:
using Config = fourdst::config::Config;
using LogManager = fourdst::logging::LogManager;
@@ -315,6 +317,7 @@ namespace gridfire {
/** @brief The set of species that are currently active in the network. */
std::vector<fourdst::atomic::Species> m_activeSpecies;
/** @brief The set of reactions that are currently active in the network. */
reaction::ReactionSet m_activeReactions;

View File

@@ -220,6 +220,8 @@ namespace gridfire{
[[nodiscard]] std::vector<double> mapNetInToMolarAbundanceVector(const NetIn &netIn) const override;
[[nodiscard]] PrimingReport primeEngine(const NetIn &netIn) override;
fourdst::composition::Composition collectComposition(fourdst::composition::Composition &comp) const override;
protected:
bool m_isStale = true;
GraphEngine& m_baseEngine;

View File

@@ -650,7 +650,7 @@ namespace gridfire {
* @brief Exports the network to a DOT file for visualization.
*
* @param filename The name of the DOT file to create.
* @param Y Vector of current molar abundances for the full network.
* @param comp Composition object
* @param T9 Temperature in units of 10^9 K.
* @param rho Density in g/cm^3.
*
@@ -663,7 +663,7 @@ namespace gridfire {
*/
void exportToDot(
const std::string& filename,
const fourdst::composition::Composition &Y,
const fourdst::composition::Composition &comp,
double T9,
double rho
) const;
@@ -784,6 +784,16 @@ namespace gridfire {
bool involvesSpeciesInDynamic(const fourdst::atomic::Species &species) const;
/**
* @brief Collect the composition from this and sub engines.
* @details This method operates by injecting the current equilibrium abundances for algebraic species into
* the composition object so that they can be bubbled up to the caller.
* @param comp Input Composition
* @return New composition which is comp + any edits from lower levels + the equilibrium abundances of all algebraic species.
* @throws BadCollectionError: if there is a species in the algebraic species set which does not show up in the reported composition from the base engine.:w
*/
fourdst::composition::Composition collectComposition(fourdst::composition::Composition &comp) const override;
private:
/**

View File

@@ -143,4 +143,12 @@ namespace gridfire::exceptions {
std::string m_message;
};
class BadCollectionError final : public EngineError {
public:
explicit BadCollectionError(std::string message): m_message(std::move(message)) {}
[[nodiscard]] const char* what() const noexcept override { return m_message.c_str(); }
private:
std::string m_message;
};
}

View File

@@ -14,11 +14,12 @@ namespace gridfire::solver {
* @struct SolverContextBase
* @brief Base class for solver callback contexts.
*
* This struct serves as a base class for contexts that can be passed to solver callbacks, it enforces
* This struct serves as a base class for contexts that can be papubl;ssed to solver callbacks, it enforces
* that derived classes implement a `describe` method that returns a vector of tuples describing
* the context that a callback will receive when called.
*/
struct SolverContextBase {
class SolverContextBase {
public:
virtual ~SolverContextBase() = default;
/**

View File

@@ -121,6 +121,19 @@ namespace gridfire::solver {
*/
NetOut evaluate(const NetIn& netIn) override;
/**
* @brief Call to evaluate which will let the user control if the trigger reasoning is displayed
* @param netIn Inputs: temperature [K], density [g cm^-3], tMax [s], composition.
* @param displayTrigger Boolean flag to control if trigger reasoning is displayed
* @return NetOut containing final Composition, accumulated energy [erg/g], step count,
* and dEps/dT, dEps/dRho.
* @throws std::runtime_error If any CVODE or SUNDIALS call fails (negative return codes),
* or if internal consistency checks fail during engine updates.
* @throws exceptions::StaleEngineTrigger Propagated if the engine signals a stale state
* during RHS evaluation (captured in the wrapper then rethrown here).
*/
NetOut evaluate(const NetIn& netIn, bool displayTrigger);
/**
* @brief Install a timestep callback.
* @param callback std::any containing TimestepCallback (std::function<void(const TimestepContext&)>).
@@ -135,8 +148,9 @@ namespace gridfire::solver {
/**
* @brief Enable/disable per-step stdout logging.
* @param logging_enabled Flag to control if a timestep summary is written to standard output or not
*/
void set_stdout_logging_enabled(const bool value);
void set_stdout_logging_enabled(bool logging_enabled);
/**
* @brief Schema of fields exposed to the timestep callback context.

View File

@@ -2,6 +2,8 @@
#include "fourdst/composition/composition.h"
#include "fourdst/composition/atomicSpecies.h"
#include <ranges>
namespace gridfire::utils {
inline double massFractionFromMolarAbundanceAndComposition (
const fourdst::composition::Composition& composition,
@@ -65,10 +67,14 @@ namespace gridfire::utils {
inline std::vector<double> molarMassVectorFromComposition(
const fourdst::composition::Composition& composition
) {
std::vector<double> molarMassVector;
molarMassVector.reserve(composition.getRegisteredSymbols().size());
std::map<fourdst::atomic::Species, double> molarMassMap;
for (const auto &entry: composition | std::views::values) {
molarMassVector.push_back(entry.isotope().mass());
molarMassMap.emplace(entry.isotope(), entry.isotope().mass());
}
std::vector<double> molarMassVector;
molarMassVector.reserve(molarMassMap.size());
for (const auto molarMass : molarMassMap | std::views::values) {
molarMassVector.push_back(molarMass);
}
return molarMassVector;
}