Skip to content

Commit

Permalink
[Kinetics] Check for unmatched duplicate reactions
Browse files Browse the repository at this point in the history
Reactions which are marked as duplicates but have no matching reactions are
considered errors.

Fixes #389
  • Loading branch information
speth committed Jan 23, 2017
1 parent 7979a2b commit 0fd2f7c
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 4 deletions.
3 changes: 3 additions & 0 deletions interfaces/cython/cantera/test/test_kinetics.py
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,9 @@ def test_declared_duplicate(self):
gas = ct.Solution(self.infile, 'I')
self.assertEqual(gas.n_reactions, 2)

def test_unmatched_duplicate(self):
self.check('J')


class TestReaction(utilities.CanteraTest):
@classmethod
Expand Down
28 changes: 24 additions & 4 deletions src/kinetics/Kinetics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "cantera/kinetics/Kinetics.h"
#include "cantera/kinetics/Reaction.h"
#include "cantera/base/stringUtils.h"
#include <unordered_set>

using namespace std;

Expand Down Expand Up @@ -156,6 +157,12 @@ std::pair<size_t, size_t> Kinetics::checkDuplicates(bool throw_err) const
//! Map of (key indicating participating species) to reaction numbers
std::map<size_t, std::vector<size_t> > participants;
std::vector<std::map<int, double> > net_stoich;
std::unordered_set<size_t> unmatched_duplicates;
for (size_t i = 0; i < m_reactions.size(); i++) {
if (m_reactions[i]->duplicate) {
unmatched_duplicates.insert(i);
}
}

for (size_t i = 0; i < m_reactions.size(); i++) {
// Get data about this reaction
Expand All @@ -178,10 +185,13 @@ std::pair<size_t, size_t> Kinetics::checkDuplicates(bool throw_err) const
vector<size_t>& related = participants[key];
for (size_t m = 0; m < related.size(); m++) {
Reaction& other = *m_reactions[related[m]];
if (R.reaction_type != other.reaction_type) {
if (R.duplicate && other.duplicate) {
// marked duplicates
unmatched_duplicates.erase(i);
unmatched_duplicates.erase(related[m]);
continue;
} else if (R.reaction_type != other.reaction_type) {
continue; // different reaction types
} else if (R.duplicate && other.duplicate) {
continue; // marked duplicates
}
doublereal c = checkDuplicateStoich(net_stoich[i], net_stoich[m]);
if (c == 0) {
Expand Down Expand Up @@ -223,7 +233,7 @@ std::pair<size_t, size_t> Kinetics::checkDuplicates(bool throw_err) const
}
}
if (throw_err) {
throw CanteraError("installReaction",
throw CanteraError("Kinetics::checkDuplicates",
"Undeclared duplicate reactions detected:\n"
"Reaction {}: {}\nReaction {}: {}\n",
i+1, other.equation(), m+1, R.equation());
Expand All @@ -233,6 +243,16 @@ std::pair<size_t, size_t> Kinetics::checkDuplicates(bool throw_err) const
}
participants[key].push_back(i);
}
if (unmatched_duplicates.size()) {
size_t i = *unmatched_duplicates.begin();
if (throw_err) {
throw CanteraError("Kinetics::checkDuplicates",
"No duplicate found for declared duplicate reaction number {}"
" ({})", i, m_reactions[i]->equation());
} else {
return {i, i};
}
}
return {npos, npos};
}

Expand Down
1 change: 1 addition & 0 deletions test/data/duplicate-reactions.cti
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ make_gas('F', 'F-*')
make_gas('G', 'G-*')
make_gas('H', 'H-*')
make_gas('I', 'I-*')
make_gas('J', ['C-1', 'F-1', 'I-1']) # unmatched duplicate

kf = [1e10, 0, 100]

Expand Down

0 comments on commit 0fd2f7c

Please sign in to comment.