Beispiel #1
0
def interstitial_tetrahedral(lattice, species, interstitial_species=None,
                             min_atoms=0, supercell=None, index=-1):
    """
    Create a crystal structure with a tetrahedral interstitial atom between
    four atoms.

    Parameters
    ----------
    lattice : str
        Lattice to use for the base crystal structure. Valid choices are 'bcc'
        and 'fcc'.
    species : int or str
        Identity of species used to construct the lattice.
    interstitial_species : int or str, optional
        Identity of the interstitial species; if not specified, creates a
        self-interstitial.
    min_atoms : int, optional
        Construct a supercell to include at least this many atoms.
    supercell : (int, int, int), optional
        Request a specific supercell of bulk material. If not given,
        max_atoms will be used instead to create a cubic cell.
    index : int, optional
        Index of nearest lattice atom to the interstitial. Additional atom is
        placed along the <210> direction in bcc and <221> in fcc.

    Returns
    -------
    ase.Atoms
        Lattice with a tetrahedral interstitial atom.
    """

    species = Element(species)
    if interstitial_species is None:
        interstitial_species = species
    else:
        interstitial_species = Element(interstitial_species)

    ibulk = bulk(species, lattice, min_atoms, supercell)
    lattice_constant = ibulk.info['lattice_constant']

    if lattice.lower() == 'bcc':
        displacement = [lattice_constant/4.0, lattice_constant/2.0, 0]
    elif lattice.lower() == 'fcc':
        displacement = [lattice_constant/4.0,
                        lattice_constant/4.0,
                        lattice_constant/2.0]
    else:
        raise NotImplementedError("Tetrahedral defects not implemented in "
                                  "{0}".format(lattice))

    if index < 0:
        index += len(ibulk)

    # Move into tetrahedral position
    ibulk.append(Atom(interstitial_species,
                      position=ibulk[index].position + displacement))

    return ibulk
Beispiel #2
0
def interstitial_dumbbell(lattice, species, direction='111',
                          interstitial_species=None, min_atoms=0,
                          supercell=None, index=-1):
    """
    Create a crystal structure, such as bcc or fcc, with a dumbbell
    interstitial atom along the given lattice direction.

    Parameters
    ----------
    lattice : str
        Lattice type to generate, valid values are 'bcc' and 'fcc' or anything
        accepted by sats bulk.
    species : int or str
        Identity of species used to construct the lattice.
    direction : str
        Lattice direction along which to create the dumbbell.
    interstitial_species : int or str, optional
        Identity of the interstitial species; if not specified, creates a
        self-interstitial.
    min_atoms : int, optional
        Construct a supercell to include at least this many atoms.
    supercell : (int, int, int), optional
        Request a specific supercell of bulk material. If not given,
        max_atoms will be used instead to create a cubic cell.
    index : int, optional
        Index of atom with which to create the dumbbell. Added atom is always
        at the end.

    Returns
    -------
    ase.Atoms
        Lattice with a dumbbell interstitial atom.
    """

    species = Element(species)
    if interstitial_species is None:
        interstitial_species = species
    else:
        interstitial_species = Element(interstitial_species)

    ibulk = bulk(species, lattice, min_atoms, supercell)
    lattice_constant = ibulk.info['lattice_constant']

    if index < 0:
        index += len(ibulk)

    # parses the digits from any string, ignoring brackets etc.
    direction = [int(x) for x in re.findall('[+-]*[0-9]', direction)]
    displacement = [1.0/x if x else 0.0 for x in direction]
    # Move 1/3 of the <111> atom separation in each direction
    magnitude = lattice_constant/(12*sum(x**2 for x in displacement))**0.5
    displacement = [x*magnitude for x in displacement]
    ibulk.append(Atom(interstitial_species,
                      position=ibulk[index].position + displacement))
    ibulk[index].position -= displacement

    return ibulk
Beispiel #3
0
def vacancy(lattice, species, n_vacancies=1, min_atoms=0, direction=None):
    """
    Helper function to create a vacancy in a lattice. Multiple vacancies are
    created in a line along close packed directions.

    Parameters
    ----------
    lattice : str
        Lattice type for the bulk structure. Generated as a sats bulk.
    species : int or str
        Identity of species used to construct the lattice.
    n_vacancies : int, optional
        Number of vacancies to create in a row.
    min_atoms : int, optional
        Construct a supercell to include at least this many atoms.
    direction : tuple of int, optional
        Create vacancy row along this direction. If none is specified then
        the close packed direction is used.

    Returns
    -------
    vacancy : ase.Atoms
        Lattice with the requested defect.
    """

    species = Element(species)

    vbulk = bulk(species, lattice, min_atoms)

    if direction is None:
        direction = {
            'bcc': (1, 1, 1),
            'hcp': (1 / 3.0**0.5, 1, 0),
            'fcc': (1, 1, 0)
        }[lattice]

    # order from lowest x, y and z to get an origin
    sites = [
        atom.index for atom in sorted(vbulk, key=lambda a: (a.c, a.a, a.b))
    ]

    origin = vbulk[sites[0]]

    line_atoms = []
    # index all the atoms along the line from origin
    for atom in vbulk:
        separation = atom.position - origin.position
        if norm(cross(separation, direction)) < 1.0e-5:
            line_atoms.append((norm(separation), atom.index))

    if n_vacancies >= 1:
        for atom in sorted(line_atoms, reverse=True)[-n_vacancies:]:
            del vbulk[atom[1]]

    return vbulk