Пример #1
0
 def test_get_A(self):
     exp_sm_SoR = self.H2O_TS_sm.get_SoR(T=c.T0('K')) \
                  - self.H2_sm.get_SoR(T=c.T0('K')) \
                  - self.O2_sm.get_SoR(T=c.T0('K'))*0.5
     exp_sm_A = c.kb('J/K') * c.T0('K') / c.h('J s') * np.exp(-exp_sm_SoR)
     exp_sm_SoR_rev = self.H2O_TS_sm.get_SoR(T=c.T0('K')) \
                      - self.H2O_sm.get_SoR(T=c.T0('K'))
     exp_sm_A_rev = c.kb('J/K') * c.T0('K') / c.h('J s') * np.exp(
         -exp_sm_SoR_rev)
     self.assertAlmostEqual(self.rxn_sm.get_A(T=c.T0('K')), exp_sm_A)
     self.assertAlmostEqual(self.rxn_sm.get_A(T=c.T0('K'), rev=True),
                            exp_sm_A_rev)
Пример #2
0
 def __init__(self,
              A_st=None,
              atoms=None,
              symmetrynumber=None,
              inertia=None,
              geometry=None,
              vib_energies=None,
              potentialenergy=None,
              **kwargs):
     super().__init__(atoms=atoms,
                      symmetrynumber=symmetrynumber,
                      geometry=geometry,
                      vib_energies=vib_energies,
                      potentialenergy=potentialenergy,
                      **kwargs)
     self.A_st = A_st
     self.atoms = atoms
     self.geometry = geometry
     self.symmetrynumber = symmetrynumber
     self.inertia = inertia
     self.etotal = potentialenergy
     self.vib_energies = vib_energies
     self.theta = np.array(vib_energies) / c.kb('eV/K')
     self.zpe = sum(np.array(vib_energies)/2.) *\
         c.convert_unit(from_='eV', to='kcal')*c.Na
     if np.sum(vib_energies) != 0:
         self.q_vib = np.product(
             np.divide(1, (1 - np.exp(-self.theta / c.T0('K')))))
     if self.phase == 'G':
         if self.inertia is not None:
             self.I3 = self.inertia
         else:
             self.I3 = atoms.get_moments_of_inertia() *\
                     c.convert_unit(from_='A2', to='m2') *\
                     c.convert_unit(from_='amu', to='kg')
         self.T_I = c.h('J s')**2 / (8 * np.pi**2 * c.kb('J/K'))
     if self.phase == 'G':
         Irot = np.max(self.I3)
         if self.geometry == 'nonlinear':
             self.q_rot = np.sqrt(np.pi*Irot)/self.symmetrynumber *\
                                 (c.T0('K')/self.T_I)**(3./2.)
         else:
             self.q_rot = (c.T0('K') * Irot /
                           self.symmetrynumber) / self.T_I
     else:
         self.q_rot = 0.
     if self.A_st is not None:
         self.MW = mw(self.elements) * c.convert_unit(from_='g',
                                                      to='kg') / c.Na
         self.q_trans2D = self.A_st * (2 * np.pi * self.MW * c.kb('J/K') *
                                       c.T0('K')) / c.h('J s')**2
Пример #3
0
    def get_SoR(self, T, P=c.P0('bar')):
        """Calculates the dimensionless entropy

        :math:`\\frac{S^{trans}}{R}=1+\\frac{n_{degrees}}{2}+\\log\\bigg(\\big(
        \\frac{2\\pi mk_bT}{h^2})^\\frac{n_{degrees}}{2}\\frac{RT}{PN_a}\\bigg)`

        Parameters
        ----------
            T : float
                Temperature in K
            P : float, optional
                Pressure (bar) or pressure-like quantity.
                Default is atmospheric pressure

        Returns
        -------
            SoR_trans : float
                Translational dimensionless entropy
        """
        V = self.get_V(T=T, P=P)
        unit_mass = self.molecular_weight *\
            c.convert_unit(from_='g', to='kg')/c.Na
        return 1. + float(self.n_degrees)/2. \
            + np.log((2.*np.pi*unit_mass*c.kb('J/K')*T/c.h('J s')**2)
                     ** (float(self.n_degrees)/2.)*V/c.Na)
Пример #4
0
    def get_GoRT(self, Ts, verbose=False):
        """Calculate dimensionless Gibbs energy at a given temperature.

        Args:
            Ts (float or numpy array): Temperature(s) in K
            verbose (bool): Flag to print each contribution to enthalpy
        Returns:
            GoRT (float or numpy array): Dimensionless heat capacity (H/RT)
        """
        try:
            iter(Ts)
        except TypeError:
            GoRT = self.model.get_helmholtz_energy(Ts, verbose) / \
                   (c.kb('eV/K') * Ts)
        else:
            GoRT = np.zeros_like(Ts)
            for i, T in enumerate(Ts):
                GoRT[i] = self.model.get_helmholtz_energy(T, verbose) / \
                          (c.kb('eV/K') * T)
        return GoRT
Пример #5
0
    def get_ZPE(self):
        """Calculates the zero point energy

        :math:`ZPE=\\frac{1}{2}h\\sum_i \\Theta_{V,i}`

        Returns
        -------
            zpe : float
                Zero point energy in eV
        """
        return 0.5 * c.kb('eV/K') * np.sum(self._vib_temperatures)
Пример #6
0
def _get_single_CvoR_vib(vib_energies, T):
    """Calculate the dimensionless vibrational heat capacity

    Parameters:
        vib_energies (array of floats): Vibrational energies in eV
        T (float): Temperatures in K
    Returns:
        CvoR_vib (float): Dimensionless vibrational heat capacity
    """
    dimensionless_vibs = vib_energies / c.kb('eV/K') / T
    CvoR_vib = np.sum((0.5 * dimensionless_vibs)**2 *
                      (1. / np.sinh(0.5 * dimensionless_vibs))**2)
    return CvoR_vib
Пример #7
0
def get_CvoR_vib(vib_energies, temperature):
    """Calculate the dimensionless vibrational heat capacity

    :math:`\\frac {Cp_{vib}}{R} = \\sum_{i=1}^{n} \\bigg(\\frac {\\Theta_{V,i}}{2T}\\bigg)^2 \\frac {1}{\\big(sinh(\\frac {\\Theta_{V,i}}{2T})\\big)^2}`

    Parameters:
        vib_energies (array of floats): Vibrational energies in eV
        temperature (float): Temperature in K
    """
    dimensionless_vibs = vib_energies / c.kb('eV/K') / temperature
    CvoR_vib = np.sum((0.5 * dimensionless_vibs)**2 *
                      (1. / np.sinh(0.5 * dimensionless_vibs))**2)
    return CvoR_vib
Пример #8
0
    def get_HoRT(self, Ts, verbose=False):
        """Calculate the dimensionless enthalpy.

        Parameters:
            Ts : float or (N,) `numpy.ndarray`_
                Temperature(s) in K
            verbose : bool
                Whether a table breaking down each contribution should be printed
        Returns
            HoRT : float or (N,) `numpy.ndarray`_
                Dimensionless heat capacity (H/RT)
        """
        try:
            iter(Ts)
        except TypeError:
            HoRT = self.model.get_enthalpy(Ts, verbose=verbose) / \
                   (c.kb('eV/K') * Ts)
        else:
            HoRT = np.zeros_like(Ts)
            for i, T in enumerate(Ts):
                HoRT[i] = self.model.get_enthalpy(T, verbose=verbose) / \
                          (c.kb('eV/K') * T)
        return HoRT
Пример #9
0
    def get_HoRT(self, temperature, verbose=False):
        """Calculate the dimensionless enthalpy.

        Parameters:
            temperature (float): Temperature in K
            verbose (bool): Print a table breaking down each contribution
        """
        if self.specie_type == 'ideal gas':
            enthalpy = self.model.get_enthalpy(temperature, verbose=verbose)
        else:
            enthalpy = self.model.get_internal_energy(temperature,
                                                      verbose=verbose)

        return enthalpy / (c.kb('eV/K') * temperature)
Пример #10
0
    def get_UoRT(self, T):
        """Calculates the imensionless internal energy

        :math:`\\frac{U^{elec}}{RT}=\\frac{E}{RT}`

        Parameters
        ----------
            T : float
                Temperature in K
        Returns
        -------
            UoRT_elec : float
                Electronic dimensionless internal energy
        """
        return self.potentialenergy / c.kb('eV/K') / T
Пример #11
0
    def get_GoRT(self, temperature, pressure=1.0, verbose=False):
        """Calculate the dimensionless Gibbs energy.

        Parameters:
            temperature (float): Temperature(s) in K
            pressure (float, optional): Pressure in atm. Default is 1 atm.
            verbose (bool): Print a table breaking down each contribution
        """
        if self.specie_type == 'ideal gas':
            G = self.model.get_gibbs_energy(
                temperature,
                pressure=pressure * c.convert_unit(from_='bar', to='Pa'),
                verbose=verbose)
        else:
            G = self.model.get_helmholtz_energy(temperature, verbose=verbose)

        return G / (c.kb('eV/K') * temperature)
Пример #12
0
    def _get_SoR_RRHO(self, T, vib_inertia):
        """Calculates the dimensionless RRHO contribution to entropy

        Parameters
        ----------
            T : float
                Temperature in K
            vib_inertia : float
                Vibrational inertia in kg m2
        Returns
        -------
            SoR_RHHO : float
                Dimensionless entropy of Rigid Rotor Harmonic Oscillator
        """
        return 0.5 + np.log(
            (8. * np.pi**3 * vib_inertia * c.kb('J/K') * T / c.h('J s')**2)**
            0.5)
Пример #13
0
    def get_A(self, T=c.T0('K'), rev=False, **kwargs):
        """Gets pre-exponential factor between reactants (or products) and 
        transition state in 1/s

        Parameters
        ----------
            rev : bool, optional
                Reverse direction. If True, uses products as initial state 
                instead of reactants. Default is False
            T : float, optional
                Temperature in K. Default is standard temperature.
            kwargs : keyword arguments
                Parameters required to calculate pre-exponential factor
        Returns
        -------
            A : float
                Pre-exponential factor  
        """
        return c.kb('J/K')*T/c.h('J s')\
               *np.exp(-self.get_SoR_act(rev=rev, T=c.T0('K'), **kwargs))
Пример #14
0
    def get_q(self, T, P=c.P0('bar')):
        """Calculates the partition function

        :math:`q_{trans} = \\bigg(\\frac{2\\pi \\sum_{i}^{atoms}m_ikT}{h^2}
        \\bigg)^\\frac {n_{degrees}} {2}V`

        Parameters
        ----------
            T : float
                Temperature in K
            P : float, optional
                Pressure (bar) or pressure-like quantity.
                Default is atmospheric pressure
        Returns
        -------
            q_trans : float
                Translational partition function
        """
        V = self.get_V(T=T, P=P)
        unit_mass = self.molecular_weight *\
            c.convert_unit(from_='g', to='kg')/c.Na
        return V*(2*np.pi*c.kb('J/K')*T*unit_mass/c.h('J s')**2) \
            ** (float(self.n_degrees)/2.)
	def test_get_CvoR_vib(self):
		#Vibrational frequencies correspond to H2O
		vib_energies = np.array([5360., 5160., 2290.]) * c.kb('eV/K')
		self.assertAlmostEqual(heat_capacity._get_single_CvoR_vib(vib_energies=vib_energies, T=300.), 0.02824711469596)
		self.assertAlmostEqual(heat_capacity.get_CvoR_vib(vib_energies=vib_energies, Ts=300.), 0.02824711469596)
		np.testing.assert_almost_equal(heat_capacity.get_CvoR_vib(vib_energies=vib_energies, Ts=np.array([300., 400., 500.])), np.array([0.02824711469596, 0.10834772440392, 0.22564243671432]))
Пример #16
0
 def test_kb(self):
     self.assertEqual(c.kb('J/K'), 1.38064852e-23)
     with self.assertRaises(KeyError):
         c.kb('arbitrary unit')