[Kinetics] Check for unmatched duplicate reactions
Reactions which are marked as duplicates but have no matching reactions are considered errors. Fixes #389
This commit is contained in:
parent
7979a2b52a
commit
0fd2f7c4d0
3 changed files with 28 additions and 4 deletions
|
|
@ -651,6 +651,9 @@ class TestDuplicateReactions(utilities.CanteraTest):
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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) {
|
||||
|
|
@ -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());
|
||||
|
|
@ -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};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue