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 orthorhombic lattices. 

2 

3The following lattice creators are defined: 

4 SimleOrthorhombic 

5 BaseCenteredOrthorhombic 

6 BodyCenteredOrthorhombic 

7 FaceCenteredOrthorhombic 

8""" 

9 

10from ase.lattice.bravais import Bravais 

11import numpy as np 

12from ase.data import reference_states as _refstate 

13 

14 

15class SimpleOrthorhombicFactory(Bravais): 

16 "A factory for creating simple orthorhombic lattices." 

17 

18 # The name of the crystal structure in ChemicalElements 

19 xtal_name = "orthorhombic" 

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 def get_lattice_constant(self): 

34 """Get the lattice constant of an element with orhtorhombic 

35 crystal structure.""" 

36 if _refstate[self.atomicnumber]['symmetry'] != self.xtal_name: 

37 raise ValueError(("Cannot guess the %s lattice constant of" 

38 + " an element with crystal structure %s.") 

39 % (self.xtal_name, 

40 _refstate[self.atomicnumber]['symmetry'])) 

41 return _refstate[self.atomicnumber].copy() 

42 

43 def make_crystal_basis(self): 

44 """Make the basis matrix for the crystal unit cell and the system unit 

45 cell.""" 

46 

47 lattice = self.latticeconstant 

48 if isinstance(lattice, type({})): 

49 a = lattice['a'] 

50 try: 

51 b = lattice['b'] 

52 except KeyError: 

53 b = a * lattice['b/a'] 

54 try: 

55 c = lattice['c'] 

56 except KeyError: 

57 c = a * lattice['c/a'] 

58 else: 

59 if len(lattice) == 3: 

60 (a, b, c) = lattice 

61 else: 

62 raise ValueError( 

63 "Improper lattice constants for orthorhombic crystal.") 

64 

65 lattice = np.array([[a, 0, 0], [0, b, 0], [0, 0, c]]) 

66 self.latticeconstant = lattice 

67 self.miller_basis = lattice 

68 self.crystal_basis = (self.basis_factor * 

69 np.dot(self.int_basis, lattice)) 

70 self.basis = np.dot(self.directions, self.crystal_basis) 

71 self.check_basis_volume() 

72 

73 def check_basis_volume(self): 

74 "Check the volume of the unit cell." 

75 vol1 = abs(np.linalg.det(self.basis)) 

76 vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant) 

77 if self.bravais_basis is not None: 

78 vol2 /= len(self.bravais_basis) 

79 if abs(vol1 - vol2) > 1e-5: 

80 print("WARNING: Got volume %f, expected %f" % (vol1, vol2)) 

81 

82 

83SimpleOrthorhombic = SimpleOrthorhombicFactory() 

84 

85 

86class BaseCenteredOrthorhombicFactory(SimpleOrthorhombicFactory): 

87 "A factory for creating base-centered orthorhombic lattices." 

88 

89 # The natural basis vectors of the crystal structure 

90 int_basis = np.array([[1, -1, 0], 

91 [1, 1, 0], 

92 [0, 0, 2]]) 

93 basis_factor = 0.5 

94 

95 # Converts the natural basis back to the crystallographic basis 

96 inverse_basis = np.array([[1, 1, 0], 

97 [-1, 1, 0], 

98 [0, 0, 1]]) 

99 inverse_basis_factor = 1.0 

100 

101 def check_basis_volume(self): 

102 "Check the volume of the unit cell." 

103 vol1 = abs(np.linalg.det(self.basis)) 

104 vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant) / 2.0 

105 if abs(vol1 - vol2) > 1e-5: 

106 print("WARNING: Got volume %f, expected %f" % (vol1, vol2)) 

107 

108 

109BaseCenteredOrthorhombic = BaseCenteredOrthorhombicFactory() 

110 

111 

112class BodyCenteredOrthorhombicFactory(SimpleOrthorhombicFactory): 

113 "A factory for creating body-centered orthorhombic lattices." 

114 

115 int_basis = np.array([[-1, 1, 1], 

116 [1, -1, 1], 

117 [1, 1, -1]]) 

118 basis_factor = 0.5 

119 inverse_basis = np.array([[0, 1, 1], 

120 [1, 0, 1], 

121 [1, 1, 0]]) 

122 inverse_basis_factor = 1.0 

123 

124 def check_basis_volume(self): 

125 "Check the volume of the unit cell." 

126 vol1 = abs(np.linalg.det(self.basis)) 

127 vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant) / 2.0 

128 if abs(vol1 - vol2) > 1e-5: 

129 print("WARNING: Got volume %f, expected %f" % (vol1, vol2)) 

130 

131 

132BodyCenteredOrthorhombic = BodyCenteredOrthorhombicFactory() 

133 

134 

135class FaceCenteredOrthorhombicFactory(SimpleOrthorhombicFactory): 

136 "A factory for creating face-centered orthorhombic lattices." 

137 

138 int_basis = np.array([[0, 1, 1], 

139 [1, 0, 1], 

140 [1, 1, 0]]) 

141 basis_factor = 0.5 

142 inverse_basis = np.array([[-1, 1, 1], 

143 [1, -1, 1], 

144 [1, 1, -1]]) 

145 inverse_basis_factor = 1.0 

146 

147 def check_basis_volume(self): 

148 "Check the volume of the unit cell." 

149 vol1 = abs(np.linalg.det(self.basis)) 

150 vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant) / 4.0 

151 if abs(vol1 - vol2) > 1e-5: 

152 print("WARNING: Got volume %f, expected %f" % (vol1, vol2)) 

153 

154 

155FaceCenteredOrthorhombic = FaceCenteredOrthorhombicFactory()