GridFire 0.0.1a
General Purpose Nuclear Network
Loading...
Searching...
No Matches
reaction.cpp
Go to the documentation of this file.
2
3#include<string_view>
4#include<string>
5#include<vector>
6#include<unordered_set>
7#include<algorithm>
8#include <ranges>
9
10#include "quill/LogMacros.h"
11
12#include "fourdst/composition/atomicSpecies.h"
13
14#include "xxhash64.h"
15
16namespace gridfire::reaction {
17 using namespace fourdst::atomic;
18
20 const std::string_view id,
21 const std::string_view peName,
22 const int chapter,
23 const std::vector<Species>& reactants,
24 const std::vector<Species>& products,
25 const double qValue,
26 const std::string_view label,
27 const RateCoefficientSet& sets,
28 const bool reverse) :
29 m_id(id),
35 m_sourceLabel(label),
37 m_reverse(reverse) {}
38
39 double Reaction::calculate_rate(const double T9) const {
40 return calculate_rate<double>(T9);
41 }
42
43 CppAD::AD<double> Reaction::calculate_rate(const CppAD::AD<double> T9) const {
45 }
46
47 bool Reaction::contains(const Species &species) const {
48 return contains_reactant(species) || contains_product(species);
49 }
50
51
52 bool Reaction::contains_reactant(const Species& species) const {
53 for (const auto& reactant : m_reactants) {
54 if (reactant == species) {
55 return true;
56 }
57 }
58 return false;
59 }
60
61 bool Reaction::contains_product(const Species& species) const {
62 for (const auto& product : m_products) {
63 if (product == species) {
64 return true;
65 }
66 }
67 return false;
68 }
69
70 std::unordered_set<Species> Reaction::all_species() const {
71 auto rs = reactant_species();
72 auto ps = product_species();
73 rs.insert(ps.begin(), ps.end());
74 return rs;
75 }
76
77 std::unordered_set<Species> Reaction::reactant_species() const {
78 std::unordered_set<Species> reactantsSet;
79 for (const auto& reactant : m_reactants) {
80 reactantsSet.insert(reactant);
81 }
82 return reactantsSet;
83 }
84
85 std::unordered_set<Species> Reaction::product_species() const {
86 std::unordered_set<Species> productsSet;
87 for (const auto& product : m_products) {
88 productsSet.insert(product);
89 }
90 return productsSet;
91 }
92
93 int Reaction::stoichiometry(const Species& species) const {
94 int s = 0;
95 for (const auto& reactant : m_reactants) {
96 if (reactant == species) {
97 s--;
98 }
99 }
100 for (const auto& product : m_products) {
101 if (product == species) {
102 s++;
103 }
104 }
105 return s;
106 }
107
108 size_t Reaction::num_species() const {
109 return all_species().size();
110 }
111
112 std::unordered_map<Species, int> Reaction::stoichiometry() const {
113 std::unordered_map<Species, int> stoichiometryMap;
114 for (const auto& reactant : m_reactants) {
115 stoichiometryMap[reactant]--;
116 }
117 for (const auto& product : m_products) {
118 stoichiometryMap[product]++;
119 }
120 return stoichiometryMap;
121 }
122
123 double Reaction::excess_energy() const {
124 double reactantMass = 0.0;
125 double productMass = 0.0;
126 constexpr double AMU2MeV = 931.494893; // Conversion factor from atomic mass unit to MeV
127 for (const auto& reactant : m_reactants) {
128 reactantMass += reactant.mass();
129 }
130 for (const auto& product : m_products) {
131 productMass += product.mass();
132 }
133 return (reactantMass - productMass) * AMU2MeV;
134 }
135
136 uint64_t Reaction::hash(uint64_t seed) const {
137 return XXHash64::hash(m_id.data(), m_id.size(), seed);
138 }
139
141 std::vector<Reaction> reactions
142 ) :
143 m_reactions(std::move(reactions)) {
144 if (m_reactions.empty()) {
145 return; // Case where the reactions will be added later.
146 }
147 m_reactionNameMap.reserve(reactions.size());
148 for (const auto& reaction : m_reactions) {
149 m_id += reaction.id();
150 m_reactionNameMap.emplace(reaction.id(), reaction);
151 }
152 }
153
155 m_reactions.reserve(other.m_reactions.size());
156 for (const auto& reaction_ptr: other.m_reactions) {
157 m_reactions.push_back(reaction_ptr);
158 }
159
160 m_reactionNameMap.reserve(other.m_reactionNameMap.size());
161 for (const auto& reaction_ptr : m_reactions) {
162 m_reactionNameMap.emplace(reaction_ptr.id(), reaction_ptr);
163 }
164 }
165
167 if (this != &other) {
168 ReactionSet temp(other);
169 std::swap(m_reactions, temp.m_reactions);
170 std::swap(m_reactionNameMap, temp.m_reactionNameMap);
171 }
172 return *this;
173 }
174
176 m_reactions.emplace_back(reaction);
177 m_id += m_reactions.back().id();
178 m_reactionNameMap.emplace(m_reactions.back().id(), m_reactions.back());
179 }
180
182 if (!m_reactionNameMap.contains(std::string(reaction.id()))) {
183 return;
184 }
185
186 m_reactionNameMap.erase(std::string(reaction.id()));
187
188 std::erase_if(m_reactions, [&reaction](const Reaction& r) {
189 return r == reaction;
190 });
191 }
192
193 bool ReactionSet::contains(const std::string_view& id) const {
194 for (const auto& reaction : m_reactions) {
195 if (reaction.id() == id) {
196 return true;
197 }
198 }
199 return false;
200 }
201
203 for (const auto& r : m_reactions) {
204 if (r == reaction) {
205 return true;
206 }
207 }
208 return false;
209 }
210
212 m_reactions.clear();
213 m_reactionNameMap.clear();
214 }
215
216 bool ReactionSet::contains_species(const Species& species) const {
217 for (const auto& reaction : m_reactions) {
218 if (reaction.contains(species)) {
219 return true;
220 }
221 }
222 return false;
223 }
224
225 bool ReactionSet::contains_reactant(const Species& species) const {
226 for (const auto& r : m_reactions) {
227 if (r.contains_reactant(species)) {
228 return true;
229 }
230 }
231 return false;
232 }
233
234 bool ReactionSet::contains_product(const Species& species) const {
235 for (const auto& r : m_reactions) {
236 if (r.contains_product(species)) {
237 return true;
238 }
239 }
240 return false;
241 }
242
243 const Reaction& ReactionSet::operator[](const size_t index) const {
244 if (index >= m_reactions.size()) {
245 m_logger -> flush_log();
246 throw std::out_of_range("Index" + std::to_string(index) + " out of range for ReactionSet of size " + std::to_string(m_reactions.size()) + ".");
247 }
248 return m_reactions[index];
249 }
250
251 const Reaction& ReactionSet::operator[](const std::string_view& id) const {
252 if (auto it = m_reactionNameMap.find(std::string(id)); it != m_reactionNameMap.end()) {
253 return it->second;
254 }
255 m_logger -> flush_log();
256 throw std::out_of_range("Species " + std::string(id) + " does not exist in ReactionSet.");
257 }
258
259 bool ReactionSet::operator==(const ReactionSet& other) const {
260 if (size() != other.size()) {
261 return false;
262 }
263 return hash() == other.hash();
264 }
265
266 bool ReactionSet::operator!=(const ReactionSet& other) const {
267 return !(*this == other);
268 }
269
270 uint64_t ReactionSet::hash(uint64_t seed) const {
271 if (m_reactions.empty()) {
272 return XXHash64::hash(nullptr, 0, seed);
273 }
274 std::vector<uint64_t> individualReactionHashes;
275 individualReactionHashes.reserve(m_reactions.size());
276 for (const auto& reaction : m_reactions) {
277 individualReactionHashes.push_back(reaction.hash(seed));
278 }
279
280 std::ranges::sort(individualReactionHashes);
281
282 const void* data = static_cast<const void*>(individualReactionHashes.data());
283 size_t sizeInBytes = individualReactionHashes.size() * sizeof(uint64_t);
284 return XXHash64::hash(data, sizeInBytes, seed);
285 }
286
287
288 LogicalReaction::LogicalReaction(const std::vector<Reaction>& reactants) :
289 Reaction(reactants.front().peName(),
290 reactants.front().peName(),
291 reactants.front().chapter(),
292 reactants.front().reactants(),
293 reactants.front().products(),
294 reactants.front().qValue(),
295 reactants.front().sourceLabel(),
296 reactants.front().rateCoefficients(),
297 reactants.front().is_reverse()) {
298
299 m_sources.reserve(reactants.size());
300 m_rates.reserve(reactants.size());
301 for (const auto& reaction : reactants) {
302 if (std::abs(std::abs(reaction.qValue()) - std::abs(m_qValue)) > 1e-6) {
303 LOG_ERROR(
304 m_logger,
305 "LogicalReaction constructed with reactions having different Q-values. Expected {} got {}.",
306 m_qValue,
307 reaction.qValue()
308 );
309 m_logger -> flush_log();
310 throw std::runtime_error("LogicalReaction constructed with reactions having different Q-values. Expected " + std::to_string(m_qValue) + " got " + std::to_string(reaction.qValue()) + " (difference : " + std::to_string(std::abs(reaction.qValue() - m_qValue)) + ").");
311 }
312 m_sources.push_back(std::string(reaction.sourceLabel()));
313 m_rates.push_back(reaction.rateCoefficients());
314 }
315 }
316
318 if (reaction.peName() != m_id) {
319 LOG_ERROR(m_logger, "Cannot add reaction with different peName to LogicalReaction. Expected {} got {}.", m_id, reaction.peName());
320 m_logger -> flush_log();
321 throw std::runtime_error("Cannot add reaction with different peName to LogicalReaction. Expected " + std::string(m_id) + " got " + std::string(reaction.peName()) + ".");
322 }
323 for (const auto& source : m_sources) {
324 if (source == reaction.sourceLabel()) {
325 LOG_ERROR(m_logger, "Cannot add reaction with duplicate source label {} to LogicalReaction.", reaction.sourceLabel());
326 m_logger -> flush_log();
327 throw std::runtime_error("Cannot add reaction with duplicate source label " + std::string(reaction.sourceLabel()) + " to LogicalReaction.");
328 }
329 }
330 if (std::abs(reaction.qValue() - m_qValue) > 1e-6) {
331 LOG_ERROR(m_logger, "LogicalReaction constructed with reactions having different Q-values. Expected {} got {}.", m_qValue, reaction.qValue());
332 m_logger -> flush_log();
333 throw std::runtime_error("LogicalReaction constructed with reactions having different Q-values. Expected " + std::to_string(m_qValue) + " got " + std::to_string(reaction.qValue()) + ".");
334 }
335 m_sources.push_back(std::string(reaction.sourceLabel()));
336 m_rates.push_back(reaction.rateCoefficients());
337 }
338
339 double LogicalReaction::calculate_rate(const double T9) const {
340 return calculate_rate<double>(T9);
341 }
342
343 CppAD::AD<double> LogicalReaction::calculate_rate(const CppAD::AD<double> T9) const {
345 }
346
348 ReactionSet(std::vector<Reaction>()) {
349
350 std::unordered_map<std::string_view, std::vector<Reaction>> grouped_reactions;
351
352 for (const auto& reaction : reactionSet) {
353 grouped_reactions[reaction.peName()].push_back(reaction);
354 }
355 m_reactions.reserve(grouped_reactions.size());
356 m_reactionNameMap.reserve(grouped_reactions.size());
357 for (const auto &reactions_for_peName: grouped_reactions | std::views::values) {
358 LogicalReaction logical_reaction(reactions_for_peName);
359 m_reactionNameMap.emplace(logical_reaction.id(), logical_reaction);
360 m_reactions.push_back(std::move(logical_reaction));
361 }
362 }
363}
364
365namespace std {
366 template<>
367 struct hash<gridfire::reaction::Reaction> {
368 size_t operator()(const gridfire::reaction::Reaction& r) const noexcept {
369 return r.hash(0);
370 }
371 };
372
373 template<>
374 struct hash<gridfire::reaction::ReactionSet> {
375 size_t operator()(const gridfire::reaction::ReactionSet& s) const noexcept {
376 return s.hash(0);
377 }
378 };
379} // namespace std
Represents a "logical" reaction that aggregates rates from multiple sources.
Definition reaction.h:459
void add_reaction(const Reaction &reaction)
Adds another Reaction source to this logical reaction.
Definition reaction.cpp:317
double calculate_rate(const double T9) const override
Calculates the total reaction rate by summing all source rates.
Definition reaction.cpp:339
LogicalReaction(const std::vector< Reaction > &reactions)
Constructs a LogicalReaction from a vector of Reaction objects.
Definition reaction.cpp:288
std::vector< std::string > m_sources
List of source labels.
Definition reaction.h:513
std::vector< RateCoefficientSet > m_rates
List of rate coefficient sets from each source.
Definition reaction.h:514
std::vector< LogicalReaction > m_reactions
Definition reaction.h:593
std::unordered_map< std::string, LogicalReaction > m_reactionNameMap
Maps reaction IDs to LogicalReaction objects for quick lookup.
Definition reaction.h:595
LogicalReactionSet()=delete
Deleted default constructor.
Represents a single nuclear reaction from a specific data source.
Definition reaction.h:71
std::string m_sourceLabel
Source label for the rate data (e.g., "wc12w", "st08").
Definition reaction.h:263
std::unordered_set< fourdst::atomic::Species > product_species() const
Gets a set of all unique product species.
Definition reaction.cpp:85
bool contains_product(const fourdst::atomic::Species &species) const
Checks if the reaction involves a given species as a product.
Definition reaction.cpp:61
std::string_view id() const
Gets the unique identifier of the reaction.
Definition reaction.h:201
bool m_reverse
Flag indicating if this is a reverse reaction rate.
Definition reaction.h:265
const std::vector< fourdst::atomic::Species > & reactants() const
Gets the vector of reactant species.
Definition reaction.h:213
int m_chapter
Chapter number from the REACLIB database, defining the reaction structure.
Definition reaction.h:259
size_t num_species() const
Gets the number of unique species involved in the reaction.
Definition reaction.cpp:108
std::string_view sourceLabel() const
Gets the source label for the rate data.
Definition reaction.h:131
std::vector< fourdst::atomic::Species > m_products
Products of the reaction.
Definition reaction.h:262
double m_qValue
Q-value of the reaction in MeV.
Definition reaction.h:260
std::string m_id
Unique identifier for the reaction (e.g., "h1+h1=>h2+e+nu").
Definition reaction.h:257
int chapter() const
Gets the REACLIB chapter number.
Definition reaction.h:125
std::string m_peName
Name of the reaction in (projectile, ejectile) notation (e.g. "p(p,g)d").
Definition reaction.h:258
const std::vector< fourdst::atomic::Species > & products() const
Gets the vector of product species.
Definition reaction.h:219
quill::Logger * m_logger
Definition reaction.h:256
virtual std::string_view peName() const
Gets the reaction name in (projectile, ejectile) notation.
Definition reaction.h:119
std::unordered_set< fourdst::atomic::Species > all_species() const
Gets a set of all unique species involved in the reaction.
Definition reaction.cpp:70
Reaction(const std::string_view id, const std::string_view peName, const int chapter, const std::vector< fourdst::atomic::Species > &reactants, const std::vector< fourdst::atomic::Species > &products, const double qValue, const std::string_view label, const RateCoefficientSet &sets, const bool reverse=false)
Constructs a Reaction object.
Definition reaction.cpp:19
std::unordered_set< fourdst::atomic::Species > reactant_species() const
Gets a set of all unique reactant species.
Definition reaction.cpp:77
const RateCoefficientSet & rateCoefficients() const
Gets the set of rate coefficients.
Definition reaction.h:137
std::vector< fourdst::atomic::Species > m_reactants
Reactants of the reaction.
Definition reaction.h:261
double excess_energy() const
Calculates the excess energy from the mass difference of reactants and products.
Definition reaction.cpp:123
RateCoefficientSet m_rateCoefficients
The seven rate coefficients.
Definition reaction.h:264
bool is_reverse() const
Checks if this is a reverse reaction rate.
Definition reaction.h:225
bool contains(const fourdst::atomic::Species &species) const
Checks if the reaction involves a given species as a reactant or product.
Definition reaction.cpp:47
bool contains_reactant(const fourdst::atomic::Species &species) const
Checks if the reaction involves a given species as a reactant.
Definition reaction.cpp:52
double qValue() const
Gets the Q-value of the reaction.
Definition reaction.h:207
std::unordered_map< fourdst::atomic::Species, int > stoichiometry() const
Gets a map of all species to their stoichiometric coefficients.
Definition reaction.cpp:112
virtual double calculate_rate(const double T9) const
Calculates the reaction rate for a given temperature.
Definition reaction.cpp:39
uint64_t hash(uint64_t seed=0) const
Computes a hash for the reaction based on its ID.
Definition reaction.cpp:136
A collection of Reaction objects.
Definition reaction.h:307
virtual void remove_reaction(const Reaction &reaction)
Removes a reaction from the set.
Definition reaction.cpp:181
bool contains_reactant(const fourdst::atomic::Species &species) const
Checks if any reaction in the set contains the given species as a reactant.
Definition reaction.cpp:225
uint64_t hash(uint64_t seed=0) const
Computes a hash for the entire set.
Definition reaction.cpp:270
virtual const Reaction & operator[](size_t index) const
Accesses a reaction by its index.
Definition reaction.cpp:243
bool contains_product(const fourdst::atomic::Species &species) const
Checks if any reaction in the set contains the given species as a product.
Definition reaction.cpp:234
bool operator==(const ReactionSet &other) const
Compares this set with another for equality.
Definition reaction.cpp:259
bool operator!=(const ReactionSet &other) const
Compares this set with another for inequality.
Definition reaction.cpp:266
bool contains_species(const fourdst::atomic::Species &species) const
Checks if any reaction in the set involves the given species.
Definition reaction.cpp:216
virtual size_t size() const
Gets the number of reactions in the set.
Definition reaction.h:363
void clear()
Removes all reactions from the set.
Definition reaction.cpp:211
std::vector< Reaction > m_reactions
Definition reaction.h:442
ReactionSet & operator=(const ReactionSet &other)
Copy assignment operator.
Definition reaction.cpp:166
virtual void add_reaction(Reaction reaction)
Adds a reaction to the set.
Definition reaction.cpp:175
std::unordered_map< std::string, Reaction > m_reactionNameMap
Maps reaction IDs to Reaction objects for quick lookup.
Definition reaction.h:444
bool contains(const std::string_view &id) const
Checks if the set contains a reaction with the given ID.
Definition reaction.cpp:193
ReactionSet(std::vector< Reaction > reactions)
Constructs a ReactionSet from a vector of reactions.
Definition reaction.cpp:140
STL namespace.
Defines classes for representing and managing nuclear reactions.
Holds the seven coefficients for the REACLIB rate equation.
Definition reaction.h:32
size_t operator()(const gridfire::reaction::Reaction &r) const noexcept
Definition reaction.cpp:368
size_t operator()(const gridfire::reaction::ReactionSet &s) const noexcept
Definition reaction.cpp:375