示例#1
0
    def generateThermo(self):
        """
        Generate the thermodynamic data for the species and fit it to the
        desired heat capacity model (as specified in the `thermoClass` 
        attribute).
        """
        if self.thermoClass.lower() not in ['wilhoit', 'nasa']:
            raise Exception('Unknown thermodynamic model "{0}".'.format(
                self.thermoClass))

        species = self.species

        logging.info('Generating {0} thermo model for {1}...'.format(
            self.thermoClass, species))

        Tlist = numpy.arange(10.0, 3001.0, 10.0, numpy.float64)
        Cplist = numpy.zeros_like(Tlist)
        H298 = 0.0
        S298 = 0.0
        conformer = self.species.conformer
        for i in range(Tlist.shape[0]):
            Cplist[i] += conformer.getHeatCapacity(Tlist[i])
        H298 += conformer.getEnthalpy(298.) + conformer.E0.value_si
        S298 += conformer.getEntropy(298.)

        if not any([
                isinstance(mode, (LinearRotor, NonlinearRotor))
                for mode in conformer.modes
        ]):
            # Monatomic species
            linear = False
            Nfreq = 0
            Nrotors = 0
            Cp0 = 2.5 * constants.R
            CpInf = 2.5 * constants.R
        else:
            # Polyatomic species
            linear = True if isinstance(conformer.modes[1],
                                        LinearRotor) else False
            Nfreq = len(conformer.modes[2].frequencies.value)
            Nrotors = len(conformer.modes[3:])
            Cp0 = (3.5 if linear else 4.0) * constants.R
            CpInf = Cp0 + (Nfreq + 0.5 * Nrotors) * constants.R

        wilhoit = Wilhoit()
        if Nfreq == 0 and Nrotors == 0:
            wilhoit.Cp0 = (Cplist[0], "J/(mol*K)")
            wilhoit.CpInf = (Cplist[0], "J/(mol*K)")
            wilhoit.B = (500., "K")
            wilhoit.H0 = (0.0, "J/mol")
            wilhoit.S0 = (0.0, "J/(mol*K)")
            wilhoit.H0 = (H298 - wilhoit.getEnthalpy(298.15), "J/mol")
            wilhoit.S0 = (S298 - wilhoit.getEntropy(298.15), "J/(mol*K)")
        else:
            wilhoit.fitToData(Tlist, Cplist, Cp0, CpInf, H298, S298, B0=500.0)

        if self.thermoClass.lower() == 'nasa':
            species.thermo = wilhoit.toNASA(Tmin=10.0, Tmax=3000.0, Tint=500.0)
        else:
            species.thermo = wilhoit
示例#2
0
 def setUp(self):
     """
     A function run before each unit test in this class.
     """
     self.Cp0 = 4.0
     self.CpInf = 21.5
     self.a0 = 0.0977518
     self.a1 = -16.3067
     self.a2 = 26.2524
     self.a3 = -12.6785
     self.B = 1068.68
     self.H0 = -94088. # -782.292 kJ/mol / constants.R
     self.S0 = -118.46 # -984.932 J/mol*K / constants.R
     self.Tmin = 300.
     self.Tmax = 3000.
     self.comment = 'C2H6'
     self.wilhoit = Wilhoit(
         Cp0 = (self.Cp0*constants.R,"J/(mol*K)"),
         CpInf = (self.CpInf*constants.R,"J/(mol*K)"),
         a0 = self.a0,
         a1 = self.a1,
         a2 = self.a2,
         a3 = self.a3,
         B = (self.B,"K"),
         H0 = (self.H0*0.001*constants.R,"kJ/mol"),
         S0 = (self.S0*constants.R,"J/(mol*K)"),
         Tmin = (self.Tmin,"K"),
         Tmax = (self.Tmax,"K"),
         comment = self.comment,
     )
示例#3
0
    def test_fit_to_data(self):
        """
        Test the Wilhoit.fit_to_data() method.
        """
        h298 = self.wilhoit.get_enthalpy(298)
        s298 = self.wilhoit.get_entropy(298)
        Tdata = np.array([300., 400., 500., 600., 800., 1000., 1500.])
        cp_data = np.zeros_like(Tdata)
        for i in range(Tdata.shape[0]):
            cp_data[i] = self.wilhoit.get_heat_capacity(Tdata[i])
        cp_0 = self.Cp0 * constants.R
        cp_inf = self.CpInf * constants.R

        # Fit the Wilhoit polynomial to the data
        wilhoit = Wilhoit().fit_to_data(Tdata, cp_data, cp_0, cp_inf, h298,
                                        s298)

        # Check that the fit reproduces the input data
        for T in Tdata:
            cp_exp = self.wilhoit.get_heat_capacity(T)
            cp_act = wilhoit.get_heat_capacity(T)
            self.assertAlmostEqual(cp_act, cp_exp, 4)
            h_exp = self.wilhoit.get_enthalpy(T)
            h_act = wilhoit.get_enthalpy(T)
            self.assertAlmostEqual(h_act, h_exp, 3)
            s_exp = self.wilhoit.get_entropy(T)
            s_act = wilhoit.get_entropy(T)
            self.assertAlmostEqual(s_act, s_exp, 4)

        # Check that the fit reproduces the input parameters
        # Since we're fitting to data generated from a Wilhoit (and since the
        # fitting algorithm is linear least-squares), we should get the same
        # Wilhoit parameters (with a small allowance for fitting error)
        self.assertAlmostEqual(wilhoit.Cp0.value_si, self.wilhoit.Cp0.value_si,
                               6)
        self.assertAlmostEqual(wilhoit.CpInf.value_si,
                               self.wilhoit.CpInf.value_si, 6)
        self.assertAlmostEqual(wilhoit.a0, self.wilhoit.a0, 2)
        self.assertAlmostEqual(wilhoit.a1, self.wilhoit.a1, 2)
        self.assertAlmostEqual(wilhoit.a2, self.wilhoit.a2, 2)
        self.assertAlmostEqual(wilhoit.a3, self.wilhoit.a3, 2)
        self.assertAlmostEqual(wilhoit.B.value_si, self.wilhoit.B.value_si, 2)
        self.assertAlmostEqual(wilhoit.H0.value_si, self.wilhoit.H0.value_si,
                               0)
        self.assertAlmostEqual(wilhoit.S0.value_si, self.wilhoit.S0.value_si,
                               2)
示例#4
0
    def test_fitToData(self):
        """
        Test the Wilhoit.fitToData() method.
        """
        H298 = self.wilhoit.getEnthalpy(298)
        S298 = self.wilhoit.getEntropy(298)
        Tdata = numpy.array([300., 400., 500., 600., 800., 1000., 1500.])
        Cpdata = numpy.zeros_like(Tdata)
        for i in range(Tdata.shape[0]):
            Cpdata[i] = self.wilhoit.getHeatCapacity(Tdata[i])
        Cp0 = self.Cp0 * constants.R
        CpInf = self.CpInf * constants.R

        # Fit the Wilhoit polynomial to the data
        wilhoit = Wilhoit().fitToData(Tdata, Cpdata, Cp0, CpInf, H298, S298)

        # Check that the fit reproduces the input data
        for T in Tdata:
            Cpexp = self.wilhoit.getHeatCapacity(T)
            Cpact = wilhoit.getHeatCapacity(T)
            self.assertAlmostEqual(Cpact, Cpexp, 4)
            Hexp = self.wilhoit.getEnthalpy(T)
            Hact = wilhoit.getEnthalpy(T)
            self.assertAlmostEqual(Hact, Hexp, 3)
            Sexp = self.wilhoit.getEntropy(T)
            Sact = wilhoit.getEntropy(T)
            self.assertAlmostEqual(Sact, Sexp, 4)

        # Check that the fit reproduces the input parameters
        # Since we're fitting to data generated from a Wilhoit (and since the
        # fitting algorithm is linear least-squares), we should get the same
        # Wilhoit parameters (with a small allowance for fitting error)
        self.assertAlmostEqual(wilhoit.Cp0.value_si, self.wilhoit.Cp0.value_si,
                               6)
        self.assertAlmostEqual(wilhoit.CpInf.value_si,
                               self.wilhoit.CpInf.value_si, 6)
        self.assertAlmostEqual(wilhoit.a0, self.wilhoit.a0, 2)
        self.assertAlmostEqual(wilhoit.a1, self.wilhoit.a1, 2)
        self.assertAlmostEqual(wilhoit.a2, self.wilhoit.a2, 2)
        self.assertAlmostEqual(wilhoit.a3, self.wilhoit.a3, 2)
        self.assertAlmostEqual(wilhoit.B.value_si, self.wilhoit.B.value_si, 2)
        self.assertAlmostEqual(wilhoit.H0.value_si, self.wilhoit.H0.value_si,
                               0)
        self.assertAlmostEqual(wilhoit.S0.value_si, self.wilhoit.S0.value_si,
                               2)
示例#5
0
    def generate_thermo(self):
        """
        Generate the thermodynamic data for the species and fit it to the
        desired heat capacity model (as specified in the `thermo_class`
        attribute).
        """
        if self.thermo_class.lower() not in ['wilhoit', 'nasa']:
            raise InputError('Unknown thermodynamic model "{0}".'.format(
                self.thermo_class))

        species = self.species

        logging.debug('Generating {0} thermo model for {1}...'.format(
            self.thermo_class, species))

        if species.thermo is not None:
            logging.info(
                "Thermo already generated for species {}. Skipping thermo generation."
                .format(species))
            return None

        Tlist = np.arange(10.0, 3001.0, 10.0, np.float64)
        Cplist = np.zeros_like(Tlist)
        H298 = 0.0
        S298 = 0.0
        conformer = self.species.conformer
        for i in range(Tlist.shape[0]):
            Cplist[i] += conformer.get_heat_capacity(Tlist[i])
        H298 += conformer.get_enthalpy(298.) + conformer.E0.value_si
        S298 += conformer.get_entropy(298.)

        if not any([
                isinstance(mode, (LinearRotor, NonlinearRotor))
                for mode in conformer.modes
        ]):
            # Monatomic species
            n_freq = 0
            n_rotors = 0
            Cp0 = 2.5 * constants.R
            CpInf = 2.5 * constants.R
        else:
            # Polyatomic species
            linear = True if isinstance(conformer.modes[1],
                                        LinearRotor) else False
            n_freq = len(conformer.modes[2].frequencies.value)
            n_rotors = len(conformer.modes[3:])
            Cp0 = (3.5 if linear else 4.0) * constants.R
            CpInf = Cp0 + (n_freq + 0.5 * n_rotors) * constants.R

        wilhoit = Wilhoit()
        if n_freq == 0 and n_rotors == 0:
            wilhoit.Cp0 = (Cplist[0], "J/(mol*K)")
            wilhoit.CpInf = (Cplist[0], "J/(mol*K)")
            wilhoit.B = (500., "K")
            wilhoit.H0 = (0.0, "J/mol")
            wilhoit.S0 = (0.0, "J/(mol*K)")
            wilhoit.H0 = (H298 - wilhoit.get_enthalpy(298.15), "J/mol")
            wilhoit.S0 = (S298 - wilhoit.get_entropy(298.15), "J/(mol*K)")
        else:
            wilhoit.fit_to_data(Tlist,
                                Cplist,
                                Cp0,
                                CpInf,
                                H298,
                                S298,
                                B0=500.0)

        if self.thermo_class.lower() == 'nasa':
            species.thermo = wilhoit.to_nasa(Tmin=10.0,
                                             Tmax=3000.0,
                                             Tint=500.0)
        else:
            species.thermo = wilhoit
elementCounts = {'C': 6, 'H': 5, 'I': 1}

Tlist = numpy.array([300.0,400.0,500.0,600.0,800.0,1000.0])
Cplist = numpy.array([24.2, 31.1, 36.9, 41.4, 48, 52.55])*4.184 #J/mol*K
H298 = 40.5*4184 #J/mol
S298 = 81.35*4.184 #J/mol*K

# Polyatomic species
linear = False
Nfreq = 30
Nrotors = 0
Cp0 = (3.5 if linear else 4.0) * constants.R
CpInf = Cp0 + (Nfreq + 0.5 * Nrotors) * constants.R

wilhoit = Wilhoit()

wilhoit.fitToData(Tlist, Cplist, Cp0, CpInf, H298, S298, B0=500.0)\

NASA_fit = wilhoit.toNASA(Tlist[0], Tlist[-1], Tint=500.0)

string = ''

f = open('chem.inp', 'a')

# Line 1
string += '{0:<16}        '.format(SpeciesIdentifier)
if len(elementCounts) <= 4:
    # Use the original Chemkin syntax for the element counts
    for key, count in elementCounts.iteritems():
        if isinstance(key, tuple):