Coverage for /builds/kinetik161/ase/ase/lattice/cubic.py: 88.71%
62 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-12-10 11:04 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-12-10 11:04 +0000
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"""
10import numpy as np
12from ase.data import reference_states as _refstate
13from ase.lattice.bravais import Bravais, reduceindex
16class SimpleCubicFactory(Bravais):
17 "A factory for creating simple cubic lattices."
19 # The name of the crystal structure in ChemicalElements
20 xtal_name = "sc"
22 # The natural basis vectors of the crystal structure
23 int_basis = np.array([[1, 0, 0],
24 [0, 1, 0],
25 [0, 0, 1]])
26 basis_factor = 1.0
28 # Converts the natural basis back to the crystallographic basis
29 inverse_basis = np.array([[1, 0, 0],
30 [0, 1, 0],
31 [0, 0, 1]])
32 inverse_basis_factor = 1.0
34 # For checking the basis volume
35 atoms_in_unit_cell = 1
37 def get_lattice_constant(self):
38 "Get the lattice constant of an element with cubic crystal structure."
39 if _refstate[self.atomicnumber]['symmetry'] != self.xtal_name:
40 raise ValueError(("Cannot guess the %s lattice constant of"
41 + " an element with crystal structure %s.")
42 % (self.xtal_name,
43 _refstate[self.atomicnumber]['symmetry']))
44 return _refstate[self.atomicnumber]['a']
46 def make_crystal_basis(self):
47 """Make the basis matrix for the crystal unit cell and the
48 system unit cell."""
49 self.crystal_basis = (self.latticeconstant * self.basis_factor
50 * self.int_basis)
51 self.miller_basis = self.latticeconstant * np.identity(3)
52 self.basis = np.dot(self.directions, self.crystal_basis)
53 self.check_basis_volume()
55 def check_basis_volume(self):
56 "Check the volume of the unit cell."
57 vol1 = abs(np.linalg.det(self.basis))
58 cellsize = self.atoms_in_unit_cell
59 if self.bravais_basis is not None:
60 cellsize *= len(self.bravais_basis)
61 vol2 = (self.calc_num_atoms() * self.latticeconstant**3 / cellsize)
62 assert abs(vol1 - vol2) < 1e-5
64 def find_directions(self, directions, miller):
65 "Find missing directions and miller indices from the specified ones."
66 directions = list(directions)
67 miller = list(miller)
68 # Process keyword "orthogonal"
69 self.find_ortho(directions)
70 self.find_ortho(miller)
71 Bravais.find_directions(self, directions, miller)
73 def find_ortho(self, idx):
74 "Replace keyword 'ortho' or 'orthogonal' with a direction."
75 for i in range(3):
76 if (isinstance(idx[i], str)
77 and (idx[i].lower() == "ortho" or
78 idx[i].lower() == "orthogonal")):
79 if self.debug:
80 print("Calculating orthogonal direction", i)
81 print(idx[i - 2], "X", idx[i - 1], end=' ')
82 idx[i] = reduceindex(np.cross(idx[i - 2], idx[i - 1]))
83 if self.debug:
84 print("=", idx[i])
87SimpleCubic = SimpleCubicFactory()
90class FaceCenteredCubicFactory(SimpleCubicFactory):
91 "A factory for creating face-centered cubic lattices."
93 xtal_name = "fcc"
94 int_basis = np.array([[0, 1, 1],
95 [1, 0, 1],
96 [1, 1, 0]])
97 basis_factor = 0.5
98 inverse_basis = np.array([[-1, 1, 1],
99 [1, -1, 1],
100 [1, 1, -1]])
101 inverse_basis_factor = 1.0
103 atoms_in_unit_cell = 4
106FaceCenteredCubic = FaceCenteredCubicFactory()
109class BodyCenteredCubicFactory(SimpleCubicFactory):
110 "A factory for creating body-centered cubic lattices."
112 xtal_name = "bcc"
113 int_basis = np.array([[-1, 1, 1],
114 [1, -1, 1],
115 [1, 1, -1]])
116 basis_factor = 0.5
117 inverse_basis = np.array([[0, 1, 1],
118 [1, 0, 1],
119 [1, 1, 0]])
120 inverse_basis_factor = 1.0
122 atoms_in_unit_cell = 2
125BodyCenteredCubic = BodyCenteredCubicFactory()
128class DiamondFactory(FaceCenteredCubicFactory):
129 "A factory for creating diamond lattices."
130 xtal_name = "diamond"
131 bravais_basis = [[0, 0, 0], [0.25, 0.25, 0.25]]
134Diamond = DiamondFactory()