Statistiques
| Révision :

root / ase / lattice / cubic.py @ 18

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

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

3
The following lattice creators are defined:
4
    SimpleCubic
5
    FaceCenteredCubic
6
    BodyCenteredCubic
7
    Diamond
8
"""
9

    
10
from ase.lattice.bravais import Bravais
11
import numpy as np
12
from ase.data import reference_states as _refstate
13

    
14
class SimpleCubicFactory(Bravais):
15
    "A factory for creating simple cubic lattices."
16

    
17
    # The name of the crystal structure in ChemicalElements
18
    xtal_name = "sc"
19

    
20
    # The natural basis vectors of the crystal structure
21
    int_basis = np.array([[1, 0, 0],
22
                          [0, 1, 0],
23
                          [0, 0, 1]])
24
    basis_factor = 1.0
25

    
26
    # Converts the natural basis back to the crystallographic basis
27
    inverse_basis = np.array([[1, 0, 0],
28
                              [0, 1, 0],
29
                              [0, 0, 1]])
30
    inverse_basis_factor = 1.0
31

    
32
    # For checking the basis volume
33
    atoms_in_unit_cell = 1
34
    
35
    def get_lattice_constant(self):
36
        "Get the lattice constant of an element with cubic crystal structure."
37
        if _refstate[self.atomicnumber]['symmetry'].lower() != self.xtal_name:
38
            raise ValueError, (("Cannot guess the %s lattice constant of"
39
                                + " an element with crystal structure %s.")
40
                               % (self.xtal_name,
41
                                  _refstate[self.atomicnumber]['symmetry']))
42
        return _refstate[self.atomicnumber]['a']
43

    
44
    def make_crystal_basis(self):
45
        "Make the basis matrix for the crystal unit cell and the system unit cell."
46
        self.crystal_basis = (self.latticeconstant * self.basis_factor
47
                              * self.int_basis)
48
        self.miller_basis = self.latticeconstant * np.identity(3)
49
        self.basis = np.dot(self.directions, self.crystal_basis)
50
        self.check_basis_volume()
51

    
52
    def check_basis_volume(self):
53
        "Check the volume of the unit cell."
54
        vol1 = abs(np.linalg.det(self.basis))
55
        cellsize = self.atoms_in_unit_cell
56
        if self.bravais_basis is not None:
57
            cellsize *= len(self.bravais_basis)
58
        vol2 = (self.calc_num_atoms() * self.latticeconstant**3 / cellsize)
59
        assert abs(vol1-vol2) < 1e-5
60

    
61
    def find_directions(self, directions, miller):
62
        "Find missing directions and miller indices from the specified ones."
63
        directions = list(directions)
64
        miller = list(miller)
65
        # Process keyword "orthogonal"
66
        self.find_ortho(directions)
67
        self.find_ortho(miller)
68
        Bravais.find_directions(self, directions, miller)
69
        
70
    def find_ortho(self, idx):
71
        "Replace keyword 'ortho' or 'orthogonal' with a direction."
72
        for i in range(3):
73
            if isinstance(idx[i], str) and (idx[i].lower() == "ortho" or
74
                                            idx[i].lower() == "orthogonal"):
75
                if self.debug:
76
                    print "Calculating orthogonal direction", i
77
                    print  idx[i-2], "X", idx[i-1],  
78
                idx[i] = reduceindex(cross(idx[i-2], idx[i-1]))
79
                if self.debug:
80
                    print "=", idx[i]
81
                
82

    
83
SimpleCubic = SimpleCubicFactory()
84

    
85
class FaceCenteredCubicFactory(SimpleCubicFactory):
86
    "A factory for creating face-centered cubic lattices."
87

    
88
    xtal_name = "fcc"
89
    int_basis = np.array([[0, 1, 1],
90
                          [1, 0, 1],
91
                          [1, 1, 0]])
92
    basis_factor = 0.5
93
    inverse_basis = np.array([[-1, 1, 1],
94
                              [1, -1, 1],
95
                              [1, 1, -1]])
96
    inverse_basis_factor = 1.0
97

    
98
    atoms_in_unit_cell = 4
99
    
100
FaceCenteredCubic = FaceCenteredCubicFactory()
101

    
102
class BodyCenteredCubicFactory(SimpleCubicFactory):
103
    "A factory for creating body-centered cubic lattices."
104

    
105
    xtal_name = "bcc"
106
    int_basis = np.array([[-1, 1, 1],
107
                          [1, -1, 1],
108
                          [1, 1, -1]])
109
    basis_factor = 0.5
110
    inverse_basis = np.array([[0, 1, 1],
111
                              [1, 0, 1],
112
                              [1, 1, 0]])
113
    inverse_basis_factor = 1.0
114

    
115
    atoms_in_unit_cell = 2
116
    
117
BodyCenteredCubic = BodyCenteredCubicFactory()
118

    
119
class DiamondFactory(FaceCenteredCubicFactory):
120
    "A factory for creating diamond lattices."
121
    xtal_name = "diamond"
122
    bravais_basis = [[0,0,0], [0.25, 0.25, 0.25]]
123
    
124
Diamond = DiamondFactory()
125