From eb075276e896bb419947a25f300fbaeb7eb888bc Mon Sep 17 00:00:00 2001 From: Ingmar Schoegl Date: Sun, 24 Jul 2022 02:45:03 -0500 Subject: [PATCH] [Kinetics] Enforce zero default efficiency for explicit third body --- include/cantera/kinetics/Falloff.h | 2 +- include/cantera/kinetics/Reaction.h | 9 +++--- src/kinetics/Reaction.cpp | 43 +++++++++++++++-------------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/include/cantera/kinetics/Falloff.h b/include/cantera/kinetics/Falloff.h index c982b4aba0..db2592c7b1 100644 --- a/include/cantera/kinetics/Falloff.h +++ b/include/cantera/kinetics/Falloff.h @@ -195,7 +195,7 @@ class FalloffRate : public ReactionRate "To be removed after Cantera 3.0; superseded by getFalloffCoeffs."); } - virtual void getParameters(AnyMap& node) const; + virtual void getParameters(AnyMap& node) const override; //! Evaluate reaction rate //! @param shared_data data shared by all reactions of a given type diff --git a/include/cantera/kinetics/Reaction.h b/include/cantera/kinetics/Reaction.h index 5df2a92d2f..1074c1cb65 100644 --- a/include/cantera/kinetics/Reaction.h +++ b/include/cantera/kinetics/Reaction.h @@ -197,9 +197,6 @@ class Reaction //! Flag indicating that serialization uses explicit type bool m_explicit_type = false; - //! Flag indicating that third body requires explicit serialization - bool m_explicit_3rd = false; - //! Flag indicating that object was instantiated from reactant/product compositions bool m_from_composition = false; @@ -243,9 +240,8 @@ class ThirdBody //! Get third-body efficiencies from AnyMap *node* //! @param node AnyMap receiving serialized parameters - //! @param explicit_3rd Flag triggering explicit third body efficiency output //! @since New in Cantera 3.0 - void getParameters(AnyMap& node, bool explicit_3rd) const; + void getParameters(AnyMap& node) const; //! Get the third-body efficiency for species *k* double efficiency(const std::string& k) const; @@ -274,6 +270,9 @@ class ThirdBody //! (`true` for three-body reactions, `false` for falloff reactions) bool mass_action = true; + //! Flag indicating whether third body requires explicit serialization + bool explicit_3rd = false; + protected: //! Name of the third body collider std::string m_name = "M"; diff --git a/src/kinetics/Reaction.cpp b/src/kinetics/Reaction.cpp index 99e3f39297..ac5bee9265 100644 --- a/src/kinetics/Reaction.cpp +++ b/src/kinetics/Reaction.cpp @@ -48,7 +48,7 @@ Reaction::Reaction(const Composition& reactants_, } if (count) { if (tbody_ && tbody_->name() != "M") { - m_explicit_3rd = true; + m_third_body->explicit_3rd = true; } else if (!tbody_) { m_explicit_type = true; } @@ -63,7 +63,7 @@ Reaction::Reaction(const std::string& equation, setEquation(equation); setRate(rate_); if (tbody_ && tbody_->name() != "M") { - m_explicit_3rd = true; + m_third_body->explicit_3rd = true; } } @@ -206,7 +206,7 @@ void Reaction::getParameters(AnyMap& reactionNode) const } if (m_third_body) { - m_third_body->getParameters(reactionNode, m_explicit_3rd); + m_third_body->getParameters(reactionNode); } } @@ -237,13 +237,9 @@ void Reaction::setParameters(const AnyMap& node, const Kinetics& kin) allow_nonreactant_orders = node.getBool("nonreactant-orders", false); if (m_third_body) { - try { - m_third_body->setParameters(node); - if (m_third_body->name() == "M" && m_third_body->efficiencies.size() == 1) { - m_explicit_3rd = true; - } - } catch (CanteraError& err) { - throw InputFileError("Reaction::setParameters", input, err.getMessage()); + m_third_body->setParameters(node); + if (m_third_body->name() == "M" && m_third_body->efficiencies.size() == 1) { + m_third_body->explicit_3rd = true; } } else if (node.hasKey("default-efficiency") || node.hasKey("efficiencies")) { throw InputFileError("Reaction::setParameters", input, @@ -401,8 +397,8 @@ void Reaction::setEquation(const std::string& equation, const Kinetics* kin) "ThirdBody object needs to specify a single species", equation); } third_body = effs.begin()->first; - m_explicit_3rd = true; - } else if (input.hasKey("efficiencies") && input.hasKey("default-efficiency")) { + m_third_body->explicit_3rd = true; + } else if (input.hasKey("efficiencies")) { // third body is implicitly defined by efficiency auto effs = input["efficiencies"].asMap(); if (effs.size() != 1 || !reactants.count(effs.begin()->first)) { @@ -411,13 +407,14 @@ void Reaction::setEquation(const std::string& equation, const Kinetics* kin) "Collision efficiencies need to specify single species", equation); } third_body = effs.begin()->first; - m_explicit_3rd = true; - } else if (input.hasKey("efficiencies") || input.hasKey("default-efficiency")) { + m_third_body.reset(new ThirdBody(third_body)); + m_third_body->explicit_3rd = true; + } else if (input.hasKey("default-efficiency")) { // insufficient disambiguation of third bodies throw InputFileError("Reaction::setEquation", input, "Detected ambiguous third body colliders in reaction '{}'\n" - "Third-body definition requires specification of efficiencies " - "as well as default efficiency", equation); + "Third-body definition requires specification of efficiencies", + equation); } else if (ba::starts_with(rate_type, "three-body")) { // no disambiguation of third bodies throw InputFileError("Reaction::setEquation", input, @@ -761,7 +758,13 @@ void ThirdBody::setEfficiencies(const AnyMap& node) void ThirdBody::setParameters(const AnyMap& node) { if (node.hasKey("default-efficiency")) { - default_efficiency = node["default-efficiency"].asDouble(); + double value = node["default-efficiency"].asDouble(); + if (m_name != "M" && value != 0.) { + throw InputFileError("ThirdBody::setParameters", node["default-efficiency"], + "Invalid default efficiency for explicit collider {};\n" + "value is optional and/or needs to be zero", m_name); + } + default_efficiency = value; } if (node.hasKey("efficiencies")) { efficiencies = node["efficiencies"].asMap(); @@ -769,19 +772,19 @@ void ThirdBody::setParameters(const AnyMap& node) if (m_name != "M" && (efficiencies.size() != 1 || efficiencies.begin()->first != m_name)) { - throw CanteraError("Reaction::setEquation", + throw InputFileError("ThirdBody::setParameters", node, "Detected incompatible third body colliders definitions"); } } -void ThirdBody::getParameters(AnyMap& node, bool explicit_3rd) const +void ThirdBody::getParameters(AnyMap& node) const { if (m_name == "M" || explicit_3rd) { if (efficiencies.size()) { node["efficiencies"] = efficiencies; node["efficiencies"].setFlowStyle(); } - if (default_efficiency != 1.0) { + if (default_efficiency != 1.0 && !explicit_3rd) { node["default-efficiency"] = default_efficiency; } }