Coverage for /builds/kinetik161/ase/ase/lattice/orthorhombic.py: 45.33%

75 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-12-10 11:04 +0000

1"""Function-like objects creating orthorhombic lattices. 

2 

3The following lattice creators are defined: 

4 SimleOrthorhombic 

5 BaseCenteredOrthorhombic 

6 BodyCenteredOrthorhombic 

7 FaceCenteredOrthorhombic 

8""" 

9 

10import numpy as np 

11 

12from ase.data import reference_states as _refstate 

13from ase.lattice.bravais import Bravais 

14 

15 

16class SimpleOrthorhombicFactory(Bravais): 

17 "A factory for creating simple orthorhombic lattices." 

18 

19 # The name of the crystal structure in ChemicalElements 

20 xtal_name = "orthorhombic" 

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

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

36 crystal structure.""" 

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

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

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

40 % (self.xtal_name, 

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

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

43 

44 def make_crystal_basis(self): 

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

46 cell.""" 

47 

48 lattice = self.latticeconstant 

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

50 a = lattice['a'] 

51 try: 

52 b = lattice['b'] 

53 except KeyError: 

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

55 try: 

56 c = lattice['c'] 

57 except KeyError: 

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

59 else: 

60 if len(lattice) == 3: 

61 (a, b, c) = lattice 

62 else: 

63 raise ValueError( 

64 "Improper lattice constants for orthorhombic crystal.") 

65 

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

67 self.latticeconstant = lattice 

68 self.miller_basis = lattice 

69 self.crystal_basis = (self.basis_factor * 

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

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

72 self.check_basis_volume() 

73 

74 def check_basis_volume(self): 

75 "Check the volume of the unit cell." 

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

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

78 if self.bravais_basis is not None: 

79 vol2 /= len(self.bravais_basis) 

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

81 print(f"WARNING: Got volume {vol1:f}, expected {vol2:f}") 

82 

83 

84SimpleOrthorhombic = SimpleOrthorhombicFactory() 

85 

86 

87class BaseCenteredOrthorhombicFactory(SimpleOrthorhombicFactory): 

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

89 

90 # The natural basis vectors of the crystal structure 

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

92 [1, 1, 0], 

93 [0, 0, 2]]) 

94 basis_factor = 0.5 

95 

96 # Converts the natural basis back to the crystallographic basis 

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

98 [-1, 1, 0], 

99 [0, 0, 1]]) 

100 inverse_basis_factor = 1.0 

101 

102 def check_basis_volume(self): 

103 "Check the volume of the unit cell." 

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

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

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

107 print(f"WARNING: Got volume {vol1:f}, expected {vol2:f}") 

108 

109 

110BaseCenteredOrthorhombic = BaseCenteredOrthorhombicFactory() 

111 

112 

113class BodyCenteredOrthorhombicFactory(SimpleOrthorhombicFactory): 

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

115 

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

117 [1, -1, 1], 

118 [1, 1, -1]]) 

119 basis_factor = 0.5 

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

121 [1, 0, 1], 

122 [1, 1, 0]]) 

123 inverse_basis_factor = 1.0 

124 

125 def check_basis_volume(self): 

126 "Check the volume of the unit cell." 

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

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

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

130 print(f"WARNING: Got volume {vol1:f}, expected {vol2:f}") 

131 

132 

133BodyCenteredOrthorhombic = BodyCenteredOrthorhombicFactory() 

134 

135 

136class FaceCenteredOrthorhombicFactory(SimpleOrthorhombicFactory): 

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

138 

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

140 [1, 0, 1], 

141 [1, 1, 0]]) 

142 basis_factor = 0.5 

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

144 [1, -1, 1], 

145 [1, 1, -1]]) 

146 inverse_basis_factor = 1.0 

147 

148 def check_basis_volume(self): 

149 "Check the volume of the unit cell." 

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

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

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

153 print(f"WARNING: Got volume {vol1:f}, expected {vol2:f}") 

154 

155 

156FaceCenteredOrthorhombic = FaceCenteredOrthorhombicFactory()