Skip to content

Commit

Permalink
Merge 8ca6aca into 703fd1d
Browse files Browse the repository at this point in the history
  • Loading branch information
mefuller authored Sep 3, 2021
2 parents 703fd1d + 8ca6aca commit 0009a77
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 15 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Steven DeCaluwe (@decaluwe), Colorado School of Mines
Vishesh Devgan (@vdevgan)
Thomas Fiala (@thomasfiala), Technische Universität München
David Fronczek
Mark E. Fuller (@mefuller), Technion
Matteo Giani (@MarcDuQuesne)
Dave Goodwin, California Institute of Technology
John Hewson (@jchewson), Sandia National Laboratory
Expand Down
103 changes: 88 additions & 15 deletions include/cantera/kinetics/Falloff.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class Falloff
* @param T Temperature [K].
* @param work storage space for intermediate results.
*/
virtual void updateTemp(doublereal T, doublereal* work) const {}
virtual void updateTemp(double T, double* work) const {}

/**
* The falloff function. This is defined so that the rate coefficient is
Expand All @@ -67,7 +67,7 @@ class Falloff
* to updateTemp.
* @returns the value of the falloff function \f$ F \f$ defined above
*/
virtual doublereal F(doublereal pr, const doublereal* work) const {
virtual double F(double pr, const double* work) const {
return 1.0;
}

Expand Down Expand Up @@ -144,9 +144,9 @@ class Troe : public Falloff
* @param work Vector of working space, length 1, representing the
* temperature-dependent part of the parameterization.
*/
virtual void updateTemp(doublereal T, doublereal* work) const;
virtual void updateTemp(double T, double* work) const;

virtual doublereal F(doublereal pr, const doublereal* work) const;
virtual double F(double pr, const double* work) const;

virtual size_t workSize() {
return 1;
Expand All @@ -167,16 +167,16 @@ class Troe : public Falloff

protected:
//! parameter a in the 4-parameter Troe falloff function. Dimensionless
doublereal m_a;
double m_a;

//! parameter 1/T_3 in the 4-parameter Troe falloff function. [K^-1]
doublereal m_rt3;
double m_rt3;

//! parameter 1/T_1 in the 4-parameter Troe falloff function. [K^-1]
doublereal m_rt1;
double m_rt1;

//! parameter T_2 in the 4-parameter Troe falloff function. [K]
doublereal m_t2;
double m_t2;
};

//! The SRI falloff function
Expand Down Expand Up @@ -220,9 +220,9 @@ class SRI : public Falloff
* @param work Vector of working space, length 2, representing the
* temperature-dependent part of the parameterization.
*/
virtual void updateTemp(doublereal T, doublereal* work) const;
virtual void updateTemp(double T, double* work) const;

virtual doublereal F(doublereal pr, const doublereal* work) const;
virtual double F(double pr, const double* work) const;

virtual size_t workSize() {
return 2;
Expand All @@ -243,19 +243,92 @@ class SRI : public Falloff

protected:
//! parameter a in the 5-parameter SRI falloff function. Dimensionless.
doublereal m_a;
double m_a;

//! parameter b in the 5-parameter SRI falloff function. [K]
doublereal m_b;
double m_b;

//! parameter c in the 5-parameter SRI falloff function. [K]
doublereal m_c;
double m_c;

//! parameter d in the 5-parameter SRI falloff function. Dimensionless.
doublereal m_d;
double m_d;

//! parameter d in the 5-parameter SRI falloff function. Dimensionless.
doublereal m_e;
double m_e;
};

//! The 1- or 2-parameter Tsang falloff parameterization.
/*!
* The Tsang falloff model is adapted from that of Troe.
* It provides a constant or linear in temperature value for \f$ F_{cent} \f$:
* \f[ F_{cent} = A + B*T \f]
*
* The value of \f$ F_{cent} \f$ is then applied to Troe's model for the
* determination of the value of \f$ F \f$:
* \f[ F = F_{cent}^{1/(1 + f_1^2)} \f]
* where
* \f[ f_1 = (\log_{10} P_r + C) /
* \left(N - 0.14 (\log_{10} P_r + C)\right) \f]
*
* \f[ C = -0.4 - 0.67 \log_{10} F_{cent} \f]
*
* \f[ N = 0.75 - 1.27 \log_{10} F_{cent} \f]
*
* References:
* Example of reaction database developed by Tsang utilizing this format:
* https://doi.org/10.1063/1.555890
* Example of Chemkin implementation of Tsang format (supplemental materials):
* https://doi.org/10.1016/j.combustflame.2011.02.010
*
* @ingroup falloffGroup
*/
class Tsang : public Falloff
{
public:
//! Constructor
Tsang() : m_a(0.0), m_b(0.0) {}

//! Initialization of the object
/*!
* @param c Vector of one or two doubles: The doubles are the parameters,
* a and (optionally) b of the Tsang F_cent parameterization
*/
virtual void init(const vector_fp& c);

//! Update the temperature parameters in the representation
/*!
* @param T Temperature (Kelvin)
* @param work Vector of working space, length 1, representing the
* temperature-dependent part of the parameterization.
*/
virtual void updateTemp(double T, double* work) const;

virtual double F(double pr, const double* work) const;

virtual size_t workSize() {
return 1;
}

virtual std::string type() const {
return "Tsang";
}

virtual size_t nParameters() const {
return 2;
}

//! Sets params to contain, in order, \f[ (A, B) \f]
virtual void getParameters(double* params) const;

virtual void getParameters(AnyMap& reactionNode) const;

protected:
//! parameter a in the Tsang F_cent formulation. Dimensionless
double m_a;

//! parameter b in the Tsang F_cent formulation. [K^-1]
double m_b;
};

}
Expand Down
48 changes: 48 additions & 0 deletions src/kinetics/Falloff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,52 @@ void SRI::getParameters(AnyMap& reactionNode) const
reactionNode["SRI"] = std::move(params);
}

void Tsang::init(const vector_fp& c)
{
if (c.size() != 1 && c.size() != 2) {
throw CanteraError("Tsang::init",
"Incorrect number of parameters. 1 or 2 required. Received {}.",
c.size());
}
m_a = c[0];

if (c.size() == 2) {
m_b = c[1];
}
else {
m_b = 0.0;
}
}

void Tsang::updateTemp(double T, double* work) const
{
double Fcent = m_a + (m_b * T);
*work = log10(std::max(Fcent, SmallNumber));
}

double Tsang::F(double pr, const double* work) const
{ //identical to Troe::F
double lpr = log10(std::max(pr,SmallNumber));
double cc = -0.4 - 0.67 * (*work);
double nn = 0.75 - 1.27 * (*work);
double f1 = (lpr + cc)/ (nn - 0.14 * (lpr + cc));
double lgf = (*work) / (1.0 + f1 * f1);
return pow(10.0, lgf);
}

void Tsang::getParameters(double* params) const {
params[0] = m_a;
params[1] = m_b;
}

void Tsang::getParameters(AnyMap& reactionNode) const
{
AnyMap params;
params["A"] = m_a;
params["B"] = m_b;

params.setFlowStyle();
reactionNode["Tsang"] = std::move(params);
}

}
1 change: 1 addition & 0 deletions src/kinetics/FalloffFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ FalloffFactory::FalloffFactory()
addAlias("Lindemann", "Simple");
reg("Troe", []() { return new Troe(); });
reg("SRI", []() { return new SRI(); });
reg("Tsang", []() { return new Tsang(); });
}

Falloff* FalloffFactory::newFalloff(const std::string& type, const vector_fp& c)
Expand Down
13 changes: 13 additions & 0 deletions src/kinetics/Reaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,12 @@ void readFalloff(FalloffReaction& R, const XML_Node& rc_node)
"3 or 5 parameters, but {} were given", np);
}
R.falloff = newFalloff("SRI", falloff_parameters);
} else if (caseInsensitiveEquals(falloff["type"], "tsang")) {
if (np != 2) {
throw CanteraError("readFalloff", "Tsang parameterization takes "
"2 parameters, but {} were given", np);
}
R.falloff = newFalloff("Tsang", falloff_parameters);
} else {
throw CanteraError("readFalloff", "Unrecognized falloff type: '{}'",
falloff["type"]);
Expand Down Expand Up @@ -1214,6 +1220,13 @@ void readFalloff(FalloffReaction& R, const AnyMap& node)
params.push_back(f["E"].asDouble());
}
R.falloff = newFalloff("SRI", params);
} else if (node.hasKey("Tsang")) {
auto& f = node["Tsang"].as<AnyMap>();
vector_fp params{
f["A"].asDouble(),
f["B"].asDouble()
};
R.falloff = newFalloff("Tsang", params);
} else {
R.falloff = newFalloff("Lindemann", {});
}
Expand Down
57 changes: 57 additions & 0 deletions test/data/tsang-falloff.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
description: |-
Sample reactions in the Tsang falloff format for testing.
From Lucassen et al. 2011 (doi: 10.1016/j.combustflame.2011.02.010)
generator: cti2yaml
cantera-version: 2.6.0a2
date: Mon, 30 Aug 2021 16:33:51 +0300
input-files: [Lucassen-2011.cti]

units: {length: cm, quantity: mol, activation-energy: cal/mol}

phases:
- name: gas
thermo: ideal-gas
elements: [H, C, O, N, Ar]
species:
- gri30.yaml/species: [H, NO, OH, CN, HCN, CO2, H2O, N2, N2O]
- species: [HONO]
kinetics: gas
reactions: all
transport: mixture-averaged
state:
T: 300.0
P: 1.01325e+05

species:
- name: HONO
composition: {H: 1, N: 1, O: 2}
thermo:
model: NASA7
temperature-ranges: [300.0, 1000.0, 5000.0]
data:
- [2.290413, 0.01409922, -1.367872e-05, 7.49878e-09, -1.876905e-12,
-1.043195e+04, 13.28077]
- [5.486893, 4.218065e-03, -1.649143e-06, 2.971877e-10, -2.021148e-14,
-1.126865e+04, -2.997002]
transport:
model: gas
geometry: nonlinear
diameter: 3.828
well-depth: 232.4
rotational-relaxation: 1.0
note: '31787'

reactions:
- equation: NO + OH (+ M) <=> HONO (+ M) # Reaction 761
type: falloff
low-P-rate-constant: {A: 5.08e+23, b: -2.51, Ea: -67.6}
high-P-rate-constant: {A: 1.988e+12, b: -0.05, Ea: -721.0}
Tsang: {A: 0.62, B: 0.0}
efficiencies: {CO2: 1.5, H2O: 8.3, N2: 1.0, N2O: 5.0}
- equation: HCN (+ M) <=> H + CN (+ M) # Reaction 762
type: falloff
low-P-rate-constant: {A: 3.57e+26, b: -2.6, Ea: 1.249e+05}
high-P-rate-constant: {A: 8.3e+17, b: -0.93, Ea: 1.238e+05}
Tsang: {A: 0.95, B: -1.0e-04}
efficiencies: {CO2: 1.6, H2O: 5.0, N2: 1.0, N2O: 5.0}
38 changes: 38 additions & 0 deletions test/kinetics/kineticsFromYaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,33 @@ TEST(Reaction, FalloffFromYaml2)
EXPECT_EQ(R->input["source"].asString(), "somewhere");
}

TEST(Reaction, FalloffFromYaml3)
{
auto sol = newSolution("gri30.yaml", "", "None");
AnyMap rxn = AnyMap::fromYamlString(
"{equation: HCN (+ M) <=> H + CN (+ M),"
" type: falloff,"
" low-P-rate-constant: {A: 3.57e+26, b: -2.6, Ea: 1.249e+05},"
" high-P-rate-constant: {A: 8.3e+17, b: -0.93, Ea: 1.238e+05},"
" Tsang: {A: 0.95, B: -1.0e-04},"
" efficiencies: {CO2: 1.6, H2O: 5.0, N2: 1.0, N2O: 5.0},"
" source: ARL-TR-5088}");

auto R = newReaction(rxn, *(sol->kinetics()));
auto FR = dynamic_cast<FalloffReaction&>(*R);
EXPECT_DOUBLE_EQ(FR.third_body.efficiency("N2"), 1.0);
EXPECT_DOUBLE_EQ(FR.third_body.efficiency("H2O"), 5.0);
EXPECT_DOUBLE_EQ(FR.high_rate.preExponentialFactor(), 8.3e17);
EXPECT_DOUBLE_EQ(FR.low_rate.preExponentialFactor(), 3.57e26);
EXPECT_DOUBLE_EQ(FR.high_rate.activationEnergy_R(), 123800.0 / GasConstant);
EXPECT_DOUBLE_EQ(FR.low_rate.activationEnergy_R(), 124900.0 / GasConstant);
vector_fp params(2);
FR.falloff->getParameters(params.data());
EXPECT_DOUBLE_EQ(params[0], 0.95);
EXPECT_DOUBLE_EQ(params[1], -0.0001);
EXPECT_EQ(R->input["source"].asString(), "ARL-TR-5088");
}

TEST(Reaction, ChemicallyActivatedFromYaml)
{
auto sol = newSolution("gri30.yaml", "", "None");
Expand Down Expand Up @@ -511,6 +538,17 @@ TEST_F(ReactionToYaml, SriFalloff)
compareReactions();
}

TEST_F(ReactionToYaml, TsangFalloff)
{
soln = newSolution("tsang-falloff.yaml");
soln->thermo()->setState_TPY(1000, 2e5, "NO:1.0, OH:1.0, H:1.0, CN:1.0");
duplicateReaction(0);
EXPECT_TRUE(std::dynamic_pointer_cast<FalloffReaction>(duplicate));
compareReactions();
duplicateReaction(1);
compareReactions();
}

TEST_F(ReactionToYaml, chemicallyActivated)
{
soln = newSolution("chemically-activated-reaction.yaml");
Expand Down

0 comments on commit 0009a77

Please sign in to comment.