Coverage for /builds/ase/ase/ase/lattice/orthorhombic.py: 45.33%
75 statements
« prev ^ index » next coverage.py v7.5.3, created at 2025-08-02 00:12 +0000
« prev ^ index » next coverage.py v7.5.3, created at 2025-08-02 00:12 +0000
1# fmt: off
3"""Function-like objects creating orthorhombic lattices.
5The following lattice creators are defined:
6 SimleOrthorhombic
7 BaseCenteredOrthorhombic
8 BodyCenteredOrthorhombic
9 FaceCenteredOrthorhombic
10"""
12import numpy as np
14from ase.data import reference_states as _refstate
15from ase.lattice.bravais import Bravais
18class SimpleOrthorhombicFactory(Bravais):
19 "A factory for creating simple orthorhombic lattices."
21 # The name of the crystal structure in ChemicalElements
22 xtal_name = "orthorhombic"
24 # The natural basis vectors of the crystal structure
25 int_basis = np.array([[1, 0, 0],
26 [0, 1, 0],
27 [0, 0, 1]])
28 basis_factor = 1.0
30 # Converts the natural basis back to the crystallographic basis
31 inverse_basis = np.array([[1, 0, 0],
32 [0, 1, 0],
33 [0, 0, 1]])
34 inverse_basis_factor = 1.0
36 def get_lattice_constant(self):
37 """Get the lattice constant of an element with orhtorhombic
38 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].copy()
46 def make_crystal_basis(self):
47 """Make the basis matrix for the crystal unit cell and the system unit
48 cell."""
50 lattice = self.latticeconstant
51 if isinstance(lattice, type({})):
52 a = lattice['a']
53 try:
54 b = lattice['b']
55 except KeyError:
56 b = a * lattice['b/a']
57 try:
58 c = lattice['c']
59 except KeyError:
60 c = a * lattice['c/a']
61 else:
62 if len(lattice) == 3:
63 (a, b, c) = lattice
64 else:
65 raise ValueError(
66 "Improper lattice constants for orthorhombic crystal.")
68 lattice = np.array([[a, 0, 0], [0, b, 0], [0, 0, c]])
69 self.latticeconstant = lattice
70 self.miller_basis = lattice
71 self.crystal_basis = (self.basis_factor *
72 np.dot(self.int_basis, lattice))
73 self.basis = np.dot(self.directions, self.crystal_basis)
74 self.check_basis_volume()
76 def check_basis_volume(self):
77 "Check the volume of the unit cell."
78 vol1 = abs(np.linalg.det(self.basis))
79 vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant)
80 if self.bravais_basis is not None:
81 vol2 /= len(self.bravais_basis)
82 if abs(vol1 - vol2) > 1e-5:
83 print(f"WARNING: Got volume {vol1:f}, expected {vol2:f}")
86SimpleOrthorhombic = SimpleOrthorhombicFactory()
89class BaseCenteredOrthorhombicFactory(SimpleOrthorhombicFactory):
90 "A factory for creating base-centered orthorhombic lattices."
92 # The natural basis vectors of the crystal structure
93 int_basis = np.array([[1, -1, 0],
94 [1, 1, 0],
95 [0, 0, 2]])
96 basis_factor = 0.5
98 # Converts the natural basis back to the crystallographic basis
99 inverse_basis = np.array([[1, 1, 0],
100 [-1, 1, 0],
101 [0, 0, 1]])
102 inverse_basis_factor = 1.0
104 def check_basis_volume(self):
105 "Check the volume of the unit cell."
106 vol1 = abs(np.linalg.det(self.basis))
107 vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant) / 2.0
108 if abs(vol1 - vol2) > 1e-5:
109 print(f"WARNING: Got volume {vol1:f}, expected {vol2:f}")
112BaseCenteredOrthorhombic = BaseCenteredOrthorhombicFactory()
115class BodyCenteredOrthorhombicFactory(SimpleOrthorhombicFactory):
116 "A factory for creating body-centered orthorhombic lattices."
118 int_basis = np.array([[-1, 1, 1],
119 [1, -1, 1],
120 [1, 1, -1]])
121 basis_factor = 0.5
122 inverse_basis = np.array([[0, 1, 1],
123 [1, 0, 1],
124 [1, 1, 0]])
125 inverse_basis_factor = 1.0
127 def check_basis_volume(self):
128 "Check the volume of the unit cell."
129 vol1 = abs(np.linalg.det(self.basis))
130 vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant) / 2.0
131 if abs(vol1 - vol2) > 1e-5:
132 print(f"WARNING: Got volume {vol1:f}, expected {vol2:f}")
135BodyCenteredOrthorhombic = BodyCenteredOrthorhombicFactory()
138class FaceCenteredOrthorhombicFactory(SimpleOrthorhombicFactory):
139 "A factory for creating face-centered orthorhombic lattices."
141 int_basis = np.array([[0, 1, 1],
142 [1, 0, 1],
143 [1, 1, 0]])
144 basis_factor = 0.5
145 inverse_basis = np.array([[-1, 1, 1],
146 [1, -1, 1],
147 [1, 1, -1]])
148 inverse_basis_factor = 1.0
150 def check_basis_volume(self):
151 "Check the volume of the unit cell."
152 vol1 = abs(np.linalg.det(self.basis))
153 vol2 = self.calc_num_atoms() * np.linalg.det(self.latticeconstant) / 4.0
154 if abs(vol1 - vol2) > 1e-5:
155 print(f"WARNING: Got volume {vol1:f}, expected {vol2:f}")
158FaceCenteredOrthorhombic = FaceCenteredOrthorhombicFactory()