Cantera  4.0.0a1
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(Kinetics& kin) override {
65 m_shared.resize(kin);
66 m_shared.invalidateCache();
67 }
68
69 void getRateConstants(span<double> kf) override {
70 for (auto& [iRxn, rate] : m_rxn_rates) {
71 kf[iRxn] = rate.evalFromStruct(m_shared);
72 }
73 }
74
75 void modifyRateConstants(span<double> kf, span<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(span<double> rop, span<const double> kf,
84 double deltaT) override
85 {
86 if constexpr (has_ddT<RateType>::value) {
87 for (const auto& [iRxn, rate] : m_rxn_rates) {
88 rop[iRxn] *= rate.ddTScaledFromStruct(m_shared);
89 }
90 } else {
91 // perturb conditions
92 double dTinv = 1. / (m_shared.temperature * deltaT);
93 m_shared.perturbTemperature(deltaT);
94 _update();
95
96 // apply numerical derivative
97 for (auto& [iRxn, rate] : m_rxn_rates) {
98 if (kf[iRxn] != 0.) {
99 double k1 = rate.evalFromStruct(m_shared);
100 rop[iRxn] *= dTinv * (k1 / kf[iRxn] - 1.);
101 } // else not needed: derivative is already zero
102 }
103
104 // revert changes
105 m_shared.restore();
106 _update();
107 }
108 }
109
110 void processRateConstants_ddP(span<double> rop, span<const double> kf,
111 double deltaP) override
112 {
113 if constexpr (has_ddP<DataType>::value) {
114 double dPinv = 1. / (m_shared.pressure * deltaP);
115 m_shared.perturbPressure(deltaP);
116 _update();
117
118 for (auto& [iRxn, rate] : m_rxn_rates) {
119 if (kf[iRxn] != 0.) {
120 double k1 = rate.evalFromStruct(m_shared);
121 rop[iRxn] *= dPinv * (k1 / kf[iRxn] - 1.);
122 } // else not needed: derivative is already zero
123 }
124
125 // revert changes
126 m_shared.restore();
127 _update();
128 } else {
129 for (const auto& [iRxn, rate] : m_rxn_rates) {
130 rop[iRxn] = 0.;
131 }
132 }
133 }
134
135 void processRateConstants_ddM(span<double> rop, span<const double> kf,
136 double deltaM, bool overwrite=true) override
137 {
138 if constexpr (has_ddM<DataType>::value) {
139 double dMinv = 1. / deltaM;
140 m_shared.perturbThirdBodies(deltaM);
141 _update();
142
143 for (auto& [iRxn, rate] : m_rxn_rates) {
144 if (kf[iRxn] != 0. && m_shared.conc_3b[iRxn] > 0.) {
145 double k1 = rate.evalFromStruct(m_shared);
146 rop[iRxn] *= dMinv * (k1 / kf[iRxn] - 1.);
147 rop[iRxn] /= m_shared.conc_3b[iRxn];
148 } else {
149 rop[iRxn] = 0.;
150 }
151 }
152
153 // revert changes
154 m_shared.restore();
155 _update();
156 } else {
157 if (!overwrite) {
158 // do not overwrite existing entries
159 return;
160 }
161 for (const auto& [iRxn, rate] : m_rxn_rates) {
162 rop[iRxn] = 0.;
163 }
164 }
165 }
166
167 void update(double T) override {
168 m_shared.update(T);
169 _update();
170 }
171
172 void update(double T, double extra) override {
173 m_shared.update(T, extra);
174 _update();
175 }
176
177 void update(double T, span<const double> extra) override {
178 m_shared.update(T, extra);
179 _update();
180 }
181
182 bool update(const ThermoPhase& phase, const Kinetics& kin) override {
183 bool changed = m_shared.update(phase, kin);
184 if (changed) {
185 // call helper function only if needed: implementation depends on whether
186 // ReactionRate::updateFromStruct is defined
187 _update();
188 }
189 return changed;
190 }
191
192 double evalSingle(ReactionRate& rate) override {
193 RateType& R = static_cast<RateType&>(rate);
194 if constexpr (has_update<RateType>::value) {
195 R.updateFromStruct(m_shared);
196 }
197 return R.evalFromStruct(m_shared);
198 }
199
200 //! Access the underlying shared data object. Used for setting up
201 //! ReactionDataDelegator instances.
202 DataType& sharedData() {
203 return m_shared;
204 }
205
206protected:
207 //! Helper function to process updates
208 void _update() {
209 if constexpr (has_update<RateType>::value) {
210 for (auto& [i, rxn] : m_rxn_rates) {
211 rxn.updateFromStruct(m_shared);
212 }
213 }
214 }
215
216 //! Vector of pairs of reaction rates indices and reaction rates
217 vector<pair<size_t, RateType>> m_rxn_rates;
218 map<size_t, size_t> m_indices; //! Mapping of indices
219 DataType m_shared;
220};
221
222}
223
224#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 getRateConstants(span< double > kf) override
Evaluate all rate constants handled by the evaluator.
Definition MultiRate.h:69
void processRateConstants_ddT(span< double > rop, span< const double > kf, double deltaT) override
Evaluate all rate constant temperature derivatives handled by the evaluator; which are multiplied wit...
Definition MultiRate.h:83
bool update(const ThermoPhase &phase, const Kinetics &kin) override
Update data common to reaction rates of a specific type.
Definition MultiRate.h:182
DataType & sharedData()
Access the underlying shared data object.
Definition MultiRate.h:202
string type() override
Identifier of reaction rate type.
Definition MultiRate.h:30
void update(double T) override
Update common reaction rate data based on temperature.
Definition MultiRate.h:167
bool replace(size_t rxn_index, ReactionRate &rate) override
Replace reaction rate object handled by the evaluator.
Definition MultiRate.h:44
void processRateConstants_ddP(span< double > rop, span< const double > kf, double deltaP) override
Evaluate all rate constant pressure derivatives handled by the evaluator; which are multiplied with t...
Definition MultiRate.h:110
double evalSingle(ReactionRate &rate) override
Get the rate for a single reaction.
Definition MultiRate.h:192
void _update()
Helper function to process updates.
Definition MultiRate.h:208
DataType m_shared
Mapping of indices.
Definition MultiRate.h:219
void resize(Kinetics &kin) override
Update array sizes that depend on number of species, reactions or phases.
Definition MultiRate.h:64
void modifyRateConstants(span< double > kf, span< double > kr) override
For certain reaction types that do not follow mass action kinetics (for example, Butler-Volmer),...
Definition MultiRate.h:75
void add(size_t rxn_index, ReactionRate &rate) override
Add reaction rate object to the evaluator.
Definition MultiRate.h:38
void processRateConstants_ddM(span< double > rop, span< 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:135
void update(double T, span< const double > extra) override
Update common reaction rate data based on temperature and extra parameter.
Definition MultiRate.h:177
void update(double T, double extra) override
Update common reaction rate data based on temperature and extra parameter.
Definition MultiRate.h:172
vector< pair< size_t, RateType > > m_rxn_rates
Vector of pairs of reaction rates indices and reaction rates.
Definition MultiRate.h:217
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:238