Issue with ITensor flux while implementing conserved parity in DMRG C++

,

Hi there!

I am trying to implement conserved parity in ITensor C++ version. I consider one dimensional Ising chain with periodic boundary condition. The Hamiltonian is H = -g\sum_j \sigma_j^z- J\sum_j \sigma_j^x \sigma_{j+1}^x. This hamiltonian commutes with the operator \mathcal{F} = \prod_j \sigma_j^z. My goal is to compute ground state energy in each parity sector, i.e., \mathcal{F}=1 and \mathcal{F}=-1. My code is as follows:

#include "itensor/all.h"
#include "itensor/util/print_macro.h"

using namespace itensor;

int main(int argc, char *argv[])
    {
    int N;
    double J, g;

    N = atoi (argv[1]);
    J = 2*atof (argv[2]);
    g = 2*atof (argv[3]);
   
    auto sites = SpinOne(N,{"ConserveParity=",true});

    auto ampo = AutoMPO(sites);
    for(int j = 1; j <=N; ++j){
        ampo += -g,"Sz",j;
        int jp1 = (j % N)+1; // Periodic boundary condition
        ampo += -J,"Sx",j,"Sx",jp1;
        }
    auto H = toMPO(ampo);
    auto sweeps = Sweeps(10);
    sweeps.maxdim() = 10,20,100,200,400;
    sweeps.cutoff() = 1E-10;

   auto psi0 = randomMPS(sites);
   auto [en0, psi_opt] = dmrg(H, psi0, sweeps,{"Quite=",true});

   printfln("\nGround State Energy =",en0);

    return 0;
    }

This gives me following error:
`
Trying to set element:
Index: (dim=3|id=706|“S=1,n=1,Site”)
1: 1 QN({“Sz”,2})
2: 1 QN({“Sz”,0})
3: 1 QN({“Sz”,-2}), Val: 2
Index: (dim=3|id=706|“S=1,n=1,Site”)’
1: 1 QN({“Sz”,2})
2: 1 QN({“Sz”,0})
3: 1 QN({“Sz”,-2}), Val: 1
Element flux is: QN({“Sz”,2})
ITensor flux is: QN({“Sz”,-2})
From line 327, file /Users/itensor/itensor/itensor_impl.h

In .set, cannot set element with flux different from ITensor flux

In .set, cannot set element with flux different from ITensor flux
zsh: abort
`
Could you please point out what I am doing wrong. Also how do I specify value of \mathcal{F} to be +1 or -1?

Thanks!

Hi Sutapa,
Thanks for the question and sorry about the very slow reply. The answer to your two questions is actually the same: your code is missing the extra step of defining the initial state to be a product state with specific quantum numbers.

Please see the following “code example” that explains how to do this (it is “Change 2” in the example page):
http://itensor.org/docs.cgi?vers=cppv3&page=formulas/qn_dmrg

The way our system works is that whatever initial state you make determines the total quantum numbers that the state will have throughout the DMRG calculation. So that is also the answer to your question about choosing the flux you want to have. If you choose your initial state to have a certain pattern of spins that makes the \mathcal{F} operator be +1, then \mathcal{F} will still be +1 for the ground state after DMRG is finished. And similar for \mathcal{F}=-1.

Miles

Hi Miles,

Thank you so much for your response.

Unfortunately, the error persists even if I replace auto psi0 = randomMPS(sites); with

    auto state = InitState(sites);

    for(auto i : range1(N))
    {
     state.set(i,"Up");
    }
    auto psi0 = MPS(state);

The later is now a state with \mathcal{F}=+1.

Your fix is a step in the right direction. But I think I see the deeper issue now with what you’re trying to do.

The deeper issue is this: for the SpinOne sites we only currently offer to conserve quantum numbers or not, and to conserve total Sz or not. There is no such keyword as “ConserveParity” for SpinOne. (It’s an unfortunate aspect of C++ that we don’t have a system to detect unsupported keyword names – this is one of the many things that we have found to be better in our Julia language version.)

So there are two solutions:

  • switch to using the Julia version of ITensor and we could help you very quickly define a custom site type there that would model spin 1’s with only parity conservation, which you could do in a few lines quite easily
  • copy the file itensor/mps/sites/spinone.h in our source code, rename it to a different name, and make a new type modeled on it. It could be called ParitySpinOne or similar. Then you can modify the SpinOneSite and SpinOne types to make your new ParitySpinOne sites instead.

Please let me know which one you want to pursue. And you could probably go a long way yourself but if you get stuck, you’re welcome to ask questions as needed below.

Thank you for your prompt response. Trying the Julia version seems a simpler solution to me. Thanks!

1 Like

Hi Miles, I built a code in Julia to implement the parity symmetry and was able to compute energies at each symmetry sector successfully.

Now I am working with a system with parity operator \mathcal{F} = \sigma_1^z\sigma_2^z\cdots\sigma_r^y\sigma_{r+1}^z\cdots\sigma_N^z. Again my goal is to compute ground state for \mathcal{F} = +1 and \mathcal{F} = -1.

  1. For this case the built in ‘conserve_szparity’ does not work. Is there a way to preserve this custom parity symmetry?

  2. If I build my initial state to be in one symmetry sector and do not set any quantum number conservation to be ‘true’, does DMRG continue to stay in that parity sector?