Exemplo n.º 1
def primitive_from_conventional_cell(atoms, spacegroup=1, setting=1):
    """Returns primitive cell given an Atoms object for a conventional
    cell and it's spacegroup."""
    from ase.lattice.spacegroup import Spacegroup
    from ase.utils.geometry  import cut
    sg = Spacegroup(spacegroup, setting)
    prim_cell = sg.scaled_primitive_cell  # Check if we need to transpose
    return cut(atoms, a=prim_cell[0], b=prim_cell[1], c=prim_cell[2])
Exemplo n.º 2
def crystal(symbols=None, basis=None, spacegroup=1, setting=1, 
            cell=None, cellpar=None, 
            ab_normal=(0,0,1), a_direction=None, size=(1,1,1),
            ondublicates='warn', symprec=0.001, 
            pbc=True, primitive_cell=False, **kwargs):
    """Create an Atoms instance for a conventional unit cell of a
    space group.


    symbols : str | sequence of str | sequence of Atom | Atoms
        Element symbols of the unique sites.  Can either be a string
        formula or a sequence of element symbols. E.g. ('Na', 'Cl')
        and 'NaCl' are equivalent.  Can also be given as a sequence of
        Atom objects or an Atoms object.
    basis : list of scaled coordinates 
        Positions of the unique sites corresponding to symbols given
        either as scaled positions or through an atoms instance.  Not
        needed if *symbols* is a sequence of Atom objects or an Atoms
    spacegroup : int | string | Spacegroup instance
        Space group given either as its number in International Tables
        or as its Hermann-Mauguin symbol.
    setting : 1 | 2
        Space group setting.
    cell : 3x3 matrix
        Unit cell vectors.
    cellpar : [a, b, c, alpha, beta, gamma]
        Cell parameters with angles in degree. Is not used when `cell`
        is given. 
    ab_normal : vector
        Is used to define the orientation of the unit cell relative
        to the Cartesian system when `cell` is not given. It is the
        normal vector of the plane spanned by a and b.
    a_direction : vector
        Defines the orientation of the unit cell a vector. a will be 
        parallel to the projection of `a_direction` onto the a-b plane.
    size : 3 positive integers
        How many times the conventional unit cell should be repeated
        in each direction.
    ondublicates : 'keep' | 'replace' | 'warn' | 'error'
        Action if `basis` contain symmetry-equivalent positions:
            'keep'    - ignore additional symmetry-equivalent positions
            'replace' - replace
            'warn'    - like 'keep', but issue an UserWarning
            'error'   - raises a SpacegroupValueError
    symprec : float
        Minimum "distance" betweed two sites in scaled coordinates
        before they are counted as the same site.
    pbc : one or three bools
        Periodic boundary conditions flags.  Examples: True,
        False, 0, 1, (1, 1, 0), (True, False, False).  Default
        is True.
    primitive_cell : bool
        Wheter to return the primitive instead of the conventional
        unit cell.

    Keyword arguments:

    All additional keyword arguments are passed on to the Atoms
    constructor.  Currently, probably the most useful additional
    keyword arguments are `info`, `constraint` and `calculator`.


    Two diamond unit cells (space group number 227)

    >>> diamond = crystal('C', [(0,0,0)], spacegroup=227, 
    ...     cellpar=[3.57, 3.57, 3.57, 90, 90, 90], size=(2,1,1))
    >>> ase.view(diamond)  # doctest: +SKIP

    A CoSb3 skutterudite unit cell containing 32 atoms

    >>> skutterudite = crystal(('Co', 'Sb'), 
    ...     basis=[(0.25,0.25,0.25), (0.0, 0.335, 0.158)], 
    ...     spacegroup=204, cellpar=[9.04, 9.04, 9.04, 90, 90, 90])
    >>> len(skutterudite)
    sg = Spacegroup(spacegroup, setting)
    if (not isinstance(symbols, str) and 
        hasattr(symbols, '__getitem__') and
        len(symbols) > 0 and 
        isinstance(symbols[0], ase.Atom)):
        symbols = ase.Atoms(symbols)
    if isinstance(symbols, ase.Atoms):
        basis = symbols
        symbols = basis.get_chemical_symbols()
    if isinstance(basis, ase.Atoms):
        basis_coords = basis.get_scaled_positions()
        if cell is None and cellpar is None:
            cell = basis.cell
        if symbols is None:
            symbols = basis.get_chemical_symbols()
        basis_coords = np.array(basis, dtype=float, copy=False, ndmin=2)
    sites, kinds = sg.equivalent_sites(basis_coords, 
    symbols = parse_symbols(symbols)
    symbols = [symbols[i] for i in kinds]
    if cell is None:
        cell = cellpar_to_cell(cellpar, ab_normal, a_direction)

    info = dict(spacegroup=sg)
    if primitive_cell:
        info['unit_cell'] = 'primitive'
        info['unit_cell'] = 'conventional'

    if 'info' in kwargs:
    kwargs['info'] = info

    atoms = ase.Atoms(symbols, 

    if isinstance(basis, ase.Atoms):
        for name in basis.arrays:
            if not atoms.has(name):
                array = basis.get_array(name)
                atoms.new_array(name, [array[i] for i in kinds], 
                                dtype=array.dtype, shape=array.shape[1:])

    if primitive_cell:
        from ase.utils.geometry  import cut
        prim_cell = sg.scaled_primitive_cell
        atoms = cut(atoms, a=prim_cell[0], b=prim_cell[1], c=prim_cell[2])

    if size != (1, 1, 1):
        atoms = atoms.repeat(size)
    return atoms
Exemplo n.º 3
"""Test the ase.utils.geometry module"""

import numpy as np

from ase.lattice.spacegroup import crystal
from ase.utils.geometry import get_layers, cut, stack
from ase.atoms import Atoms


al = crystal("Al", [(0, 0, 0)], spacegroup=225, cellpar=4.05)

# Cut out slab of 5 Al(001) layers
al001 = cut(al, nlayers=5)
correct_pos = np.array(
        [0.0, 0.0, 0.0],
        [0.0, 0.5, 0.2],
        [0.5, 0.0, 0.2],
        [0.5, 0.5, 0.0],
        [0.0, 0.0, 0.4],
        [0.0, 0.5, 0.6],
        [0.5, 0.0, 0.6],
        [0.5, 0.5, 0.4],
        [0.0, 0.0, 0.8],
        [0.5, 0.5, 0.8],
assert np.allclose(correct_pos, al001.get_scaled_positions())
Exemplo n.º 4
def cut111(crystal,nlayers=6):
    """Cleave the 111 surface"""
    crystal111 = cut(crystal,[1,0,1],[1,1,0],nlayers=nlayers)
    return crystal111
Exemplo n.º 5
def cut001(crystal,nlayers=6):
    """Cleave the 001 surface"""
    crystal001 = cut(crystal,[0,1,0],[0,0,1],nlayers=nlayers)
    return crystal001
Exemplo n.º 6
def cut010(crystal,nlayers=6):
    """Cleave the 010 surface"""
    crystal010 = cut(crystal,[1,0,0],[0,0,1],nlayers=nlayers)
    return crystal010
Exemplo n.º 7
def cut100(crystal,nlayers=6):
    """Cleave the 100 surface"""
    crystal100 = cut(crystal,[0,0,1],[0,1,0],nlayers=nlayers)
    return crystal100
Exemplo n.º 8
import numpy as np
import ase.utils.geometry as geometry
import ase.io as io

# Create a new atoms instance with Co at origo including all atoms on the 
# surface of the unit cell
cosb3 = geometry.cut(skutterudite, origo=(0.25, 0.25, 0.25), extend=1.01)

# Define the atomic bonds to show
bondatoms = []
symbols = cosb3.get_chemical_symbols()
for i in xrange(len(cosb3)):
    for j in xrange(i):
        if (symbols[i] == symbols[j] == 'Co' and 
            cosb3.get_distance(i, j) < 4.53):
            bondatoms.append((i, j))
        elif (symbols[i] == symbols[j] == 'Sb' and 
              cosb3.get_distance(i, j) < 2.99):
            bondatoms.append((i, j))

# Create nice-looking image using povray
io.write('spacegroup-cosb3.pov', cosb3,