Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make reactions extendable #982

Merged
merged 67 commits into from
Mar 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
9f9e9d8
[Kinetics] create ReactionFactory
Nov 5, 2019
aaf3f31
[Kinetics] add Reaction::type method
Nov 7, 2019
4e718f4
[Kinetics] add setup function wrappers to ReactionFactory
Nov 9, 2019
14115f9
[Kinetics] remove magic numbers from Python interface
ischoegl Nov 8, 2019
bb26e7c
[Kinetics] simplify newReaction
Nov 9, 2019
e7958be
[Kinetics] make GasKinetics extendable
ischoegl Nov 11, 2019
d117c94
[Kinetics] buffer available Reaction class constructors in Cython
ischoegl Nov 14, 2019
d2f6634
[Kinetics] move isElectrochemicalReaction
Dec 28, 2019
2c94aca
[Reaction] replace m_synonyms by addAlias
ischoegl Jan 27, 2020
8918c36
[Kinetics] ensure correct setup routine is called for XML node
ischoegl Feb 21, 2021
8eedf28
[Kinetics] add missing header files
ischoegl Feb 22, 2021
c3123b1
[Scons] add reference to test-help after build
ischoegl Feb 22, 2021
c35c983
[Kinetics] initial draft for custom reaction rate defined in Python
ischoegl Feb 22, 2021
93ce06a
[Kinetics] create rudimentary hooks for CustomPyReaction
ischoegl Feb 22, 2021
37ce114
[Kinetics] expose CustomReaction to Python
ischoegl Feb 22, 2021
7d8ecbe
[Kinetics] implement Python constructor for CustomReaction
ischoegl Feb 23, 2021
9126fb5
[Kinetics] implement setup of CustomReaction
ischoegl Feb 23, 2021
43261de
[Kinetics] introduce boolean to mark reaction validity
ischoegl Feb 27, 2021
d499527
[Kinetics] replace magic numbers
ischoegl Feb 27, 2021
4c14bb7
[Kinetics] create hooks in GasKinetics
ischoegl Feb 27, 2021
0829793
[Kinetics] add initial unit tests
ischoegl Feb 26, 2021
1c525f7
[Kinetics] simplify naming of CustomPyRate
ischoegl Feb 27, 2021
e99fd79
[Kinetics] add default constructor for C++ Reaction
ischoegl Feb 27, 2021
d7e0382
[Kinetics] mark unused reaction type magic numbers
ischoegl Feb 27, 2021
fa48c1e
[Kinetics] Replace remaining references to reaction_type
ischoegl Feb 27, 2021
7a4fa08
[Kinetics] expose reaction_type_str to Python
ischoegl Feb 27, 2021
20b7621
[Kinetics] deprecate functions referencing magic numbers
ischoegl Feb 27, 2021
5575336
[Kinetics] finalize deprecation of reaction type magic numbers
ischoegl Feb 27, 2021
e8bce32
[Kinetics] make C++ pure abstract base class
ischoegl Feb 28, 2021
29101a2
[Func1] make CxxFunc1 shareable
ischoegl Feb 28, 2021
436f1ee
[Kinetics] make CustomRate persistent withing CustomReaction
ischoegl Feb 28, 2021
f71cfb6
[Kinetics] Create C++ abstract base class RxnRate
ischoegl Feb 28, 2021
18a2ad3
[Kinetics] enable calculation of rate constants for CustomReaction
ischoegl Mar 1, 2021
8d1571b
[Kinetics] generalize addition of RxnRate in GasKinetics
ischoegl Mar 1, 2021
71c7150
[Kinetics] add alternative ArrheniusRate
ischoegl Mar 1, 2021
d5930d5
[Kinetics] update state used for RxnRate calculations
ischoegl Mar 1, 2021
359f721
[Func1] prevent invalid callback functions.
ischoegl Mar 1, 2021
4c181c0
[UnitTest] Create stand-alone file to test reactions
ischoegl Mar 1, 2021
b1efc54
[Kinetics] create TestReaction for benchmarking purposes
ischoegl Mar 1, 2021
fe3e96d
[UnitTest] include new test in __init__
ischoegl Mar 1, 2021
7125e11
[Kinetics] expose TestReaction to Python interface
ischoegl Mar 2, 2021
f467be1
[UnitTest] add tests for TestReaction
ischoegl Mar 2, 2021
aa23b52
[samples] illustrate usage of Python CustomReaction
ischoegl Mar 2, 2021
139323a
[Kinetics] minor simplifications and edits
ischoegl Mar 2, 2021
7a4e9f3
[Kinetics] eliminate reg_addRxn and reg_modRxn
ischoegl Mar 6, 2021
54e7e65
[Kinetics] make RxnRate thread-safe
ischoegl Mar 6, 2021
6e51231
[Kinetics] create State data container for RxnRate evaluations
ischoegl Mar 6, 2021
684ca49
[Kinetics] mark derived RxnRate classes as 'final'
ischoegl Mar 7, 2021
d393bba
[Kinetics] switch from map to vector of RxnRate pointers
ischoegl Mar 7, 2021
7188f81
[Kinetics] store specialized reaction rate types separately
ischoegl Mar 7, 2021
77bda94
[examples] switch custom_reactions.py to gri30.yaml
ischoegl Mar 6, 2021
ac8fc76
[Kinetics] store specialized RxnRate objects without pointers
ischoegl Mar 7, 2021
8c07226
[kinetics] add signatures for analytical derivatives to RxnRates
ischoegl Mar 7, 2021
7622fda
[Kinetics] address 'simple' review comments for new reaction framework
ischoegl Mar 13, 2021
4d086a6
[Kinetics] introduce reaction-rate specific shared data types
ischoegl Mar 13, 2021
efbe7bc
[Kinetics] create ArrheniusRate from AnyMap
ischoegl Mar 14, 2021
7362930
[Kinetics] add XML related 'todo' comments to ReactionFactory
ischoegl Mar 14, 2021
0454bf4
[Kinetics] implement Reaction::setup method
ischoegl Mar 14, 2021
aa4d072
[Kinetics] add MultiRateBase evaluator class
ischoegl Mar 14, 2021
1b15047
[Kinetics] switch to MultiRateBase framework
ischoegl Mar 14, 2021
d046a0f
[Kinetics] minor updates
ischoegl Mar 15, 2021
b3194f6
[Kinetics] add intermediate class Reaction2 as base for new framework
ischoegl Mar 15, 2021
a69c25f
[Func1] roll back blocking method callbacks
ischoegl Mar 18, 2021
8f78505
[Kinetics] implement review comments
ischoegl Mar 19, 2021
5fb1813
[Kinetics] finalize ReactionRate and corresponding data types
ischoegl Mar 19, 2021
5369f51
[Kinetics] simplify Reaction.wrap
ischoegl Mar 19, 2021
b770450
[Kinetics] rename Reaction2::setup to Reaction2::setParameters
ischoegl Mar 19, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -1746,6 +1746,7 @@ def postBuildMessage(target, source, env):
print("*******************************************************")
print("Compilation completed successfully.\n")
print("- To run the test suite, type 'scons test'.")
print("- To list available tests, type 'scons test-help'.")
if env['googletest'] == 'none':
print(" WARNING: You set the 'googletest' to 'none' and all it's tests will be skipped.")
if os.name == 'nt':
Expand Down
7 changes: 7 additions & 0 deletions include/cantera/kinetics/BulkKinetics.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "Kinetics.h"
#include "RateCoeffMgr.h"
#include "cantera/kinetics/MultiRate.h"

namespace Cantera
{
Expand All @@ -37,6 +38,8 @@ class BulkKinetics : public Kinetics
bool doIrreversible = false);

virtual bool addReaction(shared_ptr<Reaction> r);
virtual void modifyReaction(size_t i, shared_ptr<Reaction> rNew);

virtual void resizeSpecies();

virtual void setMultiplier(size_t i, double f);
Expand All @@ -46,6 +49,10 @@ class BulkKinetics : public Kinetics
virtual void addElementaryReaction(ElementaryReaction& r);
virtual void modifyElementaryReaction(size_t i, ElementaryReaction& rNew);

//! Vector of rate handlers
std::vector<unique_ptr<MultiRateBase>> m_bulk_rates;
std::map<std::string, size_t> m_bulk_types; //!< Mapping of rate handlers

Rate1<Arrhenius> m_rates;
std::vector<size_t> m_revindex; //!< Indices of reversible reactions
std::vector<size_t> m_irrev; //!< Indices of irreversible reactions
Expand Down
33 changes: 28 additions & 5 deletions include/cantera/kinetics/FalloffMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#define CT_FALLOFFMGR_H

#include "Falloff.h"
#include "cantera/base/global.h"

namespace Cantera
{
Expand All @@ -32,13 +33,35 @@ class FalloffMgr
* determine which array entry is modified in method pr_to_falloff.
* @param reactionType Either `FALLOFF_RXN` or `CHEMACT_RXN`
* @param f The falloff function.
*
* @deprecated To be removed after Cantera 2.6.
*/
void install(size_t rxn, int reactionType, shared_ptr<Falloff> f) {
warn_deprecated("FalloffMgr::install()",
"To be removed after Cantera 2.6. Specify reaction type using "
"string instead.");

m_rxn.push_back(rxn);
m_offset.push_back(m_worksize);
m_worksize += f->workSize();
m_falloff.push_back(f);
m_isfalloff.push_back(reactionType == FALLOFF_RXN);
m_indices[rxn] = m_falloff.size()-1;
}

//! Install a new falloff function calculator.
/*
* @param rxn Index of the falloff reaction. This will be used to
* determine which array entry is modified in method pr_to_falloff.
* @param type Reaction type identifier.
* @param f The falloff function.
*/
void install(size_t rxn, std::string type, shared_ptr<Falloff> f) {
m_rxn.push_back(rxn);
m_offset.push_back(m_worksize);
m_worksize += f->workSize();
m_falloff.push_back(f);
m_reactionType.push_back(reactionType);
m_isfalloff.push_back(type == "falloff");
m_indices[rxn] = m_falloff.size()-1;
}

Expand Down Expand Up @@ -76,14 +99,14 @@ class FalloffMgr
void pr_to_falloff(doublereal* values, const doublereal* work) {
for (size_t i = 0; i < m_rxn.size(); i++) {
double pr = values[m_rxn[i]];
if (m_reactionType[i] == FALLOFF_RXN) {
if (m_isfalloff[i]) {
// Pr / (1 + Pr) * F
values[m_rxn[i]] *=
m_falloff[i]->F(pr, work + m_offset[i]) /(1.0 + pr);
m_falloff[i]->F(pr, work + m_offset[i]) / (1.0 + pr);
} else {
// 1 / (1 + Pr) * F
values[m_rxn[i]] =
m_falloff[i]->F(pr, work + m_offset[i]) /(1.0 + pr);
m_falloff[i]->F(pr, work + m_offset[i]) / (1.0 + pr);
}
}
}
Expand All @@ -96,7 +119,7 @@ class FalloffMgr
size_t m_worksize;

//! Distinguish between falloff and chemically activated reactions
vector_int m_reactionType;
std::vector<bool> m_isfalloff;

//! map of external reaction index to local index
std::map<size_t, size_t> m_indices;
Expand Down
10 changes: 10 additions & 0 deletions include/cantera/kinetics/Kinetics.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "StoichManager.h"
#include "cantera/base/ValueCache.h"
#include "cantera/kinetics/ReactionFactory.h"

namespace Cantera
{
Expand Down Expand Up @@ -601,9 +602,18 @@ class Kinetics
* are specific to the particular kinetics manager.
*
* @param i reaction index
*
* @deprecated To be changed after Cantera 2.6.
*/
virtual int reactionType(size_t i) const;

/**
* String specifying the type of reaction.
*
* @param i reaction index
*/
virtual std::string reactionTypeStr(size_t i) const;

/**
* True if reaction i has been declared to be reversible. If isReversible(i)
* is false, then the reverse rate of progress for reaction i is always
Expand Down
127 changes: 127 additions & 0 deletions include/cantera/kinetics/MultiRate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/**
* @file MultiRate.h
*
* @warning This file is an experimental part of the %Cantera API and
* may be changed or removed without notice.
*/

// This file is part of Cantera. See License.txt in the top-level directory or
// at https://cantera.org/license.txt for license and copyright information.

#ifndef CT_MULTIRATE_H
#define CT_MULTIRATE_H

#include "cantera/kinetics/ReactionRate.h"

namespace Cantera
{

//! An abstract base class for evaluating all reactions of a particular type.
/**
* Because this class has no template parameters, the `Kinetics` object
* can store all of these rate coefficient evaluators as a
* `vector<shared_ptr<MultiRateBase>>`.
*
* @todo At the moment, implemented methods are specific to `BulkKinetics`,
* which can be updated using information of a single `ThermoPhase`.
* `InterfaceKinetics` will require access to an entire `Kinetics` object
* or the underlying `vector<ThermoPhase*>` vector (e.g. `m_thermo`).
*
* @warning This class is an experimental part of the %Cantera API and
* may be changed or removed without notice.
*/
class MultiRateBase
{
public:
virtual ~MultiRateBase() {}

//! Add reaction rate object to the evaluator
//! @param rxn_index index of reaction
//! @param rate reaction rate object
virtual void add(const size_t rxn_index,
ReactionRateBase& rate) = 0;

//! Replace reaction rate object handled by the evaluator
//! @param rxn_index index of reaction
//! @param rate reaction rate object
virtual bool replace(const size_t rxn_index,
ReactionRateBase& rate) = 0;

//! Evaluate all rate constants handled by the evaluator
//! @param bulk object representing bulk phase
//! @param kf array of rate constants
virtual void getRateConstants(const ThermoPhase& bulk,
double* kf) const = 0;

//! Update data common to reaction rates of a specific type
//! @param bulk object representing bulk phase
virtual void update(const ThermoPhase& bulk) = 0;
};


//! A class template handling all reaction rates specific to `BulkKinetics`.
/**
* @warning This class is an experimental part of the %Cantera API and
* may be changed or removed without notice.
*/
template <class RateType, class DataType>
class MultiBulkRates final : public MultiRateBase
{
public:
virtual void add(const size_t rxn_index,
ReactionRateBase& rate) override {
m_indices[rxn_index] = m_rates.size();
m_rates.push_back(dynamic_cast<RateType&>(rate));
m_rxn.push_back(rxn_index);
}

virtual bool replace(const size_t rxn_index,
ReactionRateBase& rate) override {
if (!m_rates.size()) {
throw CanteraError("MultiBulkRate::replace",
"Invalid operation: cannot replace rate object "
"in empty rate handler.");
} else if (typeid(rate) != typeid(RateType)) {
throw CanteraError("MultiBulkRate::replace",
"Invalid operation: cannot replace rate object of type '{}' "
"with a new rate of type '{}'.",
m_rates[0].type(), rate.type());
}
if (m_indices.find(rxn_index) != m_indices.end()) {
size_t j = m_indices[rxn_index];
m_rates[j] = dynamic_cast<RateType&>(rate);
return true;
}
return false;
}

virtual void getRateConstants(const ThermoPhase& bulk,
double* kf) const override {
for (size_t i = 0; i < m_rates.size(); i++) {
kf[m_rxn[i]] = m_rates[i].eval(m_shared);
}
}

virtual void update(const ThermoPhase& bulk) override {
// update common data once for each reaction type
m_shared.update(bulk);
if (RateType::uses_update()) {
// update reaction-specific data for each reaction. This loop
// is efficient as all function calls are de-virtualized, and
// all of the rate objects are contiguous in memory
for (auto& rate : m_rates) {
rate.update(m_shared, bulk);
}
}
}

protected:
std::vector<RateType> m_rates; //! Reaction rate objects
std::vector<size_t> m_rxn; //! Index within overall rate vector
std::map<size_t, size_t> m_indices; //! Mapping of indices
DataType m_shared;
};

}

#endif
Loading