+1 vote
asked by (230 points)

I want to study a system with two species of fermions, that is right movers and left movers. I want to label the operators as c{R} and c{L} for right and left movers respectively . Is there any way to do this in ITensor?

commented by (70.1k points)
Hi, thanks for the question. Could please elaborate a bit more so I can be sure to give the most helpful answer? When you say right and left moving fermions, do you mean in the context of say a Luttinger liquid or relatedly the low-energy description of one-dimensional fermions?

If so, I think my answer will be mostly in the negative, that I don't know a good way to treat these using tensor networks on a discrete lattice. But the main issues aren't ITensor-specific: rather there are a number of deep obstructions to representing relativistic fermion theories faithfully using discretized lattice models (e.g. the fermion doubling problem and other issues).

But maybe your question is a different one, just about having multiple "species" of fermions?

If you could point me to a precise lattice Hamiltonian (such as in a paper) you are trying to simulate that would be the most helpful info you could give.

commented by (230 points)
edited by
   Thank you for the response. Sorry for not elaborating the question properly.
So basically the lattice Hamiltonian i want to simulate is
H_0 = - t\sum_{i=1}^{N} c^{\dagger}_{R,i}c_{R,i+1} - t\sum_{i=1}^{N} c^{\dagger}_{L,i}c_{L,i+1}-
t\sum_{i=1}^{N} c^{\dagger}_{R,i+1}c_{R,i} \\ - t\sum_{i=1}^{N} c^{\dagger}_{L,i+1}c_{L,i}
plus an interaction part of the type
H_{I} = v_0 \sum_{i=1}^{N} n_i n_{i+1}
where @@ n_i = c^{\dagger}_{R,i}c_{R,i} +  c^{\dagger}_{L,i}c_{L,i} @@.

Like you mentioned there are difficulties in treating the Luttinger liquid fermions in a lattice model, but I want to simulate  in some sense a toy lattice model that  tries to capture some of the physics of a Luttinger liquid with only short range forward - scattering interactions.

So I want to be able to define creation and annihilation operators for two species of fermions that I label R (right) and L (left).  I'm using C++ v3 by the way.

Best Regards

1 Answer

0 votes
answered by (70.1k points)

Thanks for the extra info above.

So the easiest way to do this with the setup available in ITensor is to define (in your head, more so than in the code) the odd numbered sites to be "L" fermions and the even numbered sites to be "R" fermions. Then this choice is enforced by how you construct the Hamiltonian, such as only inputting hopping terms which connect even to even or odd to odd sites.

Does that approach seem clear to you? Note that converging this setup in DMRG may become a bit harder because two-site DMRG becomes effectively one-site DMRG, but you can overcome this with a good choice of initial state and the use of the noise term.

In the Julia version of ITensor, we offer some more customizability of operators, as used by the AutoMPO system. So there you can introduce custom fermionic operator types and it would be possible to put the L and R fermions on the same site (making dimension 4 site, sort of like in the Hubbard model but with L,R taking the place of spin).


commented by (230 points)
Thanks for the answer. I'll try to implement this in the Julia version and see if I can put L and R fermions on the same site.
commented by (70.1k points)
Ok great. Since you're interested in going that route, the key thing to learn about is the `has_fermion_string` function overloads, which you can see in these files which define the various fermionic site types included in ITensors.jl:
(See the very end of each of these files.)

As long as you (1) define these functions to return `true` for any fermionic operator you define and (2) define that operator correctly so that it has the right commutation relations in an on-site way too (note the minus signs for "Cdn" and "Cdagdn" in the Electron site definitions, which are these 'on site' signs I'm referring to, since down electrons are taken to be ordered 'after' up electrons in our convention), then you will be guaranteed to get the correct result from the AutoMPO system when using it to make a Hamiltonian with your custom operators.

This capability isn't available in the C++ version currently, because there we just hard-wired which fermionic operators AutoMPO knows about. It's a lot easier to extend library code in Julia which is one of the reasons we switched to it for the newest version of ITensor.

commented by (700 points)
Hi Miles, I actually tried the odd sites even sites approach. I wrote the simplest code with two fermion species and they hop around independently. In this case, indeed I have convergence issue. To be precise, the system got stuck in the initial product state configuration.

You mentioned in the above answer that this issue could be resolved by choosing a better initial state or adding a noise term. My questions are the following:
1. For the initial state, do we have better options other than product state if we want to conserve the quantum numbers?
2. For the noise term method, it seems that we need to modify the density matrix during the process based on the original paper by White. Is there a convenient way to implement it in ITensor?

Thanks a lot
commented by (70.1k points)
Hi Mason,
Which version of ITensor are using? In the Julia version, regarding question (1) there is a capability to use a better initial state than a product state even when conserving QNs.

For (2), yes we already offer the noise term for all of our DMRG codes. Please look at the example codes such as in the example/dmrg folder of the Julia version or the sample/ folder (such as sample/exthubbard.cc) for examples of DMRG codes which set the noise term strength.

commented by (700 points)
Hi Miles, thanks for replying. I'm using the Julia version.
In this case, how do we construct the initial state?
Thanks again.
commented by (70.1k points)
Hi Mason,
That's good - so there is a function called `randomMPS` which takes an extra variable `state` which is an array of strings or integers specifying the initial product state which is then randomized to make a random MPS. The reason for specifying this initial state is you can choose which total QN you want the state to have, and the randomMPS function will respect this choice. It is documented here:

For the case of spinless fermions, an example of using it would be:

s = siteinds("Fermion",N;conserve_qns=true)
state = ["Emp","Occ","Emp","Occ"] # product, or Fock, state with two fermions
psi = randomMPS(s,state,4) # make a randomMPS of bond dimension 4
commented by (700 points)
This is really helpful. Thanks Miles!
commented by (700 points)
Hi Miles,

Sorry to bother you again, but another issue popped up when initializing the random state this way. The QN-conserving random MPS conserves the total fermion number, but the numbers for each flavor (i.e. the total number on odd or even sites) are not separately conserved.

I tried to define the sites_odd and sites_even separately using siteinds(...), and then combine them into a single sites array, but it doesn't work.

Thanks a lot for your time.
commented by (70.1k points)
Hi, so for that to work you will need to define custom quantum numbers ("QN" objects) which use a different name for the two types of fermions. Then when you make the array of site indices (so you will need to either overload the siteinds function or just make an array in a loop) you should switch off the QNs in odd versus even sites to have the appropriate QNs labeling their subspaces.

commented by (70.1k points)
You could use this example to see how things work:

If you print out the `sites` array, you'll see that it's nothing but a plain Julia array of Index objects. Then if you look at the QN structure of each of these Index objects you will see it alternates from site to site. So if you construct a similar array with QNs reflective of your system then it ought to just work the way you want.

commented by (700 points)
Hi Miles, I tried to define a new site type "Electrons_two_flavors" by including the flavor index at each site and try to conserve the $\tau_z$ QN, which is defined to be the onsite number difference between the two flavors. Here is the beginning part of the code (I can post the rest if you need it):

function space(::SiteType"Electron_two_flavors";
               conserve_qns = false,
               conserve_sz = conserve_qns,
               conserve_nf = conserve_qns,
               conserve_nfparity = conserve_qns,
               qnname_sz = "Sz",
               qnname_tauz = "Tauz",
               qnname_nf = "Nf",
               qnname_nfparity = "NfParity",
               # Deprecated
               conserve_parity = nothing)

However, when I run this  I got the error "LoadError: String is too long for SmallString. Maximum length is 8". I tried to reduce the lengths of the defined OpNames and StateNames to be within 8, but the error is still there.

Another question is, is there a way to incorporate this new site type into my ITensor so that I don't have to run it every time before running the other code?

Thanks a lot for your time
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.