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

Proof-of-concept: Modify reaction rates in memory #1051

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 21 additions & 6 deletions include/cantera/kinetics/Arrhenius.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,28 @@ class ArrheniusBase : public ReactionRate
return m_A;
}

//! Set the pre-exponential factor *A* (in m, kmol, s to powers depending
//! on the reaction order)
void setPreExponentialFactor(double A);

//! Return the temperature exponent *b*
double temperatureExponent() const {
return m_b;
}

//! Set the temperature exponent *b*
void setTemperatureExponent(double b);

//! Return the intrinsic activation energy *Ea* [J/kmol]
//! The value corresponds to the constant specified by input parameters;
//! in the simplest case, this is equal to the activation energy itself
double intrinsicActivationEnergy() const {
return m_Ea_R * GasConstant;
}

//! Set the activation energy *Ea* [J/kmol]
void setIntrinsicActivationEnergy(double Ea);

// Return units of the reaction rate expression
const Units& rateUnits() const {
return m_rate_units;
Expand Down Expand Up @@ -152,8 +162,8 @@ class ArrheniusRate final : public ArrheniusBase
setParameters(node, rate_units);
}

unique_ptr<MultiRateBase> newMultiRate() const override {
return unique_ptr<MultiRateBase>(new MultiBulkRate<ArrheniusRate, ArrheniusData>);
shared_ptr<MultiRateBase> newMultiRate() const override {
return shared_ptr<MultiRateBase>(new MultiBulkRate<ArrheniusRate, ArrheniusData>);
}

//! Identifier of reaction rate type
Expand Down Expand Up @@ -190,6 +200,11 @@ class ArrheniusRate final : public ArrheniusBase
return m_Ea_R * GasConstant;
}

//! Set the activation energy *Ea* [J/kmol]
void setActivationEnergy(double Ea) {
setIntrinsicActivationEnergy(Ea);
}

//! Return the activation energy divided by the gas constant (i.e. the
//! activation temperature) [K]
double activationEnergy_R() const {
Expand Down Expand Up @@ -231,8 +246,8 @@ class TwoTempPlasmaRate final : public ArrheniusBase
*/
TwoTempPlasmaRate(double A, double b, double Ea, double EE);

unique_ptr<MultiRateBase> newMultiRate() const override {
return unique_ptr<MultiRateBase>(
shared_ptr<MultiRateBase> newMultiRate() const override {
return shared_ptr<MultiRateBase>(
new MultiBulkRate<TwoTempPlasmaRate, TwoTempPlasmaData>);
}

Expand Down Expand Up @@ -340,8 +355,8 @@ class BlowersMaselRate final : public ArrheniusBase
*/
BlowersMaselRate(double A, double b, double Ea0, double w);

unique_ptr<MultiRateBase> newMultiRate() const {
return unique_ptr<MultiRateBase>(
shared_ptr<MultiRateBase> newMultiRate() const {
return shared_ptr<MultiRateBase>(
new MultiBulkRate<BlowersMaselRate, BlowersMaselData>);
}

Expand Down
2 changes: 1 addition & 1 deletion include/cantera/kinetics/BulkKinetics.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class BulkKinetics : public Kinetics
virtual void modifyElementaryReaction(size_t i, ElementaryReaction2& rNew);

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

Rate1<Arrhenius> m_rates; //!< @deprecated (legacy only)
Expand Down
4 changes: 2 additions & 2 deletions include/cantera/kinetics/Custom.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ class CustomFunc1Rate final : public ReactionRate
setParameters(node, rate_units);
}

unique_ptr<MultiRateBase> newMultiRate() const override {
return unique_ptr<MultiRateBase>(new MultiBulkRate<CustomFunc1Rate, ArrheniusData>);
shared_ptr<MultiRateBase> newMultiRate() const override {
return shared_ptr<MultiRateBase>(new MultiBulkRate<CustomFunc1Rate, ArrheniusData>);
}

const std::string type() const override { return "custom-rate-function"; }
Expand Down
16 changes: 8 additions & 8 deletions include/cantera/kinetics/Falloff.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,8 @@ class LindemannRate final : public FalloffRate
setFalloffCoeffs(c);
}

unique_ptr<MultiRateBase> newMultiRate() const {
return unique_ptr<MultiRateBase>(
shared_ptr<MultiRateBase> newMultiRate() const {
return shared_ptr<MultiRateBase>(
new MultiBulkRate<LindemannRate, FalloffData>);
}

Expand Down Expand Up @@ -303,8 +303,8 @@ class TroeRate final : public FalloffRate
setFalloffCoeffs(c);
}

unique_ptr<MultiRateBase> newMultiRate() const {
return unique_ptr<MultiRateBase>(new MultiBulkRate<TroeRate, FalloffData>);
shared_ptr<MultiRateBase> newMultiRate() const {
return shared_ptr<MultiRateBase>(new MultiBulkRate<TroeRate, FalloffData>);
}

//! Set coefficients used by parameterization
Expand Down Expand Up @@ -405,8 +405,8 @@ class SriRate final : public FalloffRate
setFalloffCoeffs(c);
}

unique_ptr<MultiRateBase> newMultiRate() const {
return unique_ptr<MultiRateBase>(new MultiBulkRate<SriRate, FalloffData>);
shared_ptr<MultiRateBase> newMultiRate() const {
return shared_ptr<MultiRateBase>(new MultiBulkRate<SriRate, FalloffData>);
}

//! Set coefficients used by parameterization
Expand Down Expand Up @@ -515,8 +515,8 @@ class TsangRate final : public FalloffRate
setFalloffCoeffs(c);
}

unique_ptr<MultiRateBase> newMultiRate() const {
return unique_ptr<MultiRateBase>(new MultiBulkRate<TsangRate, FalloffData>);
shared_ptr<MultiRateBase> newMultiRate() const {
return shared_ptr<MultiRateBase>(new MultiBulkRate<TsangRate, FalloffData>);
}

//! Set coefficients used by parameterization
Expand Down
64 changes: 54 additions & 10 deletions include/cantera/kinetics/MultiRate.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,67 @@ class MultiBulkRate final : public MultiRateBase
CT_DEFINE_HAS_MEMBER(has_ddM, perturbThirdBodies)

public:
virtual ~MultiBulkRate() {
for (size_t i = 0; i < m_bases.size(); i++) {
m_bases[i]->releaseEvaluator();
}
}

virtual std::string type() override {
if (!m_rxn_rates.size()) {
throw CanteraError("MultiBulkRate::type",
"Cannot determine type of empty rate handler.");
"Cannot determine type of empty rate handler.");
}
return m_rxn_rates.at(0).second.type();
}

virtual void add(const size_t rxn_index, ReactionRate& rate) override {
virtual void add(const size_t rxn_index,
shared_ptr<ReactionRate>& rate) override
{
if (typeid(*rate) != typeid(RateType)) {
throw CanteraError("MultiBulkRate::add",
"Wrong type: cannot add rate object of type '{}'",
rate->type());
}
if (rate->rateIndex() != npos) {
throw CanteraError("MultiBulkRate::add",
"Reaction rate is already linked to a reaction rate evaluator;\n"
"object needs to be released before it can be added again.");
}
m_indices[rxn_index] = m_rxn_rates.size();
m_rxn_rates.emplace_back(rxn_index, dynamic_cast<RateType&>(rate));
m_rxn_rates.emplace_back(rxn_index, dynamic_cast<RateType&>(*rate));
m_rxn_rates.back().second.setRateIndex(rxn_index);
m_shared.invalidateCache();
// keep link to original object
m_bases.push_back(rate);
}

virtual bool replace(const size_t rxn_index, ReactionRate& rate) override {
virtual bool replace(const size_t rxn_index,
shared_ptr<ReactionRate>& rate) override
{
if (!m_rxn_rates.size()) {
throw CanteraError("MultiBulkRate::replace",
"Invalid operation: cannot replace rate object "
"in empty rate handler.");
"Invalid operation: cannot replace rate object "
"in empty rate handler.");
}
if (rate.type() != type()) {
if (rate->rateIndex() != npos) {
throw CanteraError("MultiBulkRate::replace",
"Invalid operation: cannot replace rate object of type '{}' "
"with a new rate of type '{}'.", type(), rate.type());
"Reaction rate is already linked to a reaction rate evaluator;\n"
"object needs to to be released before it can be added again.");
}
if (rate->type() != type()) {
throw CanteraError("MultiBulkRate::replace",
"Invalid operation: cannot replace rate object of type '{}' "
"with a new rate of type '{}'.", type(), rate->type());
}
m_shared.invalidateCache();
if (m_indices.find(rxn_index) != m_indices.end()) {
size_t j = m_indices[rxn_index];
m_rxn_rates.at(j).second = dynamic_cast<RateType&>(rate);
m_rxn_rates.at(j).second = dynamic_cast<RateType&>(*rate);
m_rxn_rates.at(j).second.setRateIndex(rxn_index);
// release evaluator from previously used rate object and update
m_bases[j]->releaseEvaluator();
m_bases[j] = rate;
return true;
}
return false;
Expand All @@ -64,6 +96,15 @@ class MultiBulkRate final : public MultiRateBase
m_shared.invalidateCache();
}

virtual void invalidateCache() override {
m_shared.invalidateCache();
}

virtual ReactionRate& rate(size_t rxn_index) override {
size_t j = m_indices[rxn_index];
return dynamic_cast<ReactionRate&>(m_rxn_rates.at(j).second);
}

virtual void getRateConstants(double* kf) override {
for (auto& rxn : m_rxn_rates) {
kf[rxn.first] = rxn.second.evalFromStruct(m_shared);
Expand Down Expand Up @@ -211,6 +252,9 @@ class MultiBulkRate final : public MultiRateBase
}
}

//! Pointers to reaction rate objects managed by Reaction object
std::vector<shared_ptr<ReactionRate>> m_bases;

//! Vector of pairs of reaction rates indices and reaction rates
std::vector<std::pair<size_t, RateType>> m_rxn_rates;
std::map<size_t, size_t> m_indices; //! Mapping of indices
Expand Down
11 changes: 9 additions & 2 deletions include/cantera/kinetics/MultiRateBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,25 @@ class MultiRateBase
//! Add reaction rate object to the evaluator
//! @param rxn_index index of reaction
//! @param rate reaction rate object
virtual void add(size_t rxn_index, ReactionRate& rate) = 0;
virtual void add(size_t rxn_index, shared_ptr<ReactionRate>& rate) = 0;

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

//! Update number of species and reactions
//! @param n_species number of species
//! @param n_reactions number of reactions
virtual void resize(size_t n_species, size_t n_reactions) = 0;

//! Force shared data and reaction rates to be updated next time
virtual void invalidateCache() = 0;

//! Access reaction rate object handled by evaluator
//! @param rxn_index index of reaction
virtual ReactionRate& rate(size_t rxn_index) = 0;

//! Evaluate all rate constants handled by the evaluator
//! @param kf array of rate constants
virtual void getRateConstants(double* kf) = 0;
Expand Down
35 changes: 29 additions & 6 deletions include/cantera/kinetics/ReactionRate.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ class ReactionRate
//! Derived classes usually implement this as:
//!
//! ```.cpp
//! unique_ptr<MultiRateBase> newMultiRate() const override {
//! return unique_ptr<MultiRateBase>(new MultiBulkRate<RateType, DataType>);
//! shared_ptr<MultiRateBase> newMultiRate() const override {
//! return shared_ptr<MultiRateBase>(new MultiBulkRate<RateType, DataType>);
//! ```
//!
//! where `RateType` is the derived class name and `DataType` is the corresponding
//! container for parameters needed to evaluate reactions of that type.
virtual unique_ptr<MultiRateBase> newMultiRate() const = 0;
virtual shared_ptr<MultiRateBase> newMultiRate() const = 0;

virtual const std::string type() const = 0;

Expand Down Expand Up @@ -109,14 +109,34 @@ class ReactionRate
m_rate_index = idx;
}

//! Return boolean indicating whether reaction rate object is linked to
//! a MultiRateBase evaluator
bool linked() {
return m_rate_index != npos;
}

//! Link reaction to MultiRateBase evaluator
void linkEvaluator(size_t index, const shared_ptr<MultiRateBase> evaluator) {
m_rate_index = index;
m_evaluator = evaluator;
}

//! Release (unlink) reaction from MultiRateBase evaluator
void releaseEvaluator() {
m_rate_index = npos;
m_evaluator.reset();
}

//! Evaluate reaction rate based on temperature
//! @param T temperature [K]
//! Used in conjunction with MultiRateBase::evalSingle / ReactionRate::eval.
//! This method allows for testing of a reaction rate expression outside of
//! Kinetics reaction rate evaluators.
double eval(double T) {
_evaluator().update(T);
return _evaluator().evalSingle(*this);
double ret = _evaluator().evalSingle(*this);
_evaluator().invalidateCache();
return ret;
}

//! Evaluate reaction rate based on temperature and an extra parameter.
Expand All @@ -129,7 +149,9 @@ class ReactionRate
//! Kinetics reaction rate evaluators.
double eval(double T, double extra) {
_evaluator().update(T, extra);
return _evaluator().evalSingle(*this);
double ret = _evaluator().evalSingle(*this);
_evaluator().invalidateCache();
return ret;
}

protected:
Expand Down Expand Up @@ -159,7 +181,8 @@ class ReactionRate
return *m_evaluator;
}

unique_ptr<MultiRateBase> m_evaluator;
protected:
shared_ptr<MultiRateBase> m_evaluator;
};

}
Expand Down
12 changes: 6 additions & 6 deletions include/cantera/kinetics/RxnRates.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class Arrhenius2 : public ArrheniusBase
}

// The following methods are unused but required by the base class
unique_ptr<MultiRateBase> newMultiRate() const {
shared_ptr<MultiRateBase> newMultiRate() const {
throw NotImplementedError("Arrhenius2::newMultiRate");
}

Expand Down Expand Up @@ -146,7 +146,7 @@ class BlowersMasel2

BlowersMasel2(double A, double b, double E0, double w);

unique_ptr<MultiRateBase> newMultiRate() const {
shared_ptr<MultiRateBase> newMultiRate() const {
throw NotImplementedError("BlowersMasel2::newMultiRate");
}

Expand Down Expand Up @@ -348,8 +348,8 @@ class PlogRate final : public ReactionRate
setParameters(node, rate_units);
}

unique_ptr<MultiRateBase> newMultiRate() const {
return unique_ptr<MultiRateBase>(new MultiBulkRate<PlogRate, PlogData>);
shared_ptr<MultiRateBase> newMultiRate() const {
return shared_ptr<MultiRateBase>(new MultiBulkRate<PlogRate, PlogData>);
}

//! Identifier of reaction rate type
Expand Down Expand Up @@ -550,8 +550,8 @@ class ChebyshevRate3 final : public ReactionRate
setParameters(node, rate_units);
}

unique_ptr<MultiRateBase> newMultiRate() const {
return unique_ptr<MultiRateBase>(
shared_ptr<MultiRateBase> newMultiRate() const {
return shared_ptr<MultiRateBase>(
new MultiBulkRate<ChebyshevRate3, ChebyshevData>);
}

Expand Down
Loading