From e4362d37e7cf2d527a14c6202868b5ffd76f2436 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Mon, 27 Aug 2018 21:22:52 -0400 Subject: [PATCH] [Kinetics] Check for non-existent species in reaction orders When the nonreactant_orders option was enabled, specifying reactant orders for species which were not present in the phase previously resulted in out-of-bounds memory access. --- interfaces/cython/cantera/test/test_convert.py | 1 + src/kinetics/Kinetics.cpp | 11 +++++++++++ test/data/reaction-orders.cti | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/interfaces/cython/cantera/test/test_convert.py b/interfaces/cython/cantera/test/test_convert.py index e994a7fb3..2ddca7cb4 100644 --- a/interfaces/cython/cantera/test/test_convert.py +++ b/interfaces/cython/cantera/test/test_convert.py @@ -500,6 +500,7 @@ class CtmlConverterTest(utilities.CanteraTest): def test_reaction_orders(self): gas = ct.Solution('reaction-orders.cti') + self.assertEqual(gas.n_reactions, 1) R = gas.reaction(0) self.assertTrue(R.allow_nonreactant_orders) self.assertNear(R.orders.get('OH'), 0.15) diff --git a/src/kinetics/Kinetics.cpp b/src/kinetics/Kinetics.cpp index 88643f29e..0675277f6 100644 --- a/src/kinetics/Kinetics.cpp +++ b/src/kinetics/Kinetics.cpp @@ -498,6 +498,17 @@ bool Kinetics::addReaction(shared_ptr r) } } } + for (const auto& sp : r->orders) { + if (kineticsSpeciesIndex(sp.first) == npos) { + if (m_skipUndeclaredSpecies) { + return false; + } else { + throw CanteraError("Kinetics::addReaction", "Reaction '{}' has " + "a reaction order specified for the undeclared species '{}'", + r->equation(), sp.first); + } + } + } checkReactionBalance(*r); size_t irxn = nReactions(); // index of the new reaction diff --git a/test/data/reaction-orders.cti b/test/data/reaction-orders.cti index 58a3831f7..4fbfa2842 100644 --- a/test/data/reaction-orders.cti +++ b/test/data/reaction-orders.cti @@ -6,6 +6,7 @@ ideal_gas(name = "gas", elements = " O H ", species = """gri30: H2 O2 H2O OH """, reactions = "all", + options=['skip_undeclared_species'], initial_state = state(temperature = 300.0, pressure = OneAtm) ) @@ -13,6 +14,11 @@ ideal_gas(name = "gas", # Reactions data #------------------------------------------------------------------------------- +# This reaction should be skipped due to the non-existent species 'HO2' +reaction("H2 + O2 => 2 OH", [1e13, 0.0, 0.0], + order="HO2:-0.25", + options=['negative_orders', 'nonreactant_orders']) + #test negative orders and non-reactant orders reaction("2 H2 + O2 => 2 H2O", [1e13, 0.0, 0.0], order="H2:-0.25 OH:0.15",