From 21cfce998bc14864f2ab1e0b9f498434adcac4c5 Mon Sep 17 00:00:00 2001 From: 12Chao Date: Wed, 12 May 2021 17:55:14 -0400 Subject: [PATCH] [Kinetics] Fix issue 717, Add check for sticking coefficient more than 1 --- include/cantera/kinetics/Reaction.h | 2 + include/cantera/kinetics/RxnRates.h | 8 +++ .../cython/cantera/test/test_kinetics.py | 18 ++++++ src/kinetics/Reaction.cpp | 16 ++++++ src/kinetics/RxnRates.cpp | 35 ++++++++++++ test/data/sticking_coeff_check.yaml | 56 +++++++++++++++++++ 6 files changed, 135 insertions(+) create mode 100644 test/data/sticking_coeff_check.yaml diff --git a/include/cantera/kinetics/Reaction.h b/include/cantera/kinetics/Reaction.h index 84f6511c0b1..a5fb62f2a33 100644 --- a/include/cantera/kinetics/Reaction.h +++ b/include/cantera/kinetics/Reaction.h @@ -384,6 +384,7 @@ class InterfaceReaction : public ElementaryReaction2 const Arrhenius& rate, bool isStick=false); virtual void calculateRateCoeffUnits(const Kinetics& kin); virtual void getParameters(AnyMap& reactionNode) const; + virtual void validate(); virtual std::string type() const { return "interface"; @@ -457,6 +458,7 @@ class BlowersMaselInterfaceReaction : public BlowersMaselReaction const BlowersMasel& rate, bool isStick=false); virtual void getParameters(AnyMap& reactionNode) const; virtual void calculateRateCoeffUnits(const Kinetics& kin); + virtual void validate(); virtual std::string type() const { return "surface-Blowers-Masel"; diff --git a/include/cantera/kinetics/RxnRates.h b/include/cantera/kinetics/RxnRates.h index 2edc6dbe7a2..1746a7b7b3e 100644 --- a/include/cantera/kinetics/RxnRates.h +++ b/include/cantera/kinetics/RxnRates.h @@ -102,6 +102,10 @@ class Arrhenius return m_E; } + //! Check to make sure that the sticking coefficient is + //! less than 1 over a range of temperatures + void validate(const std::string& equation); + protected: doublereal m_logA, m_b, m_E, m_A; }; @@ -212,6 +216,10 @@ class BlowersMasel return m_w; } + //! Check to make sure that the sticking coefficient is + //! less than 1 over a range of temperatures + void validate(const std::string& equation); + protected: doublereal m_logA, m_b, m_A, m_w, m_E0; }; diff --git a/interfaces/cython/cantera/test/test_kinetics.py b/interfaces/cython/cantera/test/test_kinetics.py index db2becc7634..3a37d8b3853 100644 --- a/interfaces/cython/cantera/test/test_kinetics.py +++ b/interfaces/cython/cantera/test/test_kinetics.py @@ -422,6 +422,24 @@ def test_pdep_err(self): for msg in err_msg: self.assertIn(msg, err_msg_list) + def test_sticking_coeff_err(self): + err_msg = (" Sticking coefficient is more than 1 for reaction 'O2 + 2 PT(S) => 2 O(S)'", + " at T = 200.0", + " at T = 500.0", + " at T = 1000.0", + " at T = 2000.0", + " at T = 5000.0", + " at T = 10000.0", + " Sticking coefficient is more than 1 for reaction 'OH + PT(S) => OH(S)'" + ) + try: + gas = ct.Solution('sticking_coeff_check.yaml') + surface = ct.Interface('sticking_coeff_check.yaml', 'Pt_surf', [gas]) + self.fail('CanteraError not raised') + except ct.CanteraError as e: + err_msg_list = str(e).splitlines() + for msg in err_msg: + self.assertIn(msg, err_msg_list) class TestUndeclared(utilities.CanteraTest): diff --git a/src/kinetics/Reaction.cpp b/src/kinetics/Reaction.cpp index 21eee166913..b2645d78f1d 100644 --- a/src/kinetics/Reaction.cpp +++ b/src/kinetics/Reaction.cpp @@ -745,6 +745,14 @@ void InterfaceReaction::getParameters(AnyMap& reactionNode) const } } +void InterfaceReaction::validate() { + ElementaryReaction::validate(); + if (is_sticking_coefficient != false) { + rate.validate(equation()); + } + +} + ElectrochemicalReaction::ElectrochemicalReaction() : beta(0.5) , exchange_current_density_formulation(false) @@ -1099,6 +1107,14 @@ CustomFunc1Reaction::CustomFunc1Reaction(const AnyMap& node, const Kinetics& kin setRate(std::make_shared(node, rate_units)); } +void BlowersMaselInterfaceReaction::validate() +{ + BlowersMaselReaction::validate(); + if (is_sticking_coefficient != false) { + rate.validate(equation()); + } +} + Arrhenius readArrhenius(const XML_Node& arrhenius_node) { return Arrhenius(getFloat(arrhenius_node, "A", "toSI"), diff --git a/src/kinetics/RxnRates.cpp b/src/kinetics/RxnRates.cpp index 892821dc8ec..b7e65450ac1 100644 --- a/src/kinetics/RxnRates.cpp +++ b/src/kinetics/RxnRates.cpp @@ -7,6 +7,7 @@ #include "cantera/base/Array.h" #include "cantera/base/AnyMap.h" #include "cantera/base/global.h" +#include namespace Cantera { @@ -83,6 +84,23 @@ void Arrhenius::getParameters(AnyMap& rateNode, const Units& rate_units) const rateNode.setFlowStyle(); } +void Arrhenius::validate(const std::string& equation) { + fmt::memory_buffer err_reactions; + double T[] = {200.0, 500.0, 1000.0, 2000.0, 5000.0, 10000.0}; + for (size_t i=0; i < 6; i++) { + double gamma = m_A * std::exp(m_b*log(T[i]) - m_E*(1/T[i])); + if (gamma > 1) { + format_to(err_reactions, + "\n Sticking coefficient is more than 1 for reaction '{}'\n" + " at T = {:.1f}\n", + equation, T[i]); + } + } + if (err_reactions.size()) { + throw CanteraError("Arrhenius::validate", to_string(err_reactions)); + } +} + BlowersMasel::BlowersMasel() : m_logA(-1.0E300) , m_b(0.0) @@ -123,6 +141,23 @@ void BlowersMasel::getParameters(AnyMap& rateNode, const Units& rate_units) cons rateNode.setFlowStyle(); } +void BlowersMasel::validate(const std::string& equation) { + fmt::memory_buffer err_reactions; + double T[] = {200.0, 500.0, 1000.0, 2000.0, 5000.0, 10000.0}; + for (size_t i=0; i < 6; i++) { + double gamma = m_A * std::exp(m_b*log(T[i]) - m_E0*(1/T[i])); + if (gamma > 1) { + format_to(err_reactions, + "\n Sticking coefficient is more than 1 for reaction '{}'\n" + " at T = {:.1f}\n", + equation, T[i]); + } + } + if (err_reactions.size()) { + throw CanteraError("BlowersMasel::validate", to_string(err_reactions)); + } +} + SurfaceArrhenius::SurfaceArrhenius() : m_b(0.0) , m_E(0.0) diff --git a/test/data/sticking_coeff_check.yaml b/test/data/sticking_coeff_check.yaml new file mode 100644 index 00000000000..1654826134e --- /dev/null +++ b/test/data/sticking_coeff_check.yaml @@ -0,0 +1,56 @@ +units: {length: cm, quantity: mol, activation-energy: J/mol} + +phases: +- name: gas + thermo: ideal-gas + elements: [O, H, C, N, Ar] + species: + - gri30.yaml/species: [ O2, OH] + skip-undeclared-elements: true + kinetics: gas + reactions: + - gri30.yaml/reactions: declared-species + transport: mixture-averaged +- name: Pt_surf + thermo: ideal-surface + elements: [Pt, H, O, C] + species: [{Pt-surf-species: all}] + kinetics: surface + reactions: [Pt-reactions] + +Pt-surf-species: +- name: PT(S) + composition: {Pt: 1} + thermo: + model: NASA7 + temperature-ranges: [300.0, 1000.0, 3000.0] + data: + - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] + - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] +- name: OH(S) + composition: {O: 1, H: 1, Pt: 1} + thermo: + model: NASA7 + temperature-ranges: [300.0, 1000.0, 3000.0] + data: + - [-2.0340881, 9.3662683e-03, 6.6275214e-07, -5.2074887e-09, 1.7088735e-12, + -2.5319949e+04, 8.9863186] + - [1.8249973, 3.2501565e-03, -3.1197541e-07, -3.4603206e-10, 7.9171472e-14, + -2.6685492e+04, -12.280891] +- name: O(S) + composition: {O: 1, Pt: 1} + thermo: + model: NASA7 + temperature-ranges: [300.0, 1000.0, 3000.0] + data: + - [-0.94986904, 7.4042305e-03, -1.0451424e-06, -6.112042e-09, 3.3787992e-12, + -1.3209912e+04, 3.6137905] + - [1.945418, 9.1761647e-04, -1.1226719e-07, -9.9099624e-11, 2.4307699e-14, + -1.4005187e+04, -11.531663] + +Pt-reactions: +- equation: O2 + 2 PT(S) => 2 O(S) # Reaction 4 + sticking-coefficient: {A: 2.0, b: 0, Ea: 0} +- equation: OH + PT(S) => OH(S) # Reaction 5 + type: Blowers-Masel + sticking-coefficient: {A: 2.0, b: 0, Ea0: 0, w: 100000}