Cantera  3.1.0a1
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
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:66
Public interface for kinetics managers.
Definition: Kinetics.h:125
An abstract base class for evaluating all reactions of a particular type.
Definition: MultiRateBase.h:28
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:124
void getRateConstants(double *kf) override
Evaluate all rate constants handled by the evaluator.
Definition: MultiRate.h:68
bool update(const ThermoPhase &phase, const Kinetics &kin) override
Update data common to reaction rates of a specific type.
Definition: MultiRate.h:171
string type() override
Identifier of reaction rate type.
Definition: MultiRate.h:29
void update(double T, const vector< double > &extra) override
Update common reaction rate data based on temperature and extra parameter.
Definition: MultiRate.h:166
void update(double T) override
Update common reaction rate data based on temperature.
Definition: MultiRate.h:156
bool replace(size_t rxn_index, ReactionRate &rate) override
Replace reaction rate object handled by the evaluator.
Definition: MultiRate.h:43
void resize(size_t nSpecies, size_t nReactions, size_t nPhases) override
Update number of species and reactions.
Definition: MultiRate.h:63
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
double evalSingle(ReactionRate &rate) override
Get the rate for a single reaction.
Definition: MultiRate.h:181
void _update()
Helper function to process updates.
Definition: MultiRate.h:197
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
DataType m_shared
Mapping of indices.
Definition: MultiRate.h:208
void add(size_t rxn_index, ReactionRate &rate) override
Add reaction rate object to the evaluator.
Definition: MultiRate.h:37
DataType & sharedData()
Access the underlying shared data object.
Definition: MultiRate.h:191
void update(double T, double extra) override
Update common reaction rate data based on temperature and extra parameter.
Definition: MultiRate.h:161
vector< pair< size_t, RateType > > m_rxn_rates
Vector of pairs of reaction rates indices and reaction rates.
Definition: MultiRate.h:206
Abstract base class for reaction rate definitions; this base class is used by user-facing APIs to acc...
Definition: ReactionRate.h:49
virtual const string type() const =0
String identifying reaction rate specialization.
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:390
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:564
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