def test_abs_cap(self): self.assertEqual(abs_cap(1.000000001), 1.0) self.assertEqual(abs_cap(-1.000000001), -1.0) v = random.uniform(-1, 1) self.assertEqual(abs_cap(v), v) self.assertEqual(abs_cap(1.000000001, 2), 1.000000001) self.assertEqual(abs_cap(-2.000000001, 2), -2.0)
def __init__(self, matrix): """ Create a lattice from any sequence of 9 numbers. Note that the sequence is assumed to be read one row at a time. Each row represents one lattice vector. Args: matrix: Sequence of numbers in any form. Examples of acceptable input. i) An actual numpy array. ii) [[1, 0, 0], [0, 1, 0], [0, 0, 1]] iii) [1, 0, 0 , 0, 1, 0, 0, 0, 1] iv) (1, 0, 0, 0, 1, 0, 0, 0, 1) Each row should correspond to a lattice vector. E.g., [[10, 0, 0], [20, 10, 0], [0, 0, 30]] specifies a lattice with lattice vectors [10, 0, 0], [20, 10, 0] and [0, 0, 30]. """ m = np.array(matrix, dtype=np.float64).reshape((3, 3)) lengths = np.sqrt(np.sum(m ** 2, axis=1)) angles = np.zeros(3) for i in range(3): j = (i + 1) % 3 k = (i + 2) % 3 angles[i] = abs_cap(dot(m[j], m[k]) / (lengths[j] * lengths[k])) self._angles = np.arccos(angles) * 180. / pi self._lengths = lengths self._matrix = m # The inverse matrix is lazily generated for efficiency. self._inv_matrix = None self._metric_tensor = None
def from_parameters(a, b, c, alpha, beta, gamma): """ Create a Lattice using unit cell lengths and angles (in degrees). Args: a (float): *a* lattice parameter. b (float): *b* lattice parameter. c (float): *c* lattice parameter. alpha (float): *alpha* angle in degrees. beta (float): *beta* angle in degrees. gamma (float): *gamma* angle in degrees. Returns: Lattice with the specified lattice parameters. """ alpha_r = radians(alpha) beta_r = radians(beta) gamma_r = radians(gamma) val = (np.cos(alpha_r) * np.cos(beta_r) - np.cos(gamma_r))\ / (np.sin(alpha_r) * np.sin(beta_r)) #Sometimes rounding errors result in values slightly > 1. val = abs_cap(val) gamma_star = np.arccos(val) vector_a = [a * np.sin(beta_r), 0.0, a * np.cos(beta_r)] vector_b = [-b * np.sin(alpha_r) * np.cos(gamma_star), b * np.sin(alpha_r) * np.sin(gamma_star), b * np.cos(alpha_r)] vector_c = [0.0, 0.0, float(c)] return Lattice([vector_a, vector_b, vector_c])
def solid_angle(center, coords): """ Helper method to calculate the solid angle of a set of coords from the center. Args: center (3x1 array): Center to measure solid angle from. coords (Nx3 array): List of coords to determine solid angle. Returns: The solid angle. """ o = np.array(center) r = [np.array(c) - o for c in coords] r.append(r[0]) n = [np.cross(r[i + 1], r[i]) for i in range(len(r) - 1)] n.append(np.cross(r[1], r[0])) vals = [] for i in range(len(n) - 1): v = -np.dot(n[i], n[i + 1]) / (np.linalg.norm(n[i]) * np.linalg.norm(n[i + 1])) vals.append(math.acos(abs_cap(v))) phi = sum(vals) return phi + (3 - len(r)) * math.pi
def solid_angle(center, coords): """ Helper method to calculate the solid angle of a set of coords from the center. Args: center (3x1 array): Center to measure solid angle from. coords (Nx3 array): List of coords to determine solid angle. Returns: The solid angle. """ o = np.array(center) r = [np.array(c) - o for c in coords] r.append(r[0]) n = [np.cross(r[i + 1], r[i]) for i in range(len(r) - 1)] n.append(np.cross(r[1], r[0])) vals = [] for i in range(len(n) - 1): v = -np.dot(n[i], n[i + 1])\ / (np.linalg.norm(n[i]) * np.linalg.norm(n[i + 1])) vals.append(math.acos(abs_cap(v))) phi = sum(vals) return phi + (3 - len(r)) * math.pi