13#ifndef CD_KMCDUALSTATEREACTIONIMPLEM_H
14#define CD_KMCDUALSTATEREACTIONIMPLEM_H
24#include <CD_NamespaceHeader.H>
26template <
typename State,
typename T>
28 const std::list<size_t>& a_rhsReactives,
29 const std::list<size_t>& a_rhsNonReactives)
noexcept
31 m_lhsReactives = a_lhsReactives;
32 m_rhsReactives = a_rhsReactives;
33 m_rhsNonReactives = a_rhsNonReactives;
35 CH_assert(a_lhsReactives.size() > 0);
37 this->computeStateChanges();
40template <
typename State,
typename T>
44template <
typename State,
typename T>
49 for (
const auto& r : m_lhsReactives) {
50 if (m_reactiveStateChange.find(r) == m_reactiveStateChange.end()) {
51 m_reactiveStateChange.emplace(r, -1);
54 m_reactiveStateChange[r]--;
59 for (
const auto& p : m_rhsReactives) {
60 if (m_reactiveStateChange.find(p) == m_reactiveStateChange.end()) {
61 m_reactiveStateChange.emplace(p, +1);
64 m_reactiveStateChange[p]++;
69 for (
const auto& p : m_rhsNonReactives) {
70 if (m_nonReactiveStateChange.find(p) == m_nonReactiveStateChange.end()) {
71 m_nonReactiveStateChange.emplace(p, +1);
74 m_nonReactiveStateChange[p]++;
92 m_propensityFactor = 1.0;
94 std::map<size_t, size_t> reactantNumbers;
95 for (
const auto& r : m_lhsReactives) {
96 if (reactantNumbers.find(r) == reactantNumbers.end()) {
97 reactantNumbers.emplace(r, 1);
100 reactantNumbers[r]++;
105 auto factorial = [](
const T& N) -> T {
107 for (T i = 2; i <= N; i++) {
114 for (
const auto& rn : reactantNumbers) {
115 m_propensityFactor *= 1.0 / factorial(rn.second);
121 m_lhsOrders.reserve(reactantNumbers.size());
123 for (
const auto& rn : reactantNumbers) {
124 m_lhsOrders.emplace_back(rn.first, rn.second);
130 m_reactiveStateChangeDense.clear();
132 if (!m_reactiveStateChange.empty()) {
133 const size_t highestSpecies = m_reactiveStateChange.rbegin()->first;
135 m_reactiveStateChangeDense.assign(highestSpecies + 1, (T)0);
137 for (
const auto& s : m_reactiveStateChange) {
138 m_reactiveStateChangeDense[s.first] = s.second;
143template <
typename State,
typename T>
150template <
typename State,
typename T>
154 const auto& reactiveState = a_state.getReactiveState();
156 CH_assert(reactiveState.size() > a_reactant);
158 return reactiveState[a_reactant];
161template <
typename State,
typename T>
166 this->sanityCheck(a_state);
169 Real A = m_rate * m_propensityFactor;
171 const auto& reactiveState = a_state.getReactiveState();
177 for (
const auto& lhs : m_lhsOrders) {
178 T X = reactiveState[lhs.first];
180 for (
size_t k = 0; k < lhs.second; k++) {
190template <
typename State,
typename T>
195 this->sanityCheck(a_state);
198 T Lj = std::numeric_limits<T>::max();
200 const auto& reactiveState = a_state.getReactiveState();
202 for (
const auto& s : m_reactiveStateChange) {
204 const size_t rI = s.first;
205 const T nuIJ = s.second;
208 Lj = std::min(Lj, reactiveState[rI] / std::abs(nuIJ));
215template <
typename State,
typename T>
216inline const std::list<size_t>&
219 return m_lhsReactives;
222template <
typename State,
typename T>
223inline std::list<size_t>
226 return m_rhsReactives;
229template <
typename State,
typename T>
230inline std::list<size_t>
233 return m_rhsNonReactives;
236template <
typename State,
typename T>
244 if (a_particleReactant < m_reactiveStateChangeDense.size()) {
245 nuIJ = m_reactiveStateChangeDense[a_particleReactant];
251template <
typename State,
typename T>
256 this->sanityCheck(a_state);
258 CH_assert(a_state.isValidState());
260 auto& reactiveState = a_state.getReactiveState();
261 auto& photonState = a_state.getNonReactiveState();
263 for (
const auto& s : m_reactiveStateChange) {
264 reactiveState[s.first] += a_numReactions * s.second;
267 for (
const auto& s : m_nonReactiveStateChange) {
268 photonState[s.first] += a_numReactions * s.second;
271 CH_assert(a_state.isValidState());
274template <
typename State,
typename T>
278 const auto& reactiveState = a_state.getReactiveState();
279 const auto& photonState = a_state.getNonReactiveState();
281 for (
const auto& idx : m_lhsReactives) {
282 CH_assert(reactiveState.size() > idx);
285 for (
const auto& idx : m_rhsReactives) {
286 CH_assert(reactiveState.size() > idx);
289 for (
const auto& idx : m_rhsNonReactives) {
290 CH_assert(photonState.size() > idx);
294#include <CD_NamespaceFooter.H>
Declaration of a simple plasma reaction type for Kinetic Monte Carlo.
T getStateChange(const size_t a_reactant) const noexcept
Get the state change due to a change in the input reactant.
Definition CD_KMCDualStateReactionImplem.H:238
void sanityCheck(const State &a_state) const noexcept
Debugging function which ensures that the class data holders do not reach out of the incoming state.
Definition CD_KMCDualStateReactionImplem.H:276
void computeStateChanges() noexcept
Compute state change vectors from the reactant/product lists.
Definition CD_KMCDualStateReactionImplem.H:46
std::list< size_t > getNonReactiveProducts() const noexcept
Get the non-reactive products from the reaction.
Definition CD_KMCDualStateReactionImplem.H:231
KMCDualStateReaction()=default
Default constructor.
virtual ~KMCDualStateReaction()
Destructor.
Definition CD_KMCDualStateReactionImplem.H:41
std::list< size_t > getReactiveProducts() const noexcept
Get the products from the reaction.
Definition CD_KMCDualStateReactionImplem.H:224
Real propensity(const State &a_state) const noexcept
Compute the propensity function for this reaction type.
Definition CD_KMCDualStateReactionImplem.H:163
T computeCriticalNumberOfReactions(const State &a_state) const noexcept
Compute the number of times the reaction can fire before exhausting one of the reactants.
Definition CD_KMCDualStateReactionImplem.H:192
Real & rate() const noexcept
Get modifiable reaction rate.
Definition CD_KMCDualStateReactionImplem.H:145
void advanceState(State &a_state, const T &a_numReactions) const noexcept
Advance the incoming state with the number of reactions.
Definition CD_KMCDualStateReactionImplem.H:253
const std::list< size_t > & getReactants() const noexcept
Get the reactants in the reaction.
Definition CD_KMCDualStateReactionImplem.H:217
static T population(const size_t &a_reactant, const State &a_state) noexcept
Get the population of the reactant in the input state.
Definition CD_KMCDualStateReactionImplem.H:152