3#include "fourdst/composition/atomicSpecies.h"
4#include "fourdst/composition/composition.h"
5#include "fourdst/logging/logging.h"
6#include "fourdst/config/config.h"
17#include <unordered_map>
22#include <boost/numeric/ublas/matrix_sparse.hpp>
24#include "cppad/cppad.hpp"
25#include "cppad/utility/sparse_rc.hpp"
26#include "cppad/speed/sparse_jac_fun.hpp"
31#include "quill/LogMacros.h"
46 using fourdst::config::Config;
47 using fourdst::logging::LogManager;
48 using fourdst::constant::Constants;
113 const fourdst::composition::Composition &composition,
118 const fourdst::composition::Composition &composition,
147 const std::vector<double>& Y,
166 const std::vector<double>& Y_dynamic,
172 const std::vector<double> &Y_dynamic,
200 const std::vector<double>&Y,
209 [[nodiscard]]
const std::vector<fourdst::atomic::Species>&
getNetworkSpecies()
const override;
257 const int speciesIndex,
258 const int reactionIndex
273 const std::vector<double>& Y,
279 const std::vector<double>& Y,
284 fourdst::composition::Composition
update(
const NetIn &netIn)
override;
295 const fourdst::atomic::Species& species
315 const std::string& filename
335 const std::string& filename
356 const double forwardRate,
357 const double expFactor
363 const double reverseRate
371 const fourdst::atomic::Species& species
400 const double u = Constants::getInstance().get(
"u").value;
401 const double Na = Constants::getInstance().get(
"N_a").value;
402 const double c = Constants::getInstance().get(
"c").value;
403 const double kB = Constants::getInstance().get(
"kB").value;
412 atomic_base<double>(
"AtomicReverseRate"),
419 const CppAD::vector<bool>& vx,
420 CppAD::vector<bool>& vy,
421 const CppAD::vector<double>& tx,
422 CppAD::vector<double>& ty
426 const CppAD::vector<double>& tx,
427 const CppAD::vector<double>& ty,
428 CppAD::vector<double>& px,
429 const CppAD::vector<double>& py
433 const CppAD::vector<std::set<size_t>>&r,
434 CppAD::vector<std::set<size_t>>& s
438 const CppAD::vector<std::set<size_t>>&rt,
439 CppAD::vector<std::set<size_t>>& st
448 quill::Logger*
m_logger = LogManager::getInstance().getLogger(
"log");
552 const std::vector<double> &Y_in,
553 const std::vector<double>& bare_rates,
554 const std::vector<double> &bare_reverse_rates,
555 double T9,
double rho
571 template <IsArithmeticOrAD T>
574 const std::vector<T> &Y,
579 template<IsArithmeticOrAD T>
583 std::vector<T> screeningFactors,
585 size_t reactionIndex,
601 template<IsArithmeticOrAD T>
603 const std::vector<T> &Y_in,
621 const std::vector<double>& Y_in,
639 const std::vector<ADDouble>& Y_in,
647 template <IsArithmeticOrAD T>
651 std::vector<T> screeningFactors,
653 size_t reactionIndex,
657 return static_cast<T
>(0.0);
659 T reverseMolarFlow =
static_cast<T
>(0.0);
662 T reverseRateConstant =
static_cast<T
>(0.0);
663 if constexpr (std::is_same_v<T, ADDouble>) {
665 if (atomic_func_ptr !=
nullptr) {
668 std::vector<T> ax = { T9 };
670 std::vector<T> ay(1);
671 (*atomic_func_ptr)(ax, ay);
672 reverseRateConstant =
static_cast<T
>(ay[0]);
674 return reverseMolarFlow;
682 std::unordered_map<fourdst::atomic::Species, int> productCounts;
683 for (
const auto& product :
reaction.products()) {
684 productCounts[product]++;
688 T reverseSymmetryFactor =
static_cast<T
>(1.0);
689 for (
const auto &count: productCounts | std::views::values) {
690 reverseSymmetryFactor /=
static_cast<T
>(std::tgamma(
static_cast<double>(count + 1)));
694 T productAbundanceTerm =
static_cast<T
>(1.0);
695 for (
const auto& [species, count] : productCounts) {
697 productAbundanceTerm *= CppAD::pow(Y[speciesIndex], count);
701 const size_t num_products =
reaction.products().size();
702 const T rho_power = CppAD::pow(rho,
static_cast<T
>(num_products > 1 ? num_products - 1 : 0));
705 reverseMolarFlow = screeningFactors[reactionIndex] *
706 reverseRateConstant *
707 productAbundanceTerm *
708 reverseSymmetryFactor *
711 return reverseMolarFlow;
714 template<IsArithmeticOrAD T>
716 const std::vector<T> &Y_in, T T9, T rho)
const {
717 std::vector<T> screeningFactors =
m_screeningModel->calculateScreeningFactors(
731 const T zero =
static_cast<T
>(0.0);
732 const T one =
static_cast<T
>(1.0);
741 T threshold_flag = CppAD::CondExpLt(rho, rho_threshold, zero, one);
743 std::vector<T> Y = Y_in;
750 Y[i] = CppAD::CondExpLt(Y[i], zero, zero, Y[i]);
758 for (
size_t reactionIndex = 0; reactionIndex <
m_reactions.size(); ++reactionIndex) {
762 const T forwardMolarReactionFlow = screeningFactors[reactionIndex] *
775 const T molarReactionFlow = forwardMolarReactionFlow - reverseMolarFlow;
778 for (
size_t speciesIndex = 0; speciesIndex <
m_networkSpecies.size(); ++speciesIndex) {
780 result.
dydt[speciesIndex] += threshold_flag * nu_ij * molarReactionFlow;
784 T massProductionRate =
static_cast<T
>(0.0);
786 massProductionRate += result.
dydt[index] * species.mass() * u;
795 template <IsArithmeticOrAD T>
798 const std::vector<T> &Y,
805 const T zero =
static_cast<T
>(0.0);
808 const T k_reaction =
reaction.calculate_rate(T9);
811 std::unordered_map<std::string, int> reactant_counts;
812 reactant_counts.reserve(
reaction.reactants().size());
813 for (
const auto& reactant :
reaction.reactants()) {
814 reactant_counts[std::string(reactant.name())]++;
816 const int totalReactants =
static_cast<int>(
reaction.reactants().size());
819 auto molar_concentration_product =
static_cast<T
>(1.0);
822 for (
const auto& [species_name, count] : reactant_counts) {
826 const size_t species_index = species_it->second;
827 const T Yi = Y[species_index];
830 molar_concentration_product *= CppAD::pow(Yi,
static_cast<T
>(count));
834 molar_concentration_product /=
static_cast<T
>(std::tgamma(
static_cast<double>(count + 1)));
842 const T densityTerm = CppAD::pow(rho, totalReactants > 1 ?
static_cast<T
>(totalReactants - 1) : zero);
843 return molar_concentration_product * k_reaction * densityTerm;
Abstract class for engines supporting Jacobian and stoichiometry operations.
AtomicReverseRate(const reaction::Reaction &reaction, const GraphEngine &engine)
bool reverse(size_t q, const CppAD::vector< double > &tx, const CppAD::vector< double > &ty, CppAD::vector< double > &px, const CppAD::vector< double > &py) override
const GraphEngine & m_engine
bool rev_sparse_jac(size_t q, const CppAD::vector< std::set< size_t > > &rt, CppAD::vector< std::set< size_t > > &st) override
const reaction::Reaction & m_reaction
bool forward(size_t p, size_t q, const CppAD::vector< bool > &vx, CppAD::vector< bool > &vy, const CppAD::vector< double > &tx, CppAD::vector< double > &ty) override
bool for_sparse_jac(size_t q, const CppAD::vector< std::set< size_t > > &r, CppAD::vector< std::set< size_t > > &s) override
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
const std::vector< fourdst::atomic::Species > & getNetworkSpecies() const override
Gets the list of species in the network.
BuildDepthType getDepth() const override
T calculateReverseMolarReactionFlow(T T9, T rho, std::vector< T > screeningFactors, std::vector< T > Y, size_t reactionIndex, const reaction::LogicalReaction &reaction) const
bool m_usePrecomputation
Flag to enable or disable using precomputed reactions for efficiency. Mathematically,...
CppAD::sparse_rc< std::vector< size_t > > m_full_jacobian_sparsity_pattern
Full sparsity pattern for the Jacobian matrix.
CppAD::sparse_jac_work m_jac_work
Work object for sparse Jacobian calculations.
void populateReactionIDMap()
Populates the reaction ID map.
std::vector< double > mapNetInToMolarAbundanceVector(const NetIn &netIn) const override
void collectAtomicReverseRateAtomicBases()
CppAD::ADFun< double > m_rhsADFun
CppAD function for the right-hand side of the ODE.
boost::numeric::ublas::compressed_matrix< double > m_jacobianMatrix
Jacobian matrix (species x species).
double getJacobianMatrixEntry(const int i, const int j) const override
Gets an entry from the previously generated Jacobian matrix.
std::unordered_map< std::string_view, fourdst::atomic::Species > m_networkSpeciesMap
Map from species name to Species object.
bool m_useReverseReactions
Flag to enable or disable reverse reactions. If false, only forward reactions are considered.
std::unique_ptr< partition::PartitionFunction > m_partitionFunction
Partition function for the network.
void setNetworkReactions(const reaction::LogicalReactionSet &reactions) override
void setUseReverseReactions(bool useReverse)
void populateSpeciesToIndexMap()
Populates the species-to-index map.
screening::ScreeningType m_screeningType
Screening type for the reaction network. Default to no screening.
fourdst::composition::Composition update(const NetIn &netIn) override
Update the internal state of the engine.
std::vector< PrecomputedReaction > m_precomputedReactions
Precomputed reactions for efficiency.
std::unordered_map< std::string_view, reaction::Reaction * > m_reactionIDMap
Map from reaction ID to REACLIBReaction. //PERF: This makes copies of REACLIBReaction and could be a ...
std::expected< std::unordered_map< fourdst::atomic::Species, double >, expectations::StaleEngineError > getSpeciesTimescales(const std::vector< double > &Y, double T9, double rho) const override
Computes timescales for all species in the network.
screening::ScreeningType getScreeningModel() const override
Get the current electron screening model.
int getStoichiometryMatrixEntry(const int speciesIndex, const int reactionIndex) const override
Gets an entry from the stoichiometry matrix.
void setPrecomputation(bool precompute)
void setScreeningModel(screening::ScreeningType) override
Set the electron screening model.
std::vector< std::unique_ptr< AtomicReverseRate > > m_atomicReverseRates
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.
void reserveJacobianMatrix() const
Reserves space for the Jacobian matrix.
int getSpeciesIndex(const fourdst::atomic::Species &species) const override
double calculateMolarReactionFlow(const reaction::Reaction &reaction, const std::vector< double > &Y, const double T9, const double rho) const override
Calculates the molar reaction flow for a given reaction.
std::vector< fourdst::atomic::Species > m_networkSpecies
Vector of unique species in the network.
void recordADTape()
Records the AD tape for the right-hand side of the ODE.
StepDerivatives< double > calculateAllDerivativesUsingPrecomputation(const std::vector< double > &Y_in, const std::vector< double > &bare_rates, const std::vector< double > &bare_reverse_rates, double T9, double rho) const
bool involvesSpecies(const fourdst::atomic::Species &species) const
Checks if a given species is involved in the network.
std::expected< StepDerivatives< double >, expectations::StaleEngineError > calculateRHSAndEnergy(const std::vector< double > &Y, const double T9, const double rho) const override
Calculates the right-hand side (dY/dt) and energy generation rate.
reaction::LogicalReactionSet m_reactions
Set of REACLIB reactions in the network.
void syncInternalMaps()
Synchronizes the internal maps.
bool validateConservation() const
Validates mass and charge conservation across all reactions.
void generateJacobianMatrix(const std::vector< double > &Y_dynamic, const double T9, const double rho) const override
Generates the Jacobian matrix for the current state.
boost::numeric::ublas::compressed_matrix< int > m_stoichiometryMatrix
Stoichiometry matrix (species x reactions).
const reaction::LogicalReactionSet & getNetworkReactions() const override
Gets the set of logical reactions in the network.
std::unordered_map< fourdst::atomic::Species, size_t > m_speciesToIndexMap
Map from species to their index in the stoichiometry matrix.
void rebuild(const fourdst::composition::Composition &comp, const BuildDepthType depth) override
void exportToDot(const std::string &filename) const
Exports the network to a DOT file for visualization.
const partition::PartitionFunction & getPartitionFunction() const
bool isUsingReverseReactions() const
PrimingReport primeEngine(const NetIn &netIn) override
void generateStoichiometryMatrix() override
Generates the stoichiometry matrix for the network.
void collectNetworkSpecies()
Collects the unique species in the network.
std::expected< std::unordered_map< fourdst::atomic::Species, double >, expectations::StaleEngineError > getSpeciesDestructionTimescales(const std::vector< double > &Y, double T9, double rho) const override
bool isStale(const NetIn &netIn) override
std::unique_ptr< screening::ScreeningModel > m_screeningModel
double calculateReverseRateTwoBodyDerivative(const reaction::Reaction &reaction, const double T9, const double reverseRate) const
StepDerivatives< T > calculateAllDerivatives(const std::vector< T > &Y_in, T T9, T rho) const
Calculates all derivatives (dY/dt) and the energy generation rate.
GraphEngine(const fourdst::composition::Composition &composition, const BuildDepthType=NetworkBuildDepth::Full)
Constructs a GraphEngine from a composition.
Abstract interface for evaluating nuclear partition functions.
Represents a "logical" reaction that aggregates rates from multiple sources.
Represents a single nuclear reaction from a specific data source.
Abstract interfaces for reaction network engines in GridFire.
TemplatedReactionSet< LogicalReaction > LogicalReactionSet
A set of logical reactions.
std::unique_ptr< ScreeningModel > selectScreeningModel(ScreeningType type)
A factory function to select and create a screening model.
ScreeningType
Enumerates the available plasma screening models.
@ BARE
No screening applied. The screening factor is always 1.0.
CppAD::AD< double > ADDouble
Alias for CppAD AD type for double precision.
std::variant< NetworkBuildDepth, int > BuildDepthType
Variant specifying either a predefined NetworkBuildDepth or a custom integer depth.
std::vector< std::pair< size_t, size_t > > SparsityPattern
static constexpr double MIN_ABUNDANCE_THRESHOLD
Minimum abundance threshold below which species are ignored.
static constexpr double MIN_DENSITY_THRESHOLD
Minimum density threshold below which reactions are ignored.
static constexpr double MIN_JACOBIAN_THRESHOLD
Minimum value for Jacobian matrix entries.
Defines classes for representing and managing nuclear reactions.
std::vector< int > reactant_powers
std::vector< int > product_powers
Powers of each unique product in the reverse reaction.
std::vector< size_t > affected_species_indices
std::vector< size_t > unique_reactant_indices
double reverse_symmetry_factor
Symmetry factor for reverse reactions.
std::vector< int > stoichiometric_coefficients
std::vector< size_t > unique_product_indices
Unique product indices for reverse reactions.
const double kB
Boltzmann constant in erg/K.
const double u
Atomic mass unit in g.
const double Na
Avogadro's number.
const double c
Speed of light in cm/s.
Captures the result of a network priming operation.
Structure holding derivatives and energy generation for a network step.
T nuclearEnergyGenerationRate
Specific energy generation rate (e.g., erg/g/s).
std::vector< T > dydt
Derivatives of abundances (dY/dt for each species).