From 42a934a37eaabc03a4272be3a4bddbfea195f4c1 Mon Sep 17 00:00:00 2001 From: Harry Moffat Date: Wed, 3 Sep 2014 16:46:53 +0000 Subject: [PATCH] InterfaceKinetics rewrite -> next iteration. Addition of Affinity input terms. --- include/cantera/kinetics/ReactionData.h | 22 ++++- include/cantera/kinetics/importKinetics.h | 6 ++ src/kinetics/importKinetics.cpp | 97 +++++++++++++++++++++++ 3 files changed, 123 insertions(+), 2 deletions(-) diff --git a/include/cantera/kinetics/ReactionData.h b/include/cantera/kinetics/ReactionData.h index 5f6a6f23d..258bb57a2 100644 --- a/include/cantera/kinetics/ReactionData.h +++ b/include/cantera/kinetics/ReactionData.h @@ -25,6 +25,8 @@ public: number(0), rxn_number(0), filmResistivity(0.0), + equilibriumConstantPower(1.0), + affinityPower(1.0), reversible(true), duplicate(false), rateCoeffType(ARRHENIUS_REACTION_RATECOEFF_TYPE), @@ -107,8 +109,23 @@ public: /*! * Only valid for Butler-Volmer formulations. * Units are in ohms m2. + * default = 0.0 ohms m2 */ - double filmResistivity; + doublereal filmResistivity; + + //! Power of the equilibrium constant within the Affinity representation + /*! + * Only valid for Affinity representation. + * default = 1.0 + */ + doublereal equilibriumConstantPower; + + //! Power of the "One minus Affinity" term within the Affinity representation + /*! + * Only valud for Affinity representation + * default = 1.0 + */ + doublereal affinityPower; //! True if the current reaction is reversible. False otherwise bool reversible; @@ -174,7 +191,8 @@ public: //! phases with unity activities. bool isReversibleWithFrac; - doublereal beta; //!< for electrochemical reactions + //! Forward value of the apparent Electrochemical transfer coefficient + doublereal beta; //! Arrhenius parameters for P-log reactions. //! The keys are the pressures corresponding to each Arrhenius expression. diff --git a/include/cantera/kinetics/importKinetics.h b/include/cantera/kinetics/importKinetics.h index e821d0cf1..6a20d332e 100644 --- a/include/cantera/kinetics/importKinetics.h +++ b/include/cantera/kinetics/importKinetics.h @@ -105,6 +105,12 @@ extern bool getOrders(const XML_Node& rxnNode, Kinetics& kin, vector_fp& order, vector_fp& fullForwardsOrders, const ReactionRules& rules); +extern bool getRxnFormulation(const XML_Node& rxnNode, Kinetics& kin, + std::string default_phase, const ReactionData& rdata, + vector_fp& order, vector_fp& fullForwardsOrders, + doublereal &affinityPower, + doublereal & equilibriumConstantPower, + const ReactionRules& rules); //! Read the rate coefficient data from the XML file. /*! diff --git a/src/kinetics/importKinetics.cpp b/src/kinetics/importKinetics.cpp index b1267ec5d..b35f50fa1 100644 --- a/src/kinetics/importKinetics.cpp +++ b/src/kinetics/importKinetics.cpp @@ -407,6 +407,92 @@ bool getOrders(const XML_Node& rxnNode, Kinetics& kin, return true; } //==================================================================================================================== +bool getRxnFormulation(const XML_Node& rxnNode, Kinetics& kin, + std::string default_phase, const ReactionData& rdata, + vector_fp& order, vector_fp& fullForwardsOrders, + doublereal &affinityPower,doublereal & equilibriumConstantPower, + const ReactionRules& rules) +{ + // + // Gather the number of species in the kinetics object and resize fullForwardsOrders + // + size_t nsp = kin.nTotalSpecies(); + fullForwardsOrders.resize(nsp, 0.0); + + const std::vector& reactants = rdata.reactants; + //const std::vector& rstoich = rdata.rstoich; + const std::vector& products = rdata.products; + const std::vector& pstoich = rdata.pstoich; + + if (rxnNode.hasChild("reactionOrderFormulation")) { + XML_Node& rfNode = rxnNode.child("reactionOrderFormulation"); + // + // read the model attribute and figure out how to initialize the full orders vector. + // + string baseHndling = rfNode["model"]; + string ss = lowercase(baseHndling); + if (ss == "zeroorders") { + for (size_t k = 0; k < nsp; k++) { + fullForwardsOrders[k] = 0.0; + } + } else if (ss == "reactantorders") { + for (size_t k = 0; k < nsp; k++) { + fullForwardsOrders[k] = 0.0; + } + for (size_t n = 0; n < order.size(); n++) { + size_t k = reactants[n]; + double fac = order[n]; + fullForwardsOrders[k] = fac; + } + } else if (ss == "butlervolmerorders") { + // + // ok first thing to do is get the electrochemical transfer coefficient + // since the order depend on the value. + // Also, if we don't find one, then it's an error + double beta = -10.0; + if (rxnNode.hasChild("rateCoeff")) { + XML_Node& rc = rxnNode.child("rateCoeff"); + if (rc.hasChild("electrochem")) { + XML_Node& eb = rc.child("electrochem"); + string sbeta = eb["beta"]; + beta = fpValueCheck(sbeta); + } + } + if (beta == -10.0) { + throw CanteraError("getRxnFormulation()", + "ButlerVolmerOrders model requested but no electrochem beta input"); + } + double betar = 1.0 - beta; + for (size_t k = 0; k < nsp; k++) { + fullForwardsOrders[k] = 0.0; + } + for (size_t n = 0; n < reactants.size(); n++) { + size_t k = reactants[n]; + double fac = order[n]; + fullForwardsOrders[k] += fac * betar; + } + for (size_t n = 0; n < products.size(); n++) { + size_t k = products[n]; + double fac = pstoich[n]; + fullForwardsOrders[k] += fac * beta; + } + } else { + throw CanteraError("getRxnFormulation()", "unknown model for reactionOrders XML_Node: " + baseHndling); + } + + + if (rfNode.hasChild("affinityPower")) { + XML_Node& fNode = rxnNode.child("affinityPower"); + affinityPower = fpValueCheck( fNode() ); + } + if (rfNode.hasChild("equilibriumConstantPower")) { + XML_Node& eNode = rxnNode.child("equilibriumConstantPower"); + equilibriumConstantPower = fpValueCheck( eNode() ); + } + } + return true; +} +//==================================================================================================================== /** * getArrhenius() parses the xml element called Arrhenius. * The Arrhenius expression is @@ -920,6 +1006,15 @@ bool rxninfo::installReaction(int iRxn, const XML_Node& rxnNode, Kinetics& kin, rdata.filmResistivity = fpValueCheck( fNode() ); } } + // + // Fill in the global reaction formulation terms (Affinity reactions) + // + if (rxnNode.hasChild("reactionOrderFormulation")) { + ok = getRxnFormulation(rxnNode, kin, default_phase, rdata, + rdata.rorder, rdata.forwardFullOrder_, rdata.affinityPower, + rdata.equilibriumConstantPower, rules); + } + // // Fill in the forwardFullOrder_ array // @@ -928,6 +1023,8 @@ bool rxninfo::installReaction(int iRxn, const XML_Node& rxnNode, Kinetics& kin, rdata.rorder, rdata.forwardFullOrder_, rules); } + + // Some reactions can be elementary reactions but have fractional // stoichiometries wrt to some products and reactants. An example of these // are solid reactions involving phase transformations. Species with