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 Dec 2, 2019
1 parent aab230b commit 44d7554
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 24 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 read_thermo_entry(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 @@ -103,6 +103,21 @@ def read_thermo_entry(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
71 changes: 48 additions & 23 deletions rmgpy/chemkinTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,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 @@ -451,20 +451,43 @@ def setUp(self):
comment=comment,
)

def test_write_thermo_block(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 C 2H 6 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
"""

self.entry2 = """CH3NO2X G 300.000 3000.000 650.73 1&
C 1 H 3 N 1 O 2 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
"""

expected = """C2H6 C 2H 6 G 300.000 3000.000 650.73 1
self.entry3 = """CH3NO2SX G 300.000 3000.000 650.73 1&
C 1 H 3 N 1 O 2 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 test_write_thermo_block(self):
"""Test that we can write a normal thermo block"""
species = Species(smiles='CC')
species.thermo = self.nasa

result = write_thermo_entry(species, verbose=False)

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

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

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

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

expected = """CH3NO2X G 300.000 3000.000 650.73 1&
C 1 H 3 N 1 O 2 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 = write_thermo_entry(species, verbose=False)

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

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

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

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

expected = """CH3NO2SX G 300.000 3000.000 650.73 1&
C 1 H 3 N 1 O 2 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 = write_thermo_entry(species, verbose=False)

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

def test_read_thermo_block_6_elem(self):
"""Test that we can read a thermo block with 6 elements"""
species, thermo, formula = read_thermo_entry(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.is_identical_to(thermo))


class TestReadReactionComments(unittest.TestCase):
Expand Down

0 comments on commit 44d7554

Please sign in to comment.