Statistiques
| Révision :

root / ase / lattice / orthorhombic.py @ 1

Historique | Voir | Annoter | Télécharger (5,3 ko)

1
"""Function-like objects creating orthorhombic lattices.
2

3
The following lattice creators are defined:
4
    SimleOrthorhombic
5
    BaseCenteredOrthorhombic
6
    BodyCenteredOrthorhombic
7
    FaceCenteredOrthorhombic
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

    
15
class SimpleOrthorhombicFactory(Bravais):
16
    "A factory for creating simple orthorhombic lattices."
17

    
18
    # The name of the crystal structure in ChemicalElements
19
    xtal_name = "orthorhombic"
20

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

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

    
33
    def get_lattice_constant(self):
34
        "Get the lattice constant of an element with orhtorhombic crystal structure."
35
        if _refstate[self.atomicnumber]['symmetry'].lower() != self.xtal_name:
36
            raise ValueError, (("Cannot guess the %s lattice constant of"
37
                                + " an element with crystal structure %s.")
38
                               % (self.xtal_name,
39
                                  _refstate[self.atomicnumber]['symmetry']))
40
        return _refstate[self.atomicnumber].copy()
41

    
42
    def make_crystal_basis(self):
43
        "Make the basis matrix for the crystal unit cell and the system unit cell."
44
        lattice = self.latticeconstant
45
        if type(lattice) == type({}):
46
            a = lattice['a']
47
            try:
48
                b = lattice['b']
49
            except KeyError:
50
                b = a * lattice['b/a']
51
            try:
52
                c = lattice['c']
53
            except KeyError:
54
                c = a * lattice['c/a']
55
        else:
56
            if len(lattice) == 3:
57
                (a,b,c) = lattice
58
            else:
59
                raise ValueError, "Improper lattice constants for orthorhombic crystal."
60

    
61
        lattice = np.array([[a,0,0],[0,b,0],[0,0,c]])
62
        self.latticeconstant = lattice
63
        self.miller_basis = lattice
64
        self.crystal_basis = (self.basis_factor *
65
                              np.dot(self.int_basis, lattice))
66
        self.basis = np.dot(self.directions, self.crystal_basis)
67
        self.check_basis_volume()
68

    
69
    def check_basis_volume(self):
70
        "Check the volume of the unit cell."
71
        vol1 = abs(np.linalg.det(self.basis))
72
        vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant)
73
        if self.bravais_basis is not None:
74
            vol2 /= len(self.bravais_basis)
75
        if abs(vol1-vol2) > 1e-5:
76
            print "WARNING: Got volume %f, expected %f" % (vol1, vol2)
77

    
78
SimpleOrthorhombic = SimpleOrthorhombicFactory()
79

    
80
class BaseCenteredOrthorhombicFactory(SimpleOrthorhombicFactory):
81
    "A factory for creating base-centered orthorhombic lattices."
82

    
83
    # The natural basis vectors of the crystal structure
84
    int_basis = np.array([[1, -1, 0],
85
                          [1, 1, 0],
86
                          [0, 0, 2]])
87
    basis_factor = 0.5
88

    
89
    # Converts the natural basis back to the crystallographic basis
90
    inverse_basis = np.array([[1, 1, 0],
91
                              [-1, 1, 0],
92
                              [0, 0, 1]])
93
    inverse_basis_factor = 1.0
94

    
95
    def check_basis_volume(self):
96
        "Check the volume of the unit cell."
97
        vol1 = abs(np.linalg.det(self.basis))
98
        vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant) / 2.0
99
        if abs(vol1-vol2) > 1e-5:
100
            print "WARNING: Got volume %f, expected %f" % (vol1, vol2)
101

    
102
BaseCenteredOrthorhombic = BaseCenteredOrthorhombicFactory()
103

    
104
class BodyCenteredOrthorhombicFactory(SimpleOrthorhombicFactory):
105
    "A factory for creating body-centered orthorhombic lattices."
106

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

    
116
    def check_basis_volume(self):
117
        "Check the volume of the unit cell."
118
        vol1 = abs(np.linalg.det(self.basis))
119
        vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant) / 2.0
120
        if abs(vol1-vol2) > 1e-5:
121
            print "WARNING: Got volume %f, expected %f" % (vol1, vol2)
122

    
123
BodyCenteredOrthorhombic = BodyCenteredOrthorhombicFactory()
124
class FaceCenteredOrthorhombicFactory(SimpleOrthorhombicFactory):
125
    "A factory for creating face-centered orthorhombic lattices."
126

    
127
    int_basis = np.array([[0, 1, 1],
128
                          [1, 0, 1],
129
                          [1, 1, 0]])
130
    basis_factor = 0.5
131
    inverse_basis = np.array([[-1, 1, 1],
132
                              [1, -1, 1],
133
                              [1, 1, -1]])
134
    inverse_basis_factor = 1.0
135

    
136
    def check_basis_volume(self):
137
        "Check the volume of the unit cell."
138
        vol1 = abs(np.linalg.det(self.basis))
139
        vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant) / 4.0
140
        if abs(vol1-vol2) > 1e-5:
141
            print "WARNING: Got volume %f, expected %f" % (vol1, vol2)
142

    
143
FaceCenteredOrthorhombic = FaceCenteredOrthorhombicFactory()
144