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

52 

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 

61 

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) 

70 

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

83 

84 

85SimpleCubic = SimpleCubicFactory() 

86 

87 

88class FaceCenteredCubicFactory(SimpleCubicFactory): 

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

90 

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 

100 

101 atoms_in_unit_cell = 4 

102 

103 

104FaceCenteredCubic = FaceCenteredCubicFactory() 

105 

106 

107class BodyCenteredCubicFactory(SimpleCubicFactory): 

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

109 

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 

119 

120 atoms_in_unit_cell = 2 

121 

122 

123BodyCenteredCubic = BodyCenteredCubicFactory() 

124 

125 

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

130 

131 

132Diamond = DiamondFactory()