lattice_guide

Lattice Infrastructure

The lattice layer defines the spatial geometry of the simulation and provides all coordinate, indexing, and stencil infrastructure used by the tensor and backend layers.

Lattice Concept

Every lattice type must satisfy the Lattice[D] concept, parameterized by the number of spatial dimensions D (a compile-time static[int]). A conforming type exposes three arrays:

FieldTypeDescription
globalGridarray[D, int]Full extent per dimension
mpiGridarray[D, int]MPI process grid (-1 for auto)
ghostGridarray[D, int]Ghost (halo) width per dimension

The concept lives in its own module (lattice/latticeconcept) to break circular imports between lattice.nim and lattice/stencil.nim.

SimpleCubicLattice

The only concrete lattice type currently provided is SimpleCubicLattice[D], which satisfies Lattice[D].

Construction

import reliq

# Minimal: auto-detect MPI decomposition, no ghosts
let lat = newSimpleCubicLattice([8, 8, 8, 16])

# Explicit MPI grid (4 ranks along t-axis)
let lat2 = newSimpleCubicLattice([8, 8, 8, 16], [1, 1, 1, 4])

# Full control: MPI grid + ghost widths
let lat3 = newSimpleCubicLattice([8, 8, 8, 16], [1, 1, 1, 4], [1, 1, 1, 1])

Properties

lat.globalGrid   # [8, 8, 8, 16]
lat.mpiGrid      # [1, 1, 1, 4]
lat.ghostGrid    # [1, 1, 1, 1]

Coordinate Indexing

The lattice/indexing module provides pure-function coordinate conversion utilities. All use little-endian flat-index ordering: dimension 0 varies fastest.

ProcSignatureDescription
flatToCoords(idx: int, dims: array[D, int]): array[D, int]Flat index → coordinates
coordsToFlat(coords, dims: array[D, int]): intCoordinates → flat index
localToGlobalCoords(localCoords, lo: array[D, int]): array[D, int]Local → global offset
globalToLocalCoords(globalCoords, lo: array[D, int]): array[D, int]Global → local offset
localFlatToGlobalFlat(localIdx: int, localDims, globalDims, lo): intFlat local → flat global
globalFlatToLocalFlat(globalIdx: int, localDims, globalDims, lo): intFlat global → flat local

Example:

import reliq

let dims = [4, 4]
let coords = flatToCoords(5, dims)   # [1, 1]  (5 = 1 + 1*4)
let flat = coordsToFlat(coords, dims) # 5

Stencil Operations

The unified stencil system lives in lattice/stencil and provides a single LatticeStencil[D] type that works identically across all backends.

Stencil Patterns

A StencilPattern[D] defines the shape of a stencil as a set of offsets relative to the center site:

import reliq

# Built-in nearest-neighbor stencil for 4D
let nn = nearestNeighborStencil[4]()
echo nn.name      # "nearest_neighbor"
echo nn.nPoints   # 8  (±1 in each of 4 dims)

# Built-in Laplacian stencil
let lap = laplacianStencil[4]()

# Lattice-inferred patterns (reads D from lattice type)
let lat = newSimpleCubicLattice([8, 8, 8, 16])
let nn2 = nearestNeighborStencil(lat)

# Custom patterns
var custom = newStencilPattern[2]("custom")
custom.addPoint([2, 0])   # Two steps in x
custom.addPoint([0, 2])   # Two steps in y

LatticeStencil

A LatticeStencil[D] binds a pattern to a specific lattice, pre-computing all neighbor offsets (including ghost region handling):

import reliq

let lat = newSimpleCubicLattice([8, 8, 8, 16], [1, 1, 1, 1], [1, 1, 1, 1])

# Create stencil from pattern
let stencil = newLatticeStencil(nearestNeighborStencil[4](), lat)

# Direct construction from lattice (uses nearest-neighbor by default)
let stencil2 = newLatticeStencil(lat)

Neighbor Access

Inside an each loop, use the shift API:

for n in each 0..<vC.numSites():
  let fwd_x = stencil.fwd(n, 0)   # Forward neighbor in x
  let bwd_x = stencil.bwd(n, 0)   # Backward neighbor in x
  let fwd_t = stencil.fwd(n, 3)   # Forward neighbor in t
  vC[n] = vA[fwd_x] + vA[bwd_x] - 2.0 * vA[n]

Path-Based Stencils

For Wilson loops and transport paths:

# Plaquette path: fwd(mu), fwd(nu), bwd(mu), bwd(nu)
let path = plaquettePath(0, 1)  # xy-plaquette

# Rectangle path
let rect = rectanglePath(0, 1, 2, 1)  # 2×1 rectangle in xy-plane

# Convert path to stencil pattern
let pattern = pathToStencil[4](path)

Direction Types

Type-safe direction indexing:

let d = Direction(0)
echo d    # 0
let sd = forward(d)    # SignedDirection(dir: 0, sign: +1)
let bd = backward(d)   # SignedDirection(dir: 0, sign: -1)

# Named constants
echo X   # Direction(0)
echo Y   # Direction(1)
echo Z   # Direction(2)
echo T   # Direction(3)

# Iterators
for d in directions(4):
  echo d  # 0, 1, 2, 3

for sd in allDirections(4):
  echo sd  # ±0, ±1, ±2, ±3

Backend Detection

The stencil system auto-detects the active backend at construction time:

BackendStencilBackendOffset format
OpenCLsbOpenCLFlat offsets for GPU buffers
SYCLsbSyclFlat offsets for GPU buffers
OpenMP (SIMD)sbSimdOuter/lane offset pairs
ScalarsbScalarFlat coordinate offsets

Module Reference

ModuleDescription
lattice/latticeconceptLattice[D] concept definition
lattice/simplecubiclatticeSimpleCubicLattice[D] implementation
lattice/stencilUnified stencil operations
lattice/indexingCoordinate conversion utilities