Boundary API

See Boundary conditions guide and the concept column Boundary conditions for the narrative background.

Abstract types

LatticeCore.AbstractBoundaryConditionType
AbstractBoundaryCondition

Abstract supertype for lattice boundary conditions.

The canonical concrete type is LatticeBoundary, which composes:

The split is deliberate: an axis BC decides whether a candidate bond exists (and whether it carries a twist phase), while a modifier only reweights existing bonds (e.g. sine-square deformation). Multiple concerns are composed, not shoehorned into a single taxonomy.

See dev/note/04_architecture/03_boundary_and_coordinates/README.md for the design rationale.

source
LatticeCore.AbstractAxisBCType
AbstractAxisBC

Abstract supertype for per-axis boundary conditions. Concrete subtypes decide how a raw candidate cell index is wrapped into the lattice's index range along a single axis.

Subtypes:

  • PeriodicAxis — wraps via mod1
  • OpenAxis — rejects out-of-range indices
  • TwistedAxis — wraps like PeriodicAxis but attaches a phase factor to bonds that cross the boundary
source
LatticeCore.AbstractBoundaryModifierType
AbstractBoundaryModifier

Abstract supertype for boundary modifiers. A modifier does not change which bonds exist — it only reweights existing bonds through bond_weight. Examples: NoModifier, SSD.

Extending

Downstream packages may define their own modifier types by subtyping AbstractBoundaryModifier and overloading

bond_weight(::MyModifier, lat::AbstractLattice, i::Int, j::Int)::Float64

The two-argument default bond_weight(modifier, lat) may also be overloaded if a modifier wants to broadcast a single scalar over the whole lattice. AbstractBoundaryModifier and the concrete NoModifier / SSD types are part of the public exported API of LatticeCore precisely so downstream code can extend them.

source

Axis-level boundaries

Modifiers

LatticeCore.SSDType
SSD(L)

Sine-square deformation modifier. L is a characteristic scale carried by the modifier; the canonical bond weight evaluation (bond_weight(::SSD, lat, i, j)) reads the per-axis lengths of the lattice from size_trait instead, so L is informational under finite, fully-specified geometries. It is retained for downstream packages that may want to override the default with an alternative scale (e.g. infinite-system extrapolations).

Canonical envelope

For a D-dimensional finite lattice with per-axis cell counts (L_1, …, L_D), the SSD envelope evaluated at a lattice cell with 1-based per-axis coordinate cx_d ∈ 1:L_d is

\[f(\mathbf{r}) = \prod_{d=1}^{D} \sin^{2}\!\left( \pi \, \frac{c_{x,d} - 1/2}{L_d} \right),\]

equivalent to the standard $\sin^2(\pi (i + 1/2) / L)$ on 0-indexed sites. The bond weight between sites i, j is the arithmetic mean of the two endpoint envelopes, $w(i, j) = (f(\mathbf{r}_i) + f(\mathbf{r}_j)) / 2$.

SSD is exported so downstream MC / TN packages can construct boundaries with SSD weighting and dispatch on the type. Custom deformations should subtype AbstractBoundaryModifier rather than re-using SSD.

source

Composite boundary

LatticeCore.LatticeBoundaryType
LatticeBoundary{N, A, M}(axes::NTuple{N, <:AbstractAxisBC}, modifier)

Composite boundary condition for an N-dimensional lattice. Stores one AbstractAxisBC per axis plus a single AbstractBoundaryModifier. Supports mixed-axis boundary conditions natively — a cylinder is

LatticeBoundary((PeriodicAxis(), OpenAxis()))

The zero-modifier form is the default.

source

Hook functions

LatticeCore.apply_axis_bcFunction
apply_axis_bc(axis_bc::AbstractAxisBC, idx::Int, L::Int) → (wrapped, is_valid)

Apply the axis-level BC to a raw cell index idx ∈ ℤ on an axis of length L. Returns a tuple (wrapped::Int, is_valid::Bool):

  • PeriodicAxis, TwistedAxis: (mod1(idx, L), true)
  • OpenAxis: (idx, 1 <= idx <= L)

The twist phase is intentionally reported separately by axis_phase: MC code paths that do not need phases (classical Ising / XY / Heisenberg) are not forced to traffic in complex numbers.

source
LatticeCore.axis_phaseFunction
axis_phase(axis_bc::AbstractAxisBC, idx::Int, L::Int) → ComplexF64

Phase factor attached to a bond that steps from a valid cell index to idx (possibly out of 1:L) along a single axis.

  • PeriodicAxis, OpenAxis: always 1 + 0im.
  • TwistedAxis(θ): cis(+θ) if idx > L, cis(-θ) if idx < 1, otherwise 1 + 0im.

Classical MC paths may ignore this; quantum / flux-carrying code should multiply bond contributions by the phase.

source
LatticeCore.bond_weightFunction
bond_weight(modifier::AbstractBoundaryModifier, lat, i::Int, j::Int) → Float64

Multiplicative weight applied to the bond (i, j) by a boundary modifier. Default implementation for NoModifier returns 1.0. SSD and other non-trivial modifiers will override this.

source
bond_weight(::SSD, lat::AbstractLattice, i::Int, j::Int) → Float64

Sine-square deformation envelope for the bond (i, j). Each axis contributes a sin²(π (c_d - 1/2) / L_d) factor, where c_d is the 1-based per-axis cell coordinate read from to_lattice(lat, RealSpace(position(lat, i))) and L_d is the matching component of size_trait(lat).dims. The bond weight is the arithmetic mean of the two endpoint envelopes,

\[w(i, j) = \tfrac{1}{2}\bigl(f(\mathbf{r}_i) + f(\mathbf{r}_j)\bigr).\]

Requires a FiniteSize lattice; an InfiniteSize / QuasiInfiniteSize lattice raises ArgumentError because the envelope has no canonical scale without finite per-axis lengths. Downstream packages may overload the method on a more specific lattice type to supply alternative scales.

Boundary-condition assumptions

SSD is most commonly paired with open boundaries (the envelope suppresses surface excitations of an OBC sample); the implementation itself is BC-agnostic and will weight any bond regardless of the axis BCs in LatticeBoundary.

source