VUMPS for multi-site unit cells

Hello Miles and Matt,

I’ve been trying to under the VUMPS code for the Heisenberg model and then apply to my own multi-site unit cell model.

My first question is concerned with defining the Model using

function unit_cell_terms(::Model"MyModel")
    opsum = OpSum()
    opsum += ....
end

Assuming we have a unit cell consisting of 4 sites, and the interaction term O_1O_2O_3 spans 3 neighboring sites, then if I follow the Heisenberg model definition, I would put

opsum += O, 1, O, 2, O, 3
opsum += O, 2, O, 3, O, 4

Would ITensor automatically include the inter-cell terms like O_3O_4O_5 and O_4O_5O_6? It seems that it would from the given Heisenberg example, but I just want to double check.

My second question is about the following part for the Heisenberg VUMPS:

function expect_two_site(ψ::InfiniteCanonicalMPS, h::ITensor, n1n2)  
  n1, n2 = n1n2
  ϕ = ψ.AL[n1] * ψ.AL[n2] * ψ.C[n2]
  return inner(ϕ, apply(h, ϕ))				
end

function expect_two_site(ψ::InfiniteCanonicalMPS, h::MPO, n1n2)
  return expect_two_site(ψ, contract(h), n1n2)             
end

bs = [(1, 2), (2, 3)]
energy_infinite = map(b -> expect_two_site(ψ, H[b], b), bs) 

It seems to me that the defined function expect_two_site() only works for systems with two-site unit cell. If it’s my 4-site unit cell system, then would it be modified like the following?

function expect_four_site(ψ::InfiniteCanonicalMPS, h::ITensor, n1n2n3n4)  
  n1, n2, n3, n4 = n1n2n3n4      ##  n1n2n3n4 is a four-element array
  ϕ = ψ.AL[n1] * ψ.AL[n2]* ψ.C[n2] * ψ.AL[n3]* ψ.C[n3]* ψ.AL[n4]* ψ.C[n4]
  return inner(ϕ, apply(h, ϕ))				
end

function expect_four_site(ψ::InfiniteCanonicalMPS, h::MPO, n1n2n3n4)
  return expect_four_site(ψ, contract(h), n1n2n3n4)             
end

bs = [(1, 2, 3, 4), (2, 3, 4, 5), (3, 4, 5, 6), (4, 5, 6, 7)]
energy_infinite = map(b -> expect_four_site(ψ, H[b], b), bs) 

Thanks a lot for your time and I apologize for the long question.
-Meng

1 Like

You should include all unique terms that connect to the first unit cell, so O_1 O_2 O_3, O_2 O_3 O_4, O_3 O_4 O_5, and O_4 O_5 O_6.

The expectation value function would depend on the support of your Hamiltonian, it looks like your Hamiltonian has support on 3 sites so you should use a 3-site wavefunction. Also, you are using too many ψ.C terms (only one is required to get the wavefunction), the expectation value would be:

function expect_three_site(ψ::InfiniteCanonicalMPS, h::ITensor, n1n2n3)  
  n1, n2, n3 = n1n2n3
  ϕ = ψ.AL[n1] * ψ.AL[n2]* ψ.AL[n3] * ψ.C[n3]
  return inner(ϕ, apply(h, ϕ))				
end

Thank you Matt. Then how come for the Heisenberg model the inter-unit-cell terms are not included?

  opsum += 0.5, "S+", 1, "S-", 2
  opsum += 0.5, "S-", 1, "S+", 2
  opsum += "Sz", 1, "Sz", 2

That is probably for a single-site unit cell. If I remember correctly, the package internally will take the definition for a single site unit cell and repeat it if you use a multisite unit cell, so you don’t have to make a new definition for all unit cell lengths. Of course the unit cell that you choose should be commensurate with the “primitive” unit cell defined implicitly by the function unit_cell_terms.

2 Likes

Hi Matt, I tried out different ways of defining the interactions. It seems that including all the O_1O_2O_3,O_2O_3O_4,O_3O_4O_5,O_4O_5O_6 would give me the error “MethodError: no method matching translatecell(::ITensorInfiniteMPS.var”#_shift_cell#149"{Int64}, ::Scaled{ComplexF64, Prod{Op}}, ::Int64)
". If I only include O_1O_2O_3, then the code runs fine. More specifically, I tried with the three-site density-density interaction in the Hubbard model:

opsum += "Ntot", 1, "Ntot", 2, "Ntot", 3

Hi Matt,

I realize your attention is probably focused on the new TensorNetworks.jl, but could you point to where this repetition is occurring? I’ve been having the exact same question about whether or not to include inter-cell terms.

The function being used internally is ITensorInfiniteMPS.opsum_infinite, for example:

using ITensors
using ITensorInfiniteMPS

ITensorInfiniteMPS.opsum_infinite(Model("heisenberg"), 3)

outputs:

sum(
  0.5 S+(1,) S-(2,)
  0.5 S-(1,) S+(2,)
  1.0 Sz(1,) Sz(2,)
  0.5 S+(2,) S-(3,)
  0.5 S-(2,) S+(3,)
  1.0 Sz(2,) Sz(3,)
  0.5 S+(3,) S-(4,)
  0.5 S-(3,) S+(4,)
  1.0 Sz(3,) Sz(4,)
)

That’s being used here: ITensorInfiniteMPS.jl/src/models/models.jl at 27fd437b38acc5331900d4e857a054adf5a6d864 · ITensor/ITensorInfiniteMPS.jl · GitHub

I’ve lost track of this issue, if someone could post a minimal runnable example of something that isn’t working, I may be able to investigate it or point someone towards how it might be fixed.

1 Like

In terms of needing to include inter-cell terms, you should include inter-cell terms crossing one boundary of the minimal unit cell of your model, and you can see that ITensorInfiniteMPS.opsum_infinite will then repeat that minimal unit cell for whatever number of sites you specify when you go to build the infinite MPO.

1 Like

@mtfishman Apologies for the delayed response, I didn’t see a notification. The issue was that the example had N=2 so it was unclear the boundary was included. The call_length in the link you provided explains how the repetition works. Thanks!