[ck2cti] Fix support for species names containing '+' and '='
This addesses a parsing error that would occur if a mechanism contained both 'foo' and 'foo+', where reactions written as 'foo+bar' would be parsed as a reaction with 'foo+' and 'bar'. See Issue 182.
This commit is contained in:
parent
d9af4af88f
commit
c34877a96f
3 changed files with 42 additions and 22 deletions
|
|
@ -1001,16 +1001,18 @@ class Parser(object):
|
|||
return species, thermo, composition, note
|
||||
|
||||
def setupKinetics(self):
|
||||
self.valid_tokens = dict((k,'species') for k in self.speciesDict)
|
||||
self.valid_tokens.update(('(+%s)' % k, 'falloff3b: %s' % k) for k in self.speciesDict)
|
||||
self.valid_tokens['M'] = 'third-body'
|
||||
self.valid_tokens['m'] = 'third-body'
|
||||
self.valid_tokens['(+M)'] = 'falloff3b'
|
||||
self.valid_tokens['(+m)'] = 'falloff3b'
|
||||
self.valid_tokens['<=>'] = 'equal'
|
||||
self.valid_tokens['=>'] = 'equal'
|
||||
self.valid_tokens['='] = 'equal'
|
||||
self.Slen = max(map(len, self.valid_tokens))
|
||||
# We look for species including the next permissible character. '\n' is
|
||||
# appended to the reaction string to identify the last species in the
|
||||
# reaction string. Checking this character is necessary to correctly
|
||||
# identify species with names ending in '+' or '='.
|
||||
self.species_tokens = set()
|
||||
for next_char in ('<','=','(','+','\n'):
|
||||
self.species_tokens.update(k + next_char for k in self.speciesDict)
|
||||
self.other_tokens = {'M': 'third-body', 'm': 'third-body',
|
||||
'(+M)': 'falloff3b', '(+m)': 'falloff3b',
|
||||
'<=>': 'equal', '=>': 'equal', '=': 'equal'}
|
||||
self.other_tokens.update(('(+%s)' % k, 'falloff3b: %s' % k) for k in self.speciesDict)
|
||||
self.Slen = max(map(len, self.other_tokens))
|
||||
|
||||
def readKineticsEntry(self, entry):
|
||||
"""
|
||||
|
|
@ -1048,17 +1050,26 @@ class Parser(object):
|
|||
A = float(tokens[-3])
|
||||
b = float(tokens[-2])
|
||||
Ea = float(tokens[-1])
|
||||
reaction = ''.join(tokens[:-3])
|
||||
reaction = ''.join(tokens[:-3]) + '\n'
|
||||
|
||||
# Identify tokens comprising the reaction expression. Look for the
|
||||
# longest possible sub-sequences first.
|
||||
# Identify species tokens in the reaction expression in order of
|
||||
# decreasing length
|
||||
locs = {}
|
||||
for i in range(self.Slen, 0, -1):
|
||||
for j in range(len(reaction)-i+1):
|
||||
test = reaction[j:j+i]
|
||||
if test in self.valid_tokens:
|
||||
if test in self.species_tokens:
|
||||
reaction = reaction[:j] + ' '*(i-1) + reaction[j+i-1:]
|
||||
locs[j] = test[:-1], 'species'
|
||||
|
||||
# Identify other tokens in the reaction expression in order of
|
||||
# descending length
|
||||
for i in range(self.Slen, 0, -1):
|
||||
for j in range(len(reaction)-i+1):
|
||||
test = reaction[j:j+i]
|
||||
if test in self.other_tokens:
|
||||
reaction = reaction[:j] + ' '*i + reaction[j+i:]
|
||||
locs[j] = test, self.valid_tokens[test]
|
||||
locs[j] = test, self.other_tokens[test]
|
||||
|
||||
# Anything that's left should be a stoichiometric coefficient or a '+'
|
||||
# between species
|
||||
|
|
|
|||
|
|
@ -131,19 +131,22 @@ class chemkinConverterTest(utilities.CanteraTest):
|
|||
outName='species-names.cti', quiet=True)
|
||||
gas = ct.Solution('species-names.cti')
|
||||
|
||||
self.assertEqual(gas.n_species, 5)
|
||||
self.assertEqual(gas.n_species, 6)
|
||||
self.assertEqual(gas.species_name(0), '(Parens)')
|
||||
self.assertEqual(gas.species_name(1), '@#$%^-2')
|
||||
self.assertEqual(gas.species_name(2), '[xy2]*{.}')
|
||||
self.assertEqual(gas.species_name(3), 'plus+')
|
||||
self.assertEqual(gas.species_name(4), 'eq=uals')
|
||||
self.assertEqual(gas.species_name(5), 'plus')
|
||||
|
||||
self.assertEqual(gas.n_reactions, 4)
|
||||
self.assertEqual(gas.n_reactions, 6)
|
||||
nu = gas.product_stoich_coeffs() - gas.reactant_stoich_coeffs()
|
||||
self.assertEqual(list(nu[:,0]), [-1, -1, 2, 0, 0])
|
||||
self.assertEqual(list(nu[:,1]), [-2, 3, -1, 0, 0])
|
||||
self.assertEqual(list(nu[:,2]), [-1, 0, 0, 1, 0])
|
||||
self.assertEqual(list(nu[:,3]), [3, 0, 0, -2, -1])
|
||||
self.assertEqual(list(nu[:,0]), [-1, -1, 2, 0, 0, 0])
|
||||
self.assertEqual(list(nu[:,1]), [-2, 3, -1, 0, 0, 0])
|
||||
self.assertEqual(list(nu[:,2]), [-1, 0, 0, 1, 0, 0])
|
||||
self.assertEqual(list(nu[:,3]), [3, 0, 0, -2, -1, 0])
|
||||
self.assertEqual(list(nu[:,4]), [2, 0, 0, -1, 0, -1])
|
||||
self.assertEqual(list(nu[:,5]), [1, 0, 0, 1, -1, -1])
|
||||
|
||||
def test_unterminatedSections(self):
|
||||
self.assertRaises(ck2cti.InputParseError,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ Elements
|
|||
H C
|
||||
End
|
||||
SPEC
|
||||
(Parens) @#$%^-2 [xy2]*{.} plus+ eq=uals
|
||||
(Parens) @#$%^-2 [xy2]*{.} plus+ eq=uals plus
|
||||
end
|
||||
|
||||
thermo
|
||||
|
|
@ -23,6 +23,10 @@ plus+ C 1H 4 G 200.000 3500.000 1000.000 1
|
|||
7.48514950E-02 1.33909467E-02-5.73285809E-06 1.22292535E-09-1.01815230E-13 2
|
||||
-9.46834459E+03 1.84373180E+01 5.14987613E+00-1.36709788E-02 4.91800599E-05 3
|
||||
-4.84743026E-08 1.66693956E-11-1.02466476E+04-4.64130376E+00 4
|
||||
plus C 1H 4 G 200.000 3500.000 1000.000 1
|
||||
7.48514950E-02 1.33909467E-02-5.73285809E-06 1.22292535E-09-1.01815230E-13 2
|
||||
-9.46834459E+03 1.84373180E+01 5.14987613E+00-1.36709788E-02 4.91800599E-05 3
|
||||
-4.84743026E-08 1.66693956E-11-1.02466476E+04-4.64130376E+00 4
|
||||
eq=uals C 1H 4 G 200.000 3500.000 1000.000 1
|
||||
7.48514950E-02 1.33909467E-02-5.73285809E-06 1.22292535E-09-1.01815230E-13 2
|
||||
-9.46834459E+03 1.84373180E+01 5.14987613E+00-1.36709788E-02 4.91800599E-05 3
|
||||
|
|
@ -34,5 +38,7 @@ end
|
|||
2(Parens) + [xy2]*{.} = 3@#$%^-2 5.4321e10 1.0 500.0
|
||||
plus+ + (Parens) = 2plus+ 9.999e9 9.9 999.9
|
||||
2 plus+ + eq=uals = 3(Parens) 9.999e9 9.9 999.9
|
||||
plus + plus+ = 2 (Parens) 9.999e9 9.9 999.9
|
||||
plus+ eq=uals = plus++(Parens) 9.999e9 9.9 999.9
|
||||
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue