def setUp(self):
        """
        A function run before each unit test in this class.
        """
        self.nC4H10O = Species(
            label = 'n-C4H10O',
            conformer = Conformer(
                E0 = (-317.807,'kJ/mol'),
                modes = [
                    IdealGasTranslation(mass=(74.07,"g/mol")),
                    NonlinearRotor(inertia=([41.5091,215.751,233.258],"amu*angstrom^2"), symmetry=1),
                    HarmonicOscillator(frequencies=([240.915,341.933,500.066,728.41,809.987,833.93,926.308,948.571,1009.3,1031.46,1076,1118.4,1184.66,1251.36,1314.36,1321.42,1381.17,1396.5,1400.54,1448.08,1480.18,1485.34,1492.24,1494.99,1586.16,2949.01,2963.03,2986.19,2988.1,2995.27,3026.03,3049.05,3053.47,3054.83,3778.88],"cm^-1")),
                    HinderedRotor(inertia=(0.854054,"amu*angstrom^2"), symmetry=1, fourier=([[0.25183,-1.37378,-2.8379,0.0305112,0.0028088], [0.458307,0.542121,-0.599366,-0.00283925,0.0398529]],"kJ/mol")),
                    HinderedRotor(inertia=(8.79408,"amu*angstrom^2"), symmetry=1, fourier=([[0.26871,-0.59533,-8.15002,-0.294325,-0.145357], [1.1884,0.99479,-0.940416,-0.186538,0.0309834]],"kJ/mol")),
                    HinderedRotor(inertia=(7.88153,"amu*angstrom^2"), symmetry=1, fourier=([[-4.67373,2.03735,-6.25993,-0.27325,-0.048748], [-0.982845,1.76637,-1.57619,0.474364,-0.000681718]],"kJ/mol")),
                    HinderedRotor(inertia=(2.81525,"amu*angstrom^2"), symmetry=3, barrier=(2.96807,"kcal/mol")),
                ],
                spinMultiplicity = 1,
                opticalIsomers = 1,
            ),
            molecularWeight = (74.07,"g/mol"),
            transportData=TransportData(sigma=(5.94, 'angstrom'), epsilon=(559, 'K')),
            energyTransferModel = SingleExponentialDown(alpha0=(447.5*0.011962,"kJ/mol"), T0=(300,"K"), n=0.85),
        )
        
        self.nC4H8 = Species(
            label = 'n-C4H8',
            conformer = Conformer(
                E0 = (-17.8832,'kJ/mol'),
                modes = [
                    IdealGasTranslation(mass=(56.06,"g/mol")),
                    NonlinearRotor(inertia=([22.2748,122.4,125.198],"amu*angstrom^2"), symmetry=1),
                    HarmonicOscillator(frequencies=([308.537,418.67,636.246,788.665,848.906,936.762,979.97,1009.48,1024.22,1082.96,1186.38,1277.55,1307.65,1332.87,1396.67,1439.09,1469.71,1484.45,1493.19,1691.49,2972.12,2994.31,3018.48,3056.87,3062.76,3079.38,3093.54,3174.52],"cm^-1")),
                    HinderedRotor(inertia=(5.28338,"amu*angstrom^2"), symmetry=1, fourier=([[-0.579364,-0.28241,-4.46469,0.143368,0.126756], [1.01804,-0.494628,-0.00318651,-0.245289,0.193728]],"kJ/mol")),
                    HinderedRotor(inertia=(2.60818,"amu*angstrom^2"), symmetry=3, fourier=([[0.0400372,0.0301986,-6.4787,-0.0248675,-0.0324753], [0.0312541,0.0538,-0.493785,0.0965968,0.125292]],"kJ/mol")),
                ],
                spinMultiplicity = 1,
                opticalIsomers = 1,
            ),
        )
        
        self.H2O = Species(
            label = 'H2O',
            conformer = Conformer(
                E0 = (-269.598,'kJ/mol'),
                modes = [
                    IdealGasTranslation(mass=(18.01,"g/mol")),
                    NonlinearRotor(inertia=([0.630578,1.15529,1.78586],"amu*angstrom^2"), symmetry=2),
                    HarmonicOscillator(frequencies=([1622.09,3771.85,3867.85],"cm^-1")),
                ],
                spinMultiplicity = 1,
                opticalIsomers = 1,
            ),
        )

        self.configuration = Configuration(self.nC4H8, self.H2O)
class TestConfiguration(unittest.TestCase):
    """
    Contains unit tests of the :class:`Network` class.
    """
    def setUp(self):
        """
        A function run before each unit test in this class.
        """
        self.nC4H10O = Species(
            label='n-C4H10O',
            conformer=Conformer(
                E0=(-317.807, 'kJ/mol'),
                modes=[
                    IdealGasTranslation(mass=(74.07, "g/mol")),
                    NonlinearRotor(inertia=([41.5091, 215.751,
                                             233.258], "amu*angstrom^2"),
                                   symmetry=1),
                    HarmonicOscillator(frequencies=([
                        240.915, 341.933, 500.066, 728.41, 809.987, 833.93,
                        926.308, 948.571, 1009.3, 1031.46, 1076, 1118.4,
                        1184.66, 1251.36, 1314.36, 1321.42, 1381.17, 1396.5,
                        1400.54, 1448.08, 1480.18, 1485.34, 1492.24, 1494.99,
                        1586.16, 2949.01, 2963.03, 2986.19, 2988.1, 2995.27,
                        3026.03, 3049.05, 3053.47, 3054.83, 3778.88
                    ], "cm^-1")),
                    HinderedRotor(inertia=(0.854054, "amu*angstrom^2"),
                                  symmetry=1,
                                  fourier=([[
                                      0.25183, -1.37378, -2.8379, 0.0305112,
                                      0.0028088
                                  ],
                                            [
                                                0.458307, 0.542121, -0.599366,
                                                -0.00283925, 0.0398529
                                            ]], "kJ/mol")),
                    HinderedRotor(
                        inertia=(8.79408, "amu*angstrom^2"),
                        symmetry=1,
                        fourier=([[
                            0.26871, -0.59533, -8.15002, -0.294325, -0.145357
                        ], [1.1884, 0.99479, -0.940416, -0.186538,
                            0.0309834]], "kJ/mol")),
                    HinderedRotor(inertia=(7.88153, "amu*angstrom^2"),
                                  symmetry=1,
                                  fourier=([[
                                      -4.67373, 2.03735, -6.25993, -0.27325,
                                      -0.048748
                                  ],
                                            [
                                                -0.982845, 1.76637, -1.57619,
                                                0.474364, -0.000681718
                                            ]], "kJ/mol")),
                    HinderedRotor(inertia=(2.81525, "amu*angstrom^2"),
                                  symmetry=3,
                                  barrier=(2.96807, "kcal/mol")),
                ],
                spin_multiplicity=1,
                optical_isomers=1,
            ),
            molecular_weight=(74.07, "g/mol"),
            transport_data=TransportData(sigma=(5.94, 'angstrom'),
                                         epsilon=(559, 'K')),
            energy_transfer_model=SingleExponentialDown(
                alpha0=(447.5 * 0.011962, "kJ/mol"), T0=(300, "K"), n=0.85),
        )

        self.nC4H8 = Species(
            label='n-C4H8',
            conformer=Conformer(
                E0=(-17.8832, 'kJ/mol'),
                modes=[
                    IdealGasTranslation(mass=(56.06, "g/mol")),
                    NonlinearRotor(inertia=([22.2748, 122.4,
                                             125.198], "amu*angstrom^2"),
                                   symmetry=1),
                    HarmonicOscillator(frequencies=([
                        308.537, 418.67, 636.246, 788.665, 848.906, 936.762,
                        979.97, 1009.48, 1024.22, 1082.96, 1186.38, 1277.55,
                        1307.65, 1332.87, 1396.67, 1439.09, 1469.71, 1484.45,
                        1493.19, 1691.49, 2972.12, 2994.31, 3018.48, 3056.87,
                        3062.76, 3079.38, 3093.54, 3174.52
                    ], "cm^-1")),
                    HinderedRotor(inertia=(5.28338, "amu*angstrom^2"),
                                  symmetry=1,
                                  fourier=([[
                                      -0.579364, -0.28241, -4.46469, 0.143368,
                                      0.126756
                                  ],
                                            [
                                                1.01804, -0.494628,
                                                -0.00318651, -0.245289,
                                                0.193728
                                            ]], "kJ/mol")),
                    HinderedRotor(
                        inertia=(2.60818, "amu*angstrom^2"),
                        symmetry=3,
                        fourier=([[
                            0.0400372, 0.0301986, -6.4787, -0.0248675,
                            -0.0324753
                        ], [0.0312541, 0.0538, -0.493785, 0.0965968,
                            0.125292]], "kJ/mol")),
                ],
                spin_multiplicity=1,
                optical_isomers=1,
            ),
        )

        self.H2O = Species(
            label='H2O',
            conformer=Conformer(
                E0=(-269.598, 'kJ/mol'),
                modes=[
                    IdealGasTranslation(mass=(18.01, "g/mol")),
                    NonlinearRotor(inertia=([0.630578, 1.15529,
                                             1.78586], "amu*angstrom^2"),
                                   symmetry=2),
                    HarmonicOscillator(
                        frequencies=([1622.09, 3771.85, 3867.85], "cm^-1")),
                ],
                spin_multiplicity=1,
                optical_isomers=1,
            ),
        )

        self.configuration = Configuration(self.nC4H8, self.H2O)

    def test_repr(self):
        """
        Test that the `repr` representation contains desired properties.
        """
        output = repr(self.configuration)
        # ensure species strings
        labels = ['H2O', 'n-C4H8']
        for label in labels:
            self.assertIn(label, output)

        # ensure classes are used as well
        attributes = [
            'Configuration', 'Species', 'Conformer', 'NonlinearRotor',
            'HarmonicOscillator', 'frequencies', 'IdealGasTranslation',
            'HinderedRotor', 'E0', 'mass', 'symmetry', 'fourier'
        ]
        for label in attributes:
            self.assertIn(label, output)

    def test_str(self):
        """
        Test that the string representation contains desired properties.
        """
        output = str(self.configuration)
        # ensure species strings
        labels = ['H2O', 'n-C4H8']
        for label in labels:
            self.assertIn(label, output)

        # ensure this extra fluff is not in Network string
        attributes = [
            'Species', 'Conformer', 'Molecule', 'NonlinearRotor',
            'HarmonicOscillator', 'frequencies', 'spin_multiplicity',
            'TransportData', 'molecular_weight', 'SingleExponentialDown'
        ]
        for label in attributes:
            self.assertNotIn(label, output)

    def test_no_nan_in_densStates(self):
        """
        This test asserts that there shouldn't be any NaN in the density of
        states produced by calculateDensityofStates
        """
        elist = np.linspace(0, 1e5)
        self.configuration.calculate_density_of_states(elist)
        self.assertFalse(np.isnan(self.configuration.dens_states).any())
Exemple #3
0
    def setUp(self):
        """
        A function run before each unit test in this class.
        """
        self.nC4H10O = Species(
            label='n-C4H10O',
            conformer=Conformer(
                E0=(-317.807, 'kJ/mol'),
                modes=[
                    IdealGasTranslation(mass=(74.07, "g/mol")),
                    NonlinearRotor(inertia=([41.5091, 215.751,
                                             233.258], "amu*angstrom^2"),
                                   symmetry=1),
                    HarmonicOscillator(frequencies=([
                        240.915, 341.933, 500.066, 728.41, 809.987, 833.93,
                        926.308, 948.571, 1009.3, 1031.46, 1076, 1118.4,
                        1184.66, 1251.36, 1314.36, 1321.42, 1381.17, 1396.5,
                        1400.54, 1448.08, 1480.18, 1485.34, 1492.24, 1494.99,
                        1586.16, 2949.01, 2963.03, 2986.19, 2988.1, 2995.27,
                        3026.03, 3049.05, 3053.47, 3054.83, 3778.88
                    ], "cm^-1")),
                    HinderedRotor(inertia=(0.854054, "amu*angstrom^2"),
                                  symmetry=1,
                                  fourier=([[
                                      0.25183, -1.37378, -2.8379, 0.0305112,
                                      0.0028088
                                  ],
                                            [
                                                0.458307, 0.542121, -0.599366,
                                                -0.00283925, 0.0398529
                                            ]], "kJ/mol")),
                    HinderedRotor(
                        inertia=(8.79408, "amu*angstrom^2"),
                        symmetry=1,
                        fourier=([[
                            0.26871, -0.59533, -8.15002, -0.294325, -0.145357
                        ], [1.1884, 0.99479, -0.940416, -0.186538,
                            0.0309834]], "kJ/mol")),
                    HinderedRotor(inertia=(7.88153, "amu*angstrom^2"),
                                  symmetry=1,
                                  fourier=([[
                                      -4.67373, 2.03735, -6.25993, -0.27325,
                                      -0.048748
                                  ],
                                            [
                                                -0.982845, 1.76637, -1.57619,
                                                0.474364, -0.000681718
                                            ]], "kJ/mol")),
                    HinderedRotor(inertia=(2.81525, "amu*angstrom^2"),
                                  symmetry=3,
                                  barrier=(2.96807, "kcal/mol")),
                ],
                spin_multiplicity=1,
                optical_isomers=1,
            ),
            molecular_weight=(74.07, "g/mol"),
            transport_data=TransportData(sigma=(5.94, 'angstrom'),
                                         epsilon=(559, 'K')),
            energy_transfer_model=SingleExponentialDown(
                alpha0=(447.5 * 0.011962, "kJ/mol"), T0=(300, "K"), n=0.85),
        )

        self.nC4H8 = Species(
            label='n-C4H8',
            conformer=Conformer(
                E0=(-17.8832, 'kJ/mol'),
                modes=[
                    IdealGasTranslation(mass=(56.06, "g/mol")),
                    NonlinearRotor(inertia=([22.2748, 122.4,
                                             125.198], "amu*angstrom^2"),
                                   symmetry=1),
                    HarmonicOscillator(frequencies=([
                        308.537, 418.67, 636.246, 788.665, 848.906, 936.762,
                        979.97, 1009.48, 1024.22, 1082.96, 1186.38, 1277.55,
                        1307.65, 1332.87, 1396.67, 1439.09, 1469.71, 1484.45,
                        1493.19, 1691.49, 2972.12, 2994.31, 3018.48, 3056.87,
                        3062.76, 3079.38, 3093.54, 3174.52
                    ], "cm^-1")),
                    HinderedRotor(inertia=(5.28338, "amu*angstrom^2"),
                                  symmetry=1,
                                  fourier=([[
                                      -0.579364, -0.28241, -4.46469, 0.143368,
                                      0.126756
                                  ],
                                            [
                                                1.01804, -0.494628,
                                                -0.00318651, -0.245289,
                                                0.193728
                                            ]], "kJ/mol")),
                    HinderedRotor(
                        inertia=(2.60818, "amu*angstrom^2"),
                        symmetry=3,
                        fourier=([[
                            0.0400372, 0.0301986, -6.4787, -0.0248675,
                            -0.0324753
                        ], [0.0312541, 0.0538, -0.493785, 0.0965968,
                            0.125292]], "kJ/mol")),
                ],
                spin_multiplicity=1,
                optical_isomers=1,
            ),
        )

        self.H2O = Species(
            label='H2O',
            conformer=Conformer(
                E0=(-269.598, 'kJ/mol'),
                modes=[
                    IdealGasTranslation(mass=(18.01, "g/mol")),
                    NonlinearRotor(inertia=([0.630578, 1.15529,
                                             1.78586], "amu*angstrom^2"),
                                   symmetry=2),
                    HarmonicOscillator(
                        frequencies=([1622.09, 3771.85, 3867.85], "cm^-1")),
                ],
                spin_multiplicity=1,
                optical_isomers=1,
            ),
        )

        self.N2 = Species(
            label='N2',
            molecular_weight=(28.04, "g/mol"),
            transport_data=TransportData(sigma=(3.41, "angstrom"),
                                         epsilon=(124, "K")),
            energy_transfer_model=None,
        )

        self.TS = TransitionState(
            label='TS',
            conformer=Conformer(
                E0=(-42.4373, "kJ/mol"),
                modes=[
                    IdealGasTranslation(mass=(74.07, "g/mol")),
                    NonlinearRotor(inertia=([40.518, 232.666,
                                             246.092], "u*angstrom**2"),
                                   symmetry=1,
                                   quantum=False),
                    HarmonicOscillator(frequencies=([
                        134.289, 302.326, 351.792, 407.986, 443.419, 583.988,
                        699.001, 766.1, 777.969, 829.671, 949.753, 994.731,
                        1013.59, 1073.98, 1103.79, 1171.89, 1225.91, 1280.67,
                        1335.08, 1373.9, 1392.32, 1417.43, 1469.51, 1481.61,
                        1490.16, 1503.73, 1573.16, 2972.85, 2984.3, 3003.67,
                        3045.78, 3051.77, 3082.37, 3090.44, 3190.73, 3708.52
                    ], "kayser")),
                    HinderedRotor(inertia=(2.68206, "amu*angstrom^2"),
                                  symmetry=3,
                                  barrier=(3.35244, "kcal/mol")),
                    HinderedRotor(inertia=(9.77669, "amu*angstrom^2"),
                                  symmetry=1,
                                  fourier=([[
                                      0.208938, -1.55291, -4.05398, -0.105798,
                                      -0.104752
                                  ],
                                            [
                                                2.00518, -0.020767, -0.333595,
                                                0.137791, -0.274578
                                            ]], "kJ/mol")),
                ],
                spin_multiplicity=1,
                optical_isomers=1,
            ),
            frequency=(-2038.34, 'cm^-1'),
        )

        self.reaction = Reaction(
            label='dehydration',
            reactants=[self.nC4H10O],
            products=[self.nC4H8, self.H2O],
            transition_state=self.TS,
        )

        self.network = Network(
            label='n-butanol',
            isomers=[Configuration(self.nC4H10O)],
            reactants=[],
            products=[Configuration(self.nC4H8, self.H2O)],
            path_reactions=[self.reaction],
            bath_gas={self.N2: 1.0},
        )
Exemple #4
0
def network(label,
            isomers=None,
            reactants=None,
            products=None,
            pathReactions=None,
            bathGas=None):
    """Load a network from an input file"""
    global network_dict, species_dict, reaction_dict
    logging.info('Loading network {0}...'.format(label))
    isomers0 = isomers or []
    isomers = []
    for isomer in isomers0:
        if isinstance(isomer, (list, tuple)):
            raise ValueError(
                'Only one species can be present in a unimolecular isomer.')
        isomers.append(species_dict[isomer])

    reactants0 = reactants or []
    reactants = []
    for reactant in reactants0:
        if not isinstance(reactant, (list, tuple)):
            reactant = [reactant]
        reactants.append(sorted([species_dict[spec] for spec in reactant]))

    if pathReactions is None:
        # Only add reactions that match reactants and/or isomers
        path_reactions = []
        for rxn in reaction_dict.values():
            if not rxn.is_unimolecular():
                # this reaction is not pressure dependent
                continue
            reactant_is_isomer = len(
                rxn.reactants) == 1 and rxn.reactants[0] in isomers
            product_is_isomer = len(
                rxn.products) == 1 and rxn.products[0] in isomers
            reactant_is_reactant = any([
                frozenset(rxn.reactants) == frozenset(reactant_pair)
                for reactant_pair in reactants
            ])
            product_is_reactant = any([
                frozenset(rxn.products) == frozenset(reactant_pair)
                for reactant_pair in reactants
            ])
            if reactant_is_isomer or reactant_is_reactant or product_is_isomer or product_is_reactant:
                path_reactions.append(rxn)
        logging.debug('Path reactions {} were found for network {}'.format(
            [rxn.label for rxn in path_reactions], label))
    else:
        path_reactions_0 = pathReactions
        path_reactions = []
        for rxn in path_reactions_0:
            path_reactions.append(reaction_dict[rxn])

    if products is None:
        # Figure out which configurations are isomers, reactant channels, and product channels
        products = []
        for rxn in path_reactions:
            # Sort bimolecular configurations so that we always encounter them in the same order
            # The actual order doesn't matter, as long as it is consistent
            rxn.reactants.sort()
            rxn.products.sort()
            # All reactant configurations not already defined as reactants or
            # isomers are assumed to be product channels
            if len(rxn.reactants) == 1 and rxn.reactants[
                    0] not in isomers and rxn.reactants not in products:
                products.append(rxn.reactants)
            elif len(
                    rxn.reactants
            ) > 1 and rxn.reactants not in reactants and rxn.reactants not in products:
                products.append(rxn.reactants)
            # All product configurations not already defined as reactants or
            # isomers are assumed to be product channels
            if len(rxn.products) == 1 and rxn.products[
                    0] not in isomers and rxn.products not in products:
                products.append(rxn.products)
            elif len(
                    rxn.products
            ) > 1 and rxn.products not in reactants and rxn.products not in products:
                products.append(rxn.products)
    else:
        products0 = products or []
        products = []
        for product in products0:
            if not isinstance(product, (list, tuple)):
                product = [product]
            products.append(sorted([species_dict[spec] for spec in product]))

    isomers = [Configuration(species) for species in isomers]
    reactants = [Configuration(*species) for species in reactants]
    products = [Configuration(*species) for species in products]

    bath_gas_0 = bathGas or {}
    bath_gas = {}
    for spec, fraction in bath_gas_0.items():
        bath_gas[species_dict[spec]] = fraction

    network = Network(
        label=label,
        isomers=isomers,
        reactants=reactants,
        products=products,
        path_reactions=path_reactions,
        bath_gas=bath_gas,
    )
    network_dict[label] = network
def network(label,
            isomers=None,
            reactants=None,
            products=None,
            pathReactions=None,
            bathGas=None):
    global networkDict, speciesDict, reactionDict
    logging.info('Loading network {0}...'.format(label))
    isomers0 = isomers or []
    isomers = []
    for isomer in isomers0:
        if isinstance(isomer, (list, tuple)):
            raise ValueError(
                'Only one species can be present in a unimolecular isomer.')
        isomers.append(speciesDict[isomer])

    reactants0 = reactants or []
    reactants = []
    for reactant in reactants0:
        if not isinstance(reactant, (list, tuple)):
            reactant = [reactant]
        reactants.append(sorted([speciesDict[spec] for spec in reactant]))

    if pathReactions is None:
        # If not explicitly given, use all reactions in input file
        pathReactions = reactionDict.values()
    else:
        pathReactions0 = pathReactions
        pathReactions = []
        for rxn in pathReactions0:
            pathReactions.append(reactionDict[rxn])

    if products is None:
        # Figure out which configurations are isomers, reactant channels, and product channels
        products = []
        for rxn in pathReactions:
            # Sort bimolecular configurations so that we always encounter them in the
            # same order
            # The actual order doesn't matter, as long as it is consistent
            rxn.reactants.sort()
            rxn.products.sort()
            # All reactant configurations not already defined as reactants or
            # isomers are assumed to be product channels
            if len(rxn.reactants) == 1 and rxn.reactants[
                    0] not in isomers and rxn.reactants not in products:
                products.append(rxn.reactants)
            elif len(
                    rxn.reactants
            ) > 1 and rxn.reactants not in reactants and rxn.reactants not in products:
                products.append(rxn.reactants)
            # All product configurations not already defined as reactants or
            # isomers are assumed to be product channels
            if len(rxn.products) == 1 and rxn.products[
                    0] not in isomers and rxn.products not in products:
                products.append(rxn.products)
            elif len(
                    rxn.products
            ) > 1 and rxn.products not in reactants and rxn.products not in products:
                products.append(rxn.products)
    else:
        products0 = products or []
        products = []
        for product in products0:
            if not isinstance(product, (list, tuple)):
                product = [product]
            products.append(sorted([speciesDict[spec] for spec in product]))

    isomers = [Configuration(species) for species in isomers]
    reactants = [Configuration(*species) for species in reactants]
    products = [Configuration(*species) for species in products]

    bathGas0 = bathGas or {}
    bathGas = {}
    for spec, fraction in bathGas0.items():
        bathGas[speciesDict[spec]] = fraction

    network = Network(
        label=label,
        isomers=isomers,
        reactants=reactants,
        products=products,
        pathReactions=pathReactions,
        bathGas=bathGas,
    )
    networkDict[label] = network