Ejemplo n.º 1
0
 def test_pmutt_list_to_dict(self):
     sum_obj1 = self.sum_class(num1=1, num2=2)
     sum_obj2 = self.sum_class(num1=2, num2=3)
     self.assertDictEqual(
         pmutt.pmutt_list_to_dict([sum_obj1, sum_obj2], key='num1'), {
             1: sum_obj1,
             2: sum_obj2
         })
Ejemplo n.º 2
0
def organize_phases(phases_data,
                    species=None,
                    reactions=None,
                    interactions=None):
    """Helper method to organize phase data for OpenMKM
    
    Parameters
    ----------
        phases_data : list of dict
            Each element of the list corresponds to the data to initialize the
            phase. Each dictionary are keyword arguments.
        species : list of :class:`~pmutt.empirical.nasa.Nasa`, :class:`~pmutt.empirical.nasa.Nasa9` and/or :class:`~pmutt.empirical.shomate.Shomate` objects, optional
            Species with phases to include. Default is None.
        reactions : list of :class:`~pmutt.omkm.reaction.SurfaceReaction` objects, optional
            Reactions occuring on phases to include. Default is None.
        interactions : list of :class:`~pmutt.mixture.cov.PiecewiseCovEffect` objects, optional
            Lateral interactions to include. Default is None
    Returns
    -------
        phases : list of :class:`~pmutt.cantera.phase.Phase` objects
            Phases organized using parameters.
    """
    species_phases = get_species_phases(species)
    reactions_phases = get_reactions_phases(reactions)
    interactions_phases = \
            get_interactions_phases(interactions=interactions,
                                    species=pmutt_list_to_dict(species))

    phases = []
    phase_kwargs = {
        'species': species_phases,
        'reactions': reactions_phases,
        'interactions': interactions_phases
    }
    for phase_data in phases_data:
        # Pre-processing relevant data
        phase_name = phase_data['name']
        phase_type = phase_data.pop('phase_type')

        # Add relevant data about species, reactions and interactions if present
        for attr_name, attr_values in phase_kwargs.items():
            # Skip if no data has been provided for this attribute
            if attr_values is None:
                continue

            try:
                attr_value = attr_values[phase_name]
            except KeyError:
                # Skip if the phase is not present
                continue
            # Skip if the phase has no values assigned (occurs if attr_value is
            # a defaultdict(list))
            if len(attr_value) == 0:
                continue

            # Assign the kwargs
            phase_data[attr_name] = attr_value

        phase_class = getattr(omkm_phases, phase_type)
        phase = phase_class(**phase_data)
        phases.append(phase)
    return phases
Ejemplo n.º 3
0
# - [thermdat](thermdat) Thermdat file used to initialize ``Nasa`` species

# ## Initialize Species Used For Reaction
# First, we need to describe our species as pMuTT objects. For this example, we will be importing the thermdat from the [combustion database by Berkeley](http://combustion.berkeley.edu/gri_mech/version30/files30/thermo30.dat). We will store the species in a dictionary for code clarity later on.

# In[1]:

from pprint import pprint
from pmutt.io.thermdat import read_thermdat
from pmutt import pmutt_list_to_dict

# The output will be a list
species_list = read_thermdat(filename='thermdat')

# This function converts the list to a dict for easier usage downstream
species_dict = pmutt_list_to_dict(pmutt_list=species_list, key='name')

# (Optional) Print the species_dict to see what's in it
pprint(species_dict)

# To calculate transition state properties, we will need to represent the transition state species as a pMuTT object. For this example, we will create a new ``Nasa`` object based on the H2O entry but modify the a6 parameter arbitrarily to give it a higher enthalpy.

# In[2]:

from copy import deepcopy

# Make a copy so we don't edit the original H2O
H2O_TS = deepcopy(species_dict['H2O'])

# Change name to differentiate it
H2O_TS.name = 'H2O_TS'
Ejemplo n.º 4
0
# [0]: https://vlachosgroup.github.io/pmutt/io.html#pmutt.io.thermdat.read_thermdat

# ## Reactions
# You can also evaluate reactions properties. The most straightforward way to do this is to initialize using strings.

# In[15]:


from pmutt.io.thermdat import read_thermdat
from pmutt import pmutt_list_to_dict
from pmutt.reaction import Reaction

# Get a dictionary of species
thermdat_H2O_path = os.path.join(notebook_folder, 'thermdat_H2O')
species_list = read_thermdat(thermdat_H2O_path)
species_dict = pmutt_list_to_dict(species_list)

# Initialize the reaction
rxn_H2O = Reaction.from_string('H2 + 0.5O2 = H2O', species=species_dict)

# Calculate reaction properties
H_rxn = rxn_H2O.get_delta_H(T=298., units='kJ/mol')
S_rxn = rxn_H2O.get_delta_S(T=298., units='J/mol/K')
print('H_rxn(T=298) = {:.1f} kJ/mol'.format(H_rxn))
print('S_rxn(T=298) = {:.2f} J/mol/K'.format(S_rxn))


# ## Exercise
# Write a script to calculate the Enthalpy of adsorption (in kcal/mol) of H2O on Cu(111) at T = 298 K. Some important details are given below.
# 
# ### Information Required
Ejemplo n.º 5
0
def read_thermdat(filename, format='list', key='name'):
    """Directly read thermdat file that is in the Chemkin format

    Parameters
    ----------
        filename : str
            Input filename
        format : str, optional
            Format to output NASA polynomials. Supported options are:
            'list', 'tuple', 'dict'. Default is 'list'
        key : str, optional
            If `format` is 'dict', uses this attribute as the key for the
            output dictionary. Default is 'name'
    Returns
    -------
        Nasas : list, tuple or dict of :class:`~pmutt.empirical.nasa.Nasa`
    Raises
    ------
        FileNotFoundError
            If the file isn't found.
        IOError
            Invalid line number found.
    """

    species = []
    with open(filename, 'r') as f_ptr:
        for line in f_ptr:
            '''
            Lines to skip
            '''
            # Skip the header line
            if 'THERMO' in line:
                continue
            # Skip the end line
            if 'END' in line:
                continue
            # Skip blank lines
            if line == '\n':
                continue
            # Skip comment lines
            if line[0] == '!':
                continue
            # Skip header temperatures
            if _is_temperature_header(line):
                continue
            '''
            Parse lines
            '''
            line_num = _read_line_num(line)
            if line_num == 1:
                nasa_data = _read_line1(line)
            elif line_num == 2:
                nasa_data = _read_line2(line, nasa_data)
            elif line_num == 3:
                nasa_data = _read_line3(line, nasa_data)
            elif line_num == 4:
                nasa_data = _read_line4(line, nasa_data)
                species.append(Nasa(**nasa_data))
            else:
                err_msg = ('Invalid line number, {}, in thermdat file: {}'
                           ''.format(line_num, filename))
                raise IOError(err_msg)
    # Format the NASA polynomials in the required format
    if format == 'list':
        pass
    elif format == 'tuple':
        species = tuple(species)
    elif format == 'dict':
        species = pmutt_list_to_dict(species, key=key)
    else:
        err_msg = (
            'Unsupported format: {}. See pmutt.io.thermdat.read_thermdat'
            ' docstring for supported formats.'.format(format))
        raise ValueError(err_msg)
    return species
Ejemplo n.º 6
0
beps = []
for bep_data in beps_data:
    beps.append(BEP(**bep_data))

# Combine species and BEPs to make reactions
species_with_beps = species + beps

# ### Read reactions

# In[6]:

from pmutt import pmutt_list_to_dict
from pmutt.omkm.reaction import SurfaceReaction

# Convert species to dictionary for easier reaction assignment
species_with_beps_dict = pmutt_list_to_dict(species_with_beps)
reactions_data = read_excel(io=input_path, sheet_name='reactions')
reactions = []
# Store information about phases for later retrieval
reaction_phases = {}
for reaction_data in reactions_data:
    reaction = SurfaceReaction.from_string(species=species_with_beps_dict,
                                           **reaction_data)
    reactions.append(reaction)
    # Assign phase information
    reaction_species = reaction.get_species(include_TS=True)
    for ind_species in reaction_species:
        try:
            phase = species_with_beps_dict[ind_species].phase
        except AttributeError:
            pass
Ejemplo n.º 7
0
def read_reactions(filename, species=None):
    """Directly read reactions from Chemkin gas.inp or surf.inp files

    Parameters
    ----------
        filename : str
            Input filename for Chemkin surf or gas .inp file
        species : list of :class:`~pmutt.empirical.nasa.Nasa` objects
            List of NASA objects containing thermodynamic properties for
            all Reactants and Products in Reactions
            default = None. Will not return React_obj and Prod_obj
    Returns
    -------
        Reactions   : list of reactions
        Reactants   : list of reactants found in reactions
        React_obj   : list of NASA polynomials for each Reactant
                      If species object list is supplied
        React_stoic : list of reaction stoichiometries for Reactants
        Products    : list of products found in reactions
        Prod_obj    : list of NASA polynomials for each Product
                      If species object list is supplied
        Prod_stoic  : list of reaction stoichiometries for Products
    Raises
    ------
        FileNotFoundError
            If the surf.inp or gas.inp file isn't found.
        NameError
            If the species file does not exist
        AttributeError
            If the species list is incorrect format
    """
    if species is not None:
        species_dict = pmutt_list_to_dict(species)

    rxns = []
    with open(filename, 'r') as lines:
        for line in lines:
            if re.findall(r'(^[^\!].+)( *<*(?<![0-9][eE])[=\-]>* *)', line):
                rxns.append(line.strip())
    RHS = []
    LHS = []
    for rxn in rxns:
        LHS.append(re.split(r' *<*(?<![0-9][eE])[=\-]>* *', rxn)[0])
        RHS.append(re.split(r' *<*(?<![0-9][eE])[=\-]>* *', rxn)[1])
    Reactants = []
    Products = []
    React_obj = []
    Prod_obj = []
    React_stoic = []
    Prod_stoic = []
    for Reacs, Prods in zip(LHS, RHS):
        Reactants.append(re.split(r' *\+ *| +', Reacs))
        Products.append(re.split(r' *\+ *| +', Prods)[0:-3])
        R = []
        RS = []
        Rx = []
        for RR in Reactants[-1]:
            stoic = re.findall(r'^[0-9]*', RR)[0]
            if stoic == '':
                stoic = 1
            else:
                RR = RR.replace(stoic, "")
                stoic = int(stoic)
            Rx.append(RR)
            RS.append(stoic)
            if species is not None:
                R.append(species_dict[RR])
        Reactants[-1] = Rx
        React_stoic.append(RS)
        P = []
        PS = []
        Px = []
        for PP in Products[-1]:
            stoic = re.findall(r'^[0-9]*', PP)[0]
            if stoic == '':
                stoic = 1
            else:
                PP = PP.replace(stoic, "")
                stoic = int(stoic)
            Px.append(PP)
            PS.append(stoic)
            if species is not None:
                P.append(species_dict[PP])
        Products[-1] = Px
        Prod_stoic.append(PS)
        React_obj.append(R)
        Prod_obj.append(P)
    Reactions = []
    for rxn, Prods in zip(rxns, Products):
        Reactions.append(rxn[0:rxn.rindex(Prods[-1]) + len(Prods[-1])])
    if species is not None:
        return (Reactions, Reactants, React_obj, React_stoic, Products,
                Prod_obj, Prod_stoic)
    else:
        return (Reactions, Reactants, React_stoic, Products, Prod_stoic)