Esempio n. 1
0
def mycut(atoms,
          a_atom,
          b_atom,
          c_atom,
          origo_atom,
          nlayers=None,
          extend=1.0,
          tolerance=0.01,
          maxatoms=None):
    """
    atoms: atoms
    a_atoms,b_atoms,c_atoms: the symol_number of the atoms (a_atom-origo_atom)-> a; ...
    origo_atom: the atom at the origin.
    other parameters are as ase.io.geometry.cut
    """
    symdict = symbol_number(atoms)
    origo = symdict[origo_atom]
    a = symdict[a_atom]
    b = symdict[b_atom]
    c = symdict[c_atom]
    atoms = cut(atoms,
                a=a,
                b=b,
                c=c,
                clength=None,
                origo=origo,
                nlayers=None,
                extend=1.0,
                tolerance=0.01,
                maxatoms=None)
    return atoms
Esempio n. 2
0
def rh2hex(lattice):
    """ return Atomic objects with 3 times volume hexgonal cell of the input rhombohedral cell
        exist slightly different cut vectors, see ITC vol. A
    """
    from ase.utils.geometry import cut
    re=cut(lattice, (1.0, -1.0, 0.0), (0.0, 1.0, -1.0), (1.0, 1.0,1.0), origo=(0,0,0))
    
    return re
Esempio n. 3
0
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])
Esempio n. 4
0
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])
Esempio n. 5
0
def cut_z(atoms, symnum1, symnum2, shift):
    """
    cut along the z direction.
    """
    symdict = symbol_number(atoms)
    z1 = atoms.get_positions()[symdict[symnum1]][2] - shift
    z2 = atoms.get_positions()[symdict[symnum2]][2] - shift
    c = atoms.get_cell()[2][2]
    dz = z2 - z1
    newatoms = cut(atoms, clength=dz, origo=(0, 0, z1 / c))
    newatoms.translate([0, 0, -shift])
    return newatoms
Esempio n. 6
0
"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

np.set_printoptions(suppress=True)

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.5, 0.2], [0.5, 0., 0.2],
                        [0.5, 0.5, 0.], [0., 0., 0.4], [0., 0.5, 0.6],
                        [0.5, 0., 0.6], [0.5, 0.5, 0.4], [0., 0., 0.8],
                        [0.5, 0.5, 0.8]])
assert np.allclose(correct_pos, al001.get_scaled_positions())

# Check layers along 001
tags, levels = get_layers(al001, (0, 0, 1))
assert np.allclose(tags, [0, 1, 1, 0, 2, 3, 3, 2, 4, 4])
assert np.allclose(levels, [0., 2.025, 4.05, 6.075, 8.1])

# Check layers along 101
tags, levels = get_layers(al001, (1, 0, 1))
assert np.allclose(tags, [0, 1, 5, 3, 2, 4, 8, 7, 6, 9])
assert np.allclose(
    levels,
    [0.000, 0.752, 1.504, 1.880, 2.256, 2.632, 3.008, 3.384, 4.136, 4.888],
    atol=0.001)
Esempio n. 7
0
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,
    transparent=False,
    display=False,
    run_povray=True,
    camera_type='perspective',
    canvas_width=320,
    radii=0.4,
    rotation='90y',
Esempio n. 8
0
"""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

np.set_printoptions(suppress=True)

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())
Esempio n. 9
0
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.

    Parameters:

    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
        object.
    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`.

    Examples:

    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)
    32
    """
    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()
    else:
        basis_coords = np.array(basis, dtype=float, copy=False, ndmin=2)
    sites, kinds = sg.equivalent_sites(basis_coords, 
                                       ondublicates=ondublicates, 
                                       symprec=symprec)
    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'
    else:
        info['unit_cell'] = 'conventional'

    if 'info' in kwargs:
        info.update(kwargs['info'])
    kwargs['info'] = info

    atoms = ase.Atoms(symbols, 
                      scaled_positions=sites, 
                      cell=cell,
                      pbc=pbc,
                      **kwargs)

    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
Esempio n. 10
0
def cut111(crystal,nlayers=6):
    """Cleave the 111 surface"""
    crystal111 = cut(crystal,[1,0,1],[1,1,0],nlayers=nlayers)
    return crystal111
Esempio n. 11
0
def cut001(crystal,nlayers=6):
    """Cleave the 001 surface"""
    crystal001 = cut(crystal,[0,1,0],[0,0,1],nlayers=nlayers)
    return crystal001
Esempio n. 12
0
def cut010(crystal,nlayers=6):
    """Cleave the 010 surface"""
    crystal010 = cut(crystal,[1,0,0],[0,0,1],nlayers=nlayers)
    return crystal010
Esempio n. 13
0
def cut100(crystal,nlayers=6):
    """Cleave the 100 surface"""
    crystal100 = cut(crystal,[0,0,1],[0,1,0],nlayers=nlayers)
    return crystal100
Esempio n. 14
0
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.

    Parameters:

    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
        object.
    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`.

    Examples:

    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)
    32
    """
    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()
    else:
        basis_coords = np.array(basis, dtype=float, copy=False, ndmin=2)
    sites, kinds = sg.equivalent_sites(basis_coords,
                                       ondublicates=ondublicates,
                                       symprec=symprec)
    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'
    else:
        info['unit_cell'] = 'conventional'

    if 'info' in kwargs:
        info.update(kwargs['info'])
    kwargs['info'] = info

    atoms = ase.Atoms(symbols,
                      scaled_positions=sites,
                      cell=cell,
                      pbc=pbc,
                      **kwargs)

    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
Esempio n. 15
0
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,         
         transparent=False, 
         display=False,
         run_povray=True,
         camera_type='perspective',
         canvas_width=320,
         radii=0.4,
         rotation='90y',
         bondlinewidth=0.07,
         bondatoms=bondatoms,