kim_tools.symmetry_util package

Submodules

kim_tools.symmetry_util.core module

Crystal Symmetry utilities and data that are (mostly) independent of AFLOW

exception kim_tools.symmetry_util.core.IncorrectCrystallographyException

Bases: Exception

Raised when incorrect data is provided, e.g. nonexistent Bravais lattice etc.

exception kim_tools.symmetry_util.core.IncorrectNumAtomsException

Bases: Exception

Raised when the a disagreement in the number of atoms is found.

exception kim_tools.symmetry_util.core.PeriodExtensionException

Bases: Exception

Raised when a period-extending phase transition is detected.

kim_tools.symmetry_util.core._check_space_group(sgnum)
kim_tools.symmetry_util.core.cartesian_to_fractional_itc_rotation_from_ase_cell(cart_rot, cell)

Convert Cartesian to fractional rotation. Read the arguments and returns carefully, as there is some unfortunate mixing of row and columns because of the different conventions of the ITC and ASE and other simulation packages

Parameters:
  • cart_rot (Union[_Buffer, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[bool | int | float | complex | str | bytes]]) -- Cartesian rotation. It is assumed that this is for left-multiplying column vectors, although in cases where we don't care if we're working with the rotation or its inverse (e.g. when checking whether or not it's in the point group), this doesn't matter due to orthogonality

  • cell (Union[_Buffer, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[bool | int | float | complex | str | bytes]]) -- The cell of the crystal, with each row being a cartesian vector representing a lattice vector. This is consistent with most simulation packages, but transposed from the ITC

Return type:

Union[_Buffer, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[bool | int | float | complex | str | bytes]]

Returns:

The fractional rotation in ITC convention, i.e. for left-multiplying column vectors. Here the distinction with a matrix's transpose DOES matter, because the fractional coordinate system is not orthonormal.

kim_tools.symmetry_util.core.fractional_to_cartesian_itc_rotation_from_ase_cell(frac_rot, cell)

Convert fractional to Cartesian rotation. Read the arguments and returns carefully, as there is some unfortunate mixing of row and columns because of the different conventions of the ITC and ASE and other simulation packages

Parameters:
  • frac_rot (Union[_Buffer, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[bool | int | float | complex | str | bytes]]) -- The fractional rotation in ITC convention, i.e. for left-multiplying column vectors. Here the distinction with a matrix's transpose DOES matter, because the fractional coordinate system is not orthonormal.

  • cell (Union[_Buffer, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[bool | int | float | complex | str | bytes]]) -- The cell of the crystal, with each row being a cartesian vector representing a lattice vector. This is consistent with most simulation packages, but transposed from the ITC

Return type:

Union[_Buffer, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[bool | int | float | complex | str | bytes]]

Returns:

Cartesian rotation. It is assumed that this is for left-multiplying column vectors, although in cases where we don't care if we're working with the rotation or its inverse (e.g. when checking whether or not it's in the point group), this doesn't matter due to orthogonality

kim_tools.symmetry_util.core.cartesian_rotation_is_in_point_group(cart_rot, sgnum, cell, rtol=0.01, atol=0.01)

Check that a Cartesian rotation is in the point group of a crystal given by its space group number and primitive cell

Parameters:
Return type:

bool

kim_tools.symmetry_util.core.get_cell_from_poscar(poscar)

Extract the unit cell from a POSCAR file, including the specified scaling

Return type:

Union[_Buffer, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[bool | int | float | complex | str | bytes]]

kim_tools.symmetry_util.core.are_in_same_wyckoff_set(letter_1, letter_2, sgnum)

Given two Wyckoff letters and a space group number, return whether or not they are in the same Wyckoff set, meaning that their orbits are related by an operation in the normalizer of the space group

kim_tools.symmetry_util.core.space_group_numbers_are_enantiomorphic(sg_1, sg_2)

Return whether or not two spacegroups (specified by number) are enantiomorphs of each other

Return type:

bool

kim_tools.symmetry_util.core.get_wyck_pos_xform_under_normalizer(sgnum)

Get the "Transformed WP" column of the tables at the bottom of the page for each space group from https://cryst.ehu.es/cryst/get_set.html

Return type:

List[List[str]]

kim_tools.symmetry_util.core.get_bravais_lattice_from_space_group(sgnum)

Get the symbol (e.g. 'cF') of one of the 14 Bravais lattices from the space group number

kim_tools.symmetry_util.core.get_formal_bravais_lattice_from_space_group(sgnum)

Same as get_bravais_lattice_from_space_group() except distinguish between "oA" and "oC"

kim_tools.symmetry_util.core.get_primitive_wyckoff_multiplicity(sgnum, wyckoff)

Get the multiplicity of a given Wyckoff letter for a primitive cell of the crystal

Return type:

int

kim_tools.symmetry_util.core.get_symbolic_cell_from_formal_bravais_lattice(formal_bravais_lattice)

Get the symbolic primitive unit cell as defined in http://doi.org/10.1016/j.commatsci.2017.01.017 in terms of the appropriate (possibly trivial) subset of the parameters a, b, c, alpha, beta, gamma

Parameters:

formal_bravais_lattice (str) -- The symbol for the Bravais lattice, e.g "oA". Specifically, "oA" is distinguished from "oC", meaning there are 15 possibilities, not just the 14 Bravais lattices.

Return type:

MutableDenseMatrix

Returns:

Symbolic 3x3 matrix with the rows being cell vectors. This is in agreement with most simulation software, but the transpose of how the ITA defines cell vectors.

Raises:

IncorrectCrystallographyException -- If a nonexistent Bravais lattice is provided

kim_tools.symmetry_util.core.get_change_of_basis_matrix_to_conventional_cell_from_formal_bravais_lattice(formal_bravais_lattice)

Get a change of basis matrix P as defined in ITA 1.5.1.2, with "old basis" being the primitive cell of the provided Bravais lattice, and the "new basis" being the conventional cell, i.e. the cell of the primitive lattice of the same crystal family. E.g. if formal_bravais_lattice="oA", then "old basis" is oA, and "new basis" is oP. The cell choices are defined in http://doi.org/10.1016/j.commatsci.2017.01.017, including distinguishing between oA and oC.

The matrices are given in ITC convention, meaning that they expect to operate on column vectors, i.e. The bases are related by the following, where the primed symbols indicate the new basis:

Relationship between basis vectors: (a', b', c') = (a, b, c) P

Relationship between fractional coordinates in each basis: x = P x'

For operating on row vectors, as is often given in simulation software, make sure to transpose these relationships appropriately.

Parameters:

formal_bravais_lattice (str) -- The symbol for the Bravais lattice, e.g "oA". Specifically, "oA" is distinguished from "oC", meaning there are 15 possibilities, not just the 14 Bravais lattices.

Return type:

Union[_Buffer, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[bool | int | float | complex | str | bytes]]

Returns:

Integral 3x3 matrix representing the change of basis

Raises:

IncorrectCrystallographyException -- If a nonexistent Bravais lattice is provided

kim_tools.symmetry_util.core.change_of_basis_atoms(atoms, change_of_basis, cutoff=None)

Perform an arbitrary basis change on an Atoms object, duplicating or cropping atoms as needed. A basic check is made that the determinant of change_of_basis is compatible with the number of atoms, but this is far from fully determining that change_of_basis is appropriate for the particuar crystal described by atoms, which is up to the user.

TODO: Incorporate period extension test into this function

Parameters:
  • atoms (Atoms) -- The object to transform

  • change_of_basis (Union[_Buffer, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[bool | int | float | complex | str | bytes]]) --

    A change of basis matrix P as defined in ITA 1.5.1.2, with atoms corresponding to the "old basis" and the returned Atoms object being in the "new basis".

    This matrix should be given in ITC convention, meaning that it expects to operate on column vectors, i.e. The bases are related by the following, where the primed symbols indicate the new basis:

    Relationship between basis vectors: (a', b', c') = (a, b, c) P

    Relationship between fractional coordinates in each basis: x = P x'

  • cutoff (Optional[float]) -- The cutoff to use for deleting duplicate atoms. If not specified, the AFLOW tolerance of 0.01*(smallest NN distance) is used.

Return type:

Atoms

Returns:

The transformed Atoms object, containing the original number of atoms mutiplied by the determinant of the change of basis.

kim_tools.symmetry_util.core.get_possible_primitive_shifts(sgnum)

Get all unique translation parts of operations in the space group's normalizer that don't leave the primitive cell. Given in the primitive basis as defined in http://doi.org/10.1016/j.commatsci.2017.01.017

Parameters:

sgnum (Union[int, str]) -- space group number

Return type:

List[List[float]]

kim_tools.symmetry_util.core.get_primitive_genpos_ops(sgnum)

Get the matrices and columns of the space group operations in the primitive setting as defined in http://doi.org/10.1016/j.commatsci.2017.01.017

Parameters:

sgnum (Union[int, str]) -- space group number

Return type:

List[Dict]

Returns:

List of dictionaries, with each dictionary containing a matrix 'W' and translation 'w' as generally defined in the ITA, but in the primitive setting.

kim_tools.symmetry_util.core.transform_atoms(atoms, op)

Transform atoms by an operation defined by a dictionary containing a matrix 'W' and translation 'w' defined as fractional operations in the unit cell. 'W' should be oriented to operate on column vectors

Return type:

Atoms

kim_tools.symmetry_util.core.reduce_and_avg(atoms, repeat)

TODO: Upgrade change_of_basis_atoms() to provide the distances array, obviating this function

Function to reduce all atoms to the original unit cell position, assuming the supercell is built from contiguous repeats of the unit cell (i.e. atoms 0 to N-1 in the supercell are the original unit cell, atoms N to 2*[N-1] are the original unit cell shifted by an integer multiple of the lattice vectors, and so on)

Parameters:
  • atoms (Atoms) -- The supercell to reduce

  • repeat (Tuple[int, int, int]) -- The number of repeats of each unit cell vector in the provided supercell

Return type:

Atoms

Returns:

The reduced unit cell

Raises:

PeriodExtensionException -- If two atoms that should be identical by translational symmetry are further than 0.01*(smallest NN distance) apart when reduced to the unit cell

kim_tools.symmetry_util.core.voigt_to_full_symb(voigt_input)

Convert a 3-dimensional symbolic Voigt matrix to a full tensor. Order is automatically detected. For now, only works with tensors that don't have special scaling for the Voigt matrix (e.g. this doesn't work with the compliance tensor)

Return type:

MutableDenseNDimArray

kim_tools.symmetry_util.core.full_to_voigt_symb(full)

Convert a 3-dimensional symbolic full tensor to a Voigt matrix. Order is automatically detected. For now, only works with tensors that don't have special scaling for the Voigt matrix (e.g. this doesn't work with the compliance tensor). No error checking is done to see if the full tensor has the required symmetries to be converted to Voigt.

Return type:

MutableDenseNDimArray

kim_tools.symmetry_util.core.rotate_tensor_symb(t, r)

Rotate a 3-dimensional symbolic Cartesian tensor by a rotation matrix.

Parameters:
  • t (ImmutableDenseNDimArray) -- The tensor to rotate

  • r (ImmutableDenseNDimArray) -- The rotation matrix, or a precomputed tensor product of rotation matrices with the correct rank

Return type:

ImmutableDenseNDimArray

kim_tools.symmetry_util.core.fit_voigt_tensor_to_cell_and_space_group_symb(symb_voigt_inp, cell, sgnum)

Given a Cartesian symbolic tensor in Voigt form, average it over all the operations in the crystal's space group in order to remove violations of the material symmetry due to numerical errors. Similar to pymatgen.core.tensors.Tensor.fit_to_structure(), except the input in output are Voigt, and the symmetry operations are tabulated instead of being detected on the fly from a structure.

The provided tensor and cell must be in the standard primitive setting and orientation w.r.t. Cartesian coordinates as defined in https://doi.org/10.1016/j.commatsci.2017.01.017

Parameters:
Returns:

Tensor symmetrized w.r.t. operations of the space group, additionally the symmetrized error if voigt_error is provided

kim_tools.symmetry_util.core.fit_voigt_tensor_and_error_to_cell_and_space_group(voigt_input, voigt_error, cell, sgnum, symmetric=False)

Given a Cartesian Tensor and its errors in Voigt form, average them over all the operations in the crystal's space group in order to remove violations of the material symmetry due to numerical errors. Similar to pymatgen.core.tensors.Tensor.fit_to_structure(), except the input in output are Voigt, and the symmetry operations are tabulated instead of being detected on the fly from a structure.

Only use this function if you need the errors. If you do not, use fit_voigt_tensor_to_cell_and_space_group(), which is significantly faster.

The provided tensor and cell must be in the standard primitive setting and orientation w.r.t. Cartesian coordinates as defined in https://doi.org/10.1016/j.commatsci.2017.01.017

Parameters:
Return type:

Tuple[Union[_Buffer, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[bool | int | float | complex | str | bytes]], Union[_Buffer, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[bool | int | float | complex | str | bytes]]]

Returns:

Tensor symmetrized w.r.t. operations of the space group, and its symmetrized error

kim_tools.symmetry_util.core.fit_voigt_tensor_to_cell_and_space_group(voigt_input, cell, sgnum)

Given a Cartesian Tensor in voigt form, average it over all the operations in the crystal's space group in order to remove violations of the material symmetry due to numerical errors. Similar to pymatgen.core.tensors.Tensor.fit_to_structure(), except the input in output are Voigt, and the symmetry operations are tabulated instead of being detected on the fly from a structure.

If you need to symmetrize the errors as well, use fit_voigt_tensor_and_error_to_cell_and_space_group(), which properly handles errors, but is much slower.

The provided tensor and cell must be in the standard primitive setting and orientation w.r.t. Cartesian coordinates as defined in https://doi.org/10.1016/j.commatsci.2017.01.017

Parameters:
Return type:

Union[_Buffer, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[bool | int | float | complex | str | bytes]]

Returns:

Tensor symmetrized w.r.t. operations of the space group

kim_tools.symmetry_util.core.get_smallest_nn_dist(atoms)

Get the smallest NN distance in an Atoms object

Return type:

float

class kim_tools.symmetry_util.core.FixProvidedSymmetry(atoms, symmetry, adjust_positions=True, adjust_cell=True)

Bases: FixSymmetry

A modification of FixSymmetry that takes a prescribed symmetry instead of analyzing the atoms object on the fly

Parameters:

symmetry (Union[str, int, List[Dict]]) -- Either the space group number, or a list of operations as dictionaries with keys "W": (fractional rotation matrix), "w": (fractional translation). The space group number input will not work correctly unless this contraint is applied to a primitive unit cell as defined in http://doi.org/10.1016/j.commatsci.2017.01.017

prep_symm_map()

Prepare self.symm_map using provided symmetries

Return type:

None

todict()

kim_tools.symmetry_util.elasticity module

kim_tools.symmetry_util.elasticity.voigt_elast_class(sgnum)

Get the name of the class of the structure of the elasticity tensor, out of the following possibilities: "cubic", "hexagonal", "trigonal_3bar_m_2nd_pos", "trigonal_3bar_m_3rd_pos", "trigonal_3bar", "tetragonal_class_4_slash_mmm", "tetragonal_class_4_slash_m", "orthorhombic", "monoclinic", "triclinic". The names that don't correspond to a crystal system are taken from https://dictionary.iucr.org/Laue_class

Note that this is a novel classification as far as the authors are aware. Most crystallography texts on the subject will show 9 classes. This function returns 10 possibilities, because the structure of the components of the elasticity tensor for Laue class -3m depends on whether the twofold axis is aligned along the Cartesian x or y axis. Assuming one adopts a standard orientation of the hexagonal unit cell w.r.t. the Cartesian coordinate system, as we do, different space groups in this Laue class have different forms.

See https://doi.org/10.1017/CBO9781139017657.008 pg 232 for a review of the subject.

Return type:

str

kim_tools.symmetry_util.elasticity.voigt_elast_compon_eqn(sgnum)

Get the algebraic equations describing the symmetry restrictions on the elasticity matrix in Voigt form given a space group number. The unit cell must be in the orientation defined in doi.org/10.1016/j.commatsci.2017.01.017 for these equations to be correct.

Return type:

Dict

Returns:

Encoding of symmetry restrictions on elasticity matrices. The keys are the Voigt indices of non-independent components. The values are a pair of lists representing the linear combination of the unique compoonents that is used to determine the non-unique component specified in the key. The first list is the coefficients, the second is the indices. If a non-independent component is zero, this is indicated by a value of None. Any components not listed as a key are assumed to be independent. Only the upper triangle (i<j) is listed. Indices are one-based.

kim_tools.symmetry_util.elasticity.voigt_elast_struct_svg(sgnum, dest_filename)

Write a copy of the image showing the structure of the Voigt elasticity matrix for the specified space group

Return type:

None

kim_tools.symmetry_util.elasticity.indep_elast_compon_names_and_values_from_voigt(voigt, sgnum)

From an elasticity matrix in Voigt order and a space group number, extract the elastic constants that should be unique (cij where first i is as low as possible, then j)

Return type:

Tuple[List[str], List[float]]

kim_tools.symmetry_util.elasticity.calc_bulk(elastic_constants)

Compute the bulk modulus given the elastic constants matrix in Voigt ordering.

Parameters:

elastic_constants -- float A 6x6 numpy array containing the elastic constants in Voigt ordering. The material can have arbitrary anisotropy.

Returns:

float

The bulk modulus, defined as the ratio between the hydrostatic stress (negative of the pressure p) in hydrostatic loading and the diltation e (trace of the strain tensor), i.e. B = -p/e

Return type:

bulk

kim_tools.symmetry_util.elasticity.map_to_Kelvin(C)

Compute the Kelvin form of the input 6x6 Voigt matrix

Return type:

Union[_Buffer, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[bool | int | float | complex | str | bytes]]

kim_tools.symmetry_util.elasticity.function_of_matrix(A, f)

Compute the function of a matrix

kim_tools.symmetry_util.elasticity.find_nearest_isotropy(elastic_constants)

Compute the distance between the provided matrix of elastic constants in Voigt notation, to the nearest matrix of elastic constants for an isotropic material. Return this distance, and the isotropic bulk and shear modulus.

Ref: Morin, L; Gilormini, P and Derrien, K,

"Generalized Euclidean Distances for Elasticity Tensors", Journal of Elasticity, Vol 138, pp. 221-232 (2020).

Parameters:

elastic_constants -- float A 6x6 numpy array containing the elastic constants in Voigt ordering. The material can have arbitrary anisotropy.

Returns:

float

Distance to the nearest elastic constants. log Euclidean metric.

kappafloat

Isotropic bulk modulus

mufloat

Isotropic shear modulus

Return type:

d

Module contents