Source code for wulffpack.single_crystal

from typing import Tuple, List
from ase import Atoms
import numpy as np
from .core import BaseParticle
from .core.geometry import get_symmetries, get_standardized_structure
from .core.form import setup_forms


[docs] class SingleCrystal(BaseParticle): """ A `SingleCrystal` object is a Wulff construction of a single crystalline particle, i.e., a standard Wulff construction. Parameters ---------- surface_energies A dictionary with surface energies, where keys are Miller indices and values surface energies (per area) in a unit of choice, such as J/m^2. primitive_structure primitive cell to implicitly define the point group as well as the atomic structure used if an atomic structure is requested. By default, an Au FCC structure is used. natoms Together with `primitive_structure`, this parameter defines the volume of the particle. If an atomic structure is requested, the number of atoms will as closely as possible match this value. symprec Numerical tolerance for symmetry analysis, forwarded to spglib. tol Numerical tolerance parameter. symmetry_operations This parameter allows one to pass an explicit list of allowed symmetry operations. By default (``None``) the allowed symmetry operations are obtained from :attr:`primitive_structure`. Example ------- The following example illustrates some possible uses of a `SingleCrystal` object:: >>> from wulffpack import SingleCrystal >>> from ase.build import bulk >>> from ase.io import write >>> surface_energies = {(1, 1, 0): 1.0, (1, 0, 0): 1.08} >>> prim = bulk('W', a=3.16, crystalstructure='bcc') >>> particle = SingleCrystal(surface_energies, prim) >>> particle.view() >>> write('single_crystal.xyz', particle.atoms) # Writes atomic structure to file """ def __init__( self, surface_energies: dict, primitive_structure: Atoms = None, natoms: int = 1000, symprec: float = 1e-5, tol: float = 1e-5, symmetry_operations: List[np.ndarray] = None, ): standardized_structure = get_standardized_structure(primitive_structure, symprec=symprec) if symmetry_operations is None: symmetries = get_symmetries(standardized_structure, symprec=symprec) else: if len(symmetry_operations) == 0: raise ValueError('You need to provide at least one symmetry operation.') symmetries = symmetry_operations forms = setup_forms(surface_energies, standardized_structure.cell.T, symmetries, symmetries) super().__init__(forms=forms, standardized_structure=standardized_structure, natoms=natoms, tol=tol) @property def atoms(self) -> Atoms: """ Returns an ASE Atoms object """ return self._get_atoms()
[docs] def get_shifted_atoms( self, center_shift: Tuple[float, float, float] = None, ) -> Atoms: """ Returns an ASE Atoms object where the center has been shifted from with respect to the standardized cells. This can, for example, allow creation of atomistic representations in which the center of the nanoparticle does not coincide with an atom. Thereby the space of possible atomistic representations increases and may make the returned number of atoms closer to the requested number. Parameters ---------- center_shift Shift of center in Cartesian coordinates. """ return self._get_atoms(center_shift=center_shift)