Exemple #1
0
 def test_fit_to_data(self):
     """
     Test the Chebyshev.fit_to_data() method.
     """
     Tdata = np.array([
         300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400,
         1500, 1600, 1700, 1800, 1900, 2000
     ])
     Pdata = np.array([3e3, 1e4, 3e4, 1e5, 3e5, 1e6, 3e7])
     nT = len(Tdata)
     nP = len(Pdata)
     kdata = np.zeros((nT, nP))
     for t in range(nT):
         for p in range(nP):
             kdata[t, p] = self.chebyshev.get_rate_coefficient(
                 Tdata[t], Pdata[p]) * 1e6
     chebyshev = Chebyshev().fit_to_data(Tdata,
                                         Pdata,
                                         kdata,
                                         kunits="cm^3/(mol*s)",
                                         degreeT=6,
                                         degreeP=4,
                                         Tmin=300,
                                         Tmax=2000,
                                         Pmin=0.1,
                                         Pmax=10.)
     for t in range(nT):
         for p in range(nP):
             kfit = chebyshev.get_rate_coefficient(Tdata[t], Pdata[p]) * 1e6
             self.assertAlmostEqual(kfit,
                                    kdata[t, p],
                                    delta=1e-4 * kdata[t, p])
Exemple #2
0
class TestChebyshev(unittest.TestCase):
    """
    Contains unit tests of the Chebyshev class.
    """
    def setUp(self):
        """
        A function run before each unit test in this class.
        """
        self.Tmin = 300.
        self.Tmax = 2000.
        self.Pmin = 0.01
        self.Pmax = 100.
        self.coeffs = np.array([
            [11.67723, 0.729281, -0.11984, 0.00882175],
            [-1.02669, 0.853639, -0.0323485, -0.027367],
            [-0.447011, 0.244144, 0.0559122, -0.0101723],
            [-0.128261, 0.0111596, 0.0281176, 0.00604353],
            [-0.0117034, -0.0235646, 0.00061009, 0.00401309],
            [0.0155433, -0.0136846, -0.00463048, -0.000261353],
        ])
        self.comment = """acetyl + O2 -> acetylperoxy"""
        self.chebyshev = Chebyshev(
            coeffs=self.coeffs,
            kunits="cm^3/(mol*s)",
            Tmin=(self.Tmin, "K"),
            Tmax=(self.Tmax, "K"),
            Pmin=(self.Pmin, "bar"),
            Pmax=(self.Pmax, "bar"),
            comment=self.comment,
        )

    def test_coeffs(self):
        """
        Test that the Chebyshev coeffs property was properly set.
        """
        self.assertEqual(self.chebyshev.coeffs.value.shape, self.coeffs.shape)
        for i in range(self.chebyshev.coeffs.value.shape[0]):
            for j in range(self.chebyshev.coeffs.value.shape[1]):
                C0 = float(self.coeffs[i, j])
                C = float(self.chebyshev.coeffs.value_si[i, j])
                if i == 0 and j == 0:
                    C0 -= 6  # Unit conversion from cm^3/(mol*s) to m^3/(mol*s)
                self.assertAlmostEqual(C0, C, delta=1e-6 * C0)

    def test_temperature_min(self):
        """
        Test that the Chebyshev Tmin property was properly set.
        """
        self.assertAlmostEqual(self.chebyshev.Tmin.value_si, self.Tmin, 6)

    def test_temperature_max(self):
        """
        Test that the Chebyshev Tmax property was properly set.
        """
        self.assertAlmostEqual(self.chebyshev.Tmax.value_si, self.Tmax, 6)

    def test_pressure_min(self):
        """
        Test that the Chebyshev Pmin property was properly set.
        """
        self.assertAlmostEqual(self.chebyshev.Pmin.value_si * 1e-5, self.Pmin,
                               6)

    def test_pressure_max(self):
        """
        Test that the Chebyshev Pmax property was properly set.
        """
        self.assertAlmostEqual(self.chebyshev.Pmax.value_si * 1e-5, self.Pmax,
                               6)

    def test_comment(self):
        """
        Test that the Chebyshev comment property was properly set.
        """
        self.assertEqual(self.chebyshev.comment, self.comment)

    def test_is_pressure_dependent(self):
        """
        Test the Chebyshev.is_pressure_dependent() method.
        
        """
        self.assertTrue(self.chebyshev.is_pressure_dependent())

    def test_get_rate_coefficient(self):
        """
        Test the Chebyshev.get_rate_coefficient() method.
        """
        Tlist = np.array([300, 500, 1000, 1500])
        Plist = np.array([1e4, 1e5, 1e6])
        Kexp = np.array([
            [2.29100e+06, 2.58452e+06, 2.57204e+06],
            [1.10198e+06, 2.04037e+06, 2.57428e+06],
            [4.37919e+04, 2.36481e+05, 8.57727e+05],
            [5.20144e+03, 4.10123e+04, 2.50401e+05],
        ])
        for t in range(Tlist.shape[0]):
            for p in range(Plist.shape[0]):
                Kact = self.chebyshev.get_rate_coefficient(Tlist[t], Plist[p])
                self.assertAlmostEqual(
                    Kact / Kexp[t, p], 1.0, 4,
                    '{0} != {1} within 4 places'.format(Kexp[t, p], Kact))

    def test_fit_to_data(self):
        """
        Test the Chebyshev.fit_to_data() method.
        """
        Tdata = np.array([
            300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400,
            1500, 1600, 1700, 1800, 1900, 2000
        ])
        Pdata = np.array([3e3, 1e4, 3e4, 1e5, 3e5, 1e6, 3e7])
        nT = len(Tdata)
        nP = len(Pdata)
        kdata = np.zeros((nT, nP))
        for t in range(nT):
            for p in range(nP):
                kdata[t, p] = self.chebyshev.get_rate_coefficient(
                    Tdata[t], Pdata[p]) * 1e6
        chebyshev = Chebyshev().fit_to_data(Tdata,
                                            Pdata,
                                            kdata,
                                            kunits="cm^3/(mol*s)",
                                            degreeT=6,
                                            degreeP=4,
                                            Tmin=300,
                                            Tmax=2000,
                                            Pmin=0.1,
                                            Pmax=10.)
        for t in range(nT):
            for p in range(nP):
                kfit = chebyshev.get_rate_coefficient(Tdata[t], Pdata[p]) * 1e6
                self.assertAlmostEqual(kfit,
                                       kdata[t, p],
                                       delta=1e-4 * kdata[t, p])

    def test_fit_to_data2(self):
        """
        Test the Chebyshev.fit_to_data() method throws error without enough degrees of freedom.
        
        Here only 3 temperatures are given, but the polynomial desired has 6 parameters.
        """
        Tdata = np.array([300, 1200, 2000])
        Pdata = np.array([1e5, 3e5, 1e6, 3e7])
        nT = len(Tdata)
        nP = len(Pdata)
        kdata = np.zeros((nT, nP))
        for t in range(nT):
            for p in range(nP):
                kdata[t, p] = self.chebyshev.get_rate_coefficient(
                    Tdata[t], Pdata[p])
        with self.assertRaises(KineticsError):
            Chebyshev().fit_to_data(Tdata,
                                    Pdata,
                                    kdata,
                                    kunits="cm^3/(mol*s)",
                                    degreeT=12,
                                    degreeP=8,
                                    Tmin=300,
                                    Tmax=2000,
                                    Pmin=0.1,
                                    Pmax=10.)

    def test_pickle(self):
        """
        Test that a Chebyshev object can be pickled and unpickled with no loss
        of information.
        """
        import pickle
        chebyshev = pickle.loads(pickle.dumps(self.chebyshev, -1))
        self.assertEqual(self.chebyshev.coeffs.value.shape[0],
                         chebyshev.coeffs.value.shape[0])
        self.assertEqual(self.chebyshev.coeffs.value.shape[1],
                         chebyshev.coeffs.value.shape[1])
        for i in range(self.chebyshev.coeffs.value.shape[0]):
            for j in range(self.chebyshev.coeffs.value.shape[1]):
                C0 = self.chebyshev.coeffs.value_si[i, j]
                C = chebyshev.coeffs.value_si[i, j]
                self.assertAlmostEqual(C0, C, delta=1e-4 * C0)
        self.assertAlmostEqual(self.chebyshev.Tmin.value, chebyshev.Tmin.value,
                               4)
        self.assertEqual(self.chebyshev.Tmin.units, chebyshev.Tmin.units)
        self.assertAlmostEqual(self.chebyshev.Tmax.value, chebyshev.Tmax.value,
                               4)
        self.assertEqual(self.chebyshev.Tmax.units, chebyshev.Tmax.units)
        self.assertAlmostEqual(self.chebyshev.Pmin.value, chebyshev.Pmin.value,
                               4)
        self.assertEqual(self.chebyshev.Pmin.units, chebyshev.Pmin.units)
        self.assertAlmostEqual(self.chebyshev.Pmax.value, chebyshev.Pmax.value,
                               4)
        self.assertEqual(self.chebyshev.Pmax.units, chebyshev.Pmax.units)
        self.assertEqual(self.chebyshev.comment, chebyshev.comment)

    def test_repr(self):
        """
        Test that a Chebyshev object can be reconstructed from its repr()
        output with no loss of information.
        """
        namespace = {}
        exec('chebyshev = {0!r}'.format(self.chebyshev), globals(), namespace)
        self.assertIn('chebyshev', namespace)
        chebyshev = namespace['chebyshev']
        self.assertEqual(self.chebyshev.coeffs.value.shape[0],
                         chebyshev.coeffs.value.shape[0])
        self.assertEqual(self.chebyshev.coeffs.value.shape[1],
                         chebyshev.coeffs.value.shape[1])
        for i in range(self.chebyshev.coeffs.value.shape[0]):
            for j in range(self.chebyshev.coeffs.value.shape[1]):
                C0 = self.chebyshev.coeffs.value[i, j]
                C = chebyshev.coeffs.value[i, j]
                self.assertAlmostEqual(C0, C, delta=1e-4 * C0)
        self.assertAlmostEqual(self.chebyshev.Tmin.value, chebyshev.Tmin.value,
                               4)
        self.assertEqual(self.chebyshev.Tmin.units, chebyshev.Tmin.units)
        self.assertAlmostEqual(self.chebyshev.Tmax.value, chebyshev.Tmax.value,
                               4)
        self.assertEqual(self.chebyshev.Tmax.units, chebyshev.Tmax.units)
        self.assertAlmostEqual(self.chebyshev.Pmin.value, chebyshev.Pmin.value,
                               4)
        self.assertEqual(self.chebyshev.Pmin.units, chebyshev.Pmin.units)
        self.assertAlmostEqual(self.chebyshev.Pmax.value, chebyshev.Pmax.value,
                               4)
        self.assertEqual(self.chebyshev.Pmax.units, chebyshev.Pmax.units)
        self.assertEqual(self.chebyshev.comment, chebyshev.comment)

    def test_change_rate(self):
        """
        Test the Chebyshev.change_rate() method.
        """
        Tlist = np.array([
            300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400,
            1500
        ])
        k0list = np.array(
            [self.chebyshev.get_rate_coefficient(T, 1e5) for T in Tlist])
        self.chebyshev.change_rate(2)
        for T, kexp in zip(Tlist, k0list):
            kact = self.chebyshev.get_rate_coefficient(T, 1e5)
            self.assertAlmostEqual(2 * kexp, kact, delta=1e-6 * kexp)

    def test_is_identical_to(self):
        """
        Test the Chebyshev.is_identical_to() method.
        """
        # Trivial case, compare to a KineticsModel
        from rmgpy.kinetics.model import KineticsModel
        self.assertFalse(self.chebyshev.is_identical_to(KineticsModel()))

        # Compare to identical Chebyshev
        new_chebyshev = Chebyshev(
            coeffs=self.coeffs,
            kunits="cm^3/(mol*s)",
            Tmin=(self.Tmin, "K"),
            Tmax=(self.Tmax, "K"),
            Pmin=(self.Pmin, "bar"),
            Pmax=(self.Pmax, "bar"),
            comment=self.comment,
        )
        self.assertTrue(self.chebyshev.is_identical_to(new_chebyshev))

        # Compare to Chebyshev with different Tmin/Tmax
        new_chebyshev = Chebyshev(
            coeffs=self.coeffs,
            kunits="cm^3/(mol*s)",
            Tmin=(200, "K"),
            Tmax=(self.Tmax, "K"),
            Pmin=(self.Pmin, "bar"),
            Pmax=(self.Pmax, "bar"),
            comment=self.comment,
        )
        self.assertFalse(self.chebyshev.is_identical_to(new_chebyshev))

        new_chebyshev = Chebyshev(
            coeffs=self.coeffs,
            kunits="cm^3/(mol*s)",
            Tmin=(self.Tmin, "K"),
            Tmax=(2500, "K"),
            Pmin=(self.Pmin, "bar"),
            Pmax=(self.Pmax, "bar"),
            comment=self.comment,
        )
        self.assertFalse(self.chebyshev.is_identical_to(new_chebyshev))

        # Compare to Chebyshev with different degreeT/degreeP
        new_chebyshev = Chebyshev(
            coeffs=self.coeffs[0:-1, :],  # Remove one T dimension
            kunits="cm^3/(mol*s)",
            Tmin=(self.Tmin, "K"),
            Tmax=(self.Tmax, "K"),
            Pmin=(self.Pmin, "bar"),
            Pmax=(self.Pmax, "bar"),
            comment=self.comment,
        )
        self.assertFalse(self.chebyshev.is_identical_to(new_chebyshev))

        new_chebyshev = Chebyshev(
            coeffs=self.coeffs[:, 0:-1],  # Remove one P dimension
            kunits="cm^3/(mol*s)",
            Tmin=(self.Tmin, "K"),
            Tmax=(self.Tmax, "K"),
            Pmin=(self.Pmin, "bar"),
            Pmax=(self.Pmax, "bar"),
            comment=self.comment,
        )
        self.assertFalse(self.chebyshev.is_identical_to(new_chebyshev))

        # Compare to Chebyshev with different units
        new_chebyshev = Chebyshev(
            coeffs=self.coeffs,
            kunits="m^3/(mol*s)",
            Tmin=(self.Tmin, "K"),
            Tmax=(self.Tmax, "K"),
            Pmin=(self.Pmin, "bar"),
            Pmax=(self.Pmax, "bar"),
            comment=self.comment,
        )
        self.assertFalse(self.chebyshev.is_identical_to(new_chebyshev))

        # Compare to Chebyshev with slightly different coefficients
        new_chebyshev = Chebyshev(
            coeffs=np.copy(self.coeffs) * 0.01,
            kunits="cm^3/(mol*s)",
            Tmin=(self.Tmin, "K"),
            Tmax=(self.Tmax, "K"),
            Pmin=(self.Pmin, "bar"),
            Pmax=(self.Pmax, "bar"),
            comment=self.comment,
        )
        self.assertFalse(self.chebyshev.is_identical_to(new_chebyshev))