# [Julia] Two types of sites with conserve_qns=true only for one of them

Hi, everyone in ITensor community!

I am trying to construct a Hamiltonian involving two types of sites, "Fermion" and "S=1/2".

A similar question has been answered by Miles. Based on it, I have successfully performed some DMRG calculations.

To fix the filling factor of fermions, one may simply add a chemical potential term. My question is: Is it possible to use conserve_qns=true for "Fermion" sites only, so that to work directly with a fixed fermion number?

I find that using conserve_qns=true for both types of sites simultaneously is allowed, but only applying to one of them returns error. As an example, the following codes seem to work (which is based on this formula)

let
N=6
sites = siteinds(n->isodd(n) ? "S=1/2" : "S=1", N; conserve_qns=true)

# H
ampo = OpSum()
for j=1:N-3
ampo += (0.5*J,"S+",j,"S-",j+2,"S+",j+1,"S-",j+3)
ampo += (0.5*J,"S-",j,"S+",j+1,"S-",j+1,"S+",j+3)
ampo += (J,"Sz",j,"Sz",j+2,"Sz",j+1,"Sz",j+3)
end
H = MPO(ampo,sites)

# ψ0
states = [isodd(n) ? "Up" : "Dn" for n in 1:N]
psi0 = MPS(sites,states);

#DMRG
sweeps = Sweeps(10)
setmaxdim!(sweeps,10,10,20,40,80,100,140,180,200)
setcutoff!(sweeps,1E-8)
energy,psi = dmrg(H,psi0,sweeps)
end


But if I apply conserve_qns=true only to S=1 sites, as follows,

let
N=6
sites1 = siteinds("S=1",div(N,2);conserve_qns=true)
sites2 = siteinds("S=1/2",div(N,2);conserve_qns=false)
sites = [
if mod(i,2)==1
replacetags(sites1[div(i+1,2)],
"S=1,Site,n=$(div(i+1,2))", "S=1,Site,n=$i")
else
replacetags(sites2[div(i,2)],
"S=1/2,Site,n=$(div(i,2))", "S=1/2,Site,n=$i")
end
for i=1:N]

... # the rest are the same as before
end


It then returns error. Note if I choose conserve_qns=true (or conserve_qns=false) for both sites in above codes, it again works!

Best,
Junsen

commented by (610 points)
I also construct Fermion and S=1/2 types, and find again that using conserve_qns=true for both simultaneously works, but only for one of them returns error.

+1 vote

Hi Junsen, we can discuss more if my answer does not completely solve your problem, but here are two responses I think could help with your case:

1. first, it appears that your Hamiltonian may conserve Sz parity, which is the number of spins that are up modulo two. In fact, it may even conserve total Sz in which case I would ask why are you wanting to turn off spin conservation? (Or maybe your Hamiltonian was only an example and not the one you are planning to use.)

2. secondly, assuming you still do want to only conserve Fermion number and nothing else, then unfortunately a limitation of ITensor right now is that all Index and ITensor objects need to have a block structure within a DMRG calculation. So a trick you could use is to make your spin Index objects have a block structure, but a trivial one. So like for a S=1/2 Index you could define it as:

Index([QN()=>2];tags="S=1/2,Site")


and for S=1 as

    Index([QN()=>3];tags="S=1,Site")


Though I have not tried it, I think it ought to work and give the same results as if the spin indices were regular (dense) indices but now can be used in combination with other tensors where the indices have a block structure.

Best,
Miles

commented by (610 points)
Hi Miles, thanks for the quick reply! Your suggestion indeed works! The following is a minimal example, for others who may find it useful:

sites = [ isodd(n) ? siteind("Fermion",n,conserve_qns=true) : Index([QN()=>2];tags="S=1/2,Site,n=\$n") for n in 1:N]

[Regarding to your first response, yes, I just randomly come up with a Hamiltonian which conserves Sz symmetry for two types of spin individually, so that one can use conserve_qns=true separately.]

Best,
Junsen
commented by (70.1k points)