Skip to content

Commit

Permalink
[UnitTests] Cover edge cases for three-body reaction logic
Browse files Browse the repository at this point in the history
  • Loading branch information
ischoegl authored and speth committed Jul 24, 2022
1 parent 451dd75 commit bf617fb
Show file tree
Hide file tree
Showing 2 changed files with 222 additions and 0 deletions.
43 changes: 43 additions & 0 deletions test/kinetics/kineticsFromScratch.cpp
Expand Up @@ -149,6 +149,49 @@ TEST_F(KineticsFromScratch, multiple_third_bodies3)
EXPECT_TRUE(R->usesThirdBody());
}

TEST_F(KineticsFromScratch, multiple_third_bodies4)
{
std::string equation = "H2 + O2 => H2 + O2";
auto rate = make_shared<ArrheniusRate>(1.2e11, -1.0, 0.0);
auto tbody = make_shared<ThirdBody>("O2");
auto R = make_shared<Reaction>(equation, rate, tbody);

AnyMap input = R->parameters();
EXPECT_FALSE(input.hasKey("type"));
EXPECT_TRUE(input.hasKey("efficiencies"));
auto efficiencies = input["efficiencies"].asMap<double>();
EXPECT_EQ(efficiencies.size(), 1);
EXPECT_EQ(efficiencies.begin()->first, "O2");
EXPECT_TRUE(input.hasKey("default-efficiency"));
EXPECT_EQ(input["default-efficiency"].asDouble(), 0.);
}

TEST_F(KineticsFromScratch, multiple_third_bodies5)
{
std::string equation = "H2 + O2 => H2 + O2";
auto rate = make_shared<ArrheniusRate>(1.2e11, -1.0, 0.0);
auto tbody = make_shared<ThirdBody>("AR"); // incompatible third body
ASSERT_THROW(Reaction(equation, rate, tbody), CanteraError);
}

TEST_F(KineticsFromScratch, multiple_third_bodies6)
{
Composition reac = parseCompString("H2:1");
Composition prod = parseCompString("H2:1");
auto rate = make_shared<ArrheniusRate>(1.2e11, -1.0, 0.0);
auto tbody = make_shared<ThirdBody>("O2");
auto R = make_shared<Reaction>(reac, prod, rate, tbody);

AnyMap input = R->parameters();
EXPECT_FALSE(input.hasKey("type"));
EXPECT_TRUE(input.hasKey("efficiencies"));
auto efficiencies = input["efficiencies"].asMap<double>();
EXPECT_EQ(efficiencies.size(), 1);
EXPECT_EQ(efficiencies.begin()->first, "O2");
EXPECT_TRUE(input.hasKey("default-efficiency"));
EXPECT_EQ(input["default-efficiency"].asDouble(), 0.);
}

TEST_F(KineticsFromScratch, add_two_temperature_plasma)
{
std::string equation = "O + H => O + H";
Expand Down
179 changes: 179 additions & 0 deletions test/kinetics/kineticsFromYaml.cpp
Expand Up @@ -91,6 +91,119 @@ TEST(Reaction, ThreeBodyFromYaml2)

const auto& rate = std::dynamic_pointer_cast<ArrheniusRate>(R->rate());
EXPECT_DOUBLE_EQ(rate->preExponentialFactor(), 1.2e11);

AnyMap input = R->parameters();
EXPECT_FALSE(input.hasKey("type"));
EXPECT_TRUE(input.hasKey("efficiencies"));

auto efficiencies = input["efficiencies"].asMap<double>();
EXPECT_EQ(efficiencies.size(), 2);
EXPECT_EQ(efficiencies["AR"], 0.83);
EXPECT_EQ(efficiencies["H2O"], 5.);
}

TEST(Reaction, ThreeBodyFromYaml3)
{
auto sol = newSolution("gri30.yaml", "", "None");
AnyMap rxn = AnyMap::fromYamlString(
"{equation: CH2 + M <=> CH2(S) + M,"
" rate-constant: {A: 5.0e+9, b: 0.0, Ea: 0.0}}");

auto R = new Reaction(rxn, *(sol->kinetics()));
EXPECT_EQ(R->type(), "three-body-Arrhenius");
EXPECT_TRUE(R->usesThirdBody());
EXPECT_EQ(R->thirdBody()->name(), "M");

const auto& rate = std::dynamic_pointer_cast<ArrheniusRate>(R->rate());
EXPECT_DOUBLE_EQ(rate->preExponentialFactor(), 5.0e+9);
}

TEST(Reaction, ThreeBodyFromYaml4)
{
auto sol = newSolution("gri30.yaml", "", "None");
AnyMap rxn = AnyMap::fromYamlString(
"{equation: CH2 + O2 <=> CH2(S) + O2,"
" type: three-body,"
" rate-constant: {A: 5.0e+9, b: 0.0, Ea: 0.0}}");

auto R = newReaction(rxn, *(sol->kinetics()));
EXPECT_EQ(R->type(), "three-body-Arrhenius");
EXPECT_TRUE(R->usesThirdBody());
EXPECT_EQ(R->thirdBody()->name(), "O2");

const auto& rate = std::dynamic_pointer_cast<ArrheniusRate>(R->rate());
EXPECT_DOUBLE_EQ(rate->preExponentialFactor(), 5.0e+9);

AnyMap input = R->parameters();
EXPECT_EQ(input.getString("type", ""), "three-body");
EXPECT_FALSE(input.hasKey("efficiencies"));
EXPECT_FALSE(input.hasKey("default-efficiency"));
}

TEST(Reaction, ThreeBodyFromYaml5)
{
auto sol = newSolution("gri30.yaml", "", "None");
AnyMap rxn = AnyMap::fromYamlString(
"{equation: CH2 + O2 <=> CH2 + O2,"
" type: three-body,"
" rate-constant: {A: 5.0e+9, b: 0.0, Ea: 0.0}}");

EXPECT_THROW(newReaction(rxn, *(sol->kinetics())), CanteraError);
}

TEST(Reaction, ThreeBodyFromYaml6)
{
auto sol = newSolution("gri30.yaml", "", "None");
AnyMap rxn = AnyMap::fromYamlString(
"{equation: CH2 + O2 <=> CH2 + O2,"
" rate-constant: {A: 5.0e+9, b: 0.0, Ea: 0.0},"
" default-efficiency: 0.,"
" efficiencies: {O2: 1.}}");

auto R = newReaction(rxn, *(sol->kinetics()));
EXPECT_EQ(R->type(), "three-body-Arrhenius");
EXPECT_TRUE(R->usesThirdBody());
EXPECT_EQ(R->thirdBody()->name(), "O2");

const auto& rate = std::dynamic_pointer_cast<ArrheniusRate>(R->rate());
EXPECT_DOUBLE_EQ(rate->preExponentialFactor(), 5.0e+9);

AnyMap input = R->parameters();
EXPECT_FALSE(input.hasKey("type"));
EXPECT_TRUE(input.hasKey("efficiencies"));
auto efficiencies = input["efficiencies"].asMap<double>();
EXPECT_EQ(efficiencies.size(), 1);
EXPECT_EQ(efficiencies.begin()->first, "O2");
EXPECT_TRUE(input.hasKey("default-efficiency"));
EXPECT_EQ(input["default-efficiency"].asDouble(), 0.);
}

TEST(Reaction, ThreeBodyFromYaml7)
{
auto sol = newSolution("gri30.yaml", "", "None");
AnyMap rxn = AnyMap::fromYamlString(
"{equation: CH2 + O2 <=> CH2 + O2,"
" type: three-body,"
" rate-constant: {A: 5.0e+9, b: 0.0, Ea: 0.0},"
" default-efficiency: 0.,"
" efficiencies: {O2: 1.}}");

auto R = newReaction(rxn, *(sol->kinetics()));
EXPECT_EQ(R->type(), "three-body-Arrhenius");
EXPECT_TRUE(R->usesThirdBody());
EXPECT_EQ(R->thirdBody()->name(), "O2");

const auto& rate = std::dynamic_pointer_cast<ArrheniusRate>(R->rate());
EXPECT_DOUBLE_EQ(rate->preExponentialFactor(), 5.0e+9);

AnyMap input = R->parameters();
EXPECT_EQ(input.getString("type", ""), "three-body");
EXPECT_TRUE(input.hasKey("efficiencies"));
auto efficiencies = input["efficiencies"].asMap<double>();
EXPECT_EQ(efficiencies.size(), 1);
EXPECT_EQ(efficiencies.begin()->first, "O2");
EXPECT_TRUE(input.hasKey("default-efficiency"));
EXPECT_EQ(input["default-efficiency"].asDouble(), 0.);
}

TEST(Reaction, ThreeBodyFromYamlMissingM)
Expand All @@ -104,6 +217,41 @@ TEST(Reaction, ThreeBodyFromYamlMissingM)
EXPECT_THROW(newReaction(rxn, *(sol->kinetics())), CanteraError);
}

TEST(Reaction, ThreeBodyFromYamlMultiple)
{
auto sol = newSolution("gri30.yaml", "", "None");
AnyMap rxn = AnyMap::fromYamlString(
"{equation: CH2 + O2 <=> CH2 + O2,"
" type: three-body," // ambiguous valid explicit third bodies
" rate-constant: {A: 5.0e+9, b: 0.0, Ea: 0.0}}");

EXPECT_THROW(newReaction(rxn, *(sol->kinetics())), CanteraError);
}

TEST(Reaction, ThreeBodyFromYamlIncompatible1)
{
auto sol = newSolution("gri30.yaml", "", "None");
AnyMap rxn = AnyMap::fromYamlString(
"{equation: CH2 + O2 <=> CH2 + O2,"
" rate-constant: {A: 5.0e+9, b: 0.0, Ea: 0.0},"
" default-efficiency: 0.,"
" efficiencies: {AR: 1.}}"); // incompatible third body

EXPECT_THROW(newReaction(rxn, *(sol->kinetics())), CanteraError);
}

TEST(Reaction, ThreeBodyFromYamlIncompatible2)
{
auto sol = newSolution("gri30.yaml", "", "None");
AnyMap rxn = AnyMap::fromYamlString(
"{equation: CH2 + O2 <=> CH2(S) + O2,"
" rate-constant: {A: 5.0e+9, b: 0.0, Ea: 0.0},"
" default-efficiency: 0.,"
" efficiencies: {AR: 1.}}"); // incompatible single third body

EXPECT_THROW(newReaction(rxn, *(sol->kinetics())), CanteraError);
}

TEST(Reaction, FalloffFromYaml1)
{
auto sol = newSolution("gri30.yaml", "", "None");
Expand Down Expand Up @@ -290,6 +438,37 @@ TEST(Reaction, BlowersMaselFromYaml)
EXPECT_FALSE(R->allow_negative_orders);
}

TEST(Reaction, ThreeBodyBlowersMaselFromYaml)
{
auto sol = newSolution("gri30.yaml", "", "None");
AnyMap rxn = AnyMap::fromYamlString(
"{equation: CH2 + O2 <=> CH2(S) + O2,"
" type: three-body-Blowers-Masel,"
" rate-constant: [3.87e+04 cm^3/mol/s, 2.7, 6260.0 cal/mol, 1e9 cal/mol]}");

auto R = newReaction(rxn, *(sol->kinetics()));
EXPECT_EQ(R->type(), "three-body-Blowers-Masel");
EXPECT_TRUE(R->usesThirdBody());
EXPECT_EQ(R->thirdBody()->name(), "O2");

const auto& rate = std::dynamic_pointer_cast<BlowersMaselRate>(R->rate());
EXPECT_DOUBLE_EQ(rate->preExponentialFactor(), 38.7);

AnyMap input = R->parameters();
EXPECT_EQ(input.getString("type", ""), "three-body-Blowers-Masel");
}

TEST(Reaction, InvalidBlowersMaselFromYaml)
{
auto sol = newSolution("gri30.yaml", "", "None");
AnyMap rxn = AnyMap::fromYamlString(
"{equation: O + H2 <=> H + OH,"
" type: three-body-Blowers-Masel,"
" rate-constant: [3.87e+04 cm^3/mol/s, 2.7, 6260.0 cal/mol, 1e9 cal/mol]}");

EXPECT_THROW(newReaction(rxn, *(sol->kinetics())), CanteraError);
}

TEST(Reaction, TwoTempPlasmaFromYaml)
{
auto sol = newSolution("ET_test.yaml");
Expand Down

0 comments on commit bf617fb

Please sign in to comment.