# VUMPS example, 2d heisenberg model interaction term

**URL:** <https://itensor.discourse.group/t/vumps-example-2d-heisenberg-model-interaction-term/2052>\
**Category:** DMRG and Numerical Methods\
**Tags:** julia\
**Created:** [October 11, 2024, 1:34am UTC](https://itensor.discourse.group/t/vumps-example-2d-heisenberg-model-interaction-term/2052 "2024-10-11T01:34:15Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![sunam](https://avatars.discourse-cdn.com/v4/letter/s/77aa72/32.png) [@sunam](https://itensor.discourse.group/u/sunam)\
**Post date:** [October 11, 2024, 1:34am UTC](https://itensor.discourse.group/t/vumps-example-2d-heisenberg-model-interaction-term/2052/1 "2024-10-11T01:34:15Z")

</div>

The following is an example of creating a 2D-Heisenberg model for VUMPS calculations. However, I don’t quite understand the part where the interaction positions are specified when creating the `opsum`.  
First, due to the use of `mod`, values corresponding to position 0 are included. What does the value 0 for site mean? When width=4, vertical interaction (3, 0) occurs but interaction (3,4) is absent.

Second, vertical hopping is defined only on the first line, but shouldn’t vertical hopping also be specified on the second line?

([ITensorInfiniteMPS.jl/examples/vumps/vumps\_2d\_heisenberg.jl at main · ITensor/ITensorInfiniteMPS.jl · GitHub](https://github.com/ITensor/ITensorInfiniteMPS.jl/blob/main/examples/vumps/vumps_2d_heisenberg.jl))

```julia
using ITensorInfiniteMPS
using ITensors, ITensorMPS
N = width # Number of sites in the unit cell

include(
  joinpath(
    pkgdir(ITensorInfiniteMPS), "examples", "vumps", "src", "vumps_subspace_expansion.jl"
  ),
)

maxdim = 256 # Maximum bond dimension
cutoff = 1e-6 # Singular value cutoff when increasing the bond dimension
max_vumps_iters = 100 # Maximum number of iterations of the VUMPS algorithm at each bond dimension
vumps_tol = 1e-4
conserve_qns = true
solver_tol = (x -> x / 10)
outer_iters = 10 # Number of times to increase the bond dimension
width = 4

initstate(n) = isodd(n) ? "↑" : "↓"
s = infsiteinds("S=1/2", N; conserve_qns, initstate)
ψ = InfMPS(s, initstate)

function ITensorInfiniteMPS.unit_cell_terms(::Model"heisenberg2D"; width)
  opsum = OpSum()
  for i in 1:width
    # Vertical
    opsum += -0.5, "S+", i, "S-", mod(i + 1, width)
    opsum += -0.5, "S-", i, "S+", mod(i + 1, width)
    opsum += "Sz", i, "Sz", mod(i + 1, width)
    # Horizontal
    opsum += -0.5, "S+", i, "S-", i + width
    opsum += -0.5, "S-", i, "S+", i + width
    opsum += "Sz", i, "Sz", i + width
  end
  return opsum
end

```

---

<div class="post-metadata">

**Author:** ![ryanlevy](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/ryanlevy/32/150_2.png) [@ryanlevy](https://itensor.discourse.group/u/ryanlevy)\
**Post date:** [October 11, 2024, 12:04pm UTC](https://itensor.discourse.group/t/vumps-example-2d-heisenberg-model-interaction-term/2052/2 "2024-10-11T12:04:44Z")

</div>

From what I can tell, interactions with a site \<= 0 are ignored, so there is a mistake in this example.  
It should be

```julia
function ITensorInfiniteMPS.unit_cell_terms(::Model"heisenberg2D"; width)
  opsum = OpSum()
  for i in 1:width
    # Vertical
    opsum += -0.5, "S+", i, "S-", i + 1
    opsum += -0.5, "S-", i, "S+", i + 1
    opsum += "Sz", i, "Sz", i + 1
    # Horizontal
    opsum += -0.5, "S+", i, "S-", i + width
    opsum += -0.5, "S-", i, "S+", i + width
    opsum += "Sz", i, "Sz", i + width
  end
  return opsum
end

```

---

<div class="post-metadata">

**Author:** ![sunam-Jeon](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/sunam-jeon/32/503_2.png) [@sunam-Jeon](https://itensor.discourse.group/u/sunam-Jeon)\
**Post date:** [October 13, 2024, 7:29am UTC](https://itensor.discourse.group/t/vumps-example-2d-heisenberg-model-interaction-term/2052/3 "2024-10-13T07:29:29Z")

</div>

If width=4 case, why we don’t consider the vertical interactions between (5,6), (6,7), (7,8), (8,9)…

---

<div class="post-metadata">

**Author:** ![ryanlevy](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/ryanlevy/32/150_2.png) [@ryanlevy](https://itensor.discourse.group/u/ryanlevy)\
**Post date:** [October 13, 2024, 4:08pm UTC](https://itensor.discourse.group/t/vumps-example-2d-heisenberg-model-interaction-term/2052/4 "2024-10-13T16:08:09Z")

</div>

If you have a width=4 case and a unit cell size of N=width (4 sites), we’ll have in the unit cell from the `# vertical` section bonds

```auto
(1,2), (2,3), (3,4)

```

And from the `# horizontal` section

```auto
(1,5), (2,6), (3,7), (4,8)

```

The sites `5,6,7,8` are all in the next unit cell, so we don’t need to consider them here, only the connections within and out of our unit cell. If you want an 8+ site unit cell, then those would be created automatically from the site shifting tools within ITensorInfiniteMPS.

To see this, let’s just switch to Sz\*Sz and make it the coupling larger in one direction

```julia
function ITensorInfiniteMPS.unit_cell_terms(::Model"heisenberg2D"; width)
  opsum = OpSum()
  for i in 1:width
    # Vertical
    a = 100
    opsum += a,"Sz", i, "Sz", i+1
    # Horizontal
    opsum += "Sz", i, "Sz", i + width
  end
  return opsum
end

```

We can see the terms of the unit cell

```julia
julia> ITensorInfiniteMPS.unit_cell_terms(model;width)
sum(
  100.0 Sz(1,) Sz(2,)
  1.0 Sz(1,) Sz(5,)
  100.0 Sz(2,) Sz(3,)
  1.0 Sz(2,) Sz(6,)
  100.0 Sz(3,) Sz(4,)
  1.0 Sz(3,) Sz(7,)
  100.0 Sz(4,) Sz(5,)
  1.0 Sz(4,) Sz(8,)
)

```

And if we want to make it into a finite cell of 3 unit cells (a total of 3\*width=12 sites), we can see we get

```julia
julia> ITensorInfiniteMPS.opsum_finite(model,width*3; width)
sum(
  100.0 Sz(1,) Sz(2,)
  1.0 Sz(1,) Sz(5,)
  100.0 Sz(2,) Sz(3,)
  1.0 Sz(2,) Sz(6,)
  100.0 Sz(3,) Sz(4,)
  1.0 Sz(3,) Sz(7,)
  100.0 Sz(4,) Sz(5,)
  1.0 Sz(4,) Sz(8,)
  100.0 Sz(5,) Sz(6,)
  1.0 Sz(5,) Sz(9,)
  100.0 Sz(6,) Sz(7,)
  1.0 Sz(6,) Sz(10,)
  100.0 Sz(7,) Sz(8,)
  1.0 Sz(7,) Sz(11,)
  100.0 Sz(8,) Sz(9,)
  1.0 Sz(8,) Sz(12,)
  100.0 Sz(9,) Sz(10,)
  100.0 Sz(10,) Sz(11,)
  100.0 Sz(11,) Sz(12,)
)

```

which has the terms you’re considering

(Also note this example doesn’t have periodic boundaries for the y direction of course)

---

<div class="post-metadata">

**Author:** ![ryanlevy](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/ryanlevy/32/150_2.png) [@ryanlevy](https://itensor.discourse.group/u/ryanlevy)\
**Post date:** [October 13, 2024, 5:00pm UTC](https://itensor.discourse.group/t/vumps-example-2d-heisenberg-model-interaction-term/2052/6 "2024-10-13T17:00:25Z")

</div>

In the 3 unit cell output, (5,6), (6,7) and (6,8) are also included. Both these and the (9,10), (10,11), and (11,12) are generated by shifting the original unit cell over.

The important thing is that those terms on only _within_ the unit cell, and so we dont need to include the next cell’s intra-cell terms ((5,6) etc) as they will be generated when forming the supercell (shifting the unit cell over).  
In other words, we take the original unit cell

```auto
sum(
  100.0 Sz(1,) Sz(2,)
  1.0 Sz(1,) Sz(5,)
  100.0 Sz(2,) Sz(3,)
  1.0 Sz(2,) Sz(6,)
  100.0 Sz(3,) Sz(4,)
  1.0 Sz(3,) Sz(7,)
  100.0 Sz(4,) Sz(5,)
  1.0 Sz(4,) Sz(8,)
)

```

and add `N=width` here to everything to generate the next unit cell, so (1,2) → (1+N, 2+N)= (5,6), and so on. Then again for the third cell. If we included (5,6) in the original definition, it might be double counted.  
If we define the `unit_cell_terms` properly, just by shifting the cell we should be able to generate the appropriate terms without listing them explicitly, but you can always enlarge the unit cell to list them explicitly too.

---

<div class="post-metadata">

**Author:** ![sunam-Jeon](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/sunam-jeon/32/503_2.png) [@sunam-Jeon](https://itensor.discourse.group/u/sunam-Jeon)\
**Post date:** [October 13, 2024, 5:34pm UTC](https://itensor.discourse.group/t/vumps-example-2d-heisenberg-model-interaction-term/2052/7 "2024-10-13T17:34:00Z")

</div>

I understand it: In the case of a single unit cell, the interactions (1,2), (2,3), and (3,4) automatically generate the interactions (5,6), (6,7), and (7,8) when forming the next unit cell.

Thanks!

---

<div class="post-metadata">

**Author:** ![ryanlevy](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/ryanlevy/32/150_2.png) [@ryanlevy](https://itensor.discourse.group/u/ryanlevy)\
**Post date:** [October 14, 2024, 3:59pm UTC](https://itensor.discourse.group/t/vumps-example-2d-heisenberg-model-interaction-term/2052/8 "2024-10-14T15:59:00Z")

</div>

Thanks again for pointing this out, the latest commit now has a fixed example that has a proper 2D model (with or without cylindrical boundaries)

> <https://github.com/ITensor/ITensorInfiniteMPS.jl/blob/main/examples/vumps/vumps_2d_heisenberg.jl#L34>

---

<div class="post-metadata">

**Author:** ![cfengno1](https://avatars.discourse-cdn.com/v4/letter/c/7feea3/32.png) [@cfengno1](https://itensor.discourse.group/u/cfengno1)\
**Post date:** [October 30, 2024, 12:15pm UTC](https://itensor.discourse.group/t/vumps-example-2d-heisenberg-model-interaction-term/2052/9 "2024-10-30T12:15:34Z")

</div>

Hi Ryan，

Thank you for posting the example code.

In the vertical bonds, why is there a bond between width and width+1? Shoud not we limit i between 1 and width-1 for the vertical bonds?

Best,  
Feng

---

<div class="post-metadata">

**Author:** ![ryanlevy](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/ryanlevy/32/150_2.png) [@ryanlevy](https://itensor.discourse.group/u/ryanlevy)\
**Post date:** [October 30, 2024, 12:44pm UTC](https://itensor.discourse.group/t/vumps-example-2d-heisenberg-model-interaction-term/2052/10 "2024-10-30T12:44:02Z")

</div>

Yes great point, thank you!  
I think some things got lost in removing the `mod`, I’ll open a PR to update the code shortly
