예제 #1
0
 def _run_statmech(self,
                   arkane_spc,
                   arkane_file,
                   output_file_path=None,
                   use_bac=False,
                   kinetics=False,
                   plot=False):
     """
     A helper function for running an Arkane statmech job
     `arkane_spc` is the species() function from Arkane's input.py
     `arkane_file` is the Arkane species file (either .py or YAML form)
     `output_file_path` is a path to the Arkane output.py file
     `use_bac` is a bool flag indicating whether or not to use bond additivity corrections
     `kinetics` is a bool flag indicating whether this specie sis part of a kinetics job, in which case..??
     `plot` is a bool flag indicating whether or not to plot a PDF of the calculated thermo properties
     """
     success = True
     stat_mech_job = StatMechJob(arkane_spc, arkane_file)
     stat_mech_job.applyBondEnergyCorrections = use_bac and not kinetics and self.model_chemistry
     if not kinetics or kinetics and self.model_chemistry:
         # currently we have to use a model chemistry for thermo
         stat_mech_job.modelChemistry = self.model_chemistry
     else:
         # if this is a klinetics computation and we don't have a valid model chemistry, don't bother about it
         stat_mech_job.applyAtomEnergyCorrections = False
     stat_mech_job.frequencyScaleFactor = assign_frequency_scale_factor(
         self.model_chemistry)
     try:
         stat_mech_job.execute(outputFile=output_file_path, plot=plot)
     except Exception:
         success = False
     return success
예제 #2
0
    def _run_statmech(self, arkane_spc, arkane_file, output_path=None, use_bac=False, kinetics=False, plot=False):
        """
        A helper function for running an Arkane statmech job.

        Args:
            arkane_spc (str): An Arkane species() function representor.
            arkane_file (str): The path to the Arkane species file (either in .py or YAML form).
            output_path (str): The path to the folder containing the Arkane output.py file.
            use_bac (bool): A flag indicating whether or not to use bond additivity corrections (True to use).
            kinetics (bool) A flag indicating whether this specie is part of a kinetics job.
            plot (bool): A flag indicating whether to plot a PDF of the calculated thermo properties (True to plot)

        Returns:
            bool: Whether the job was successful (True for successful).
        """
        success = True
        stat_mech_job = StatMechJob(arkane_spc, arkane_file)
        stat_mech_job.applyBondEnergyCorrections = use_bac and not kinetics and self.sp_level
        if not kinetics or (kinetics and self.sp_level):
            # currently we have to use a model chemistry for thermo
            stat_mech_job.modelChemistry = self.sp_level
        else:
            # if this is a kinetics computation and we don't have a valid model chemistry, don't bother about it
            stat_mech_job.applyAtomEnergyCorrections = False
        # Use the scaling factor if given, else try determining it from Arkane
        # (defaults to 1 and prints a warning if not found)
        stat_mech_job.frequencyScaleFactor = self.freq_scale_factor or assign_frequency_scale_factor(self.freq_level)
        try:
            stat_mech_job.execute(output_directory=os.path.join(output_path, 'output.py'), plot=plot)
        except Exception:
            success = False
        return success
예제 #3
0
파일: input.py 프로젝트: qize/RMG-Py
def load_input_file(path):
    """
    Load the Arkane input file located at `path` on disk, and return a list of
    the jobs defined in that file.
    """
    global species_dict, transition_state_dict, reaction_dict, network_dict, job_list

    # Clear module-level variables
    species_dict, transition_state_dict, reaction_dict, network_dict = dict(
    ), dict(), dict(), dict()
    job_list = []

    global_context = {'__builtins__': None}
    local_context = {
        '__builtins__': None,
        'True': True,
        'False': False,
        'range': range,
        # Collision
        'TransportData': TransportData,
        'SingleExponentialDown': SingleExponentialDown,
        # Kinetics
        'Arrhenius': Arrhenius,
        # Statistical mechanics
        'IdealGasTranslation': IdealGasTranslation,
        'LinearRotor': LinearRotor,
        'NonlinearRotor': NonlinearRotor,
        'KRotor': KRotor,
        'SphericalTopRotor': SphericalTopRotor,
        'HarmonicOscillator': HarmonicOscillator,
        'HinderedRotor': HinderedRotor,
        'FreeRotor': FreeRotor,
        # Thermo
        'ThermoData': ThermoData,
        'Wilhoit': Wilhoit,
        'NASA': NASA,
        'NASAPolynomial': NASAPolynomial,
        # Functions
        'reaction': reaction,
        'species': species,
        'transitionState': transitionState,
        'network': network,
        'database': database,
        # Jobs
        'kinetics': kinetics,
        'statmech': statmech,
        'thermo': thermo,
        'pressureDependence': pressureDependence,
        'explorer': explorer,
        # Miscellaneous
        'SMILES': SMILES,
        'adjacencyList': adjacencyList,
        'InChI': InChI,
    }

    load_necessary_databases()

    with open(path, 'r') as f:
        try:
            exec(f.read(), global_context, local_context)
        except (NameError, TypeError, SyntaxError):
            logging.error('The input file {0!r} was invalid:'.format(path))
            raise

    model_chemistry = local_context.get('modelChemistry', '').lower()
    sp_level, freq_level = process_model_chemistry(model_chemistry)

    author = local_context.get('author', '')
    if 'frequencyScaleFactor' in local_context:
        frequency_scale_factor = local_context.get('frequencyScaleFactor')
    else:
        logging.debug(
            'Tying to assign a frequencyScaleFactor according to the frequency '
            'level of theory {0}'.format(freq_level))
        frequency_scale_factor = assign_frequency_scale_factor(freq_level)
    use_hindered_rotors = local_context.get('useHinderedRotors', True)
    use_atom_corrections = local_context.get('useAtomCorrections', True)
    use_bond_corrections = local_context.get('useBondCorrections', False)
    bac_type = local_context.get('bondCorrectionType', 'p')
    atom_energies = local_context.get('atomEnergies', None)

    directory = os.path.dirname(path)

    for rxn in reaction_dict.values():
        rxn.elementary_high_p = True

    for job in job_list:
        if isinstance(job, StatMechJob):
            job.path = os.path.join(directory, job.path)
            job.modelChemistry = sp_level
            job.frequencyScaleFactor = frequency_scale_factor
            job.includeHinderedRotors = use_hindered_rotors
            job.applyAtomEnergyCorrections = use_atom_corrections
            job.applyBondEnergyCorrections = use_bond_corrections
            job.bondEnergyCorrectionType = bac_type
            job.atomEnergies = atom_energies
        if isinstance(job, ThermoJob):
            job.arkane_species.author = author
            job.arkane_species.level_of_theory = model_chemistry
            job.arkane_species.frequency_scale_factor = frequency_scale_factor
            job.arkane_species.use_hindered_rotors = use_hindered_rotors
            job.arkane_species.use_bond_corrections = use_bond_corrections
            if atom_energies is not None:
                job.arkane_species.atom_energies = atom_energies

    return job_list, reaction_dict, species_dict, transition_state_dict, network_dict
예제 #4
0
    def process(self):
        """Process ARC outputs and generate thermo and kinetics"""
        # Thermo:
        species_list_for_thermo_parity = list()
        species_for_thermo_lib = list()
        for species in self.species_dict.values():
            if not species.is_ts and 'ALL converged' in self.output[
                    species.label]['status']:
                species_for_thermo_lib.append(species)
                output_file_path = self._generate_arkane_species_file(species)
                arkane_spc = arkane_species(str(species.label),
                                            species.arkane_file)
                if species.mol_list:
                    arkane_spc.molecule = species.mol_list
                stat_mech_job = StatMechJob(arkane_spc, species.arkane_file)
                stat_mech_job.applyBondEnergyCorrections = self.use_bac
                stat_mech_job.modelChemistry = self.model_chemistry
                stat_mech_job.frequencyScaleFactor = assign_frequency_scale_factor(
                    self.model_chemistry)
                stat_mech_job.execute(outputFile=output_file_path, plot=False)
                if species.generate_thermo:
                    thermo_job = ThermoJob(arkane_spc, 'NASA')
                    thermo_job.execute(outputFile=output_file_path, plot=False)
                    species.thermo = arkane_spc.getThermoData()
                    plotter.log_thermo(species.label, path=output_file_path)

                species.rmg_species = Species(molecule=[species.mol])
                species.rmg_species.reactive = True
                if species.mol_list:
                    species.rmg_species.molecule = species.mol_list  # add resonance structures for thermo determination
                try:
                    species.rmg_thermo = self.rmgdb.thermo.getThermoData(
                        species.rmg_species)
                except ValueError:
                    logging.info(
                        'Could not retrieve RMG thermo for species {0}, possibly due to missing 2D structure '
                        '(bond orders). Not including this species in the parity plots.'
                        .format(species.label))
                else:
                    if species.generate_thermo:
                        species_list_for_thermo_parity.append(species)
        # Kinetics:
        rxn_list_for_kinetics_plots = list()
        arkane_spc_dict = dict()  # a dictionary with all species and the TSs
        for rxn in self.rxn_list:
            logging.info('\n\n')
            species = self.species_dict[rxn.ts_label]  # The TS
            if 'ALL converged' in self.output[
                    species.label]['status'] and rxn.check_ts():
                self.copy_freq_output_for_ts(species.label)
                success = True
                rxn_list_for_kinetics_plots.append(rxn)
                output_file_path = self._generate_arkane_species_file(species)
                arkane_ts = arkane_transition_state(str(species.label),
                                                    species.arkane_file)
                arkane_spc_dict[species.label] = arkane_ts
                stat_mech_job = StatMechJob(arkane_ts, species.arkane_file)
                stat_mech_job.applyBondEnergyCorrections = False
                if not self.model_chemistry:
                    stat_mech_job.modelChemistry = self.model_chemistry
                else:
                    stat_mech_job.applyAtomEnergyCorrections = False
                stat_mech_job.frequencyScaleFactor = assign_frequency_scale_factor(
                    self.model_chemistry)
                stat_mech_job.execute(outputFile=None, plot=False)
                for spc in rxn.r_species + rxn.p_species:
                    if spc.label not in arkane_spc_dict.keys():
                        # add an extra character to the arkane_species label to distinguish between species calculated
                        #  for thermo and species calculated for kinetics (where we don't want to use BAC)
                        arkane_spc = arkane_species(str(spc.label + '_'),
                                                    spc.arkane_file)
                        stat_mech_job = StatMechJob(arkane_spc,
                                                    spc.arkane_file)
                        arkane_spc_dict[spc.label] = arkane_spc
                        stat_mech_job.applyBondEnergyCorrections = False
                        if not self.model_chemistry:
                            stat_mech_job.modelChemistry = self.model_chemistry
                        else:
                            stat_mech_job.applyAtomEnergyCorrections = False
                        stat_mech_job.frequencyScaleFactor = assign_frequency_scale_factor(
                            self.model_chemistry)
                        stat_mech_job.execute(outputFile=None, plot=False)
                        # thermo_job = ThermoJob(arkane_spc, 'NASA')
                        # thermo_job.execute(outputFile=None, plot=False)
                        # arkane_spc.thermo = arkane_spc.getThermoData()
                rxn.dh_rxn298 = sum([product.thermo.getEnthalpy(298) for product in arkane_spc_dict.values()
                                     if product.label in rxn.products])\
                                - sum([reactant.thermo.getEnthalpy(298) for reactant in arkane_spc_dict.values()
                                       if reactant.label in rxn.reactants])
                arkane_rxn = arkane_reaction(
                    label=str(rxn.label),
                    reactants=[
                        str(label + '_') for label in arkane_spc_dict.keys()
                        if label in rxn.reactants
                    ],
                    products=[
                        str(label + '_') for label in arkane_spc_dict.keys()
                        if label in rxn.products
                    ],
                    transitionState=rxn.ts_label,
                    tunneling='Eckart')
                kinetics_job = KineticsJob(reaction=arkane_rxn,
                                           Tmin=self.t_min,
                                           Tmax=self.t_max,
                                           Tcount=self.t_count)
                logging.info('Calculating rate for reaction {0}'.format(
                    rxn.label))
                try:
                    kinetics_job.execute(outputFile=output_file_path,
                                         plot=False)
                except ValueError as e:
                    """
                    ValueError: One or both of the barrier heights of -9.35259 and 62.6834 kJ/mol encountered in Eckart
                    method are invalid.
                    """
                    logging.error(
                        'Failed to generate kinetics for {0} with message:\n{1}'
                        .format(rxn.label, e))
                    success = False
                if success:
                    rxn.kinetics = kinetics_job.reaction.kinetics
                    plotter.log_kinetics(species.label, path=output_file_path)
                    rxn.rmg_reactions = rmgdb.determine_rmg_kinetics(
                        rmgdb=self.rmgdb,
                        reaction=rxn.rmg_reaction,
                        dh_rxn298=rxn.dh_rxn298)

        logging.info('\n\n')
        output_dir = os.path.join(self.project_directory, 'output')

        if species_list_for_thermo_parity:
            plotter.draw_thermo_parity_plots(species_list_for_thermo_parity,
                                             path=output_dir)
            libraries_path = os.path.join(output_dir, 'RMG libraries')
            # species_list = [spc for spc in self.species_dict.values()]
            plotter.save_thermo_lib(species_for_thermo_lib,
                                    path=libraries_path,
                                    name=self.project,
                                    lib_long_desc=self.lib_long_desc)
        if rxn_list_for_kinetics_plots:
            plotter.draw_kinetics_plots(rxn_list_for_kinetics_plots,
                                        path=output_dir,
                                        t_min=self.t_min,
                                        t_max=self.t_max,
                                        t_count=self.t_count)
            libraries_path = os.path.join(output_dir, 'RMG libraries')
            plotter.save_kinetics_lib(rxn_list=rxn_list_for_kinetics_plots,
                                      path=libraries_path,
                                      name=self.project,
                                      lib_long_desc=self.lib_long_desc)

        self.clean_output_directory()
예제 #5
0
파일: input.py 프로젝트: z5476t4508/RMG-Py
    with open(path, 'r') as f:
        try:
            exec f in global_context, local_context
        except (NameError, TypeError, SyntaxError), e:
            logging.error('The input file {0!r} was invalid:'.format(path))
            raise

    model_chemistry = local_context.get('modelChemistry', '')
    level_of_theory = local_context.get('levelOfTheory', '')
    author = local_context.get('author', '')
    if 'frequencyScaleFactor' not in local_context:
        logging.debug(
            'Assigning a frequencyScaleFactor according to the modelChemistry...'
        )
        frequency_scale_factor = assign_frequency_scale_factor(model_chemistry)
    else:
        frequency_scale_factor = local_context.get('frequencyScaleFactor')
    use_hindered_rotors = local_context.get('useHinderedRotors', True)
    use_atom_corrections = local_context.get('useAtomCorrections', True)
    use_bond_corrections = local_context.get('useBondCorrections', False)
    atom_energies = local_context.get('atomEnergies', None)

    directory = os.path.dirname(path)

    for rxn in reactionDict.values():
        rxn.elementary_high_p = True

    for job in jobList:
        if isinstance(job, StatMechJob):
            job.path = os.path.join(directory, job.path)
예제 #6
0
        'InChI': InChI,
    }

    loadNecessaryDatabases()

    with open(path, 'r') as f:
        try:
            exec f in global_context, local_context
        except (NameError, TypeError, SyntaxError), e:
            logging.error('The input file {0!r} was invalid:'.format(path))
            raise

    modelChemistry = local_context.get('modelChemistry', '')
    if 'frequencyScaleFactor' not in local_context:
        logging.debug('Assigning a frequencyScaleFactor according to the modelChemistry...')
        frequencyScaleFactor = assign_frequency_scale_factor(modelChemistry)
    else:
        frequencyScaleFactor = local_context.get('frequencyScaleFactor')
    useHinderedRotors = local_context.get('useHinderedRotors', True)
    useAtomCorrections = local_context.get('useAtomCorrections', True)
    useBondCorrections = local_context.get('useBondCorrections', False)
    atomEnergies = local_context.get('atomEnergies', None)
    
    directory = os.path.dirname(path)
    
    for rxn in reactionDict.values():
        rxn.elementary_high_p = True
        
    for job in jobList:
        if isinstance(job, StatMechJob):
            job.path = os.path.join(directory, job.path)
예제 #7
0
def loadInputFile(path):
    """
    Load the Arkane input file located at `path` on disk, and return a list of
    the jobs defined in that file.
    """
    global speciesDict, transitionStateDict, reactionDict, networkDict, jobList
    
    # Clear module-level variables
    speciesDict = {}
    transitionStateDict = {}
    reactionDict = {}
    networkDict = {}
    jobList = []
    
    global_context = { '__builtins__': None }
    local_context = {
        '__builtins__': None,
        'True': True,
        'False': False,
        'range': range,
        # Collision
        'TransportData': TransportData,
        'SingleExponentialDown': SingleExponentialDown,
        # Kinetics
        'Arrhenius': Arrhenius,
        # Statistical mechanics
        'IdealGasTranslation': IdealGasTranslation,
        'LinearRotor': LinearRotor,
        'NonlinearRotor': NonlinearRotor,
        'KRotor': KRotor,
        'SphericalTopRotor': SphericalTopRotor,
        'HarmonicOscillator': HarmonicOscillator,
        'HinderedRotor': HinderedRotor,
        'FreeRotor':FreeRotor,
        # Thermo
        'ThermoData': ThermoData,
        'Wilhoit': Wilhoit,
        'NASA': NASA,
        'NASAPolynomial': NASAPolynomial,
        # Functions
        'reaction': reaction,
        'species': species,
        'transitionState': transitionState,
        'network': network,
        'database': database,
        # Jobs
        'kinetics': kinetics,
        'statmech': statmech,
        'thermo': thermo,
        'pressureDependence': pressureDependence,
        'explorer':explorer,
        # Miscellaneous
        'SMILES': SMILES,
        'adjacencyList': adjacencyList,
        'InChI': InChI,
    }

    loadNecessaryDatabases()

    with open(path, 'r') as f:
        try:
            exec f in global_context, local_context
        except (NameError, TypeError, SyntaxError):
            logging.error('The input file {0!r} was invalid:'.format(path))
            raise

    model_chemistry = local_context.get('modelChemistry', '')
    level_of_theory = local_context.get('levelOfTheory', '')
    author = local_context.get('author', '')
    if 'frequencyScaleFactor' not in local_context:
        logging.debug('Assigning a frequencyScaleFactor according to the modelChemistry...')
        frequency_scale_factor = assign_frequency_scale_factor(model_chemistry)
    else:
        frequency_scale_factor = local_context.get('frequencyScaleFactor')
    use_hindered_rotors = local_context.get('useHinderedRotors', True)
    use_atom_corrections = local_context.get('useAtomCorrections', True)
    use_bond_corrections = local_context.get('useBondCorrections', False)
    atom_energies = local_context.get('atomEnergies', None)
    
    directory = os.path.dirname(path)
    
    for rxn in reactionDict.values():
        rxn.elementary_high_p = True
        
    for job in jobList:
        if isinstance(job, StatMechJob):
            job.path = os.path.join(directory, job.path)
            job.modelChemistry = model_chemistry.lower()
            job.frequencyScaleFactor = frequency_scale_factor
            job.includeHinderedRotors = use_hindered_rotors
            job.applyAtomEnergyCorrections = use_atom_corrections
            job.applyBondEnergyCorrections = use_bond_corrections
            job.atomEnergies = atom_energies
        if isinstance(job, ThermoJob):
            job.arkane_species.author = author
            job.arkane_species.level_of_theory = level_of_theory
            if '//' in level_of_theory:
                level_of_theory_energy = level_of_theory.split('//')[0]
                if level_of_theory_energy != model_chemistry:
                    # Only log the model chemistry if it isn't identical to the first part of level_of_theory
                    job.arkane_species.model_chemistry = model_chemistry
            job.arkane_species.frequency_scale_factor = frequency_scale_factor
            job.arkane_species.use_hindered_rotors = use_hindered_rotors
            job.arkane_species.use_bond_corrections = use_bond_corrections
            if atom_energies is not None:
                job.arkane_species.atom_energies = atom_energies
    
    return jobList, reactionDict, speciesDict, transitionStateDict, networkDict