Exemplo n.º 1
0
    def test_gas_phase_example(self):
        """Test the gas phase enumerator examples."""
        db_name = 'C2H6-example.db'
        with ReactionNetwork(db_name=db_name) as rn:

            rn.molecule_search(
                element_pool={
                    'C': 2,
                    'H': 6
                }, multiple_bond_search=False)
            molecules = rn.load_molecules()

            assert (len(molecules) == 17)

            rn.path_search(reconfiguration=False, substitution=False)
            pathways = rn.load_pathways()

            assert (len(pathways) == 27)

        names = np.empty(len(molecules) + 1, dtype='a5')
        names[0] = ''
        for k, v in molecules.items():
            atn = nx.get_node_attributes(v.graph, 'number')

            hill = formula_hill(list(atn.values()))
            names[k] = hill

        for path in pathways:
            print('|{} + {} --> {} + {}|'.format(*names[path]))
Exemplo n.º 2
0
 def _get_species_name(self, index):
     site = self._get_site_index(index)
     if self.formula == 'hill':
         n = nx.get_node_attributes(self.molecules[index], 'atomic_number')
         name = formula_hill(list(n.values()))
     elif self.formula == 'smiles':
         name = get_smiles(self.molecules[index])
     else:
         raise NotImplementedError(str(self.formula))
     return '_'.join([name, site])
Exemplo n.º 3
0
def test_gas_phase_example():
    db_name = 'C2H6-example.db'
    with ReactionNetwork(db_name=db_name) as rn:

        rn.molecule_search(element_pool={
            'C': 2,
            'H': 6
        },
                           multiple_bond_search=False)
        molecules = rn.load_molecules()

        assert (len(molecules) == 17)

        for i, molecule in molecules.items():
            plot_molecule(molecule,
                          file_name='./images/molecule-{}.png'.format(i))

            molecule = get_uff_coordinates(molecule, steps=50)
            rn.save_3d_structure(molecule)

        images = rn.load_3d_structures()

        assert (len(images) == 17)

        rn.path_search(reconfiguration=False, substitution=False)
        rn.plot_reaction_network(file_name='./images/reaction-network.png')
        pathways = rn.load_pathways()

        assert (len(pathways) == 27)

    names = np.empty(len(molecules) + 1, dtype='a5')
    names[0] = ''
    for k, v in molecules.items():
        atn = nx.get_node_attributes(v.graph, 'number')

        hill = formula_hill(list(atn.values()))
        names[k] = hill

    for path in pathways:
        print('|{} + {} --> {} + {}|'.format(*names[path]))

    os.unlink(db_name)
Exemplo n.º 4
0
    def get_chemical_formula(self, mode='hill', empirical=False):
        """Get chemical formula.

        See documentation of ase.atoms.Atoms.get_chemical_formula()."""
        if mode in ('reduce', 'all') and empirical:
            warnings.warn("Empirical chemical formula not available "
                          "for mode '{}'".format(mode))

        if len(self) == 0:
            return ''

        numbers = self.numbers

        if mode == 'reduce':
            n = len(numbers)
            changes = np.concatenate(
                ([0], np.arange(1, n)[numbers[1:] != numbers[:-1]]))
            symbols = [chemical_symbols[e] for e in numbers[changes]]
            counts = np.append(changes[1:], n) - changes

            tokens = []
            for s, c in zip(symbols, counts):
                tokens.append(s)
                if c > 1:
                    tokens.append(str(c))
            formula = ''.join(tokens)
        elif mode == 'hill':
            formula = formula_hill(numbers, empirical=empirical)
        elif mode == 'all':
            formula = ''.join([chemical_symbols[n] for n in numbers])
        elif mode == 'metal':
            formula = formula_metal(numbers, empirical=empirical)
        else:
            raise ValueError("Use mode = 'all', 'reduce', 'hill' or 'metal'.")

        return formula
Exemplo n.º 5
0
    def __init__(self, references, filter='', verbose=True):
        """Phase-diagram.

        references: list of (name, energy) tuples
            List of references.  The energy must be the total energy and not
            energy per atom.  The names can also be dicts like
            ``{'Zn': 1, 'O': 2}`` which would be equivalent to ``'ZnO2'``.
        filter: str or list of str
            Use only those references that match the given filter.
            Example: ``filter='ZnO'`` will select those that
            contain zinc or oxygen.
        verbose: bool
            Write information.
        """

        if not references:
            raise ValueError("You must provide a non-empty list of references"
                             " for the phase diagram! "
                             "You have provided '{}'".format(references))
        filter = parse_formula(filter)[0]

        self.verbose = verbose

        self.species = OrderedDict()
        self.references = []
        for name, energy in references:
            if isinstance(name, basestring):
                count = parse_formula(name)[0]
            else:
                count = name

            if filter and any(symbol not in filter for symbol in count):
                continue

            if not isinstance(name, basestring):
                name = formula_hill(count)

            natoms = 0
            for symbol, n in count.items():
                natoms += n
                if symbol not in self.species:
                    self.species[symbol] = len(self.species)
            self.references.append((count, energy, name, natoms))

        ns = len(self.species)
        self.symbols = [None] * ns
        for symbol, id in self.species.items():
            self.symbols[id] = symbol

        if verbose:
            print('Species:', ', '.join(self.symbols))
            print('References:', len(self.references))
            for i, (count, energy, name, natoms) in enumerate(self.references):
                print('{:<5}{:10}{:10.3f}'.format(i, name, energy))

        self.points = np.zeros((len(self.references), ns + 1))
        for s, (count, energy, name, natoms) in enumerate(self.references):
            for symbol, n in count.items():
                self.points[s, self.species[symbol]] = n / natoms
            self.points[s, -1] = energy / natoms

        if len(self.points) == ns:
            # Simple case that qhull would choke on:
            self.simplices = np.arange(ns).reshape((1, ns))
            self.hull = np.ones(ns, bool)
        else:
            hull = ConvexHull(self.points[:, 1:])

            # Find relevant simplices:
            ok = hull.equations[:, -2] < 0
            self.simplices = hull.simplices[ok]

            # Create a mask for those points that are on the convex hull:
            self.hull = np.zeros(len(self.points), bool)
            for simplex in self.simplices:
                self.hull[simplex] = True

        if verbose:
            print('Simplices:', len(self.simplices))
Exemplo n.º 6
0
    def __init__(self, references, filter='', verbose=True):
        """Phase-diagram.

        references: list of (name, energy) tuples
            List of references.  The energy must be the total energy and not
            energy per atom.  The names can also be dicts like
            ``{'Zn': 1, 'O': 2}`` which would be equivalent to ``'ZnO2'``.
        filter: str or list of str
            Use only those references that match the given filter.
            Example: ``filter='ZnO'`` will select those that
            contain zinc or oxygen.
        verbose: bool
            Write information.
        """

        filter = parse_formula(filter)[0]

        self.verbose = verbose

        self.species = {}
        self.references = []
        for name, energy in references:
            if isinstance(name, basestring):
                count = parse_formula(name)[0]
            else:
                count = name
                name = formula_hill(count)

            if filter and any(symbol not in filter for symbol in count):
                continue

            natoms = 0
            for symbol, n in count.items():
                natoms += n
                if symbol not in self.species:
                    self.species[symbol] = len(self.species)
            self.references.append((count, energy, name, natoms))

        self.symbols = [None] * len(self.species)
        for symbol, id in self.species.items():
            self.symbols[id] = symbol

        if verbose:
            print('Species:', ', '.join(self.symbols))
            print('References:', len(self.references))
            for i, (count, energy, name, natoms) in enumerate(self.references):
                print('{0:<5}{1:10}{2:10.3f}'.format(i, name, energy))

        self.points = np.zeros((len(self.references), len(self.species) + 1))
        for s, (count, energy, name, natoms) in enumerate(self.references):
            for symbol, n in count.items():
                self.points[s, self.species[symbol]] = n / natoms
            self.points[s, -1] = energy / natoms

        hull = ConvexHull(self.points[:, 1:])

        # Find relevant simplices:
        ok = hull.equations[:, -2] < 0
        self.simplices = hull.simplices[ok]

        # Create a mask for those points that are on the convex hull:
        self.hull = np.zeros(len(self.points), bool)
        for simplex in self.simplices:
            self.hull[simplex] = True

        if verbose:
            print('Simplices:', len(self.simplices))
Exemplo n.º 7
0
    def __init__(self, references, filter='', verbose=True):
        """Phase-diagram.

        references: list of (name, energy) tuples
            List of references.  The energy must be the total energy and not
            energy per atom.  The names can also be dicts like
            ``{'Zn': 1, 'O': 2}`` which would be equivalent to ``'ZnO2'``.
        filter: str or list of str
            Use only those references that match the given filter.
            Example: ``filter='ZnO'`` will select those that
            contain zinc or oxygen.
        verbose: bool
            Write information.
        """

        filter = parse_formula(filter)[0]

        self.verbose = verbose

        self.species = {}
        self.references = []
        for name, energy in references:
            if isinstance(name, basestring):
                count = parse_formula(name)[0]
            else:
                count = name
                name = formula_hill(count)

            if filter and any(symbol not in filter for symbol in count):
                continue

            natoms = 0
            for symbol, n in count.items():
                natoms += n
                if symbol not in self.species:
                    self.species[symbol] = len(self.species)
            self.references.append((count, energy, name, natoms))

        self.symbols = [None] * len(self.species)
        for symbol, id in self.species.items():
            self.symbols[id] = symbol

        if verbose:
            print('Species:', ', '.join(self.symbols))
            print('References:', len(self.references))
            for i, (count, energy, name, natoms) in enumerate(self.references):
                print('{0:<5}{1:10}{2:10.3f}'.format(i, name, energy))

        self.points = np.zeros((len(self.references), len(self.species) + 1))
        for s, (count, energy, name, natoms) in enumerate(self.references):
            for symbol, n in count.items():
                self.points[s, self.species[symbol]] = n / natoms
            self.points[s, -1] = energy / natoms

        hull = ConvexHull(self.points[:, 1:])

        # Find relevant simplices:
        ok = hull.equations[:, -2] < 0
        self.simplices = hull.simplices[ok]

        # Create a mask for those points that are on the convex hull:
        self.hull = np.zeros(len(self.points), bool)
        for simplex in self.simplices:
            self.hull[simplex] = True

        if verbose:
            print('Simplices:', len(self.simplices))