diff --git a/include/cantera/kinetics/MultiRate.h b/include/cantera/kinetics/MultiRate.h index d8e73e5ba36..7fa4a2d423b 100644 --- a/include/cantera/kinetics/MultiRate.h +++ b/include/cantera/kinetics/MultiRate.h @@ -23,6 +23,7 @@ class MultiRate final : public MultiRateBase CT_DEFINE_HAS_MEMBER(has_ddT, ddTScaledFromStruct) CT_DEFINE_HAS_MEMBER(has_ddP, perturbPressure) CT_DEFINE_HAS_MEMBER(has_ddM, perturbThirdBodies) + CT_DEFINE_HAS_MEMBER(has_chargeTransfer, voltageCorrection) public: virtual std::string type() override { @@ -98,6 +99,15 @@ class MultiRate final : public MultiRateBase _process_ddM(rop, kf, deltaM, overwrite); } + virtual void processVoltageCorrections(double* kf, + const double* pot, + double RT) override + { + // call helper function: implementation depends on whether + // ReactionRate::voltageCorrection is defined + _processVoltageCorrections(kf, pot, RT); + } + virtual void update(double T) override { m_shared.update(T); _update(); @@ -147,7 +157,7 @@ class MultiRate final : public MultiRateBase void _update() { } - //! Helper function to update a single rate that has an `updateFromStruct method`. + //! Helper function to update a single rate that has an `updateFromStruct` method`. template ::value, bool>::type = true> void _updateRate(RateType& rate) { @@ -161,6 +171,22 @@ class MultiRate final : public MultiRateBase void _updateRate(RateType& rate) { } + //! Helper function to update a single rate that has a `voltageCorrection` method. + template ::value, bool>::type = true> + void _processVoltageCorrections(double* kf, const double* pot, double RT) { + for (auto& rxn : m_rxn_rates) { + kf[rxn.first] *= rxn.second.voltageCorrection(pot, RT); + } + } + + //! Helper function for single rate that does not implement `updateFromStruct`. + //! Exists to allow generic implementations of `evalSingle` and `ddTSingle`. + template ::value, bool>::type = true> + void _processVoltageCorrections(double* kf, const double* pot, double RT) { + } + //! Helper function to process temperature derivatives for rate types that //! implement the `ddTScaledFromStruct` method. template resize(nTotalSpecies(), nReactions()); + // @todo ensure that ReactionData are updated; calling rates->update + // blocks correct behavior in InterfaceKinetics::_update_rates_T + // and running updateROP() is premature + } } void InterfaceKinetics::setElectricPotential(int n, doublereal V) @@ -98,7 +105,7 @@ void InterfaceKinetics::_update_rates_T() m_redo_rates = false; } - // loop over MultiRate evaluators for each reaction type + // loop over interface MultiRate evaluators for each reaction type for (auto& rates : m_interfaceRates) { bool changed = rates->update(thermo(), *this); if (changed) { @@ -108,6 +115,18 @@ void InterfaceKinetics::_update_rates_T() } } + // loop over charge transfer MultiRate evaluators for each reaction type + for (auto& rates : m_chargeTransferRates) { + bool changed = rates->update(thermo(), *this); + if (changed) { + rates->getRateConstants(m_rfn.data()); + rates->processVoltageCorrections( + m_rfn.data(), m_pot.data(), thermo(reactionPhaseIndex()).RT()); + m_ROP_ok = false; + m_redo_rates = true; + } + } + if (!m_ROP_ok) { updateKc(); }