Hide keyboard shortcuts

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

2 

3The following lattice creators are defined: 

4 SimpleCubic 

5 FaceCenteredCubic 

6 BodyCenteredCubic 

7 Diamond 

8""" 

9 

10from ase.lattice.bravais import Bravais, reduceindex 

11import numpy as np 

12from ase.data import reference_states as _refstate 

13 

14 

15class SimpleCubicFactory(Bravais): 

16 "A factory for creating simple cubic lattices." 

17 

18 # The name of the crystal structure in ChemicalElements 

19 xtal_name = "sc" 

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 # For checking the basis volume 

34 atoms_in_unit_cell = 1 

35 

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

44 

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

53 

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 

62 

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) 

71 

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

84 

85 

86SimpleCubic = SimpleCubicFactory() 

87 

88 

89class FaceCenteredCubicFactory(SimpleCubicFactory): 

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

91 

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 

101 

102 atoms_in_unit_cell = 4 

103 

104 

105FaceCenteredCubic = FaceCenteredCubicFactory() 

106 

107 

108class BodyCenteredCubicFactory(SimpleCubicFactory): 

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

110 

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 

120 

121 atoms_in_unit_cell = 2 

122 

123 

124BodyCenteredCubic = BodyCenteredCubicFactory() 

125 

126 

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

131 

132 

133Diamond = DiamondFactory()