From 79e762889e7f987dfbe8ae1309b7916ee04fe88b Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Sat, 16 Oct 2021 14:12:10 -0400 Subject: [PATCH 1/7] [Kinetics] Fail fast when adding reactions with optimizations disabled The behavior of collecting errors related to trying to add all reactions before reporting them can make it hard to diagnose some problems. Since disabling optimizations is usually an early step in the debugging process, this will make such problems apparent at that time. --- src/kinetics/KineticsFactory.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/kinetics/KineticsFactory.cpp b/src/kinetics/KineticsFactory.cpp index af192158c3..b45d27c474 100644 --- a/src/kinetics/KineticsFactory.cpp +++ b/src/kinetics/KineticsFactory.cpp @@ -183,11 +183,15 @@ void addReactions(Kinetics& kin, const AnyMap& phaseNode, const AnyMap& rootNode } else { // specified section is in the current file for (const auto& R : rootNode.at(sections[i]).asVector()) { - try { + #ifdef NDEBUG + try { + kin.addReaction(newReaction(R, kin), false); + } catch (CanteraError& err) { + format_to(add_rxn_err, "{}", err.what()); + } + #else kin.addReaction(newReaction(R, kin), false); - } catch (CanteraError& err) { - format_to(add_rxn_err, "{}", err.what()); - } + #endif } } } From cca11fe8e2c61b08b03b4cb863483c3d88f1518f Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Sat, 16 Oct 2021 19:42:45 -0400 Subject: [PATCH 2/7] [Python/Transport] Fix handling of exceptions from CKMode --- interfaces/cython/cantera/_cantera.pxd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces/cython/cantera/_cantera.pxd b/interfaces/cython/cantera/_cantera.pxd index 753d3dc632..d4ea6e6e7e 100644 --- a/interfaces/cython/cantera/_cantera.pxd +++ b/interfaces/cython/cantera/_cantera.pxd @@ -614,7 +614,7 @@ cdef extern from "cantera/transport/TransportBase.h" namespace "Cantera": cdef cppclass CxxTransport "Cantera::Transport": CxxTransport(CxxThermoPhase*) string transportType() - cbool CKMode() + cbool CKMode() except +translate_exception double viscosity() except +translate_exception double thermalConductivity() except +translate_exception double electricalConductivity() except +translate_exception From eb7a7dba635f4051b8e9c6f7b12ae0aa628ea23e Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Sat, 16 Oct 2021 19:55:04 -0400 Subject: [PATCH 3/7] [Test] Use valid conditions for checking liquid water properties ctml2yamlTest.test_water_IAPWS95_thermo was trying to calculate transport properties in a region where the underlying model (which assumes liquid water) wasn't valid, resulting in NaNs. --- interfaces/cython/cantera/test/test_convert.py | 1 + 1 file changed, 1 insertion(+) diff --git a/interfaces/cython/cantera/test/test_convert.py b/interfaces/cython/cantera/test/test_convert.py index 61fd2a25fd..1c6b854273 100644 --- a/interfaces/cython/cantera/test/test_convert.py +++ b/interfaces/cython/cantera/test/test_convert.py @@ -1150,6 +1150,7 @@ def test_water_IAPWS95_thermo(self): ctmlWater, yamlWater = self.checkConversion("liquid-water") self.checkThermo(ctmlWater, yamlWater, [300, 500, 1300, 2000], pressure=22064000.0) self.assertEqual(ctmlWater.transport_model, yamlWater.transport_model) + ctmlWater.TP = yamlWater.TP = 300, 22064000.0 dens = ctmlWater.density for T in [298, 1001, 2400]: ctmlWater.TD = T, dens From 0d82d90558d5328371b74dbc2cc3f414750e5210 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Sat, 16 Oct 2021 21:41:22 -0400 Subject: [PATCH 4/7] [Test] Add workaround for Plog rate setting test Using chained getter/setter notation to set the rate of a Plog reaction doesn't work because the 'rate' getter always returns a copy of the PlogRate object, and modifying this object doesn't update the parent Reaction object. --- interfaces/cython/cantera/test/test_kinetics.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/interfaces/cython/cantera/test/test_kinetics.py b/interfaces/cython/cantera/test/test_kinetics.py index 4328a80e3a..0c55a3aec9 100644 --- a/interfaces/cython/cantera/test/test_kinetics.py +++ b/interfaces/cython/cantera/test/test_kinetics.py @@ -1121,12 +1121,15 @@ def test_plog(self): r = ct.PlogReaction() r.reactants = {'R1A':1, 'R1B':1} r.products = {'P1':1, 'H':1} - r.rate.rates = [ + # @todo: Fix so chained setter works, i.e. r.rate.rates = ... + rate = r.rate + rate.rates = [ (0.01*ct.one_atm, ct.Arrhenius(1.2124e13, -0.5779, 10872.7*4184)), (1.0*ct.one_atm, ct.Arrhenius(4.9108e28, -4.8507, 24772.8*4184)), (10.0*ct.one_atm, ct.Arrhenius(1.2866e44, -9.0246, 39796.5*4184)), (100.0*ct.one_atm, ct.Arrhenius(5.9632e53, -11.529, 52599.6*4184)) ] + r.rate = rate gas2 = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=species, reactions=[r]) From 14213c12f174666a78913fca4f9101f8c6370e1f Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Sat, 16 Oct 2021 21:44:06 -0400 Subject: [PATCH 5/7] [Kinetics] Fix setting parameters of standalone Arrhenius rates --- src/kinetics/RxnRates.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/kinetics/RxnRates.cpp b/src/kinetics/RxnRates.cpp index 863bbca7c6..4f91f0534f 100644 --- a/src/kinetics/RxnRates.cpp +++ b/src/kinetics/RxnRates.cpp @@ -43,14 +43,19 @@ void Arrhenius::setParameters(const AnyValue& rate, m_E = NAN; } else if (rate.is()) { auto& rate_map = rate.as(); - if (rate_units.factor() == 0 && rate_map["A"].is()) { + if (rate_units.factor() == 0) { // A zero rate units factor is used as a sentinel to detect // stand-alone reaction rate objects - throw InputFileError("Arrhenius::setParameters", rate_map, - "Specification of units is not supported for pre-exponential factor " - "when\ncreating a standalone 'ReactionRate' object."); + if (rate_map["A"].is()) { + throw InputFileError("Arrhenius::setParameters", rate_map, + "Specification of units is not supported for pre-exponential " + "factor when\ncreating a standalone 'ReactionRate' object."); + } else { + m_A = rate_map["A"].asDouble(); + } + } else { + m_A = units.convert(rate_map["A"], rate_units); } - m_A = units.convert(rate_map["A"], rate_units); m_b = rate_map["b"].asDouble(); m_E = units.convertActivationEnergy(rate_map["Ea"], "K"); } else { From c23fe0b3ef5a1ee73e2326e399b291293d715f92 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Sat, 16 Oct 2021 21:57:03 -0400 Subject: [PATCH 6/7] [Test] Check that unassigned reaction rates return NaN --- interfaces/cython/cantera/test/test_reaction.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/interfaces/cython/cantera/test/test_reaction.py b/interfaces/cython/cantera/test/test_reaction.py index 1f13e1d6cb..adc02a4de2 100644 --- a/interfaces/cython/cantera/test/test_reaction.py +++ b/interfaces/cython/cantera/test/test_reaction.py @@ -477,17 +477,17 @@ def test_no_rate(self): return rxn = self._cls(equation=self._equation, kinetics=self.gas, legacy=self._legacy, **self._kwargs) - if self._legacy: - self.assertNear(rxn.rate(self.gas.T), 0.) - else: - self.assertTrue(np.isnan(rxn.rate(self.gas.T, self.gas.P))) - gas2 = ct.Solution(thermo="IdealGas", kinetics="GasKinetics", species=self.species, reactions=[rxn]) gas2.TPX = self.gas.TPX - self.assertNear(gas2.forward_rate_constants[0], 0.) - self.assertNear(gas2.net_rates_of_progress[0], 0.) + if self._legacy: + self.assertNear(rxn.rate(self.gas.T), 0.) + self.assertNear(gas2.forward_rate_constants[0], 0.) + self.assertNear(gas2.net_rates_of_progress[0], 0.) + else: + self.assertTrue(np.isnan(rxn.rate(self.gas.T, self.gas.P))) + self.assertTrue(np.isnan(gas2.forward_rate_constants[0])) def test_replace_rate(self): # check replacing reaction rate expression From 421bb7ad89112957f1389337a8779218e6ad84b4 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Wed, 6 Oct 2021 14:57:41 -0400 Subject: [PATCH 7/7] [Test] Fix assertNear to handle inf and nan correctly --- interfaces/cython/cantera/test/utilities.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interfaces/cython/cantera/test/utilities.py b/interfaces/cython/cantera/test/utilities.py index 727391132b..c9b7f396ce 100644 --- a/interfaces/cython/cantera/test/utilities.py +++ b/interfaces/cython/cantera/test/utilities.py @@ -70,7 +70,7 @@ def tearDownClass(cls): def assertNear(self, a, b, rtol=1e-8, atol=1e-12, msg=None): cmp = 2 * abs(a - b)/(abs(a) + abs(b) + 2 * atol / rtol) - if cmp > rtol: + if not cmp < rtol: message = ('AssertNear: %.14g - %.14g = %.14g\n' % (a, b, a-b) + 'Relative error of %10e exceeds rtol = %10e' % (cmp, rtol)) if msg: @@ -88,12 +88,12 @@ def assertArrayNear(self, A, B, rtol=1e-8, atol=1e-12, msg=None): a = A[i] b = B[i] cmp = 2 * abs(a - b)/(abs(a) + abs(b) + 2 * atol / rtol) - if cmp > rtol: + if not cmp < rtol: message = ('AssertNear: {:.14g} - {:.14g} = {:.14g}\n'.format(a, b, a-b) + 'Relative error for element {} of {:10e} exceeds rtol = {:10e}'.format(i, cmp, rtol)) if msg: message = msg + '\n' + message - if cmp > worst[0]: + if not cmp < worst[0]: worst = cmp, message if worst[0]: