Ejemplo n.º 1
0
    def generateConditions(self, reactorTypeList, reactionTimeList, molFracList, Tlist=None, Plist=None, Vlist=None):
        """
        Creates a list of conditions from from the lists provided. 
        
        ======================= ====================================================
        Argument                Description
        ======================= ====================================================
        `reactorTypeList`        A list of strings of the cantera reactor type. List of supported types below:
            IdealGasReactor: A constant volume, zero-dimensional reactor for ideal gas mixtures
            IdealGasConstPressureReactor: A homogeneous, constant pressure, zero-dimensional reactor for ideal gas mixtures

        `reactionTimeList`      A tuple object giving the ([list of reaction times], units)
        `molFracList`           A list of molfrac dictionaries with species object keys
                               and mole fraction values
        To specify the system for an ideal gas, you must define 2 of the following 3 parameters:
        `T0List`                A tuple giving the ([list of initial temperatures], units)
        'P0List'                A tuple giving the ([list of initial pressures], units)
        'V0List'                A tuple giving the ([list of initial specific volumes], units)
        
        This saves all the reaction conditions into both the old and new cantera jobs.
        """
        # Store the conditions in the observables test case, for bookkeeping
        self.conditions = generateCanteraConditions(reactorTypeList, reactionTimeList, molFracList, Tlist=Tlist, Plist=Plist, Vlist=Vlist)

        # Map the mole fractions dictionaries to species objects from the old and new models
        oldMolFracList = []
        newMolFracList = []

        for molFracCondition in molFracList:
            oldCondition = {}
            newCondition = {} 
            oldSpeciesDict = getRMGSpeciesFromUserSpecies(molFracCondition.keys(), self.oldSim.speciesList)
            newSpeciesDict = getRMGSpeciesFromUserSpecies(molFracCondition.keys(), self.newSim.speciesList)
            for smiles, molfrac in molFracCondition.iteritems():
                if oldSpeciesDict[smiles] is None:
                    raise Exception('SMILES {0} was not found in the old model!'.format(smiles))
                if newSpeciesDict[smiles] is None:
                    raise Exception('SMILES {0} was not found in the new model!'.format(smiles))

                oldCondition[oldSpeciesDict[smiles]] = molfrac
                newCondition[newSpeciesDict[smiles]] = molfrac
            oldMolFracList.append(oldCondition)
            newMolFracList.append(newCondition)
        
        # Generate the conditions in each simulation
        self.oldSim.generateConditions(reactorTypeList, reactionTimeList, oldMolFracList, Tlist=Tlist, Plist=Plist, Vlist=Vlist)
        self.newSim.generateConditions(reactorTypeList, reactionTimeList, newMolFracList, Tlist=Tlist, Plist=Plist, Vlist=Vlist)
Ejemplo n.º 2
0
    def generateConditions(self, reactorTypeList, reactionTimeList, molFracList, Tlist=None, Plist=None, Vlist=None):
        """
        Creates a list of conditions from from the lists provided. 
        
        ======================= ====================================================
        Argument                Description
        ======================= ====================================================
        `reactorTypeList`        A list of strings of the cantera reactor type. List of supported types below:
            IdealGasReactor: A constant volume, zero-dimensional reactor for ideal gas mixtures
            IdealGasConstPressureReactor: A homogeneous, constant pressure, zero-dimensional reactor for ideal gas mixtures

        `reactionTimeList`      A tuple object giving the ([list of reaction times], units)
        `molFracList`           A list of molfrac dictionaries with species object keys
                               and mole fraction values
        To specify the system for an ideal gas, you must define 2 of the following 3 parameters:
        `T0List`                A tuple giving the ([list of initial temperatures], units)
        'P0List'                A tuple giving the ([list of initial pressures], units)
        'V0List'                A tuple giving the ([list of initial specific volumes], units)
        
        This saves all the reaction conditions into both the old and new cantera jobs.
        """
        # Store the conditions in the observables test case, for bookkeeping
        self.conditions = generateCanteraConditions(reactorTypeList, reactionTimeList, molFracList, Tlist=Tlist, Plist=Plist, Vlist=Vlist)

        # Map the mole fractions dictionaries to species objects from the old and new models
        oldMolFracList = []
        newMolFracList = []

        for molFracCondition in molFracList:
            oldCondition = {}
            newCondition = {} 
            oldSpeciesDict = getRMGSpeciesFromUserSpecies(molFracCondition.keys(), self.oldSim.speciesList)
            newSpeciesDict = getRMGSpeciesFromUserSpecies(molFracCondition.keys(), self.newSim.speciesList)
            for smiles, molfrac in molFracCondition.iteritems():
                if oldSpeciesDict[smiles] is None:
                    raise Exception('SMILES {0} was not found in the old model!'.format(smiles))
                if newSpeciesDict[smiles] is None:
                    raise Exception('SMILES {0} was not found in the new model!'.format(smiles))

                oldCondition[oldSpeciesDict[smiles]] = molfrac
                newCondition[newSpeciesDict[smiles]] = molfrac
            oldMolFracList.append(oldCondition)
            newMolFracList.append(newCondition)
        
        # Generate the conditions in each simulation
        self.oldSim.generateConditions(reactorTypeList, reactionTimeList, oldMolFracList, Tlist=Tlist, Plist=Plist, Vlist=Vlist)
        self.newSim.generateConditions(reactorTypeList, reactionTimeList, newMolFracList, Tlist=Tlist, Plist=Plist, Vlist=Vlist)
Ejemplo n.º 3
0
    def compare(self, tol, plot=False):
        """
        Compare the old and new model
        'tol':  average error acceptable between old and new model for variables
        `plot`: if set to True, it will comparison plots of the two models comparing their species.

        Returns a list of variables failed in a list of tuples in the format:
        
        (CanteraCondition, variable label, variableOld, variableNew)

        """
        # Ignore Inerts
        inertList = ['[Ar]','[He]','[N#N]','[Ne]']

        oldConditionData, newConditionData = self.runSimulations()

        conditionsBroken=[]
        variablesFailed=[]
        
        print ''
        print '{0} Comparison'.format(self)
        print '================'
        # Check the species profile observables
        if 'species' in self.observables:
            oldSpeciesDict = getRMGSpeciesFromUserSpecies(self.observables['species'], self.oldSim.speciesList)
            newSpeciesDict = getRMGSpeciesFromUserSpecies(self.observables['species'], self.newSim.speciesList)
        
        # Check state variable observables 
        implementedVariables = ['temperature','pressure']
        if 'variable' in self.observables:
            for item in self.observables['variable']:
                if item.lower() not in implementedVariables:
                    print 'Observable variable {0} not yet implemented'.format(item)
                    
        failHeader='\nThe following observables did not match:\n'
        failHeaderPrinted=False
        for i in range(len(oldConditionData)):
            timeOld, dataListOld = oldConditionData[i]
            timeNew, dataListNew = newConditionData[i]

            # Compare species observables
            if 'species' in self.observables:
                smilesList=[] #This is to make sure we don't have species with duplicate smiles
                multiplicityList=['','(S)','(D)','(T)','(Q)'] #list ot add multiplcity
                for species in self.observables['species']:

                    smiles=species.molecule[0].toSMILES() #For purpose of naming the plot only
                    if smiles in smilesList: smiles=smiles+multiplicityList[species.molecule[0].multiplicity]
                    smilesList.append(smiles)
                    
                    fail = False
                    oldRmgSpecies = oldSpeciesDict[species]
                    newRmgSpecies = newSpeciesDict[species]
                    
                    if oldRmgSpecies:
                        variableOld = next((data for data in dataListOld if data.species == oldRmgSpecies), None)
                    else:
                        print 'No RMG species found for observable species {0} in old model.'.format(smiles)
                        fail = True
                    if newRmgSpecies:
                        variableNew = next((data for data in dataListNew if data.species == newRmgSpecies), None)
                    else:
                        print 'No RMG species found for observable species {0} in new model.'.format(smiles)
                        fail = True
                    
                    if fail is False:
                        if not curvesSimilar(timeOld.data, variableOld.data, timeNew.data, variableNew.data, tol):
                            fail = True
                            
                        # Try plotting only when species are found in both models
                        if plot:
                            oldSpeciesPlot = SimulationPlot(xVar=timeOld, yVar=variableOld)
                            newSpeciesPlot = SimulationPlot(xVar=timeNew, yVar=variableNew)
                            oldSpeciesPlot.comparePlot(newSpeciesPlot,
                                                       title='Observable Species {0} Comparison'.format(smiles),
                                                       ylabel='Mole Fraction',
                                                       filename='condition_{0}_species_{1}.png'.format(i+1,smiles))
                    
                    # Append to failed variables or conditions if this test failed
                    if fail:
                        if not failHeaderPrinted:
                            print failHeader
                            failHeaderPrinted=True
                        if i not in conditionsBroken: conditionsBroken.append(i)
                        print "Observable species {0} varied by more than {1:.3f} on average between old model {2} and \
new model {3} in condition {4:d}.".format(smiles,
                                          tol,
                                           variableOld.label, 
                                           variableNew.label,
                                           i+1)
                        variablesFailed.append((self.conditions[i], smiles, variableOld, variableNew))
                    
            
            # Compare state variable observables
            if 'variable' in self.observables:
                for varName in self.observables['variable']:
                    variableOld = next((data for data in dataListOld if data.label == varName), None)
                    variableNew = next((data for data in dataListNew if data.label == varName), None)
                    if not curvesSimilar(timeOld.data, variableOld.data, timeNew.data, variableNew.data, 0.05):
                        if i not in conditionsBroken: conditionsBroken.append(i)
                        if not failHeaderPrinted:
                            failHeaderPrinted=True
                            print failHeader

                        print "Observable variable {0} varied by more than {1:.3f} on average between old model and \
new model in condition {2:d}.".format(variableOld.label, i+1)
                        variablesFailed.append((self.conditions[i], tol, varName, variableOld, variableNew))
                    
                    if plot:
                        oldVarPlot = GenericPlot(xVar=timeOld, yVar=variableOld)
                        newVarPlot = GenericPlot(xVar=timeNew, yVar=variableNew)
                        oldVarPlot.comparePlot(newSpeciesPlot,
                                                   title='Observable Variable {0} Comparison'.format(varName),
                                                   filename='condition_{0}_variable_{1}.png'.format(i+1, varName))
                        
            # Compare ignition delay observables
            if 'ignitionDelay' in self.observables:
                print 'Ignition delay observable comparison not implemented yet.'
                
                
        if failHeaderPrinted:
            print ''
            print 'The following reaction conditions were had some discrepancies:'
            print ''
            for index in conditionsBroken:
                print "Condition {0:d}:".format(index+1)
                print str(self.conditions[index])
                print ''

            return variablesFailed
        else:
            print ''
            print 'All Observables varied by less than {0:.3f} on average between old model and \
new model in all conditions!'.format(tol)
            print ''
Ejemplo n.º 4
0
def run_cantera_job(
    smiles_dictionary,
    specie_initial_mol_frac,
    final_time,
    temp_initial,
    initial_p,
    chemkin_file='',
    species_dictionary_file='',
    transport_file=None,
    reactor_type='IdealGasConstPressureTemperatureReactor',
    time_units='s',
    temp_units='K',
    p_units='atm',
    species_list=None,
    reaction_list=None,
):
    """General function for running Cantera jobs from chemkin files with common defaults

    =========================== =======================================================================
    Input (Required)            Description
    =========================== =======================================================================
    smiles_dictionary           A dictionary with user names as keys and SMILES strings as values
    specie_initial_mol_frac     A dictionary with user specie names as keys and mol fractions as values
    final_time                  Termination time for the simulation
    temp_initial                Initial temperature for the simulation
    initial_p                   Initial pressure for the simulation
    =========================== =======================================================================
    Inputs with Defaults        Description
    =========================== =======================================================================
    chemkin_file                String relative path of the chem.inp or chem_annotated.inp file
    species_dictionary_file     String relative path of species_dictionary file
    reactor_type                String with Cantera reactor type
    time_units                  Default is s (min and h are also supported)
    temp_units                  Default is K (C is also supported)
    p_units                     Default is atm (bar and Pa are also supported)
    =========================== =======================================================================
    Optional Inputs             Description
    =========================== =======================================================================
    transport_file              String relative path of trans.dat file
    species_list                Output from loadChemkinFile for faster simulation (otherwise generated)
    reaction_list               Output from loadChemkinFile for faster simulation (otherwise generated)
    ===================================================================================================


    =========================== =======================================================================
    Output                      Description
    =========================== =======================================================================
    all_data                    Cantera Simulation Data Object [time, [temp, pressure, spc1, spc2,..]]
    ===================================================================================================
    """
    logging.info(
        'Running a cantera job using the chemkin file {}'.format(chemkin_file))

    logging.debug('loading chemkin and species dictionary file')
    cwd = os.getcwd()
    if chemkin_file == '':
        chemkin_file = os.path.join(cwd, 'chem_annotated.inp')

    if species_dictionary_file == '':
        species_dictionary_file = os.path.join(cwd, 'species_dictionary.txt')

    user_species_dictionary = create_species_from_smiles(smiles_dictionary)
    specie_initial_mol_frac = set_species_mol_fractions(
        specie_initial_mol_frac, user_species_dictionary)

    if (not species_list) or (not reaction_list):
        (species_list,
         reaction_list) = loadChemkinFile(chemkin_file,
                                          species_dictionary_file)

    name_dictionary = getRMGSpeciesFromUserSpecies(
        user_species_dictionary.values(), species_list)

    mol_fractions = {}
    for (user_name, chemkin_name) in name_dictionary.iteritems():
        try:
            mol_fractions[chemkin_name] = specie_initial_mol_frac[user_name]
        except KeyError:
            logging.debug(
                '{} initial mol fractions set to 0'.format(user_name))

    if temp_units == 'C':
        temp_initial += 273.0

    temp_initial = ([temp_initial], 'K')
    initial_p = ([initial_p], p_units)

    job = Cantera(speciesList=species_list,
                  reactionList=reaction_list,
                  outputDirectory='')
    job.loadChemkinModel(chemkin_file, transportFile=transport_file)
    job.generateConditions([reactor_type], ([final_time], time_units),
                           [mol_fractions], temp_initial, initial_p)

    logging.debug('Starting Cantera Simulation')
    all_data = job.simulate()
    all_data = all_data[0]
    logging.info('Cantera Simulation Complete')

    logging.debug('Setting labels to user defined species labels')

    species_index = {}
    for i in range(len(species_list)):
        species_index[species_list[i]] = i + 2

    user_index = {}
    for (user_name, specie) in user_species_dictionary.iteritems():
        try:
            user_index[species_index[name_dictionary[specie]]] = user_name
        except KeyError:
            logging.info('{0} is not in the model for {1}'.format(
                user_name, chemkin_file))

    for (indices, user_label) in user_index.iteritems():
        try:
            all_data[1][indices].label = user_label
        except KeyError:
            pass

    return all_data
Ejemplo n.º 5
0
    def compare(self, tol, plot=False):
        """
        Compare the old and new model
        'tol':  average error acceptable between old and new model for variables
        `plot`: if set to True, it will comparison plots of the two models comparing their species.

        Returns a list of variables failed in a list of tuples in the format:
        
        (CanteraCondition, variable label, variableOld, variableNew)

        """
        # Ignore Inerts
        inertList = ['[Ar]', '[He]', '[N#N]', '[Ne]']

        oldConditionData, newConditionData = self.runSimulations()

        conditionsBroken = []
        variablesFailed = []

        print ''
        print '{0} Comparison'.format(self)
        print '================'
        # Check the species profile observables
        if 'species' in self.observables:
            oldSpeciesDict = getRMGSpeciesFromUserSpecies(
                self.observables['species'], self.oldSim.speciesList)
            newSpeciesDict = getRMGSpeciesFromUserSpecies(
                self.observables['species'], self.newSim.speciesList)

        # Check state variable observables
        implementedVariables = ['temperature', 'pressure']
        if 'variable' in self.observables:
            for item in self.observables['variable']:
                if item.lower() not in implementedVariables:
                    print 'Observable variable {0} not yet implemented'.format(
                        item)

        failHeader = '\nThe following observables did not match:\n'
        failHeaderPrinted = False
        for i in range(len(oldConditionData)):
            timeOld, dataListOld = oldConditionData[i]
            timeNew, dataListNew = newConditionData[i]

            # Compare species observables
            if 'species' in self.observables:
                smilesList = [
                ]  #This is to make sure we don't have species with duplicate smiles
                multiplicityList = ['', '(S)', '(D)', '(T)',
                                    '(Q)']  #list ot add multiplcity
                for species in self.observables['species']:

                    smiles = species.molecule[0].toSMILES(
                    )  #For purpose of naming the plot only
                    if smiles in smilesList:
                        smiles = smiles + multiplicityList[
                            species.molecule[0].multiplicity]
                    smilesList.append(smiles)

                    fail = False
                    oldRmgSpecies = oldSpeciesDict[species]
                    newRmgSpecies = newSpeciesDict[species]

                    if oldRmgSpecies:
                        variableOld = next((data for data in dataListOld
                                            if data.species == oldRmgSpecies),
                                           None)
                    else:
                        print 'No RMG species found for observable species {0} in old model.'.format(
                            smiles)
                        fail = True
                    if newRmgSpecies:
                        variableNew = next((data for data in dataListNew
                                            if data.species == newRmgSpecies),
                                           None)
                    else:
                        print 'No RMG species found for observable species {0} in new model.'.format(
                            smiles)
                        fail = True

                    if fail is False:
                        if not curvesSimilar(timeOld.data, variableOld.data,
                                             timeNew.data, variableNew.data,
                                             tol):
                            fail = True

                        # Try plotting only when species are found in both models
                        if plot:
                            oldSpeciesPlot = SimulationPlot(xVar=timeOld,
                                                            yVar=variableOld)
                            newSpeciesPlot = SimulationPlot(xVar=timeNew,
                                                            yVar=variableNew)
                            oldSpeciesPlot.comparePlot(
                                newSpeciesPlot,
                                title='Observable Species {0} Comparison'.
                                format(smiles),
                                ylabel='Mole Fraction',
                                filename='condition_{0}_species_{1}.png'.
                                format(i + 1, smiles))

                    # Append to failed variables or conditions if this test failed
                    if fail:
                        if not failHeaderPrinted:
                            print failHeader
                            failHeaderPrinted = True
                        if i not in conditionsBroken:
                            conditionsBroken.append(i)
                        print "Observable species {0} varied by more than {1:.3f} on average between old model {2} and \
new model {3} in condition {4:d}.".format(smiles, tol, variableOld.label,
                                          variableNew.label, i + 1)
                        variablesFailed.append((self.conditions[i], smiles,
                                                variableOld, variableNew))

            # Compare state variable observables
            if 'variable' in self.observables:
                for varName in self.observables['variable']:
                    variableOld = next(
                        (data
                         for data in dataListOld if data.label == varName),
                        None)
                    variableNew = next(
                        (data
                         for data in dataListNew if data.label == varName),
                        None)
                    if not curvesSimilar(timeOld.data, variableOld.data,
                                         timeNew.data, variableNew.data, 0.05):
                        if i not in conditionsBroken:
                            conditionsBroken.append(i)
                        if not failHeaderPrinted:
                            failHeaderPrinted = True
                            print failHeader

                        print "Observable variable {0} varied by more than {1:.3f} on average between old model and \
new model in condition {2:d}.".format(variableOld.label, i + 1)
                        variablesFailed.append(
                            (self.conditions[i], tol, varName, variableOld,
                             variableNew))

                    if plot:
                        oldVarPlot = GenericPlot(xVar=timeOld,
                                                 yVar=variableOld)
                        newVarPlot = GenericPlot(xVar=timeNew,
                                                 yVar=variableNew)
                        oldVarPlot.comparePlot(
                            newSpeciesPlot,
                            title='Observable Variable {0} Comparison'.format(
                                varName),
                            filename='condition_{0}_variable_{1}.png'.format(
                                i + 1, varName))

            # Compare ignition delay observables
            if 'ignitionDelay' in self.observables:
                print 'Ignition delay observable comparison not implemented yet.'

        if failHeaderPrinted:
            print ''
            print 'The following reaction conditions were had some discrepancies:'
            print ''
            for index in conditionsBroken:
                print "Condition {0:d}:".format(index + 1)
                print str(self.conditions[index])
                print ''

            return variablesFailed
        else:
            print ''
            print 'All Observables varied by less than {0:.3f} on average between old model and \
new model in all conditions!'.format(tol)
            print ''