Lattice2D.jl

A Julia package for constructing and visualizing 2D lattices for quantum many-body physics simulations.

Installation

using Pkg
Pkg.add("Lattice2D")

Models

The models implemented in this module is below.

Lattice2D.AbstractTopologyType
AbstractTopology{D}

Abstract supertype for 2D lattice topologies (Square, Triangular, Honeycomb, ...). Each concrete subtype is a singleton that acts as a dispatch key for get_unit_cell, and, through TopologyTrait in LatticeCore, as the topology(lat) value of the resulting Lattice.

source
Lattice2D.ConnectionType
Connection(src_sub, dst_sub, dx, dy, type)

A unit-cell-level connection rule — the description of an edge between sublattices inside a single unit cell, or between a sublattice in one cell and a sublattice in a neighbouring cell.

This is distinct from LatticeCore.Bond:

  • A Connection is a template on the unit cell (src_sub, dst_sub are sublattice ids, dx, dy are relative cell offsets). It is topology data, known statically from get_unit_cell.
  • A LatticeCore.Bond is an instantiated edge on a concrete Lx × Ly sample, with absolute site indices and a wrapped displacement vector. It is the per-sample output of build_lattice.

Fields

  • src_sub::Int — 1-based sublattice id of the source site
  • dst_sub::Int — 1-based sublattice id of the destination site
  • dx::Int — x-axis cell offset (0 = same unit cell)
  • dy::Int — y-axis cell offset
  • type::Int — bond type tag. Currently stored as an Int on the Connection side for backward compatibility; build_lattice converts this to a Symbol (:type_N) when it emits LatticeCore.Bond.
source
Lattice2D.DiceType
Dice <: AbstractTopology{2}

Dice (T3) lattice: bipartite triangular-based structure with a single 6-coordinated hub site and two 3-coordinated rim sites per unit cell.

source
Lattice2D.DilutedLatticeType
DilutedLattice{D, T, L<:AbstractLattice{D, T}} <: AbstractLattice{D, T}

Wrapper lattice with disordered sites / bonds. See module docstring of disorder/dilution.jl.

Fields

  • base::L — the underlying lattice
  • active_sites::BitVector — length num_sites(base); true where the site is kept
  • killed_bonds::Set{Tuple{Int, Int}} — canonical (min_i, max_j) base-index pairs of bonds that are explicitly removed (in addition to bonds whose endpoints are inactive)
  • new_to_old::Vector{Int}new_to_old[k] is the base-lattice index of the k-th active site (length == count(active_sites))
  • old_to_new::Vector{Int}old_to_new[i] is the new index of base site i, or 0 if i is inactive

The new_to_old / old_to_new arrays are derived from active_sites and cached at construction; the constructors below are the only sanctioned entry points so the invariants stay tight.

source
Lattice2D.DilutedLatticeMethod
DilutedLattice(base, active_sites, killed_bonds = Set{Tuple{Int, Int}}())

Construct a DilutedLattice from a base lattice plus a site-activity mask and an optional explicit bond-removal set. The remap arrays are derived from active_sites. killed_bonds keys are canonicalised to (min, max) form.

Throws ArgumentError if active_sites does not match num_sites(base), or if any entry of killed_bonds references a site outside 1:num_sites(base).

source
Lattice2D.HoneycombType
Honeycomb <: AbstractTopology{2}

Honeycomb lattice: two-sublattice (A/B) bipartite triangular Bravais lattice, three nearest neighbours per site.

source
Lattice2D.InfiniteLatticeType
InfiniteLattice{Topo, T, L}(; layout = UniformLayout(IsingSite()))

A truly infinite 2D lattice of topology Topo — the thermodynamic-limit counterpart of the finite Lattice under periodic boundary conditions. It carries no size (size_trait is InfiniteSize, num_sites throws) and is described by, and accessed through, its unit-cell motif:

  • site_orbits / bond_orbits — the finite fundamental domain (one entry per sublattice / per Connection of get_unit_cell(Topo));
  • cell_position, neighbors_at, incident_cell_bonds — on-demand access to any CellSite, computed without materialising the lattice.

If a finite sample is needed, materialize tiles the motif into a periodic Lattice:

inf = InfiniteLattice(Honeycomb)
fin = materialize(inf; dims = (8, 8))   # 8×8 PBC honeycomb Lattice

but the lazy accessors above never require it.

Positions use Float64, matching the finite Lattice produced by build_lattice.

Example

inf = InfiniteLattice(Kagome)
site_orbits(inf)                         # 1:3  (three sublattices)
length(collect(bond_orbits(inf)))        # motif bond count
neighbors_at(inf, CellSite((0, 0), 1))   # neighbours of basis-1 site
source
Lattice2D.KagomeType
Kagome <: AbstractTopology{2}

Kagome lattice: three-sublattice (A/B/C) structure on a triangular Bravais lattice, four nearest neighbours per site.

source
Lattice2D.LatticeType
Lattice{Topo, T}

Finite 2D lattice obtained by tiling a unit cell (described by get_unit_cell on a topology singleton) over an Lx × Ly sample, with a LatticeCore.LatticeBoundary defining per-axis boundary conditions. Subtype of LatticeCore.AbstractLattice{2, T}.

The struct stores only the parameters that define the lattice; all pure-function-of-input data (position, sublattice, neighbors, basis_vectors, ...) are derived on demand through the LatticeCore interface (lattice_coord, apply_axis_bc, to_real). This mirrors the reference SimpleSquareLattice in LatticeCore and keeps the type lightweight.

Boundary-condition-dependent aggregates that appear repeatedly (bonds, plaquettes, the bond and plaquette reverse-lookup tables) are memoised through a lazy cache field — populated on first access by _get_cache and then reused by the O(local) element-center and incidence overrides.

Type parameters

  • Topo<:AbstractTopology{2} — topology singleton
  • T<:AbstractFloat — numeric type for positions

The boundary, indexing, and layout are stored as fields with abstract eltypes (LatticeBoundary, AbstractIndexing, AbstractSiteLayout). Hot paths that depend on the concrete types of these fields (_connection_steps, _neighbors_by_shell, _materialise_plaquettes) use a function-barrier pattern: they extract the fields and immediately forward to a specialised kernel, so the JIT specialises on the runtime types and the inner loops stay type-stable. This trades 5 type parameters for 2 to cut dispatch / compile-time cost without measurable hot-path regression. See issue #48 for context.

Prefer constructing via build_lattice.

source
Lattice2D.LatticeMethod
Lattice2D.Lattice(Topology, Lx, Ly; kwargs...)

Convenience alias for build_lattice. Kept so that Lattice2D.Lattice(Square, 4, 4) reads naturally at the call site.

source
Lattice2D.LatticeCacheType
LatticeCache{T}

Lazy, per-lattice cache of bonds, plaquettes, and the reverse-lookup tables needed to make the element-center / incidence API O(local) instead of O(numbonds + numplaquettes) per call.

The cache is constructed once on first access through _get_cache and lives inside a Ref field on the parent Lattice, so the struct itself stays immutable and cheap to copy. For sizes typical of MC work (10⁴–10⁶ sites), the cache occupies a few hundred kilobytes and is negligible relative to the state vectors MC actually keeps hot.

Fields

  • bonds::Vector{Bond{2, T}} — materialised bond list, ordered by (cell_y, cell_x, connection_index) just like the generic bonds(lat) iteration.
  • plaquettes::Vector{Plaquette{2, T}} — materialised plaquette list, ordered by (cell_y, cell_x, rule_index).
  • bond_index_of::Dict{Tuple{Int, Int}, Int}(min_i, max_j) → integer bond index. Keyed by the canonical (smaller, larger) endpoint tuple so that bond_index_of[(min(i, j), max(i, j))] always hits regardless of which endpoint walked first.
  • plaquettes_by_vertex::Vector{Vector{Int}} — per-site list of plaquette indices whose boundary contains that site.
  • plaquettes_by_bond::Dict{Tuple{Int, Int}, Vector{Int}} — per-bond list of plaquette indices that have that bond on their boundary. Same canonical (min, max) keying as bond_index_of.
source
Lattice2D.LiebType
Lieb <: AbstractTopology{2}

Lieb (line-centred square) lattice: three-sublattice structure on a square Bravais lattice. Used for flat-band physics.

source
Lattice2D.ShastrySutherlandType
ShastrySutherland <: AbstractTopology{2}

Shastry–Sutherland lattice: square Bravais lattice with four sites per unit cell, both nearest-neighbour (square) bonds and dimer (J′) bonds.

source
Lattice2D.SquareType
Square <: AbstractTopology{2}

Standard square lattice: one sublattice, orthonormal primitive vectors, four nearest neighbours per site.

source
Lattice2D.StepType
Step{T}

Internal, concretely-typed record returned by _connection_steps: the result of resolving a unit-cell Connection against the sample boundary. Fields:

  • j::Int — neighbour site index
  • d_vec::SVector{2,T} — wrapped displacement vector
  • type::Symbol — bond type tag (:type_N)

Replaces the previous Tuple{Int,SVector{2,T},Symbol} representation to make the eltype concrete and remove the per-step dynamic Symbol("type_", conn.type) from the hot path.

source
Lattice2D.TriangularType
Triangular <: AbstractTopology{2}

Triangular lattice: one sublattice, 60° primitive vectors, six nearest neighbours per site.

source
Lattice2D.UnionJackType
UnionJack <: AbstractTopology{2}

Union Jack (centred square) lattice: square primitive cell with two sublattices — a corner site and a body-centred site — and eight-coordinated corner sites, four-coordinated body sites.

source
Lattice2D.UnitCellType
UnitCell{D, T}

Static topology description for a D-dimensional Bravais lattice with an arbitrary basis. Contains

  • basis::Vector{Vector{T}} — the D primitive vectors
  • sublattice_positions::Vector{Vector{T}} — one offset per geometric sublattice inside the unit cell
  • connections::Vector{Connection} — the full list of intra- and inter-cell connection rules for this topology
  • plaquettes::Vector{LatticeCore.PlaquetteRule} — declarative list of plaquette rules (one per plaquette kind) anchored at the reference cell. Empty for topologies that haven't been wired up to the plaquette API yet.

Produced by get_unit_cell on an AbstractTopology singleton.

source
Lattice2D.UnitCellMethod
UnitCell{D, T}(; basis, sublattice_positions, connections, plaquettes = PlaquetteRule[])

Keyword-argument constructor for UnitCell. Equivalent to the positional UnitCell{D, T}(basis, sublattice_positions, connections, plaquettes), but lets call sites label each argument explicitly and omit plaquettes for topologies that don't (yet) declare any.

The 3-positional and 4-positional forms remain available unchanged.

source
Lattice2D._edge_keyMethod
_edge_key(i::Int, j::Int) → Tuple{Int, Int}

Canonical, orientation-independent key for an undirected edge between sites i and j, defined as (min(i, j), max(i, j)).

This helper is used by the per-lattice LatticeCache and the element / incidence API in core/element_api.jl to look up bonds and plaquette-by-bond entries without caring which endpoint walked first.

It is shared as a single internal utility (rather than re-defined ad hoc in each file) so that any future change to the canonical-form convention (e.g. promoting it to a struct) only needs to happen here.

This is internal to Lattice2D — it is not exported and should not be relied on by downstream packages. If a similar helper is needed in LatticeCore itself it should be promoted there in a separate PR.

source
Lattice2D._get_cacheMethod
_get_cache(lat::Lattice{Topo, T}) → LatticeCache{T}

Return the lattice's per-sample cache, populating it on first access.

source
Lattice2D._resolve_boundaryMethod
_resolve_boundary(axis::LatticeCore.AbstractAxisBC)
_resolve_boundary(boundary::LatticeCore.LatticeBoundary)

Normalise the user-facing boundary argument of build_lattice to a LatticeBoundary{2}. A single axis BC is broadcast to both axes with a NoModifier; an explicit LatticeBoundary is returned as-is.

source
Lattice2D.block_sublatticeMethod
block_sublattice(nsub, f, sub, o) -> Int

Index of the new sublattice carrying old sublattice sub at block offset o (a (dx, dy) in 0:f-1). Ordering is old-sublattice-fastest, then ox, then oy, so sub = 1, o = (0,0) is 1.

source
Lattice2D.blockingFunction
blocking(::Type{Topo}, f::Integer = 2) -> UnitCell

Convenience form: blocking(get_unit_cell(Topo), f). Takes a topology type, so no lattice — and in particular no lattice size — has to exist first.

source
Lattice2D.blockingMethod
blocking(uc::UnitCell{2,T}, f::Integer = 2) -> UnitCell{2,T}

The unit cell of the lattice coarse-grained by a factor f per axis: old cells become one new cell, whose basis is f times the old one and whose sublattices are the old sublattices at each of the block offsets.

Every Connection is re-expressed in the new cell. A bond whose two ends land in the same new cell becomes an internal connection (offset (0,0)); one that crosses gets the corresponding new offset. No site indices are involved, so this applies to an infinite lattice exactly as it does to a finite one — unlike cell_partition, which enumerates 1:num_sites.

julia> using Lattice2D

julia> uc = get_unit_cell(Square);

julia> b = blocking(uc, 2);

julia> length(b.sublattice_positions)      # 2×2 block of a one-site cell
4

julia> b.basis                              # the basis is doubled
2-element Vector{Vector{Float64}}:
 [2.0, 0.0]
 [0.0, 2.0]

julia> count(c -> c.dx == 0 && c.dy == 0, b.connections)   # bonds now internal to the new cell
4
source
Lattice2D.bond_distancesMethod
bond_distances(lat::Lattice) -> Vector{Float64}

Euclidean length of every bond returned by bonds, in the same order. Lengths are not deduplicated, so the multiset of distances encodes both the bond-type spectrum and the bond multiplicity.

source
Lattice2D.bond_typeMethod
bond_type(lat::Lattice, i::Int, j::Int) → Symbol

Return the bond-type tag of the edge connecting sites i and j on lat. Uses the cached bond-index reverse lookup, so each call is O(1) after the first cache access. Throws ArgumentError if there is no declared bond between i and j.

The tag is inherited from the Connection.type of the underlying unit cell, so it distinguishes anisotropic edges such as the ShastrySutherland J′ dimer (:type_2) from its square-lattice NN bonds (:type_1).

source
Lattice2D.brillouin_zoneFunction
brillouin_zone(lat::Lattice; shell::Int=2) -> Vector{SVector{2,Float64}}

Compute the Brillouin zone of lat as the Wigner-Seitz cell of its reciprocal lattice. Returns an ordered list of polygon vertices in Cartesian k-space, walked counter-clockwise around the origin.

Throws ArgumentError if lat has any open axis (no reciprocal lattice => no BZ).

The concrete method lives in the Lattice2DPlotsExt package extension and is loaded automatically once Plots is in scope. See the Lattice2DPlotsExt module docstring for the algorithm and the shell keyword.

source
Lattice2D.build_latticeMethod
build_lattice(Topology, Lx, Ly;
              boundary = PeriodicAxis(),
              indexing = RowMajor(),
              layout   = UniformLayout(IsingSite())) → Lattice

Construct a finite 2D lattice of topology Topology on an Lx × Ly sample. The boundary argument accepts either a single LatticeCore.AbstractAxisBC (broadcast to both axes) or an explicit LatticeCore.LatticeBoundary for mixed-axis setups such as cylinders.

All geometric / connectivity data (positions, neighbours, bonds) are computed lazily by the accessors defined on Lattice; this constructor only validates and wraps its arguments, so building is O(1) regardless of Lx × Ly.

Examples

# 4 × 4 periodic square lattice, row-major linearisation, Ising sites
lat = build_lattice(Square, 4, 4)

# Open honeycomb 6 × 6
open_hc = build_lattice(Honeycomb, 6, 6; boundary = OpenAxis())

# Cylinder: square lattice with PBC in x, OBC in y
cyl = build_lattice(Square, 4, 4;
    boundary = LatticeBoundary((PeriodicAxis(), OpenAxis())))

# Kagome with XY sites
xy_kg = build_lattice(Kagome, 4, 4; layout = UniformLayout(XYSite()))
source
Lattice2D.coordination_numberMethod
coordination_number(lat::Lattice, i::Int) -> Int

Degree of site i in the declared adjacency graph of lat (number of distinct neighbours, no double-counting). For PBC samples on uniform lattices this matches the textbook coordination number (Square = 4, Triangular = 6, Honeycomb = 3, Kagome = 4, ...). For OBC samples it returns the local degree, which is smaller at the boundary.

source
Lattice2D.diceFunction
dice(L::Int, M::Int = L; kw...) -> Lattice

Shortcut for build_lattice(Dice, L, M; kw...).

source
Lattice2D.dilute_bondsMethod
dilute_bonds(base::AbstractLattice, p::Real; rng=nothing) → DilutedLattice

Keep all sites; delete each bond of base independently with probability p. The returned DilutedLattice shares the site indexing of base (num_sites and position are unchanged) but its bond / neighbour iterators omit the killed edges.

p must lie in [0, 1]. p = 0 keeps every bond; p = 1 deletes every bond.

rng is forwarded as the first positional argument to rand, so any AbstractRNG may be passed for reproducibility. The default nothing falls back to the argument-less rand().

source
Lattice2D.dilute_sitesMethod
dilute_sites(base::AbstractLattice, p::Real; rng=nothing) → DilutedLattice

Delete each site of base independently with probability p. The returned DilutedLattice renumbers the surviving sites contiguously as 1..N_active.

p must lie in [0, 1]. p = 0 reproduces the base lattice (modulo the wrapper); p = 1 removes every site (the wrapper is still well-formed but most queries become empty).

rng is forwarded as the first positional argument to rand, so any AbstractRNG (e.g. Random.MersenneTwister(seed)) may be passed for reproducibility. The default nothing falls back to the argument-less rand() (Julia's thread-local RNG).

source
Lattice2D.dual_latticeMethod
dual_lattice(lat::Lattice; kwargs...) -> Lattice

Construct the dual lattice of lat (see dual_topology for the topology map). The dual keeps the (Lx, Ly) extents and the boundary condition of lat; the indexing strategy is preserved unless overridden. Any extra kwargs are forwarded to build_lattice.

Because the topology map is an involution, dual_lattice(dual_lattice(lat)) has the same topology, extents and boundary as lat.

Example

tri  = triangular(6, 6)
hexy = dual_lattice(tri)          # honeycomb, 6x6, same boundary
topology(dual_lattice(hexy))      # back to the triangular topology

Throws ArgumentError if the dual of lat's topology is not a supported tiling (Lieb, ShastrySutherland, UnionJack).

See also dual_topology.

source
Lattice2D.dual_topologyMethod
dual_topology(::Type{T}) where {T <: AbstractTopology} -> Type

Return the topology type dual to T. Defined for Square (self-dual), Triangular/Honeycomb, and Kagome/Dice. Throws ArgumentError for topologies whose dual is not itself a supported tiling (Lieb, ShastrySutherland, UnionJack).

The map is an involution: dual_topology(dual_topology(T)) === T.

source
Lattice2D.dual_topologyMethod
dual_topology(t::AbstractTopology) -> AbstractTopology

Instance form: returns the dual topology singleton, e.g. dual_topology(Triangular()) === Honeycomb().

source
Lattice2D.get_plaquette_rulesMethod
get_plaquette_rules(::Type{T}) where {T <: AbstractTopology}
    → Vector{PlaquetteRule}

Introspection helper that returns the list of PlaquetteRule templates declared in topology T's unit cell. Equivalent to get_unit_cell(T).plaquettes, but communicates intent ("I only want the plaquette rules, not the full unit cell") and returns an empty Vector{PlaquetteRule} for topologies that haven't been wired up to the plaquette API yet.

Each PlaquetteRule is a template on the unit cell: its corners are (sublattice, dx, dy) tuples relative to the reference cell, its type tags the plaquette kind (e.g. :square, :up_triangle), and build_lattice instantiates them into concrete Plaquette objects on the finite sample. The complementary count on the instantiated lattice is num_plaquettes.

Example

julia> rules = get_plaquette_rules(Square);

julia> length(rules), rules[1].type
(1, :square)
source
Lattice2D.get_unit_cellMethod
get_unit_cell(::Type{T}) where {T <: AbstractTopology}

Return the UnitCell describing topology T. Concrete topology types (Square, Triangular, ...) specialise this method. The fallback throws.

See also get_plaquette_rules for plaquette-only introspection.

source
Lattice2D.high_symmetry_pointsFunction
high_symmetry_points(lat::Lattice) -> Dict{Symbol,SVector{2,Float64}}

Topology-keyed dictionary of high-symmetry points (Gamma, X, M, K, ...) in Cartesian k-coordinates. Currently populated for Square, Triangular, and Honeycomb; other topologies fall back to a singleton :Gamma entry.

The concrete method lives in the Lattice2DPlotsExt package extension and is loaded automatically once Plots is in scope.

source
Lattice2D.honeycombFunction
honeycomb(L::Int, M::Int = L; kw...) -> Lattice

Shortcut for build_lattice(Honeycomb, L, M; kw...).

source
Lattice2D.is_inversionMethod
is_inversion(op::SymmetryOperation) -> Bool

true if op is the point inversion r ↦ -r (in 2D, the 180° rotation).

source
Lattice2D.is_reflectionMethod
is_reflection(op::SymmetryOperation) -> Bool

true if op is an improper operation — a mirror reflection (det = -1).

source
Lattice2D.is_rotationMethod
is_rotation(op::SymmetryOperation) -> Bool

true if op is a proper rotation (det = +1), including the identity and the 180° inversion.

source
Lattice2D.kagomeFunction
kagome(L::Int, M::Int = L; kw...) -> Lattice

Shortcut for build_lattice(Kagome, L, M; kw...).

source
Lattice2D.liebFunction
lieb(L::Int, M::Int = L; kw...) -> Lattice

Shortcut for build_lattice(Lieb, L, M; kw...).

source
Lattice2D.mean_coordinationMethod
mean_coordination(lat::Lattice) -> Float64

Average coordination number across all sites of lat. For periodic uniform lattices this equals the bulk coordination number; for samples with open boundaries it is strictly smaller.

source
Lattice2D.num_bondsMethod
num_bonds(lat::Lattice) → Int

Convenience alias for num_elements(lat, BondCenter()) / the length of the cached bond Vector. O(1) after the first cache access.

source
Lattice2D.num_plaquettesMethod
num_plaquettes(lat::Lattice) → Int

Convenience alias for num_elements(lat, PlaquetteCenter()). Returns 0 for topologies whose unit cell declares no PlaquetteRule (currently this is just Dice — wait, now it is not; every shipped topology has a plaquette list as of Iter 6).

source
Lattice2D.plot_bondsFunction
plot_bonds(lat::Lattice; bond_types=:all, color_by=:type, kwargs...)

Lattice2D-flavoured standalone bond plot. Returns a fresh Plots.Plot that draws every bond in lat (optionally filtered by bond_types) as a line segment, grouped — and therefore coloured — by either the bond's :type tag or its rounded direction.

This function is a stub in the core module; the concrete method lives in the Lattice2DPlotsExt package extension and is loaded automatically once Plots is in scope.

See the Lattice2DPlotsExt module docstring for the full keyword list and worked examples.

source
Lattice2D.plot_brillouin_zoneFunction
plot_brillouin_zone(lat::Lattice; show_mesh=false, ml=nothing,
                    show_high_symmetry=false, kwargs...) -> Plots.Plot

Plot the Brillouin zone of lat as a closed polygon. Optionally overlays a momentum-lattice mesh on top of the BZ and labels high-symmetry points.

The concrete method lives in the Lattice2DPlotsExt package extension and is loaded automatically once Plots is in scope. See the Lattice2DPlotsExt module docstring for the full keyword list.

source
Lattice2D.plot_stateFunction
plot_state(lat::Lattice, state::AbstractVector;
           colormap=:viridis, marker_size=12, kwargs...) → Plots.Plot

Visualise a per-site state::AbstractVector (with length(state) == num_sites(lat)) as a coloured scatter on top of the lattice geometry. Both continuous fields (energy density, charge density, expectation values) and discrete labels (Bool, small-cardinality Int spin / clock-model configurations) are supported through the same call.

The concrete method lives in the Lattice2DPlotsExt package extension and is loaded automatically once Plots is in scope. See the Lattice2DPlotsExt module docstring for the full keyword list and worked examples.

source
Lattice2D.rotation_angleMethod
rotation_angle(op::SymmetryOperation) -> Float64

Rotation angle in radians (in (-π, π]) for a proper rotation. For a reflection it returns the angle of the equivalent orthogonal matrix; use is_rotation to guard.

source
Lattice2D.shellsMethod
shells(lat::Lattice, i::Int; n_shells::Int = 3) -> Vector{Vector{Int}}

Return the first n_shells geometric neighbour shells of site i as a list of site-index vectors. Each entry corresponds to one Euclidean distance class, in increasing order; the k-th entry is exactly neighbors(lat, i; shell = k).

Trailing empty shells (e.g. on a small OBC sample where the requested shell count exceeds the geometric reach) are returned as empty vectors, so the result always has length n_shells.

n_shells must be ≥ 1.

source
Lattice2D.site_orbitMethod
site_orbit(lat::Lattice, i::Int; kwargs...) -> Vector{Int}

The orbit (sorted site indices) containing site i under the realized point group of lat. kwargs are forwarded to symmetry_operations.

source
Lattice2D.squareFunction
square(L::Int, M::Int = L; kw...) -> Lattice

Shortcut for build_lattice(Square, L, M; kw...).

source
Lattice2D.sublattice_layoutMethod
sublattice_layout(Topology, Lx, Ly, types; indexing = RowMajor())

Convenience constructor for a SublatticeLayout that matches the geometric sublattice structure of an Lx × Ly lattice of the given Topology.

types must be a tuple of AbstractSiteType values with length equal to the number of sublattices in the topology's unit cell; types[k] becomes the site type for every site in the k-th geometric sublattice.

The indexing keyword must match whatever indexing will be passed to build_lattice — the layout's sublattice_of vector is computed via the chosen linearisation.

Example

# Honeycomb A / B with an Ising A sublattice and an XY B sublattice:
layout = sublattice_layout(Honeycomb, 4, 4, (IsingSite(), XYSite()))
lat = build_lattice(Honeycomb, 4, 4; layout = layout)
source
Lattice2D.symmetry_group_orderMethod
symmetry_group_order(lat::Lattice; kwargs...) -> Int

Number of realized point-group operations of lat (length(symmetry_operations(lat; kwargs...))).

source
Lattice2D.symmetry_operationsMethod
symmetry_operations(lat::Lattice; center=:auto, tol=1e-7)
    -> Vector{SymmetryOperation}

Realized point-group operations of lat — every rotation / reflection / inversion about center that permutes the sites (modulo the supercell on periodic axes). Always contains the identity.

center is :auto (origin for a fully periodic sample, centroid otherwise), :origin, :centroid, or an explicit 2-vector. tol is the position-matching tolerance.

See also symmetry_orbits, symmetry_group_order.

source
Lattice2D.symmetry_orbitsMethod
symmetry_orbits(lat::Lattice; kwargs...) -> Vector{Vector{Int}}

Partition the sites of lat into orbits under its realized point group: two sites are in the same orbit iff some symmetry maps one to the other. Each orbit is returned sorted, and the orbits are ordered by their smallest site index. By the orbit–stabilizer theorem every orbit size divides symmetry_group_order.

kwargs are forwarded to symmetry_operations (center, tol).

Example

lat = square(6, 6)            # periodic C₄ᵥ about the origin
orbits = symmetry_orbits(lat) # sites grouped by C₄ᵥ equivalence
source
Lattice2D.triangularFunction
triangular(L::Int, M::Int = L; kw...) -> Lattice

Shortcut for build_lattice(Triangular, L, M; kw...).

source
Lattice2D.union_jackFunction
union_jack(L::Int, M::Int = L; kw...) -> Lattice

Shortcut for build_lattice(UnionJack, L, M; kw...).

source
LatticeCore.cell_partitionFunction
cell_partition(lat::Lattice, k::Integer = 1) -> Vector{Vector{Int}}

Group the sites of lat by which unit cell of the lattice k steps coarser — that is, of rescale(lat, -k) — they fall into. Entry c lists the site indices of lat inside cell c of the coarser lattice, indexed with lat's own AbstractIndexing; together the groups partition 1:num_sites(lat).

Each group holds factor^k × factor^k unit cells of lat, hence factor^(2k) * num_sublattices(lat) sites. Requires Lx and Ly to be divisible by factor^k, for the same reason rescale does.

julia> using Lattice2D, LatticeCore

julia> groups = cell_partition(build_lattice(Square, 4, 4), 1);

julia> length(groups), length(first(groups))
(4, 4)

julia> sort(reduce(vcat, groups)) == 1:16
true
source
LatticeCore.is_bipartiteMethod
is_bipartite(lat::Lattice) -> Bool

Return true iff the declared adjacency graph of lat is bipartite, i.e. its sites admit a 2-colouring such that every bond connects different colours.

Implemented as a BFS 2-colouring over neighbors, starting a fresh BFS from each unvisited site so disconnected components are handled. O(num_sites + num_bonds).

source
LatticeCore.materializeMethod
materialize(lat::InfiniteLattice{Topo}; dims::NTuple{2, Int}) → Lattice{Topo}

Tile the motif into a dims[1] × dims[2] periodic Lattice of the same topology, carrying the infinite lattice's site layout. This is the optional infinite → finite bridge; the lazy translation-cell accessors do not require it.

source
LatticeCore.neighborsMethod
neighbors(lat::Lattice, i::Int) → Vector{Int}
neighbors(lat::Lattice, i::Int; shell::Int) → Vector{Int}

Neighbour indices of site i.

  • Without the shell keyword, returns all declared unit-cell connections. For most topologies this is the geometric NN; for topologies whose unit cell mixes bond types at different distances (e.g. ShastrySutherland, which declares both square NN and dimer J′ bonds), the returned set is the union.
  • With shell=k (k ≥ 1), returns the k-th geometric neighbour shell, ranked by Euclidean distance. For ShastrySutherland this separates the square NN (shell=1) from the dimer partner (shell=2).

The geometric search is bounded by the sample size — for PBC the minimum-image distance is used, for OBC only in-sample candidates are considered.

source
LatticeCore.rescaleFunction
rescale(lat::Lattice, k::Integer = 1) -> Lattice

The same lattice k scale steps larger: (Lx, Ly) are multiplied by factor^k, where factor comes from scaling_rule. Topology, boundary condition, indexing and layout are carried over unchanged.

k = 0 returns lat. Negative k steps down, and requires both Lx and Ly to be divisible by factor^|k| — a lattice that cannot be halved exactly raises rather than rounding, since a silently rounded size would corrupt any sequence built on it.

julia> using Lattice2D, LatticeCore

julia> lat = build_lattice(Square, 2, 3);

julia> l2 = rescale(lat, 2);

julia> (l2.Lx, l2.Ly)
(8, 12)

julia> num_sites.(size_sequence(lat, 2))
3-element Vector{Int64}:
  6
 24
 96
source
LatticeCore.to_latticeMethod
to_lattice(lat::Lattice, coord::RealSpace) → LatticeCoord{2}

Inverse of to_real: map a real-space point back to the nearest LatticeCoord on lat. The implementation inverts the basis matrix A = [a1 a2] once per call (SMatrix{2,2}, so the inverse is non-allocating), subtracts each candidate sublattice offset, and picks the (cell, sublattice) triple whose rounded cell indices reproduce coord with the smallest residual.

For periodic axes the rounded cell is wrapped into 1:Lx / 1:Ly through mod1, so points that lie outside the fundamental domain still resolve to a valid in-sample site. For open axes the rounded cell is returned as-is even when it falls outside 1:L; callers that need an in-sample guarantee should validate the result against (Lx, Ly).

Together with to_real this satisfies to_lattice(lat, to_real(lat, c)) == c for every in-sample LatticeCoord and every shipped topology.

source