# sisl.Lattice

class sisl.Lattice(cell, nsc=None, origin=None, boundary_condition: = BoundaryCondition.PERIODIC)

Bases: _Dispatchs

A cell class to retain lattice vectors and a supercell structure

The supercell structure is comprising the primary unit-cell and neighboring unit-cells. The number of supercells is given by the attribute nsc which is a vector with 3 elements, one per lattice vector. It describes how many times the primary unit-cell is extended along the i’th lattice vector. For nsc[i] == 3 the supercell is made up of 3 unit-cells. One behind, the primary unit-cell and one after.

Parameters:
• cell (array_like) – the lattice parameters of the unit cell (the actual cell is returned from tocell.

• nsc (array_like of int) – number of supercells along each lattice vector

• origin ((3,) of float, optional) – the origin of the supercell.

• boundary_condition (int/str or list of int/str (3, 2) or (3, ), optional) – the boundary conditions for each of the cell’s planes. Defaults to periodic boundary condition. See BoundaryCondition for valid enumerations.

Methods

 add(other) Add two supercell lattice vectors to each other add_vacuum(vacuum, axis[, orthogonal_to_plane]) Returns a new object with vacuum along the axis lattice vector angle(axis1, axis2[, rad]) The angle between two of the cell vectors append(other, axis) Appends other Lattice to this grid along axis area(axis1, axis2) Calculate the area spanned by the two axis ax0 and ax1 cell2length(length[, axes]) Calculate cell vectors such that they each have length length center([axes]) Returns center of the Lattice, possibly with respect to axes copy([cell, origin]) A deepcopy of the object equal(other[, tol]) Check whether two lattices are equivalent fit(xyz[, axes, tol]) Fit the supercell to xyz such that the unit-cell becomes periodic in the specified directions is_cartesian([tol]) Checks if cell vectors a,b,c are multiples of the cartesian axis vectors (x, y, z) is_orthogonal([tol]) Returns true if the cell vectors are orthogonal. offset([isc]) Returns the supercell offset of the supercell index parallel(other[, axes]) Returns true if the cell vectors are parallel to other parameters([rad]) Cell parameters of this cell in 3 lengths and 3 angles plane(axis1, axis2[, origin]) Query point and plane-normal for the plane spanning ax1 and ax2 prepend(other, axis) Prepends other Lattice to this grid along axis read(sile, *args, **kwargs) Reads the supercell from the Sile using Sile.read_lattice repeat(reps, axis) Extend the unit-cell reps times along the axis lattice vector rotate(angle, v[, rad, what]) Rotates the supercell, in-place by the angle around the vector sc_index(sc_off) Returns the integer index in the sc_off list that corresponds to sc_off scale(scale[, what]) Scale lattice vectors set_boundary_condition([boundary, a, b, c]) Set the boundary conditions on the grid set_nsc([nsc, a, b, c]) Sets the number of supercells in the 3 different cell directions swapaxes(axes1, axes2[, what]) Swaps axes axes1 and axes2 tile(reps, axis) Extend the unit-cell reps times along the axis lattice vector toCuboid(*args, **kwargs) A cuboid with vectors as this unit-cell and center with respect to its origin tocell(*args) Returns a 3x3 unit-cell dependent on the input unrepeat(reps, axis) Reverses a Lattice.tile and returns the segmented version untile(reps, axis) Reverses a Lattice.tile and returns the segmented version Vertices of the cell write(sile, *args, **kwargs) Writes latticey to the sile using sile.write_lattice cell nsc n_s boundary_condition Boundary conditions for each lattice vector (lower/upper) sides (3, 2) icell Returns the reciprocal (inverse) cell for the Lattice. isc_off Internal indexed supercell [ia, ib, ic] == i length Length of each lattice vector new origin Origin for the cell pbc Boolean array to specify whether the boundary conditions are periodic rcell Returns the reciprocal cell for the Lattice with 2*np.pi sc_off Integer supercell offsets to A dispatcher for classes, using __get__ it converts into ObjectDispatcher upon invocation from an object, or a TypeDispatcher when invoked from a class volume Volume of cell
BC

alias of BoundaryCondition

__init__(cell, nsc=None, origin=None, boundary_condition: = BoundaryCondition.PERIODIC)[source]
Parameters:

boundary_condition (BoundaryCondition | int | str | bool | Sequence[BoundaryCondition | int | str | bool])

Add two supercell lattice vectors to each other

Parameters:
• other (Lattice, array_like) – the lattice vectors of the other supercell to add

• lattice (Lattice)

Return type:

Lattice

add_vacuum(vacuum: float, axis: sisl.typing.CellAxis, orthogonal_to_plane: bool = False) [source]

Returns a new object with vacuum along the axis lattice vector

Parameters:
• vacuum (float) – amount of vacuum added, in Ang

• axis (sisl.typing.CellAxis) – the lattice vector to add vacuum along

• orthogonal_to_plane (bool, optional) – whether the lattice vector should be elongated so that it is vacuum longer when projected onto the normal vector of the other two axis.

Return type:

Lattice

angle(axis1: sisl.typing.CellAxis, axis2: sisl.typing.CellAxis, rad: bool = False) [source]

The angle between two of the cell vectors

Parameters:
• axis1 (sisl.typing.CellAxis) – the first cell vector

• axis2 (sisl.typing.CellAxis) – the second cell vector

• rad (bool, optional) – whether the returned value is in radians

Return type:

float

append(other, axis: sisl.typing.CellAxis)

Appends other Lattice to this grid along axis

Parameters:
• lattice (Lattice)

• axis (sisl.typing.CellAxis)

Return type:

Lattice

area(axis1: sisl.typing.CellAxis, axis2: sisl.typing.CellAxis) [source]

Calculate the area spanned by the two axis ax0 and ax1

Parameters:
• axis1 (sisl.typing.CellAxis)

• axis2 (sisl.typing.CellAxis)

Return type:

float

property boundary_condition: ndarray

Boundary conditions for each lattice vector (lower/upper) sides (3, 2)

cell
cell2length(length, axes: sisl.typing.CellAxes = (0, 1, 2)) [source]

Calculate cell vectors such that they each have length length

Parameters:
• length (float or array_like) – length for cell vectors, if an array it corresponds to the individual vectors and it must have length equal to axes

• axes (sisl.typing.CellAxes) – which axes the length variable refers too.

Returns:

cell-vectors with prescribed length, same order as axes

Return type:

ndarray

center(axes: sisl.typing.CellAxes = (0, 1, 2))

Returns center of the Lattice, possibly with respect to axes

Parameters:
• lattice (Lattice)

• axes (sisl.typing.CellAxes)

Return type:

ndarray

copy(cell=None, origin: sisl.typing.Coord | None = None)

A deepcopy of the object

Parameters:
• cell (array_like) – the new cell parameters

• origin (array_like) – the new origin

• lattice (Lattice)

Return type:

Lattice

equal(other, tol: float = 0.0001) bool[source]

Check whether two lattices are equivalent

Parameters:
• other (Lattice) – the other object to check whether the lattice is equivalent

• tol (float, optional) – tolerance value for the cell vectors and origin

Return type:

bool

fit(xyz, axes: sisl.typing.CellAxes = (0, 1, 2), tol: float = 0.05) [source]

Fit the supercell to xyz such that the unit-cell becomes periodic in the specified directions

The fitted supercell tries to determine the unit-cell parameters by solving a set of linear equations corresponding to the current supercell vectors.

>>> numpy.linalg.solve(self.cell.T, xyz.T)


It is important to know that this routine will only work if at least some of the atoms are integer offsets of the lattice vectors. I.e. the resulting fit will depend on the translation of the coordinates.

Parameters:
• xyz (array_like shape(*, 3)) – the coordinates that we will wish to encompass and analyze.

• axes (sisl.typing.CellAxes) – only the cell-vectors along the provided axes will be used

• tol (float) – tolerance (in Angstrom) of the positions. I.e. we neglect coordinates which are not within the radius of this magnitude

Return type:

Lattice

property icell: ndarray

Returns the reciprocal (inverse) cell for the Lattice.

Note: The returned vectors are still in [0, :] format and not as returned by an inverse LAPACK algorithm.

is_cartesian(tol: float = 0.001) bool[source]

Checks if cell vectors a,b,c are multiples of the cartesian axis vectors (x, y, z)

Parameters:

tol (float, optional) – the threshold above which an off diagonal term will be considered non-zero.

Return type:

bool

is_orthogonal(tol: float = 0.001) bool[source]

Returns true if the cell vectors are orthogonal.

Parameters:

tol (float, optional) – the threshold above which the scalar product of two cell vectors will be considered non-zero.

Return type:

bool

property isc_off: ndarray

Internal indexed supercell [ia, ib, ic] == i

property length: ndarray

Length of each lattice vector

n_s
new = <TypeDispatcher{obj=<class 'sisl.Lattice'>}>
nsc
offset(isc=None) [source]

Returns the supercell offset of the supercell index

Return type:
property origin: ndarray

Origin for the cell

parallel(other, axes: sisl.typing.CellAxes = (0, 1, 2)) bool[source]

Returns true if the cell vectors are parallel to other

Parameters:
• other (Lattice) – the other object to check whether the axis are parallel

• axes (sisl.typing.CellAxes) – only check the specified axes (default to all)

Return type:

bool

Cell parameters of this cell in 3 lengths and 3 angles

Notes

Since we return the length and angles between vectors it may not be possible to recreate the same cell. Only in the case where the first lattice vector only has a Cartesian $$x$$ component will this be the case.

Parameters:

rad (bool, optional) – whether the angles are returned in radians (otherwise in degree)

Returns:

• float – length of first lattice vector

• float – length of second lattice vector

• float – length of third lattice vector

• float – angle between b and c vectors

• float – angle between a and c vectors

• float – angle between a and b vectors

Return type:
property pbc: ndarray

Boolean array to specify whether the boundary conditions are periodic

plane(axis1: sisl.typing.CellAxis, axis2: sisl.typing.CellAxis, origin: bool = True) [source]

Query point and plane-normal for the plane spanning ax1 and ax2

Parameters:
• axis1 (sisl.typing.CellAxis) – the first axis vector

• axis2 (sisl.typing.CellAxis) – the second axis vector

• origin (bool, optional) – whether the plane intersects the origin or the opposite corner of the unit-cell.

Returns:

• normal_V (numpy.ndarray) – planes normal vector (pointing outwards with regards to the cell)

• p (numpy.ndarray) – a point on the plane

Return type:

Examples

All 6 faces of the supercell can be retrieved like this:

>>> lattice = Lattice(4)
>>> n1, p1 = lattice.plane(0, 1, True)
>>> n2, p2 = lattice.plane(0, 1, False)
>>> n3, p3 = lattice.plane(0, 2, True)
>>> n4, p4 = lattice.plane(0, 2, False)
>>> n5, p5 = lattice.plane(1, 2, True)
>>> n6, p6 = lattice.plane(1, 2, False)


However, for performance critical calculations it may be advantageous to do this:

>>> lattice = Lattice(4)
>>> uc = lattice.cell.sum(0)
>>> n1, p1 = lattice.plane(0, 1)
>>> n2 = -n1
>>> p2 = p1 + uc
>>> n3, p3 = lattice.plane(0, 2)
>>> n4 = -n3
>>> p4 = p3 + uc
>>> n5, p5 = lattice.plane(1, 2)
>>> n6 = -n5
>>> p6 = p5 + uc


Secondly, the variables p1, p3 and p5 are always [0, 0, 0] and p2, p4 and p6 are always uc. Hence this may be used to further reduce certain computations.

prepend(other, axis: sisl.typing.CellAxis)

Prepends other Lattice to this grid along axis

For a Lattice object this is equivalent to append.

Parameters:
• lattice (Lattice)

• axis (sisl.typing.CellAxis)

Return type:

Lattice

property rcell: ndarray

Returns the reciprocal cell for the Lattice with 2*np.pi

Note: The returned vectors are still in [0, :] format and not as returned by an inverse LAPACK algorithm.

Reads the supercell from the Sile using Sile.read_lattice

Parameters:

sile (Sile, str or Path) – a Sile object which will be used to read the supercell if it is a string it will create a new sile using sisl.io.get_sile.

Return type:

Lattice

repeat(reps: int, axis: sisl.typing.CellAxis)

Extend the unit-cell reps times along the axis lattice vector

Notes

This is exactly equivalent to the tile routine.

Parameters:
• reps (int) – number of times the unit-cell is repeated along the specified lattice vector

• axis (sisl.typing.CellAxis) – the lattice vector along which the repetition is performed

• lattice (Lattice)

Return type:

Lattice

rotate(angle: float, v: str | int | Coord, rad: bool = False, what: Literal['abc', 'a', ...] = 'abc')

Rotates the supercell, in-place by the angle around the vector

One can control which cell vectors are rotated by designating them individually with only='[abc]'.

Parameters:
• angle (float) – the angle of which the geometry should be rotated

• v (Union[str, int, Coord]) – the vector around the rotation is going to happen [1, 0, 0] will rotate in the yz plane

• rad (bool) – Whether the angle is in radians (True) or in degrees (False)

• what (Literal['abc', 'a', ...]) – only rotate the designated cell vectors.

• lattice (Lattice)

Return type:

Lattice

sc_index(sc_off) [source]

Returns the integer index in the sc_off list that corresponds to sc_off

Returns the index for the supercell in the global offset.

Parameters:

sc_off ((3,) or list of (3,)) – super cell specification. For each axis having value None all supercells along that axis is returned.

Return type:
property sc_off: ndarray

Integer supercell offsets

scale(scale: CoordOrScalar, what: Literal['abc', 'xyz'] = 'abc')

Scale lattice vectors

Does not scale origin.

Parameters:
• scale (CoordOrScalar) – the scale factor for the new lattice vectors.

• what (Literal['abc', 'xyz']) – If three different scale factors are provided, whether each scaling factor is to be applied on the corresponding lattice vector (“abc”) or on the corresponding cartesian coordinate (“xyz”).

• lattice (Lattice)

Return type:

Lattice

set_boundary_condition(boundary: = None, a: = None, b: = None, c: = None)[source]

Set the boundary conditions on the grid

Parameters:
• boundary ((3, 2) or (3, ) or int, optional) – boundary condition for all boundaries (or the same for all)

• a (int or list of int, optional) – boundary condition for the first unit-cell vector direction

• b (int or list of int, optional) – boundary condition for the second unit-cell vector direction

• c (int or list of int, optional) – boundary condition for the third unit-cell vector direction

Raises:

ValueError – if specifying periodic one one boundary, so must the opposite side.

set_nsc(nsc=None, a: = None, b: = None, c: = None) None[source]

Sets the number of supercells in the 3 different cell directions

Parameters:
• nsc (list of int, optional) – number of supercells in each direction

• a (int, optional) – number of supercells in the first unit-cell vector direction

• b (int, optional) – number of supercells in the second unit-cell vector direction

• c (int, optional) – number of supercells in the third unit-cell vector direction

Return type:

None

swapaxes(axes1: AnyAxes, axes2: AnyAxes, what: Literal['abc', 'xyz', 'abc+xyz'] = 'abc')

Swaps axes axes1 and axes2

Swapaxes is a versatile method for changing the order of axes elements, either lattice vector order, or Cartesian coordinate orders.

Parameters:
• axes1 (AnyAxes) – the old axis indices (or labels if str) A string will translate each character as a specific axis index. Lattice vectors are denoted by abc while the Cartesian coordinates are denote by xyz. If str, then what is not used.

• axes2 (AnyAxes) – the new axis indices, same as axes1

• what (Literal['abc', 'xyz', 'abc+xyz']) – which elements to swap, lattice vectors (abc), or Cartesian coordinates (xyz), or both. This argument is only used if the axes arguments are ints.

• lattice (Lattice)

Return type:

Lattice

Examples

Swap the first two axes

>>> sc_ba = sc.swapaxes(0, 1)
>>> assert np.allclose(sc_ba.cell[(1, 0, 2)], sc.cell)


Swap the Cartesian coordinates of the lattice vectors

>>> sc_yx = sc.swapaxes(0, 1, what="xyz")
>>> assert np.allclose(sc_ba.cell[:, (1, 0, 2)], sc.cell)


Consecutive swapping: 1. abc -> bac 2. bac -> bca

>>> sc_bca = sc.swapaxes("ab", "bc")
>>> assert np.allclose(sc_ba.cell[:, (1, 0, 2)], sc.cell)

tile(reps: int, axis: sisl.typing.CellAxis)

Extend the unit-cell reps times along the axis lattice vector

Notes

This is exactly equivalent to the repeat routine.

Parameters:
• reps (int) – number of times the unit-cell is repeated along the specified lattice vector

• axis (sisl.typing.CellAxis) – the lattice vector along which the repetition is performed

• lattice (Lattice)

Return type:

Lattice

to

A dispatcher for classes, using __get__ it converts into ObjectDispatcher upon invocation from an object, or a TypeDispatcher when invoked from a class

This is a class-placeholder allowing a dispatcher to be a class attribute and converted into an ObjectDispatcher when invoked from an object.

If it is called on the class, it will return a TypeDispatcher.

This class should be an attribute of a class. It heavily relies on the __get__ special method.

Parameters:
• name (str) – name of the attribute in the class

• dispatchs (dict, optional) – dictionary of dispatch methods

• obj_getattr (callable, optional) – method with 2 arguments, an obj and the attr which may be used to control how the attribute is called.

• instance_dispatcher (AbstractDispatcher, optional) – control how instance dispatchers are handled through __get__ method. This controls the dispatcher used if called from an instance.

• type_dispatcher (AbstractDispatcher, optional) – control how class dispatchers are handled through __get__ method. This controls the dispatcher used if called from a class.

Examples

>>> class A:
...   new = ClassDispatcher("new", obj_getattr=lambda obj, attr: getattr(obj.sub, attr))


The above defers any attributes to the contained A.sub attribute.

toCuboid(*args, **kwargs)[source]

A cuboid with vectors as this unit-cell and center with respect to its origin

Parameters:

orthogonal (bool, optional) – if true the cuboid has orthogonal sides such that the entire cell is contained

classmethod tocell(*args) [source]

Returns a 3x3 unit-cell dependent on the input

1 argument

a unit-cell along Cartesian coordinates with side-length equal to the argument.

3 arguments

the diagonal components of a Cartesian unit-cell

6 arguments

the cell parameters given by $$a$$, $$b$$, $$c$$, $$\alpha$$, $$\beta$$ and $$\gamma$$ (angles in degrees).

9 arguments

a 3x3 unit-cell.

Parameters:

*args (float) – May be either, 1, 3, 6 or 9 elements. Note that the arguments will be put into an array and flattened before checking the number of arguments.

Return type:

Lattice

Examples

>>> cell_1_1_1 = Lattice.tocell(1.)
>>> cell_1_2_3 = Lattice.tocell(1., 2., 3.)
>>> cell_1_2_3 = Lattice.tocell([1., 2., 3.]) # same as above

unrepeat(reps: int, axis: sisl.typing.CellAxis)

Reverses a Lattice.tile and returns the segmented version

Notes

Untiling will not correctly re-calculate nsc since it has no knowledge of connections.

Lattice.tile

opposite of this method

Parameters:
• lattice (Lattice)

• reps (int)

• axis (sisl.typing.CellAxis)

Return type:

Lattice

untile(reps: int, axis: sisl.typing.CellAxis)

Reverses a Lattice.tile and returns the segmented version

Notes

Untiling will not correctly re-calculate nsc since it has no knowledge of connections.

Lattice.tile

opposite of this method

Parameters:
• lattice (Lattice)

• reps (int)

• axis (sisl.typing.CellAxis)

Return type:

Lattice

vertices() [source]

Vertices of the cell

Returns:

The coordinates of the vertices of the cell. The first three dimensions correspond to each cell axis (off, on), and the last one contains the xyz coordinates.

Return type:

array of shape (2, 2, 2, 3)

property volume: float

Volume of cell

write(sile: sisl.typing.SileLike, *args, **kwargs) None

Writes latticey to the sile using sile.write_lattice

Parameters:
• sile (sisl.typing.SileLike) – a Sile object which will be used to write the lattice if it is a string it will create a new sile using get_sile

• *args – Any other args will be passed directly to the underlying routine

• **kwargs – Any other args will be passed directly to the underlying routine

• lattice (Lattice)

Return type:

None

Lattice.read
reads a Lattice from a given Sile/file