[Input] Improve detection of invalid lines in reaction entries
Previously, lines which did not contain a reaction equation or a known keyword and did not contain any slashes would be silently skipped. This caused reactions mistakenly written using '->' as the arrow to be ignored without warning. Fixes #583
This commit is contained in:
parent
b633544477
commit
d56b6205fa
3 changed files with 41 additions and 1 deletions
|
|
@ -1317,22 +1317,28 @@ class Parser(object):
|
||||||
# Note that the subsequent lines could be in any order
|
# Note that the subsequent lines could be in any order
|
||||||
for line in lines[1:]:
|
for line in lines[1:]:
|
||||||
tokens = line.split('/')
|
tokens = line.split('/')
|
||||||
|
parsed = False
|
||||||
|
|
||||||
if 'stick' in line.lower():
|
if 'stick' in line.lower():
|
||||||
|
parsed = True
|
||||||
arrhenius.is_sticking = True
|
arrhenius.is_sticking = True
|
||||||
|
|
||||||
if 'mwon' in line.lower():
|
if 'mwon' in line.lower():
|
||||||
|
parsed = True
|
||||||
arrhenius.motz_wise = True
|
arrhenius.motz_wise = True
|
||||||
|
|
||||||
if 'mwoff' in line.lower():
|
if 'mwoff' in line.lower():
|
||||||
|
parsed = True
|
||||||
arrhenius.motz_wise = False
|
arrhenius.motz_wise = False
|
||||||
|
|
||||||
if 'dup' in line.lower():
|
if 'dup' in line.lower():
|
||||||
# Duplicate reaction
|
# Duplicate reaction
|
||||||
|
parsed = True
|
||||||
reaction.duplicate = True
|
reaction.duplicate = True
|
||||||
|
|
||||||
if 'low' in line.lower():
|
if 'low' in line.lower():
|
||||||
# Low-pressure-limit Arrhenius parameters for "falloff" reaction
|
# Low-pressure-limit Arrhenius parameters for "falloff" reaction
|
||||||
|
parsed = True
|
||||||
tokens = tokens[1].split()
|
tokens = tokens[1].split()
|
||||||
arrheniusLow = Arrhenius(
|
arrheniusLow = Arrhenius(
|
||||||
A=(float(tokens[0].strip()), klow_units),
|
A=(float(tokens[0].strip()), klow_units),
|
||||||
|
|
@ -1345,6 +1351,7 @@ class Parser(object):
|
||||||
elif 'high' in line.lower():
|
elif 'high' in line.lower():
|
||||||
# High-pressure-limit Arrhenius parameters for "chemically
|
# High-pressure-limit Arrhenius parameters for "chemically
|
||||||
# activated" reaction
|
# activated" reaction
|
||||||
|
parsed = True
|
||||||
tokens = tokens[1].split()
|
tokens = tokens[1].split()
|
||||||
arrheniusHigh = Arrhenius(
|
arrheniusHigh = Arrhenius(
|
||||||
A=(float(tokens[0].strip()), kunits),
|
A=(float(tokens[0].strip()), kunits),
|
||||||
|
|
@ -1357,6 +1364,7 @@ class Parser(object):
|
||||||
arrhenius.A = (arrhenius.A[0], klow_units)
|
arrhenius.A = (arrhenius.A[0], klow_units)
|
||||||
|
|
||||||
elif 'rev' in line.lower():
|
elif 'rev' in line.lower():
|
||||||
|
parsed = True
|
||||||
reaction.reversible = False
|
reaction.reversible = False
|
||||||
|
|
||||||
tokens = tokens[1].split()
|
tokens = tokens[1].split()
|
||||||
|
|
@ -1382,11 +1390,13 @@ class Parser(object):
|
||||||
parser=self)
|
parser=self)
|
||||||
|
|
||||||
elif 'ford' in line.lower():
|
elif 'ford' in line.lower():
|
||||||
|
parsed = True
|
||||||
tokens = tokens[1].split()
|
tokens = tokens[1].split()
|
||||||
reaction.fwdOrders[tokens[0].strip()] = tokens[1].strip()
|
reaction.fwdOrders[tokens[0].strip()] = tokens[1].strip()
|
||||||
|
|
||||||
elif 'troe' in line.lower():
|
elif 'troe' in line.lower():
|
||||||
# Troe falloff parameters
|
# Troe falloff parameters
|
||||||
|
parsed = True
|
||||||
tokens = tokens[1].split()
|
tokens = tokens[1].split()
|
||||||
alpha = float(tokens[0].strip())
|
alpha = float(tokens[0].strip())
|
||||||
T3 = float(tokens[1].strip())
|
T3 = float(tokens[1].strip())
|
||||||
|
|
@ -1401,6 +1411,7 @@ class Parser(object):
|
||||||
)
|
)
|
||||||
elif 'sri' in line.lower():
|
elif 'sri' in line.lower():
|
||||||
# SRI falloff parameters
|
# SRI falloff parameters
|
||||||
|
parsed = True
|
||||||
tokens = tokens[1].split()
|
tokens = tokens[1].split()
|
||||||
A = float(tokens[0].strip())
|
A = float(tokens[0].strip())
|
||||||
B = float(tokens[1].strip())
|
B = float(tokens[1].strip())
|
||||||
|
|
@ -1418,12 +1429,14 @@ class Parser(object):
|
||||||
falloff = Sri(A=A, B=B, C=C, D=D, E=E)
|
falloff = Sri(A=A, B=B, C=C, D=D, E=E)
|
||||||
|
|
||||||
elif 'cov' in line.lower():
|
elif 'cov' in line.lower():
|
||||||
|
parsed = True
|
||||||
C = tokens[1].split()
|
C = tokens[1].split()
|
||||||
arrhenius.coverages.append(
|
arrhenius.coverages.append(
|
||||||
[C[0], fortFloat(C[1]), fortFloat(C[2]), fortFloat(C[3])])
|
[C[0], fortFloat(C[1]), fortFloat(C[2]), fortFloat(C[3])])
|
||||||
|
|
||||||
elif 'cheb' in line.lower():
|
elif 'cheb' in line.lower():
|
||||||
# Chebyshev parameters
|
# Chebyshev parameters
|
||||||
|
parsed = True
|
||||||
if chebyshev is None:
|
if chebyshev is None:
|
||||||
chebyshev = Chebyshev()
|
chebyshev = Chebyshev()
|
||||||
tokens = [t.strip() for t in tokens]
|
tokens = [t.strip() for t in tokens]
|
||||||
|
|
@ -1451,6 +1464,7 @@ class Parser(object):
|
||||||
|
|
||||||
elif 'plog' in line.lower():
|
elif 'plog' in line.lower():
|
||||||
# Pressure-dependent Arrhenius parameters
|
# Pressure-dependent Arrhenius parameters
|
||||||
|
parsed = True
|
||||||
if pdepArrhenius is None:
|
if pdepArrhenius is None:
|
||||||
pdepArrhenius = []
|
pdepArrhenius = []
|
||||||
tokens = tokens[1].split()
|
tokens = tokens[1].split()
|
||||||
|
|
@ -1461,11 +1475,16 @@ class Parser(object):
|
||||||
T0=(1,"K"),
|
T0=(1,"K"),
|
||||||
parser=self
|
parser=self
|
||||||
)])
|
)])
|
||||||
else:
|
elif len(tokens) >= 2:
|
||||||
# Assume a list of collider efficiencies
|
# Assume a list of collider efficiencies
|
||||||
|
parsed = True
|
||||||
for collider, efficiency in zip(tokens[0::2], tokens[1::2]):
|
for collider, efficiency in zip(tokens[0::2], tokens[1::2]):
|
||||||
efficiencies[collider.strip()] = float(efficiency.strip())
|
efficiencies[collider.strip()] = float(efficiency.strip())
|
||||||
|
|
||||||
|
if not parsed:
|
||||||
|
raise InputParseError('Unparsable line:\n"""\n{0}\n"""'.format(line))
|
||||||
|
|
||||||
|
|
||||||
# Decide which kinetics to keep and store them on the reaction object
|
# Decide which kinetics to keep and store them on the reaction object
|
||||||
# Only one of these should be true at a time!
|
# Only one of these should be true at a time!
|
||||||
if chebyshev is not None:
|
if chebyshev is not None:
|
||||||
|
|
|
||||||
|
|
@ -286,6 +286,12 @@ class chemkinConverterTest(utilities.CanteraTest):
|
||||||
thermoFile=pjoin(self.test_data_dir, 'dummy-thermo.dat'),
|
thermoFile=pjoin(self.test_data_dir, 'dummy-thermo.dat'),
|
||||||
outName=pjoin(self.test_work_dir, 'bad-troe.cti'), quiet=True)
|
outName=pjoin(self.test_work_dir, 'bad-troe.cti'), quiet=True)
|
||||||
|
|
||||||
|
def test_invalid_reaction_equation(self):
|
||||||
|
with self.assertRaisesRegex(ck2cti.InputParseError, 'Unparsable'):
|
||||||
|
convertMech(pjoin(self.test_data_dir, 'invalid-equation.inp'),
|
||||||
|
thermoFile=pjoin(self.test_data_dir, 'dummy-thermo.dat'),
|
||||||
|
outName=pjoin(self.test_work_dir, 'invalid-equation.cti'), quiet=True)
|
||||||
|
|
||||||
def test_reaction_units(self):
|
def test_reaction_units(self):
|
||||||
convertMech(pjoin(self.test_data_dir, 'units-default.inp'),
|
convertMech(pjoin(self.test_data_dir, 'units-default.inp'),
|
||||||
thermoFile=pjoin(self.test_data_dir, 'dummy-thermo.dat'),
|
thermoFile=pjoin(self.test_data_dir, 'dummy-thermo.dat'),
|
||||||
|
|
|
||||||
15
test/data/invalid-equation.inp
Normal file
15
test/data/invalid-equation.inp
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
ELEMENTS
|
||||||
|
H C
|
||||||
|
END
|
||||||
|
|
||||||
|
SPECIES
|
||||||
|
H R1A R1B P1 P2A
|
||||||
|
END
|
||||||
|
|
||||||
|
REACTIONS
|
||||||
|
R1A+R1B(+M) <=> H+P1(+M) 1e12 0.0 20000.0
|
||||||
|
LOW / 1.040E+26 -2.760 1600.00/
|
||||||
|
TROE/ .5620 91.00 5836.00 1.00000e+100/
|
||||||
|
R1A <-> R1B 1e12 0.0 20000.0
|
||||||
|
R1A => P2A 1e12 0.0 20000.0
|
||||||
|
END
|
||||||
Loading…
Add table
Reference in a new issue