Utilities¶
utils
¶
Utilities for brille
These functions help to construct lattices and grids for brillouin zone interpolation.
.. code-block:: python
import numpy as np from brille.utils import create_bz, create_grid
def dispersion(q): energies = np.sum(np.cos(np.pi * q), axis=1) eigenvectors = np.sin(np.pi * q) return energies, eigenvectors
bz = create_bz([4.1, 4.1, 4.1], [90, 90, 90], spacegroup='F m -3 m') grid = create_grid(bz, max_size=1e-6) energies, eigenvectors = dispersion(grid.rlu) n_energies = 1 # Only one mode n_eigenvectors = 3 # Three values per q rotateslike = 0 # See note below grid.fill(energies, [n_energies, 0, 0, rotateslike], eigenvectors, [n_eigenvectors, 0, 0, rotateslike])
interp_en, interp_ev = grid.ir_interpolate_at(np.random.rand(1000, 3))
Note
The rotateslike enumeration is given in fill
and describes how the eigenvalues / eigenvectors should be treated on application of a
symmetry operation. The gamma option (rotateslike=3) should be used for
phonon eigenvectors.
.. currentmodule:: brille.utils
.. autosummary:: :toctree: _generate
Functions:
-
create_bz–Construct a BrillouinZone object.
-
create_grid–Constructs an interpolation grid for a given BrillouinZone object
-
conventional_to_primitive–Convert eigen-solutions of a centred conventional cell to its primitive cell
create_bz
¶
create_bz(*args, is_reciprocal=False, use_primitive=True, search_length=1, time_reversal_symmetry=False, wedge_search=True, snap_to_symmetry=True, **kwargs)
Construct a BrillouinZone object.
Parameters:
-
*args–The lattice and its space group, in one of three forms (see the note below):
a, b, c, alpha, beta, gamma, spacegroup;lens, angs, spacegroup; orlattice_vectors, spacegroup. -
is_reciprocal(bool, keyword-only optional (default: False), default:False) –Whether the lattice parameters or lattice vectors refers to a reciprocal rather than direct lattice. If True, a/b/c/lens should be in reciprocal Angstrom, otherwise they should be in Angstrom
-
use_primitive(bool, keyword-only optional (default: True), default:True) –Whether the primitive (or conventional) lattice should be used
-
search_length(int, keyword-only optional (default: 1), default:1) –An integer to control how-far the vertex-finding algorithm should search in τ-index. The default indicates that (1̄1̄1̄), (1̄1̄0), (1̄1̄1), (1̄0̄1), ..., (111) are included.
-
time_reversal_symmetry(bool, keyword-only optional (default: False), default:False) –Whether to include time-reversal symmetry as an operation to determine the irreducible Brillouin zone
-
wedge_search(bool, keyword-only optional (default: True), default:True) –If true, return an irreducible first Brillouin zone, otherwise just return the first Brillouin zone
-
snap_to_symmetry–Enforces that provided lattice parameters / basis vectors / atom-basis positions conform to the provided symmetry operations, if present.
Other Parameters:
-
a(float) –Lattice parameters as separate floating point values
-
b(float) –Lattice parameters as separate floating point values
-
c(float) –Lattice parameters as separate floating point values
-
lens((3,) [`numpy.ndarray`][numpy.ndarray] or list) –Lattice parameters as a 3-element array or list
-
alpha(float) –Lattice angles in degrees or radians as separate floating point values. Brille tries to determine if the input is in degrees or radians by looking at its magnitude. If the values are all less than PI it assumes the angles are in radians otherwise it assumes degrees
-
beta(float) –Lattice angles in degrees or radians as separate floating point values. Brille tries to determine if the input is in degrees or radians by looking at its magnitude. If the values are all less than PI it assumes the angles are in radians otherwise it assumes degrees
-
gamma(float) –Lattice angles in degrees or radians as separate floating point values. Brille tries to determine if the input is in degrees or radians by looking at its magnitude. If the values are all less than PI it assumes the angles are in radians otherwise it assumes degrees
-
angs((3,) [`numpy.ndarray`][numpy.ndarray] or list) –Lattice angles in degrees or radians as a 3-element array or list
-
lattice_vectors((3, 3) [`numpy.ndarray`][numpy.ndarray] or list of list) –The lattice vectors as a 3x3 matrix, array or list of list
-
spacegroup(str) –The spacegroup in either International Tables (Hermann-Mauguin) notation or a Hall symbol.
Note
The lattice may be given by keyword instead, with the names above; it
must be given in one of these forms:
- EITHER create_bz(a, b, c, alpha, beta, gamma, spacegroup, ...)
- OR create_bz(lens, angs, spacegroup, ...)
- OR create_bz(lattice_vectors, spacegroup, ...)
E.g. you cannot mix specifing a, b, c, and angs etc.
create_grid
¶
create_grid(bz, complex_values=False, complex_vectors=False, mesh=False, nest=False, trellis=False, **kwargs)
Constructs an interpolation grid for a given BrillouinZone object
Brille provides three different grid implementations: - BZMeshQ: A structured tetrahedral mesh, clipped exactly to the zone and refinable. [Default] - BZTrellisQ: A hybrid Cartesian and tetrahedral grid, with tetrahedral nodes on the BZ surface and cuboids inside. - BZNestQ: A fully tetrahedral grid with a nested tree data structure.
By default, a BZMeshQ grid is made, unless a BZTrellisQ's keyword
arguments are given (as before brille 0.9, when the trellis was the
default). Without a size, the mesh has max_size = 1e-5 / 6, which gives
about as many vertices as the trellis's default node_volume_fraction =
1e-5.
Parameters:
-
bz(`BrillouinZone`) –A BrillouinZone object (required)
-
complex_values(bool, optional (default: False), default:False) –Whether the interpolated scalar quantities are complex
-
complex_vectors(bool, optional (default: False), default:False) –Whether the interpolated vector quantities are complex
-
mesh(bool, optional (default: False), default:False) –Whether to construct a BZMeshQ; it is the default anyway
-
nest(bool, optional (default: False), default:False) –Whether to construct a BZNestQ
-
trellis(bool, optional (default: False), default:False) –Whether to construct a BZTrellisQ; it is also made when its keyword arguments are given
Other Parameters:
-
node_volume_fraction(float, optional (default: 1e-5)) –For
BZTrellisQ. Despite its name, a volume in cubic reciprocal Angstrom, not a fraction: the volume of one cubic node of the trellis, which sets its spacing. For a given value, a zone twice the size (in each direction) gets eight times the nodes. Smaller numbers give better interpolation accuracy at the cost of greater computation time. To size the grid by its number of points, usebz.ir_polyhedron.volume / points, which gives roughly 1.3 to 2 timespointsvertices. -
always_triangulate(bool, optional (default: False)) –For
BZTrellisQ. If True, every node is divided into tetrahedra; otherwise only the nodes the zone boundary cuts are, and the others stay cubes. -
max_size(float, optional (default: -1.0)) –For
BZMeshQ. The maximum volume of a grid tetrahedron in cubic reciprocal Angstrom, which sets the grid spacing. If not positive, the grid is the reciprocal lattice itself, clipped to the zone. Each cell of the grid holds six tetrahedra, so a mesh withmax_size = node_volume_fraction / 6has about as many vertices as a trellis withnode_volume_fraction(up to 1.5 times as many for small grids); andbz.ir_polyhedron.volume / (6 * points)gives roughly 1.5 to 3 timespointsvertices, the most for small grids. -
num_levels(int, optional (default: 3)) –For
BZMeshQ. Unused; kept for compatibility. -
max_points(int, optional (default: -1)) –For
BZMeshQ. If positive, the grid is coarsened until its estimated number of vertices is at most this. -
max_volume(float) –For
BZNestQ. Maximum volume of a tetrahedron in cubic reciprocal Angstrom. -
number_density(float) –For
BZNestQ. Number density of points in reciprocal space. -
max_branchings(int, optional (default: 5)) –For
BZNestQ. Maximum number of branchings in the tree structure.
Note
Setting more than one of mesh, nest and trellis gives an error. Each
grid's keyword arguments are refused for the other grids, and a BZNestQ
needs nest=True and one of max_volume or number_density.
conventional_to_primitive
¶
conventional_to_primitive(lattice, q, values, vectors, tolerance=1e-08)
Convert eigen-solutions of a centred conventional cell to its primitive cell
A grid's eigenvectors describe the atoms of one primitive cell,
primitive_basis, or every atom of the
conventional cell; convert them to interpolate the primitive cell's modes
only. A code given a centred
conventional cell instead returns, at each q, all of its modes: the primitive
cell's modes at q folded together with those at the other wavevectors the
larger cell cannot tell from q. This picks out the modes at q, and keeps the
atoms of the primitive basis.
Parameters:
-
lattice([`Lattice`][brille._brille.Lattice]) –The conventional lattice, with its full
basisin the order the eigenvectors use. -
q((Q, 3) array) –The points the eigen-solutions are for, in the conventional cell's reciprocal lattice units, as
rlu. -
values((Q, B, ...) array) –The mode values, such as energies, for B = 3 × the conventional cell's atoms modes; modes with equal values (in their first element) are degenerate.
-
vectors((Q, B, n, 3) or (Q, B, 3n) array) –The eigenvectors, one 3-vector for each of the conventional cell's n atoms, in the cell phase convention: periodic in the conventional cell's reciprocal lattice. Their units do not matter.
-
tolerance(float, default:1e-08) –Relative tolerance for degenerate values.
Returns:
-
(values, vectors)–The primitive cell's B / m modes at each q, where m is the number of primitive cells in the conventional cell, in the input's order of values, with vectors for the atoms of the primitive basis only, in the input's layout.
Note
A mode folded from a wavevector p changes by exp(2πi p·d) between an atom and its copy d away; the modes at q are those for which p = q, and their primitive eigenvector for atom k is the sum over its copies of exp(-2πi q·d) times the copy's component, over √m. Degenerate modes can mix the folds, so each degenerate group is projected onto the modes at q as a whole.