root / ase / lattice / spacegroup / crystal.py @ 1
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() |