perf(thread saftey): All Engines are now thread safe

Previously engines were not thread safe, a seperate engine would be
needed for every thread. This is no longer the case. This allows for
much more efficient parallel execution
This commit is contained in:
2025-12-12 12:08:47 -05:00
parent c7574a2f3d
commit e114c0e240
46 changed files with 3685 additions and 1604 deletions

View File

@@ -6,9 +6,10 @@
#include "gridfire/screening/screening_types.h"
#include "gridfire/engine/types/reporting.h"
#include "gridfire/engine/types/building.h"
#include "gridfire/engine/types/jacobian.h"
#include "gridfire/engine/scratchpads/blob.h"
#include "fourdst/composition/composition_abstract.h"
#include <vector>
@@ -136,7 +137,9 @@ namespace gridfire::engine {
* @brief Get the list of species in the network.
* @return Vector of Species objects representing all network species.
*/
[[nodiscard]] virtual const std::vector<fourdst::atomic::Species>& getNetworkSpecies() const = 0;
[[nodiscard]] virtual const std::vector<fourdst::atomic::Species>& getNetworkSpecies(
scratch::StateBlob& ctx
) const = 0;
/**
* @brief Calculate the right-hand side (dY/dt) and energy generation.
@@ -153,6 +156,7 @@ namespace gridfire::engine {
* rate for the current state.
*/
[[nodiscard]] virtual std::expected<StepDerivatives<double>, EngineStatus> calculateRHSAndEnergy(
scratch::StateBlob&,
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho,
@@ -187,6 +191,7 @@ namespace gridfire::engine {
* for the current state. The matrix can then be accessed via getJacobianMatrixEntry().
*/
[[nodiscard]] virtual NetworkJacobian generateJacobianMatrix(
scratch::StateBlob& ctx,
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
@@ -205,6 +210,7 @@ namespace gridfire::engine {
* The matrix can then be accessed via getJacobianMatrixEntry().
*/
[[nodiscard]] virtual NetworkJacobian generateJacobianMatrix(
scratch::StateBlob& ctx,
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho,
@@ -228,6 +234,7 @@ namespace gridfire::engine {
* @see getJacobianMatrixEntry()
*/
[[nodiscard]] virtual NetworkJacobian generateJacobianMatrix(
scratch::StateBlob& ctx,
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho,
@@ -235,28 +242,6 @@ namespace gridfire::engine {
) const = 0;
/**
* @brief Generate the stoichiometry matrix for the network.
*
* This method must compute and store the stoichiometry matrix,
* which encodes the net change of each species in each reaction.
*/
virtual void generateStoichiometryMatrix() = 0;
/**
* @brief Get an entry from the stoichiometry matrix.
*
* @param species species to look up stoichiometry for.
* @param reaction reaction to find
* @return Stoichiometric coefficient for the species in the reaction.
*
* The stoichiometry matrix must have been generated by generateStoichiometryMatrix().
*/
[[nodiscard]] virtual int getStoichiometryMatrixEntry(
const fourdst::atomic::Species& species,
const reaction::Reaction& reaction
) const = 0;
/**
* @brief Calculate the molar reaction flow for a given reaction.
*
@@ -270,6 +255,7 @@ namespace gridfire::engine {
* under the current state.
*/
[[nodiscard]] virtual double calculateMolarReactionFlow(
scratch::StateBlob& ctx,
const reaction::Reaction& reaction,
const fourdst::composition::CompositionAbstract &comp,
double T9,
@@ -288,6 +274,7 @@ namespace gridfire::engine {
* generation rate with respect to temperature and density for the current state.
*/
[[nodiscard]] virtual EnergyDerivatives calculateEpsDerivatives(
scratch::StateBlob& ctx,
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
@@ -298,18 +285,10 @@ namespace gridfire::engine {
*
* @return Reference to the LogicalReactionSet containing all reactions.
*/
[[nodiscard]] virtual const reaction::ReactionSet& getNetworkReactions() const = 0;
[[nodiscard]] virtual const reaction::ReactionSet& getNetworkReactions(
scratch::StateBlob& ctx
) const = 0;
/**
* @brief Set the reactions for the network.
*
* @param reactions The set of reactions to use in the network.
*
* This method replaces the current set of reactions in the network
* with the provided set. It marks the engine as stale, requiring
* regeneration of matrices and recalculation of rates.
*/
virtual void setNetworkReactions(const reaction::ReactionSet& reactions) = 0;
/**
* @brief Compute timescales for all species in the network.
@@ -323,6 +302,7 @@ namespace gridfire::engine {
* which can be used for timestep control, diagnostics, and reaction network culling.
*/
[[nodiscard]] virtual std::expected<std::unordered_map<fourdst::atomic::Species, double>, EngineStatus> getSpeciesTimescales(
scratch::StateBlob& ctx,
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
@@ -340,13 +320,14 @@ namespace gridfire::engine {
* which can be useful for understanding reaction flows and equilibrium states.
*/
[[nodiscard]] virtual std::expected<std::unordered_map<fourdst::atomic::Species, double>, EngineStatus> getSpeciesDestructionTimescales(
scratch::StateBlob& ctx,
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
) const = 0;
/**
* @brief Update the internal state of the engine.
* @brief Update the thread local scratch pad state of a network.
*
* @param netIn A struct containing the current network input, such as
* temperature, density, and composition.
@@ -365,47 +346,10 @@ namespace gridfire::engine {
*
* @post The internal state of the engine is updated to reflect the new conditions.
*/
virtual fourdst::composition::Composition update(const NetIn &netIn) = 0;
/**
* @brief Check if the engine's internal state is stale.
*
* @param netIn A struct containing the current network input, such as
* temperature, density, and composition.
* @return True if the engine's state is stale and needs to be updated; false otherwise.
*
* This method allows derived classes to determine if their internal state
* is out-of-date with respect to the provided network conditions. If the engine
* is stale, it may require a call to `update()` before performing calculations.
*
* @par Usage Example:
* @code
* NetIn input = { ... };
* if (myEngine.isStale(input)) {
* // Update the engine before proceeding
* }
* @endcode
*/
[[nodiscard]]
virtual bool isStale(const NetIn& netIn) = 0;
/**
* @brief Set the electron screening model.
*
* @param model The type of screening model to use for reaction rate calculations.
*
* This method allows changing the screening model at runtime. Screening corrections
* account for the electrostatic shielding of nuclei by electrons, which affects
* reaction rates in dense stellar plasmas.
*
* @par Usage Example:
* @code
* myEngine.setScreeningModel(screening::ScreeningType::WEAK);
* @endcode
*
* @post The engine will use the specified screening model for subsequent rate calculations.
*/
virtual void setScreeningModel(screening::ScreeningType model) = 0;
[[nodiscard]] virtual fourdst::composition::Composition project(
scratch::StateBlob& ctx,
const NetIn &netIn
) const = 0;
/**
* @brief Get the current electron screening model.
@@ -417,7 +361,9 @@ namespace gridfire::engine {
* screening::ScreeningType currentModel = myEngine.getScreeningModel();
* @endcode
*/
[[nodiscard]] virtual screening::ScreeningType getScreeningModel() const = 0;
[[nodiscard]] virtual screening::ScreeningType getScreeningModel(
scratch::StateBlob& ctx
) const = 0;
/**
* @brief Get the index of a species in the network.
@@ -428,18 +374,10 @@ namespace gridfire::engine {
* engine's internal representation. It is useful for accessing species
* data efficiently.
*/
[[nodiscard]] virtual size_t getSpeciesIndex(const fourdst::atomic::Species &species) const = 0;
/**
* @brief Map a NetIn object to a vector of molar abundances.
*
* @param netIn The input conditions for the network.
* @return A vector of molar abundances corresponding to the species in the network.
*
* This method converts the input conditions into a vector of molar abundances,
* which can be used for further calculations or diagnostics.
*/
[[nodiscard]] virtual std::vector<double> mapNetInToMolarAbundanceVector(const NetIn &netIn) const = 0;
[[nodiscard]] virtual size_t getSpeciesIndex(
scratch::StateBlob& ctx,
const fourdst::atomic::Species &species
) const = 0;
/**
* @brief Prime the engine with initial conditions.
@@ -452,36 +390,10 @@ namespace gridfire::engine {
* rates, initializing internal data structures, and performing any necessary
* pre-computation.
*/
[[nodiscard]] virtual PrimingReport primeEngine(const NetIn &netIn) = 0;
/**
* @brief Get the depth of the network.
*
* @return The depth of the network, which may indicate the level of detail or
* complexity in the reaction network.
*
* This method is intended to provide information about the network's structure,
* such as how many layers of reactions or species are present. It can be useful
* for diagnostics and understanding the network's complexity.
*/
[[nodiscard]] virtual BuildDepthType getDepth() const {
throw std::logic_error("Network depth not supported by this engine.");
}
/**
* @brief Rebuild the network with a specified depth.
*
* @param comp The composition to rebuild the network with.
* @param depth The desired depth of the network.
*
* This method is intended to allow dynamic adjustment of the network's depth,
* which may involve adding or removing species and reactions based on the
* specified depth. However, not all engines support this operation.
*/
virtual void rebuild(const fourdst::composition::CompositionAbstract &comp, BuildDepthType depth) {
throw std::logic_error("Setting network depth not supported by this engine.");
// ReSharper disable once CppDFAUnreachableCode
}
[[nodiscard]] virtual PrimingReport primeEngine(
scratch::StateBlob& ctx,
const NetIn &netIn
) const = 0;
/**
* @brief Recursively collect composition from current engine and any sub engines if they exist.
@@ -497,7 +409,8 @@ namespace gridfire::engine {
* @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(
[[nodiscard]] virtual fourdst::composition::Composition collectComposition(
scratch::StateBlob& ctx,
const fourdst::composition::CompositionAbstract &comp,
double T9,
double rho
@@ -512,11 +425,14 @@ namespace gridfire::engine {
* This method allows querying the current status of a specific species
* within the engine's network.
*/
[[nodiscard]] virtual SpeciesStatus getSpeciesStatus(const fourdst::atomic::Species& species) const = 0;
[[nodiscard]] virtual SpeciesStatus getSpeciesStatus(
scratch::StateBlob& ctx,
const fourdst::atomic::Species& species
) const = 0;
[[nodiscard]] virtual std::optional<StepDerivatives<double>> getMostRecentRHSCalculation() const {
return std::nullopt;
}
[[nodiscard]] virtual std::optional<StepDerivatives<double>> getMostRecentRHSCalculation(
scratch::StateBlob& ctx
) const = 0;
};
}