Skip to main content

Lattice

In the concepts entry we saw how the lattice class is intended to work with other aleph objects at a high level. Here we look at some recipes for common uses, starting with an overview of all the ways a lattice can be built.

Building a lattice

The most direct way to build a Bravais lattice is by providing the primitive vectors, dimensions, and boundary conditions directly to the lattice factory.

var xdim = 4
var ydim = 10
var bcs = [boundary_condition.periodic, boundary_condition.open]
var my_lattice = lattice(matrix([[1,0],[0,1]], as_real), [xdim,ydim], bcs)

We can then build up the atomic basis by providing the position vectors,

my_lattice.add_basis([0.0, 0.5])

The lattice can be extended into a new dimension, provided that the new dimension isn't in the span of the existing primitive vectors,

my_lattice.add_dimension([1.0, 1.0, 1.0], 10)

printing the above lattice now gives,

primitive vectors (arranged by row):
1 0 0
0 1 0
1 1 1
basis primitive_indices (arranged by row):
0 0 0
dimensions = (4, 10, 10)
boundaries = (open, open, open)
basis size = 1
unit cells = 400
sites = 400

Iterating over coordinates

It's often convenient to loop over the sites of a lattice for the purpose of performing a measurement or modifying a state. We can loop over the coordinates in a lattice using,

for(coord : lattice_range(lattice)) {
print(coord)
}

Initializing states

Néel State

Initializing a Néel state can be done straightforwardly on any Bravais lattice by flipping the spins on one of the sublattices.

var lx = 6
var ly = 6
var square = lattice("square", [lx,ly])
var state = Qbit(lx*ly)

for(coord : lattice_range(square))
{
if(sum(coord.primitive_indices) % 2 == 0) {
state.flip(square.to_index(coord))
}
}

Documentation Contributors

James Lambert