Statistiques
| Révision :

root / ase / lattice / cubic.py @ 12

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

1 1 tkerber
"""Function-like objects creating cubic lattices (SC, FCC, BCC and Diamond).
2 1 tkerber

3 1 tkerber
The following lattice creators are defined:
4 1 tkerber
    SimpleCubic
5 1 tkerber
    FaceCenteredCubic
6 1 tkerber
    BodyCenteredCubic
7 1 tkerber
    Diamond
8 1 tkerber
"""
9 1 tkerber
10 1 tkerber
from ase.lattice.bravais import Bravais
11 1 tkerber
import numpy as np
12 1 tkerber
from ase.data import reference_states as _refstate
13 1 tkerber
14 1 tkerber
class SimpleCubicFactory(Bravais):
15 1 tkerber
    "A factory for creating simple cubic lattices."
16 1 tkerber
17 1 tkerber
    # The name of the crystal structure in ChemicalElements
18 1 tkerber
    xtal_name = "sc"
19 1 tkerber
20 1 tkerber
    # The natural basis vectors of the crystal structure
21 1 tkerber
    int_basis = np.array([[1, 0, 0],
22 1 tkerber
                          [0, 1, 0],
23 1 tkerber
                          [0, 0, 1]])
24 1 tkerber
    basis_factor = 1.0
25 1 tkerber
26 1 tkerber
    # Converts the natural basis back to the crystallographic basis
27 1 tkerber
    inverse_basis = np.array([[1, 0, 0],
28 1 tkerber
                              [0, 1, 0],
29 1 tkerber
                              [0, 0, 1]])
30 1 tkerber
    inverse_basis_factor = 1.0
31 1 tkerber
32 1 tkerber
    # For checking the basis volume
33 1 tkerber
    atoms_in_unit_cell = 1
34 1 tkerber
35 1 tkerber
    def get_lattice_constant(self):
36 1 tkerber
        "Get the lattice constant of an element with cubic crystal structure."
37 1 tkerber
        if _refstate[self.atomicnumber]['symmetry'].lower() != self.xtal_name:
38 1 tkerber
            raise ValueError, (("Cannot guess the %s lattice constant of"
39 1 tkerber
                                + " an element with crystal structure %s.")
40 1 tkerber
                               % (self.xtal_name,
41 1 tkerber
                                  _refstate[self.atomicnumber]['symmetry']))
42 1 tkerber
        return _refstate[self.atomicnumber]['a']
43 1 tkerber
44 1 tkerber
    def make_crystal_basis(self):
45 1 tkerber
        "Make the basis matrix for the crystal unit cell and the system unit cell."
46 1 tkerber
        self.crystal_basis = (self.latticeconstant * self.basis_factor
47 1 tkerber
                              * self.int_basis)
48 1 tkerber
        self.miller_basis = self.latticeconstant * np.identity(3)
49 1 tkerber
        self.basis = np.dot(self.directions, self.crystal_basis)
50 1 tkerber
        self.check_basis_volume()
51 1 tkerber
52 1 tkerber
    def check_basis_volume(self):
53 1 tkerber
        "Check the volume of the unit cell."
54 1 tkerber
        vol1 = abs(np.linalg.det(self.basis))
55 1 tkerber
        cellsize = self.atoms_in_unit_cell
56 1 tkerber
        if self.bravais_basis is not None:
57 1 tkerber
            cellsize *= len(self.bravais_basis)
58 1 tkerber
        vol2 = (self.calc_num_atoms() * self.latticeconstant**3 / cellsize)
59 1 tkerber
        assert abs(vol1-vol2) < 1e-5
60 1 tkerber
61 1 tkerber
    def find_directions(self, directions, miller):
62 1 tkerber
        "Find missing directions and miller indices from the specified ones."
63 1 tkerber
        directions = list(directions)
64 1 tkerber
        miller = list(miller)
65 1 tkerber
        # Process keyword "orthogonal"
66 1 tkerber
        self.find_ortho(directions)
67 1 tkerber
        self.find_ortho(miller)
68 1 tkerber
        Bravais.find_directions(self, directions, miller)
69 1 tkerber
70 1 tkerber
    def find_ortho(self, idx):
71 1 tkerber
        "Replace keyword 'ortho' or 'orthogonal' with a direction."
72 1 tkerber
        for i in range(3):
73 1 tkerber
            if isinstance(idx[i], str) and (idx[i].lower() == "ortho" or
74 1 tkerber
                                            idx[i].lower() == "orthogonal"):
75 1 tkerber
                if self.debug:
76 1 tkerber
                    print "Calculating orthogonal direction", i
77 1 tkerber
                    print  idx[i-2], "X", idx[i-1],
78 1 tkerber
                idx[i] = reduceindex(cross(idx[i-2], idx[i-1]))
79 1 tkerber
                if self.debug:
80 1 tkerber
                    print "=", idx[i]
81 1 tkerber
82 1 tkerber
83 1 tkerber
SimpleCubic = SimpleCubicFactory()
84 1 tkerber
85 1 tkerber
class FaceCenteredCubicFactory(SimpleCubicFactory):
86 1 tkerber
    "A factory for creating face-centered cubic lattices."
87 1 tkerber
88 1 tkerber
    xtal_name = "fcc"
89 1 tkerber
    int_basis = np.array([[0, 1, 1],
90 1 tkerber
                          [1, 0, 1],
91 1 tkerber
                          [1, 1, 0]])
92 1 tkerber
    basis_factor = 0.5
93 1 tkerber
    inverse_basis = np.array([[-1, 1, 1],
94 1 tkerber
                              [1, -1, 1],
95 1 tkerber
                              [1, 1, -1]])
96 1 tkerber
    inverse_basis_factor = 1.0
97 1 tkerber
98 1 tkerber
    atoms_in_unit_cell = 4
99 1 tkerber
100 1 tkerber
FaceCenteredCubic = FaceCenteredCubicFactory()
101 1 tkerber
102 1 tkerber
class BodyCenteredCubicFactory(SimpleCubicFactory):
103 1 tkerber
    "A factory for creating body-centered cubic lattices."
104 1 tkerber
105 1 tkerber
    xtal_name = "bcc"
106 1 tkerber
    int_basis = np.array([[-1, 1, 1],
107 1 tkerber
                          [1, -1, 1],
108 1 tkerber
                          [1, 1, -1]])
109 1 tkerber
    basis_factor = 0.5
110 1 tkerber
    inverse_basis = np.array([[0, 1, 1],
111 1 tkerber
                              [1, 0, 1],
112 1 tkerber
                              [1, 1, 0]])
113 1 tkerber
    inverse_basis_factor = 1.0
114 1 tkerber
115 1 tkerber
    atoms_in_unit_cell = 2
116 1 tkerber
117 1 tkerber
BodyCenteredCubic = BodyCenteredCubicFactory()
118 1 tkerber
119 1 tkerber
class DiamondFactory(FaceCenteredCubicFactory):
120 1 tkerber
    "A factory for creating diamond lattices."
121 1 tkerber
    xtal_name = "diamond"
122 1 tkerber
    bravais_basis = [[0,0,0], [0.25, 0.25, 0.25]]
123 1 tkerber
124 1 tkerber
Diamond = DiamondFactory()