Skip to content

Commit d0efafc

Browse files
authored
Fix 2D Heisenberg Example (#95)
1 parent 33c38cf commit d0efafc

File tree

3 files changed

+140
-19
lines changed

3 files changed

+140
-19
lines changed

examples/vumps/vumps_2d_heisenberg.jl

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,6 @@ initstate(n) = isodd(n) ? "↑" : "↓"
3131
s = infsiteinds("S=1/2", N; conserve_qns, initstate)
3232
ψ = InfMPS(s, initstate)
3333

34-
function ITensorInfiniteMPS.unit_cell_terms(::Model"heisenberg2D"; width, yperiodic)
35-
opsum = OpSum()
36-
for i in 1:width
37-
# Vertical
38-
opsum -= 0.5, "S+", i, "S-", i + 1
39-
opsum -= 0.5, "S-", i, "S+", i + 1
40-
opsum += "Sz", i, "Sz", i + 1
41-
# Horizontal
42-
opsum -= 0.5, "S+", i, "S-", i + width
43-
opsum -= 0.5, "S-", i, "S+", i + width
44-
opsum += "Sz", i, "Sz", i + width
45-
end
46-
if yperiodic
47-
opsum -= 0.5, "S+", 1, "S-", width
48-
opsum -= 0.5, "S-", 1, "S+", width
49-
opsum += "Sz", 1, "Sz", width
50-
end
51-
return opsum
52-
end
5334
model = Model("heisenberg2D")
5435

5536
# Form the Hamiltonian
@@ -75,6 +56,11 @@ subspace_expansion_kwargs = (cutoff=cutoff, maxdim=maxdim)
7556

7657
energy_infinite = expect(ψ, H)
7758
@show energy_infinite
59+
@show sum(energy_infinite) / width
7860

61+
energy_approx_exact = reference(model, Observable("energy"); width, yperiodic)
62+
@show energy_approx_exact
63+
64+
@show isapprox(sum(energy_infinite) / width, energy_approx_exact, atol=1e-4)
7965
## using JLD2
8066
## jldsave("infmps.jld2"; ψ)

src/models/heisenberg.jl

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,49 @@ function reference(::Model"heisenberg", ::Observable"energy"; N=∞)
2525
correction = 1 + 0.375 / log(N)^3
2626
return (E∞ - Eᶠⁱⁿⁱᵗᵉ * correction) / (2N)
2727
end
28+
29+
function unit_cell_terms(::Model"heisenberg2D"; width, yperiodic)
30+
opsum = OpSum()
31+
for i in 1:width
32+
# Vertical
33+
if (i < width) || (yperiodic && width > 2)
34+
opsum -= 0.5, "S+", i, "S-", mod(i, width) + 1
35+
opsum -= 0.5, "S-", i, "S+", mod(i, width) + 1
36+
opsum += "Sz", i, "Sz", mod(i, width) + 1
37+
end
38+
# Horizontal
39+
opsum -= 0.5, "S+", i, "S-", i + width
40+
opsum -= 0.5, "S-", i, "S+", i + width
41+
opsum += "Sz", i, "Sz", i + width
42+
end
43+
return opsum
44+
end
45+
46+
"""
47+
reference(::Model"heisenberg2D", ::Observable"energy"; width, yperiodic)
48+
49+
Report the reference isotropic 2D square heisenberg ground energy per site for length `N`.
50+
Taken from [1,2]. Note that periodic results have an errorbar of ~1e-4 - 1e-3
51+
52+
[1] Ramos and Xavier. "N-leg spin-S Heisenberg ladders:
53+
A density-matrix renormalization group study"
54+
Phys. Rev. B 89, 094424 - Published 27 March 2014
55+
[2] Frischmuth, Ammon, and Troyer. "Susceptibility and low-temperature
56+
thermodynamics of spin-½ Heisenberg ladders"
57+
Phys. Rev. B 54, R3714(R) - Published 1 August 1996
58+
"""
59+
function reference(::Model"heisenberg2D", ::Observable"energy"; width, yperiodic)
60+
if width > 6
61+
error("Ladders of width greater than 6 are not in reference data")
62+
end
63+
64+
if yperiodic
65+
(width == ∞) && return -0.66931
66+
energies = [-0.4432, -0.5780, -0.6006, -0.6187, -0.6278, -0.635]
67+
return energies[width]
68+
else
69+
(width == ∞) && return -0.6768
70+
energies = [-0.4431471, -0.578043140180, -0.600537, -0.618566, -0.62776, -0.6346]
71+
return energies[width]
72+
end
73+
end

test/test_modelMPOs.jl

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using ITensors, ITensorMPS
2+
using ITensorInfiniteMPS
3+
using Test
4+
5+
@testset verbose = true "Heisenberg Model Test" begin
6+
cell_widths = [2, 3, 4, 5]
7+
@testset "cell_width=$width" for width in cell_widths
8+
model = Model("heisenberg")
9+
os = ITensorInfiniteMPS.opsum_finite(model, width;)
10+
11+
connections = []
12+
for term in os
13+
push!(connections, sort(ITensors.sites(term)))
14+
end
15+
for i in 1:(width - 1)
16+
@test [i, i + 1] connections
17+
end
18+
end
19+
end
20+
21+
@testset verbose = true "Heisenberg2D Model Test" begin
22+
widths = [2, 3, 4, 5, 6]
23+
cell_widths = [2, 3, 4, 5]
24+
@testset "cell_width=$cell_width width=$width" for cell_width in cell_widths,
25+
width in widths
26+
27+
model = Model("heisenberg2D")
28+
29+
os = ITensorInfiniteMPS.opsum_finite(model, cell_width * width; width, yperiodic)
30+
31+
connections = []
32+
for term in os
33+
push!(connections, ITensors.sites(term))
34+
end
35+
for col in 1:(cell_width - 1)
36+
for row in 1:(width - 1)
37+
i = (col - 1) * width + row
38+
@test [i, i + 1] connections
39+
@test [i, i + width] connections
40+
end
41+
(yperiodic && width > 2) && @test [i, i + width - 1] connections
42+
end
43+
# the above forgets the last horizontal bond
44+
for col in 1:(cell_width - 1)
45+
i = (col - 1) * width + width
46+
@test [i, i + width] connections
47+
end
48+
end
49+
end
50+
51+
@testset verbose = true "Ising Model Test" begin
52+
cell_widths = [2, 3, 4, 5]
53+
@testset "cell_width=$width" for width in cell_widths
54+
model = Model("ising")
55+
os = ITensorInfiniteMPS.opsum_finite(model, width;)
56+
57+
connections = []
58+
for term in os
59+
push!(connections, sort(ITensors.sites(term)))
60+
end
61+
for i in 1:(width - 1)
62+
@test [i, i + 1] connections
63+
@test [i] connections
64+
end
65+
@test [width] connections
66+
end
67+
end
68+
69+
@testset verbose = true "Hubbard Model Test" begin
70+
t, U = 1.0, 4.0
71+
cell_widths = [2, 3, 4, 5]
72+
@testset "cell_width=$width" for width in cell_widths
73+
model = Model("hubbard")
74+
os = ITensorInfiniteMPS.opsum_finite(model, width; t, U)
75+
76+
connections = []
77+
for term in os
78+
push!(connections, ITensors.sites(term))
79+
end
80+
for i in 1:(width - 1)
81+
@test [i, i + 1] connections
82+
@test [i + 1, i] connections
83+
@test [i] connections
84+
end
85+
@test [width] connections
86+
end
87+
end
88+
89+
nothing

0 commit comments

Comments
 (0)