GridFire 0.0.1a
General Purpose Nuclear Network
Loading...
Searching...
No Matches
bindings.cpp
Go to the documentation of this file.
1#include <pybind11/pybind11.h>
2#include <pybind11/stl.h> // Needed for vectors, maps, sets, strings
3#include <pybind11/stl_bind.h> // Needed for binding std::vector, std::map etc if needed directly
4
5#include <iostream>
6
7#include "bindings.h"
8
11
12
13
14namespace py = pybind11;
15
16namespace {
17 template <typename T>
18 concept IsDynamicEngine = std::is_base_of_v<gridfire::DynamicEngine, T>;
19
20 template <IsDynamicEngine T, IsDynamicEngine BaseT>
21 void registerDynamicEngineDefs(py::class_<T, BaseT> pyClass) {
22 pyClass.def("calculateRHSAndEnergy", &T::calculateRHSAndEnergy,
23 py::arg("Y"),
24 py::arg("T9"),
25 py::arg("rho"),
26 "Calculate the right-hand side (dY/dt) and energy generation rate."
27 )
28 .def("generateJacobianMatrix", py::overload_cast<const std::vector<double>&, double, double>(&T::generateJacobianMatrix, py::const_),
29 py::arg("Y_dynamic"),
30 py::arg("T9"),
31 py::arg("rho"),
32 "Generate the Jacobian matrix for the current state."
33 )
34 .def("generateStoichiometryMatrix", &T::generateStoichiometryMatrix)
35 .def("calculateMolarReactionFlow",
36 static_cast<double (T::*)(const gridfire::reaction::Reaction&, const std::vector<double>&, const double, const double) const>(&T::calculateMolarReactionFlow),
37 py::arg("reaction"),
38 py::arg("Y"),
39 py::arg("T9"),
40 py::arg("rho"),
41 "Calculate the molar reaction flow for a given reaction."
42 )
43 .def("getNetworkSpecies", &T::getNetworkSpecies,
44 "Get the list of species in the network."
45 )
46 .def("getNetworkReactions", &T::getNetworkReactions,
47 "Get the set of logical reactions in the network."
48 )
49 .def ("setNetworkReactions", &T::setNetworkReactions,
50 py::arg("reactions"),
51 "Set the network reactions to a new set of reactions."
52 )
53 .def("getJacobianMatrixEntry", &T::getJacobianMatrixEntry,
54 py::arg("i"),
55 py::arg("j"),
56 "Get an entry from the previously generated Jacobian matrix."
57 )
58 .def("getStoichiometryMatrixEntry", &T::getStoichiometryMatrixEntry,
59 py::arg("speciesIndex"),
60 py::arg("reactionIndex"),
61 "Get an entry from the stoichiometry matrix."
62 )
63 .def("getSpeciesTimescales", &T::getSpeciesTimescales,
64 py::arg("Y"),
65 py::arg("T9"),
66 py::arg("rho"),
67 "Get the timescales for each species in the network."
68 )
69 .def("getSpeciesDestructionTimescales", &T::getSpeciesDestructionTimescales,
70 py::arg("Y"),
71 py::arg("T9"),
72 py::arg("rho"),
73 "Get the destruction timescales for each species in the network."
74 )
75 .def("update", &T::update,
76 py::arg("netIn"),
77 "Update the engine state based on the provided NetIn object."
78 )
79 .def("setScreeningModel", &T::setScreeningModel,
80 py::arg("screeningModel"),
81 "Set the screening model for the engine."
82 )
83 .def("getScreeningModel", &T::getScreeningModel,
84 "Get the current screening model of the engine."
85 )
86 .def("getSpeciesIndex", &T::getSpeciesIndex,
87 py::arg("species"),
88 "Get the index of a species in the network."
89 )
90 .def("mapNetInToMolarAbundanceVector", &T::mapNetInToMolarAbundanceVector,
91 py::arg("netIn"),
92 "Map a NetIn object to a vector of molar abundances."
93 )
94 .def("primeEngine", &T::primeEngine,
95 py::arg("netIn"),
96 "Prime the engine with a NetIn object to prepare for calculations."
97 )
98 .def("getDepth", &T::getDepth,
99 "Get the current build depth of the engine."
100 )
101 .def("rebuild", &T::rebuild,
102 py::arg("composition"),
103 py::arg("depth") = gridfire::NetworkBuildDepth::Full,
104 "Rebuild the engine with a new composition and build depth."
105 )
106 .def("isStale", &T::isStale,
107 py::arg("netIn"),
108 "Check if the engine is stale based on the provided NetIn object."
109 );
110
111 }
112}
113
114void register_engine_bindings(py::module &m) {
117
118 m.def("build_reaclib_nuclear_network", &gridfire::build_reaclib_nuclear_network,
119 py::arg("composition"),
120 py::arg("maxLayers") = gridfire::NetworkBuildDepth::Full,
121 py::arg("reverse") = false,
122 "Build a nuclear network from a composition using ReacLib data."
123 );
124
125 py::enum_<gridfire::PrimingReportStatus>(m, "PrimingReportStatus")
126 .value("FULL_SUCCESS", gridfire::PrimingReportStatus::FULL_SUCCESS, "Priming was full successful.")
127 .value("NO_SPECIES_TO_PRIME", gridfire::PrimingReportStatus::NO_SPECIES_TO_PRIME, "No species to prime.")
128 .value("MAX_ITERATIONS_REACHED", gridfire::PrimingReportStatus::MAX_ITERATIONS_REACHED, "Maximum iterations reached during priming.")
129 .value("FAILED_TO_FINALIZE_COMPOSITION", gridfire::PrimingReportStatus::FAILED_TO_FINALIZE_COMPOSITION, "Failed to finalize the composition after priming.")
130 .value("FAILED_TO_FIND_CREATION_CHANNEL", gridfire::PrimingReportStatus::FAILED_TO_FIND_CREATION_CHANNEL, "Failed to find a creation channel for the priming species.")
131 .value("FAILED_TO_FIND_PRIMING_REACTIONS", gridfire::PrimingReportStatus::FAILED_TO_FIND_PRIMING_REACTIONS, "Failed to find priming reactions for the species.")
132 .value("BASE_NETWORK_TOO_SHALLOW", gridfire::PrimingReportStatus::BASE_NETWORK_TOO_SHALLOW, "The base network is too shallow for priming.")
133 .export_values()
134 .def("__repr__", [](const gridfire::PrimingReportStatus& status) {
135 std::stringstream ss;
136 ss << gridfire::PrimingReportStatusStrings.at(status) << "\n";
137 return ss.str();
138 },
139 "String representation of the PrimingReport."
140 );
141
142 py::class_<gridfire::PrimingReport>(m, "PrimingReport")
143 .def_readonly("success", &gridfire::PrimingReport::success, "Indicates if the priming was successful.")
144 .def_readonly("massFractionChanges", &gridfire::PrimingReport::massFractionChanges, "Map of species to their mass fraction changes after priming.")
145 .def_readonly("primedComposition", &gridfire::PrimingReport::primedComposition, "The composition after priming.")
146 .def_readonly("status", &gridfire::PrimingReport::status, "Status message from the priming process.")
147 .def("__repr__", [](const gridfire::PrimingReport& report) {
148 std::stringstream ss;
149 ss << report;
150 return ss.str();
151 }
152 );
153}
154
155void register_base_engine_bindings(pybind11::module &m) {
156
157 py::class_<gridfire::StepDerivatives<double>>(m, "StepDerivatives")
158 .def_readonly("dYdt", &gridfire::StepDerivatives<double>::dydt, "The right-hand side (dY/dt) of the ODE system.")
159 .def_readonly("energy", &gridfire::StepDerivatives<double>::nuclearEnergyGenerationRate, "The energy generation rate.");
160
161 py::class_<gridfire::SparsityPattern>(m, "SparsityPattern");
162
166}
167
168void abs_stype_register_engine_bindings(pybind11::module &m) {
169 py::class_<gridfire::Engine, PyEngine>(m, "Engine");
170}
171
173 const auto a = py::class_<gridfire::DynamicEngine, PyDynamicEngine>(m, "DynamicEngine");
174}
175
177 py::enum_<gridfire::NetworkBuildDepth>(m, "NetworkBuildDepth")
178 .value("Full", gridfire::NetworkBuildDepth::Full, "Full network build depth")
179 .value("Shallow", gridfire::NetworkBuildDepth::Shallow, "Shallow network build depth")
180 .value("SecondOrder", gridfire::NetworkBuildDepth::SecondOrder, "Second order network build depth")
181 .value("ThirdOrder", gridfire::NetworkBuildDepth::ThirdOrder, "Third order network build depth")
182 .value("FourthOrder", gridfire::NetworkBuildDepth::FourthOrder, "Fourth order network build depth")
183 .value("FifthOrder", gridfire::NetworkBuildDepth::FifthOrder, "Fifth order network build depth")
184 .export_values();
185
186 py::class_<gridfire::BuildDepthType>(m, "BuildDepthType");
187
188 auto py_dynamic_engine_bindings = py::class_<gridfire::GraphEngine, gridfire::DynamicEngine>(m, "GraphEngine");
189
190 // Register the Graph Engine Specific Bindings
191 py_dynamic_engine_bindings.def(py::init<const fourdst::composition::Composition &, const gridfire::BuildDepthType>(),
192 py::arg("composition"),
193 py::arg("depth") = gridfire::NetworkBuildDepth::Full,
194 "Initialize GraphEngine with a composition and build depth."
195 );
196 py_dynamic_engine_bindings.def(py::init<const fourdst::composition::Composition &, const gridfire::partition::PartitionFunction &, const gridfire::BuildDepthType>(),
197 py::arg("composition"),
198 py::arg("partitionFunction"),
199 py::arg("depth") = gridfire::NetworkBuildDepth::Full,
200 "Initialize GraphEngine with a composition, partition function and build depth."
201 );
202 py_dynamic_engine_bindings.def(py::init<const gridfire::reaction::LogicalReactionSet &>(),
203 py::arg("reactions"),
204 "Initialize GraphEngine with a set of reactions."
205 );
206 py_dynamic_engine_bindings.def("generateJacobianMatrix", py::overload_cast<const std::vector<double>&, double, double, const gridfire::SparsityPattern&>(&gridfire::GraphEngine::generateJacobianMatrix, py::const_),
207 py::arg("Y_dynamic"),
208 py::arg("T9"),
209 py::arg("rho"),
210 py::arg("sparsityPattern"),
211 "Generate the Jacobian matrix for the current state with a specified sparsity pattern."
212 );
213 py_dynamic_engine_bindings.def_static("getNetReactionStoichiometry", &gridfire::GraphEngine::getNetReactionStoichiometry,
214 py::arg("reaction"),
215 "Get the net stoichiometry for a given reaction."
216 );
217 py_dynamic_engine_bindings.def("involvesSpecies", &gridfire::GraphEngine::involvesSpecies,
218 py::arg("species"),
219 "Check if a given species is involved in the network."
220 );
221 py_dynamic_engine_bindings.def("exportToDot", &gridfire::GraphEngine::exportToDot,
222 py::arg("filename"),
223 "Export the network to a DOT file for visualization."
224 );
225 py_dynamic_engine_bindings.def("exportToCSV", &gridfire::GraphEngine::exportToCSV,
226 py::arg("filename"),
227 "Export the network to a CSV file for analysis."
228 );
229 py_dynamic_engine_bindings.def("setPrecomputation", &gridfire::GraphEngine::setPrecomputation,
230 py::arg("precompute"),
231 "Enable or disable precomputation for the engine."
232 );
233 py_dynamic_engine_bindings.def("isPrecomputationEnabled", &gridfire::GraphEngine::isPrecomputationEnabled,
234 "Check if precomputation is enabled for the engine."
235 );
236 py_dynamic_engine_bindings.def("getPartitionFunction", &gridfire::GraphEngine::getPartitionFunction,
237 "Get the partition function used by the engine."
238 );
239 py_dynamic_engine_bindings.def("calculateReverseRate", &gridfire::GraphEngine::calculateReverseRate,
240 py::arg("reaction"),
241 py::arg("T9"),
242 "Calculate the reverse rate for a given reaction at a specific temperature."
243 );
244 py_dynamic_engine_bindings.def("calculateReverseRateTwoBody", &gridfire::GraphEngine::calculateReverseRateTwoBody,
245 py::arg("reaction"),
246 py::arg("T9"),
247 py::arg("forwardRate"),
248 py::arg("expFactor"),
249 "Calculate the reverse rate for a two-body reaction at a specific temperature."
250 );
251 py_dynamic_engine_bindings.def("calculateReverseRateTwoBodyDerivative", &gridfire::GraphEngine::calculateReverseRateTwoBodyDerivative,
252 py::arg("reaction"),
253 py::arg("T9"),
254 py::arg("reverseRate"),
255 "Calculate the derivative of the reverse rate for a two-body reaction at a specific temperature."
256 );
257 py_dynamic_engine_bindings.def("isUsingReverseReactions", &gridfire::GraphEngine::isUsingReverseReactions,
258 "Check if the engine is using reverse reactions."
259 );
260 py_dynamic_engine_bindings.def("setUseReverseReactions", &gridfire::GraphEngine::setUseReverseReactions,
261 py::arg("useReverse"),
262 "Enable or disable the use of reverse reactions in the engine."
263 );
264
265
266 // Register the general dynamic engine bindings
267 registerDynamicEngineDefs<gridfire::GraphEngine, gridfire::DynamicEngine>(py_dynamic_engine_bindings);
268}
269
270void register_engine_view_bindings(pybind11::module &m) {
271 auto py_defined_engine_view_bindings = py::class_<gridfire::DefinedEngineView, gridfire::DynamicEngine>(m, "DefinedEngineView");
272
273 py_defined_engine_view_bindings.def(py::init<std::vector<std::string>, gridfire::DynamicEngine&>(),
274 py::arg("peNames"),
275 py::arg("baseEngine"),
276 "Construct a defined engine view with a list of tracked reactions and a base engine.");
277 py_defined_engine_view_bindings.def("getBaseEngine", &gridfire::DefinedEngineView::getBaseEngine,
278 "Get the base engine associated with this defined engine view.");
279
280 registerDynamicEngineDefs<gridfire::DefinedEngineView, gridfire::DynamicEngine>(py_defined_engine_view_bindings);
281
282 auto py_file_defined_engine_view_bindings = py::class_<gridfire::FileDefinedEngineView, gridfire::DefinedEngineView>(m, "FileDefinedEngineView");
283 py_file_defined_engine_view_bindings.def(py::init<gridfire::DynamicEngine&, const std::string&, const gridfire::io::NetworkFileParser&>(),
284 py::arg("baseEngine"),
285 py::arg("fileName"),
286 py::arg("parser"),
287 "Construct a defined engine view from a file and a base engine."
288 );
289 py_file_defined_engine_view_bindings.def("getNetworkFile", &gridfire::FileDefinedEngineView::getNetworkFile,
290 "Get the network file associated with this defined engine view."
291 );
292 py_file_defined_engine_view_bindings.def("getParser", &gridfire::FileDefinedEngineView::getParser,
293 "Get the parser used for this defined engine view."
294 );
295 py_file_defined_engine_view_bindings.def("getBaseEngine", &gridfire::FileDefinedEngineView::getBaseEngine,
296 "Get the base engine associated with this file defined engine view.");
297
298 registerDynamicEngineDefs<gridfire::FileDefinedEngineView, gridfire::DefinedEngineView>(py_file_defined_engine_view_bindings);
299
300 auto py_priming_engine_view_bindings = py::class_<gridfire::NetworkPrimingEngineView, gridfire::DefinedEngineView>(m, "NetworkPrimingEngineView");
301 py_priming_engine_view_bindings.def(py::init<const std::string&, gridfire::DynamicEngine&>(),
302 py::arg("primingSymbol"),
303 py::arg("baseEngine"),
304 "Construct a priming engine view with a priming symbol and a base engine.");
305 py_priming_engine_view_bindings.def(py::init<const fourdst::atomic::Species&, gridfire::DynamicEngine&>(),
306 py::arg("primingSpecies"),
307 py::arg("baseEngine"),
308 "Construct a priming engine view with a priming species and a base engine.");
309 py_priming_engine_view_bindings.def("getBaseEngine", &gridfire::NetworkPrimingEngineView::getBaseEngine,
310 "Get the base engine associated with this priming engine view.");
311
312 registerDynamicEngineDefs<gridfire::NetworkPrimingEngineView, gridfire::DefinedEngineView>(py_priming_engine_view_bindings);
313
314 auto py_adaptive_engine_view_bindings = py::class_<gridfire::AdaptiveEngineView, gridfire::DynamicEngine>(m, "AdaptiveEngineView");
315 py_adaptive_engine_view_bindings.def(py::init<gridfire::DynamicEngine&>(),
316 py::arg("baseEngine"),
317 "Construct an adaptive engine view with a base engine.");
318 py_adaptive_engine_view_bindings.def("getBaseEngine", &gridfire::AdaptiveEngineView::getBaseEngine,
319 "Get the base engine associated with this adaptive engine view.");
320
321 registerDynamicEngineDefs<gridfire::AdaptiveEngineView, gridfire::DynamicEngine>(py_adaptive_engine_view_bindings);
322
323 auto py_qse_cache_config = py::class_<gridfire::QSECacheConfig>(m, "QSECacheConfig");
324 auto py_qse_cache_key = py::class_<gridfire::QSECacheKey>(m, "QSECacheKey");
325
326 py_qse_cache_key.def(py::init<double, double, const std::vector<double>&>(),
327 py::arg("T9"),
328 py::arg("rho"),
329 py::arg("Y")
330 );
331
332 py_qse_cache_key.def("hash", &gridfire::QSECacheKey::hash,
333 "Get the pre-computed hash value of the key");
334
335 py_qse_cache_key.def_static("bin", &gridfire::QSECacheKey::bin,
336 py::arg("value"),
337 py::arg("tol"),
338 "bin a value based on a tolerance");
339 py_qse_cache_key.def("__eq__", &gridfire::QSECacheKey::operator==,
340 py::arg("other"),
341 "Check if two QSECacheKeys are equal");
342
343 auto py_multiscale_engine_view_bindings = py::class_<gridfire::MultiscalePartitioningEngineView, gridfire::DynamicEngine>(m, "MultiscalePartitioningEngineView");
344 py_multiscale_engine_view_bindings.def(py::init<gridfire::GraphEngine&>(),
345 py::arg("baseEngine"),
346 "Construct a multiscale partitioning engine view with a base engine.");
347 py_multiscale_engine_view_bindings.def("getBaseEngine", &gridfire::MultiscalePartitioningEngineView::getBaseEngine,
348 "Get the base engine associated with this multiscale partitioning engine view.");
349 py_multiscale_engine_view_bindings.def("analyzeTimescalePoolConnectivity", &gridfire::MultiscalePartitioningEngineView::analyzeTimescalePoolConnectivity,
350 py::arg("timescale_pools"),
351 py::arg("Y"),
352 py::arg("T9"),
353 py::arg("rho"),
354 "Analyze the connectivity of timescale pools in the network.");
355 py_multiscale_engine_view_bindings.def("partitionNetwork", py::overload_cast<const std::vector<double>&, double, double>(&gridfire::MultiscalePartitioningEngineView::partitionNetwork),
356 py::arg("Y"),
357 py::arg("T9"),
358 py::arg("rho"),
359 "Partition the network based on species timescales and connectivity.");
360 py_multiscale_engine_view_bindings.def("partitionNetwork", py::overload_cast<const gridfire::NetIn&>(&gridfire::MultiscalePartitioningEngineView::partitionNetwork),
361 py::arg("netIn"),
362 "Partition the network based on a NetIn object.");
363 py_multiscale_engine_view_bindings.def("exportToDot", &gridfire::MultiscalePartitioningEngineView::exportToDot,
364 py::arg("filename"),
365 py::arg("Y"),
366 py::arg("T9"),
367 py::arg("rho"),
368 "Export the network to a DOT file for visualization.");
369 py_multiscale_engine_view_bindings.def("getFastSpecies", &gridfire::MultiscalePartitioningEngineView::getFastSpecies,
370 "Get the list of fast species in the network.");
371 py_multiscale_engine_view_bindings.def("getDynamicSpecies", &gridfire::MultiscalePartitioningEngineView::getDynamicSpecies,
372 "Get the list of dynamic species in the network.");
373 py_multiscale_engine_view_bindings.def("equilibrateNetwork", py::overload_cast<const std::vector<double>&, double, double>(&gridfire::MultiscalePartitioningEngineView::equilibrateNetwork),
374 py::arg("Y"),
375 py::arg("T9"),
376 py::arg("rho"),
377 "Equilibrate the network based on species abundances and conditions.");
378 py_multiscale_engine_view_bindings.def("equilibrateNetwork", py::overload_cast<const gridfire::NetIn&>(&gridfire::MultiscalePartitioningEngineView::equilibrateNetwork),
379 py::arg("netIn"),
380 "Equilibrate the network based on a NetIn object.");
381
382 registerDynamicEngineDefs<gridfire::MultiscalePartitioningEngineView, gridfire::DynamicEngine>(py_multiscale_engine_view_bindings);
383}
384
385
386
387
388
389
390
391
const DynamicEngine & getBaseEngine() const override
Gets the base engine.
const DynamicEngine & getBaseEngine() const override
Access the underlying engine instance.
Abstract class for engines supporting Jacobian and stoichiometry operations.
std::string getNetworkFile() const
const io::NetworkFileParser & getParser() const
bool isPrecomputationEnabled() const
double calculateReverseRateTwoBody(const reaction::Reaction &reaction, const double T9, const double forwardRate, const double expFactor) const
double calculateReverseRate(const reaction::Reaction &reaction, double T9) const
void setUseReverseReactions(bool useReverse)
void setPrecomputation(bool precompute)
void exportToCSV(const std::string &filename) const
Exports the network to a CSV file for analysis.
static std::unordered_map< fourdst::atomic::Species, int > getNetReactionStoichiometry(const reaction::Reaction &reaction)
Gets the net stoichiometry for a given reaction.
bool involvesSpecies(const fourdst::atomic::Species &species) const
Checks if a given species is involved in the network.
void generateJacobianMatrix(const std::vector< double > &Y_dynamic, const double T9, const double rho) const override
Generates the Jacobian matrix for the current state.
void exportToDot(const std::string &filename) const
Exports the network to a DOT file for visualization.
const partition::PartitionFunction & getPartitionFunction() const
bool isUsingReverseReactions() const
double calculateReverseRateTwoBodyDerivative(const reaction::Reaction &reaction, const double T9, const double reverseRate) const
const std::vector< fourdst::atomic::Species > & getDynamicSpecies() const
Gets the dynamic species in the network.
const DynamicEngine & getBaseEngine() const override
Gets the base engine.
std::vector< fourdst::atomic::Species > getFastSpecies() const
Gets the fast species in the network.
fourdst::composition::Composition equilibrateNetwork(const std::vector< double > &Y, double T9, double rho)
Equilibrates the network by partitioning and solving for QSE abundances.
void partitionNetwork(const std::vector< double > &Y, double T9, double rho)
Partitions the network into dynamic and algebraic (QSE) groups based on timescales.
void exportToDot(const std::string &filename, const std::vector< double > &Y, const double T9, const double rho) const
Exports the network to a DOT file for visualization.
std::vector< std::vector< size_t > > analyzeTimescalePoolConnectivity(const std::vector< std::vector< size_t > > &timescale_pools, const std::vector< double > &Y, double T9, double rho) const
Analyzes the connectivity of timescale pools.
Represents a single nuclear reaction from a specific data source.
Definition reaction.h:72
void abs_stype_register_engine_bindings(pybind11::module &m)
Definition bindings.cpp:168
void abs_stype_register_dynamic_engine_bindings(pybind11::module &m)
Definition bindings.cpp:172
void con_stype_register_graph_engine_bindings(pybind11::module &m)
Definition bindings.cpp:176
void register_engine_view_bindings(pybind11::module &m)
Definition bindings.cpp:270
void register_base_engine_bindings(pybind11::module &m)
Definition bindings.cpp:155
void register_engine_bindings(py::module &m)
Definition bindings.cpp:114
Core header for the GridFire reaction network engine module.
std::map< PrimingReportStatus, std::string > PrimingReportStatusStrings
Mapping from PrimingReportStatus codes to human-readable strings.
Definition reporting.h:47
std::vector< std::pair< size_t, size_t > > SparsityPattern
PrimingReportStatus
Enumerates outcome codes for a network priming operation.
Definition reporting.h:31
reaction::LogicalReactionSet build_reaclib_nuclear_network(const fourdst::composition::Composition &composition, BuildDepthType maxLayers=NetworkBuildDepth::Full, bool reverse=false)
Builds a nuclear reaction network from the Reaclib library based on an initial composition.
Captures the result of a network priming operation.
Definition reporting.h:67
fourdst::composition::Composition primedComposition
Definition reporting.h:69
std::vector< std::pair< fourdst::atomic::Species, double > > massFractionChanges
Definition reporting.h:74
PrimingReportStatus status
Definition reporting.h:78
size_t hash() const
Computes the hash value for this key.
static long bin(double value, double tol)
Converts a value to a discrete bin based on a tolerance.
T nuclearEnergyGenerationRate
Specific energy generation rate (e.g., erg/g/s).
std::vector< T > dydt
Derivatives of abundances (dY/dt for each species).