Exemple #1
0
    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)
Exemple #2
0
    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)
Exemple #3
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
        self._inv_matrix = None
        self._metric_tensor = None
        self._diags = None
        self._lll_matrix_mappings = {}
        self._lll_inverse = None
        self.is_orthogonal = all([abs(a - 90) < 1e-5 for a in self._angles])
Exemple #4
0
    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])
Exemple #5
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
        self._inv_matrix = None
        self._metric_tensor = None
        self._diags = None
        self._lll_matrix_mappings = {}
        self._lll_inverse = None
        self.is_orthogonal = all([abs(a - 90) < 1e-5 for a in self._angles])
Exemple #6
0
    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])
Exemple #7
0
    def set_matrix(self,matrix):
        '''
        Set the values of the matrix of lattice vectors
        and reset lengths and angles accordingly
        
        Args:
            matrix (list) of length n_dim x n_dim
        
        
        '''        
        m = np.array(matrix, dtype=np.float64).reshape((self.n_dim, self.n_dim))
        lengths = np.sqrt(np.sum(m ** 2, axis=1))
        angles = np.zeros(self.n_dim)
        for i in range(self.n_dim):
            j = (i + 1) % self.n_dim
            k = (i + 2) % self.n_dim
            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
        self._inv_matrix = None
        self._metric_tensor = None
        self._diags = None
        self._lll_matrix_mappings = {}
        self._lll_inverse = None
        self.is_orthogonal = all([abs(a - 90) < 1e-5 for a in self._angles])
Exemple #8
0
    def from_parameters(
        a: float,
        b: float,
        c: float,
        alpha: float,
        beta: float,
        gamma: float,
        vesta: bool = False,
    ):
        """
        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.
            vesta: True if you import Cartesian coordinates from VESTA.

        Returns:
            Lattice with the specified lattice parameters.
        """

        alpha_r = radians(alpha)
        beta_r = radians(beta)
        gamma_r = radians(gamma)

        if vesta:
            cos_alpha = np.cos(alpha_r)
            cos_beta = np.cos(beta_r)
            cos_gamma = np.cos(gamma_r)
            sin_gamma = np.sin(gamma_r)

            c1 = c * cos_beta
            c2 = (c * (cos_alpha - (cos_beta * cos_gamma))) / sin_gamma

            vector_a = [float(a), 0.0, 0.0]
            vector_b = [b * cos_gamma, b * sin_gamma, 0]
            vector_c = [c1, c2, math.sqrt(c ** 2 - c1 ** 2 - c2 ** 2)]

        else:
            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])
Exemple #9
0
    def from_parameters(
        a: float,
        b: float,
        c: float,
        alpha: float,
        beta: float,
        gamma: float,
        vesta: bool = False,
    ):
        """
        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.
            vesta: True if you import Cartesian coordinates from VESTA.

        Returns:
            Lattice with the specified lattice parameters.
        """

        alpha_r = radians(alpha)
        beta_r = radians(beta)
        gamma_r = radians(gamma)

        if vesta:
            cos_alpha = np.cos(alpha_r)
            cos_beta = np.cos(beta_r)
            cos_gamma = np.cos(gamma_r)
            sin_gamma = np.sin(gamma_r)

            c1 = c * cos_beta
            c2 = (c * (cos_alpha - (cos_beta * cos_gamma))) / sin_gamma

            vector_a = [float(a), 0.0, 0.0]
            vector_b = [b * cos_gamma, b * sin_gamma, 0]
            vector_c = [c1, c2, math.sqrt(c**2 - c1**2 - c2**2)]

        else:
            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])
Exemple #10
0
def get_angles(matrix, lengths=None):
    """Returns the angles (alpha, beta, gamma) of the lattice."""
    if lengths is not None:
        lengths = get_lengths(matrix)
    m = matrix
    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]))
    angles = np.arccos(angles) * 180.0 / pi
    return tuple(angles.tolist())  # type: ignore
Exemple #11
0
 def angles(self) -> Tuple[float]:
     """
     Returns the angles (alpha, beta, gamma) of the lattice.
     """
     m = self._matrix
     lengths = self.lengths
     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]))
     angles = np.arccos(angles) * 180.0 / pi
     return tuple(angles.tolist())
Exemple #12
0
 def angles(self) -> Tuple[float]:
     """
     Returns the angles (alpha, beta, gamma) of the lattice.
     """
     m = self._matrix
     lengths = self.lengths
     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]))
     angles = np.arccos(angles) * 180.0 / pi
     return tuple(angles.tolist())
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(acos(abs_cap(v)))
    phi = sum(vals)
    return phi + (3 - len(r)) * pi
Exemple #14
0
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(acos(abs_cap(v)))
    phi = sum(vals)
    return phi + (3 - len(r)) * pi