Coverage for /builds/ase/ase/ase/lattice/cubic.py : 88.71%

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
47 system unit cell."""
48 self.crystal_basis = (self.latticeconstant * self.basis_factor
49 * self.int_basis)
50 self.miller_basis = self.latticeconstant * np.identity(3)
51 self.basis = np.dot(self.directions, self.crystal_basis)
52 self.check_basis_volume()
54 def check_basis_volume(self):
55 "Check the volume of the unit cell."
56 vol1 = abs(np.linalg.det(self.basis))
57 cellsize = self.atoms_in_unit_cell
58 if self.bravais_basis is not None:
59 cellsize *= len(self.bravais_basis)
60 vol2 = (self.calc_num_atoms() * self.latticeconstant**3 / cellsize)
61 assert abs(vol1 - vol2) < 1e-5
63 def find_directions(self, directions, miller):
64 "Find missing directions and miller indices from the specified ones."
65 directions = list(directions)
66 miller = list(miller)
67 # Process keyword "orthogonal"
68 self.find_ortho(directions)
69 self.find_ortho(miller)
70 Bravais.find_directions(self, directions, miller)
72 def find_ortho(self, idx):
73 "Replace keyword 'ortho' or 'orthogonal' with a direction."
74 for i in range(3):
75 if (isinstance(idx[i], str)
76 and (idx[i].lower() == "ortho" or
77 idx[i].lower() == "orthogonal")):
78 if self.debug:
79 print("Calculating orthogonal direction", i)
80 print(idx[i - 2], "X", idx[i - 1], end=' ')
81 idx[i] = reduceindex(np.cross(idx[i - 2], idx[i - 1]))
82 if self.debug:
83 print("=", idx[i])
86SimpleCubic = SimpleCubicFactory()
89class FaceCenteredCubicFactory(SimpleCubicFactory):
90 "A factory for creating face-centered cubic lattices."
92 xtal_name = "fcc"
93 int_basis = np.array([[0, 1, 1],
94 [1, 0, 1],
95 [1, 1, 0]])
96 basis_factor = 0.5
97 inverse_basis = np.array([[-1, 1, 1],
98 [1, -1, 1],
99 [1, 1, -1]])
100 inverse_basis_factor = 1.0
102 atoms_in_unit_cell = 4
105FaceCenteredCubic = FaceCenteredCubicFactory()
108class BodyCenteredCubicFactory(SimpleCubicFactory):
109 "A factory for creating body-centered cubic lattices."
111 xtal_name = "bcc"
112 int_basis = np.array([[-1, 1, 1],
113 [1, -1, 1],
114 [1, 1, -1]])
115 basis_factor = 0.5
116 inverse_basis = np.array([[0, 1, 1],
117 [1, 0, 1],
118 [1, 1, 0]])
119 inverse_basis_factor = 1.0
121 atoms_in_unit_cell = 2
124BodyCenteredCubic = BodyCenteredCubicFactory()
127class DiamondFactory(FaceCenteredCubicFactory):
128 "A factory for creating diamond lattices."
129 xtal_name = "diamond"
130 bravais_basis = [[0, 0, 0], [0.25, 0.25, 0.25]]
133Diamond = DiamondFactory()