Geometry guide¶
Predefined lattices¶
All constructors accept finite extents and boundary conditions. Lowercase names are the canonical API; capitalized aliases are provided for migration convenience.
| Constructor | Sites per cell | Built-in plaquettes | Meaning of a |
|---|---|---|---|
chain |
1 | none | nearest-neighbor spacing |
square |
1 | square | nearest-neighbor spacing |
triangular |
1 | up/down triangles | nearest-neighbor spacing |
triangular_nnn |
1 | up/down triangles | nearest-neighbor spacing |
honeycomb |
2 | hexagon | nearest-neighbor spacing |
kagome |
3 | up/down triangles and hexagon | nearest-neighbor spacing |
grid / hypercubic |
1 | none | per-axis spacing / common spacing |
bcc / fcc |
1 | none | conventional cubic lattice constant |
diamond |
2 | none | conventional cubic lattice constant |
pyrochlore |
4 | typed tetrahedron faces | conventional cubic lattice constant |
bond_types= reclassifies the declared directions without assigning coupling values.
Declare a custom unit cell¶
from latticegeom import Bond, Lattice, Plaquette, Site, UnitCell
cell = UnitCell(
sites=[Site((0.0, 0.0), "A"), Site((0.5, 0.0), "B")],
bonds=[
Bond(0, 1, (0, 0), "intracell"),
Bond(1, 0, (1, 0), "intercell"),
],
plaquettes=[
Plaquette(
[(0, (0, 0)), (1, (0, 0)), (0, (1, 0)), (1, (0, 1))],
"loop",
)
],
)
lat = Lattice(
basis=((1.0, 0.0), (0.2, 1.0)),
unit_cell=cell,
extent=(8, 5),
pbc=(True, False),
)
Site positions are Cartesian offsets from the cell origin. Every relation shift is an integer coordinate in the primitive basis. A plaquette must contain at least three unique vertices; do not repeat the first vertex to close it.
Boundary conditions¶
Use pbc=True or False for all axes, or a boolean sequence for mixed boundaries.
Open-axis relations that leave the finite extent are dropped. Periodic-axis relations
are wrapped while retaining their exact image shift.
site = lat.site_id((7, 2), site=1)
cell_coord, sublattice = lat.cell_and_site(site)
unfolded = lat.position(site, super_idx=lat.super_index((1, 0)))
wrap=True in site_id may fold periodic axes but never folds an open axis.
Query bonds and plaquettes¶
rows = lat.find_bonds(
type="intercell",
cell_shift=(1, 0),
crossing=True,
)
plaquettes = lat.plaquettes.indices(type="loop", crossing=False)
sites, images = lat.plaquettes.vertices(plaquettes[0])
boundary = lat.plaquette_boundary(plaquettes[0])
Bond filters return row indices because multiedges are intentional. PlaquetteBoundary
returns exact directed perimeter endpoints plus primitive and simulation-supercell
shifts. plaquette_positions, plaquette_centers, and plaquette_signed_areas use
unfolded geometry.
For lightweight graph code, lat.edges(...) and lat.adjacency_list(...) return Python
containers. Performance-sensitive code should access lat.bonds directly.
Compose unit cells¶
UnitCellBuilder is mutable only during authoring:
from latticegeom import UnitCellBuilder
builder = UnitCellBuilder(lower_cell)
upper = builder.extend(
lower_cell,
offset=(0.0, 0.0, 0.3),
site_type_map=lambda label: ("upper", label),
)
builder.add_bond(0, upper[0], (0, 0), "interlayer")
bilayer = builder.build()
translate_unit_cell shifts Cartesian site offsets. merge_unit_cells combines
declarations and renumbers their references.
Enlarge or tilt the declaration cell¶
Use an orientation-preserving integer transformation to create a crystallographic or magnetic supercell without rediscovering bonds by distance:
from latticegeom import Lattice, make_unit_cell_supercell
new_basis, new_cell = make_unit_cell_supercell(
lat.basis,
lat.unit_cell,
((2, 1), (0, 1)),
)
enlarged = Lattice(new_basis, new_cell, (3, 3), pbc=True)
The transformation remaps site representatives, bond shifts, and plaquette vertices exactly. Its determinant gives the number of old cells inside the new declaration cell.