[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:
Ray Speth 2014-01-24 20:40:26 +00:00
parent d9af4af88f
commit c34877a96f
3 changed files with 42 additions and 22 deletions

View file

@ -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

View file

@ -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,

View file

@ -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