[Kinetics] Fix some cases where duplicate reactions were not detected
Also add several tests which check that the various kinds of duplicate reactions are being identified as errors or allowed as intended.
This commit is contained in:
parent
ecf4301208
commit
24c509f539
3 changed files with 101 additions and 4 deletions
|
|
@ -462,3 +462,43 @@ class TestSofcKinetics(utilities.CanteraTest):
|
|||
anode_bulk.electric_potential])
|
||||
|
||||
self.compare(data, '../data/sofc-test.csv')
|
||||
|
||||
|
||||
class TestDuplicateReactions(utilities.CanteraTest):
|
||||
infile = 'duplicate-reactions.cti'
|
||||
|
||||
def check(self, name):
|
||||
with self.assertRaises(Exception) as cm:
|
||||
ct.Solution(self.infile, name)
|
||||
self.assertIn('duplicate reaction', str(cm.exception))
|
||||
|
||||
def test_forward_multiple(self):
|
||||
self.check('A')
|
||||
|
||||
def test_opposite_direction1(self):
|
||||
self.check('B')
|
||||
|
||||
def test_opposite_direction2(self):
|
||||
self.check('C')
|
||||
|
||||
def test_opposite_direction3(self):
|
||||
self.check('D')
|
||||
|
||||
def test_opposite_direction4(self):
|
||||
gas = ct.Solution(self.infile, 'E')
|
||||
self.assertEqual(gas.n_reactions, 2)
|
||||
|
||||
def test_common_efficiencies(self):
|
||||
self.check('F')
|
||||
|
||||
def test_disjoint_efficiencies(self):
|
||||
gas = ct.Solution(self.infile, 'G')
|
||||
self.assertEqual(gas.n_reactions, 2)
|
||||
|
||||
def test_different_type(self):
|
||||
gas = ct.Solution(self.infile, 'H')
|
||||
self.assertEqual(gas.n_reactions, 2)
|
||||
|
||||
def test_declared_duplicate(self):
|
||||
gas = ct.Solution(self.infile, 'I')
|
||||
self.assertEqual(gas.n_reactions, 2)
|
||||
|
|
|
|||
|
|
@ -1027,15 +1027,13 @@ bool rxninfo::installReaction(int iRxn, const XML_Node& rxnNode, Kinetics& kin,
|
|||
}
|
||||
for (size_t nn = 0; nn < rdata.products.size(); nn++) {
|
||||
rdata.net_stoich[int(rdata.products[nn])+1] += rdata.pstoich[nn];
|
||||
participants += 1000000 * static_cast<unsigned long int>(rdata.products[nn]);
|
||||
participants += static_cast<unsigned long int>(rdata.products[nn]);
|
||||
}
|
||||
|
||||
vector<size_t>& related = m_participants[participants];
|
||||
for (size_t mm = 0; mm < related.size(); mm++) {
|
||||
ReactionData& other = *m_rdata[related[mm]];
|
||||
if (rdata.reactants.size() != other.reactants.size()) {
|
||||
continue; // different numbers of reactants
|
||||
} else if (rdata.reactionType != other.reactionType) {
|
||||
if (rdata.reactionType != other.reactionType) {
|
||||
continue; // different reaction types
|
||||
} else if (rdata.duplicate && other.duplicate) {
|
||||
continue; // marked duplicates
|
||||
|
|
|
|||
59
test/data/duplicate-reactions.cti
Normal file
59
test/data/duplicate-reactions.cti
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
units(length='cm', time='s', quantity='mol', act_energy='cal/mol')
|
||||
|
||||
def make_gas(name, reactions):
|
||||
ideal_gas(name=name,
|
||||
elements=" O H Ar ",
|
||||
species="""h2o2: H2 H O O2 OH H2O HO2 H2O2 AR """,
|
||||
reactions=reactions,
|
||||
transport="None")
|
||||
|
||||
make_gas('A', 'A-*')
|
||||
make_gas('B', 'B-*')
|
||||
make_gas('C', 'C-*')
|
||||
make_gas('D', 'D-*')
|
||||
make_gas('E', 'E-*')
|
||||
make_gas('F', 'F-*')
|
||||
make_gas('G', 'G-*')
|
||||
make_gas('H', 'H-*')
|
||||
make_gas('I', 'I-*')
|
||||
|
||||
kf = [1e10, 0, 100]
|
||||
|
||||
# Forward multiple (not allowed)
|
||||
reaction('O + H2 <=> H + OH', kf, id='A-1')
|
||||
reaction('2 O + 2 H2 <=> 2 H + 2 OH', kf, id='A-2')
|
||||
|
||||
# Opposite direction #1 (not allowed)
|
||||
reaction('O + H2 <=> H + OH', kf, id='B-1')
|
||||
reaction('H + OH <=> O + H2', kf, id='B-2')
|
||||
|
||||
# Opposite direction #2 (not allowed)
|
||||
reaction('H + O2 + AR <=> HO2 + AR', kf, id='C-1')
|
||||
reaction('HO2 + AR <=> H + O2 + AR', kf, id='C-2')
|
||||
|
||||
# Opposite direction #3 (not allowed)
|
||||
reaction('H + O2 + AR <=> HO2 + AR', kf, id='D-1')
|
||||
reaction('HO2 + AR => H + O2 + AR', kf, id='D-2')
|
||||
|
||||
# Opposite direction #4 (allowed)
|
||||
reaction('H + O2 + AR => HO2 + AR', kf, id='E-1')
|
||||
reaction('HO2 + AR => H + O2 + AR', kf, id='E-2')
|
||||
|
||||
# Common efficiencies (not allowed)
|
||||
falloff_reaction('2 OH (+ M) <=> H2O2 (+ M)', kf=kf, kf0=kf,
|
||||
efficiencies='H2:2.0 H2O:6.0', id='F-1')
|
||||
falloff_reaction('2 OH (+ M) <=> H2O2 (+ M)', kf=kf, kf0=kf,
|
||||
efficiencies='AR:0.7 H2:2.0', id='F-2')
|
||||
|
||||
# Disjoint efficiencies (allowed)
|
||||
falloff_reaction('2 OH (+ H2O) <=> H2O2 (+ H2O)', kf=kf, kf0=kf, id='G-1')
|
||||
falloff_reaction('2 OH (+ M) <=> H2O2 (+ M)', kf=kf, kf0=kf,
|
||||
efficiencies='AR:0.7 H2:2.0 H2O:0.0', id='G-2')
|
||||
|
||||
# Different reaction type (allowed)
|
||||
reaction('O + H2 <=> H + OH', kf, id='H-1')
|
||||
three_body_reaction('O + H2 + M <=> H + OH + M', kf, id='H-2')
|
||||
|
||||
# Declared duplicate (allowed)
|
||||
reaction('O + H2 <=> H + OH', kf, options='duplicate', id='I-1')
|
||||
reaction('H + OH <=> O + H2', kf, options='duplicate', id='I-2')
|
||||
Loading…
Add table
Reference in a new issue