| Cantera 3.0.0

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