Statistiques
| Révision :

root / ase / lattice / spacegroup / crystal.py @ 18

Historique | Voir | Annoter | Télécharger (4,93 ko)

1 1 tkerber
# Copyright (C) 2010, Jesper Friis
2 1 tkerber
# (see accompanying license files for details).
3 1 tkerber
4 1 tkerber
"""
5 1 tkerber
A module for ASE for simple creation of crystalline structures from
6 1 tkerber
knowledge of the space group.
7 1 tkerber

8 1 tkerber
"""
9 1 tkerber
10 1 tkerber
import numpy as np
11 1 tkerber
12 1 tkerber
import ase
13 1 tkerber
from ase.atoms import string2symbols
14 1 tkerber
from spacegroup import Spacegroup
15 1 tkerber
from cell import cellpar_to_cell
16 1 tkerber
17 1 tkerber
__all__ = ['crystal']
18 1 tkerber
19 1 tkerber
20 1 tkerber
21 1 tkerber
def crystal(symbols=None, basis=None, spacegroup=1, setting=1,
22 1 tkerber
            cell=None, cellpar=None,
23 1 tkerber
            ab_normal=(0,0,1), a_direction=None, size=(1,1,1),
24 1 tkerber
            ondublicates='warn', symprec=0.001,
25 1 tkerber
            pbc=True, **kwargs):
26 1 tkerber
    """Create an Atoms instance for a conventional unit cell of a
27 1 tkerber
    space group.
28 1 tkerber

29 1 tkerber
    Parameters:
30 1 tkerber

31 1 tkerber
    symbols : string | sequence of strings
32 1 tkerber
        Either a string formula or a sequence of element
33 1 tkerber
        symbols. E.g. ('Na', 'Cl') and 'NaCl' are equivalent.
34 1 tkerber
    basis : list of scaled coordinates | atoms instance
35 1 tkerber
        Positions of the non-equivalent sites given either as
36 1 tkerber
        scaled positions or through an atoms instance.
37 1 tkerber
    spacegroup : int | string | Spacegroup instance
38 1 tkerber
        Space group given either as its number in International Tables
39 1 tkerber
        or as its Hermann-Mauguin symbol.
40 1 tkerber
    setting : 1 | 2
41 1 tkerber
        Space group setting.
42 1 tkerber
    cell : 3x3 matrix
43 1 tkerber
        Unit cell vectors.
44 1 tkerber
    cellpar : [a, b, c, alpha, beta, gamma]
45 1 tkerber
        Cell parameters with angles in degree. Is not used when `cell`
46 1 tkerber
        is given.
47 1 tkerber
    ab_normal : vector
48 1 tkerber
        Is used to define the orientation of the unit cell relative
49 1 tkerber
        to the Cartesian system when `cell` is not given. It is the
50 1 tkerber
        normal vector of the plane spanned by a and b.
51 1 tkerber
    a_direction : vector
52 1 tkerber
        Defines the orientation of the unit cell a vector. a will be
53 1 tkerber
        parallel to the projection of `a_direction` onto the a-b plane.
54 1 tkerber
    size : 3 positive integers
55 1 tkerber
        How many times the conventional unit cell should be repeated
56 1 tkerber
        in each direction.
57 1 tkerber
    ondublicates : 'keep' | 'replace' | 'warn' | 'error'
58 1 tkerber
        Action if `basis` contain symmetry-equivalent positions:
59 1 tkerber
            'keep'    - ignore additional symmetry-equivalent positions
60 1 tkerber
            'replace' - reolace
61 1 tkerber
            'warn'    - like 'keep', but issue an UserWarning
62 1 tkerber
            'error'   - raises a SpacegroupValueError
63 1 tkerber
    symprec : float
64 1 tkerber
        Minimum "distance" betweed two sites in scaled coordinates
65 1 tkerber
        before they are counted as the same site.
66 1 tkerber
    pbc : one or three bools
67 1 tkerber
        Periodic boundary conditions flags.  Examples: True,
68 1 tkerber
        False, 0, 1, (1, 1, 0), (True, False, False).  Default
69 1 tkerber
        is True.
70 1 tkerber

71 1 tkerber
    Keyword arguments:
72 1 tkerber

73 1 tkerber
    All additional keyword arguments are passed on to the Atoms constructor.
74 1 tkerber
    Currently, probably the most useful additional keyword arguments are
75 1 tkerber
    `constraint` and `calculator`.
76 1 tkerber

77 1 tkerber
    Examples:
78 1 tkerber

79 1 tkerber
    Two diamond unit cells (space group number 227)
80 1 tkerber

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

85 1 tkerber
    A CoSb3 skutterudite unit cell containing 32 atoms
86 1 tkerber

87 1 tkerber
    >>> skutterudite = crystal(('Co', 'Sb'),
88 1 tkerber
    ...     basis=[(0.25,0.25,0.25), (0.0, 0.335, 0.158)],
89 1 tkerber
    ...     spacegroup=204, cellpar=[9.04, 9.04, 9.04, 90, 90, 90])
90 1 tkerber
    >>> len(skutterudite)
91 1 tkerber
    32
92 1 tkerber
    """
93 1 tkerber
    sg = Spacegroup(spacegroup, setting)
94 1 tkerber
    if isinstance(symbols, ase.Atoms):
95 1 tkerber
        basis = symbols
96 1 tkerber
        symbols = basis.get_chemical_symbols()
97 1 tkerber
    if isinstance(basis, ase.Atoms):
98 1 tkerber
        basis_coords = basis.get_scaled_positions()
99 1 tkerber
        if cell is None and cellpar is None:
100 1 tkerber
            cell = basis.cell
101 1 tkerber
        if symbols is None:
102 1 tkerber
            symbols = basis.get_chemical_symbols()
103 1 tkerber
    else:
104 1 tkerber
        basis_coords = np.array(basis, dtype=float, copy=False, ndmin=2)
105 1 tkerber
    sites, kinds = sg.equivalent_sites(basis_coords,
106 1 tkerber
                                       ondublicates=ondublicates,
107 1 tkerber
                                       symprec=symprec)
108 1 tkerber
    symbols = parse_symbols(symbols)
109 1 tkerber
    symbols = [symbols[i] for i in kinds]
110 1 tkerber
    if cell is None:
111 1 tkerber
        cell = cellpar_to_cell(cellpar, ab_normal, a_direction)
112 1 tkerber
113 1 tkerber
    atoms = ase.Atoms(symbols,
114 1 tkerber
                      scaled_positions=sites,
115 1 tkerber
                      cell=cell,
116 1 tkerber
                      pbc=pbc,
117 1 tkerber
                      **kwargs)
118 1 tkerber
119 1 tkerber
    if isinstance(basis, ase.Atoms):
120 1 tkerber
        for name in basis.arrays:
121 1 tkerber
            if not atoms.has(name):
122 1 tkerber
                array = basis.get_array(name)
123 1 tkerber
                atoms.new_array(name, [array[i] for i in kinds],
124 1 tkerber
                                dtype=array.dtype, shape=array.shape[1:])
125 1 tkerber
126 1 tkerber
    if size != (1, 1, 1):
127 1 tkerber
        atoms = atoms.repeat(size)
128 1 tkerber
    return atoms
129 1 tkerber
130 1 tkerber
def parse_symbols(symbols):
131 1 tkerber
    """Return `sumbols` as a sequence of element symbols."""
132 1 tkerber
    if isinstance(symbols, basestring):
133 1 tkerber
        symbols = string2symbols(symbols)
134 1 tkerber
    return symbols
135 1 tkerber
136 1 tkerber
137 1 tkerber
138 1 tkerber
139 1 tkerber
140 1 tkerber
141 1 tkerber
#-----------------------------------------------------------------
142 1 tkerber
# Self test
143 1 tkerber
if __name__ == '__main__':
144 1 tkerber
    import doctest
145 1 tkerber
    print 'doctest: ', doctest.testmod()