Skip to content

moirepy.layers.Layer

Base class representing a 2D crystal lattice layer.

Wraps a Rust-backed lattice object that handles the heavy numerical work.

Parameters:

Name Type Description Default
lv1 ndarray

First primitive lattice vector. Must lie along the x-axis, i.e. lv1[1] == 0.

required
lv2 ndarray

Second primitive lattice vector. Must have a positive y-component (lv2[1] > 0).

required
basis_points list of tuple

Atom positions within the unit cell. Each element is a 3-tuple (x, y, type_label) where x and y are fractional or Cartesian coordinates and type_label is a unique string identifier (e.g. "A", "B").

required
neighbours dict

Nearest-neighbour displacement vectors for each atom type. Keys are the type labels from basis_points; values are lists of [dx, dy] displacement vectors that reach the neighbours of that atom type.

required
pbc bool

Whether to apply periodic boundary conditions when computing neighbours. Default is False.

False
study_proximity int

Number of supercell shells to include in the neighbour search. Larger values find neighbours across more unit-cell images. Default is 1.

1

Raises:

Type Description
ValueError

If lv1 is not aligned with the x-axis or lv2 does not have a positive y-component.

LatticeAlreadyFinalisedError

If any of the lattice parameters are attempted to be reassigned after construction.

See Also

SquareLayer, TriangularLayer, HexagonalLayer, KagomeLayer, Rhombus60Layer : Pre-built layer types for common 2D lattices.

Notes

The orientation convention (lv1 along x, lv2 with positive y) is required by the rotation machinery. See https://jabed-umar.github.io/MoirePy/find_theta/ for details.

Examples:

Build a custom honeycomb-like layer from scratch:

>>> import numpy as np
>>> from moirepy import Layer
>>> lv1 = np.array([1.0, 0.0])
>>> lv2 = np.array([0.5, np.sqrt(3) / 2])
>>> basis = [(0, 0, "A"), (1, 1/np.sqrt(3), "B")]
>>> nb = {
...     "A": [[0, 1/np.sqrt(3)], [-0.5, -1/(2*np.sqrt(3))], [0.5, -1/(2*np.sqrt(3))]],
...     "B": [[0.5, 1/(2*np.sqrt(3))], [-0.5, 1/(2*np.sqrt(3))], [0, -1/np.sqrt(3)]],
... }
>>> layer = Layer(lv1, lv2, basis, nb)

basis_points property writable

basis_points

list of tuple: Atom positions (x, y, type_label) within the unit cell.

basis_types property writable

basis_types

list of str: Ordered atom-type labels extracted from basis_points.

bigger_points property writable

bigger_points

np.ndarray or None: Lattice points that extend beyond the primary supercell.

Used internally to resolve periodic images during neighbour search. None until :meth:generate_points has been called.

lv1 property writable

lv1

np.ndarray: First primitive lattice vector [x, 0].

lv2 property writable

lv2

np.ndarray: Second primitive lattice vector with positive y-component.

mln1 property writable

mln1

int: Supercell repetition count along mlv1.

mln2 property writable

mln2

int: Supercell repetition count along mlv2.

mlv1 property writable

mlv1

np.ndarray or None: First moiré supercell vector, set by :meth:generate_points.

mlv2 property writable

mlv2

np.ndarray or None: Second moiré supercell vector, set by :meth:generate_points.

neighbours property writable

neighbours

dict: Nearest-neighbour displacements keyed by atom-type label.

Returns a plain Python dict mapping each type label (str) to its list of [dx, dy] displacement vectors. Reconstructed from the Rust backend on every access.

pbc property writable

pbc

bool: Whether periodic boundary conditions are active.

point_types property writable

point_types

list of str: Atom-type label for each point in :attr:points.

Has the same length as :attr:points. None until :meth:generate_points has been called.

points property writable

points

np.ndarray or None: Generated lattice-point coordinates, shape (N, 2).

None until :meth:generate_points has been called.

rot_m property writable

rot_m

np.ndarray: 2x2 rotation matrix applied to this layer.

study_proximity property writable

study_proximity

int: Number of supercell shells included in the neighbour search.

translation property writable

translation

tuple of float: Translation (tx, ty) applied after rotation.

first_nearest_neighbours

first_nearest_neighbours(points=None, types=None)

Find the first nearest neighbours for each lattice point.

For every point, returns the indices of its first-shell neighbours as defined by the neighbours displacement dictionary supplied at construction. The Rust backend handles type-to-ID mapping.

Parameters:

Name Type Description Default
points array-like of shape (N, 2)

Query point coordinates. Defaults to :attr:points (the full generated lattice) if not provided.

None
types array-like of length N

Atom-type label for each query point. Defaults to :attr:point_types if not provided.

None

Returns:

Type Description
list of list of int

A jagged list of length N. result[i] is the list of (global) indices of the first nearest neighbours of point i.

Raises:

Type Description
ValueError

If points is not a 2-D array with shape (N, 2).

generate_points

generate_points(mlv1, mlv2, mln1=1, mln2=1)

Populate the layer with lattice points inside a moiré supercell.

The supercell is tiled mln1 x mln2 times along mlv1 and mlv2 respectively. All basis atoms in each unit cell within that region are added to :attr:points.

Parameters:

Name Type Description Default
mlv1 ndarray

First moiré supercell lattice vector, shape (2,).

required
mlv2 ndarray

Second moiré supercell lattice vector, shape (2,).

required
mln1 int

Number of supercell repetitions along mlv1. Must be a positive integer. Default is 1.

1
mln2 int

Number of supercell repetitions along mlv2. Must be a positive integer. Default is 1.

1

Raises:

Type Description
AssertionError

If mln1 or mln2 are not positive integers.

get_neighbors_within_radius

get_neighbors_within_radius(query_points, radius)

Find all lattice points within a given radius of each query point.

Searches the full generated lattice for any atom within radius of each entry in query_points.

Parameters:

Name Type Description Default
query_points array-like of shape (N, 2)

Coordinates of the N probe positions.

required
radius float

Search radius (in the same units as the lattice vectors).

required

Returns:

Name Type Description
bigger_list list of list of int

bigger_list[i] contains the global indices of neighbours of query point i from the larger index perspective (used for deduplication in Hamiltonian assembly).

smaller_list list of list of int

smaller_list[i] contains the corresponding partner indices (smaller-index end of each bond).

dist_list list of list of float

dist_list[i] contains the Euclidean distances to each neighbour found for query point i.

Raises:

Type Description
ValueError

If query_points is not a 2-D array with shape (N, 2).

Notes

The bigger/smaller split mirrors the convention used in the Rust backend to avoid double-counting hopping terms when building tight-binding Hamiltonians.

perform_rotation_translation

perform_rotation_translation(rot, translation=None)

Apply a rotation and optional translation to the layer.

Must be called before :meth:generate_points. The rotation is stored internally and applied when lattice points are generated.

Parameters:

Name Type Description Default
rot float

Rotation angle in degrees.

required
translation array-like of length 2

Translation vector (tx, ty) applied after rotation. Defaults to (0.0, 0.0) if not provided.

None

Raises:

Type Description
RuntimeError

If points have already been generated via :meth:generate_points.

ValueError

If translation cannot be interpreted as a pair of numbers.

plot_lattice

plot_lattice(plot_connections=True, colours=['r', 'g', 'b', 'c', 'm', 'y', 'k'])

Plot the generated lattice points, optionally with neighbour bonds.

Atom types are distinguished by colour, cycling through the colours list in the same order as :attr:basis_points. Bond lines are drawn with 10 % opacity so they do not obscure the sites.

Parameters:

Name Type Description Default
plot_connections bool

Whether to draw lines between each atom and its nearest neighbours. Default is True.

True
colours list of str

Matplotlib colour strings assigned to each atom type in order. If the list has exactly one entry, all types share that colour. Default is ["r", "g", "b", "c", "m", "y", "k"].

['r', 'g', 'b', 'c', 'm', 'y', 'k']
Notes

This method adds artists to the current active Matplotlib axes. Call plt.show() (or save the figure) after this method. The axes aspect ratio is set to "equal" automatically.

Examples:

>>> import matplotlib.pyplot as plt
>>> layer = HexagonalLayer()
>>> layer.generate_points(mlv1, mlv2)
>>> layer.plot_lattice()
>>> plt.show()