Source code for radtools.crystal.cell

# RAD-tools - Sandbox (mainly condense matter plotting).
# Copyright (C) 2022-2024  Andrey Rybakov
#
# e-mail: anry@uv.es, web: rad-tools.org
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

from math import cos, pi, sin, sqrt

import numpy as np

from radtools.constants import TORADIANS
from radtools.geometry import angle, parallelepiped_check, volume

__all__ = [
    "reciprocal",
    "from_params",
    "params",
    "primitive",
]


[docs] def reciprocal(cell): r""" Computes reciprocal cell. .. versionadded:: 0.7 Parameters ---------- cell : (3, 3) |array_like|_ Cell matrix, rows are interpreted as vectors. Returns ------- reciprocal_cell : (3, 3) :numpy:`ndarray` Reciprocal cell matrix, rows are interpreted as vectors. :math:`cell = (\vec{v}_1, \vec{v}_2, \vec{v}_3)`, where .. math:: \begin{matrix} \vec{b}_1 = \dfrac{2\pi}{V}\vec{a}_2\times\vec{a}_3 \\ \vec{b}_2 = \dfrac{2\pi}{V}\vec{a}_3\times\vec{a}_1 \\ \vec{b}_3 = \dfrac{2\pi}{V}\vec{a}_1\times\vec{a}_2 \\ \end{matrix} """ vol = volume(cell) reciprocal_cell = np.array( [ 2 * pi / vol * np.cross(cell[1], cell[2]), 2 * pi / vol * np.cross(cell[2], cell[0]), 2 * pi / vol * np.cross(cell[0], cell[1]), ] ) return reciprocal_cell
[docs] def from_params(a=1.0, b=1.0, c=1.0, alpha=90.0, beta=90.0, gamma=90.0): r""" Return cell from lattice parameters. .. versionadded:: 0.7 Parameters ---------- a : float, default 1 Length of the :math:`a_1` vector. b : float, default 1 Length of the :math:`a_2` vector. c : float, default 1 Length of the :math:`a_3` vector. alpha : float, default 90 Angle between vectors :math:`a_2` and :math:`a_3`. In degrees. beta : float, default 90 Angle between vectors :math:`a_1` and :math:`a_3`. In degrees. gamma : float, default 90 Angle between vectors :math:`a_1` and :math:`a_2`. In degrees. Returns ------- cell : (3, 3) :numpy:`ndarray` Cell matrix. .. code-block:: python cell = [[a1_x, a1_y, a1_z], [a2_x, a2_y, a2_z], [a3_x, a3_y, a3_z]] Raises ------ ValueError If parameters could not form a parallelepiped. See Also -------- parallelepiped_check : Check if parameters could form a parallelepiped. """ parallelepiped_check(a, b, c, alpha, beta, gamma, raise_error=True) alpha = alpha * TORADIANS beta = beta * TORADIANS gamma = gamma * TORADIANS return np.array( [ [a, 0, 0], [b * cos(gamma), b * sin(gamma), 0], [ c * cos(beta), c / sin(gamma) * (cos(alpha) - cos(beta) * cos(gamma)), c / sin(gamma) * sqrt( 1 + 2 * cos(alpha) * cos(beta) * cos(gamma) - cos(alpha) ** 2 - cos(beta) ** 2 - cos(gamma) ** 2 ), ], ], dtype=float, )
[docs] def params(cell): r""" Return lattice parameters from cell. .. versionadded:: 0.7 Parameters ---------- cell : (3,3) |array_like|_ Cell matrix, rows are interpreted as vectors. .. code-block:: python cell = [[a1_x, a1_y, a1_z], [a2_x, a2_y, a2_z], [a3_x, a3_y, a3_z]] Returns ------- a : float Length of the :math:`a_1` vector. b : float Length of the :math:`a_2` vector. c : float Length of the :math:`a_3` vector. alpha : float Angle between vectors :math:`a_2` and :math:`a_3`. In degrees. beta : float Angle between vectors :math:`a_1` and :math:`a_3`. In degrees. gamma : float Angle between vectors :math:`a_1` and :math:`a_2`. In degrees. """ return ( np.linalg.norm(cell[0]), np.linalg.norm(cell[1]), np.linalg.norm(cell[2]), angle(cell[1], cell[2]), angle(cell[0], cell[2]), angle(cell[0], cell[1]), )
# TODO
[docs] def primitive(cell, atoms): r""" Compute primitive cell. .. versionadded:: ??? Parameters ---------- cell : (3, 3) |array_like|_ Cell matrix, rows are interpreted as vectors. atoms : list of :py:class:`.Atom` Atoms in the cell. ``position`` attribute of the atom is interpreted as relative position in the cell. Returns ------- primitive_cell : (3, 3) :numpy:`ndarray` Primitive cell matrix, rows are interpreted as vectors. primitive_atoms : list of :py:class:`.Atom` Atoms in the primitive cell. ``position`` attribute of the atom is interpreted as relative position in the primitive cell. """ raise NotImplementedError