Implementing iDMRG for ladder lattices

How do I use this algorithm? What does that parameter do?
Post Reply
Fabio_Mendez
Posts: 5
Joined: 01 Feb 2022, 01:50

Implementing iDMRG for ladder lattices

Post by Fabio_Mendez »

Dear Johannes,

I hope you are doing great. We met at the DPG meeting this year (I recognized you in a talk, went to yours, and asked you about time evolution for open systems).

I am writing now because I am trying to implement an iDMRG code on a ladder system. My code is huge, but I'll try to point out the most important parts related to my questions.

The system I am studying is the Fermi-Hubbard model over a squared ladder, and I am now trying to reproduce the results in Fig. 2 (a) at https://doi.org/10.1103/PhysRevB.102.035163. For that, I am using a unit cell of size 2X16.

I am adding the hoppings manually in the form (assume I did it correctly with the spins and H.c terms):

Python: Select all

 self.add_local_term(-t, [('Cdu', (0, 0))), ('Cu', (1, 0))]) 
 self.add_local_term(-tv, [('Cdu', (0, 0))), ('Cu', (0, 1))]) 
 self.add_local_term(-t, [('Cdu', (0, 1))), ('Cu', (1, 1))]) 
For the different correspondent hopping terms.

I am setting the lattice with:

Python: Select all

lat = Ladder(L, site, bc='periodic', bc_MPS='infinite')
My question is the following:
I manually added the hoppings for periodic boundary conditions with add_local_terms; was I supposed to do so, or is it necessary to use add_coupling and self.lat.nearest_neighbors so that the code captures these boundary conditions?

Thanks a lot in advance,

F. P. M. Méndez-Córdoba.
User avatar
Johannes
Site Admin
Posts: 457
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: Implementing iDMRG for ladder lattices

Post by Johannes »

Hi Fabio,
whether you call add_coupling or explicitly loop over add_local_term doesn't matter for the final DMRG run, if you get the same couplings in the MPO of the hamiltonian - but with the latter, you need to iterate over the starting point of the couplings in real space, so you are responsible to correctly take into account the boundary conditions. If you call add_coupling, it will read out the Lattice.bc to determine whether the coupling fits into the lattice starting from each site, and add corresponding terms: for infinite MPS, you should thus set Ladder.bc='periodic' to get the couplings between MPS unit cells.

You can easily check which terms you have in the final MPO by calling print(Model.all_coupling_terms().to_TermList()). For an infinite MPS, it prints the terms added to MPO which start in with the left-most site inside the MPS unit cell.

If you want to explicitly loop yourself with add_local_term, compare your setup with the results of a simple example in TeNPy, e.g. the transverse field Ising model, and make sure you understand which terms you need for which combination of boundary conditions.
In the infinite case for you 2x32 lattice, you should e.g. have the \(J_{\parallel}\) hoppings between lattice sites (x=31,y=0) and (x=32,y=0), i.e. MPS sites i=62 and j=64, which would not be there if you use finite MPS on the same ladder size.
Also double-check whether you get the correct strength of the \(J_\perp\) terms - the full Square lattice is equivalent to the Ladder if you set Ly=2 and the boundary conditions to bc=[Ladder.bc, 'open'].
User avatar
Johannes
Site Admin
Posts: 457
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: Implementing iDMRG for ladder lattices

Post by Johannes »

Let me be a bit more explicit: in the simple case of the Ladder,
the following lines in init_couplings are equivalent:

Python: Select all

add_coupling(-t, 0, 'Cdu', 0, 'Cu', dx=1, plus_hc=True)
add_coupling(-tv, 0, 'Cdu', 1, 'Cu', dx=1, plus_hc=True)
add_coupling(-t, 1, 'Cdu', 1, 'Cu', dx=1, plus_hc=True)

Python: Select all

for x in range(self.lat.Ls[0] - (1 if self.lat.bc=='open' else 0)):
 self.add_local_term(-t, [('Cdu', (x, 0))), ('Cu', (x+1, 0))], plus_hc=True) 
 self.add_local_term(-t, [('Cdu', (x, 1))), ('Cu', (x+1, 1))], plus_hc=True) 
for x in range(self.lat.Ls[0]):
 self.add_local_term(-tv, [('Cdu', (x, 0))), ('Cu', (x, 1))], plus_hc=True) 
Note that the range of the loop depends on which coupling you have!
Post Reply