예제 #1
0
 def test_get_delta_AoRT(self):
     exp_sm_AoRT = self.H2O_sm.get_AoRT(T=c.T0('K')) \
                   - self.H2_sm.get_AoRT(T=c.T0('K')) \
                   - self.O2_sm.get_AoRT(T=c.T0('K'))*0.5
     self.assertAlmostEqual(self.rxn_sm.get_delta_AoRT(T=c.T0('K')),
                            exp_sm_AoRT)
     self.assertAlmostEqual(
         self.rxn_sm.get_delta_AoRT(T=c.T0('K'), rev=True), -exp_sm_AoRT)
예제 #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 setUp(self):
        unittest.TestCase.setUp(self)
        H2_thermo = BaseThermo(name='H2',
                               phase='G',
                               elements={'H': 2},
                               thermo_model=IdealGasThermo,
                               T_ref=c.T0('K'),
                               HoRT_ref=0.,
                               vib_energies=np.array([4306.1793]) *
                               c.c('cm/s') * c.h('eV s'),
                               potentialenergy=-6.7598,
                               geometry='linear',
                               symmetrynumber=2,
                               spin=0,
                               atoms=molecule('H2'))

        H2O_thermo = BaseThermo(
            name='H2O',
            phase='G',
            elements={
                'H': 2,
                'O': 1
            },
            thermo_model=IdealGasThermo,
            T_ref=c.T0('K'),
            HoRT_ref=-241.826 / (c.R('kJ/mol/K') * c.T0('K')),
            vib_energies=np.array([3825.434, 3710.264, 1582.432]) *
            c.c('cm/s') * c.h('eV s'),
            potentialenergy=-14.2209,
            geometry='nonlinear',
            symmetrynumber=2,
            spin=0,
            atoms=molecule('H2O'))

        O2_thermo = BaseThermo(name='H2O',
                               phase='G',
                               elements={'O': 2},
                               thermo_model=IdealGasThermo,
                               T_ref=c.T0('K'),
                               HoRT_ref=0.,
                               vib_energies=np.array([2205.]) * c.c('cm/s') *
                               c.h('eV s'),
                               potentialenergy=-9.86,
                               geometry='linear',
                               symmetrynumber=2,
                               spin=1,
                               atoms=molecule('O2'))
        self.references = References(
            references=[H2_thermo, H2O_thermo, O2_thermo])
예제 #4
0
 def test_get_delta_SoR(self):
     exp_nasa_SoR = self.H2O_nasa.get_SoR(T=c.T0('K')) \
                   - self.H2_nasa.get_SoR(T=c.T0('K')) \
                   - self.O2_nasa.get_SoR(T=c.T0('K'))*0.5
     exp_sm_SoR = self.H2O_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
     self.assertAlmostEqual(self.rxn_nasa.get_delta_SoR(T=c.T0('K')),
                            exp_nasa_SoR)
     self.assertAlmostEqual(
         self.rxn_nasa.get_delta_SoR(T=c.T0('K'), rev=True), -exp_nasa_SoR)
     self.assertAlmostEqual(self.rxn_sm.get_delta_SoR(T=c.T0('K')),
                            exp_sm_SoR)
     self.assertAlmostEqual(
         self.rxn_sm.get_delta_SoR(T=c.T0('K'), rev=True), -exp_sm_SoR)
예제 #5
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)
예제 #6
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(from_='bar', to='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)
예제 #7
0
파일: reaction.py 프로젝트: jtfrey/PyMuTT
    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))
예제 #8
0
 def test_get_CpoR_act(self):
     exp_sm_CpoR = self.H2O_TS_sm.get_CpoR(T=c.T0('K')) \
                   - self.H2_sm.get_CpoR(T=c.T0('K')) \
                   - self.O2_sm.get_CpoR(T=c.T0('K'))*0.5
     exp_sm_CpoR_rev = self.H2O_TS_sm.get_CpoR(T=c.T0('K')) \
                       - self.H2O_sm.get_CpoR(T=c.T0('K'))
     self.assertAlmostEqual(self.rxn_sm.get_CpoR_act(T=c.T0('K')),
                            exp_sm_CpoR)
     self.assertAlmostEqual(self.rxn_sm.get_CpoR_act(T=c.T0('K'), rev=True),
                            exp_sm_CpoR_rev)
예제 #9
0
 def test_get_GoRT_act(self):
     exp_sm_GoRT = self.H2O_TS_sm.get_GoRT(T=c.T0('K')) \
                   - self.H2_sm.get_GoRT(T=c.T0('K')) \
                   - self.O2_sm.get_GoRT(T=c.T0('K'))*0.5
     exp_sm_GoRT_rev = self.H2O_TS_sm.get_GoRT(T=c.T0('K')) \
                       - self.H2O_sm.get_GoRT(T=c.T0('K'))
     self.assertAlmostEqual(self.rxn_sm.get_GoRT_act(T=c.T0('K')),
                            exp_sm_GoRT)
     self.assertAlmostEqual(self.rxn_sm.get_GoRT_act(T=c.T0('K'), rev=True),
                            exp_sm_GoRT_rev)
예제 #10
0
    def __init__(self,
                 T_low,
                 T_mid,
                 T_high,
                 T_ref=c.T0('K'),
                 HoRT_ref=None,
                 SoR_ref=None,
                 **kwargs):
        super().__init__(T_ref=T_ref, HoRT_ref=HoRT_ref, **kwargs)

        self.T_low = T_low
        self.T_high = T_high
        self.T_mid = T_mid

        self.fit(HoRT_dft=HoRT_ref, SoR_ref=SoR_ref)
예제 #11
0
    def get_n(self, V=c.V0('m3'), P=c.P0('bar'), T=c.T0('K')):
        """Calculates the volume 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
예제 #12
0
    def get_P(self, T=c.T0('K'), V=c.V0('m3'), n=1.):
        """Calculates the pressure of an ideal gas

        Parameters
        ----------
            T : float, optional
                Temperature in K. Default is standard temperature
            V : float, optional
                Volume in m3. Default is standard volume
            n : float, optional
                Number of moles (in mol). Default is 1 mol
        Returns
        -------
            P : float
                Pressure in bar
        """
        return n * c.R('m3 bar/mol/K') * T / V
예제 #13
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
예제 #14
0
    def setUp(self):
        unittest.TestCase.setUp(self)
        # Testing Ideal Gas Model
        CO2 = molecule('CO2')
        CO2_PyMuTT_parameters = {
            'trans_model':
            trans.IdealTrans,
            '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.IdealElec,
            '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) \
                for x in CO2_PyMuTT_parameters['vib_wavenumbers']],
            'geometry':'linear',
            'symmetrynumber': 2,
            'spin': 0.
        }
        self.CO2_PyMuTT = StatMech(**CO2_PyMuTT_parameters)
        self.CO2_ASE = IdealGasThermo(**CO2_ase_parameters)

        self.T0 = c.T0('K')  # K
        self.P0 = c.P0('Pa')
        self.V0 = c.V0('m3')
예제 #15
0
    def get_P(self, T=c.T0('K'), V=c.V0('m3'), n=1.):
        """Calculates the pressure of a van der Waals gas

        Parameters
        ----------
            T : float, optional
                Temperature in K. Default is standard temperature
            V : float, optional
                Volume in m3. Default is standard volume
            n : float, optional
                Number of moles (in mol). Default is 1 mol
        Returns
        -------
            P : float
                Pressure in bar
        """
        Vm = V / n
        return (c.R('J/mol/K')*T/(Vm - self.b) - self.a*(1./Vm)**2) \
               *c.convert_unit(from_='Pa', to='bar')
예제 #16
0
파일: nasa.py 프로젝트: mbkumar/PyMuTT
    def __init__(self,
                 T_low=None,
                 T_mid=None,
                 T_high=None,
                 a_low=np.zeros(7),
                 a_high=np.zeros(7),
                 Ts=None,
                 CpoR=None,
                 T_ref=c.T0('K'),
                 HoRT_ref=None,
                 SoR_ref=None,
                 **kwargs):
        super().__init__(T_ref=T_ref, HoRT_ref=HoRT_ref, **kwargs)
        self.a_low = a_low
        self.a_high = a_high

        if T_low is not None:
            self.T_low = T_low
        else:
            try:
                self.T_low = np.min(Ts)
            except NameError:
                pass

        if T_high is not None:
            self.T_high = T_high
        else:
            try:
                self.T_high = np.max(Ts)
            except NameError:
                pass

        self.T_mid = T_mid

        if np.array_equal(a_low, np.zeros(7)) and np.array_equal(
                a_high, np.zeros(7)):
            self.fit(T_low=self.T_low,
                     T_high=self.T_high,
                     Ts=Ts,
                     CpoR=CpoR,
                     T_ref=T_ref,
                     HoRT_dft=HoRT_ref,
                     SoR_ref=SoR_ref)
예제 #17
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
예제 #18
0
    def get_n(self, V=c.V0('m3'), P=c.P0('bar'), T=c.T0('K'), gas_phase=True):
        """Calculates the volume 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)
예제 #19
0
    def __init__(self,
                 name,
                 phase=None,
                 elements=None,
                 thermo_model=None,
                 T_ref=c.T0('K'),
                 HoRT_dft=None,
                 HoRT_ref=None,
                 references=None,
                 notes=None,
                 **kwargs):
        self.name = name
        self.phase = phase
        self.elements = elements
        self.T_ref = T_ref
        self.references = references
        self.notes = notes

        #Assign self.thermo_model
        if inspect.isclass(thermo_model):
            #If class is passed, the required arguments will be guessed.
            self.thermo_model = _pass_expected_arguments(
                thermo_model, **kwargs)
        else:
            self.thermo_model = thermo_model

        #Calculate dimensionless DFT energy using thermo model
        if (HoRT_dft is None) and (self.thermo_model is not None):
            self.HoRT_dft = self.thermo_model.get_HoRT(Ts=self.T_ref)
        else:
            self.HoRT_dft = HoRT_dft

        if HoRT_ref is None:  #Assign self.HoRT_ref
            if (references is None) or (self.HoRT_dft is None):
                self.HoRT_ref = self.HoRT_dft
            else:
                self.HoRT_ref = self.HoRT_dft + references.get_HoRT_offset(
                    elements=elements, Ts=self.T_ref)
        else:
            self.HoRT_ref = HoRT_ref
예제 #20
0
'''
#Import from excel
refs_input = read_excel(io=refs_path)
refs = References([BaseThermo(**ref_input) for ref_input in refs_input])
print('Reference Input:')
pprint(refs_input)
'''
Processing Input Species
'''
#Import from excel
species_data = read_excel(io=species_path)
species = [
    Nasa(references=refs,
         T_low=T_low,
         T_high=T_high,
         T_ref=c.T0('K'),
         **specie_data) for specie_data in species_data
]
print('Species Input:')
pprint(species)
'''
Printing Out Results
'''
write_thermdat(nasa_species=species,
               filename=thermdat_path,
               write_date=write_date)
if show_plot:
    for specie in species:
        specie.plot_thermo_model_and_empirical(Cp_units='J/mol/K',
                                               H_units='kJ/mol',
                                               S_units='J/mol/K',
예제 #21
0
파일: nasa.py 프로젝트: jtfrey/PyMuTT
    def from_statmech(cls,
                      name,
                      statmech_model,
                      T_low,
                      T_high,
                      T_mid=None,
                      references=None,
                      elements=None,
                      **kwargs):
        """Calculates the NASA polynomials using statistical mechanic models

        Parameters
        ----------
            name : str
                Name of the species
            statmech_model : `PyMuTT.models.statmech.StatMech` object or class
                Statistical Mechanics model to generate data
            T_low : float
                Lower limit temerature in K
            T_high : float
                Higher limit temperature in K
            T_mid : float or iterable of float, optional
                Guess for T_mid. If float, only uses that value for T_mid. If 
                list, finds the best fit for each element in the list. If None, 
                a range of T_mid values are screened between the 6th lowest 
                and 6th highest value of T.
            references : `PyMuTT.models.empirical.references.References` object
                Reference to adjust enthalpy
            elements : dict
                Composition of the species.
                Keys of dictionary are elements, values are stoichiometric values
                in a formula unit.
                e.g. CH3OH can be represented as:
                {'C': 1, 'H': 4, 'O': 1,}.                
            **kwargs : keyword arguments
                Used to initalize ``statmech_model`` or ``BaseThermo`` 
                attributes to be stored.
        Returns
        -------
            Nasa : Nasa object
                Nasa object with polynomial terms fitted to data.
        """
        # Initialize the StatMech object
        if inspect.isclass(statmech_model):
            statmech_model = statmech_model(**kwargs)

        # Generate data
        T = np.linspace(T_low, T_high)
        if T_mid is not None:
            # Check to see if specified T_mid's are in T and, if not,
            # insert them into T.
            # If a single value for T_mid is chosen, convert to a tuple
            try:
                iter(T_mid)
            except TypeError:
                T_mid = (T_mid, )
            for x in range(0, len(T_mid)):
                if np.where(T == T_mid[x])[0].size == 0:
                    # Insert T_mid's into T and save position
                    Ts_index = np.where(T > T_mid[x])[0][0]
                    T = np.insert(T, Ts_index, T_mid[x])
        CpoR = np.array([statmech_model.get_CpoR(T=T_i) for T_i in T])
        T_ref = c.T0('K')
        HoRT_ref = statmech_model.get_HoRT(T=T_ref)
        # Add contribution of references
        if references is not None:
            HoRT_ref += references.get_HoRT_offset(elements=elements, T=T_ref)
        SoR_ref = statmech_model.get_SoR(T=T_ref)

        return cls.from_data(name=name,
                             T=T,
                             CpoR=CpoR,
                             T_ref=T_ref,
                             HoRT_ref=HoRT_ref,
                             SoR_ref=SoR_ref,
                             T_mid=T_mid,
                             statmech_model=statmech_model,
                             elements=elements,
                             references=references,
                             **kwargs)
예제 #22
0
 def test_get_n(self):
     self.assertAlmostEqual(
         self.ideal_gas.get_n(T=c.T0('K'), V=c.V0('m3'), P=c.P0('bar')), 1.)
예제 #23
0
 def test_get_P(self):
     self.assertAlmostEqual(
         self.ideal_gas.get_P(T=c.T0('K'), V=c.V0('m3'), n=1.), c.P0('bar'))
    def setUp(self):
        unittest.TestCase.setUp(self)

        H2_thermo = Reference(name='H2',
                              phase='G',
                              elements={'H': 2},
                              T_ref=c.T0('K'),
                              HoRT_ref=0.,
                              statmech_model=StatMech,
                              trans_model=trans.IdealTrans,
                              n_degrees=3,
                              vib_model=vib.HarmonicVib,
                              elec_model=elec.IdealElec,
                              rot_model=rot.RigidRotor,
                              vib_wavenumbers=np.array([4306.1793]),
                              potentialenergy=-6.7598,
                              geometry='linear',
                              symmetrynumber=2,
                              spin=0,
                              atoms=molecule('H2'))

        H2O_thermo = Reference(
            name='H2O',
            phase='G',
            elements={
                'H': 2,
                'O': 1
            },
            T_ref=c.T0('K'),
            HoRT_ref=-241.826 / (c.R('kJ/mol/K') * c.T0('K')),
            statmech_model=StatMech,
            trans_model=trans.IdealTrans,
            n_degrees=3,
            vib_model=vib.HarmonicVib,
            elec_model=elec.IdealElec,
            rot_model=rot.RigidRotor,
            vib_wavenumbers=np.array([3825.434, 3710.264, 1582.432]),
            potentialenergy=-14.2209,
            geometry='nonlinear',
            symmetrynumber=2,
            spin=0,
            atoms=molecule('H2O'))

        O2_thermo = Reference(name='H2O',
                              phase='G',
                              elements={'O': 2},
                              T_ref=c.T0('K'),
                              HoRT_ref=0.,
                              statmech_model=StatMech,
                              trans_model=trans.IdealTrans,
                              n_degrees=3,
                              vib_model=vib.HarmonicVib,
                              elec_model=elec.IdealElec,
                              rot_model=rot.RigidRotor,
                              vib_wavenumbers=np.array([2205.]),
                              potentialenergy=-9.86,
                              geometry='linear',
                              symmetrynumber=2,
                              spin=1,
                              atoms=molecule('O2'))
        self.references = References(
            references=[H2_thermo, H2O_thermo, O2_thermo])
예제 #25
0
 def test_T0(self):
     self.assertEqual(c.T0('K'), 298.15)
     with self.assertRaises(KeyError):
         c.T0('arbitrary unit')