Skip to main content

Common Spin Models

Transverse Field Ising Model

The Transverse field Ising Model (TFIM),

H=Jj,kS^jzS^kz+hjS^jx H = J\sum_{\langle j,k\rangle} \hat{S}^z_j \hat{S}^z_k + h\sum_j \hat{S}_j^x

is the prototypical model of a quantum phase transition. In the above we consider the case of a nearest neighbour interaction, but generalizations beyond nearest neighbours are often considered.

var exchange = coefficient("J", 1.0)
var field = coefficient("h", 0.5)

One Dimension

Nearest Neighbour Chain

var length = 32
var chain_tfim = model(lattice("chain", [length]))
chain_tfim.add(neighbourhood_rule("nn", 1)) // nearest neighbour interaction.
chain_tfim.add(exchange)
chain_tfim.add(field)
chain_tfim.add(term("J", [Z, Z], "nn"))
chain_tfim.add(term("h", X, "onsite"))

We can easily extend the above example to next-nearest neighbours,

chain_tfim.add(neighbourhood_rule("nnn", 2))
chain_tfim.add(term("J", [Z, Z], "nnn"))

Two Dimensions

Triangular Lattice

var lx = 4
var ly = 8
var triangular_tfim = model(lattice("triangular", [lx, ly]))
triangular_tfim.add(neighbourhood_rule("nnx", [1,0]))
triangular_tfim.add(neighbourhood_rule("nny", [0,1]))
triangular_tfim.add(exchange)
triangular_tfim.add(field)
triangular_tfim.add(term("J", [Z, Z], "nnx"))
triangular_tfim.add(term("J", [Z, Z], "nny"))
triangular_tfim.add(term("h", X, "onsite"))

Square Lattice

var lx = 4
var ly = 8
var square_tfim = model(lattice("square", [lx, ly]))
square_tfim.add(neighbourhood_rule("nn", 1)) // nearest neighbour interaction.
square_tfim.add(exchange)
square_tfim.add(field)
square_tfim.add(term("J", [Z, Z], "nn"))
square_tfim.add(term("h", X, "onsite"))

Honeycomb Lattice

The Honeycomb lattice is not a Bravais lattice. In order to define a nearest neighbour coupling we need to include both an inter and intra unit cell interaction.

var lx = 4
var ly = 4
var honeycomb_tfim = model(lattice("honeycomb", [lx, ly]))
honeycomb_tfim.add(exchange)
honeycomb_tfim.add(field)
honeycomb_tfim.add(neighbourhood_rule("inter_nn_x", [0,1]))
honeycomb_tfim.add(neighbourhood_rule("inter_nn_y", [1,0]))
honeycomb_tfim.add(neighbourhood_rule("intra_nn", lattice_coordinate([0,0], 1)))

honeycomb_tfim.add(term("J", [Z, Z], "inter_nn_x"))
honeycomb_tfim.add(term("J", [Z, Z], "inter_nn_y"))
honeycomb_tfim.add(term("J", [Z, Z], "intra_nn"))
honeycomb_tfim.add(term("h", X, "onsite"))

Heisenberg Model

The nearest neighbour Heisenberg model is given by,

H=Jj,kSjSk H = J \sum_{\langle j,k\rangle} \vec{S}_j\cdot\vec{S}_k

where, S=(Sx,Sy,Sz)\vec{S} = (S^x, S^y, S^z).

One Dimension

Chain

var length = 32
var heisenberg_chain = model(lattice("chain", [length]))
heisenberg_chain.add(coefficient("J", 1.0))
heisenberg_chain.add(neighbourhood_rule("nn", 1))
heisenberg_chain.add(term("J", [X, X], "nn"))
heisenberg_chain.add(term("J", [Y, Y], "nn"))
heisenberg_chain.add(term("J", [Z, Z], "nn"))

J1J_1-J2J_2 Model

The above model can be augmented with frustration by adding a next nearest-neighbour exchange

var length = 32
var heisenberg_chain = model(lattice("chain", [length]))
heisenberg_chain.add(coefficient("J1", 1.0))
heisenberg_chain.add(coefficient("J2", 1.0))
heisenberg_chain.add(neighbourhood_rule("nn", 1))
heisenberg_chain.add(neighbourhood_rule("nnn", 2))
heisenberg_chain.add(term("J1", [X, X], "nn"))
heisenberg_chain.add(term("J1", [Y, Y], "nn"))
heisenberg_chain.add(term("J1", [Z, Z], "nn"))

heisenberg_chain.add(term("J2", [X, X], "nnn"))
heisenberg_chain.add(term("J2", [Y, Y], "nnn"))
heisenberg_chain.add(term("J2", [Z, Z], "nnn"))

Two Dimensions

Square lattice

On a square lattice we have,

var lx = 4
var ly = 4
var heisenberg_square = model(lattice("square", [lx, ly]))
heisenberg_square.add(coefficient("J", 1.0))
heisenberg_square.add(neighbourhood_rule("nnx", [1,0]))
heisenberg_square.add(neighbourhood_rule("nny", [0,1]))
heisenberg_square.add(term("J", [X, X], "nnx"))
heisenberg_square.add(term("J", [Y, Y], "nnx"))
heisenberg_square.add(term("J", [Z, Z], "nnx"))
heisenberg_square.add(term("J", [X, X], "nny"))
heisenberg_square.add(term("J", [Y, Y], "nny"))
heisenberg_square.add(term("J", [Z, Z], "nny"))

Kitaev Model with Arbitrary Field

The Kitaev interaction is a bond-dependent Ising interaction first defined on the honeycomb lattice for the purpose of studying anyonic excitations. It's been shown that spin orbit coupling can introduce Kitaev like interactions in certain real materials. The model has also been studied on other geometries, notably the ladder and the chain. The Hamiltonian is usually written,

HK=j,kγKγSjγSkγ,γx,y,z H_{\text{K}} = \sum_{\langle j,k \rangle_\gamma} K_\gamma S_j^\gamma S_k^\gamma, \quad \gamma \in {x,y,z}

Two Dimensions

Honeycomb

var lx = 4
var ly = 4
var kitaev_honeycomb = model(lattice("honeycomb", [lx, ly]))
var rule = neighbourhood_rule
kitaev_honeycomb.add(rule("x", [1,0]))
kitaev_honeycomb.add(rule("y", [0,1]))
kitaev_honeycomb.add(rule("z", lattice_coordinate([0,0], 1)))
kitaev_honeycomb.add(coefficient("Kx", 1.0))
kitaev_honeycomb.add(coefficient("Ky", 1.0))
kitaev_honeycomb.add(coefficient("Kz", 1.0))

kitaev_honeycomb.add(term("Kx", [X, X], "x"))
kitaev_honeycomb.add(term("Ky", [Y, Y], "y"))
kitaev_honeycomb.add(term("Kz", [Z, Z], "z"))

In real materials, spin-orbit coupling leads to additional, off-diagonal exchange interactions,

HΓ=Γj,kγSjαSkβ+SjβSkα H_{\Gamma} = \Gamma \sum_{\langle j, k\rangle_\gamma} S^{\alpha}_j S^{\beta}_k + S^{\beta}_j S^{\alpha}_k

We can add this interaction to our model as follows.

kitaev_honeycomb.add(coefficient("G", 1.0))
kitaev_honeycomb.add(term("G", [Y, Z], "x"))
kitaev_honeycomb.add(term("G", [Z, Y], "x"))
kitaev_honeycomb.add(term("G", [Z, X], "y"))
kitaev_honeycomb.add(term("G", [X, Z], "y"))
kitaev_honeycomb.add(term("G", [X, Y], "z"))
kitaev_honeycomb.add(term("G", [Y, X], "z"))

Ladder

var length = 16
var rung = lattice_coordinate([1,0])
var leg = lattice_coordinate([0,1])


var kitaev_ladder = model(lattice("square", [2, length], [boundary_condition.open, boundary_condition.open]))
kitaev_ladder.add(neighbourhood_rule("x_leg", leg, fun(x) { return !bool(integer(sum(x.primitive_vector())) % 2)}))
kitaev_ladder.add(neighbourhood_rule("y_leg", leg, fun(x) { return bool(integer(sum(x.primitive_vector())) % 2) }))
kitaev_ladder.add(neighbourhood_rule("rung", rung))

// Kitaev interactions
kitaev_ladder.add(coefficient("K", 1.0))
kitaev_ladder.add(term("K", [X, X], "x_leg"))
kitaev_ladder.add(term("K", [Y, Y], "y_leg"))
kitaev_ladder.add(term("K", [Z, Z], "rung"))

// Angles for the applied field
var theta = 0.25 * pi
var phi = 0.0
kitaev_ladder.add(coefficient("hx", cos(theta)*sin(phi)))
kitaev_ladder.add(coefficient("hy", sin(theta)*sin(phi)))
kitaev_ladder.add(coefficient("hz", cos(phi)))
kitaev_ladder.add(term("hx", X, "onsite"))
kitaev_ladder.add(term("hy", Y, "onsite"))
kitaev_ladder.add(term("hz", Z, "onsite"))

Documentation Contributors

James Lambert