From 4e997464576b5776b11e242526f9a20fc9984cf4 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Sat, 15 Nov 2014 19:26:37 +0000 Subject: [PATCH] [Kinetics] Allow explicit specification of the sticking species --- include/cantera/kinetics/Reaction.h | 4 +++ src/kinetics/InterfaceKinetics.cpp | 48 ++++++++++++++++++----------- src/kinetics/Reaction.cpp | 1 + 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/include/cantera/kinetics/Reaction.h b/include/cantera/kinetics/Reaction.h index b9510c88b..11c48757b 100644 --- a/include/cantera/kinetics/Reaction.h +++ b/include/cantera/kinetics/Reaction.h @@ -198,6 +198,10 @@ public: // Set to true if `rate` is a parameterization of the sticking coefficient // rather than the forward rate constant bool is_sticking_coefficient; + + // For reactions with multiple non-surface species, the sticking species + // needs to be explicitly identified. + std::string sticking_species; }; diff --git a/src/kinetics/InterfaceKinetics.cpp b/src/kinetics/InterfaceKinetics.cpp index 5cca5e941..9b43b7d8f 100644 --- a/src/kinetics/InterfaceKinetics.cpp +++ b/src/kinetics/InterfaceKinetics.cpp @@ -915,37 +915,49 @@ void InterfaceKinetics::addReaction(shared_ptr r_base) } b_rate += 0.5; + std::string sticking_species = r.sticking_species; + if (sticking_species == "") { + // Identify the sticking species if not explicitly given + bool foundStick = false; + for (Composition::const_iterator iter = r.reactants.begin(); + iter != r.reactants.end(); + ++iter) { + size_t iPhase = speciesPhaseIndex(kineticsSpeciesIndex(iter->first)); + if (iPhase != iInterface) { + // Non-interface species. There should be exactly one of these + if (foundStick) { + throw CanteraError("InterfaceKinetics::addReaction", + "Multiple non-interface species found" + "in sticking reaction: '" + r.equation() + "'"); + } + foundStick = true; + sticking_species = iter->first; + } + } + if (!foundStick) { + throw CanteraError("InterfaceKinetics::addReaction", + "No non-interface species found" + "in sticking reaction: '" + r.equation() + "'"); + } + } - // Identify the sticking species, and adjust the A-factor - bool foundStick = false; + // Adjust the A-factor for (Composition::const_iterator iter = r.reactants.begin(); iter != r.reactants.end(); ++iter) { size_t iPhase = speciesPhaseIndex(kineticsSpeciesIndex(iter->first)); const ThermoPhase& p = thermo(iPhase); size_t k = p.speciesIndex(iter->first); - if (iPhase == iInterface) { - // Interface species. Convert from coverages used in the + if (iter->first == sticking_species) { + A_rate *= sqrt(GasConstant/(2*Pi*p.molecularWeight(k))); + } else { + // Non-sticking species. Convert from coverages used in the // sticking probability expression to the concentration units // used in the mass action rate expression double order = getValue(r.orders, iter->first, iter->second); A_rate /= pow(p.standardConcentration(k), order); - } else { - // Non-interface species. There should be exactly one of these - if (foundStick) { - throw CanteraError("InterfaceKinetics::addReaction", - "Multiple non-interface species found" - "in sticking reaction: '" + r.equation() + "'"); - } - foundStick = true; - A_rate *= sqrt(GasConstant/(2*Pi*p.molecularWeight(k))); } } - if (!foundStick) { - throw CanteraError("InterfaceKinetics::addReaction", - "No non-interface species found" - "in sticking reaction: '" + r.equation() + "'"); - } } SurfaceArrhenius rate(A_rate, b_rate, r.rate.activationEnergy_R()); diff --git a/src/kinetics/Reaction.cpp b/src/kinetics/Reaction.cpp index e98470a42..b94f9dc21 100644 --- a/src/kinetics/Reaction.cpp +++ b/src/kinetics/Reaction.cpp @@ -492,6 +492,7 @@ void setupInterfaceReaction(InterfaceReaction& R, const XML_Node& rxn_node) XML_Node& arr = rxn_node.child("rateCoeff").child("Arrhenius"); if (lowercase(arr["type"]) == "stick") { R.is_sticking_coefficient = true; + R.sticking_species = arr["species"]; } setupElementaryReaction(R, rxn_node); }