Beispiel #1
0
    def to_formula(self, bag: 'BagType') -> Formula:
        if len(bag) != self.symbol_table.count():
            raise ValueError(f'Bag {bag} does not fit symbol table')

        d = {
            self.symbol_table.get_symbol(index): count
            for index, count in enumerate(bag)
        }
        return Formula.from_dict(d)
def test_h0c1():
    f = Formula.from_dict({'H': 0, 'C': 1})
    assert f.format('hill') == 'C'
    with pytest.raises(ValueError):
        Formula.from_dict({'H': -1})
    with pytest.raises(ValueError):
        Formula.from_dict({'H': 1.5})
    with pytest.raises(ValueError):
        Formula.from_dict({7: 1})
Beispiel #3
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, str):
                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, str):
                name = Formula.from_dict(count).format('metal')

            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))
Beispiel #4
0
def remove_from_formula(formula: Formula, symbol: str) -> Formula:
    d = formula.count()
    d[symbol] -= 1
    return Formula.from_dict(d)