Qn on muti-sites DMRG

How do I use this algorithm? What does that parameter do?
Post Reply
yasin
Posts: 4
Joined: 08 Nov 2020, 12:08

Qn on muti-sites DMRG

Post by yasin »

I meet following question: I have a 1D chain that consists of a repeated unit cell formed by three same sites (SpinhalfFermion). I labeled these three sites as 'a' 'b' 'c'. The hopping exist both in unit_cell (like a to \(b_i^\dagger a_i\) and \(b_i^\dagger c_i\) and their h.c.) and between near unit_cell (like \(b_i^\dagger a_{i+1}\) and \(b_i^\dagger c_{i+1}\)and their h.c.).
I used Groupedsites for constructing the list of site

Code: Select all

    def init_sites(self, model_params):
        cons_N = model_params.get('cons_N', 'N')
        cons_Sz = model_params.get('cons_Sz', 'Sz')
        site1 = SpinHalfFermionSite(cons_N = cons_N, cons_Sz = cons_Sz)
        site2 = SpinHalfFermionSite(cons_N = cons_N, cons_Sz = cons_Sz)
        site3 = SpinHalfFermionSite(cons_N = cons_N, cons_Sz = cons_Sz)
        sites = GroupedSite([site1, site2, site3], labels = ['a', 'b', 'c'], charges = 'same')
        return sites
And the Hamiltonian is constructed as

Code: Select all

def init_terms(self, model_params):
        t1 = model_params.get('t1', 0)
        t2 = model_params.get('t2', 0)
        t3 = model_params.get('t3', 0)
        t4 = model_params.get('t4', 0)
        mu1 = model_params.get('mu1', 0)
        mu2 = model_params.get('mu2', 0)
        mu3 = model_params.get('mu3', 0)
        U = model_params.get('U', 0)
        self.add_coupling(-t4, 0, 'Cdua', 0, 'Cub', dx = 1, plus_hc = True)
        self.add_coupling(-t4, 0, 'Cdda', 0, 'Cdb', dx = 1, plus_hc = True)
        self.add_coupling(-t3, 0, 'Cdub', 0, 'Cuc', dx = 1, plus_hc = True)
        self.add_coupling(-t3, 0, 'Cddb', 0, 'Cdc', dx = 1, plus_hc = True)

        self.add_onsite(-t1, 0, 'Cdub Cua', plus_hc = True)
        self.add_onsite(-t1, 0, 'Cddb Cda', plus_hc = True)
        self.add_onsite(-t2, 0, 'Cduc Cub', plus_hc = True)
        self.add_onsite(-t2, 0, 'Cddc Cdb', plus_hc = True)

        self.add_onsite(mu1, 0, 'Ntota')
        #self.add_onsite(mu1, 0, 'Nda')
        self.add_onsite(mu2, 0, 'Ntotb')
        #self.add_onsite(mu2, 0, 'Ndb')
        self.add_onsite(mu3, 0, 'Ntotc')
        #self.add_onsite(mu3, 0, 'Ndc')

        self.add_onsite(U, 0, 'NuNda')
        self.add_onsite(U, 0, 'NuNdb')
        self.add_onsite(U, 0, 'NuNdc')
When I set the following code and run DMRG

Code: Select all

L = 10
model_params = {
        't1' : 1.,#which means the strength of [latex]b_i^\dagger a_i[/latex]
        't2' : 0,#which means the strength of [latex]b_i^\dagger c_i[/latex]
        't3' : 0,#which means the strength of [latex]b_i^\dagger c_{i+1}[/latex]
        't4' : 1,#which means the strength of [latex]b_i^\dagger a_{i+1}[/latex]
        'mu1' : 1,
        'mu2' : 1.,
        'mu3' : 0,
        'U' : 0.,
        'L' : L,
        'cons_N' : 'N',
        'bc_MPS' : 'finite',
        #'bc_x' : 'periodic',
    }
M = DChain(model_params)
pstate = ['up_a up_b empty_c'] * (L//2) +['empty_a empty_b empty_c'] * (L//2)
psi = MPS.from_product_state(M.lat.mps_sites(),pstate)
After the DMRG, I got a wrong energy and psi according to

Code: Select all

print(psi.expectation_value('Nuc'))
should be zeros but not.
User avatar
Johannes
Site Admin
Posts: 413
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: Qn on muti-sites DMRG

Post by Johannes »

Let me get this straight: you initialize the state without c electrons and DMRG to keep the number of c electrons at 0, because you have no hopping terms to c (by explicitly setting t2 and t3 to 0).
However, you have only two globally conserved charges: the total number of electrons, and the total spin (i.e. the total number of up electrons - the total number of down electrons). Equivalently, you can say that you conserve both the total number of up and the total number of down electrons.

However, while the initial number of c electrons is zero, this is not a conserved quantity enforced by charge conservation, but only by the fact that you don't have the terms changing it in your hamiltonian.
Usually, DMRG is using Lanczos, which only applies H to the given initial states, and hence you expect that it stays in whatever charge sector you started with (in your case no c electrons).
However, at very small bond dimensions, TeNPY does a full diagonalization of the effective hamiltonian.
There, it looks at all possible eigenstates in the allowed charge sector, and picks the one with the lowest energy.
In your case, that is one with both electrons of the unit cell as c particles, because the a and b electron have a penalty for the chemical potential
(you have a positive sign for mu!), while the c electron doesn't have that.
I didn't try it, but I'm quite sure that you will get a state with no particles in c, if you just switch the chemical potential to have negative signs for a, b.
Let me know if this isn't the case!


That being said, I would highly recommend not to used the GroupedSite in this case, because you will have an unnecessary large local bond dimension of d=64, and (two-site) DMRG scales with \(d^4\).
Instead, enlarge the unit cell of the lattice (keep the 3 sites you initialize), and use tenpy.networks.site.set_common_charges, if necessary.
yasin
Posts: 4
Joined: 08 Nov 2020, 12:08

Re: Qn on muti-sites DMRG

Post by yasin »

yeah, thank you for this reply. Now I can understand why c get particles in my above case. And you are right, in the negative case, c don't have any particles.

Thank you agin for your comment, but I couldn't understand why I will have an unnecessary large local bond. Actually, the parameters what I show above are not my target. I try some other parameters like t1 = 1 t2 = -2.43501 t3=-4.91973 t4 = 2.02041 mu1 = 1.21722 mu2=0 mu3 = 7.21722 U = 0, and pstate= ['up_a up_b up_c'] * (L//2) +['empty_a empty_b empty_c'] * (L//2). After DMRG, the energy is different from the result of ED.(I write a ED code for checking this DMRG) No matter how I change ''chi_max'' ''svd_min'' ''max_E_err'', the energy compare to result of ED have a difference(around 1). In this case, hopping between b and c is turn on, and the bond dimension is [64, 100, 100, 100, 100, 100, 100, 100, 64]. I think now full diagonalization won't cause this difference. I also try U =1 when pstate= ['full_a full_b full_c'] * (L//2) +['empty_a empty_b empty_c'] * (L//2) and t1 = 1 t2 = -2.43501 t3=-4.91973 t4 = 2.02041 mu1 = 1.21722 mu2=0 mu3 = 7.21722. I compare the energy with ALPS's result, TeNPY's result is higher than ALPS's result(around 3). I don’t know if L is too small.


Maybe such lattice is called diamond chain. If I don't use GroupedSite, I don't know how to realize this lattice.
User avatar
Johannes
Site Admin
Posts: 413
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: Qn on muti-sites DMRG

Post by Johannes »

DMRG scales with (at least) the third power of the local dimension. Using a GroupedSite forces the local dimension to 2^3 = 8, so you can expect a very significant speedup of roughly \(\frac{8^3}{3\cdot 2^3}\) when switching to separate sites. To implement it, simply use a lattice with a non-trivial unit cell - take the tenpy.models.lattice.Ladder as inspiration, which uses two sites as unit cell, and generalize it to the three sites and extra pairs you want.

Also, I would highly recommend not to use pstate= ['up_a up_b up_c'] * (L//2) +['empty_a empty_b empty_c'] * (L//2),
but rather to use

Code: Select all

pstate= ['up_a up_b up_c', 'empty_a empty_b empty_c'] * (L//2)
The latter only requires a local change of the density and will hence converge must better.

When you run the ED code, what fillings do you end up with, i.e. what is the total number of a,b,c particles in the final state?
Make sure that your initial state has the very same total fillings!
Post Reply