示例#1
0
文件: trans.py 项目: wittregr/pMuTT
    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(initial='g', final='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)
示例#2
0
    def get_Vm(self, T=c.T0('K'), P=c.P0('bar'), gas_phase=True):
        """Calculates the molar volume of a van der Waals gas

        Parameters
        ----------
            T : float, optional
                Temperature in K. Default is standard temperature
            P : float, optional
                Pressure in bar. Default is standard pressure
            gas_phase : bool, optional
                Relevant if system is in vapor-liquid equilibrium. If True,
                return the larger volume (gas phase). If False, returns the
                smaller volume (liquid phase).
        Returns
        -------
            Vm : float
                Volume in m3
        """
        P_SI = P * c.convert_unit(initial='bar', final='Pa')
        Vm = np.roots([
            P_SI, -(P_SI * self.b + c.R('J/mol/K') * T), self.a,
            -self.a * self.b
        ])
        real_Vm = np.real([Vm_i for Vm_i in Vm if np.isreal(Vm_i)])
        if gas_phase:
            return np.max(real_Vm)
        else:
            return np.min(real_Vm)
示例#3
0
 def test_P0(self):
     # Test P0 for all units
     self.assertAlmostEqual(c.P0('bar'), self.ans.at['test_P0', 0])
     self.assertAlmostEqual(c.P0('atm'), self.ans.at['test_P0', 1])
     self.assertAlmostEqual(c.P0('Pa'), self.ans.at['test_P0', 2])
     self.assertAlmostEqual(c.P0('kPa'), self.ans.at['test_P0', 3])
     self.assertAlmostEqual(c.P0('MPa'), self.ans.at['test_P0', 4])
     self.assertAlmostEqual(c.P0('psi'), self.ans.at['test_P0', 5])
     self.assertAlmostEqual(c.P0('mmHg'), self.ans.at['test_P0', 6])
     self.assertAlmostEqual(c.P0('torr'), self.ans.at['test_P0', 7])
     # Test P0 raises an error when an unsupported unit is passed
     with self.assertRaises(ValueError):
         c.P0('arbitrary unit')
示例#4
0
    def setUp(self):
        unittest.TestCase.setUp(self)
        # Testing Ideal Gas Model
        CO2 = molecule('CO2')
        CO2_pmutt_parameters = {
            'name':
            'CO2',
            'elements': {
                'C': 1,
                'O': 2
            },
            'trans_model':
            trans.FreeTrans,
            'n_degrees':
            3,
            'molecular_weight':
            get_molecular_weight('CO2'),
            'rot_model':
            rot.RigidRotor,
            'rot_temperatures':
            rot.get_rot_temperatures_from_atoms(CO2, geometry='linear'),
            'geometry':
            'linear',
            'symmetrynumber':
            2,
            'elec_model':
            elec.GroundStateElec,
            'potentialenergy':
            -22.994202,
            'spin':
            0.,
            'vib_model':
            vib.HarmonicVib,
            'vib_wavenumbers': [3360., 954., 954., 1890.],
        }
        CO2_ase_parameters = {
            'atoms':
            CO2,
            'potentialenergy':
            -22.994202,
            'vib_energies': [
                c.wavenumber_to_energy(x) *
                c.convert_unit(initial='J', final='eV')
                for x in CO2_pmutt_parameters['vib_wavenumbers']
            ],
            'geometry':
            'linear',
            'symmetrynumber':
            2,
            'spin':
            0.
        }
        self.CO2_pmutt = StatMech(**CO2_pmutt_parameters)
        self.CO2_ASE = IdealGasThermo(**CO2_ase_parameters)

        self.T0 = c.T0('K')  # K
        self.P0 = c.P0('Pa')
        self.V0 = c.V0('m3')
        self.mw = get_molecular_weight({'C': 1, 'O': 2})
示例#5
0
文件: __init__.py 项目: alongd/pMuTT
    def get_SoR(self, P=c.P0('bar')):
        """Calculates dimesionless entropy

        :math:`\\frac{S}{R} = -\\ln\\bigg(\\frac{P}{P_0}\\bigg)`

        Parameters
        ----------
            P : float or `numpy.ndarray`_, optional
                Pressure in bar. Default is P0 (1 bar)
        Returns
        -------
            SoR : float or `numpy.ndarray`_
                Dimensionless adjustment to entropy

        .. _`numpy.ndarray`: https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html
        """
        return -np.log(P)
示例#6
0
    def get_n(self, V=c.V0('m3'), P=c.P0('bar'), T=c.T0('K')):
        """Calculates the moles of an ideal gas

        Parameters
        ----------
            V : float, optional
                Volume in m3. Default is standard volume
            P : float, optional
                Pressure in bar. Default is standard pressure
            T : float, optional
                Temperature in K. Default is standard temperature
        Returns
        -------
            n : float
                Number of moles in mol
        """
        return P * V / c.R('m3 bar/mol/K') / T
示例#7
0
    def get_T(self, V=c.V0('m3'), P=c.P0('bar'), n=1.):
        """Calculates the temperature of an ideal gas

        Parameters
        ----------
            V : float, optional
                Volume in m3. Default is standard volume
            P : float, optional
                Pressure in bar. Default is standard pressure
            n : float, optional
                Number of moles (in mol). Default is 1 mol
        Returns
        -------
            T : float
                Temperature in K
        """
        return P * V / c.R('m3 bar/mol/K') / n
示例#8
0
    def get_V(self, T=c.T0('K'), P=c.P0('bar'), n=1.):
        """Calculates the volume of an ideal gas

        Parameters
        ----------
            T : float, optional
                Temperature in K. Default is standard temperature
            P : float, optional
                Pressure in bar. Default is standard pressure
            n : float, optional
                Number of moles (in mol). Default is 1 mol
        Returns
        -------
            V : float
                Volume in m3
        """
        return n * c.R('m3 bar/mol/K') * T / P
示例#9
0
文件: trans.py 项目: wittregr/pMuTT
    def get_GoRT(self, T, P=c.P0('bar')):
        """Calculates the dimensionless Gibbs energy

        :math:`\\frac{G^{trans}}{RT}=\\frac{H^{trans}}{RT}-\\frac{S^{trans}}{R}`       

        Parameters
        ----------
            T : float
                Temperature in K
            P : float, optional
                Pressure (bar) or pressure-like quantity.
                Default is atmospheric pressure
        Returns
        -------
            GoR_trans : float
                Translational dimensionless Gibbs energy
        """
        return self.get_HoRT() - self.get_SoR(T=T, P=P)
示例#10
0
    def get_T(self, V=c.V0('m3'), P=c.P0('bar'), n=1.):
        """Calculates the temperature of a van der Waals gas

        Parameters
        ----------
            V : float, optional
                Volume in m3. Default is standard volume
            P : float, optional
                Pressure in bar. Default is standard pressure
            n : float, optional
                Number of moles (in mol). Default is 1 mol
        Returns
        -------
            T : float
                Temperature in K
        """
        Vm = V / n
        return (P*c.convert_unit(initial='bar', final='Pa') + self.a/Vm**2) \
            * (Vm - self.b)/c.R('J/mol/K')
示例#11
0
    def get_n(self, V=c.V0('m3'), P=c.P0('bar'), T=c.T0('K'), gas_phase=True):
        """Calculates the moles of a van der Waals gas

        Parameters
        ----------
            V : float, optional
                Volume in m3. Default is standard volume
            P : float, optional
                Pressure in bar. Default is standard pressure
            T : float, optional
                Temperature in K. Default is standard temperature
            gas_phase : bool, optional
                Relevant if system is in vapor-liquid equilibrium. If True,
                return the smaller moles (gas phase). If False, returns the
                larger moles (liquid phase).
        Returns
        -------
            n : float
                Number of moles in mol
        """
        return V / self.get_Vm(T=T, P=P, gas_phase=gas_phase)
示例#12
0
    def get_V(self, T=c.T0('K'), P=c.P0('bar'), n=1., gas_phase=True):
        """Calculates the volume of a van der Waals gas

        Parameters
        ----------
            T : float, optional
                Temperature in K. Default is standard temperature
            P : float, optional
                Pressure in bar. Default is standard pressure
            n : float, optional
                Number of moles (in mol). Default is 1 mol
            gas_phase : bool, optional
                Relevant if system is in vapor-liquid equilibrium. If True,
                return the larger volume (gas phase). If False, returns the
                smaller volume (liquid phase).
        Returns
        -------
            V : float
                Volume in m3
        """
        return self.get_Vm(T=T, P=P, gas_phase=gas_phase) * n
示例#13
0
文件: trans.py 项目: wittregr/pMuTT
    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(initial='g', final='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.)
示例#14
0
    def to_CTI(self,
               T=c.T0('K'),
               P=c.P0('bar'),
               quantity_unit='molec',
               length_unit='cm',
               act_energy_unit='cal/mol',
               units=None):
        """Writes the object in Cantera's CTI format.

        Parameters
        ----------
            T : float, optional
                Temperature in K. Default is 298.15 K
            P : float, optional
                Pressure in bar. Default is 1 bar
            quantity_unit : str, optional
                Quantity unit to calculate A. Default is 'molec'
            length_unit : str, optional
                Length unit to calculate A. Default is 'cm'
            act_energy_unit : str, optional
                Unit to use for activation energy. Default is 'cal/mol'
            units : :class:`~pmutt.omkm.units.Units` object
                If specified, `quantity_unit`, `length_unit`, and
                `act_energy_unit` are overwritten. Default is None.
        Returns
        -------
            cti_str : str
                Surface reaction string in CTI format
        """
        if units is not None:
            quantity_unit = units.quantity
            length_unit = units.length
            act_energy_unit = units.act_energy

        reaction_str = self.to_string(stoich_space=True,
                                      species_delimiter=' + ',
                                      reaction_delimiter=' <=> ',\
                                      include_TS=False)
        # Determine the reaction IDs
        try:
            id = self.id
        except AttributeError:
            id_str = ''
        else:
            if id is None:
                id_str = ''
            else:
                id_str = ',\n                 id="{}"'.format(self.id)

        if self.is_adsorption:
            G_act = self.get_G_act(units=act_energy_unit, T=T, P=P)
            cti_str = ('surface_reaction("{}",\n'
                       '                 stick({: .5e}, {}, {: .5e}){})'
                       ''.format(reaction_str, self.sticking_coeff, self.beta,
                                 G_act, id_str))
        else:
            A_units = '{}/{}2'.format(quantity_unit, length_unit)
            cti_str = ('surface_reaction("{}",\n'
                       '                 [{: .5e}, {}, {: .5e}]{})'.format(
                           reaction_str,
                           self.get_A(T=T,
                                      P=P,
                                      include_entropy=False,
                                      units=A_units), self.beta,
                           self.get_G_act(units=act_energy_unit, T=T, P=P),
                           id_str))
        return cti_str
示例#15
0
 def test_P0(self):
     self.assertEqual(c.P0('bar'), 1.)
     with self.assertRaises(ValueError):
         c.P0('arbitrary unit')
示例#16
0
    def to_omkm_yaml(self,
                     T=c.T0('K'),
                     P=c.P0('bar'),
                     quantity_unit='molec',
                     length_unit='cm',
                     act_energy_unit='cal/mol',
                     ads_act_method='get_H_act',
                     units=None):
        """Writes the object in Cantera's YAML format.

        Parameters
        ----------
            T : float, optional
                Temperature in K. Default is 298.15 K
            P : float, optional
                Pressure in bar. Default is 1 bar
            quantity_unit : str, optional
                Quantity unit to calculate A. Default is 'molec'
            length_unit : str, optional
                Length unit to calculate A. Default is 'cm'
            act_energy_unit : str, optional
                Unit to use for activation energy. Default is 'cal/mol'
            ads_act_method : str, optional
                Activation method to use for adsorption reactions. Accepted 
                options include 'get_H_act' and 'get_G_act'. Default is
                'get_H_act'.
            units : :class:`~pmutt.omkm.units.Units` object
                If specified, `quantity_unit`, `length_unit`, and
                `act_energy_unit` are overwritten. Default is None.
        Returns
        -------
            yaml_dict : dict
                Dictionary compatible with Cantera's YAML format
        """
        if units is not None:
            quantity_unit = units.quantity
            length_unit = units.length
            act_energy_unit = units.act_energy

        yaml_dict = {}
        # Assign reaction name
        yaml_dict['equation'] = self.to_string(stoich_space=True,
                                               species_delimiter=' + ',
                                               reaction_delimiter=' <=> ',\
                                               include_TS=False)
        
        if self.is_adsorption:
            rate_constant_name = 'sticking-coefficient'
            # Pre-exponential
            A_param = _Param('A', self.sticking_coeff, None)

            # Activation energy
            act_method = getattr(self, ads_act_method)
            act_val = act_method(units=act_energy_unit, T=T, P=P)

            # Sticking-species
            for species in self.reactants:
                # Look for gas phase species
                if isinstance(species.phase, IdealGas) \
                   or species.phase.lower() == 'g' \
                   or species.phase.lower() == 'gas':
                    yaml_dict['sticking-species'] = species.name
                    break
            else:
                err_msg = ('Could not find gas reactant in reaction, {}. '
                           'One species must have its phase attribute set to '
                           '"g" or "gas".'
                           ''.format(str(self)))
                raise ValueError(err_msg)
            # Motz-Wise correction
            yaml_dict['Motz-Wise'] = self.use_motz_wise
        else:
            rate_constant_name = 'rate-constant'
            # Pre-exponential
            A_units = '{}/{}2'.format(quantity_unit, length_unit)
            A = float(self.get_A(T=T, P=P, include_entropy=False, units=A_units))
            # TODO Check units for A. Should have time dependence.
            A_param = _Param('A', A, None)
            # Activation energy
            act_val = self.get_G_act(units=act_energy_unit, T=T, P=P)

        # Assign activation energy, beta and pre-exponential factor
        rate_constant_dict = {}
        _assign_yaml_val(A_param, rate_constant_dict, units)
        rate_constant_dict['b'] = self.beta
        act_param = _Param('Ea', act_val, '_act_energy')
        _assign_yaml_val(act_param, rate_constant_dict, units)
        # Add kinetic parameters to overall dictionary
        yaml_dict[rate_constant_name] = rate_constant_dict

        # Assign reaction ID
        try:
            yaml_dict['id'] = self.id
        except AttributeError:
            pass

        return yaml_dict