def setUp(self): """This method is run once before each test.""" coeffs_low = [ 4.03055, -0.00214171, 4.90611e-05, -5.99027e-08, 2.38945e-11, -11257.6, 3.5613 ] coeffs_high = [ -0.307954, 0.0245269, -1.2413e-05, 3.07724e-09, -3.01467e-13, -10693, 22.628 ] Tmin = 300. Tmax = 3000. Tint = 650.73 E0 = -782292. # J/mol. comment = "C2H6" self.nasa = NASA( polynomials=[ NASAPolynomial(coeffs=coeffs_low, Tmin=(Tmin, "K"), Tmax=(Tint, "K")), NASAPolynomial(coeffs=coeffs_high, Tmin=(Tint, "K"), Tmax=(Tmax, "K")), ], Tmin=(Tmin, "K"), Tmax=(Tmax, "K"), E0=(E0, "J/mol"), comment=comment, ) # Chemkin entries for testing - note that the values are all the same self.entry1 = """C2H6 C 2H 6 G 300.000 3000.000 650.73 1 -3.07954000E-01 2.45269000E-02-1.24130000E-05 3.07724000E-09-3.01467000E-13 2 -1.06930000E+04 2.26280000E+01 4.03055000E+00-2.14171000E-03 4.90611000E-05 3 -5.99027000E-08 2.38945000E-11-1.12576000E+04 3.56130000E+00 4 """ self.entry2 = """CH3NO2X G 300.000 3000.000 650.73 1& C 1 H 3 N 1 O 2 X 1 -3.07954000E-01 2.45269000E-02-1.24130000E-05 3.07724000E-09-3.01467000E-13 2 -1.06930000E+04 2.26280000E+01 4.03055000E+00-2.14171000E-03 4.90611000E-05 3 -5.99027000E-08 2.38945000E-11-1.12576000E+04 3.56130000E+00 4 """ self.entry3 = """CH3NO2SX G 300.000 3000.000 650.73 1&
def setUp(self): """ A function run before each unit test in this class. """ self.wilhoit = Wilhoit( Cp0=(4.0 * constants.R, "J/(mol*K)"), CpInf=(21.5 * constants.R, "J/(mol*K)"), a0=0.0977518, a1=-16.3067, a2=26.2524, a3=-12.6785, B=(1068.68, "K"), H0=(-94.088 * constants.R, "kJ/mol"), S0=(-118.46 * constants.R, "J/(mol*K)"), Tmin=(10, "K"), Tmax=(3000, "K"), comment='C2H6', ) self.nasa = NASA( polynomials=[ NASAPolynomial(coeffs=[4.03055, -0.00214171, 4.90611e-05, -5.99027e-08, 2.38945e-11, -11257.6, 3.5613], Tmin=(10, "K"), Tmax=(650.73, "K")), NASAPolynomial(coeffs=[-0.307954, 0.0245269, -1.2413e-05, 3.07724e-09, -3.01467e-13, -10693, 22.628], Tmin=(650.73, "K"), Tmax=(3000, "K")), ], Tmin=(10, "K"), Tmax=(3000, "K"), E0=(-93.6077, 'kJ/mol'), Cp0=(4.0 * constants.R, "J/(mol*K)"), CpInf=(21.5 * constants.R, "J/(mol*K)"), comment='C2H6', ) self.thermodata = ThermoData( Tdata=([300, 400, 500, 600, 800, 1000, 1500], "K"), Cpdata=(np.array([6.38268, 7.80327, 9.22175, 10.5528, 12.8323, 14.6013, 17.40890]) * constants.R, "J/(mol*K)"), H298=(-81.7, "kJ/mol"), S298=(27.5727 * constants.R, "J/(mol*K)"), Cp0=(4.0 * constants.R, "J/(mol*K)"), CpInf=(21.5 * constants.R, "J/(mol*K)"), Tmin=(10, "K"), Tmax=(3000, "K"), E0=(-93.6077, 'kJ/mol'), comment='C2H6', )
def test_cantera(self): """ Test that a Cantera Species object is created correctly. """ from rmgpy.thermo import NASA, NASAPolynomial import cantera as ct rmg_species = Species(label="Ar", thermo=NASA( polynomials=[NASAPolynomial(coeffs=[2.5, 0, 0, 0, 0, -745.375, 4.37967], Tmin=(200, 'K'), Tmax=(1000, 'K')), NASAPolynomial(coeffs=[2.5, 0, 0, 0, 0, -745.375, 4.37967], Tmin=(1000, 'K'), Tmax=(6000, 'K'))], Tmin=(200, 'K'), Tmax=(6000, 'K'), comment=""" Thermo library: primaryThermoLibrary """), molecule=[Molecule(smiles="[Ar]")], transport_data=TransportData(shapeIndex=0, epsilon=(1134.93, 'J/mol'), sigma=(3.33, 'angstrom'), dipoleMoment=(2, 'De'), polarizability=(1, 'angstrom^3'), rotrelaxcollnum=15.0, comment="""GRI-Mech""")) rmg_ct_species = rmg_species.to_cantera(use_chemkin_identifier=True) ct_species = ct.Species.fromCti("""species(name=u'Ar', atoms='Ar:1', thermo=(NASA([200.00, 1000.00], [ 2.50000000E+00, 0.00000000E+00, 0.00000000E+00, 0.00000000E+00, 0.00000000E+00, -7.45375000E+02, 4.37967000E+00]), NASA([1000.00, 6000.00], [ 2.50000000E+00, 0.00000000E+00, 0.00000000E+00, 0.00000000E+00, 0.00000000E+00, -7.45375000E+02, 4.37967000E+00])), transport=gas_transport(geom='atom', diam=3.33, well_depth=136.501, dipole=2.0, polar=1.0, rot_relax=15.0))""") self.assertEqual(type(rmg_ct_species), type(ct_species)) self.assertEqual(rmg_ct_species.name, ct_species.name) self.assertEqual(rmg_ct_species.composition, ct_species.composition) self.assertEqual(rmg_ct_species.size, ct_species.size) self.assertEqual(type(rmg_ct_species.thermo), type(ct_species.thermo)) self.assertEqual(type(rmg_ct_species.transport), type(ct_species.transport))
def testParseThermoComments(self): """ Test that the ThermoDatabase.extractSourceFromComments function works properly on various thermo comments. """ from rmgpy.thermo import NASA, NASAPolynomial # Pure group additivity thermo propane = Species( index=3, label="Propane", thermo=NASA( polynomials=[ NASAPolynomial(coeffs=[ 3.05257, 0.0125099, 3.79386e-05, -5.12022e-08, 1.87065e-11, -14454.2, 10.0672 ], Tmin=(100, 'K'), Tmax=(986.57, 'K')), NASAPolynomial(coeffs=[ 5.91316, 0.0218763, -8.17661e-06, 1.49855e-09, -1.05991e-13, -16038.9, -8.86555 ], Tmin=(986.57, 'K'), Tmax=(5000, 'K')) ], Tmin=(100, 'K'), Tmax=(5000, 'K'), comment= """Thermo group additivity estimation: group(Cs-CsCsHH) + gauche(Cs(CsCsRR)) + other(R) + group(Cs-CsHHH) + gauche(Cs(Cs(CsRR)RRR)) + other(R) + group(Cs-CsHHH) + gauche(Cs(Cs(CsRR)RRR)) + other(R)""" ), molecule=[Molecule(SMILES="CCC")]) source = self.database.extractSourceFromComments(propane) self.assertTrue( 'GAV' in source, 'Should have found that propane thermo source is GAV.') self.assertEqual(len(source['GAV']['group']), 2) self.assertEqual(len(source['GAV']['other']), 1) self.assertEqual(len(source['GAV']['gauche']), 2) # Pure library thermo dipk = Species(index=1, label="DIPK", thermo=NASA(polynomials=[ NASAPolynomial(coeffs=[ 3.35002, 0.017618, -2.46235e-05, 1.7684e-08, -4.87962e-12, 35555.7, 5.75335 ], Tmin=(100, 'K'), Tmax=(888.28, 'K')), NASAPolynomial(coeffs=[ 6.36001, 0.00406378, -1.73509e-06, 5.05949e-10, -4.49975e-14, 35021, -8.41155 ], Tmin=(888.28, 'K'), Tmax=(5000, 'K')) ], Tmin=(100, 'K'), Tmax=(5000, 'K'), comment="""Thermo library: DIPK"""), molecule=[Molecule(SMILES="CC(C)C(=O)C(C)C")]) source = self.database.extractSourceFromComments(dipk) self.assertTrue('Library' in source) # Mixed library and HBI thermo dipk_rad = Species( index=4, label="R_tert", thermo=NASA(polynomials=[ NASAPolynomial(coeffs=[ 2.90061, 0.0298018, -7.06268e-05, 6.9636e-08, -2.42414e-11, 54431, 5.44492 ], Tmin=(100, 'K'), Tmax=(882.19, 'K')), NASAPolynomial(coeffs=[ 6.70999, 0.000201027, 6.65617e-07, -7.99543e-11, 4.08721e-15, 54238.6, -9.73662 ], Tmin=(882.19, 'K'), Tmax=(5000, 'K')) ], Tmin=(100, 'K'), Tmax=(5000, 'K'), comment="""Thermo library: DIPK + radical(C2CJCHO)"""), molecule=[ Molecule(SMILES="C[C](C)C(=O)C(C)C"), Molecule(SMILES="CC(C)=C([O])C(C)C") ]) source = self.database.extractSourceFromComments(dipk_rad) self.assertTrue('Library' in source) self.assertTrue('GAV' in source) self.assertEqual(len(source['GAV']['radical']), 1) # Pure QM thermo cineole = Species( index=6, label="Cineole", thermo=NASA(polynomials=[ NASAPolynomial(coeffs=[ -0.324129, 0.0619667, 9.71008e-05, -1.60598e-07, 6.28285e-11, -38699.9, 29.3686 ], Tmin=(100, 'K'), Tmax=(985.52, 'K')), NASAPolynomial(coeffs=[ 20.6043, 0.0586913, -2.22152e-05, 4.19949e-09, -3.06046e-13, -46791, -91.4152 ], Tmin=(985.52, 'K'), Tmax=(5000, 'K')) ], Tmin=(100, 'K'), Tmax=(5000, 'K'), comment="""QM MopacMolPM3 calculation attempt 1"""), molecule=[Molecule(SMILES="CC12CCC(CC1)C(C)(C)O2")]) source = self.database.extractSourceFromComments(cineole) self.assertTrue('QM' in source) # Mixed QM and HBI thermo cineole_rad = Species( index=7, label="CineoleRad", thermo=NASA( polynomials=[ NASAPolynomial(coeffs=[ -0.2897, 0.0627717, 8.63299e-05, -1.47868e-07, 5.81665e-11, -14017.6, 31.0266 ], Tmin=(100, 'K'), Tmax=(988.76, 'K')), NASAPolynomial(coeffs=[ 20.4836, 0.0562555, -2.13903e-05, 4.05725e-09, -2.96023e-13, -21915, -88.1205 ], Tmin=(988.76, 'K'), Tmax=(5000, 'K')) ], Tmin=(100, 'K'), Tmax=(5000, 'K'), comment= """QM MopacMolPM3 calculation attempt 1 + radical(Cs_P)"""), molecule=[Molecule(SMILES="[CH2]C12CCC(CC1)C(C)(C)O2")]) source = self.database.extractSourceFromComments(cineole_rad) self.assertTrue('QM' in source) self.assertTrue('GAV' in source) self.assertEqual(len(source['GAV']['radical']), 1) # No thermo comments other = Species( index=7, label="CineoleRad", thermo=NASA( polynomials=[ NASAPolynomial(coeffs=[ -0.2897, 0.0627717, 8.63299e-05, -1.47868e-07, 5.81665e-11, -14017.6, 31.0266 ], Tmin=(100, 'K'), Tmax=(988.76, 'K')), NASAPolynomial(coeffs=[ 20.4836, 0.0562555, -2.13903e-05, 4.05725e-09, -2.96023e-13, -21915, -88.1205 ], Tmin=(988.76, 'K'), Tmax=(5000, 'K')) ], Tmin=(100, 'K'), Tmax=(5000, 'K'), ), molecule=[Molecule(SMILES="[CH2]C12CCC(CC1)C(C)(C)O2")]) # Function should complain if there's no thermo comments self.assertRaises(self.database.extractSourceFromComments(cineole_rad)) # Check a dummy species that has plus and minus thermo group contributions polycyclic = Species( index=7, label="dummy", thermo=NASA( polynomials=[ NASAPolynomial(coeffs=[ -0.2897, 0.0627717, 8.63299e-05, -1.47868e-07, 5.81665e-11, -14017.6, 31.0266 ], Tmin=(100, 'K'), Tmax=(988.76, 'K')), NASAPolynomial(coeffs=[ 20.4836, 0.0562555, -2.13903e-05, 4.05725e-09, -2.96023e-13, -21915, -88.1205 ], Tmin=(988.76, 'K'), Tmax=(5000, 'K')) ], Tmin=(100, 'K'), Tmax=(5000, 'K'), comment= """Thermo group additivity estimation: group(Cs-CsCsHH) + group(Cs-CsCsHH) - ring(Benzene)""" ), molecule=[Molecule(SMILES="[CH2]C12CCC(CC1)C(C)(C)O2")]) source = self.database.extractSourceFromComments(polycyclic) self.assertTrue('GAV' in source) self.assertEqual(source['GAV']['ring'][0][1], -1) # the weight of benzene contribution should be -1 self.assertEqual( source['GAV']['group'][0][1], 2) # weight of the group(Cs-CsCsHH) conbtribution should be 2
def test_solve_ch3(self): """ Test the surface batch reactor with a nondissociative adsorption of CH3 Here we choose a kinetic model consisting of the adsorption reaction CH3 + X <=> CH3X We use a sticking coefficient for the rate expression. """ ch3 = Species( molecule=[Molecule().from_smiles("[CH3]")], thermo=NASA( polynomials=[ NASAPolynomial( coeffs=[3.91547, 0.00184155, 3.48741e-06, -3.32746e-09, 8.49953e-13, 16285.6, 0.351743], Tmin=(100, 'K'), Tmax=(1337.63, 'K')), NASAPolynomial( coeffs=[3.54146, 0.00476786, -1.82148e-06, 3.28876e-10, -2.22545e-14, 16224, 1.66032], Tmin=(1337.63, 'K'), Tmax=(5000, 'K'))], Tmin=(100, 'K'), Tmax=(5000, 'K'), E0=(135.382, 'kJ/mol'), comment="""Thermo library: primaryThermoLibrary + radical(CH3)""" ), molecular_weight=(15.0345, 'amu'), ) x = Species( molecule=[Molecule().from_adjacency_list("1 X u0 p0")], thermo=NASA(polynomials=[NASAPolynomial(coeffs=[0, 0, 0, 0, 0, 0, 0], Tmin=(298, 'K'), Tmax=(1000, 'K')), NASAPolynomial(coeffs=[0, 0, 0, 0, 0, 0, 0], Tmin=(1000, 'K'), Tmax=(2000, 'K'))], Tmin=(298, 'K'), Tmax=(2000, 'K'), E0=(-6.19426, 'kJ/mol'), comment="""Thermo library: surfaceThermo""") ) ch3x = Species( molecule=[Molecule().from_adjacency_list("1 H u0 p0 {2,S} \n 2 X u0 p0 {1,S}")], thermo=NASA( polynomials=[ NASAPolynomial( coeffs=[-0.552219, 0.026442, -3.55617e-05, 2.60044e-08, -7.52707e-12, -4433.47, 0.692144], Tmin=(298, 'K'), Tmax=(1000, 'K')), NASAPolynomial( coeffs=[3.62557, 0.00739512, -2.43797e-06, 1.86159e-10, 3.6485e-14, -5187.22, -18.9668], Tmin=(1000, 'K'), Tmax=(2000, 'K'))], Tmin=(298, 'K'), Tmax=(2000, 'K'), E0=(-39.1285, 'kJ/mol'), comment="""Thermo library: surfaceThermo""") ) rxn1 = Reaction(reactants=[ch3, x], products=[ch3x], kinetics=StickingCoefficient( A=0.1, n=0, Ea=(0, 'kcal/mol'), T0=(1, 'K'), Tmin=(200, 'K'), Tmax=(3000, 'K'), comment="""Exact match found for rate rule (Adsorbate;VacantSite)""" ) # kinetics=SurfaceArrhenius(A=(2.7e10, 'cm^3/(mol*s)'), # n=0.5, # Ea=(5.0, 'kJ/mol'), # T0=(1.0, 'K')) ) core_species = [ch3, x, ch3x] edge_species = [] core_reactions = [rxn1] edge_reactions = [] T = 800. P_initial = 1.0e5 rxn_system = SurfaceReactor( T, P_initial, n_sims=1, initial_gas_mole_fractions={ch3: 1.0}, initial_surface_coverages={x: 1.0}, surface_volume_ratio=(1., 'm^-1'), surface_site_density=(2.72e-9, 'mol/cm^2'), termination=[]) # in chemkin, the sites are mostly occupied in about 1e-8 seconds. rxn_system.initialize_model(core_species, core_reactions, edge_species, edge_reactions) tlist = np.logspace(-13, -5, 81, dtype=np.float64) print("Surface site density:", rxn_system.surface_site_density.value_si) print("rxn1 rate coefficient", rxn1.get_surface_rate_coefficient(rxn_system.T.value_si, rxn_system.surface_site_density.value_si)) # Integrate to get the solution at each time point t = [] y = [] reaction_rates = [] species_rates = [] t.append(rxn_system.t) # You must make a copy of y because it is overwritten by DASSL at # each call to advance() y.append(rxn_system.y.copy()) reaction_rates.append(rxn_system.core_reaction_rates.copy()) species_rates.append(rxn_system.core_species_rates.copy()) print("time: ", t) print("moles:", y) print("reaction rates:", reaction_rates) print("species rates:", species_rates) for t1 in tlist: rxn_system.advance(t1) t.append(rxn_system.t) # You must make a copy of y because it is overwritten by DASSL at # each call to advance() y.append(rxn_system.y.copy()) reaction_rates.append(rxn_system.core_reaction_rates.copy()) species_rates.append(rxn_system.core_species_rates.copy()) # Convert the solution vectors to np arrays t = np.array(t, np.float64) y = np.array(y, np.float64) reaction_rates = np.array(reaction_rates, np.float64) species_rates = np.array(species_rates, np.float64) V = constants.R * rxn_system.T.value_si * np.sum(y) / rxn_system.P_initial.value_si # Check that we're computing the species fluxes correctly for i in range(t.shape[0]): self.assertAlmostEqual(reaction_rates[i, 0], -species_rates[i, 0], delta=1e-6 * reaction_rates[i, 0]) self.assertAlmostEqual(reaction_rates[i, 0], -species_rates[i, 1], delta=1e-6 * reaction_rates[i, 0]) self.assertAlmostEqual(reaction_rates[i, 0], species_rates[i, 2], delta=1e-6 * reaction_rates[i, 0]) # Check that we've reached equilibrium by the end self.assertAlmostEqual(reaction_rates[-1, 0], 0.0, delta=1e-2)