Cantera 2.6.0
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.
19template <class RateType, class DataType>
20class MultiRate final : public MultiRateBase
21{
22 CT_DEFINE_HAS_MEMBER(has_update, updateFromStruct)
23 CT_DEFINE_HAS_MEMBER(has_ddT, ddTScaledFromStruct)
24 CT_DEFINE_HAS_MEMBER(has_ddP, perturbPressure)
25 CT_DEFINE_HAS_MEMBER(has_ddM, perturbThirdBodies)
26
27public:
28 virtual std::string type() override {
29 if (!m_rxn_rates.size()) {
30 throw CanteraError("MultiRate::type",
31 "Cannot determine type of empty rate handler.");
32 }
33 return m_rxn_rates.at(0).second.type();
34 }
35
36 virtual void add(size_t rxn_index, ReactionRate& rate) override {
37 m_indices[rxn_index] = m_rxn_rates.size();
38 m_rxn_rates.emplace_back(rxn_index, dynamic_cast<RateType&>(rate));
39 m_shared.invalidateCache();
40 }
41
42 virtual bool replace(size_t rxn_index, ReactionRate& rate) override {
43 if (!m_rxn_rates.size()) {
44 throw CanteraError("MultiRate::replace",
45 "Invalid operation: cannot replace rate object "
46 "in empty rate handler.");
47 }
48 if (rate.type() != type()) {
49 throw CanteraError("MultiRate::replace",
50 "Invalid operation: cannot replace rate object of type '{}' "
51 "with a new rate of type '{}'.", type(), rate.type());
52 }
53 m_shared.invalidateCache();
54 if (m_indices.find(rxn_index) != m_indices.end()) {
55 size_t j = m_indices[rxn_index];
56 m_rxn_rates.at(j).second = dynamic_cast<RateType&>(rate);
57 return true;
58 }
59 return false;
60 }
61
62 virtual void resize(size_t nSpecies, size_t nReactions, size_t nPhases) override {
63 m_shared.resize(nSpecies, nReactions, nPhases);
64 m_shared.invalidateCache();
65 }
66
67 virtual void getRateConstants(double* kf) override {
68 for (auto& rxn : m_rxn_rates) {
69 kf[rxn.first] = rxn.second.evalFromStruct(m_shared);
70 }
71 }
72
73 virtual void processRateConstants_ddT(double* rop,
74 const double* kf,
75 double deltaT) override
76 {
77 // call helper function: implementation of derivative depends on whether
78 // ReactionRate::ddTFromStruct is defined
79 _process_ddT(rop, kf, deltaT);
80 }
81
82 virtual void processRateConstants_ddP(double* rop,
83 const double* kf,
84 double deltaP) override
85 {
86 // call helper function: implementation of derivative depends on whether
87 // ReactionData::perturbPressure is defined
88 _process_ddP(rop, kf, deltaP);
89 }
90
91 virtual void processRateConstants_ddM(double* rop,
92 const double* kf,
93 double deltaM,
94 bool overwrite=true) override
95 {
96 // call helper function: implementation of derivative depends on whether
97 // ReactionRate::thirdBodyConcentration is defined
98 _process_ddM(rop, kf, deltaM, overwrite);
99 }
100
101 virtual void update(double T) override {
102 m_shared.update(T);
103 _update();
104 }
105
106 virtual void update(double T, double extra) override {
107 m_shared.update(T, extra);
108 _update();
109 }
110
111 virtual void update(double T, const vector_fp& extra) override {
112 m_shared.update(T, extra);
113 _update();
114 }
115
116 virtual bool update(const ThermoPhase& phase, const Kinetics& kin) override {
117 bool changed = m_shared.update(phase, kin);
118 if (changed) {
119 // call helper function only if needed: implementation depends on whether
120 // ReactionRate::updateFromStruct is defined
121 _update();
122 }
123 return changed;
124 }
125
126 virtual double evalSingle(ReactionRate& rate) override {
127 RateType& R = static_cast<RateType&>(rate);
128 _updateRate(R);
129 return R.evalFromStruct(m_shared);
130 }
131
132protected:
133 //! Helper function to process updates for rate types that implement the
134 //! `updateFromStruct` method.
135 template <typename T=RateType,
136 typename std::enable_if<has_update<T>::value, bool>::type = true>
137 void _update() {
138 for (auto& rxn : m_rxn_rates) {
139 rxn.second.updateFromStruct(m_shared);
140 }
141 }
142
143 //! Helper function for rate types that do not implement `updateFromStruct`.
144 //! Does nothing, but exists to allow generic implementations of update().
145 template <typename T=RateType,
146 typename std::enable_if<!has_update<T>::value, bool>::type = true>
147 void _update() {
148 }
149
150 //! Helper function to update a single rate that has an `updateFromStruct` method`.
151 template <typename T=RateType,
152 typename std::enable_if<has_update<T>::value, bool>::type = true>
153 void _updateRate(RateType& rate) {
154 rate.updateFromStruct(m_shared);
155 }
156
157 //! Helper function for single rate that does not implement `updateFromStruct`.
158 //! Exists to allow generic implementations of `evalSingle` and `ddTSingle`.
159 template <typename T=RateType,
160 typename std::enable_if<!has_update<T>::value, bool>::type = true>
161 void _updateRate(RateType& rate) {
162 }
163
164 //! Helper function to process temperature derivatives for rate types that
165 //! implement the `ddTScaledFromStruct` method.
166 template <typename T=RateType,
167 typename std::enable_if<has_ddT<T>::value, bool>::type = true>
168 void _process_ddT(double* rop, const double* kf, double deltaT) {
169 for (const auto& rxn : m_rxn_rates) {
170 rop[rxn.first] *= rxn.second.ddTScaledFromStruct(m_shared);
171 }
172 }
173
174 //! Helper function for rate types that do not implement `ddTScaledFromStruct`
175 template <typename T=RateType,
176 typename std::enable_if<!has_ddT<T>::value, bool>::type = true>
177 void _process_ddT(double* rop, const double* kf, double deltaT) {
178
179 // perturb conditions
180 double dTinv = 1. / (m_shared.temperature * deltaT);
181 m_shared.perturbTemperature(deltaT);
182 _update();
183
184 // apply numerical derivative
185 for (auto& rxn : m_rxn_rates) {
186 if (kf[rxn.first] != 0.) {
187 double k1 = rxn.second.evalFromStruct(m_shared);
188 rop[rxn.first] *= dTinv * (k1 / kf[rxn.first] - 1.);
189 } // else not needed: derivative is already zero
190 }
191
192 // revert changes
193 m_shared.restore();
194 _update();
195 }
196
197 //! Helper function to process third-body derivatives for rate data that
198 //! implement the `perturbThirdBodies` method.
199 template <typename T=RateType, typename D=DataType,
200 typename std::enable_if<has_ddM<D>::value, bool>::type = true>
201 void _process_ddM(double* rop, const double* kf, double deltaM, bool overwrite) {
202 double dMinv = 1. / deltaM;
203 m_shared.perturbThirdBodies(deltaM);
204 _update();
205
206 for (auto& rxn : m_rxn_rates) {
207 if (kf[rxn.first] != 0. && m_shared.conc_3b[rxn.first] > 0.) {
208 double k1 = rxn.second.evalFromStruct(m_shared);
209 rop[rxn.first] *= dMinv * (k1 / kf[rxn.first] - 1.);
210 rop[rxn.first] /= m_shared.conc_3b[rxn.first];
211 } else {
212 rop[rxn.first] = 0.;
213 }
214 }
215
216 // revert changes
217 m_shared.restore();
218 _update();
219 }
220
221 //! Helper function for rate data that do not implement `perturbThirdBodies`
222 template <typename T=RateType, typename D=DataType,
223 typename std::enable_if<!has_ddM<D>::value, bool>::type = true>
224 void _process_ddM(double* rop, const double* kf, double deltaM, bool overwrite) {
225 if (!overwrite) {
226 // do not overwrite existing entries
227 return;
228 }
229 for (const auto& rxn : m_rxn_rates) {
230 rop[rxn.first] = 0.;
231 }
232 }
233
234 //! Helper function to process pressure derivatives for rate data that
235 //! implement the `perturbPressure` method.
236 template <typename T=RateType, typename D=DataType,
237 typename std::enable_if<has_ddP<D>::value, bool>::type = true>
238 void _process_ddP(double* rop, const double* kf, double deltaP) {
239 double dPinv = 1. / (m_shared.pressure * deltaP);
240 m_shared.perturbPressure(deltaP);
241 _update();
242
243 for (auto& rxn : m_rxn_rates) {
244 if (kf[rxn.first] != 0.) {
245 double k1 = rxn.second.evalFromStruct(m_shared);
246 rop[rxn.first] *= dPinv * (k1 / kf[rxn.first] - 1.);
247 } // else not needed: derivative is already zero
248 }
249
250 // revert changes
251 m_shared.restore();
252 _update();
253 }
254
255 //! Helper function for rate data that do not implement `perturbPressure`
256 template <typename T=RateType, typename D=DataType,
257 typename std::enable_if<!has_ddP<D>::value, bool>::type = true>
258 void _process_ddP(double* rop, const double* kf, double deltaP) {
259 for (const auto& rxn : m_rxn_rates) {
260 rop[rxn.first] = 0.;
261 }
262 }
263
264 //! Vector of pairs of reaction rates indices and reaction rates
265 std::vector<std::pair<size_t, RateType>> m_rxn_rates;
266 std::map<size_t, size_t> m_indices; //! Mapping of indices
267 DataType m_shared;
268};
269
270}
271
272#endif
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
Public interface for kinetics managers.
Definition: Kinetics.h:114
An abstract base class for evaluating all reactions of a particular type.
Definition: MultiRateBase.h:27
A class template handling ReactionRate specializations.
Definition: MultiRate.h:21
virtual bool update(const ThermoPhase &phase, const Kinetics &kin) override
Update data common to reaction rates of a specific type.
Definition: MultiRate.h:116
std::vector< std::pair< size_t, RateType > > m_rxn_rates
Vector of pairs of reaction rates indices and reaction rates.
Definition: MultiRate.h:265
virtual 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:82
virtual void resize(size_t nSpecies, size_t nReactions, size_t nPhases) override
Update number of species and reactions.
Definition: MultiRate.h:62
virtual bool replace(size_t rxn_index, ReactionRate &rate) override
Replace reaction rate object handled by the evaluator.
Definition: MultiRate.h:42
virtual 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:91
virtual void getRateConstants(double *kf) override
Evaluate all rate constants handled by the evaluator.
Definition: MultiRate.h:67
void _process_ddT(double *rop, const double *kf, double deltaT)
Helper function to process temperature derivatives for rate types that implement the ddTScaledFromStr...
Definition: MultiRate.h:168
virtual void update(double T) override
Update common reaction rate data based on temperature.
Definition: MultiRate.h:101
virtual std::string type() override
Identifier of reaction rate type.
Definition: MultiRate.h:28
virtual double evalSingle(ReactionRate &rate) override
Get the rate for a single reaction.
Definition: MultiRate.h:126
void _process_ddP(double *rop, const double *kf, double deltaP)
Helper function to process pressure derivatives for rate data that implement the perturbPressure meth...
Definition: MultiRate.h:238
void _update()
Helper function to process updates for rate types that implement the updateFromStruct method.
Definition: MultiRate.h:137
void _updateRate(RateType &rate)
Helper function to update a single rate that has an updateFromStruct method`.
Definition: MultiRate.h:153
virtual void update(double T, const vector_fp &extra) override
Update common reaction rate data based on temperature and extra parameter.
Definition: MultiRate.h:111
void _process_ddM(double *rop, const double *kf, double deltaM, bool overwrite)
Helper function to process third-body derivatives for rate data that implement the perturbThirdBodies...
Definition: MultiRate.h:201
DataType m_shared
Mapping of indices.
Definition: MultiRate.h:267
virtual 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:73
virtual void add(size_t rxn_index, ReactionRate &rate) override
Add reaction rate object to the evaluator.
Definition: MultiRate.h:36
virtual void update(double T, double extra) override
Update common reaction rate data based on temperature and extra parameter.
Definition: MultiRate.h:106
Abstract base class for reaction rate definitions; this base class is used by user-facing APIs to acc...
Definition: ReactionRate.h:45
virtual const std::string type() const =0
String identifying reaction rate specialization.
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:102
Namespace for the Cantera kernel.
Definition: AnyMap.h:29
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:184
Various templated functions that carry out common vector operations (see Templated Utility Functions)...
#define CT_DEFINE_HAS_MEMBER(detector_name, func_name)
A macro for generating member function detectors, which can then be used in combination with std::ena...
Definition: utilities.h:193