Skip to content

Commit

Permalink
Add parsing for extended element counts in Chemkin thermo entries
Browse files Browse the repository at this point in the history
Add unit tests for various element count syntaxes
Fix incorrect index for element count in columns 74-78
    (should start at column 73 using zero-indexing)
  • Loading branch information
mliu49 committed Jun 19, 2019
1 parent e9b1fbf commit 7f9aafd
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 23 deletions.
17 changes: 16 additions & 1 deletion rmgpy/chemkin.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def readThermoEntry(entry, Tmin=0, Tint=0, Tmax=0):

comment = lines[0][len(species):24].strip()
formula = {}
for i in [24, 29, 34, 39, 74]:
for i in [24, 29, 34, 39, 73]:
element,count = lines[0][i:i+2].strip(), lines[0][i+2:i+5].strip()
if element:
try:
Expand All @@ -99,6 +99,21 @@ def readThermoEntry(entry, Tmin=0, Tint=0, Tmax=0):
raise
if count != 0: # Some people put garbage elements in, with zero count. Ignore these. Allow negative counts though (eg. negative one electron)
formula[element] = count

# Parsing for extended elemental composition syntax, adapted from Cantera ck2cti.py
if lines[0].rstrip().endswith('&'):
complines = []
for i in range(len(lines)-1):
if lines[i].rstrip().endswith('&'):
complines.append(lines[i+1])
else:
break
lines = [lines[0]] + lines[i+1:]
elements = ' '.join(line.rstrip('&\n') for line in complines).split()
formula = {}
for i in range(0, len(elements), 2):
formula[elements[i].capitalize()] = int(elements[i+1])

phase = lines[0][44]
if phase.upper() != 'G':
logging.warning("Was expecting gas phase thermo data for {0}. Skipping thermo data.".format(species))
Expand Down
69 changes: 47 additions & 22 deletions rmgpy/chemkinTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ def test_mark_duplicate_reactions(self):
self.assertEqual(duplicate_flags, expected_flags)


class TestThermoWrite(unittest.TestCase):
class TestThermoReadWrite(unittest.TestCase):

def setUp(self):
"""This method is run once before each test."""
Expand All @@ -449,20 +449,42 @@ def setUp(self):
comment=comment,
)

def testWriteThermoBlock(self):
"""Test that we can write a normal thermo block"""
species = Species(SMILES='CC')
species.thermo = self.nasa
# Chemkin entries for testing - note that the values are all the same
self.entry1 = """C2H6 H 6C 2 G 300.000 3000.000 650.73 1
-3.07954000E-01 2.45269000E-02-1.24130000E-05 3.07724000E-09-3.01467000E-13 2
-1.06930000E+04 2.26280000E+01 4.03055000E+00-2.14171000E-03 4.90611000E-05 3
-5.99027000E-08 2.38945000E-11-1.12576000E+04 3.56130000E+00 4
"""

expected = """C2H6 H 6C 2 G 300.000 3000.000 650.73 1
self.entry2 = """CH3NO2X X 1H 3C 1O 2G 300.000 3000.000 650.73N 1 1
-3.07954000E-01 2.45269000E-02-1.24130000E-05 3.07724000E-09-3.01467000E-13 2
-1.06930000E+04 2.26280000E+01 4.03055000E+00-2.14171000E-03 4.90611000E-05 3
-5.99027000E-08 2.38945000E-11-1.12576000E+04 3.56130000E+00 4
"""

self.entry3 = """CH3NO2SX G 300.000 3000.000 650.73 1&
C 1 H 3 O 2 N 1 S 1 X 1
-3.07954000E-01 2.45269000E-02-1.24130000E-05 3.07724000E-09-3.01467000E-13 2
-1.06930000E+04 2.26280000E+01 4.03055000E+00-2.14171000E-03 4.90611000E-05 3
-5.99027000E-08 2.38945000E-11-1.12576000E+04 3.56130000E+00 4
"""

def testWriteThermoBlock(self):
"""Test that we can write a normal thermo block"""
species = Species(SMILES='CC')
species.thermo = self.nasa

result = writeThermoEntry(species, verbose=False)

self.assertEqual(expected, result)
self.assertEqual(result, self.entry1)

def testReadThermoBlock(self):
"""Test that we can read a normal thermo block"""
species, thermo, formula = readThermoEntry(self.entry1)

self.assertEqual(species, 'C2H6')
self.assertEqual(formula, {'H': 6, 'C': 2})
self.assertTrue(self.nasa.isIdenticalTo(thermo))

def testWriteThermoBlock5Elem(self):
"""Test that we can write a thermo block for a species with 5 elements"""
Expand All @@ -478,15 +500,17 @@ def testWriteThermoBlock5Elem(self):
""")
species.thermo = self.nasa

expected = """CH3NO2X X 1H 3C 1O 2G 300.000 3000.000 650.73N 1 1
-3.07954000E-01 2.45269000E-02-1.24130000E-05 3.07724000E-09-3.01467000E-13 2
-1.06930000E+04 2.26280000E+01 4.03055000E+00-2.14171000E-03 4.90611000E-05 3
-5.99027000E-08 2.38945000E-11-1.12576000E+04 3.56130000E+00 4
"""

result = writeThermoEntry(species, verbose=False)

self.assertEqual(expected, result)
self.assertEqual(result, self.entry2)

def testReadThermoBlock5Elem(self):
"""Test that we can read a thermo block with 5 elements"""
species, thermo, formula = readThermoEntry(self.entry2)

self.assertEqual(species, 'CH3NO2X')
self.assertEqual(formula, {'X': 1, 'C': 1, 'O': 2, 'H': 3, 'N': 1})
self.assertTrue(self.nasa.isIdenticalTo(thermo))

def testWriteThermoBlock6Elem(self):
"""Test that we can write a thermo block for a species with 6 elements"""
Expand All @@ -503,16 +527,17 @@ def testWriteThermoBlock6Elem(self):
""")
species.thermo = self.nasa

expected = """CH3NO2SX G 300.000 3000.000 650.73 1&
C 1 H 3 O 2 N 1 S 1 X 1
-3.07954000E-01 2.45269000E-02-1.24130000E-05 3.07724000E-09-3.01467000E-13 2
-1.06930000E+04 2.26280000E+01 4.03055000E+00-2.14171000E-03 4.90611000E-05 3
-5.99027000E-08 2.38945000E-11-1.12576000E+04 3.56130000E+00 4
"""

result = writeThermoEntry(species, verbose=False)

self.assertEqual(expected, result)
self.assertEqual(result, self.entry3)

def testReadThermoBlock6Elem(self):
"""Test that we can read a thermo block with 6 elements"""
species, thermo, formula = readThermoEntry(self.entry3)

self.assertEqual(species, 'CH3NO2SX')
self.assertEqual(formula, {'X': 1, 'C': 1, 'O': 2, 'H': 3, 'N': 1, 'S': 1})
self.assertTrue(self.nasa.isIdenticalTo(thermo))


class TestReadReactionComments(unittest.TestCase):
Expand Down

0 comments on commit 7f9aafd

Please sign in to comment.