Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""Function-like objects creating cubic lattices (SC, FCC, BCC and Diamond).
3The following lattice creators are defined:
4 SimpleCubic
5 FaceCenteredCubic
6 BodyCenteredCubic
7 Diamond
8"""
10from ase.lattice.bravais import Bravais, reduceindex
11import numpy as np
12from ase.data import reference_states as _refstate
15class SimpleCubicFactory(Bravais):
16 "A factory for creating simple cubic lattices."
18 # The name of the crystal structure in ChemicalElements
19 xtal_name = "sc"
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
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
33 # For checking the basis volume
34 atoms_in_unit_cell = 1
36 def get_lattice_constant(self):
37 "Get the lattice constant of an element with cubic crystal structure."
38 if _refstate[self.atomicnumber]['symmetry'] != self.xtal_name:
39 raise ValueError(("Cannot guess the %s lattice constant of"
40 + " an element with crystal structure %s.")
41 % (self.xtal_name,
42 _refstate[self.atomicnumber]['symmetry']))
43 return _refstate[self.atomicnumber]['a']
45 def make_crystal_basis(self):
46 "Make the basis matrix for the crystal unit cell and the system unit cell."
47 self.crystal_basis = (self.latticeconstant * self.basis_factor
48 * self.int_basis)
49 self.miller_basis = self.latticeconstant * np.identity(3)
50 self.basis = np.dot(self.directions, self.crystal_basis)
51 self.check_basis_volume()
53 def check_basis_volume(self):
54 "Check the volume of the unit cell."
55 vol1 = abs(np.linalg.det(self.basis))
56 cellsize = self.atoms_in_unit_cell
57 if self.bravais_basis is not None:
58 cellsize *= len(self.bravais_basis)
59 vol2 = (self.calc_num_atoms() * self.latticeconstant**3 / cellsize)
60 assert abs(vol1-vol2) < 1e-5
62 def find_directions(self, directions, miller):
63 "Find missing directions and miller indices from the specified ones."
64 directions = list(directions)
65 miller = list(miller)
66 # Process keyword "orthogonal"
67 self.find_ortho(directions)
68 self.find_ortho(miller)
69 Bravais.find_directions(self, directions, miller)
71 def find_ortho(self, idx):
72 "Replace keyword 'ortho' or 'orthogonal' with a direction."
73 for i in range(3):
74 if (isinstance(idx[i], str)
75 and (idx[i].lower() == "ortho" or
76 idx[i].lower() == "orthogonal")):
77 if self.debug:
78 print("Calculating orthogonal direction", i)
79 print(idx[i-2], "X", idx[i-1], end=' ')
80 idx[i] = reduceindex(np.cross(idx[i-2], idx[i-1]))
81 if self.debug:
82 print("=", idx[i])
85SimpleCubic = SimpleCubicFactory()
88class FaceCenteredCubicFactory(SimpleCubicFactory):
89 "A factory for creating face-centered cubic lattices."
91 xtal_name = "fcc"
92 int_basis = np.array([[0, 1, 1],
93 [1, 0, 1],
94 [1, 1, 0]])
95 basis_factor = 0.5
96 inverse_basis = np.array([[-1, 1, 1],
97 [1, -1, 1],
98 [1, 1, -1]])
99 inverse_basis_factor = 1.0
101 atoms_in_unit_cell = 4
104FaceCenteredCubic = FaceCenteredCubicFactory()
107class BodyCenteredCubicFactory(SimpleCubicFactory):
108 "A factory for creating body-centered cubic lattices."
110 xtal_name = "bcc"
111 int_basis = np.array([[-1, 1, 1],
112 [1, -1, 1],
113 [1, 1, -1]])
114 basis_factor = 0.5
115 inverse_basis = np.array([[0, 1, 1],
116 [1, 0, 1],
117 [1, 1, 0]])
118 inverse_basis_factor = 1.0
120 atoms_in_unit_cell = 2
123BodyCenteredCubic = BodyCenteredCubicFactory()
126class DiamondFactory(FaceCenteredCubicFactory):
127 "A factory for creating diamond lattices."
128 xtal_name = "diamond"
129 bravais_basis = [[0, 0, 0], [0.25, 0.25, 0.25]]
132Diamond = DiamondFactory()