Source code for qlinks.lattice.types

from __future__ import annotations

from dataclasses import dataclass
from enum import StrEnum
from typing import TypeAlias

SiteId: TypeAlias = int
LinkId: TypeAlias = int
PlaquetteId: TypeAlias = int
CellCoord: TypeAlias = tuple[int, ...]
Position: TypeAlias = tuple[float, ...]


[docs] class BoundaryCondition(StrEnum): OPEN = "open" PERIODIC = "periodic"
[docs] @dataclass(frozen=True, slots=True) class Site: """ Geometry-level site metadata. id: Consecutive integer site id. cell: Unit-cell coordinate, e.g. (x,), (x, y), etc. sublattice: Sublattice label. For Bravais lattices, this can be 0. position: Real-space embedding coordinate. This is for geometry/debugging/plotting. It should not be used as the primary index in performance-sensitive code. """ id: SiteId cell: CellCoord sublattice: int = 0 position: Position = () def __post_init__(self) -> None: if self.id < 0: raise ValueError("Site.id must be non-negative.") if len(self.cell) == 0: raise ValueError("Site.cell cannot be empty.") if self.sublattice < 0: raise ValueError("Site.sublattice must be non-negative.") if self.position and len(self.position) != len(self.cell): raise ValueError("Site.position must have the same dimension as Site.cell.")
[docs] @dataclass(frozen=True, slots=True) class Plaquette: """ Oriented elementary loop. links: Link ids around the loop. orientations: For each link in the loop: +1 if traversed along the stored link orientation, -1 if traversed opposite to the stored link orientation. sites: Site ids around the loop. This is metadata useful for debugging, plotting, and later local operator construction. kind: Geometry-dependent plaquette type. anchor_cell: Unit-cell coordinate used to label this plaquette. """ id: PlaquetteId links: tuple[LinkId, ...] orientations: tuple[int, ...] sites: tuple[SiteId, ...] kind: str = "" anchor_cell: CellCoord = () def __post_init__(self) -> None: if self.id < 0: raise ValueError("Plaquette.id must be non-negative.") if len(self.links) == 0: raise ValueError("Plaquette.links cannot be empty.") if len(self.links) != len(self.orientations): raise ValueError("Plaquette.links and Plaquette.orientations must have equal length.") if len(self.sites) < 3: raise ValueError("Plaquette.sites must contain at least three sites.") bad = [ori for ori in self.orientations if ori not in (-1, 1)] if bad: raise ValueError("Plaquette.orientations must only contain +1 or -1.") object.__setattr__( self, "anchor_cell", tuple(int(c) for c in self.anchor_cell), ) @property def boundary(self) -> tuple[OrientedLink, ...]: """Return the oriented boundary links of this plaquette.""" return tuple( OrientedLink(link_id=link_id, orientation=orientation) for link_id, orientation in zip( self.links, self.orientations, strict=True, ) )