[Input] Parse YAML entries for three body reactions

This commit is contained in:
Ray Speth 2018-12-05 18:43:00 -05:00
parent 0220e11ef9
commit 8b502d4065
2 changed files with 61 additions and 1 deletions

View file

@ -293,7 +293,10 @@ Arrhenius readArrhenius(const Reaction& R, const AnyValue& rate_node,
for (const auto& stoich : R.reactants) {
// Order for each reactant is the reactant stoichiometric coefficient,
// unless already overridden by user-specified orders
if (R.orders.find(stoich.first) == R.orders.end()) {
if (stoich.first == "M") {
len_dim += kin.thermo(kin.reactionPhaseIndex()).nDim();
quantity_dim -= 1.0;
} else if (R.orders.find(stoich.first) == R.orders.end()) {
len_dim += stoich.second * kin.speciesPhase(stoich.first).nDim();
quantity_dim -= stoich.second;
}
@ -360,6 +363,14 @@ void readEfficiencies(ThirdBody& tbody, const XML_Node& rc_node)
tbody.efficiencies = parseCompString(eff_node.value());
}
void readEfficiencies(ThirdBody& tbody, const AnyMap& node)
{
tbody.default_efficiency = node.getDouble("default-efficiency", 1.0);
if (node.hasKey("efficiencies")) {
tbody.efficiencies = node.at("efficiencies").asMap<double>();
}
}
void setupReaction(Reaction& R, const XML_Node& rxn_node)
{
// Reactant and product stoichiometries
@ -473,6 +484,20 @@ void setupThreeBodyReaction(ThreeBodyReaction& R, const XML_Node& rxn_node)
setupElementaryReaction(R, rxn_node);
}
void setupThreeBodyReaction(ThreeBodyReaction& R, const AnyMap& node,
const Kinetics& kin, const UnitSystem& units)
{
setupElementaryReaction(R, node, kin, units);
if (R.reactants.count("M") != 1 || R.products.count("M") != 1) {
throw CanteraError("setupThreeBodyReaction",
"Reaction equation '{}' does not contain third body 'M'",
node.at("equation").asString());
}
R.reactants.erase("M");
R.products.erase("M");
readEfficiencies(R.third_body, node);
}
void setupFalloffReaction(FalloffReaction& R, const XML_Node& rxn_node)
{
XML_Node& rc_node = rxn_node.child("rateCoeff");
@ -761,6 +786,10 @@ unique_ptr<Reaction> newReaction(const AnyMap& node, const Kinetics& kin,
unique_ptr<ElementaryReaction> R(new ElementaryReaction());
setupElementaryReaction(*R, node, kin, units);
return unique_ptr<Reaction>(move(R));
} else if (type == "three-body") {
unique_ptr<ThreeBodyReaction> R(new ThreeBodyReaction());
setupThreeBodyReaction(*R, node, kin, units);
return unique_ptr<Reaction>(move(R));
} else {
throw CanteraError("newReaction", "Unknown reaction type '{}'", type);
}

View file

@ -26,3 +26,34 @@ TEST(Reaction, ElementaryFromYaml)
EXPECT_TRUE(ER.allow_negative_pre_exponential_factor);
EXPECT_FALSE(ER.allow_negative_orders);
}
TEST(Reaction, ThreeBodyFromYaml1)
{
IdealGasMix gas("gri30.xml");
AnyMap rxn = AnyMap::fromYamlString(
"{equation: 2 O + M <=> O2 + M,"
" type: three-body,"
" rate-constant: [1.20000E+17 cm^6/mol^2/s, -1, 0],"
" efficiencies: {AR: 0.83, H2O: 5}}");
UnitSystem U;
auto R = newReaction(rxn, gas, U);
EXPECT_EQ(R->reactants.count("M"), (size_t) 0);
auto TBR = dynamic_cast<ThreeBodyReaction&>(*R);
EXPECT_DOUBLE_EQ(TBR.rate.preExponentialFactor(), 1.2e11);
EXPECT_DOUBLE_EQ(TBR.third_body.efficiencies["H2O"], 5.0);
EXPECT_DOUBLE_EQ(TBR.third_body.default_efficiency, 1.0);
}
TEST(Reaction, ThreeBodyFromYaml2)
{
IdealGasMix gas("gri30.xml");
AnyMap rxn = AnyMap::fromYamlString(
"{equation: 2 O <=> O2," // Missing "M" on each side of the equation
" type: three-body,"
" rate-constant: [1.20000E+17, -1, 0]}");
UnitSystem U;
EXPECT_THROW(newReaction(rxn, gas, U), CanteraError);
}