Пример #1
0
def funcSubmitGet():
    """
    Test if we can retrieve thermo of species after submitting some of them.
    """
    load()

    spcs = [
            Species().fromSMILES('C'),\
            Species().fromSMILES('CC'), \
            Species().fromSMILES('CCC')
            ]

    for spc in spcs:
        submit(spc)

    absent = Species().fromSMILES('[CH3]')
    data = absent.getThermoData()
    if not data: return False

    present = Species().fromSMILES('CC')
    data = present.getThermoData()
    if not data: return False

    random.shuffle(spcs)
    for spc in spcs:
        data = spc.getThermoData()
        if not data: return False

    return True
Пример #2
0
def funcSubmitGet():
    """
    Test if we can retrieve thermo of species after submitting some of them.
    """
    load()

    spcs = [
            Species().fromSMILES('C'),\
            Species().fromSMILES('CC'), \
            Species().fromSMILES('CCC')
            ]
    
    for spc in spcs:
        submit(spc)

    absent = Species().fromSMILES('[CH3]')
    data = absent.getThermoData()
    if not data: return False

    present = Species().fromSMILES('CC')
    data = present.getThermoData()
    if not data: return False

    random.shuffle(spcs)
    for spc in spcs:
        data = spc.getThermoData()
        if not data: return False        

    return True
Пример #3
0
    def testToWilhoit(self):
        """
        Test if the entropy computed from other thermo implementations is close to what Wilhoit computes.
        """

        from rmgpy import settings
        from rmgpy.data.rmg import RMGDatabase, database
        from rmgpy.species import Species

        # Load databases
        database = RMGDatabase()
        database.loadThermo(os.path.join(settings['database.directory'],
                                         'thermo'),
                            thermoLibraries=['Narayanaswamy'])
        database.loadSolvation(
            os.path.join(settings['database.directory'], 'solvation'))

        spc = Species().fromSMILES('CC')
        spc.getThermoData()

        T = 1350.  # not 298K!

        # nasa to wilhoit
        nasa = spc.thermo
        Snasa = nasa.getEntropy(T)

        nasaToWh = nasa.toWilhoit()
        SnasaToWh = nasaToWh.getEntropy(T)

        self.assertAlmostEqual(Snasa, SnasaToWh, -1)
        self.assertEqual(nasa.comment, nasaToWh.comment)

        # wilhoit to nasa conversion done in nasaTest.py

        # thermo data to wilhoit:
        td = nasa.toThermoData()
        Std = td.getEntropy(T)

        wilhoit = td.toWilhoit(B=1000.)
        Swh = wilhoit.getEntropy(T)

        self.assertAlmostEqual(Std, Swh, -1)
        self.assertEqual(td.comment, wilhoit.comment)

        # wilhoit back to thermodata
        td = wilhoit.toThermoData()
        Std = td.getEntropy(T)

        self.assertAlmostEqual(Std, Swh, -1)
        self.assertEqual(td.comment, wilhoit.comment)
    def testToWilhoit(self):
        """
        Test if the entropy computed from other thermo implementations is close to what Wilhoit computes.
        """

        from rmgpy import settings
        from rmgpy.data.rmg import RMGDatabase, database
        from rmgpy.species import Species

        # Load databases
        database = RMGDatabase()
        database.loadThermo(os.path.join(settings['database.directory'], 'thermo'), thermoLibraries=['Narayanaswamy'])
        database.loadSolvation(os.path.join(settings['database.directory'], 'solvation'))

        spc = Species().fromSMILES('CC')
        spc.getThermoData()

        T = 1350.# not 298K!

        # nasa to wilhoit
        nasa = spc.thermo
        Snasa = nasa.getEntropy(T)

        nasaToWh = nasa.toWilhoit()
        SnasaToWh = nasaToWh.getEntropy(T)

        self.assertAlmostEqual(Snasa, SnasaToWh, -1)
        self.assertEqual(nasa.comment,nasaToWh.comment)

        # wilhoit to nasa conversion done in nasaTest.py

        # thermo data to wilhoit:
        td = nasa.toThermoData()
        Std = td.getEntropy(T)

        wilhoit = td.toWilhoit(B=1000.)        
        Swh = wilhoit.getEntropy(T)

        self.assertAlmostEqual(Std, Swh, -1)
        self.assertEqual(td.comment,wilhoit.comment)

        # wilhoit back to thermodata
        td = wilhoit.toThermoData()
        Std = td.getEntropy(T)

        self.assertAlmostEqual(Std, Swh, -1)
        self.assertEqual(td.comment,wilhoit.comment)
Пример #5
0
    def testToNASA(self):
        """
        Test if the entropy computed from other thermo implementations is close to what NASA computes.
        """

        from rmgpy import settings
        from rmgpy.data.rmg import RMGDatabase, database
        from rmgpy.species import Species

        # Load databases
        database = RMGDatabase()
        database.loadThermo(os.path.join(settings['database.directory'],
                                         'thermo'),
                            thermoLibraries=['Narayanaswamy'])
        database.loadSolvation(
            os.path.join(settings['database.directory'], 'solvation'))

        spc = Species().fromSMILES('CC')
        spc.getThermoData()

        T = 1350.  # not 298K!

        # nasa to thermodata
        nasa = spc.thermo
        Snasa = nasa.getEntropy(T)

        td = nasa.toThermoData()
        Std = td.getEntropy(T)

        self.assertAlmostEqual(Snasa, Std, -1)
        self.assertEqual(td.comment, nasa.comment)

        # thermodata to nasa
        nasa = td.toNASA(Tmin=100.0, Tmax=5000.0, Tint=1000.0)
        Snasa = nasa.getEntropy(T)

        self.assertAlmostEqual(Snasa, Std, -1)
        self.assertEqual(td.comment, nasa.comment)

        # wilhoit to nasa
        wilhoit = nasa.toWilhoit()
        nasa = wilhoit.toNASA(Tmin=100.0, Tmax=5000.0, Tint=1000.0)
        Snasa = nasa.getEntropy(T)

        self.assertAlmostEqual(Snasa, Std, -1)
        self.assertEqual(wilhoit.comment, nasa.comment)
Пример #6
0
    def testToNASA(self):
        """
        Test if the entropy computed from other thermo implementations is close to what NASA computes.
        """

        from rmgpy import settings
        from rmgpy.data.rmg import RMGDatabase, database
        from rmgpy.species import Species

        # Load databases
        database = RMGDatabase()
        database.loadThermo(os.path.join(settings['database.directory'], 'thermo'),thermoLibraries=['Narayanaswamy'])
        database.loadSolvation(os.path.join(settings['database.directory'], 'solvation'))

        spc = Species().fromSMILES('CC')
        spc.getThermoData()

        T = 1350.# not 298K!

        # nasa to thermodata
        nasa = spc.thermo
        Snasa = nasa.getEntropy(T)

        td = nasa.toThermoData()
        Std = td.getEntropy(T)

        self.assertAlmostEqual(Snasa, Std, -1)
        self.assertEqual(td.comment,nasa.comment)


        # thermodata to nasa
        nasa = td.toNASA(Tmin=100.0, Tmax=5000.0, Tint=1000.0)
        Snasa = nasa.getEntropy(T)

        self.assertAlmostEqual(Snasa, Std, -1)
        self.assertEqual(td.comment,nasa.comment)

        # wilhoit to nasa
        wilhoit=nasa.toWilhoit()
        nasa = wilhoit.toNASA(Tmin=100.0, Tmax=5000.0, Tint=1000.0)
        Snasa = nasa.getEntropy(T)

        self.assertAlmostEqual(Snasa, Std, -1)
        self.assertEqual(wilhoit.comment,nasa.comment)

        # nasa to wilhoi performed in wilhoitTest
Пример #7
0
class TestSpecies(unittest.TestCase):
    """
    Contains unit tests for the Species class.
    """
    def setUp(self):
        """
        A method that is run before each unit test in this class.
        """
        self.species = Species(
            index=1,
            label='C2H4',
            thermo=ThermoData(
                Tdata=([300.0, 400.0, 500.0, 600.0, 800.0, 1000.0,
                        1500.0], 'K'),
                Cpdata=([3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 15.0], 'cal/(mol*K)'),
                H298=(-20.0, 'kcal/mol'),
                S298=(50.0, 'cal/(mol*K)'),
                Tmin=(300.0, 'K'),
                Tmax=(2000.0, 'K'),
            ),
            conformer=Conformer(
                E0=(0.0, 'kJ/mol'),
                modes=[
                    IdealGasTranslation(mass=(28.03, 'amu')),
                    NonlinearRotor(
                        inertia=([5.6952e-47, 2.7758e-46,
                                  3.3454e-46], 'kg*m^2'),
                        symmetry=1),
                    HarmonicOscillator(frequencies=([
                        834.50, 973.31, 975.37, 1067.1, 1238.5, 1379.5, 1472.3,
                        1691.3, 3121.6, 3136.7, 3192.5, 3221.0
                    ], 'cm^-1')),
                ],
                spinMultiplicity=1,
                opticalIsomers=1,
            ),
            molecule=[Molecule().fromSMILES('C=C')],
            transportData=TransportData(sigma=(1, 'angstrom'),
                                        epsilon=(100, 'K')),
            molecularWeight=(28.03, 'amu'),
            reactive=True,
        )

    def testPickle(self):
        """
        Test that a Species object can be pickled and unpickled.
        
        ...with no loss of information.
        """
        import cPickle
        species = cPickle.loads(cPickle.dumps(self.species, -1))
        self.assertEqual(self.species.index, species.index)
        self.assertEqual(self.species.label, species.label)
        self.assertEqual(self.species.molecule[0].multiplicity,
                         species.molecule[0].multiplicity)
        self.assertEqual(self.species.getThermoData().H298.value_si,
                         species.getThermoData().H298.value_si)
        self.assertEqual(self.species.getThermoData().H298.units,
                         species.getThermoData().H298.units)
        self.assertEqual(len(self.species.conformer.modes),
                         len(species.conformer.modes))
        self.assertEqual(len(self.species.molecule), len(species.molecule))
        self.assertTrue(self.species.molecule[0].isIsomorphic(
            species.molecule[0]))
        self.assertEqual(self.species.conformer.E0.value_si,
                         species.conformer.E0.value_si)
        self.assertEqual(self.species.conformer.E0.units,
                         species.conformer.E0.units)
        self.assertEqual(self.species.transportData.sigma.value_si,
                         species.transportData.sigma.value_si)
        self.assertEqual(self.species.transportData.sigma.units,
                         species.transportData.sigma.units)
        self.assertAlmostEqual(
            self.species.transportData.epsilon.value_si / 1.381e-23,
            species.transportData.epsilon.value_si / 1.381e-23, 4)
        self.assertEqual(self.species.transportData.epsilon.units,
                         species.transportData.epsilon.units)
        self.assertEqual(self.species.molecularWeight.value_si,
                         species.molecularWeight.value_si)
        self.assertEqual(self.species.molecularWeight.units,
                         species.molecularWeight.units)
        self.assertEqual(self.species.reactive, species.reactive)

    def testOutput(self):
        """
        Test that a Species object can be reconstructed from its repr().
        
        ...with no loss of information.
        """
        species = None
        exec('species = {0!r}'.format(self.species))
        self.assertEqual(self.species.index, species.index)
        self.assertEqual(self.species.label, species.label)
        self.assertEqual(self.species.molecule[0].multiplicity,
                         species.molecule[0].multiplicity)
        self.assertEqual(self.species.getThermoData().H298.value_si,
                         species.getThermoData().H298.value_si)
        self.assertEqual(self.species.getThermoData().H298.units,
                         species.getThermoData().H298.units)
        self.assertEqual(len(self.species.conformer.modes),
                         len(species.conformer.modes))
        self.assertEqual(len(self.species.molecule), len(species.molecule))
        self.assertTrue(self.species.molecule[0].isIsomorphic(
            species.molecule[0]))
        self.assertEqual(self.species.conformer.E0.value_si,
                         species.conformer.E0.value_si)
        self.assertEqual(self.species.conformer.E0.units,
                         species.conformer.E0.units)
        self.assertEqual(self.species.transportData.sigma.value_si,
                         species.transportData.sigma.value_si)
        self.assertEqual(self.species.transportData.sigma.units,
                         species.transportData.sigma.units)
        self.assertAlmostEqual(self.species.transportData.epsilon.value_si,
                               species.transportData.epsilon.value_si, 3)
        self.assertEqual(self.species.transportData.epsilon.units,
                         species.transportData.epsilon.units)
        self.assertEqual(self.species.molecularWeight.value_si,
                         species.molecularWeight.value_si)
        self.assertEqual(self.species.molecularWeight.units,
                         species.molecularWeight.units)
        self.assertEqual(self.species.reactive, species.reactive)

    def testToAdjacencyList(self):
        """
        Test that toAdjacencyList() works as expected.
        """
        string = self.species.toAdjacencyList()
        self.assertTrue(
            string.startswith(self.species.molecule[0].toAdjacencyList(
                label=self.species.label, removeH=False)), string)

    def testSpeciesProps(self):
        """
        Test a key-value pair is added to the props attribute of Species.
        """
        self.species.props['foo'] = 'bar'
        self.assertIsInstance(self.species.props, dict)
        self.assertEquals(self.species.props['foo'], 'bar')

    def testSpeciesProps_object_attribute(self):
        """
        Test that Species's props dictionaries are independent of each other.
        
        Create a test in which is checked whether props is an object attribute rather
        than a class attribute
        """
        spc2 = Species()
        self.species.props['foo'] = 'bar'
        spc3 = Species()
        spc3.props['foo'] = 'bla'
        self.assertEquals(self.species.props['foo'], 'bar')
        self.assertDictEqual(spc2.props, {})
        self.assertDictEqual(spc3.props, {'foo': 'bla'})

    def testResonanceIsomersGenerated(self):
        "Test that 1-penten-3-yl makes 2-penten-1-yl resonance isomer"
        spec = Species().fromSMILES('C=C[CH]CC')
        spec.generateResonanceIsomers()
        self.assertEquals(len(spec.molecule), 2)
        self.assertEquals(spec.molecule[1].toSMILES(), "[CH2]C=CCC")

    def testResonaceIsomersRepresented(self):
        "Test that both resonance forms of 1-penten-3-yl are printed by __repr__"
        spec = Species().fromSMILES('C=C[CH]CC')
        spec.generateResonanceIsomers()
        exec('spec2 = {0!r}'.format(spec))
        self.assertEqual(len(spec.molecule), len(spec2.molecule))
        for i, j in zip(spec.molecule, spec2.molecule):
            self.assertTrue(i.isIsomorphic(j))

    def testCopy(self):
        """Test that we can make a copy of a Species object."""

        spc_cp = self.species.copy()

        self.assertTrue(id(self.species) != id(spc_cp))
        self.assertTrue(self.species.isIsomorphic(spc_cp))
        self.assertEquals(self.species.label, spc_cp.label)
        self.assertEquals(self.species.index, spc_cp.index)

        self.assertTrue(
            self.species.molecularWeight.equals(spc_cp.molecularWeight))
        self.assertEquals(self.species.reactive, spc_cp.reactive)

    def testCantera(self):
        """
        Test that a Cantera Species object is created correctly.
        """
        from rmgpy.thermo import NASA, NASAPolynomial
        import cantera as ct
        rmgSpecies = Species(
            label="Ar",
            thermo=NASA(polynomials=[
                NASAPolynomial(coeffs=[2.5, 0, 0, 0, 0, -745.375, 4.37967],
                               Tmin=(200, 'K'),
                               Tmax=(1000, 'K')),
                NASAPolynomial(coeffs=[2.5, 0, 0, 0, 0, -745.375, 4.37967],
                               Tmin=(1000, 'K'),
                               Tmax=(6000, 'K'))
            ],
                        Tmin=(200, 'K'),
                        Tmax=(6000, 'K'),
                        comment="""
Thermo library: primaryThermoLibrary
"""),
            molecule=[Molecule(SMILES="[Ar]")],
            transportData=TransportData(shapeIndex=0,
                                        epsilon=(1134.93, 'J/mol'),
                                        sigma=(3.33, 'angstrom'),
                                        dipoleMoment=(2, 'De'),
                                        polarizability=(1, 'angstrom^3'),
                                        rotrelaxcollnum=15.0,
                                        comment="""GRI-Mech"""))

        rmg_ctSpecies = rmgSpecies.toCantera()

        ctSpecies = ct.Species.fromCti("""species(name=u'Ar',
        atoms='Ar:1',
        thermo=(NASA([200.00, 1000.00],
                     [ 2.50000000E+00,  0.00000000E+00,  0.00000000E+00,
                       0.00000000E+00,  0.00000000E+00, -7.45375000E+02,
                       4.37967000E+00]),
                NASA([1000.00, 6000.00],
                     [ 2.50000000E+00,  0.00000000E+00,  0.00000000E+00,
                       0.00000000E+00,  0.00000000E+00, -7.45375000E+02,
                       4.37967000E+00])),
        transport=gas_transport(geom='atom',
                                diam=3.33,
                                well_depth=136.501,
                                dipole=2.0,
                                polar=1.0,
                                rot_relax=15.0))""")
        self.assertEqual(type(rmg_ctSpecies), type(ctSpecies))
        self.assertEqual(rmg_ctSpecies.name, ctSpecies.name)
        self.assertEqual(rmg_ctSpecies.composition, ctSpecies.composition)
        self.assertEqual(rmg_ctSpecies.size, ctSpecies.size)
        self.assertEqual(type(rmg_ctSpecies.thermo), type(ctSpecies.thermo))
        self.assertEqual(type(rmg_ctSpecies.transport),
                         type(ctSpecies.transport))

    def testGetTransportData(self):
        """
        Test that transport data can be retrieved correctly via the getTransportData method.
        """

        spc = Species(label="Ar",
                      molecule=[Molecule(SMILES="[Ar]")],
                      transportData=TransportData(
                          shapeIndex=0,
                          epsilon=(1134.93, 'J/mol'),
                          sigma=(3.33, 'angstrom'),
                          dipoleMoment=(2, 'De'),
                          polarizability=(1, 'angstrom^3'),
                          rotrelaxcollnum=15.0,
                          comment="""GRI-Mech"""))

        self.assertTrue(spc.getTransportData() is spc.transportData)
Пример #8
0
class TestSpecies(unittest.TestCase):
    """
    Contains unit tests for the Species class.
    """
    def setUp(self):
        """
        A method that is run before each unit test in this class.
        """
        self.species = Species(
            index=1,
            label='C2H4',
            thermo=ThermoData(
                Tdata=([300.0, 400.0, 500.0, 600.0, 800.0, 1000.0,
                        1500.0], 'K'),
                Cpdata=([3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 15.0], 'cal/(mol*K)'),
                H298=(-20.0, 'kcal/mol'),
                S298=(50.0, 'cal/(mol*K)'),
                Tmin=(300.0, 'K'),
                Tmax=(2000.0, 'K'),
            ),
            conformer=Conformer(
                E0=(0.0, 'kJ/mol'),
                modes=[
                    IdealGasTranslation(mass=(28.03, 'amu')),
                    NonlinearRotor(
                        inertia=([5.6952e-47, 2.7758e-46,
                                  3.3454e-46], 'kg*m^2'),
                        symmetry=1),
                    HarmonicOscillator(frequencies=([
                        834.50, 973.31, 975.37, 1067.1, 1238.5, 1379.5, 1472.3,
                        1691.3, 3121.6, 3136.7, 3192.5, 3221.0
                    ], 'cm^-1')),
                ],
                spinMultiplicity=1,
                opticalIsomers=1,
            ),
            molecule=[Molecule().fromSMILES('C=C')],
            transportData=TransportData(sigma=(1, 'angstrom'),
                                        epsilon=(100, 'K')),
            molecularWeight=(28.03, 'amu'),
            reactive=True,
        )

    def testPickle(self):
        """
        Test that a Species object can be pickled and unpickled.
        
        ...with no loss of information.
        """
        import cPickle
        species = cPickle.loads(cPickle.dumps(self.species, -1))
        self.assertEqual(self.species.index, species.index)
        self.assertEqual(self.species.label, species.label)
        self.assertEqual(self.species.molecule[0].multiplicity,
                         species.molecule[0].multiplicity)
        self.assertEqual(self.species.getThermoData().H298.value_si,
                         species.getThermoData().H298.value_si)
        self.assertEqual(self.species.getThermoData().H298.units,
                         species.getThermoData().H298.units)
        self.assertEqual(len(self.species.conformer.modes),
                         len(species.conformer.modes))
        self.assertEqual(len(self.species.molecule), len(species.molecule))
        self.assertTrue(self.species.molecule[0].isIsomorphic(
            species.molecule[0]))
        self.assertEqual(self.species.conformer.E0.value_si,
                         species.conformer.E0.value_si)
        self.assertEqual(self.species.conformer.E0.units,
                         species.conformer.E0.units)
        self.assertEqual(self.species.transportData.sigma.value_si,
                         species.transportData.sigma.value_si)
        self.assertEqual(self.species.transportData.sigma.units,
                         species.transportData.sigma.units)
        self.assertAlmostEqual(
            self.species.transportData.epsilon.value_si / 1.381e-23,
            species.transportData.epsilon.value_si / 1.381e-23, 4)
        self.assertEqual(self.species.transportData.epsilon.units,
                         species.transportData.epsilon.units)
        self.assertEqual(self.species.molecularWeight.value_si,
                         species.molecularWeight.value_si)
        self.assertEqual(self.species.molecularWeight.units,
                         species.molecularWeight.units)
        self.assertEqual(self.species.reactive, species.reactive)

    def testOutput(self):
        """
        Test that a Species object can be reconstructed from its repr().
        
        ...with no loss of information.
        """
        species = None
        exec('species = {0!r}'.format(self.species))
        self.assertEqual(self.species.index, species.index)
        self.assertEqual(self.species.label, species.label)
        self.assertEqual(self.species.molecule[0].multiplicity,
                         species.molecule[0].multiplicity)
        self.assertEqual(self.species.getThermoData().H298.value_si,
                         species.getThermoData().H298.value_si)
        self.assertEqual(self.species.getThermoData().H298.units,
                         species.getThermoData().H298.units)
        self.assertEqual(len(self.species.conformer.modes),
                         len(species.conformer.modes))
        self.assertEqual(len(self.species.molecule), len(species.molecule))
        self.assertTrue(self.species.molecule[0].isIsomorphic(
            species.molecule[0]))
        self.assertEqual(self.species.conformer.E0.value_si,
                         species.conformer.E0.value_si)
        self.assertEqual(self.species.conformer.E0.units,
                         species.conformer.E0.units)
        self.assertEqual(self.species.transportData.sigma.value_si,
                         species.transportData.sigma.value_si)
        self.assertEqual(self.species.transportData.sigma.units,
                         species.transportData.sigma.units)
        self.assertAlmostEqual(self.species.transportData.epsilon.value_si,
                               species.transportData.epsilon.value_si, 3)
        self.assertEqual(self.species.transportData.epsilon.units,
                         species.transportData.epsilon.units)
        self.assertEqual(self.species.molecularWeight.value_si,
                         species.molecularWeight.value_si)
        self.assertEqual(self.species.molecularWeight.units,
                         species.molecularWeight.units)
        self.assertEqual(self.species.reactive, species.reactive)

    def testToAdjacencyList(self):
        """
        Test that toAdjacencyList() works as expected.
        """
        string = self.species.toAdjacencyList()
        self.assertTrue(
            string.startswith(self.species.molecule[0].toAdjacencyList(
                label=self.species.label, removeH=False)), string)

    def testSpeciesProps(self):
        """
        Test a key-value pair is added to the props attribute of Species.
        """
        self.species.props['foo'] = 'bar'
        self.assertIsInstance(self.species.props, dict)
        self.assertEquals(self.species.props['foo'], 'bar')

    def testSpeciesProps_object_attribute(self):
        """
        Test that Species's props dictionaries are independent of each other.
        
        Create a test in which is checked whether props is an object attribute rather
        than a class attribute
        """
        spc2 = Species()
        self.species.props['foo'] = 'bar'
        spc3 = Species()
        spc3.props['foo'] = 'bla'
        self.assertEquals(self.species.props['foo'], 'bar')
        self.assertDictEqual(spc2.props, {})
        self.assertDictEqual(spc3.props, {'foo': 'bla'})

    def testResonanceIsomersGenerated(self):
        "Test that 1-penten-3-yl makes 2-penten-1-yl resonance isomer"
        spec = Species().fromSMILES('C=C[CH]CC')
        spec.generate_resonance_structures()
        self.assertEquals(len(spec.molecule), 2)
        self.assertEquals(spec.molecule[1].toSMILES(), "[CH2]C=CCC")

    def testResonaceIsomersRepresented(self):
        "Test that both resonance forms of 1-penten-3-yl are printed by __repr__"
        spec = Species().fromSMILES('C=C[CH]CC')
        spec.generate_resonance_structures()
        exec('spec2 = {0!r}'.format(spec))
        self.assertEqual(len(spec.molecule), len(spec2.molecule))
        for i, j in zip(spec.molecule, spec2.molecule):
            self.assertTrue(
                j.isIsomorphic(i),
                msg='i is not isomorphic with j, where i is {} and j is {}'.
                format(i.toSMILES(), j.toSMILES()))

    def test_is_isomorphic_to_filtered_resonance_structure(self):
        """
        Test that a Species containing a non-representative resonance structure is isomorphic
        with the "correct" Species containing only representative structures (which were not filtered out)

        When generating resonance isomers for N/O/S atoms, a large number of resonance structures per species could
        potentially be generated, yet most are filtered out and only the "correct" / "representative" structures
        are kept. This test makes sure that if a non-representative structure (i.e., a structure that was filtered out)
        is generated, RMG finds the Species it belongs to, if the last exists.
        """

        spc1_correct = Species().fromSMILES(
            '[O]N=O')  # check charge separation with higher octet deviation
        spc1_nonrepresentative = Species().fromAdjacencyList("""multiplicity 2
                                                                1 N u1 p1 c0 {2,S} {3,S}
                                                                2 O u0 p3 c-1 {1,S}
                                                                3 O u0 p2 c+1 {1,S}"""
                                                             )
        spc2_correct = Species().fromSMILES(
            '[N]=NON=O')  # check atoms with val 6
        spc2_nonrepresentative = Species().fromAdjacencyList("""multiplicity 2
                                                                1 O u0 p2 c0 {2,S} {3,S}
                                                                2 N u1 p1 c0 {1,S} {4,S}
                                                                3 N u0 p2 c-1 {1,S} {5,S}
                                                                4 N u0 p2 c0 {2,S}
                                                                5 O u0 p2 c+1 {3,S}"""
                                                             )
        spc3_correct = Species().fromSMILES('[O]S(O)=O')  # check O4tc penalty
        spc3_nonrepresentative = Species().fromAdjacencyList("""multiplicity 2
                                                                1 S u0 p1 c-1 {2,S} {3,S} {4,T}
                                                                2 O u0 p2 c0 {1,S} {5,S}
                                                                3 O u1 p2 c0 {1,S}
                                                                4 O u0 p1 c+1 {1,T}
                                                                5 H u0 p0 c0 {2,S}"""
                                                             )
        spc4_correct = Species().fromSMILES(
            'OS(=[N+]=[N-])O')  # check O4dc penalty
        spc4_nonrepresentative = Species().fromAdjacencyList(
            """1 S u0 p0 c+1 {2,D} {3,D} {4,S}
                                                                2 N u0 p1 c0 {1,D} {5,S}
                                                                3 O u0 p1 c+1 {1,D} {6,S}
                                                                4 O u0 p2 c0 {1,S} {7,S}
                                                                5 N u0 p3 c-2 {2,S}
                                                                6 H u0 p0 c0 {3,S}
                                                                7 H u0 p0 c0 {4,S}"""
        )
        spc5_correct = Species().fromSMILES('[O][S]')  # checks birad penalty
        spc5_nonrepresentative = Species().fromAdjacencyList("""multiplicity 3
                                                                1 O u0 p2 c0 {2,D}
                                                                2 S u2 p1 c0 {1,D}"""
                                                             )
        spc6_correct = Species().fromSMILES(
            '[N-]=[N+]=S=S=O')  # checks the S#S case
        spc6_nonrepresentative = Species().fromAdjacencyList(
            """1 S u0 p1 c0 {2,S} {3,T}
                                                                2 N u0 p0 c+1 {1,S} {4,T}
                                                                3 S u0 p1 c0 {1,T} {5,S}
                                                                4 N u0 p1 c0 {2,T}
                                                                5 O u0 p3 c-1 {3,S}"""
        )

        # check that the structures are not isomorphic if resonance structures are not generated:
        self.assertFalse(
            spc1_correct.isIsomorphic(spc1_nonrepresentative,
                                      generate_res=False))

        # check that the nonrepresentative structure is isomorphic by generating resonance structures:
        self.assertTrue(
            spc1_correct.isIsomorphic(spc1_nonrepresentative,
                                      generate_res=True))
        self.assertTrue(
            spc2_correct.isIsomorphic(spc2_nonrepresentative,
                                      generate_res=True))
        self.assertTrue(
            spc3_correct.isIsomorphic(spc3_nonrepresentative,
                                      generate_res=True))
        self.assertTrue(
            spc4_correct.isIsomorphic(spc4_nonrepresentative,
                                      generate_res=True))
        self.assertTrue(
            spc5_correct.isIsomorphic(spc5_nonrepresentative,
                                      generate_res=True))
        self.assertTrue(
            spc6_correct.isIsomorphic(spc6_nonrepresentative,
                                      generate_res=True))

    def testGetResonanceHybrid(self):
        """
        Tests that getResonanceHybrid returns an isomorphic structure
        which has intermediate bond orders.
        
        This check is for C=C[CH]CC which has another resonance structure,
        [CH2]C=CC. When these structures are merged, the bond structure should be,
        C~C~CC, where '~' is a hybrid bond of order 1.5. 
        """
        spec = Species().fromSMILES('C=C[CH]CC')
        hybridMol = spec.getResonanceHybrid()

        self.assertTrue(hybridMol.toSingleBonds().isIsomorphic(
            spec.molecule[0].toSingleBonds()))

        # a rough check for intermediate bond orders
        expected_orders = [1, 1.5]
        bonds = []
        # ensure all bond orders are expected
        for atom in hybridMol.atoms:
            for atom2 in atom.bonds:
                bond = hybridMol.getBond(atom, atom2)
                self.assertTrue(
                    any([
                        bond.isOrder(otherOrder)
                        for otherOrder in expected_orders
                    ]), 'Unexpected bond order {}'.format(bond.getOrderNum()))
                bonds.append(bond)

        # ensure all expected orders are present
        for expected_order in expected_orders:
            self.assertTrue(
                any([bond.isOrder(expected_order) for bond in bonds]),
                'No bond of order {} found'.format(expected_order))

    def testCopy(self):
        """Test that we can make a copy of a Species object."""

        spc_cp = self.species.copy()

        self.assertTrue(id(self.species) != id(spc_cp))
        self.assertTrue(self.species.isIsomorphic(spc_cp))
        self.assertEquals(self.species.label, spc_cp.label)
        self.assertEquals(self.species.index, spc_cp.index)

        self.assertTrue(
            self.species.molecularWeight.equals(spc_cp.molecularWeight))
        self.assertEquals(self.species.reactive, spc_cp.reactive)

    def testCantera(self):
        """
        Test that a Cantera Species object is created correctly.
        """
        from rmgpy.thermo import NASA, NASAPolynomial
        import cantera as ct
        rmgSpecies = Species(
            label="Ar",
            thermo=NASA(polynomials=[
                NASAPolynomial(coeffs=[2.5, 0, 0, 0, 0, -745.375, 4.37967],
                               Tmin=(200, 'K'),
                               Tmax=(1000, 'K')),
                NASAPolynomial(coeffs=[2.5, 0, 0, 0, 0, -745.375, 4.37967],
                               Tmin=(1000, 'K'),
                               Tmax=(6000, 'K'))
            ],
                        Tmin=(200, 'K'),
                        Tmax=(6000, 'K'),
                        comment="""
Thermo library: primaryThermoLibrary
"""),
            molecule=[Molecule(SMILES="[Ar]")],
            transportData=TransportData(shapeIndex=0,
                                        epsilon=(1134.93, 'J/mol'),
                                        sigma=(3.33, 'angstrom'),
                                        dipoleMoment=(2, 'De'),
                                        polarizability=(1, 'angstrom^3'),
                                        rotrelaxcollnum=15.0,
                                        comment="""GRI-Mech"""))

        rmg_ctSpecies = rmgSpecies.toCantera(useChemkinIdentifier=True)

        ctSpecies = ct.Species.fromCti("""species(name=u'Ar',
        atoms='Ar:1',
        thermo=(NASA([200.00, 1000.00],
                     [ 2.50000000E+00,  0.00000000E+00,  0.00000000E+00,
                       0.00000000E+00,  0.00000000E+00, -7.45375000E+02,
                       4.37967000E+00]),
                NASA([1000.00, 6000.00],
                     [ 2.50000000E+00,  0.00000000E+00,  0.00000000E+00,
                       0.00000000E+00,  0.00000000E+00, -7.45375000E+02,
                       4.37967000E+00])),
        transport=gas_transport(geom='atom',
                                diam=3.33,
                                well_depth=136.501,
                                dipole=2.0,
                                polar=1.0,
                                rot_relax=15.0))""")
        self.assertEqual(type(rmg_ctSpecies), type(ctSpecies))
        self.assertEqual(rmg_ctSpecies.name, ctSpecies.name)
        self.assertEqual(rmg_ctSpecies.composition, ctSpecies.composition)
        self.assertEqual(rmg_ctSpecies.size, ctSpecies.size)
        self.assertEqual(type(rmg_ctSpecies.thermo), type(ctSpecies.thermo))
        self.assertEqual(type(rmg_ctSpecies.transport),
                         type(ctSpecies.transport))

    def testGetTransportData(self):
        """
        Test that transport data can be retrieved correctly via the getTransportData method.
        """

        spc = Species(label="Ar",
                      molecule=[Molecule(SMILES="[Ar]")],
                      transportData=TransportData(
                          shapeIndex=0,
                          epsilon=(1134.93, 'J/mol'),
                          sigma=(3.33, 'angstrom'),
                          dipoleMoment=(2, 'De'),
                          polarizability=(1, 'angstrom^3'),
                          rotrelaxcollnum=15.0,
                          comment="""GRI-Mech"""))

        self.assertTrue(spc.getTransportData() is spc.transportData)
Пример #9
0
class TestSpecies(unittest.TestCase):
    """
    Contains unit tests for the Species class.
    """
    
    def setUp(self):
        """
        A method that is run before each unit test in this class.
        """
        self.species = Species(
            index=1,
            label='C2H4',
            thermo=ThermoData(
                Tdata=([300.0,400.0,500.0,600.0,800.0,1000.0,1500.0],'K'),
                Cpdata=([3.0,4.0,5.0,6.0,8.0,10.0,15.0],'cal/(mol*K)'),
                H298=(-20.0,'kcal/mol'),
                S298=(50.0,'cal/(mol*K)'),
                Tmin=(300.0,'K'),
                Tmax=(2000.0,'K'),
            ),
            conformer=Conformer(
                E0=(0.0,'kJ/mol'),
                modes=[
                    IdealGasTranslation(mass=(28.03,'amu')),
                    NonlinearRotor(inertia=([5.6952e-47, 2.7758e-46, 3.3454e-46],'kg*m^2'), symmetry=1),
                    HarmonicOscillator(frequencies=([834.50, 973.31, 975.37, 1067.1, 1238.5, 1379.5, 1472.3, 1691.3, 3121.6, 3136.7, 3192.5, 3221.0],'cm^-1')),
                ],
                spinMultiplicity=1,
                opticalIsomers=1,
            ),
            molecule=[Molecule().fromSMILES('C=C')],
            transportData=TransportData(sigma=(1, 'angstrom'), epsilon=(100, 'K')),
            molecularWeight=(28.03,'amu'),
            reactive=True,
        )
        
    def testPickle(self):
        """
        Test that a Species object can be pickled and unpickled.
        
        ...with no loss of information.
        """
        import cPickle
        species = cPickle.loads(cPickle.dumps(self.species,-1))
        self.assertEqual(self.species.index, species.index)
        self.assertEqual(self.species.label, species.label)
        self.assertEqual(self.species.molecule[0].multiplicity, species.molecule[0].multiplicity)
        self.assertEqual(self.species.getThermoData().H298.value_si, species.getThermoData().H298.value_si)
        self.assertEqual(self.species.getThermoData().H298.units, species.getThermoData().H298.units)
        self.assertEqual(len(self.species.conformer.modes), len(species.conformer.modes))
        self.assertEqual(len(self.species.molecule), len(species.molecule))
        self.assertTrue(self.species.molecule[0].isIsomorphic(species.molecule[0]))
        self.assertEqual(self.species.conformer.E0.value_si, species.conformer.E0.value_si)
        self.assertEqual(self.species.conformer.E0.units, species.conformer.E0.units)
        self.assertEqual(self.species.transportData.sigma.value_si, species.transportData.sigma.value_si)
        self.assertEqual(self.species.transportData.sigma.units, species.transportData.sigma.units)
        self.assertAlmostEqual(self.species.transportData.epsilon.value_si / 1.381e-23, species.transportData.epsilon.value_si / 1.381e-23, 4)
        self.assertEqual(self.species.transportData.epsilon.units, species.transportData.epsilon.units)
        self.assertEqual(self.species.molecularWeight.value_si, species.molecularWeight.value_si)
        self.assertEqual(self.species.molecularWeight.units, species.molecularWeight.units)
        self.assertEqual(self.species.reactive, species.reactive)

    def testOutput(self):
        """
        Test that a Species object can be reconstructed from its repr().
        
        ...with no loss of information.
        """
        species = None
        exec('species = {0!r}'.format(self.species))
        self.assertEqual(self.species.index, species.index)
        self.assertEqual(self.species.label, species.label)
        self.assertEqual(self.species.molecule[0].multiplicity, species.molecule[0].multiplicity)
        self.assertEqual(self.species.getThermoData().H298.value_si, species.getThermoData().H298.value_si)
        self.assertEqual(self.species.getThermoData().H298.units, species.getThermoData().H298.units)
        self.assertEqual(len(self.species.conformer.modes), len(species.conformer.modes))
        self.assertEqual(len(self.species.molecule), len(species.molecule))
        self.assertTrue(self.species.molecule[0].isIsomorphic(species.molecule[0]))
        self.assertEqual(self.species.conformer.E0.value_si, species.conformer.E0.value_si)
        self.assertEqual(self.species.conformer.E0.units, species.conformer.E0.units)
        self.assertEqual(self.species.transportData.sigma.value_si, species.transportData.sigma.value_si)
        self.assertEqual(self.species.transportData.sigma.units, species.transportData.sigma.units)
        self.assertAlmostEqual(self.species.transportData.epsilon.value_si, species.transportData.epsilon.value_si, 3)
        self.assertEqual(self.species.transportData.epsilon.units, species.transportData.epsilon.units)
        self.assertEqual(self.species.molecularWeight.value_si, species.molecularWeight.value_si)
        self.assertEqual(self.species.molecularWeight.units, species.molecularWeight.units)
        self.assertEqual(self.species.reactive, species.reactive)
        
    def testToAdjacencyList(self):
        """
        Test that toAdjacencyList() works as expected.
        """
        string = self.species.toAdjacencyList()
        self.assertTrue(string.startswith(self.species.molecule[0].toAdjacencyList(label=self.species.label,removeH=False)),string)
    
    def testSpeciesProps(self):
        """
        Test a key-value pair is added to the props attribute of Species.
        """
        self.species.props['foo'] = 'bar'
        self.assertIsInstance(self.species.props, dict)
        self.assertEquals(self.species.props['foo'], 'bar')
        
    def testSpeciesProps_object_attribute(self):
        """
        Test that Species's props dictionaries are independent of each other.
        
        Create a test in which is checked whether props is an object attribute rather
        than a class attribute
        """
        spc2 = Species()
        self.species.props['foo'] = 'bar'
        spc3 = Species()
        spc3.props['foo'] = 'bla'
        self.assertEquals(self.species.props['foo'], 'bar')
        self.assertDictEqual(spc2.props, {})
        self.assertDictEqual(spc3.props, {'foo': 'bla'})

    def testResonanceIsomersGenerated(self):
        "Test that 1-penten-3-yl makes 2-penten-1-yl resonance isomer"
        spec = Species().fromSMILES('C=C[CH]CC')
        spec.generate_resonance_structures()
        self.assertEquals(len(spec.molecule), 2)
        self.assertEquals(spec.molecule[1].toSMILES(), "[CH2]C=CCC")

    def testResonaceIsomersRepresented(self):
        "Test that both resonance forms of 1-penten-3-yl are printed by __repr__"
        spec = Species().fromSMILES('C=C[CH]CC')
        spec.generate_resonance_structures()
        exec('spec2 = {0!r}'.format(spec))
        self.assertEqual(len(spec.molecule), len(spec2.molecule))
        for i, j in zip(spec.molecule, spec2.molecule):
            self.assertTrue(j.isIsomorphic(i), msg='i is not isomorphic with j, where i is {} and j is {}'.format(i.toSMILES(), j.toSMILES()))

    def testGetResonanceHybrid(self):
        """
        Tests that getResonanceHybrid returns an isomorphic structure
        which has intermediate bond orders.
        
        This check is for C=C[CH]CC which has another resonance structure,
        [CH2]C=CC. When these structures are merged, the bond structure should be,
        C~C~CC, where '~' is a hybrid bond of order 1.5. 
        """
        spec = Species().fromSMILES('C=C[CH]CC')
        hybridMol = spec.getResonanceHybrid()
        
        self.assertTrue(hybridMol.toSingleBonds().isIsomorphic(spec.molecule[0].toSingleBonds()))
        
        # a rough check for intermediate bond orders
        expected_orders = [1,1.5]
        bonds = []
        # ensure all bond orders are expected
        for atom in hybridMol.atoms:
            for atom2 in atom.bonds:
                bond = hybridMol.getBond(atom,atom2)
                self.assertTrue(any([bond.isOrder(otherOrder) for otherOrder in expected_orders]), 'Unexpected bond order {}'.format(bond.getOrderNum()))
                bonds.append(bond)
                
        # ensure all expected orders are present
        for expected_order in expected_orders:
            self.assertTrue(any([bond.isOrder(expected_order) for bond in bonds]),'No bond of order {} found'.format(expected_order))
            
            
    def testCopy(self):
        """Test that we can make a copy of a Species object."""

        spc_cp = self.species.copy()

        self.assertTrue(id(self.species) != id(spc_cp))
        self.assertTrue(self.species.isIsomorphic(spc_cp))
        self.assertEquals(self.species.label, spc_cp.label)
        self.assertEquals(self.species.index, spc_cp.index)

        self.assertTrue(self.species.molecularWeight.equals(spc_cp.molecularWeight))
        self.assertEquals(self.species.reactive, spc_cp.reactive)
        
    def testCantera(self):
        """
        Test that a Cantera Species object is created correctly.
        """
        from rmgpy.thermo import NASA, NASAPolynomial
        import cantera as ct
        rmgSpecies = Species(label="Ar", thermo=NASA(polynomials=[NASAPolynomial(coeffs=[2.5,0,0,0,0,-745.375,4.37967], Tmin=(200,'K'), Tmax=(1000,'K')), NASAPolynomial(coeffs=[2.5,0,0,0,0,-745.375,4.37967], Tmin=(1000,'K'), Tmax=(6000,'K'))], Tmin=(200,'K'), Tmax=(6000,'K'), comment="""
Thermo library: primaryThermoLibrary
"""), molecule=[Molecule(SMILES="[Ar]")], transportData=TransportData(shapeIndex=0, epsilon=(1134.93,'J/mol'), sigma=(3.33,'angstrom'), dipoleMoment=(2,'De'), polarizability=(1,'angstrom^3'), rotrelaxcollnum=15.0, comment="""GRI-Mech"""))
        
        rmg_ctSpecies = rmgSpecies.toCantera(useChemkinIdentifier = True)
        
        ctSpecies = ct.Species.fromCti("""species(name=u'Ar',
        atoms='Ar:1',
        thermo=(NASA([200.00, 1000.00],
                     [ 2.50000000E+00,  0.00000000E+00,  0.00000000E+00,
                       0.00000000E+00,  0.00000000E+00, -7.45375000E+02,
                       4.37967000E+00]),
                NASA([1000.00, 6000.00],
                     [ 2.50000000E+00,  0.00000000E+00,  0.00000000E+00,
                       0.00000000E+00,  0.00000000E+00, -7.45375000E+02,
                       4.37967000E+00])),
        transport=gas_transport(geom='atom',
                                diam=3.33,
                                well_depth=136.501,
                                dipole=2.0,
                                polar=1.0,
                                rot_relax=15.0))""")
        self.assertEqual(type(rmg_ctSpecies),type(ctSpecies))
        self.assertEqual(rmg_ctSpecies.name, ctSpecies.name)
        self.assertEqual(rmg_ctSpecies.composition, ctSpecies.composition)
        self.assertEqual(rmg_ctSpecies.size, ctSpecies.size)
        self.assertEqual(type(rmg_ctSpecies.thermo), type(ctSpecies.thermo))
        self.assertEqual(type(rmg_ctSpecies.transport), type(ctSpecies.transport))

    def testGetTransportData(self):
        """
        Test that transport data can be retrieved correctly via the getTransportData method.
        """

        spc = Species(label="Ar", molecule=[Molecule(SMILES="[Ar]")], transportData=TransportData(shapeIndex=0, epsilon=(1134.93,'J/mol'), sigma=(3.33,'angstrom'), dipoleMoment=(2,'De'), polarizability=(1,'angstrom^3'), rotrelaxcollnum=15.0, comment="""GRI-Mech"""))

        self.assertTrue(spc.getTransportData() is spc.transportData)