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