Skip to content

Commit

Permalink
[Input] Improve behavior when kinetics / reactions are unspecified
Browse files Browse the repository at this point in the history
Including a 'reactions' field without a 'kinetics' field in the phase definition
is an error.

Including a 'kinetics' field without a 'reactions' field is fine, even if no
'reactions' section exists.
  • Loading branch information
speth committed Dec 16, 2019
1 parent c4c30e3 commit 8b95189
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 7 deletions.
18 changes: 11 additions & 7 deletions src/kinetics/KineticsFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ unique_ptr<Kinetics> newKinetics(vector<ThermoPhase*>& phases,
kin->addPhase(*phase);
}
kin->init();
if (kin->kineticsType() != "Kinetics") {
addReactions(*kin, phaseNode, rootNode);
}
addReactions(*kin, phaseNode, rootNode);
return kin;
}

Expand Down Expand Up @@ -103,10 +101,15 @@ void addReactions(Kinetics& kin, const AnyMap& phaseNode, const AnyMap& rootNode
vector<string> sections, rules;

if (phaseNode.hasKey("reactions")) {
if (kin.kineticsType() == "Kinetics") {
throw InputFileError("addReactions", phaseNode["reactions"],
"Phase entry includes a 'reactions' field but does not "
"specify a kinetics model.");
}
const auto& reactionsNode = phaseNode.at("reactions");
if (reactionsNode.is<string>()) {
if (reactionsNode.is<string>() && rootNode.hasKey("reactions")) {
// Specification of the rule for adding species from the default
// 'reactions' section
// 'reactions' section, if it exists
sections.push_back("reactions");
rules.push_back(reactionsNode.asString());
} else if (reactionsNode.is<vector<string>>()) {
Expand All @@ -123,8 +126,9 @@ void addReactions(Kinetics& kin, const AnyMap& phaseNode, const AnyMap& rootNode
rules.push_back(item.begin()->second.asString());
}
}
} else {
// Default behavior is to add all reactions from the 'reactions' section
} else if (kin.kineticsType() != "Kinetics" && rootNode.hasKey("reactions")) {
// Default behavior is to add all reactions from the 'reactions'
// section, if a 'kinetics' model has been specified
sections.push_back("reactions");
rules.push_back("all");
}
Expand Down
24 changes: 24 additions & 0 deletions test/data/phase-reaction-spec1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
phases:
# should work fine
- name: nokinetics-noreactions
species: [{gri30.yaml/species: [O2, H2, H2O]}]
thermo: ideal-gas

# should also work fine
- name: kinetics-noreactions
species: [{gri30.yaml/species: [O2, H2, H2O]}]
thermo: ideal-gas
kinetics: gas

# should also work fine
- name: kinetics-zero-reactions
species: [{gri30.yaml/species: [O2, H2, H2O]}]
thermo: ideal-gas
kinetics: gas
reactions: all

# should be an error
- name: nokinetics-reactions
species: [{gri30.yaml/species: [O2, H2, H2O]}]
thermo: ideal-gas
reactions: all
21 changes: 21 additions & 0 deletions test/data/phase-reaction-spec2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
phases:
# should work fine (no reactions)
- name: nokinetics-noreactions
species: [{gri30.yaml/species: [O2, H2, H2O]}]
thermo: ideal-gas

# should also work fine (all reactions)
- name: kinetics-noreactions
species: [{gri30.yaml/species: [O2, H2, H2O]}]
thermo: ideal-gas
kinetics: gas

# should be an error
- name: nokinetics-reactions
species: [{gri30.yaml/species: [O2, H2, H2O]}]
thermo: ideal-gas
reactions: all

reactions:
- equation: 2 H2 + O2 => 2 H2O
rate-constant: {A: 1.4e11, b: 0.5, Ea: 2400 cal/mol}
54 changes: 54 additions & 0 deletions test/kinetics/kineticsFromYaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,57 @@ TEST(Kinetics, ElectrochemFromYaml)
EXPECT_NEAR(ropf[0], 0.279762338, 1e-8);
EXPECT_NEAR(ropr[0], 0.045559670, 1e-8);
}

TEST(KineticsFromYaml, NoKineticsModelOrReactionsField1)
{
auto soln = newSolution("phase-reaction-spec1.yaml",
"nokinetics-noreactions");
EXPECT_EQ(soln->kinetics()->kineticsType(), "Kinetics");
EXPECT_EQ(soln->kinetics()->nReactions(), (size_t) 0);
}

TEST(KineticsFromYaml, NoKineticsModelOrReactionsField2)
{
auto soln = newSolution("phase-reaction-spec2.yaml",
"nokinetics-noreactions");
EXPECT_EQ(soln->kinetics()->kineticsType(), "Kinetics");
EXPECT_EQ(soln->kinetics()->nReactions(), (size_t) 0);
}

TEST(KineticsFromYaml, KineticsModelWithoutReactionsField1)
{
auto soln = newSolution("phase-reaction-spec1.yaml",
"kinetics-noreactions");
EXPECT_EQ(soln->kinetics()->kineticsType(), "Gas");
EXPECT_EQ(soln->kinetics()->nReactions(), (size_t) 0);
}

TEST(KineticsFromYaml, KineticsModelWithZeroReactions)
{
auto soln = newSolution("phase-reaction-spec1.yaml",
"kinetics-zero-reactions");
EXPECT_EQ(soln->kinetics()->kineticsType(), "Gas");
EXPECT_EQ(soln->kinetics()->nReactions(), (size_t) 0);
}

TEST(KineticsFromYaml, KineticsModelWithoutReactionsField2)
{
auto soln = newSolution("phase-reaction-spec2.yaml",
"kinetics-noreactions");
EXPECT_EQ(soln->kinetics()->kineticsType(), "Gas");
EXPECT_EQ(soln->kinetics()->nReactions(), (size_t) 1);
}

TEST(KineticsFromYaml, ReactionsFieldWithoutKineticsModel1)
{
EXPECT_THROW(newSolution("phase-reaction-spec1.yaml",
"nokinetics-reactions"),
InputFileError);
}

TEST(KineticsFromYaml, ReactionsFieldWithoutKineticsModel2)
{
EXPECT_THROW(newSolution("phase-reaction-spec2.yaml",
"nokinetics-reactions"),
InputFileError);
}

0 comments on commit 8b95189

Please sign in to comment.