Source code for ase2sprkkr.bindings.empty_spheres

from collections import namedtuple
from ..sprkkr.sprkkr_atoms import SPRKKRAtoms
import numpy as np
import warnings


[docs] class EmptySpheresResult(namedtuple("EmptySpheresResult", "positions radii")): def __len__(self): return len(self.radii)
[docs] def empty_spheres(atoms, method="auto", **kwargs): """Return centres and radii of empty spheres to add. ``method='auto'`` uses the optional es_finder backend when both es_finder and Pymatgen are importable, otherwise it uses the ase2sprkkr "in-house" method taken from XBand. es_finder is not publicly available package. An explicitly requested but unavailable es_finder backend also falls back to the in-house implementation, after emitting a warning. """ es_finder_available = es_finder.is_enabled if method == "auto": method = "es_finder" if es_finder_available else "inhouse" if method == "es_finder": if not es_finder_available: warnings.warn( "The es_finder method requires both es_finder and pymatgen, " "but at least one of them is not installed. Falling back to " "the inhouse empty-spheres method. Install optional support " 'for pymatgen with: python -m pip install "ase2sprkkr[es_finder]"; ' "es_finder itself must also be installed.", RuntimeWarning, stacklevel=2, ) method = "inhouse" else: return es_finder.empty_spheres(atoms, **kwargs) if method in ("inhouse", "xband"): return spheres.empty_spheres(atoms, **kwargs) raise ValueError("Unknown empty-spheres method {!r}; use 'auto', 'es_finder', or 'inhouse'".format(method))
[docs] def empty_spheres_atoms(atoms, round_zero=True, **kwargs): """ Update the structure of the (SPRKKR) ASE atoms, adding the empty spheres and updating the shpheres radii of the atomic sites, according to an :func:`empty_spheres` result. """ res = empty_spheres(atoms, **kwargs) num = len(res.radii) if num == 0: return None empty = SPRKKRAtoms( symbols="X" * len(res.radii), positions=res.positions, pbc=atoms.pbc, cell=atoms.cell, symmetry=False ) if round_zero: empty.positions[np.abs(empty.positions) < 1e-15] = 0 empty.positions = empty.get_scaled_positions(True) @ empty.cell return empty
# for i,radius in zip(empty.sites, res.radii): # not TO DO: set the radius of the sphere, since SPRKKR make it itself # next(iter(i.occupation)).radius=radius
[docs] def add_empty_spheres(atoms, *, copy=False, **kwargs): empty = empty_spheres_atoms(atoms, **kwargs) if empty: if copy: atoms = atoms.copy() atoms += empty return atoms
from . import es_finder # NOQA from .xband import spheres # NOQA