19#include <unordered_set>
20#include <boost/algorithm/string.hpp>
28 const vector<shared_ptr<ThermoPhase>>& phases)
const
30 vector<AnyMap> reactionDefs;
32 reactionDefs.push_back(
reaction(i)->parameters());
35 phaseNode[
"__fix-duplicate-reactions__"] =
true;
37 rootNode[
"reactions"] = std::move(reactionDefs);
70 "To be removed after Cantera 3.2. Only used by legacy CLib.");
88 "To be removed after Cantera 3.2. Unused.");
98 warn_deprecated(
"Kinetics::phaseIndex",
"'raise' argument not specified. "
99 "Default behavior will change from returning npos to throwing an "
100 "exception after Cantera 3.2.");
109 throw CanteraError(
"Kinetics::phaseIndex",
"Phase '{}' not found", ph);
127 throw IndexError(
"Kinetics::checkSpeciesIndex",
"species", k,
m_kk);
133 "To be removed after Cantera 3.2. Only used by legacy CLib.");
141 if (flag ==
"warn" || flag ==
"error" || flag ==
"mark-duplicate"
142 || flag ==
"modify-efficiency")
144 m_explicit_third_body_duplicates = flag;
146 throw CanteraError(
"Kinetics::setExplicitThirdBodyDuplicateHandling",
147 "Invalid flag '{}'", flag);
154 map<size_t, vector<size_t>> participants;
155 vector<map<int, double>> net_stoich;
156 std::unordered_set<size_t> unmatched_duplicates;
159 unmatched_duplicates.insert(i);
163 vector<InputFileError> errs;
166 unsigned long int key = 0;
168 net_stoich.emplace_back();
169 map<int, double>& net = net_stoich.back();
170 for (
const auto& [name, stoich] : R.
reactants) {
173 net[-1 -k] -= stoich;
175 for (
const auto& [name, stoich] : R.
products) {
182 vector<size_t>& related = participants[key];
183 for (
size_t m : related) {
187 unmatched_duplicates.erase(i);
188 unmatched_duplicates.erase(m);
190 }
else if (R.
type() != other.
type()) {
193 && R.
rate()->type() != other.
rate()->type())
205 bool thirdBodyOk =
true;
217 }
else if ((tb1.
name() ==
"M") != (tb2.
name() ==
"M")) {
219 if (m_explicit_third_body_duplicates ==
"mark-duplicate") {
223 }
else if (m_explicit_third_body_duplicates ==
"modify-efficiency") {
224 if (tb1.
name() ==
"M") {
230 }
else if (m_explicit_third_body_duplicates ==
"warn") {
233 "Undeclared duplicate third body reactions with a common "
234 "third body detected.\nAdd the field "
235 "'explicit-third-body-duplicates: mark-duplicate' or\n"
236 "'explicit-third-body-duplicates: modify-efficiency' to "
237 "the YAML phase entry\nto choose how these reactions "
238 "should be handled and suppress this warning.\n"
239 "Reaction {}: {}\nReaction {}: {}\n",
249 errs.emplace_back(
"Kinetics::checkDuplicates",
251 "Undeclared duplicate reactions detected:\n"
252 "Reaction {}: {}\nReaction {}: {}\n",
257 unmatched_duplicates.erase(i);
258 unmatched_duplicates.erase(m);
263 participants[key].push_back(i);
265 if (unmatched_duplicates.size()) {
266 for (
auto i : unmatched_duplicates) {
268 errs.emplace_back(
"Kinetics::checkDuplicates",
270 "No duplicate found for declared duplicate reaction number {}"
281 }
else if (errs.size() == 1) {
284 fmt::memory_buffer msg;
285 for (
const auto& err : errs) {
286 fmt_append(msg,
"\n{}\n", err.getMessage());
288 throw CanteraError(
"Kinetics::checkDuplicates", to_string(msg));
294 std::unordered_set<int> keys;
295 for (
auto& [speciesKey, stoich] : r1) {
296 keys.insert(speciesKey);
298 for (
auto& [speciesKey, stoich] : r2) {
299 keys.insert(speciesKey);
301 int k1 = r1.begin()->first;
304 if (r1[k1] && r2[k1]) {
305 ratio = r2[k1]/r1[k1];
306 bool different =
false;
308 if ((r1[k] && !r2[k]) ||
310 (r1[k] && fabs(r2[k]/r1[k] - ratio) > 1.e-8)) {
321 if (r1[k1] == 0.0 || r2[-k1] == 0.0) {
324 ratio = r2[-k1]/r1[k1];
326 if ((r1[k] && !r2[-k]) ||
327 (!r1[k] && r2[-k]) ||
328 (r1[k] && fabs(r2[-k]/r1[k] - ratio) > 1.e-8)) {
338 if (ret ==
"<unknown>") {
339 warn_deprecated(
"Kinetics::kineticsSpeciesName",
"Behavior will change from "
340 "returning '<unknown>' to throwing an exception after Cantera 3.2.");
347 for (
size_t n =
m_start.size()-1; n !=
npos; n--) {
354 throw IndexError(
"Kinetics::kineticsSpeciesName",
"totalSpecies", k,
m_kk);
363 warn_deprecated(
"Kinetics::kineticsSpeciesIndex",
"'raise' argument not "
364 "specified. Default behavior will change from returning npos to throwing "
365 "an exception after Cantera 3.2.");
372 for (
size_t n = 0; n <
m_thermo.size(); n++) {
381 "Species '{}' not found", nm);
388 for (
size_t n = 0; n <
m_thermo.size(); n++) {
394 throw CanteraError(
"Kinetics::speciesPhase",
"unknown species '{}'", nm);
404 throw CanteraError(
"Kinetics::speciesPhase",
"unknown species '{}'", nm);
409 for (
size_t n =
m_start.size()-1; n !=
npos; n--) {
415 "illegal species index: {}", k);
448 fill(deltaProp, deltaProp +
nReactions(), 0.0);
457 fill(deltaProp, deltaProp +
nReactions(), 0.0);
469 fill(cdot, cdot +
m_kk, 0.0);
482 fill(ddot, ddot +
m_kk, 0.0);
493 fill(net, net +
m_kk, 0.0);
502 Eigen::Map<Eigen::VectorXd> out(dwdot,
m_kk);
514 Eigen::Map<Eigen::VectorXd> out(dwdot,
m_kk);
526 Eigen::Map<Eigen::VectorXd> out(dwdot,
m_kk);
538 Eigen::SparseMatrix<double> jac;
548 Eigen::SparseMatrix<double> jac;
558 Eigen::Map<Eigen::VectorXd> out(dwdot,
m_kk);
570 Eigen::Map<Eigen::VectorXd> out(dwdot,
m_kk);
582 Eigen::Map<Eigen::VectorXd> out(dwdot,
m_kk);
594 Eigen::SparseMatrix<double> jac;
604 Eigen::SparseMatrix<double> jac;
614 Eigen::Map<Eigen::VectorXd> out(dwdot,
m_kk);
622 Eigen::Map<Eigen::VectorXd> out(dwdot,
m_kk);
630 Eigen::Map<Eigen::VectorXd> out(dwdot,
m_kk);
653 "The reacting (lowest dimensional) phase must be added first.");
666 phaseNode.
getString(
"explicit-third-body-duplicates",
"warn"));
668 if (phaseNode.
hasKey(
"rate-multipliers")) {
669 const auto& defaultMultipliers = phaseNode[
"rate-multipliers"];
670 for (
auto& [key, val] : defaultMultipliers) {
671 if (key ==
"default") {
683 string name = KineticsFactory::factory()->canonicalize(
kineticsType());
684 if (name !=
"none") {
685 out[
"kinetics"] = name;
687 out[
"reactions"] =
"none";
690 out[
"skip-undeclared-third-bodies"] =
true;
692 if (m_explicit_third_body_duplicates ==
"error") {
696 out[
"explicit-third-body-duplicates"] =
"error";
698 map<double, int> multipliers;
702 if (
static_cast<size_t>(multipliers[1.0]) != (
nReactions())) {
703 int defaultCount = 0;
704 double defaultMultiplier = 1.0;
705 for (
auto& [m, count] : multipliers) {
706 if (count > defaultCount) {
707 defaultCount = count;
708 defaultMultiplier = m;
712 multiplierMap[
"default"] = defaultMultiplier;
715 multiplierMap[to_string(i)] =
m_perturb[i];
718 out[
"rate-multipliers"] = multiplierMap;
729 for (
size_t i = 0; i <
m_thermo.size(); i++) {
747 if (!r->checkSpecies(*
this)) {
754 if (r->rate_units.factor() == 0) {
755 r->rate()->setRateUnits(r->calculateRateCoeffUnits(*
this));
761 vector<size_t> rk, pk;
765 vector<double> rstoich, pstoich;
767 for (
const auto& [name, stoich] : r->reactants) {
769 rstoich.push_back(stoich);
772 for (
const auto& [name, stoich] : r->products) {
774 pstoich.push_back(stoich);
780 vector<double> rorder = rstoich;
781 for (
const auto& [name, order] : r->orders) {
784 auto rloc = std::find(rk.begin(), rk.end(), k);
785 if (rloc != rk.end()) {
786 rorder[rloc - rk.begin()] = order;
793 rstoich.push_back(0.0);
794 rorder.push_back(order);
809 m_rfn.push_back(0.0);
834 if (rNew->rate()->type() ==
"electron-collision-plasma") {
836 "Type electron-collision-plasma is not supported. "
837 "Use the rate object of the reaction to modify the data.");
840 if (rNew->type() != rOld->type()) {
842 "Reaction types are different: {} != {}.",
843 rOld->type(), rNew->type());
846 if (rNew->rate()->type() != rOld->rate()->type()) {
848 "ReactionRate types are different: {} != {}.",
849 rOld->rate()->type(), rNew->rate()->type());
852 if (rNew->reactants != rOld->reactants) {
854 "Reactants are different: '{}' != '{}'.",
855 rOld->reactantString(), rNew->reactantString());
858 if (rNew->products != rOld->products) {
860 "Products are different: '{}' != '{}'.",
861 rOld->productString(), rNew->productString());
Base class for kinetics managers and also contains the kineticsmgr module documentation (see Kinetics...
Header file for class ThermoPhase, the base class for phases with thermodynamic properties,...
A map of string keys to values whose type can vary at runtime.
bool hasKey(const string &key) const
Returns true if the map contains an item named key.
void applyUnits()
Use the supplied UnitSystem to set the default units, and recursively process overrides from nodes na...
bool getBool(const string &key, bool default_) const
If key exists, return it as a bool, otherwise return default_.
const string & getString(const string &key, const string &default_) const
If key exists, return it as a string, otherwise return default_.
Base class for exceptions thrown by Cantera classes.
const char * what() const override
Get a description of the error.
An array index is out of range.
virtual void resizeReactions()
Finalize Kinetics object and associated objects.
void checkSpeciesArraySize(size_t mm) const
Check that an array size is at least nSpecies() Throws an exception if kk is less than nSpecies().
virtual void getFwdRatesOfProgress(double *fwdROP)
Return the forward rates of progress of the reactions.
virtual void setParameters(const AnyMap &phaseNode)
Set kinetics-related parameters from an AnyMap phase description.
size_t checkPhaseIndex(size_t m) const
Check that the specified phase index is in range.
ThermoPhase & thermo(size_t n=0)
This method returns a reference to the nth ThermoPhase object defined in this kinetics mechanism.
vector< shared_ptr< Reaction > > m_reactions
Vector of Reaction objects represented by this Kinetics manager.
double checkDuplicateStoich(map< int, double > &r1, map< int, double > &r2) const
Check whether r1 and r2 represent duplicate stoichiometries This function returns a ratio if two reac...
vector< double > m_perturb
Vector of perturbation factors for each reaction's rate of progress vector.
vector< double > m_ropf
Forward rate-of-progress for each reaction.
shared_ptr< Reaction > reaction(size_t i)
Return the Reaction object for reaction i.
virtual void getRevReactionDelta(const double *g, double *dg) const
Given an array of species properties 'g', return in array 'dg' the change in this quantity in the rev...
void setExplicitThirdBodyDuplicateHandling(const string &flag)
Specify how to handle duplicate third body reactions where one reaction has an explicit third body an...
virtual void getNetRatesOfProgress(double *netROP)
Net rates of progress.
size_t phaseIndex(const string &ph) const
Return the phase index of a phase in the list of phases defined within the object.
vector< size_t > m_start
m_start is a vector of integers specifying the beginning position for the species vector for the n'th...
virtual string kineticsType() const
Identifies the Kinetics manager type.
vector< double > m_rkcn
Reciprocal of the equilibrium constant in concentration units.
shared_ptr< ThermoPhase > reactionPhase() const
Return pointer to phase where the reactions occur.
size_t m_kk
The number of species in all of the phases that participate in this kinetics mechanism.
virtual pair< size_t, size_t > checkDuplicates(bool throw_err=true, bool fix=false)
Check for unmarked duplicate reactions and unmatched marked duplicates.
virtual void getReactionDelta(const double *property, double *deltaProperty) const
Change in species properties.
void checkPhaseArraySize(size_t mm) const
Check that an array size is at least nPhases() Throws an exception if mm is less than nPhases().
vector< double > m_dH
The enthalpy change for each reaction to calculate Blowers-Masel rates.
vector< double > m_ropr
Reverse rate-of-progress for each reaction.
size_t nPhases() const
The number of phases participating in the reaction mechanism.
vector< shared_ptr< ThermoPhase > > m_thermo
m_thermo is a vector of pointers to ThermoPhase objects that are involved with this kinetics operator
map< void *, function< void()> > m_reactionAddedCallbacks
Callback functions that are invoked when the reaction is added.
AnyMap parameters() const
Return the parameters for a phase definition which are needed to reconstruct an identical object usin...
virtual bool addReaction(shared_ptr< Reaction > r, bool resize=true)
Add a single reaction to the mechanism.
vector< size_t > m_revindex
Indices of reversible reactions.
string kineticsSpeciesName(size_t k) const
Return the name of the kth species in the kinetics manager.
virtual void getDestructionRates(double *ddot)
Species destruction rates [kmol/m^3/s or kmol/m^2/s].
virtual void init()
Prepare the class for the addition of reactions, after all phases have been added.
shared_ptr< Solution > root() const
Get the Solution object containing this Kinetics object and associated ThermoPhase objects.
virtual void modifyReaction(size_t i, shared_ptr< Reaction > rNew)
Modify the rate expression associated with a reaction.
vector< double > m_ropnet
Net rate-of-progress for each reaction.
void skipUndeclaredThirdBodies(bool skip)
Determine behavior when adding a new reaction that contains third-body efficiencies for species not d...
virtual double productStoichCoeff(size_t k, size_t i) const
Stoichiometric coefficient of species k as a product in reaction i.
virtual void addThermo(shared_ptr< ThermoPhase > thermo)
Add a phase to the kinetics manager object.
vector< double > m_rbuf
Buffer used for storage of intermediate reaction-specific results.
Eigen::SparseMatrix< double > m_stoichMatrix
Net stoichiometry (products - reactants)
map< string, size_t > m_phaseindex
Mapping of the phase name to the position of the phase within the kinetics object.
size_t m_mindim
number of spatial dimensions of lowest-dimensional phase.
StoichManagerN m_productStoich
Stoichiometry manager for the products for each reaction.
StoichManagerN m_revProductStoich
Stoichiometry manager for the products of reversible reactions.
shared_ptr< Kinetics > clone(const vector< shared_ptr< ThermoPhase > > &phases) const
Create a new Kinetics object with the same kinetics model and reactions as this one.
size_t nReactions() const
Number of reactions in the reaction mechanism.
map< size_t, double > m_defaultPerturb
Default values for perturbations defined in the phase definition's rate-multipliers field.
virtual void getRevRatesOfProgress(double *revROP)
Return the Reverse rates of progress of the reactions.
vector< size_t > m_irrev
Indices of irreversible reactions.
bool m_hasUndeclaredThirdBodies
Flag indicating whether reactions include undeclared third bodies.
size_t kineticsSpeciesIndex(size_t k, size_t n) const
The location of species k of phase n in species arrays.
vector< double > m_rfn
Forward rate constant for each reaction.
size_t checkSpeciesIndex(size_t k) const
Check that the specified species index is in range.
StoichManagerN m_reactantStoich
Stoichiometry manager for the reactants for each reaction.
virtual void resizeSpecies()
Resize arrays with sizes that depend on the total number of species.
void checkReactionArraySize(size_t ii) const
Check that an array size is at least nReactions() Throws an exception if ii is less than nReactions()...
size_t nTotalSpecies() const
The total number of species in all phases participating in the kinetics mechanism.
virtual double reactantStoichCoeff(size_t k, size_t i) const
Stoichiometric coefficient of species k as a reactant in reaction i.
virtual void getNetProductionRates(double *wdot)
Species net production rates [kmol/m^3/s or kmol/m^2/s].
ThermoPhase & speciesPhase(const string &nm)
This function looks up the name of a species and returns a reference to the ThermoPhase object of the...
vector< double > m_delta_gibbs0
Delta G^0 for all reactions.
size_t checkReactionIndex(size_t m) const
Check that the specified reaction index is in range.
virtual void getCreationRates(double *cdot)
Species creation rates [kmol/m^3/s or kmol/m^2/s].
size_t speciesPhaseIndex(size_t k) const
This function takes as an argument the kineticsSpecies index (that is, the list index in the list of ...
size_t nDim() const
Returns the number of spatial dimensions (1, 2, or 3)
string speciesName(size_t k) const
Name of the species with index k.
size_t speciesIndex(const string &name) const
Returns the index of a species named 'name' within the Phase object.
Abstract base class which stores data about a reaction and its rate parameterization so that it can b...
shared_ptr< ReactionRate > rate()
Get reaction rate pointer.
bool usesThirdBody() const
Check whether reaction involves third body collider.
shared_ptr< ThirdBody > thirdBody()
Get pointer to third-body handler.
bool reversible
True if the current reaction is reversible. False otherwise.
string type() const
The type of reaction, including reaction rate information.
string equation() const
The chemical equation for this reaction.
Composition products
Product species and stoichiometric coefficients.
Composition reactants
Reactant species and stoichiometric coefficients.
AnyMap input
Input data used for specific models.
bool duplicate
True if the current reaction is marked as duplicate.
void resizeCoeffs(size_t nSpc, size_t nRxn)
Resize the sparse coefficient matrix.
void add(size_t rxn, const vector< size_t > &k)
Add a single reaction to the list of reactions that this stoichiometric manager object handles.
const Eigen::SparseMatrix< double > & stoichCoeffs() const
Return matrix containing stoichiometric coefficients.
Base class for a phase with thermodynamic properties.
A class for managing third-body efficiencies, including default values.
double efficiency(const string &k) const
Get the third-body efficiency for species k
Composition efficiencies
Map of species to third body efficiency.
string name() const
Name of the third body collider.
This file contains definitions for utility functions and text for modules, inputfiles and logging,...
virtual Eigen::SparseMatrix< double > fwdRatesOfProgress_ddCi()
Calculate derivatives for forward rates-of-progress with respect to species concentration at constant...
Eigen::SparseMatrix< double > creationRates_ddCi()
Calculate derivatives for species creation rates with respect to species concentration at constant te...
virtual Eigen::SparseMatrix< double > netRatesOfProgress_ddCi()
Calculate derivatives for net rates-of-progress with respect to species concentration at constant tem...
void getCreationRates_ddT(double *dwdot)
Calculate derivatives for species creation rates with respect to temperature at constant pressure,...
virtual Eigen::SparseMatrix< double > netRatesOfProgress_ddX()
Calculate derivatives for net rates-of-progress with respect to species mole fractions at constant te...
Eigen::SparseMatrix< double > destructionRates_ddX()
Calculate derivatives for species destruction rates with respect to species mole fractions at constan...
void getCreationRates_ddC(double *dwdot)
Calculate derivatives for species creation rates with respect to molar concentration at constant temp...
void getDestructionRates_ddP(double *dwdot)
Calculate derivatives for species destruction rates with respect to pressure at constant temperature,...
void getNetProductionRates_ddC(double *dwdot)
Calculate derivatives for species net production rates with respect to molar concentration at constan...
void getDestructionRates_ddT(double *dwdot)
Calculate derivatives for species destruction rates with respect to temperature at constant pressure,...
virtual void getFwdRatesOfProgress_ddP(double *drop)
Calculate derivatives for forward rates-of-progress with respect to pressure at constant temperature,...
Eigen::SparseMatrix< double > netProductionRates_ddX()
Calculate derivatives for species net production rates with respect to species mole fractions at cons...
Eigen::SparseMatrix< double > creationRates_ddX()
Calculate derivatives for species creation rates with respect to species mole fractions at constant t...
Eigen::SparseMatrix< double > destructionRates_ddCi()
Calculate derivatives for species destruction rates with respect to species concentration at constant...
void getNetProductionRates_ddT(double *dwdot)
Calculate derivatives for species net production rates with respect to temperature at constant pressu...
virtual Eigen::SparseMatrix< double > fwdRatesOfProgress_ddX()
Calculate derivatives for forward rates-of-progress with respect to species mole fractions at constan...
virtual void getRevRatesOfProgress_ddT(double *drop)
Calculate derivatives for reverse rates-of-progress with respect to temperature at constant pressure,...
void getCreationRates_ddP(double *dwdot)
Calculate derivatives for species creation rates with respect to pressure at constant temperature,...
virtual void getNetRatesOfProgress_ddT(double *drop)
Calculate derivatives for net rates-of-progress with respect to temperature at constant pressure,...
virtual void getRevRatesOfProgress_ddP(double *drop)
Calculate derivatives for reverse rates-of-progress with respect to pressure at constant temperature,...
Eigen::SparseMatrix< double > netProductionRates_ddCi()
Calculate derivatives for species net production rates with respect to species concentration at const...
virtual void getRevRatesOfProgress_ddC(double *drop)
Calculate derivatives for reverse rates-of-progress with respect to molar concentration at constant t...
void getNetProductionRates_ddP(double *dwdot)
Calculate derivatives for species net production rates with respect to pressure at constant temperatu...
virtual void getNetRatesOfProgress_ddP(double *drop)
Calculate derivatives for net rates-of-progress with respect to pressure at constant temperature,...
virtual Eigen::SparseMatrix< double > revRatesOfProgress_ddCi()
Calculate derivatives for forward rates-of-progress with respect to species concentration at constant...
virtual void getFwdRatesOfProgress_ddT(double *drop)
Calculate derivatives for forward rates-of-progress with respect to temperature at constant pressure,...
void getDestructionRates_ddC(double *dwdot)
Calculate derivatives for species destruction rates with respect to molar concentration at constant t...
virtual void getNetRatesOfProgress_ddC(double *drop)
Calculate derivatives for net rates-of-progress with respect to molar concentration at constant tempe...
virtual Eigen::SparseMatrix< double > revRatesOfProgress_ddX()
Calculate derivatives for reverse rates-of-progress with respect to species mole fractions at constan...
virtual void getFwdRatesOfProgress_ddC(double *drop)
Calculate derivatives for forward rates-of-progress with respect to molar concentration at constant t...
shared_ptr< Kinetics > newKinetics(const string &model)
Create a new Kinetics instance.
void warn_user(const string &method, const string &msg, const Args &... args)
Print a user warning raised from method as CanteraWarning.
Namespace for the Cantera kernel.
const size_t npos
index returned by functions to indicate "no position"
void warn_deprecated(const string &source, const AnyBase &node, const string &message)
A deprecation warning for syntax in an input file.
const U & getValue(const map< T, U > &m, const T &key, const U &default_val)
Const accessor for a value in a map.
Contains declarations for string manipulation functions within Cantera.
Various templated functions that carry out common vector and polynomial operations (see Templated Arr...