0 votes
asked by (150 points)

Hi, It's not a long time since I started using ITensor, I want to realize Kondo-Heisenberg model on ITensor-3. The model is :
H=\sum{\langle i,j\rangle\sigma}\text{\ensuremath{\left(c{i\sigma}^{\dagger}c{j\sigma}+h.c.\right)}}
{h}\sum{\langle i,j\rangle}S{i}\cdot S_{j}

I referred the example enter link description here and here is my code

#include "itensor/all.h"
using namespace itensor;
using kondoLattice = MixedSiteSet<ElectronSite, SpinHalfSite>;
int main(int argc, char* argv[])

   auto L = 10; 
   auto N = 2 * L;
   auto t = 1.0;
   auto Jk = 1.0;
   auto Jh = 1.0;

   auto Npart = 10;

   //auto sites = kondoLattice(N,{"ConserveQNs=", false});
  auto sites = kondoLattice(N);

  auto ampo = AutoMPO(sites);

   for (int j = 1; j < N-2; j += 2)
      ampo += -t, "Cup", j, "Cdagup", j+2;
      ampo += -t, "Cdagup", j, "Cup", j+2;

      ampo += -t, "Cdn", j, "Cdagdn", j+2;
      ampo += -t, "Cdagdn", j, "Cdn", j+2;

  for (int j = 1; j < N; j += 2)
      ampo += 0.5 * Jk, "CSp", j, "Sm", j+1;
      ampo += 0.5 * Jk, "CSm", j, "Sp", j+1;
      ampo += Jk, "CSz", j, "Sz", j+1;

  for (int j = 2; j < N-1; j += 2)
      ampo += 0.5 * Jh, "Sp", j, "Sm", j+2;
      ampo += 0.5 * Jh, "Sm", j, "Sp", j+2;
      ampo += Jh, "Sz", j, "Sz", j+2;

 auto H = toMPO(ampo);

 auto state = InitState(sites);

 int p = Npart;

 for (int j = N; j > 0; j--)
     int i = (j -1) / 2;

     if(j % 2 != 0)
         if (p > i+1)
             printfln("Doublely occupying site", j);

             state.set(j, "UpDn");
             p -= 2;
         else if (p >0)
             printfln("Singlely occupying site", j);

             state.set(j, (j%4 == 1 ? "Up" : "Dn"));
             p -= 1;
             state.set(j, "Emp");
     else if (j % 4 ==2)

auto psi0 = MPS(state);
auto psi1 = randomMPS(state);
auto sweeps = Sweeps(30);
sweeps.maxdim() = 50,100,200, 200;
sweeps.mindim() = 50;
sweeps.noise() = 1E-4, 1E-5, 1E-7, 1E-8, 0.0;
sweeps.cutoff() = 1E-12;

auto [Energy,psi] = dmrg(H, psi1, sweeps, {"Quiet=", true});

printfln("Ground State Energy= %1.10f", Energy);

 return 0;

In my code , to distinguish between the spin operators of conduction electron and localized spin operators, I renamed the following operators CSp(S+) ,CSm(S-) and CSz(Sz) in the header file electron.h
In Kondo-Heisenberg model, the total number of conduction electron and total CSz+Sz are conserved. When I do not use any symmetry, I set {"ConserveQNs",false}, the code can run and the energy is converged, but the energy is disagree with my DMRG code.
When I use quantum number, based on my understanding, if I just use the particle number as good quantum number. In the electron.h file I just set

    auto conserveQNs = args.getBool("ConserveQNs", true);
    auto conserveNf = args.getBool("ConserveNf", ture);
    auto conserveCSz = args.getBool("ConserveCSz", false);

Then the code can not run normally, the error is :
From line 1579, file itensor.cc
div(ITensor) not defined for non QN conserving ITensor
div(ITensor) not defined for non QN conserving ITensor
Aborted (core dumped)

when I just use (CSz+Sz) as a good quantum number, in the electron.h file

    auto conserveQNs = args.getBool("ConserveQNs", true);
    auto conserveNf = args.getBool("ConserveNf", false);
    auto conserveCSz = args.getBool("ConserveCSz", false);

and in the spinhalf.h

    auto conserveqns = args.getBool("ConserveQNs",true);
    auto conserveSz = args.getBool("ConserveSz",ture);
    auto conserveParity = args.getBool("ConserveParity",false);

the code can run but the energy does not converge. If (Sz+CSz) and Nf are used as good quantum numbers, the program can run but the ground state energy dose not converge.

Is there any problem in my code or I have incorrect understanding of MixesSiteSet and the use of good quantum number. And what should I do to realize Kondo-Heisenberg model on ITensor-3.

1 Answer

0 votes
answered by (6.6k points)


The error you are seeing when you try to conserve Nf but not Sz is due to the fact that currently in ITensor, you can't use a SiteSet that has some indices with QNs and some without. When you set "ConserveSz=",false, in the SpinHalfSite definition it will lead to the case where the Index is made without any QNs. If you would like to make that case work, you could try changing this line:


from s = Index(2,ts); to s = Index(QN(),2,ts); (I haven't tried it, so please let us know if that works). This will make an Index with an empty QN, which should work. It may be a good idea for us to add an option for that case. One could argue that if you set "ConserveQNs=",true and "ConserveSz=",false then it should default to making an Index with empty QNs.

As for the cases you are seeing that are running without error but are not converging, you may have to play around with the Sweeps object, like changing the bond dimension growth schedule, the noise, or the number of davidson iterations. Perhaps someone else (like Miles) can comment on strategies for getting more complicated Hamiltonians like this to converge with DMRG.


commented by (150 points)
edited by
Thank you very much for your response. when I change  s = Index(2,ts); to s =Index(QN(),2,ts), then the program can run normally without conserving total Sz.  
       But the problem of non convergence still exists when I use good quantum number  Nf  and total Sz,  and I don't think the problem is related to Sweeps object. For a Kondo-Heisenberg chain with L=10(20 sites) and the number of electrons is 10 , Sz-total=0.  When I set t =Jk= 0, Jh =1, I obtain the exact ground state energy of L=10 AFM Heisenberg chain. However, when I set t=1, and jk=Jh=0, the energy is not convergent and I can not obtain the energy of the corresponding one-dimensional free electron.  When I do not use any good quantum number, the result is convergent, but it is disagree with one-dimensional free electron.

-ZHOU Zongsheng
commented by (6.6k points)
It looks like it may be an issue with the way you order your fermionic operators (see https://itensor.org/docs.cgi?page=tutorials/fermions). I believe that you should use the ordering:

    for (int j = 1; j < N-2; j += 2)
      ampo += -t, "Cdagup", j+2, "Cup", j;
      ampo += -t, "Cdagup", j, "Cup", j+2;
      ampo += -t, "Cdagdn", j+2, "Cdn", j;
      ampo += -t, "Cdagdn", j, "Cdn", j+2;

Otherwise, the terms should be negated. Could you try that and see if it helps?
commented by (150 points)
edited by
Thanks for your kind help, I tried this yesterday,  It works well .
Welcome to ITensor Support Q&A, where you can ask questions and receive answers from other members of the community.

Formatting Tips:
  • To format code, indent by four spaces
  • To format inline LaTeX, surround it by @@ on both sides
  • To format LaTeX on its own line, surround it by $$ above and below
  • For LaTeX, it may be necessary to backslash-escape underscore characters to obtain proper formatting. So for example writing \sum\_i to represent a sum over i.
If you cannot register due to firewall issues (e.g. you cannot see the capcha box) please email Miles Stoudenmire to ask for an account.

To report ITensor bugs, please use the issue tracker.