diff --git a/rmgpy/kinetics/chebyshev.pyx b/rmgpy/kinetics/chebyshev.pyx index 38935b25bc..9351a1c355 100644 --- a/rmgpy/kinetics/chebyshev.pyx +++ b/rmgpy/kinetics/chebyshev.pyx @@ -249,7 +249,7 @@ cdef class Chebyshev(PDepKineticsModel): return False if self.degreeT != other_kinetics.degreeT or self.degreeP != other_kinetics.degreeP: return False - if self.kunits != other_kinetics.kunits or (self.coeffs != other_kinetics.coeffs).any(): + if self.kunits != other_kinetics.kunits or not np.array_equal(self.coeffs.value, other_kinetics.coeffs.value): return False return True diff --git a/rmgpy/kinetics/chebyshevTest.py b/rmgpy/kinetics/chebyshevTest.py index aa5f5aff06..732a893ef2 100644 --- a/rmgpy/kinetics/chebyshevTest.py +++ b/rmgpy/kinetics/chebyshevTest.py @@ -239,6 +239,96 @@ def test_change_rate(self): 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)) + ################################################################################ diff --git a/rmgpy/kinetics/model.pyx b/rmgpy/kinetics/model.pyx index aa37f8f29b..9a15b7ac02 100644 --- a/rmgpy/kinetics/model.pyx +++ b/rmgpy/kinetics/model.pyx @@ -121,7 +121,7 @@ cdef class KineticsModel: Return a string representation that can be used to reconstruct the KineticsModel object. """ - return 'KineticsModel(Tmin={0!r}, Tmax={1!r}, Pmin={0!r}, Pmax={1!r}, comment="""{2}""")'.format( + return 'KineticsModel(Tmin={0!r}, Tmax={1!r}, Pmin={2!r}, Pmax={3!r}, uncertainty={4!r}, comment="""{5}""")'.format( self.Tmin, self.Tmax, self.Pmin, self.Pmax, self.uncertainty, self.comment) def __reduce__(self): @@ -230,15 +230,15 @@ cdef class KineticsModel: Returns ``True`` if Tmin, Tmax for both objects match. Otherwise returns ``False`` """ - if self.Tmin is not None and other_kinetics.Tmin is not None and not self.Tmin.equals(other_kinetics.Tmin): - return False + if self.Tmin is not None and other_kinetics.Tmin is not None and self.Tmin.equals(other_kinetics.Tmin): + pass elif self.Tmin is None and other_kinetics.Tmin is None: pass else: return False - if self.Tmax is not None and other_kinetics.Tmax is not None and not self.Tmax.equals(other_kinetics.Tmax): - return False + if self.Tmax is not None and other_kinetics.Tmax is not None and self.Tmax.equals(other_kinetics.Tmax): + pass elif self.Tmax is None and other_kinetics.Tmax is None: pass else: diff --git a/rmgpy/kinetics/modelTest.py b/rmgpy/kinetics/modelTest.py index fb8b279d36..7b02c56cc8 100644 --- a/rmgpy/kinetics/modelTest.py +++ b/rmgpy/kinetics/modelTest.py @@ -35,7 +35,76 @@ import unittest from rmgpy.kinetics.model import get_reaction_order_from_rate_coefficient_units, \ - get_rate_coefficient_units_from_reaction_order + get_rate_coefficient_units_from_reaction_order, \ + KineticsModel +from rmgpy.kinetics.uncertainties import RateUncertainty + + +class TestKineticsModel(unittest.TestCase): + """ + Contains unit tests of the KineticsModel class + """ + + def setUp(self): + """ + A function run before each unit test in this class. + """ + self.Tmin = 300. + self.Tmax = 3000. + self.Pmin = 0.1 + self.Pmax = 100. + self.comment = 'foo bar' + self.uncertainty = RateUncertainty(mu=0.3, var=0.6, Tref=1000.0, N=1, correlation="ab") + self.km = KineticsModel( + Tmin=(self.Tmin, "K"), + Tmax=(self.Tmax, "K"), + Pmin=(self.Pmin, "bar"), + Pmax=(self.Pmax, "bar"), + uncertainty=self.uncertainty, + comment=self.comment, + ) + + def test_is_identical_to(self): + """ + Test that the KineticsModel.is_identical_to method works on itself. + + This just checks the Temperature range + """ + self.assertTrue(self.km.is_identical_to(self.km)) + + import copy + km = copy.deepcopy(self.km) + self.assertTrue(self.km.is_identical_to(self.km)) + + km.Tmax = (self.Tmax - 50, 'K') # discrepancy must be more than 1%! + self.assertFalse(self.km.is_identical_to(km)) + + def test_repr(self): + """ + Test that an KineticsModel object can be reconstructed from its repr() + output with no loss of information. + """ + namespace = {} + exec('km = {0!r}'.format(self.km), globals(), namespace) + self.assertIn('km', namespace) + km = namespace['km'] + self.assertTrue(self.km.is_identical_to(km)) + self.assertEqual(dir(self.km), dir(km)) + for att in 'Tmax Tmin Pmax Pmin comment uncertainty'.split(): + self.assertEqual(repr(getattr(self.km, att)), repr(getattr(km, att))) + + def test_pickle(self): + """ + Test that an KineticsModel object can be pickled and unpickled + with no loss of information. + """ + import pickle + km = pickle.loads(pickle.dumps(self.km, -1)) + self.assertTrue(self.km.is_identical_to(km)) + self.assertEqual(dir(self.km), dir(km)) + for att in 'Tmax Tmin Pmax Pmin comment uncertainty'.split(): + self.assertEqual(repr(getattr(self.km, att)), repr(getattr(km, att))) + ################################################################################ @@ -44,7 +113,7 @@ class TestOrder(unittest.TestCase): Contains unit tests of the functions for converting rate coefficient units to/from reaction orders. """ - + def test_to_order_zeroth(self): """ Test the conversion of zeroth-order rate coefficient units to an integer @@ -54,14 +123,14 @@ def test_to_order_zeroth(self): self.assertEqual(0, get_reaction_order_from_rate_coefficient_units('mol/(cm^3*s)')) self.assertEqual(0, get_reaction_order_from_rate_coefficient_units('molecule/(m^3*s)')) self.assertEqual(0, get_reaction_order_from_rate_coefficient_units('molecule/(cm^3*s)')) - + def test_to_order_first(self): """ Test the conversion of first-order rate coefficient units to an integer reaction order. """ self.assertEqual(1, get_reaction_order_from_rate_coefficient_units('s^-1')) - + def test_to_order_second(self): """ Test the conversion of second-order rate coefficient units to an integer @@ -71,7 +140,7 @@ def test_to_order_second(self): self.assertEqual(2, get_reaction_order_from_rate_coefficient_units('cm^3/(mol*s)')) self.assertEqual(2, get_reaction_order_from_rate_coefficient_units('m^3/(molecule*s)')) self.assertEqual(2, get_reaction_order_from_rate_coefficient_units('cm^3/(molecule*s)')) - + def test_to_order_third(self): """ Test the conversion of third-order rate coefficient units to an integer @@ -81,28 +150,28 @@ def test_to_order_third(self): self.assertEqual(3, get_reaction_order_from_rate_coefficient_units('cm^6/(mol^2*s)')) self.assertEqual(3, get_reaction_order_from_rate_coefficient_units('m^6/(molecule^2*s)')) self.assertEqual(3, get_reaction_order_from_rate_coefficient_units('cm^6/(molecule^2*s)')) - + def test_to_units_zeroth(self): """ Test the conversion of a reaction order of zero to rate coefficient units. """ self.assertEqual('mol/(m^3*s)', get_rate_coefficient_units_from_reaction_order(0)) - + def test_to_units_first(self): """ Test the conversion of a reaction order of one to rate coefficient units. """ self.assertEqual('s^-1', get_rate_coefficient_units_from_reaction_order(1)) - + def test_to_units_second(self): """ Test the conversion of a reaction order of two to rate coefficient units. """ self.assertEqual('m^3/(mol*s)', get_rate_coefficient_units_from_reaction_order(2)) - + def test_to_units_third(self): """ Test the conversion of a reaction order of three to rate coefficient diff --git a/rmgpy/kinetics/surface.pyx b/rmgpy/kinetics/surface.pyx index 13ca5d0d99..3978082e0a 100644 --- a/rmgpy/kinetics/surface.pyx +++ b/rmgpy/kinetics/surface.pyx @@ -393,6 +393,7 @@ cdef class SurfaceArrhenius(Arrhenius): `Tmax` The maximum temperature at which the model is valid, or zero if unknown or undefined `Pmin` The minimum pressure at which the model is valid, or zero if unknown or undefined `Pmax` The maximum pressure at which the model is valid, or zero if unknown or undefined + `uncertainty` Uncertainty information `comment` Information about the model (e.g. its source) =============== ============================================================= """ @@ -415,6 +416,7 @@ cdef class SurfaceArrhenius(Arrhenius): if self.Tmax is not None: string += ', Tmax={0!r}'.format(self.Tmax) if self.Pmin is not None: string += ', Pmin={0!r}'.format(self.Pmin) if self.Pmax is not None: string += ', Pmax={0!r}'.format(self.Pmax) + if self.uncertainty is not None: string += ', uncertainty={0!r}'.format(self.uncertainty) if self.comment != '': string += ', comment="""{0}"""'.format(self.comment) string += ')' return string @@ -424,7 +426,7 @@ cdef class SurfaceArrhenius(Arrhenius): A helper function used when pickling a SurfaceArrhenius object. """ return (SurfaceArrhenius, (self.A, self.n, self.Ea, self.T0, self.Tmin, self.Tmax, self.Pmin, self.Pmax, - self.comment)) + self.uncertainty, self.comment)) ################################################################################ @@ -451,6 +453,7 @@ cdef class SurfaceArrheniusBEP(ArrheniusEP): `Tmax` The maximum temperature at which the model is valid, or zero if unknown or undefined `Pmin` The minimum pressure at which the model is valid, or zero if unknown or undefined `Pmax` The maximum pressure at which the model is valid, or zero if unknown or undefined + `uncertainty` Uncertainty information `comment` Information about the model (e.g. its source) =============== ============================================================= @@ -475,6 +478,7 @@ cdef class SurfaceArrheniusBEP(ArrheniusEP): if self.Tmax is not None: string += ', Tmax={0!r}'.format(self.Tmax) if self.Pmin is not None: string += ', Pmin={0!r}'.format(self.Pmin) if self.Pmax is not None: string += ', Pmax={0!r}'.format(self.Pmax) + if self.uncertainty is not None: string += ', uncertainty={0!r}'.format(self.uncertainty) if self.comment != '': string += ', comment="""{0}"""'.format(self.comment) string += ')' return string @@ -484,7 +488,7 @@ cdef class SurfaceArrheniusBEP(ArrheniusEP): A helper function used when pickling an SurfaceArrheniusBEP object. """ return (SurfaceArrheniusBEP, (self.A, self.n, self.alpha, self.E0, self.Tmin, self.Tmax, self.Pmin, self.Pmax, - self.comment)) + self.uncertainty, self.comment)) cpdef SurfaceArrhenius to_arrhenius(self, double dHrxn): """ @@ -502,5 +506,6 @@ cdef class SurfaceArrheniusBEP(ArrheniusEP): T0=(1, "K"), Tmin=self.Tmin, Tmax=self.Tmax, + uncertainty = self.uncertainty, comment=self.comment, ) diff --git a/rmgpy/kinetics/surfaceTest.py b/rmgpy/kinetics/surfaceTest.py new file mode 100644 index 0000000000..dfb4a5edd5 --- /dev/null +++ b/rmgpy/kinetics/surfaceTest.py @@ -0,0 +1,343 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +############################################################################### +# # +# RMG - Reaction Mechanism Generator # +# # +# Copyright (c) 2002-2019 Prof. William H. Green (whgreen@mit.edu), # +# Prof. Richard H. West (r.west@neu.edu) and the RMG Team (rmg_dev@mit.edu) # +# # +# Permission is hereby granted, free of charge, to any person obtaining a # +# copy of this software and associated documentation files (the 'Software'), # +# to deal in the Software without restriction, including without limitation # +# the rights to use, copy, modify, merge, publish, distribute, sublicense, # +# and/or sell copies of the Software, and to permit persons to whom the # +# Software is furnished to do so, subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be included in # +# all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # +# DEALINGS IN THE SOFTWARE. # +# # +############################################################################### + +""" +This script contains unit tests of the :mod:`rmgpy.kinetics.surface` module. +""" + +import unittest + +import numpy as np + +from rmgpy.kinetics.surface import StickingCoefficient, SurfaceArrhenius + +################################################################################ + + +class TestStickingCoefficient(unittest.TestCase): + """ + Contains unit tests of the :class:`StickingCoefficient` class. + """ + + def setUp(self): + """ + A function run before each unit test in this class. + """ + self.A = 4.3e-2 + self.n = -0.21 + self.Ea = 1.2 + self.T0 = 1. + self.Tmin = 300. + self.Tmax = 3000. + self.comment = 'O2 dissociative' + self.stick = StickingCoefficient( + A=self.A, + n=self.n, + Ea=(self.Ea, "kJ/mol"), + T0=(self.T0, "K"), + Tmin=(self.Tmin, "K"), + Tmax=(self.Tmax, "K"), + comment=self.comment, + ) + + def test_A(self): + """ + Test that the StickingCoefficient A property was properly set. + """ + self.assertAlmostEqual(self.stick.A.value_si, self.A, delta=1e0) + + def test_n(self): + """ + Test that the StickingCoefficient n property was properly set. + """ + self.assertAlmostEqual(self.stick.n.value_si, self.n, 6) + + def test_Ea(self): + """ + Test that the StickingCoefficient Ea property was properly set. + """ + self.assertAlmostEqual(self.stick.Ea.value_si * 0.001, self.Ea, 6) + + def test_T0(self): + """ + Test that the StickingCoefficient T0 property was properly set. + """ + self.assertAlmostEqual(self.stick.T0.value_si, self.T0, 6) + + def test_Tmin(self): + """ + Test that the StickingCoefficient Tmin property was properly set. + """ + self.assertAlmostEqual(self.stick.Tmin.value_si, self.Tmin, 6) + + def test_Tmax(self): + """ + Test that the StickingCoefficient Tmax property was properly set. + """ + self.assertAlmostEqual(self.stick.Tmax.value_si, self.Tmax, 6) + + def test_comment(self): + """ + Test that the StickingCoefficient comment property was properly set. + """ + self.assertEqual(self.stick.comment, self.comment) + + def test_is_temperature_valid(self): + """ + Test the StickingCoefficient.is_temperature_valid() method. + """ + T_data = np.array([200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 4000]) + valid_data = np.array([False, True, True, True, True, True, True, True, True, False], np.bool) + for T, valid in zip(T_data, valid_data): + valid0 = self.stick.is_temperature_valid(T) + self.assertEqual(valid0, valid) + + def test_pickle(self): + """ + Test that an StickingCoefficient object can be pickled and unpickled with no loss + of information. + """ + import pickle + stick = pickle.loads(pickle.dumps(self.stick, -1)) + self.assertAlmostEqual(self.stick.A.value, stick.A.value, delta=1e0) + self.assertEqual(self.stick.A.units, stick.A.units) + self.assertAlmostEqual(self.stick.n.value, stick.n.value, 4) + self.assertAlmostEqual(self.stick.Ea.value, stick.Ea.value, 4) + self.assertEqual(self.stick.Ea.units, stick.Ea.units) + self.assertAlmostEqual(self.stick.T0.value, stick.T0.value, 4) + self.assertEqual(self.stick.T0.units, stick.T0.units) + self.assertAlmostEqual(self.stick.Tmin.value, stick.Tmin.value, 4) + self.assertEqual(self.stick.Tmin.units, stick.Tmin.units) + self.assertAlmostEqual(self.stick.Tmax.value, stick.Tmax.value, 4) + self.assertEqual(self.stick.Tmax.units, stick.Tmax.units) + self.assertEqual(self.stick.comment, stick.comment) + self.assertEqual(dir(self.stick), dir(stick)) + + def test_repr(self): + """ + Test that an StickingCoefficient object can be reconstructed from its repr() + output with no loss of information. + """ + namespace = {} + exec('stick = {0!r}'.format(self.stick), globals(), namespace) + self.assertIn('stick', namespace) + stick = namespace['stick'] + self.assertAlmostEqual(self.stick.A.value, stick.A.value, delta=1e0) + self.assertEqual(self.stick.A.units, stick.A.units) + self.assertAlmostEqual(self.stick.n.value, stick.n.value, 4) + self.assertAlmostEqual(self.stick.Ea.value, stick.Ea.value, 4) + self.assertEqual(self.stick.Ea.units, stick.Ea.units) + self.assertAlmostEqual(self.stick.T0.value, stick.T0.value, 4) + self.assertEqual(self.stick.T0.units, stick.T0.units) + self.assertAlmostEqual(self.stick.Tmin.value, stick.Tmin.value, 4) + self.assertEqual(self.stick.Tmin.units, stick.Tmin.units) + self.assertAlmostEqual(self.stick.Tmax.value, stick.Tmax.value, 4) + self.assertEqual(self.stick.Tmax.units, stick.Tmax.units) + self.assertEqual(self.stick.comment, stick.comment) + self.assertEqual(dir(self.stick), dir(stick)) + + def test_copy(self): + """ + Test that an StickingCoefficient object can be copied with deepcopy + with no loss of information. + """ + import copy + stick = copy.deepcopy(self.stick) + self.assertAlmostEqual(self.stick.A.value, stick.A.value, delta=1e0) + self.assertEqual(self.stick.A.units, stick.A.units) + self.assertAlmostEqual(self.stick.n.value, stick.n.value, 4) + self.assertAlmostEqual(self.stick.Ea.value, stick.Ea.value, 4) + self.assertEqual(self.stick.Ea.units, stick.Ea.units) + self.assertAlmostEqual(self.stick.T0.value, stick.T0.value, 4) + self.assertEqual(self.stick.T0.units, stick.T0.units) + self.assertAlmostEqual(self.stick.Tmin.value, stick.Tmin.value, 4) + self.assertEqual(self.stick.Tmin.units, stick.Tmin.units) + self.assertAlmostEqual(self.stick.Tmax.value, stick.Tmax.value, 4) + self.assertEqual(self.stick.Tmax.units, stick.Tmax.units) + self.assertEqual(self.stick.comment, stick.comment) + self.assertEqual(dir(self.stick), dir(stick)) + + def test_is_identical_to(self): + """ + Test that the StickingCoefficient.is_identical_to method works on itself + """ + self.assertTrue(self.stick.is_identical_to(self.stick)) + +################################################################################ + + +class TestSurfaceArrhenius(unittest.TestCase): + """ + Contains unit tests of the :class:`SurfaceArrhenius` class. + """ + + def setUp(self): + """ + A function run before each unit test in this class. + """ + self.A = 1.44e18 + self.n = -0.087 + self.Ea = 63.4 + self.T0 = 1. + self.Tmin = 300. + self.Tmax = 3000. + self.comment = 'CH3x + Hx <=> CH4 + x + x' + self.surfarr = SurfaceArrhenius( + A=(self.A, 'm^2/(mol*s)'), + n=self.n, + Ea=(self.Ea, "kJ/mol"), + T0=(self.T0, "K"), + Tmin=(self.Tmin, "K"), + Tmax=(self.Tmax, "K"), + comment=self.comment, + ) + + def test_A(self): + """ + Test that the SurfaceArrhenius A property was properly set. + """ + self.assertAlmostEqual(self.surfarr.A.value_si, self.A, delta=1e0) + + def test_n(self): + """ + Test that the SurfaceArrhenius n property was properly set. + """ + self.assertAlmostEqual(self.surfarr.n.value_si, self.n, 6) + + def test_Ea(self): + """ + Test that the SurfaceArrhenius Ea property was properly set. + """ + self.assertAlmostEqual(self.surfarr.Ea.value_si * 0.001, self.Ea, 6) + + def test_T0(self): + """ + Test that the SurfaceArrhenius T0 property was properly set. + """ + self.assertAlmostEqual(self.surfarr.T0.value_si, self.T0, 6) + + def test_Tmin(self): + """ + Test that the SurfaceArrhenius Tmin property was properly set. + """ + self.assertAlmostEqual(self.surfarr.Tmin.value_si, self.Tmin, 6) + + def test_Tmax(self): + """ + Test that the SurfaceArrhenius Tmax property was properly set. + """ + self.assertAlmostEqual(self.surfarr.Tmax.value_si, self.Tmax, 6) + + def test_comment(self): + """ + Test that the SurfaceArrhenius comment property was properly set. + """ + self.assertEqual(self.surfarr.comment, self.comment) + + def test_is_temperature_valid(self): + """ + Test the SurfaceArrhenius.is_temperature_valid() method. + """ + T_data = np.array([200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 4000]) + valid_data = np.array([False, True, True, True, True, True, True, True, True, False], np.bool) + for T, valid in zip(T_data, valid_data): + valid0 = self.surfarr.is_temperature_valid(T) + self.assertEqual(valid0, valid) + + def test_pickle(self): + """ + Test that an SurfaceArrhenius object can be pickled and unpickled with no loss + of information. + """ + import pickle + surfarr = pickle.loads(pickle.dumps(self.surfarr, -1)) + self.assertAlmostEqual(self.surfarr.A.value, surfarr.A.value, delta=1e0) + self.assertEqual(self.surfarr.A.units, surfarr.A.units) + self.assertAlmostEqual(self.surfarr.n.value, surfarr.n.value, 4) + self.assertAlmostEqual(self.surfarr.Ea.value, surfarr.Ea.value, 4) + self.assertEqual(self.surfarr.Ea.units, surfarr.Ea.units) + self.assertAlmostEqual(self.surfarr.T0.value, surfarr.T0.value, 4) + self.assertEqual(self.surfarr.T0.units, surfarr.T0.units) + self.assertAlmostEqual(self.surfarr.Tmin.value, surfarr.Tmin.value, 4) + self.assertEqual(self.surfarr.Tmin.units, surfarr.Tmin.units) + self.assertAlmostEqual(self.surfarr.Tmax.value, surfarr.Tmax.value, 4) + self.assertEqual(self.surfarr.Tmax.units, surfarr.Tmax.units) + self.assertEqual(self.surfarr.comment, surfarr.comment) + self.assertEqual(dir(self.surfarr), dir(surfarr)) + + def test_repr(self): + """ + Test that an SurfaceArrhenius object can be reconstructed from its repr() + output with no loss of information. + """ + namespace = {} + exec('surfarr = {0!r}'.format(self.surfarr), globals(), namespace) + self.assertIn('surfarr', namespace) + surfarr = namespace['surfarr'] + self.assertAlmostEqual(self.surfarr.A.value, surfarr.A.value, delta=1e0) + self.assertEqual(self.surfarr.A.units, surfarr.A.units) + self.assertAlmostEqual(self.surfarr.n.value, surfarr.n.value, 4) + self.assertAlmostEqual(self.surfarr.Ea.value, surfarr.Ea.value, 4) + self.assertEqual(self.surfarr.Ea.units, surfarr.Ea.units) + self.assertAlmostEqual(self.surfarr.T0.value, surfarr.T0.value, 4) + self.assertEqual(self.surfarr.T0.units, surfarr.T0.units) + self.assertAlmostEqual(self.surfarr.Tmin.value, surfarr.Tmin.value, 4) + self.assertEqual(self.surfarr.Tmin.units, surfarr.Tmin.units) + self.assertAlmostEqual(self.surfarr.Tmax.value, surfarr.Tmax.value, 4) + self.assertEqual(self.surfarr.Tmax.units, surfarr.Tmax.units) + self.assertEqual(self.surfarr.comment, surfarr.comment) + self.assertEqual(dir(self.surfarr), dir(surfarr)) + + def test_copy(self): + """ + Test that an SurfaceArrhenius object can be copied with deepcopy + with no loss of information. + """ + import copy + surfarr = copy.deepcopy(self.surfarr) + self.assertAlmostEqual(self.surfarr.A.value, surfarr.A.value, delta=1e0) + self.assertEqual(self.surfarr.A.units, surfarr.A.units) + self.assertAlmostEqual(self.surfarr.n.value, surfarr.n.value, 4) + self.assertAlmostEqual(self.surfarr.Ea.value, surfarr.Ea.value, 4) + self.assertEqual(self.surfarr.Ea.units, surfarr.Ea.units) + self.assertAlmostEqual(self.surfarr.T0.value, surfarr.T0.value, 4) + self.assertEqual(self.surfarr.T0.units, surfarr.T0.units) + self.assertAlmostEqual(self.surfarr.Tmin.value, surfarr.Tmin.value, 4) + self.assertEqual(self.surfarr.Tmin.units, surfarr.Tmin.units) + self.assertAlmostEqual(self.surfarr.Tmax.value, surfarr.Tmax.value, 4) + self.assertEqual(self.surfarr.Tmax.units, surfarr.Tmax.units) + self.assertEqual(self.surfarr.comment, surfarr.comment) + self.assertEqual(dir(self.surfarr), dir(surfarr)) + + def test_is_identical_to(self): + """ + Test that the SurfaceArrhenius.is_identical_to method works on itself + """ + self.assertTrue(self.surfarr.is_identical_to(self.surfarr))