def test_toCantera(self): """ Test that the Cantera GasTransportData creation is successful. """ transport = 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_ctTransport = transport.toCantera() import cantera as ct ctSpecies = ct.Species.fromCti("""species(name=u'Ar', atoms='Ar:1', transport=gas_transport(geom='atom', diam=3.33, well_depth=136.501, dipole=2.0, polar=1.0, rot_relax=15.0))""") ctTransport = ctSpecies.transport self.assertAlmostEqual(rmg_ctTransport.geometry, ctTransport.geometry) self.assertAlmostEqual(rmg_ctTransport.acentric_factor, ctTransport.acentric_factor) self.assertAlmostEqual(rmg_ctTransport.diameter, ctTransport.diameter) self.assertAlmostEqual(rmg_ctTransport.dipole, ctTransport.dipole) self.assertAlmostEqual(rmg_ctTransport.polarizability, ctTransport.polarizability) self.assertAlmostEqual(rmg_ctTransport.rotational_relaxation, ctTransport.rotational_relaxation) self.assertAlmostEqual(rmg_ctTransport.well_depth, ctTransport.well_depth)
def getTransportPropertiesViaGroupEstimates(self, species): """ Return the set of transport parameters corresponding to a given :class:`Species` object `species` by estimation using the group additivity values. If no group additivity values are loaded, a :class:`DatabaseError` is raised. """ Tc = 0 Pc = 0 Tb = 0 Vc = 0 counter = 0 # assume that the stablest resonance isomer has already been put as the first # and that we want the transport properties of this isomer molecule = species.molecule[0] molecule.clearLabeledAtoms() molecule.updateAtomTypes() criticalPoint = self.estimateCriticalPropertiesViaGroupAdditivity( molecule) Tc = criticalPoint.Tc Pc = criticalPoint.Pc Vc = criticalPoint.Vc Tb = criticalPoint.Tb if criticalPoint.linear != molecule.isLinear(): logging.warning( "Group-based structure index and isLinear() function disagree about linearity of {mol!r}" .format(mol=molecule)) shapeIndex = 1 if molecule.isLinear() else 2 # Acetone values from Joback thesis: Tc = 511.455 (based on experimental Tb) Pc = 47.808 Vc = 209.000 Tb = 322.082 #print "Tc={Tc:.2f} K, Pc={Pc:.4g} bar, Vc={Vc:.4g} cm3/mol, Tb={Tb:.4g} K, average of {isomers} isomers".format(Tc=Tc,Pc=Pc,Vc=Vc,Tb=Tb,isomers=counter) #print 'Estimated with Tc={Tc:.2f} K, Pc={Pc:.4g} bar (from Joback method)'.format(Tc=Tc,Pc=Pc) transport = TransportData( shapeIndex=shapeIndex, # 1 if linear, else 2 epsilon=(.77 * Tc * constants.R, 'J/mol'), sigma=(2.44 * (Tc / Pc)**(1. / 3), 'angstroms'), dipoleMoment=(0, 'C*m'), polarizability=(0, 'angstroms^3'), rotrelaxcollnum=0, # rotational relaxation collision number at 298 K comment= 'Epsilon & sigma estimated with Tc={Tc:.2f} K, Pc={Pc:.4g} bar (from Joback method)' .format(Tc=Tc, Pc=Pc), ) return (transport, None, None)
def test_get_transport_data(self): """ Test that transport data can be retrieved correctly via the get_transport_data method. """ spc = Species(label="Ar", 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""")) self.assertTrue(spc.get_transport_data() is spc.transport_data)
def getTransportPropertiesViaLennardJonesParameters(self,species): """ Serves as last resort if every other method to estimate Transport Properties fails. Generate the Lennard-Jones parameters for the species. """ count = sum([1 for atom in species.molecule[0].vertices if atom.isNonHydrogen()]) if count == 1: sigma = (3.758e-10,"m") epsilon = (148.6,"K") elif count == 2: sigma = (4.443e-10,"m") epsilon = (110.7,"K") elif count == 3: sigma = (5.118e-10,"m") epsilon = (237.1,"K") elif count == 4: sigma = (4.687e-10,"m") epsilon = (531.4,"K") elif count == 5: sigma = (5.784e-10,"m") epsilon = (341.1,"K") else: sigma = (5.949e-10,"m") epsilon = (399.3,"K") if len(species.molecule[0].atoms) == 1: shapeIndex = 0 elif species.molecule[0].isLinear(): shapeIndex = 1 else: shapeIndex = 2 transport = TransportData( shapeIndex = shapeIndex, epsilon = epsilon, sigma = sigma, dipoleMoment = (0, 'C*m'), polarizability = (0, 'angstroms^3'), rotrelaxcollnum = 0, # rotational relaxation collision number at 298 K comment = 'Epsilon & sigma estimated with fixed Lennard Jones Parameters. This is the fallback method! Try improving transport databases!' ) return (transport, None, None)
def test_species(self): """ Test loading a species from input file-like kew word arguments """ label0 = 'CH2O' kwargs = { 'E0': (28.69, 'kcal/mol'), 'structure': SMILES('C=O'), 'collisionModel': TransportData(sigma=(3.69e-10, 'm'), epsilon=(4.0, 'kJ/mol')), 'energyTransferModel': SingleExponentialDown(alpha0=(0.956, 'kJ/mol'), T0=(300, 'K'), n=0.95), 'spinMultiplicity': 1, 'opticalIsomers': 1, 'modes': [ HarmonicOscillator( frequencies=([1180, 1261, 1529, 1764, 2931, 2999], 'cm^-1')), NonlinearRotor(rotationalConstant=([ 1.15498821005263, 1.3156969584727, 9.45570474524524 ], "cm^-1"), symmetry=2, quantum=False), IdealGasTranslation(mass=(30.0106, "g/mol")), ] } spc0 = species(label0, **kwargs) self.assertEqual(spc0.label, 'CH2O') self.assertEqual(spc0.smiles, 'C=O') self.assertAlmostEqual(spc0.conformer.E0.value_si, 120038.96) self.assertEqual(spc0.conformer.spin_multiplicity, 1) self.assertEqual(spc0.conformer.optical_isomers, 1) self.assertEqual(len(spc0.conformer.modes), 3) self.assertIsInstance(spc0.transport_data, TransportData) self.assertIsInstance(spc0.energy_transfer_model, SingleExponentialDown)
def test_transport_data_read_and_write(self): """ Test that we can write to chemkin and recreate the same transport object """ Ar = Species(label="Ar", transport_data=TransportData(shapeIndex=0, epsilon=(1134.93, 'J/mol'), sigma=(3.33, 'angstrom'), dipoleMoment=(0, 'De'), polarizability=(0, 'angstrom^3'), rotrelaxcollnum=0.0, comment="""GRI-Mech""")) Ar_write = Species(label="Ar") folder = os.path.join(os.path.dirname(rmgpy.__file__), 'test_data') temp_transport_path = os.path.join(folder, 'tran_temp.dat') save_transport_file(temp_transport_path, [Ar]) species_dict = {'Ar': Ar_write} load_transport_file(temp_transport_path, species_dict) self.assertEqual(repr(Ar), repr(Ar_write)) os.remove(temp_transport_path)
def setUp(self): """ A function run before each unit test in this class. """ self.shapeIndex = 1 self.epsilon = Energy(2.104, 'kJ/mol') self.sigma = Length(3.402, 'angstroms') self.dipoleMoment = DipoleMoment(1.000, 'C*m') self.polarizability = Volume(0.134, 'angstroms^3') self.rotrelaxcollnum = 0.000 self.comment = 'test' self.transport = TransportData( shapeIndex=self.shapeIndex, epsilon=self.epsilon, sigma=self.sigma, dipoleMoment=self.dipoleMoment, polarizability=self.polarizability, rotrelaxcollnum=self.rotrelaxcollnum, comment=self.comment, )
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 setUp(self): """ A method that is run before each unit test in this class. """ self.species = Species( index=1, label='C2H4', thermo=ThermoData( Tdata=([300.0, 400.0, 500.0, 600.0, 800.0, 1000.0, 1500.0], 'K'), Cpdata=([3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 15.0], 'cal/(mol*K)'), H298=(-20.0, 'kcal/mol'), S298=(50.0, 'cal/(mol*K)'), Tmin=(300.0, 'K'), Tmax=(2000.0, 'K'), ), conformer=Conformer( E0=(0.0, 'kJ/mol'), modes=[ IdealGasTranslation(mass=(28.03, 'amu')), NonlinearRotor( inertia=([5.6952e-47, 2.7758e-46, 3.3454e-46], 'kg*m^2'), symmetry=1), HarmonicOscillator(frequencies=([ 834.50, 973.31, 975.37, 1067.1, 1238.5, 1379.5, 1472.3, 1691.3, 3121.6, 3136.7, 3192.5, 3221.0 ], 'cm^-1')), ], spinMultiplicity=1, opticalIsomers=1, ), molecule=[Molecule().fromSMILES('C=C')], transportData=TransportData(sigma=(1, 'angstrom'), epsilon=(100, 'K')), molecularWeight=(28.03, 'amu'), reactive=True, )
def loadFAMEInput(path, moleculeDict=None): """ Load the contents of a FAME input file into the MEASURE object. FAME is an early version of MEASURE written in Fortran and used by RMG-Java. This script enables importing FAME input files into MEASURE so we can use the additional functionality that MEASURE provides. Note that it is mostly designed to load the FAME input files generated automatically by RMG-Java, and may not load hand-crafted FAME input files. If you specify a `moleculeDict`, then this script will use it to associate the species with their structures. """ def readMeaningfulLine(f): line = f.readline() while line != '': line = line.strip() if len(line) > 0 and line[0] != '#': return line else: line = f.readline() return '' moleculeDict = moleculeDict or {} logging.info('Loading file "{0}"...'.format(path)) f = open(path) job = PressureDependenceJob(network=None) # Read method method = readMeaningfulLine(f).lower() if method == 'modifiedstrongcollision': job.method = 'modified strong collision' elif method == 'reservoirstate': job.method = 'reservoir state' # Read temperatures Tcount, Tunits, Tmin, Tmax = readMeaningfulLine(f).split() job.Tmin = Quantity(float(Tmin), Tunits) job.Tmax = Quantity(float(Tmax), Tunits) job.Tcount = int(Tcount) Tlist = [] for i in range(int(Tcount)): Tlist.append(float(readMeaningfulLine(f))) job.Tlist = Quantity(Tlist, Tunits) # Read pressures Pcount, Punits, Pmin, Pmax = readMeaningfulLine(f).split() job.Pmin = Quantity(float(Pmin), Punits) job.Pmax = Quantity(float(Pmax), Punits) job.Pcount = int(Pcount) Plist = [] for i in range(int(Pcount)): Plist.append(float(readMeaningfulLine(f))) job.Plist = Quantity(Plist, Punits) # Read interpolation model model = readMeaningfulLine(f).split() if model[0].lower() == 'chebyshev': job.interpolationModel = ('chebyshev', int(model[1]), int(model[2])) elif model[0].lower() == 'pdeparrhenius': job.interpolationModel = ('pdeparrhenius',) # Read grain size or number of grains job.minimumGrainCount = 0 job.maximumGrainSize = None for i in range(2): data = readMeaningfulLine(f).split() if data[0].lower() == 'numgrains': job.minimumGrainCount = int(data[1]) elif data[0].lower() == 'grainsize': job.maximumGrainSize = (float(data[2]), data[1]) # A FAME file is almost certainly created during an RMG job, so use RMG mode job.rmgmode = True # Create the Network job.network = Network() # Read collision model data = readMeaningfulLine(f) assert data.lower() == 'singleexpdown' alpha0units, alpha0 = readMeaningfulLine(f).split() T0units, T0 = readMeaningfulLine(f).split() n = readMeaningfulLine(f) energyTransferModel = SingleExponentialDown( alpha0 = Quantity(float(alpha0), alpha0units), T0 = Quantity(float(T0), T0units), n = float(n), ) speciesDict = {} # Read bath gas parameters bathGas = Species(label='bath_gas', energyTransferModel=energyTransferModel) molWtunits, molWt = readMeaningfulLine(f).split() if molWtunits == 'u': molWtunits = 'amu' bathGas.molecularWeight = Quantity(float(molWt), molWtunits) sigmaLJunits, sigmaLJ = readMeaningfulLine(f).split() epsilonLJunits, epsilonLJ = readMeaningfulLine(f).split() assert epsilonLJunits == 'J' bathGas.transportData = TransportData( sigma = Quantity(float(sigmaLJ), sigmaLJunits), epsilon = Quantity(float(epsilonLJ) / constants.kB, 'K'), ) job.network.bathGas = {bathGas: 1.0} # Read species data Nspec = int(readMeaningfulLine(f)) for i in range(Nspec): species = Species() species.conformer = Conformer() species.energyTransferModel = energyTransferModel # Read species label species.label = readMeaningfulLine(f) speciesDict[species.label] = species if species.label in moleculeDict: species.molecule = [moleculeDict[species.label]] # Read species E0 E0units, E0 = readMeaningfulLine(f).split() species.conformer.E0 = Quantity(float(E0), E0units) species.conformer.E0.units = 'kJ/mol' # Read species thermo data H298units, H298 = readMeaningfulLine(f).split() S298units, S298 = readMeaningfulLine(f).split() Cpcount, Cpunits = readMeaningfulLine(f).split() Cpdata = [] for i in range(int(Cpcount)): Cpdata.append(float(readMeaningfulLine(f))) if S298units == 'J/mol*K': S298units = 'J/(mol*K)' if Cpunits == 'J/mol*K': Cpunits = 'J/(mol*K)' species.thermo = ThermoData( H298 = Quantity(float(H298), H298units), S298 = Quantity(float(S298), S298units), Tdata = Quantity([300,400,500,600,800,1000,1500], "K"), Cpdata = Quantity(Cpdata, Cpunits), Cp0 = (Cpdata[0], Cpunits), CpInf = (Cpdata[-1], Cpunits), ) # Read species collision parameters molWtunits, molWt = readMeaningfulLine(f).split() if molWtunits == 'u': molWtunits = 'amu' species.molecularWeight = Quantity(float(molWt), molWtunits) sigmaLJunits, sigmaLJ = readMeaningfulLine(f).split() epsilonLJunits, epsilonLJ = readMeaningfulLine(f).split() assert epsilonLJunits == 'J' species.transportData = TransportData( sigma = Quantity(float(sigmaLJ), sigmaLJunits), epsilon = Quantity(float(epsilonLJ) / constants.kB, 'K'), ) # Read species vibrational frequencies freqCount, freqUnits = readMeaningfulLine(f).split() frequencies = [] for j in range(int(freqCount)): frequencies.append(float(readMeaningfulLine(f))) species.conformer.modes.append(HarmonicOscillator( frequencies = Quantity(frequencies, freqUnits), )) # Read species external rotors rotCount, rotUnits = readMeaningfulLine(f).split() if int(rotCount) > 0: raise NotImplementedError('Cannot handle external rotational modes in FAME input.') # Read species internal rotors freqCount, freqUnits = readMeaningfulLine(f).split() frequencies = [] for j in range(int(freqCount)): frequencies.append(float(readMeaningfulLine(f))) barrCount, barrUnits = readMeaningfulLine(f).split() barriers = [] for j in range(int(barrCount)): barriers.append(float(readMeaningfulLine(f))) if barrUnits == 'cm^-1': barrUnits = 'J/mol' barriers = [barr * constants.h * constants.c * constants.Na * 100. for barr in barriers] elif barrUnits in ['Hz', 's^-1']: barrUnits = 'J/mol' barriers = [barr * constants.h * constants.Na for barr in barriers] elif barrUnits != 'J/mol': raise Exception('Unexpected units "{0}" for hindered rotor barrier height.'.format(barrUnits)) inertia = [V0 / 2.0 / (nu * constants.c * 100.)**2 / constants.Na for nu, V0 in zip(frequencies, barriers)] for I, V0 in zip(inertia, barriers): species.conformer.modes.append(HinderedRotor( inertia = Quantity(I,"kg*m^2"), barrier = Quantity(V0,barrUnits), symmetry = 1, semiclassical = False, )) # Read overall symmetry number species.conformer.spinMultiplicity = int(readMeaningfulLine(f)) # Read isomer, reactant channel, and product channel data Nisom = int(readMeaningfulLine(f)) Nreac = int(readMeaningfulLine(f)) Nprod = int(readMeaningfulLine(f)) for i in range(Nisom): data = readMeaningfulLine(f).split() assert data[0] == '1' job.network.isomers.append(speciesDict[data[1]]) for i in range(Nreac): data = readMeaningfulLine(f).split() assert data[0] == '2' job.network.reactants.append([speciesDict[data[1]], speciesDict[data[2]]]) for i in range(Nprod): data = readMeaningfulLine(f).split() if data[0] == '1': job.network.products.append([speciesDict[data[1]]]) elif data[0] == '2': job.network.products.append([speciesDict[data[1]], speciesDict[data[2]]]) # Read path reactions Nrxn = int(readMeaningfulLine(f)) for i in range(Nrxn): # Read and ignore reaction equation equation = readMeaningfulLine(f) reaction = Reaction(transitionState=TransitionState(), reversible=True) job.network.pathReactions.append(reaction) reaction.transitionState.conformer = Conformer() # Read reactant and product indices data = readMeaningfulLine(f).split() reac = int(data[0]) - 1 prod = int(data[1]) - 1 if reac < Nisom: reaction.reactants = [job.network.isomers[reac]] elif reac < Nisom+Nreac: reaction.reactants = job.network.reactants[reac-Nisom] else: reaction.reactants = job.network.products[reac-Nisom-Nreac] if prod < Nisom: reaction.products = [job.network.isomers[prod]] elif prod < Nisom+Nreac: reaction.products = job.network.reactants[prod-Nisom] else: reaction.products = job.network.products[prod-Nisom-Nreac] # Read reaction E0 E0units, E0 = readMeaningfulLine(f).split() reaction.transitionState.conformer.E0 = Quantity(float(E0), E0units) reaction.transitionState.conformer.E0.units = 'kJ/mol' # Read high-pressure limit kinetics data = readMeaningfulLine(f) assert data.lower() == 'arrhenius' Aunits, A = readMeaningfulLine(f).split() if '/' in Aunits: index = Aunits.find('/') Aunits = '{0}/({1})'.format(Aunits[0:index], Aunits[index+1:]) Eaunits, Ea = readMeaningfulLine(f).split() n = readMeaningfulLine(f) reaction.kinetics = Arrhenius( A = Quantity(float(A), Aunits), Ea = Quantity(float(Ea), Eaunits), n = Quantity(float(n)), ) reaction.kinetics.Ea.units = 'kJ/mol' f.close() job.network.isomers = [Configuration(isomer) for isomer in job.network.isomers] job.network.reactants = [Configuration(*reactants) for reactants in job.network.reactants] job.network.products = [Configuration(*products) for products in job.network.products] return job
class TestTransportData(unittest.TestCase): """ Contains unit test of the :class: 'transportData' class """ def setUp(self): """ A function run before each unit test in this class. """ self.shapeIndex = 1 self.epsilon = Energy(2.104, 'kJ/mol') self.sigma = Length(3.402, 'angstroms') self.dipoleMoment = DipoleMoment(1.000, 'C*m') self.polarizability = Volume(0.134, 'angstroms^3') self.rotrelaxcollnum = 0.000 self.comment = 'test' self.transport = TransportData( shapeIndex=self.shapeIndex, epsilon=self.epsilon, sigma=self.sigma, dipoleMoment=self.dipoleMoment, polarizability=self.polarizability, rotrelaxcollnum=self.rotrelaxcollnum, comment=self.comment, ) def test_shapeIndex(self): """ Test that the TransportData shapeIndex property was properly set. """ self.assertAlmostEqual(self.transport.shapeIndex, self.shapeIndex, 6) def test_epsilon(self): """ Test that the TransportData epsilon property was properly set. """ self.assertAlmostEqual(self.transport.epsilon.value_si, self.epsilon.value_si, 6) def test_sigma(self): """ Test that the TransportData sigma property was properly set. """ self.assertAlmostEqual(self.transport.sigma.value_si * 1e10, self.sigma.value_si * 1e10, 6) def test_dipoleMoment(self): """ Test that the TransportData dipoleMoment property was properly set. """ self.assertAlmostEqual(self.transport.dipoleMoment.value_si, self.dipoleMoment.value_si, 6) def test_polarizability(self): """ Test that the TransportData polarizability property was properly set. """ self.assertAlmostEqual(self.transport.polarizability.value_si, self.polarizability.value_si, 6) def test_rotrelaxcollnum(self): """ Test that the TransportData rotrelaxcollnum property was properly set. """ self.assertAlmostEqual(self.transport.rotrelaxcollnum, self.rotrelaxcollnum, 6) def test_comment(self): """ Test that the TransportData comment property was properly set. """ self.assertEqual(self.transport.comment, self.comment) def test_getCollisionFrequency(self): """ Test the LennardJones.getCollisionFrequency() method. """ T = 1000; P = 1.0e5 M = P / constants.R / T mu = 1.0 omega = self.transport.getCollisionFrequency(T, M, mu) self.assertAlmostEqual(omega / 1.17737e10, 1.0, 4) def test_pickle(self): """ Test that a TransportData object can be pickled and unpickled with no loss of information. """ import cPickle transport = cPickle.loads(cPickle.dumps(self.transport,-1)) self.assertAlmostEqual(self.transport.shapeIndex, transport.shapeIndex, 4) self.assertAlmostEqual(self.transport.epsilon.value_si, transport.epsilon.value_si, 4) self.assertAlmostEqual(self.transport.sigma.value_si, transport.sigma.value_si, 4) self.assertAlmostEqual(self.transport.dipoleMoment.value_si, transport.dipoleMoment.value_si, 4) self.assertAlmostEqual(self.transport.polarizability.value_si, transport.polarizability.value_si, 4) self.assertAlmostEqual(self.transport.rotrelaxcollnum, transport.rotrelaxcollnum, 4) self.assertEqual(self.transport.comment, transport.comment) def test_repr(self): """ Test that a TransportData object can be reconstructed from its repr() output with no loss of information """ transport = None exec('transport = {0!r}'.format(self.transport)) self.assertAlmostEqual(self.transport.shapeIndex, transport.shapeIndex, 4) self.assertAlmostEqual(self.transport.epsilon.value_si, transport.epsilon.value_si, 4) self.assertAlmostEqual(self.transport.sigma.value_si, transport.sigma.value_si, 4) self.assertAlmostEqual(self.transport.dipoleMoment.value_si, transport.dipoleMoment.value_si, 4) self.assertAlmostEqual(self.transport.polarizability.value_si, transport.polarizability.value_si, 4) self.assertAlmostEqual(self.transport.rotrelaxcollnum, transport.rotrelaxcollnum, 4) self.assertEqual(self.transport.comment, transport.comment)
def setUp(self): """ A function run before each unit test in this class. """ self.nC4H10O = Species( label='n-C4H10O', conformer=Conformer( E0=(-317.807, 'kJ/mol'), modes=[ IdealGasTranslation(mass=(74.07, "g/mol")), NonlinearRotor(inertia=([41.5091, 215.751, 233.258], "amu*angstrom^2"), symmetry=1), HarmonicOscillator(frequencies=([ 240.915, 341.933, 500.066, 728.41, 809.987, 833.93, 926.308, 948.571, 1009.3, 1031.46, 1076, 1118.4, 1184.66, 1251.36, 1314.36, 1321.42, 1381.17, 1396.5, 1400.54, 1448.08, 1480.18, 1485.34, 1492.24, 1494.99, 1586.16, 2949.01, 2963.03, 2986.19, 2988.1, 2995.27, 3026.03, 3049.05, 3053.47, 3054.83, 3778.88 ], "cm^-1")), HinderedRotor(inertia=(0.854054, "amu*angstrom^2"), symmetry=1, fourier=([[ 0.25183, -1.37378, -2.8379, 0.0305112, 0.0028088 ], [ 0.458307, 0.542121, -0.599366, -0.00283925, 0.0398529 ]], "kJ/mol")), HinderedRotor( inertia=(8.79408, "amu*angstrom^2"), symmetry=1, fourier=([[ 0.26871, -0.59533, -8.15002, -0.294325, -0.145357 ], [1.1884, 0.99479, -0.940416, -0.186538, 0.0309834]], "kJ/mol")), HinderedRotor(inertia=(7.88153, "amu*angstrom^2"), symmetry=1, fourier=([[ -4.67373, 2.03735, -6.25993, -0.27325, -0.048748 ], [ -0.982845, 1.76637, -1.57619, 0.474364, -0.000681718 ]], "kJ/mol")), HinderedRotor(inertia=(2.81525, "amu*angstrom^2"), symmetry=3, barrier=(2.96807, "kcal/mol")), ], spin_multiplicity=1, optical_isomers=1, ), molecular_weight=(74.07, "g/mol"), transport_data=TransportData(sigma=(5.94, 'angstrom'), epsilon=(559, 'K')), energy_transfer_model=SingleExponentialDown( alpha0=(447.5 * 0.011962, "kJ/mol"), T0=(300, "K"), n=0.85), ) self.nC4H8 = Species( label='n-C4H8', conformer=Conformer( E0=(-17.8832, 'kJ/mol'), modes=[ IdealGasTranslation(mass=(56.06, "g/mol")), NonlinearRotor(inertia=([22.2748, 122.4, 125.198], "amu*angstrom^2"), symmetry=1), HarmonicOscillator(frequencies=([ 308.537, 418.67, 636.246, 788.665, 848.906, 936.762, 979.97, 1009.48, 1024.22, 1082.96, 1186.38, 1277.55, 1307.65, 1332.87, 1396.67, 1439.09, 1469.71, 1484.45, 1493.19, 1691.49, 2972.12, 2994.31, 3018.48, 3056.87, 3062.76, 3079.38, 3093.54, 3174.52 ], "cm^-1")), HinderedRotor(inertia=(5.28338, "amu*angstrom^2"), symmetry=1, fourier=([[ -0.579364, -0.28241, -4.46469, 0.143368, 0.126756 ], [ 1.01804, -0.494628, -0.00318651, -0.245289, 0.193728 ]], "kJ/mol")), HinderedRotor( inertia=(2.60818, "amu*angstrom^2"), symmetry=3, fourier=([[ 0.0400372, 0.0301986, -6.4787, -0.0248675, -0.0324753 ], [0.0312541, 0.0538, -0.493785, 0.0965968, 0.125292]], "kJ/mol")), ], spin_multiplicity=1, optical_isomers=1, ), ) self.H2O = Species( label='H2O', conformer=Conformer( E0=(-269.598, 'kJ/mol'), modes=[ IdealGasTranslation(mass=(18.01, "g/mol")), NonlinearRotor(inertia=([0.630578, 1.15529, 1.78586], "amu*angstrom^2"), symmetry=2), HarmonicOscillator( frequencies=([1622.09, 3771.85, 3867.85], "cm^-1")), ], spin_multiplicity=1, optical_isomers=1, ), ) self.configuration = Configuration(self.nC4H8, self.H2O)
def setUp(self): """ A function run before each unit test in this class. """ self.nC4H10O = Species( label='n-C4H10O', conformer=Conformer( E0=(-317.807, 'kJ/mol'), modes=[ IdealGasTranslation(mass=(74.07, "g/mol")), NonlinearRotor(inertia=([41.5091, 215.751, 233.258], "amu*angstrom^2"), symmetry=1), HarmonicOscillator(frequencies=([ 240.915, 341.933, 500.066, 728.41, 809.987, 833.93, 926.308, 948.571, 1009.3, 1031.46, 1076, 1118.4, 1184.66, 1251.36, 1314.36, 1321.42, 1381.17, 1396.5, 1400.54, 1448.08, 1480.18, 1485.34, 1492.24, 1494.99, 1586.16, 2949.01, 2963.03, 2986.19, 2988.1, 2995.27, 3026.03, 3049.05, 3053.47, 3054.83, 3778.88 ], "cm^-1")), HinderedRotor(inertia=(0.854054, "amu*angstrom^2"), symmetry=1, fourier=([[ 0.25183, -1.37378, -2.8379, 0.0305112, 0.0028088 ], [ 0.458307, 0.542121, -0.599366, -0.00283925, 0.0398529 ]], "kJ/mol")), HinderedRotor( inertia=(8.79408, "amu*angstrom^2"), symmetry=1, fourier=([[ 0.26871, -0.59533, -8.15002, -0.294325, -0.145357 ], [1.1884, 0.99479, -0.940416, -0.186538, 0.0309834]], "kJ/mol")), HinderedRotor(inertia=(7.88153, "amu*angstrom^2"), symmetry=1, fourier=([[ -4.67373, 2.03735, -6.25993, -0.27325, -0.048748 ], [ -0.982845, 1.76637, -1.57619, 0.474364, -0.000681718 ]], "kJ/mol")), HinderedRotor(inertia=(2.81525, "amu*angstrom^2"), symmetry=3, barrier=(2.96807, "kcal/mol")), ], spin_multiplicity=1, optical_isomers=1, ), molecular_weight=(74.07, "g/mol"), transport_data=TransportData(sigma=(5.94, 'angstrom'), epsilon=(559, 'K')), energy_transfer_model=SingleExponentialDown( alpha0=(447.5 * 0.011962, "kJ/mol"), T0=(300, "K"), n=0.85), ) self.nC4H8 = Species( label='n-C4H8', conformer=Conformer( E0=(-17.8832, 'kJ/mol'), modes=[ IdealGasTranslation(mass=(56.06, "g/mol")), NonlinearRotor(inertia=([22.2748, 122.4, 125.198], "amu*angstrom^2"), symmetry=1), HarmonicOscillator(frequencies=([ 308.537, 418.67, 636.246, 788.665, 848.906, 936.762, 979.97, 1009.48, 1024.22, 1082.96, 1186.38, 1277.55, 1307.65, 1332.87, 1396.67, 1439.09, 1469.71, 1484.45, 1493.19, 1691.49, 2972.12, 2994.31, 3018.48, 3056.87, 3062.76, 3079.38, 3093.54, 3174.52 ], "cm^-1")), HinderedRotor(inertia=(5.28338, "amu*angstrom^2"), symmetry=1, fourier=([[ -0.579364, -0.28241, -4.46469, 0.143368, 0.126756 ], [ 1.01804, -0.494628, -0.00318651, -0.245289, 0.193728 ]], "kJ/mol")), HinderedRotor( inertia=(2.60818, "amu*angstrom^2"), symmetry=3, fourier=([[ 0.0400372, 0.0301986, -6.4787, -0.0248675, -0.0324753 ], [0.0312541, 0.0538, -0.493785, 0.0965968, 0.125292]], "kJ/mol")), ], spin_multiplicity=1, optical_isomers=1, ), ) self.H2O = Species( label='H2O', conformer=Conformer( E0=(-269.598, 'kJ/mol'), modes=[ IdealGasTranslation(mass=(18.01, "g/mol")), NonlinearRotor(inertia=([0.630578, 1.15529, 1.78586], "amu*angstrom^2"), symmetry=2), HarmonicOscillator( frequencies=([1622.09, 3771.85, 3867.85], "cm^-1")), ], spin_multiplicity=1, optical_isomers=1, ), ) self.N2 = Species( label='N2', molecular_weight=(28.04, "g/mol"), transport_data=TransportData(sigma=(3.41, "angstrom"), epsilon=(124, "K")), energy_transfer_model=None, ) self.TS = TransitionState( label='TS', conformer=Conformer( E0=(-42.4373, "kJ/mol"), modes=[ IdealGasTranslation(mass=(74.07, "g/mol")), NonlinearRotor(inertia=([40.518, 232.666, 246.092], "u*angstrom**2"), symmetry=1, quantum=False), HarmonicOscillator(frequencies=([ 134.289, 302.326, 351.792, 407.986, 443.419, 583.988, 699.001, 766.1, 777.969, 829.671, 949.753, 994.731, 1013.59, 1073.98, 1103.79, 1171.89, 1225.91, 1280.67, 1335.08, 1373.9, 1392.32, 1417.43, 1469.51, 1481.61, 1490.16, 1503.73, 1573.16, 2972.85, 2984.3, 3003.67, 3045.78, 3051.77, 3082.37, 3090.44, 3190.73, 3708.52 ], "kayser")), HinderedRotor(inertia=(2.68206, "amu*angstrom^2"), symmetry=3, barrier=(3.35244, "kcal/mol")), HinderedRotor(inertia=(9.77669, "amu*angstrom^2"), symmetry=1, fourier=([[ 0.208938, -1.55291, -4.05398, -0.105798, -0.104752 ], [ 2.00518, -0.020767, -0.333595, 0.137791, -0.274578 ]], "kJ/mol")), ], spin_multiplicity=1, optical_isomers=1, ), frequency=(-2038.34, 'cm^-1'), ) self.reaction = Reaction( label='dehydration', reactants=[self.nC4H10O], products=[self.nC4H8, self.H2O], transition_state=self.TS, ) self.network = Network( label='n-butanol', isomers=[Configuration(self.nC4H10O)], reactants=[], products=[Configuration(self.nC4H8, self.H2O)], path_reactions=[self.reaction], bath_gas={self.N2: 1.0}, )
class TestTransportData(unittest.TestCase): """ Contains unit test of the :class: 'transportData' class """ def setUp(self): """ A function run before each unit test in this class. """ self.shapeIndex = 1 self.epsilon = Energy(2.104, 'kJ/mol') self.sigma = Length(3.402, 'angstroms') self.dipoleMoment = DipoleMoment(1.000, 'C*m') self.polarizability = Volume(0.134, 'angstroms^3') self.rotrelaxcollnum = 0.000 self.comment = 'test' self.transport = TransportData( shapeIndex=self.shapeIndex, epsilon=self.epsilon, sigma=self.sigma, dipoleMoment=self.dipoleMoment, polarizability=self.polarizability, rotrelaxcollnum=self.rotrelaxcollnum, comment=self.comment, ) def test_shapeIndex(self): """ Test that the TransportData shapeIndex property was properly set. """ self.assertAlmostEqual(self.transport.shapeIndex, self.shapeIndex, 6) def test_epsilon(self): """ Test that the TransportData epsilon property was properly set. """ self.assertAlmostEqual(self.transport.epsilon.value_si, self.epsilon.value_si, 6) def test_sigma(self): """ Test that the TransportData sigma property was properly set. """ self.assertAlmostEqual(self.transport.sigma.value_si * 1e10, self.sigma.value_si * 1e10, 6) def test_dipoleMoment(self): """ Test that the TransportData dipoleMoment property was properly set. """ self.assertAlmostEqual(self.transport.dipoleMoment.value_si, self.dipoleMoment.value_si, 6) def test_polarizability(self): """ Test that the TransportData polarizability property was properly set. """ self.assertAlmostEqual(self.transport.polarizability.value_si, self.polarizability.value_si, 6) def test_rotrelaxcollnum(self): """ Test that the TransportData rotrelaxcollnum property was properly set. """ self.assertAlmostEqual(self.transport.rotrelaxcollnum, self.rotrelaxcollnum, 6) def test_comment(self): """ Test that the TransportData comment property was properly set. """ self.assertEqual(self.transport.comment, self.comment) def test_getCollisionFrequency(self): """ Test the LennardJones.getCollisionFrequency() method. """ T = 1000; P = 1.0e5 M = P / constants.R / T mu = 1.0 omega = self.transport.getCollisionFrequency(T, M, mu) self.assertAlmostEqual(omega / 1.17737e10, 1.0, 4) def test_pickle(self): """ Test that a TransportData object can be pickled and unpickled with no loss of information. """ import cPickle transport = cPickle.loads(cPickle.dumps(self.transport,-1)) self.assertAlmostEqual(self.transport.shapeIndex, transport.shapeIndex, 4) self.assertAlmostEqual(self.transport.epsilon.value_si, transport.epsilon.value_si, 4) self.assertAlmostEqual(self.transport.sigma.value_si, transport.sigma.value_si, 4) self.assertAlmostEqual(self.transport.dipoleMoment.value_si, transport.dipoleMoment.value_si, 4) self.assertAlmostEqual(self.transport.polarizability.value_si, transport.polarizability.value_si, 4) self.assertAlmostEqual(self.transport.rotrelaxcollnum, transport.rotrelaxcollnum, 4) self.assertEqual(self.transport.comment, transport.comment) def test_repr(self): """ Test that a TransportData object can be reconstructed from its repr() output with no loss of information """ transport = None exec('transport = {0!r}'.format(self.transport)) self.assertAlmostEqual(self.transport.shapeIndex, transport.shapeIndex, 4) self.assertAlmostEqual(self.transport.epsilon.value_si, transport.epsilon.value_si, 4) self.assertAlmostEqual(self.transport.sigma.value_si, transport.sigma.value_si, 4) self.assertAlmostEqual(self.transport.dipoleMoment.value_si, transport.dipoleMoment.value_si, 4) self.assertAlmostEqual(self.transport.polarizability.value_si, transport.polarizability.value_si, 4) self.assertAlmostEqual(self.transport.rotrelaxcollnum, transport.rotrelaxcollnum, 4) self.assertEqual(self.transport.comment, transport.comment) def test_toCantera(self): """ Test that the Cantera GasTransportData creation is successful. """ transport = 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_ctTransport = transport.toCantera() import cantera as ct ctSpecies = ct.Species.fromCti("""species(name=u'Ar', atoms='Ar:1', transport=gas_transport(geom='atom', diam=3.33, well_depth=136.501, dipole=2.0, polar=1.0, rot_relax=15.0))""") ctTransport = ctSpecies.transport self.assertAlmostEqual(rmg_ctTransport.geometry, ctTransport.geometry) self.assertAlmostEqual(rmg_ctTransport.acentric_factor, ctTransport.acentric_factor) self.assertAlmostEqual(rmg_ctTransport.diameter, ctTransport.diameter) self.assertAlmostEqual(rmg_ctTransport.dipole, ctTransport.dipole) self.assertAlmostEqual(rmg_ctTransport.polarizability, ctTransport.polarizability) self.assertAlmostEqual(rmg_ctTransport.rotational_relaxation, ctTransport.rotational_relaxation) self.assertAlmostEqual(rmg_ctTransport.well_depth, ctTransport.well_depth)
def setUp(self): """ A method that is run before each unit test in this class. """ self.species = Species( index=1, label='C2H4', thermo=ThermoData( Tdata=([300.0, 400.0, 500.0, 600.0, 800.0, 1000.0, 1500.0], 'K'), Cpdata=([3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 15.0], 'cal/(mol*K)'), H298=(-20.0, 'kcal/mol'), S298=(50.0, 'cal/(mol*K)'), Tmin=(300.0, 'K'), Tmax=(2000.0, 'K'), ), conformer=Conformer( E0=(0.0, 'kJ/mol'), modes=[ IdealGasTranslation(mass=(28.03, 'amu')), NonlinearRotor( inertia=([5.6952e-47, 2.7758e-46, 3.3454e-46], 'kg*m^2'), symmetry=1), HarmonicOscillator(frequencies=([ 834.50, 973.31, 975.37, 1067.1, 1238.5, 1379.5, 1472.3, 1691.3, 3121.6, 3136.7, 3192.5, 3221.0 ], 'cm^-1')), ], spin_multiplicity=1, optical_isomers=1, ), molecule=[Molecule().from_smiles('C=C')], transport_data=TransportData(sigma=(1, 'angstrom'), epsilon=(100, 'K')), molecular_weight=(28.03, 'amu'), reactive=True, ) self.species2 = Species().from_adjacency_list(""" 1 C u0 p0 c0 {2,D} {6,S} {7,S} 2 C u0 p0 c0 {1,D} {3,S} {8,S} 3 C u0 p0 c0 {2,S} {4,D} {9,S} 4 C u0 p0 c0 {3,D} {5,S} {10,S} 5 C u0 p0 c0 {4,S} {6,D} {11,S} 6 C u0 p0 c0 {1,S} {5,D} {12,S} 7 H u0 p0 c0 {1,S} 8 H u0 p0 c0 {2,S} 9 H u0 p0 c0 {3,S} 10 H u0 p0 c0 {4,S} 11 H u0 p0 c0 {5,S} 12 H u0 p0 c0 {6,S} """) self.species3 = Species().from_adjacency_list(""" multiplicity 2 1 O u1 p2 c0 {3,S} 2 O u0 p2 c0 {3,D} 3 N u0 p1 c0 {1,S} {2,D} """) self.species4 = Species().from_adjacency_list(""" Propane multiplicity 1 1 C u0 p0 c0 {2,S} {4,S} {5,S} {6,S} 2 C u0 p0 c0 {1,S} {3,S} {7,S} {8,S} 3 C u0 p0 c0 {2,S} {9,S} {10,S} {11,S} 4 H u0 p0 c0 {1,S} 5 H u0 p0 c0 {1,S} 6 H u0 p0 c0 {1,S} 7 H u0 p0 c0 {2,S} 8 H u0 p0 c0 {2,S} 9 H u0 p0 c0 {3,S} 10 H u0 p0 c0 {3,S} 11 H u0 p0 c0 {3,S} """)
def test_reaction(self): """ Test loading a reaction from input file-like kew word arguments """ species(label='methoxy', structure=SMILES('C[O]'), E0=(9.44, 'kcal/mol'), modes=[ HarmonicOscillator(frequencies=( [758, 960, 1106, 1393, 1403, 1518, 2940, 3019, 3065], 'cm^-1')), NonlinearRotor(rotationalConstant=([0.916, 0.921, 5.251], "cm^-1"), symmetry=3, quantum=False), IdealGasTranslation(mass=(31.01843, "g/mol")) ], spinMultiplicity=2, opticalIsomers=1, molecularWeight=(31.01843, 'amu'), collisionModel=TransportData(sigma=(3.69e-10, 'm'), epsilon=(4.0, 'kJ/mol')), energyTransferModel=SingleExponentialDown(alpha0=(0.956, 'kJ/mol'), T0=(300, 'K'), n=0.95)) species(label='formaldehyde', E0=(28.69, 'kcal/mol'), molecularWeight=(30.0106, "g/mol"), collisionModel=TransportData(sigma=(3.69e-10, 'm'), epsilon=(4.0, 'kJ/mol')), energyTransferModel=SingleExponentialDown(alpha0=(0.956, 'kJ/mol'), T0=(300, 'K'), n=0.95), spinMultiplicity=1, opticalIsomers=1, modes=[ HarmonicOscillator( frequencies=([1180, 1261, 1529, 1764, 2931, 2999], 'cm^-1')), NonlinearRotor(rotationalConstant=([ 1.15498821005263, 1.3156969584727, 9.45570474524524 ], "cm^-1"), symmetry=2, quantum=False), IdealGasTranslation(mass=(30.0106, "g/mol")) ]) species(label='H', E0=(0.000, 'kcal/mol'), molecularWeight=(1.00783, "g/mol"), collisionModel=TransportData(sigma=(3.69e-10, 'm'), epsilon=(4.0, 'kJ/mol')), energyTransferModel=SingleExponentialDown(alpha0=(0.956, 'kJ/mol'), T0=(300, 'K'), n=0.95), modes=[IdealGasTranslation(mass=(1.00783, "g/mol"))], spinMultiplicity=2, opticalIsomers=1) transitionState( label='TS3', E0=(34.1, 'kcal/mol'), spinMultiplicity=2, opticalIsomers=1, frequency=(-967, 'cm^-1'), modes=[ HarmonicOscillator(frequencies=( [466, 581, 1169, 1242, 1499, 1659, 2933, 3000], 'cm^-1')), NonlinearRotor(rotationalConstant=([0.970, 1.029, 3.717], "cm^-1"), symmetry=1, quantum=False), IdealGasTranslation(mass=(31.01843, "g/mol")) ]) reactants = ['formaldehyde', 'H'] products = ['methoxy'] tunneling = 'Eckart' rxn = reaction('CH2O+H=Methoxy', reactants, products, 'TS3', tunneling=tunneling) self.assertEqual(rxn.label, 'CH2O+H=Methoxy') self.assertEqual(len(rxn.reactants), 2) self.assertEqual(len(rxn.products), 1) self.assertAlmostEqual(rxn.reactants[0].conformer.E0.value_si, 0) self.assertAlmostEqual(rxn.reactants[1].conformer.E0.value_si, 120038.96) self.assertAlmostEqual(rxn.products[0].conformer.E0.value_si, 39496.96) self.assertAlmostEqual(rxn.transition_state.conformer.E0.value_si, 142674.4) self.assertAlmostEqual(rxn.transition_state.frequency.value_si, -967.0) self.assertIsInstance(rxn.transition_state.tunneling, Eckart)