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

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

2 

3The following lattice creators are defined: 

4 SimpleCubic 

5 FaceCenteredCubic 

6 BodyCenteredCubic 

7 Diamond 

8""" 

9 

10import numpy as np 

11 

12from ase.data import reference_states as _refstate 

13from ase.lattice.bravais import Bravais, reduceindex 

14 

15 

16class SimpleCubicFactory(Bravais): 

17 "A factory for creating simple cubic lattices." 

18 

19 # The name of the crystal structure in ChemicalElements 

20 xtal_name = "sc" 

21 

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 

27 

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 

33 

34 # For checking the basis volume 

35 atoms_in_unit_cell = 1 

36 

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'] 

45 

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() 

54 

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 

63 

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) 

72 

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]) 

85 

86 

87SimpleCubic = SimpleCubicFactory() 

88 

89 

90class FaceCenteredCubicFactory(SimpleCubicFactory): 

91 "A factory for creating face-centered cubic lattices." 

92 

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 

102 

103 atoms_in_unit_cell = 4 

104 

105 

106FaceCenteredCubic = FaceCenteredCubicFactory() 

107 

108 

109class BodyCenteredCubicFactory(SimpleCubicFactory): 

110 "A factory for creating body-centered cubic lattices." 

111 

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 

121 

122 atoms_in_unit_cell = 2 

123 

124 

125BodyCenteredCubic = BodyCenteredCubicFactory() 

126 

127 

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]] 

132 

133 

134Diamond = DiamondFactory()