diff --git a/doc/sphinx/reference/kinetics/rate-constants.md b/doc/sphinx/reference/kinetics/rate-constants.md index acde283954..7045e6bf62 100644 --- a/doc/sphinx/reference/kinetics/rate-constants.md +++ b/doc/sphinx/reference/kinetics/rate-constants.md @@ -316,7 +316,7 @@ different third-body efficiencies often are much more similar at the same reduce pressure ($R$) than at the same pressure ($P$) and, in fact, are exactly the same if they differ in only their collision frequency (but have the same energy- and angular-momentum-transfer kernel). This equation forms the basis of the computational -implementation of LMR-R in Cantera via the :ct:`LinearBurkeRate` reaction class, as it +implementation of LMR-R in Cantera via the {ct}`LinearBurkeRate` reaction class, as it enables the most accurate representation of $k_{\text{LMR-R}}(T,P,\boldsymbol{X})$ possible given limitations in the completeness of the dataset at any given moment. Further description of the LMR-R theory and computational method is available in diff --git a/doc/sphinx/yaml/reactions.rst b/doc/sphinx/yaml/reactions.rst index 88ab9e258a..38b3ab5308 100644 --- a/doc/sphinx/yaml/reactions.rst +++ b/doc/sphinx/yaml/reactions.rst @@ -450,11 +450,11 @@ Additional fields are: collider ``M``, defined as :math:`\epsilon_{0,i}(T)=\Lambda_{0,i}(T)/\Lambda_{0,\text{M}}(T)`. The user does not need to assign an ``efficiency`` for ``M``, as it is always equal to 1 by definition. However, they are free to do so, as long as it takes - the form 'efficiency: {A: 1, b: 0, Ea: 0}' (no other variations are permitted). + the form ``efficiency: {A: 1, b: 0, Ea: 0}`` (no variations are permitted). This parameter is entered in modified Arrhenius format to enable consideration of temperature dependence. If the user wishes to specify a temperature-independent value, then ``A`` can be set to this value and ``b`` and - ``Ea`` can be set to 0 (such as 'H2O: {A: 10, b: 0, Ea: 0}'). + ``Ea`` can be set to 0 (such as ``H2O: {A: 10, b: 0, Ea: 0}``). A :ref:`Troe ` implementation also requires: ``high-P-rate-constant``, ``low-P-rate-constant``, ``Troe`` (do not use the Troe ``efficiencies`` key). @@ -467,7 +467,7 @@ Additional fields are: Examples: -*`linear-Burke` rate with Troe format for the reference collider (N2)*: +`linear-Burke` *rate with Troe format for the reference collider (N2)*:: equation: H + OH <=> H2O type: linear-Burke @@ -482,7 +482,7 @@ Examples: - name: H2O efficiency: {A: 1.04529e-01, b: 5.50787e-01, Ea: -2.32675e+02} -*`linear-Burke` rate with PLOG format for the reference collider (Ar)*: +`linear-Burke` *rate with PLOG format for the reference collider (Ar)*:: equation: H + O2 (+M) <=> HO2 (+M) # Adding '(+M)' is optional type: linear-Burke @@ -511,7 +511,7 @@ Examples: - name: H2O efficiency: {A: 3.69146e+01, b: -7.12902e-02, Ea: 3.19087e+01} -*`linear-Burke` rate with Chebyshev format for the reference collider (Ar)*: +`linear-Burke` *rate with Chebyshev format for the reference collider (Ar)*:: equation: H2O2 <=> 2 OH type: linear-Burke diff --git a/include/cantera/kinetics/LinearBurkeRate.h b/include/cantera/kinetics/LinearBurkeRate.h index e1825cf4a9..7e3a027b9b 100644 --- a/include/cantera/kinetics/LinearBurkeRate.h +++ b/include/cantera/kinetics/LinearBurkeRate.h @@ -70,6 +70,7 @@ struct LinearBurkeData : public ReactionData //! This parameterization is described by Singal et al. @cite singal2024 and in the //! [science reference](../reference/kinetics/rate-constants.html#linear-burke-rate-expressions) //! documentation. +//! @ingroup otherRateGroup class LinearBurkeRate final : public ReactionRate { public: @@ -94,9 +95,9 @@ class LinearBurkeRate final : public ReactionRate void getParameters(AnyMap& rateNode) const override; - //! Create type alias that refers to PlogRate, TroeRate, and ChebyshevRate + //! Type alias that refers to PlogRate, TroeRate, and ChebyshevRate using RateTypes = boost::variant; - //! Create type alias that refers to PlogData, FalloffData, and ChebyshevData + //! Type alias that refers to PlogData, FalloffData, and ChebyshevData using DataTypes = boost::variant; double evalFromStruct(const LinearBurkeData& shared_data); @@ -106,27 +107,20 @@ class LinearBurkeRate final : public ReactionRate void validate(const string& equation, const Kinetics& kin) override; protected: - //! Evaluate overall reaction rate using PLOG to evaluate - //! pressure-dependent aspect of the reaction - double evalPlogRate( - const LinearBurkeData& shared_data, - DataTypes& dataObj, - RateTypes& rateObj, - double logPeff); - //! Evaluate overall reaction rate using Troe to evaluate - //! pressure-dependent aspect of the reaction - double evalTroeRate( - const LinearBurkeData& shared_data, - DataTypes& dataObj, - RateTypes& rateObj, - double logPeff); - //! Evaluate overall reaction rate using Chebyshev to evaluate - //! pressure-dependent aspect of the reaction - double evalChebyshevRate( - const LinearBurkeData& shared_data, - DataTypes& dataObj, - RateTypes& rateObj, - double logPeff); + //! Evaluate overall reaction rate using PLOG to evaluate pressure-dependent aspect + //! of the reaction + double evalPlogRate(const LinearBurkeData& shared_data, DataTypes& dataObj, + RateTypes& rateObj, double logPeff); + + //! Evaluate overall reaction rate using Troe to evaluate pressure-dependent aspect + //! of the reaction + double evalTroeRate(const LinearBurkeData& shared_data, DataTypes& dataObj, + RateTypes& rateObj, double logPeff); + + //! Evaluate overall reaction rate using Chebyshev to evaluate pressure-dependent + //! aspect of the reaction + double evalChebyshevRate(const LinearBurkeData& shared_data, DataTypes& dataObj, + RateTypes& rateObj, double logPeff); //! String name of each collider, appearing in the same order as that of the //! original reaction input. @@ -141,7 +135,7 @@ class LinearBurkeRate final : public ReactionRate //! Third-body collision efficiency object for k(T,P,X) and eig0_mix calculation vector m_epsObjs1; - //! Third-body collision efficiency object for m_logPeff_ calculation + //! Third-body collision efficiency object for logPeff calculation vector m_epsObjs2; //! Third-body collision efficiency object for the reference collider M //! (eig0_M/eig0_M = 1 always) diff --git a/samples/python/kinetics/jet_stirred_reactor.py b/samples/python/kinetics/jet_stirred_reactor.py index 7862b29eff..052aa6cbfe 100644 --- a/samples/python/kinetics/jet_stirred_reactor.py +++ b/samples/python/kinetics/jet_stirred_reactor.py @@ -28,9 +28,9 @@ Mixture Rules Has a Substantial Impact on Combustion Predictions for H2 and NH3, Proc. Combust. Inst. 40 (2024). -Requires: cantera >= 3.1 +Requires: cantera >= 3.1, pandas, matplotlib -.. tags:: jet-stirred reactor, kinetics +.. tags:: jet-stirred reactor, kinetics, combustion """ import numpy as np diff --git a/samples/python/kinetics/shock_tube.py b/samples/python/kinetics/shock_tube.py index 74cf167800..a07a7484a6 100644 --- a/samples/python/kinetics/shock_tube.py +++ b/samples/python/kinetics/shock_tube.py @@ -27,9 +27,9 @@ Mixture Rules Has a Substantial Impact on Combustion Predictions for H2 and NH3, Proc. Combust. Inst. 40 (2024). -Requires: cantera >= 3.1 +Requires: cantera >= 3.1, matplotlib -.. tags:: shock tube, kinetics +.. tags:: shock tube, kinetics, combustion """ import cantera as ct diff --git a/samples/python/onedim/flame_speed.py b/samples/python/onedim/flame_speed.py index 4ccc8d9175..05b25173ba 100644 --- a/samples/python/onedim/flame_speed.py +++ b/samples/python/onedim/flame_speed.py @@ -26,7 +26,7 @@ Requires: cantera >= 3.1 -.. tags:: flame speed, kinetics +.. tags:: flame speed, kinetics, combustion, premixed flame """ import cantera as ct diff --git a/src/kinetics/LinearBurkeRate.cpp b/src/kinetics/LinearBurkeRate.cpp index 949bc071cc..cc0e60c643 100644 --- a/src/kinetics/LinearBurkeRate.cpp +++ b/src/kinetics/LinearBurkeRate.cpp @@ -100,8 +100,7 @@ void LinearBurkeRate::setParameters(const AnyMap& node, const UnitStack& rate_un } else if (colliders[0]["type"] == "Chebyshev") { m_rateObj_M = ChebyshevRate(colliders[0], rate_units); m_dataObj_M = ChebyshevData(); - } - else { + } else { throw InputFileError("LinearBurkeRate::setParameters", m_input, "Collider 'M' for reaction '{}' must be specified in a" " pressure-dependent-Arrhenius (PLOG), falloff (Troe form), or Chebyshev" @@ -116,51 +115,49 @@ void LinearBurkeRate::setParameters(const AnyMap& node, const UnitStack& rate_un string eig_eps_key; // If using eig0 for all colliders, then it is mandatory to specify an eig0 value // for the reference collider - if (colliders[0].hasKey("eig0")){ + if (colliders[0].hasKey("eig0")) { eig_eps_key = "eig0"; - } - else { + } else { eig_eps_key = "efficiency"; colliders[0][eig_eps_key] = params; } // Start at 1 because index 0 is for "M" - for (size_t i = 1; i < colliders.size(); i++){ + for (size_t i = 1; i < colliders.size(); i++) { if (!colliders[i].hasKey("name")) { throw InputFileError("LinearBurkeRate::setParameters", m_input, "The collider located at index '{}' in 'colliders' of reaction '{}'" " has no 'name' defined.", i, eqn); } auto nm = colliders[i]["name"].asString(); - if (eig_eps_key == "eig0"){ // 'M' has 'eig0' - if (!colliders[i].hasKey("eig0") && !colliders[i].hasKey("efficiency")){ + if (eig_eps_key == "eig0") { // 'M' has 'eig0' + if (!colliders[i].hasKey("eig0") && !colliders[i].hasKey("efficiency")) { throw InputFileError("LinearBurkeRate::setParameters", m_input, "Collider '{}' in reaction '{}' lacks an 'eig0' key.", nm, eqn); - } else if (!colliders[i].hasKey("eig0") && colliders[i].hasKey("efficiency")){ + } else if (!colliders[i].hasKey("eig0") && colliders[i].hasKey("efficiency")) { throw InputFileError("LinearBurkeRate::setParameters", m_input, "Since 'M' has been explicitly given 'eig0', all other " "colliders must receive 'eig0' as well. No mixing and matching " "of 'eig0' and 'efficiency' is allowed.", eqn); - } else if (colliders[i].hasKey("eig0") && colliders[i].hasKey("efficiency")){ + } else if (colliders[i].hasKey("eig0") && colliders[i].hasKey("efficiency")) { throw InputFileError("LinearBurkeRate::setParameters", m_input, "Collider '{}' in reaction '{}' cannot contain both 'efficiency'" " and 'eig0'. All additional colliders must also make the" " same choice as that of 'M'.", nm, eqn); } - } - else { // 'M' has 'efficiency' - if (!colliders[i].hasKey("efficiency") && !colliders[i].hasKey("eig0")){ + } else { // 'M' has 'efficiency' + if (!colliders[i].hasKey("efficiency") && !colliders[i].hasKey("eig0")) { throw InputFileError("LinearBurkeRate::setParameters", m_input, "Collider '{}' in reaction '{}' lacks an 'efficiency' key.", nm, eqn); - } else if (!colliders[i].hasKey("efficiency") && colliders[i].hasKey("eig0")){ + } else if (!colliders[i].hasKey("efficiency") && colliders[i].hasKey("eig0")) { throw InputFileError("LinearBurkeRate::setParameters", m_input, "Since 'M' has been (implicitly) given 'efficiency', all other " "colliders must also receive an 'efficiency'. No mixing and matching " "of 'efficiency' and 'eig0' is allowed.\nIf you wish to define all " "colliders according to 'eig0' instead, then an 'eig0' value must " "be explicitly provided for 'M' as well.", eqn); - } else if (colliders[i].hasKey("efficiency") && colliders[i].hasKey("eig0")){ + } else if (colliders[i].hasKey("efficiency") && colliders[i].hasKey("eig0")) { throw InputFileError("LinearBurkeRate::setParameters", m_input, "Collider '{}' in reaction '{}' cannot contain both 'eig0'" " and 'efficiency'. All additional colliders must also make the" @@ -187,31 +184,30 @@ void LinearBurkeRate::setParameters(const AnyMap& node, const UnitStack& rate_un } epsObj_i = ArrheniusRate(AnyValue(params), colliders[i].units(), eps_units); - if(colliders[i].hasKey("type")) { + if (colliders[i].hasKey("type")) { if (colliders[i]["type"] == "pressure-dependent-Arrhenius") { m_rateObjs.push_back(PlogRate(colliders[i], rate_units)); m_dataObjs.push_back(PlogData()); m_epsObjs1.push_back(epsObj_i); m_epsObjs2.push_back(epsObj_i); - } - else if (colliders[i]["type"] == "falloff" && colliders[i].hasKey("Troe")) { + } else if (colliders[i]["type"] == "falloff" + && colliders[i].hasKey("Troe")) + { TroeRate troeRateObj = TroeRate(colliders[i], rate_units); troeRateObj.setRateIndex(0); m_rateObjs.push_back(troeRateObj); m_dataObjs.push_back(FalloffData()); m_epsObjs1.push_back(epsObj_i); m_epsObjs2.push_back(epsObj_i); - } - else if (colliders[i]["type"] == "Chebyshev") { + } else if (colliders[i]["type"] == "Chebyshev") { m_rateObjs.push_back(ChebyshevRate(colliders[i], rate_units)); m_dataObjs.push_back(ChebyshevData()); m_epsObjs1.push_back(epsObj_i); m_epsObjs2.push_back(epsObj_i); } - } - // Collider has an 'efficiency' specified, but no other info is provided. Assign - // it the same rate and data objects as "M" - else { + } else { + // Collider has an 'efficiency' specified, but no other info is provided. + // Assign it the same rate and data objects as "M" m_rateObjs.push_back(m_rateObj_M); m_dataObjs.push_back(m_dataObj_M); m_epsObjs1.push_back(epsObj_i); @@ -220,11 +216,11 @@ void LinearBurkeRate::setParameters(const AnyMap& node, const UnitStack& rate_un } } -void LinearBurkeRate::validate(const string& equation, const Kinetics& kin){} +void LinearBurkeRate::validate(const string& equation, const Kinetics& kin) {} void LinearBurkeRate::setContext(const Reaction& rxn, const Kinetics& kin) { - for (size_t i = 0; i