chombo-discharge
Loading...
Searching...
No Matches
CD_KMCSingleStateReactionImplem.H
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2021-2026 SINTEF Energy Research
3 *
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 */
6
13#ifndef CD_KMCSINGLESTATEREACTIONIMPLEM_H
14#define CD_KMCSINGLESTATEREACTIONIMPLEM_H
15
16// Our includes
18#include <CD_NamespaceHeader.H>
19
20template <typename State, typename T>
21inline KMCSingleStateReaction<State, T>::KMCSingleStateReaction(const std::list<size_t>& a_reactants,
22 const std::list<size_t>& a_products) noexcept
23 : m_reactants(a_reactants), m_products(a_products)
24{
25 this->computeStateChanges();
26}
27
28template <typename State, typename T>
31
32template <typename State, typename T>
33inline void
35{
36 // Consumed particles.
37 for (const auto& r : m_reactants) {
38 if (m_stateChange.find(r) == m_stateChange.end()) {
39 m_stateChange.emplace(r, -1);
40 }
41 else {
42 m_stateChange[r]--;
43 }
44 }
45
46 // Produced particles.
47 for (const auto& p : m_products) {
48 if (m_stateChange.find(p) == m_stateChange.end()) {
49 m_stateChange.emplace(p, +1);
50 }
51 else {
52 m_stateChange[p]++;
53 }
54 }
55
56 // Compute the propensity factor that we need when there are bi- or tri-particle reactions involving the same species.
57 // We need to do this because for biparticle reactions of N particles of the same type, there are 0.5 * N * (N-1)
58 // unique pairs of particles. Or in general when we have a k-order reaction we have 'N choose k' = N!/(k! * (N-k)!)
59 // combinations. In the propensity function we compute the propensity as
60 //
61 // a = rate * factor * N * (N-1) * (N-2) ...
62 //
63 // For this to make sense we have
64 //
65 // a = rate * N * (N-1) * (N-2) ... (N-k+1) * (N-k)!/(k! * (N-k)!)
66 // = rate * N * (N-1) * (N-2) ... * 1/k!
67 //
68 // so the factor is just 1/k! (for each species).
69
70 m_propensityFactor = 1.0;
71
72 std::map<size_t, size_t> reactantNumbers;
73 for (const auto& r : m_reactants) {
74 if (reactantNumbers.find(r) == reactantNumbers.end()) {
75 reactantNumbers.emplace(r, 1);
76 }
77 else {
78 reactantNumbers[r]++;
79 }
80 }
81
82 for (const auto& rn : reactantNumbers) {
83 m_propensityFactor *= 1.0 / factorial(rn.second);
84 }
85}
86
87template <typename State, typename T>
88inline Real&
90{
91 return m_rate;
92}
93
94template <typename State, typename T>
95inline T
96KMCSingleStateReaction<State, T>::population(const size_t& a_reactant, const State& a_state) noexcept
97{
98 return a_state[a_reactant];
99}
100
101template <typename State, typename T>
102inline Real
103KMCSingleStateReaction<State, T>::propensity(const State& a_state) const noexcept
104{
105 Real A = m_rate * m_propensityFactor;
106
107 State tmp = a_state;
108
109 for (const auto& r : m_reactants) {
110 A *= tmp[r];
111
112 tmp[r]--;
113 }
114
115 return A;
116}
117
118template <typename State, typename T>
119inline T
121{
122 T Lj = std::numeric_limits<T>::max();
123
124 for (const auto& s : m_stateChange) {
125
126 const size_t rI = s.first;
127 const T nuIJ = s.second;
128
129 if (nuIJ < 0) {
130 Lj = std::min(Lj, a_state[rI] / std::abs(nuIJ));
131 }
132 }
133
134 return Lj;
135}
136
137template <typename State, typename T>
138inline const std::list<size_t>&
140{
141 return m_reactants;
142}
143
144template <typename State, typename T>
145inline T
146KMCSingleStateReaction<State, T>::getStateChange(const size_t a_particleReactant) const noexcept
147{
148 T nuIJ = 0;
149
150 if (m_stateChange.find(a_particleReactant) != m_stateChange.end()) {
151 nuIJ = m_stateChange.at(a_particleReactant);
152 }
153
154 return nuIJ;
155}
156
157template <typename State, typename T>
158inline void
159KMCSingleStateReaction<State, T>::advanceState(State& a_state, const T& a_numReactions) const noexcept
160{
161 for (const auto& s : m_stateChange) {
162 a_state[s.first] += a_numReactions * s.second;
163 }
164}
165
166#include <CD_NamespaceFooter.H>
167
168#endif
Declaration of a simple reaction type for advancing "single states" in Kinetic Monte Carlo codes.
virtual ~KMCSingleStateReaction()
Destructor.
Definition CD_KMCSingleStateReactionImplem.H:29
Real propensity(const State &a_state) const noexcept
Compute the propensity function for this reaction type.
Definition CD_KMCSingleStateReactionImplem.H:103
T getStateChange(const size_t a_particleReactant) const noexcept
Get the state change due to a change in the input reactant species.
Definition CD_KMCSingleStateReactionImplem.H:146
void computeStateChanges() noexcept
Compute state change vectors from the reactant/product lists.
Definition CD_KMCSingleStateReactionImplem.H:34
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_KMCSingleStateReactionImplem.H:96
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_KMCSingleStateReactionImplem.H:120
void advanceState(State &a_state, const T &a_numReactions) const noexcept
Advance the incoming state with the number of reactions.
Definition CD_KMCSingleStateReactionImplem.H:159
KMCSingleStateReaction()=default
Default constructor.
const std::list< size_t > & getReactants() const noexcept
Get the reactants involved in the reaction.
Definition CD_KMCSingleStateReactionImplem.H:139
Real & rate() const noexcept
Get modifiable reaction rate.
Definition CD_KMCSingleStateReactionImplem.H:89