Cantera  3.2.0a2
Loading...
Searching...
No Matches
MultiRate.h
Go to the documentation of this file.
1/**
2 * @file MultiRate.h
3 */
4
5// This file is part of Cantera. See License.txt in the top-level directory or
6// at https://cantera.org/license.txt for license and copyright information.
7
8#ifndef CT_MULTIRATE_H
9#define CT_MULTIRATE_H
10
11#include "ReactionRate.h"
12#include "MultiRateBase.h"
14
15namespace Cantera
16{
17
18//! A class template handling ReactionRate specializations.
19//! @ingroup rateEvaluators
20template <class RateType, class DataType>
21class MultiRate final : public MultiRateBase
22{
23 CT_DEFINE_HAS_MEMBER(has_update, updateFromStruct)
24 CT_DEFINE_HAS_MEMBER(has_modifyRateConstants, modifyRateConstants)
25 CT_DEFINE_HAS_MEMBER(has_ddT, ddTScaledFromStruct)
26 CT_DEFINE_HAS_MEMBER(has_ddP, perturbPressure)
27 CT_DEFINE_HAS_MEMBER(has_ddM, perturbThirdBodies)
28
29public:
30 string type() override {
31 if (!m_rxn_rates.size()) {
32 throw CanteraError("MultiRate::type",
33 "Cannot determine type of empty rate handler.");
34 }
35 return m_rxn_rates.at(0).second.type();
36 }
37
38 void add(size_t rxn_index, ReactionRate& rate) override {
39 m_indices[rxn_index] = m_rxn_rates.size();
40 m_rxn_rates.emplace_back(rxn_index, dynamic_cast<RateType&>(rate));
41 m_shared.invalidateCache();
42 }
43
44 bool replace(size_t rxn_index, ReactionRate& rate) override {
45 if (!m_rxn_rates.size()) {
46 throw CanteraError("MultiRate::replace",
47 "Invalid operation: cannot replace rate object "
48 "in empty rate handler.");
49 }
50 if (rate.type() != type()) {
51 throw CanteraError("MultiRate::replace",
52 "Invalid operation: cannot replace rate object of type '{}' "
53 "with a new rate of type '{}'.", type(), rate.type());
54 }
55 m_shared.invalidateCache();
56 if (m_indices.find(rxn_index) != m_indices.end()) {
57 size_t j = m_indices[rxn_index];
58 m_rxn_rates.at(j).second = dynamic_cast<RateType&>(rate);
59 return true;
60 }
61 return false;
62 }
63
64 void resize(size_t nSpecies, size_t nReactions, size_t nPhases) override {
65 m_shared.resize(nSpecies, nReactions, nPhases);
66 m_shared.invalidateCache();
67 }
68
69 void getRateConstants(double* kf) override {
70 for (auto& [iRxn, rate] : m_rxn_rates) {
71 kf[iRxn] = rate.evalFromStruct(m_shared);
72 }
73 }
74
75 void modifyRateConstants(double* kf, double* kr) override {
76 if constexpr (has_modifyRateConstants<RateType>::value) {
77 for (auto& [iRxn, rate] : m_rxn_rates) {
78 rate.modifyRateConstants(m_shared, kf[iRxn], kr[iRxn]);
79 }
80 }
81 }
82
83 void processRateConstants_ddT(double* rop, const double* kf, double deltaT) override
84 {
85 if constexpr (has_ddT<RateType>::value) {
86 for (const auto& [iRxn, rate] : m_rxn_rates) {
87 rop[iRxn] *= rate.ddTScaledFromStruct(m_shared);
88 }
89 } else {
90 // perturb conditions
91 double dTinv = 1. / (m_shared.temperature * deltaT);
92 m_shared.perturbTemperature(deltaT);
93 _update();
94
95 // apply numerical derivative
96 for (auto& [iRxn, rate] : m_rxn_rates) {
97 if (kf[iRxn] != 0.) {
98 double k1 = rate.evalFromStruct(m_shared);
99 rop[iRxn] *= dTinv * (k1 / kf[iRxn] - 1.);
100 } // else not needed: derivative is already zero
101 }
102
103 // revert changes
104 m_shared.restore();
105 _update();
106 }
107 }
108
109 void processRateConstants_ddP(double* rop, const double* kf, double deltaP) override
110 {
111 if constexpr (has_ddP<DataType>::value) {
112 double dPinv = 1. / (m_shared.pressure * deltaP);
113 m_shared.perturbPressure(deltaP);
114 _update();
115
116 for (auto& [iRxn, rate] : m_rxn_rates) {
117 if (kf[iRxn] != 0.) {
118 double k1 = rate.evalFromStruct(m_shared);
119 rop[iRxn] *= dPinv * (k1 / kf[iRxn] - 1.);
120 } // else not needed: derivative is already zero
121 }
122
123 // revert changes
124 m_shared.restore();
125 _update();
126 } else {
127 for (const auto& [iRxn, rate] : m_rxn_rates) {
128 rop[iRxn] = 0.;
129 }
130 }
131 }
132
133 void processRateConstants_ddM(double* rop, const double* kf, double deltaM,
134 bool overwrite=true) override
135 {
136 if constexpr (has_ddM<DataType>::value) {
137 double dMinv = 1. / deltaM;
138 m_shared.perturbThirdBodies(deltaM);
139 _update();
140
141 for (auto& [iRxn, rate] : m_rxn_rates) {
142 if (kf[iRxn] != 0. && m_shared.conc_3b[iRxn] > 0.) {
143 double k1 = rate.evalFromStruct(m_shared);
144 rop[iRxn] *= dMinv * (k1 / kf[iRxn] - 1.);
145 rop[iRxn] /= m_shared.conc_3b[iRxn];
146 } else {
147 rop[iRxn] = 0.;
148 }
149 }
150
151 // revert changes
152 m_shared.restore();
153 _update();
154 } else {
155 if (!overwrite) {
156 // do not overwrite existing entries
157 return;
158 }
159 for (const auto& [iRxn, rate] : m_rxn_rates) {
160 rop[iRxn] = 0.;
161 }
162 }
163 }
164
165 void update(double T) override {
166 m_shared.update(T);
167 _update();
168 }
169
170 void update(double T, double extra) override {
171 m_shared.update(T, extra);
172 _update();
173 }
174
175 void update(double T, const vector<double>& extra) override {
176 m_shared.update(T, extra);
177 _update();
178 }
179
180 bool update(const ThermoPhase& phase, const Kinetics& kin) override {
181 bool changed = m_shared.update(phase, kin);
182 if (changed) {
183 // call helper function only if needed: implementation depends on whether
184 // ReactionRate::updateFromStruct is defined
185 _update();
186 }
187 return changed;
188 }
189
190 double evalSingle(ReactionRate& rate) override {
191 RateType& R = static_cast<RateType&>(rate);
192 if constexpr (has_update<RateType>::value) {
193 R.updateFromStruct(m_shared);
194 }
195 return R.evalFromStruct(m_shared);
196 }
197
198 //! Access the underlying shared data object. Used for setting up
199 //! ReactionDataDelegator instances.
200 DataType& sharedData() {
201 return m_shared;
202 }
203
204protected:
205 //! Helper function to process updates
206 void _update() {
207 if constexpr (has_update<RateType>::value) {
208 for (auto& [i, rxn] : m_rxn_rates) {
209 rxn.updateFromStruct(m_shared);
210 }
211 }
212 }
213
214 //! Vector of pairs of reaction rates indices and reaction rates
215 vector<pair<size_t, RateType>> m_rxn_rates;
216 map<size_t, size_t> m_indices; //! Mapping of indices
217 DataType m_shared;
218};
219
220}
221
222#endif
Base class for exceptions thrown by Cantera classes.
Public interface for kinetics managers.
Definition Kinetics.h:126
An abstract base class for evaluating all reactions of a particular type.
A class template handling ReactionRate specializations.
Definition MultiRate.h:22
void processRateConstants_ddM(double *rop, const double *kf, double deltaM, bool overwrite=true) override
Evaluate all rate constant third-body derivatives handled by the evaluator; which are multiplied with...
Definition MultiRate.h:133
void getRateConstants(double *kf) override
Evaluate all rate constants handled by the evaluator.
Definition MultiRate.h:69
bool update(const ThermoPhase &phase, const Kinetics &kin) override
Update data common to reaction rates of a specific type.
Definition MultiRate.h:180
DataType & sharedData()
Access the underlying shared data object.
Definition MultiRate.h:200
string type() override
Identifier of reaction rate type.
Definition MultiRate.h:30
void update(double T, const vector< double > &extra) override
Update common reaction rate data based on temperature and extra parameter.
Definition MultiRate.h:175
void update(double T) override
Update common reaction rate data based on temperature.
Definition MultiRate.h:165
bool replace(size_t rxn_index, ReactionRate &rate) override
Replace reaction rate object handled by the evaluator.
Definition MultiRate.h:44
void resize(size_t nSpecies, size_t nReactions, size_t nPhases) override
Update number of species and reactions.
Definition MultiRate.h:64
void processRateConstants_ddT(double *rop, const double *kf, double deltaT) override
Evaluate all rate constant temperature derivatives handled by the evaluator; which are multiplied wit...
Definition MultiRate.h:83
void modifyRateConstants(double *kf, double *kr) override
For certain reaction types that do not follow mass action kinetics (for example, Butler-Volmer),...
Definition MultiRate.h:75
double evalSingle(ReactionRate &rate) override
Get the rate for a single reaction.
Definition MultiRate.h:190
void _update()
Helper function to process updates.
Definition MultiRate.h:206
void processRateConstants_ddP(double *rop, const double *kf, double deltaP) override
Evaluate all rate constant pressure derivatives handled by the evaluator; which are multiplied with t...
Definition MultiRate.h:109
DataType m_shared
Mapping of indices.
Definition MultiRate.h:217
void add(size_t rxn_index, ReactionRate &rate) override
Add reaction rate object to the evaluator.
Definition MultiRate.h:38
void update(double T, double extra) override
Update common reaction rate data based on temperature and extra parameter.
Definition MultiRate.h:170
vector< pair< size_t, RateType > > m_rxn_rates
Vector of pairs of reaction rates indices and reaction rates.
Definition MultiRate.h:215
Abstract base class for reaction rate definitions; this base class is used by user-facing APIs to acc...
virtual const string type() const =0
String identifying reaction rate specialization.
Base class for a phase with thermodynamic properties.
Namespace for the Cantera kernel.
Definition AnyMap.cpp:595
Various templated functions that carry out common vector and polynomial operations (see Templated Arr...
#define CT_DEFINE_HAS_MEMBER(detector_name, func_name)
A macro for generating member function detectors, which can then be used in combination with if const...
Definition utilities.h:205