## Two component Bose-Hubbard model

How do I use this algorithm? What does that parameter do?
dehond
Posts: 2
Joined: 08 Feb 2021, 20:00

### Two component Bose-Hubbard model

I'm trying to use DMRG to calculate some ground state properties of the two-component Bose-Hubbard model on a one-dimensional chain:

$H = -t \sum_{< i,j >} \left( a_i^+ a_j + b_i^+ b_j + H.c. \right) + \frac{U}{2} \sum_i [a_i^+ a_i (a_i^+ a_i - 1) + b_i^+ b_i (b_i^+ b_i - 1)] + U_{AB} \sum_i a_i^+ a_i b_i^+ b_i,$

where $$U$$ and $$U_{AB}$$ are the inter- and intrastate onsite interactions, respectively. I have implemented this as its own CouplingMPOModel class, while heeding some of the things I've learned from studying this topic on combining multiple charges on the same site.

Essentially I set up a superlattice with two sites in every unit cell: an _A_ site and a _B_ site. In the init_lattice() routine I use a pairs dictionary to get the geometry right:

Code: Select all

class TwoComponentBoseHubbardModel(CouplingMPOModel):
def init_sites(self, model_params):
n_max = model_params.get('n_max', 3)
filling = model_params.get('filling', 1)
conserve = model_params.get('conserve', 'N')
if conserve == 'best':
conserve = 'N'
if self.verbose >= 1.:
print(self.name + ": set conserve to", conserve)
siteA = BosonSite(Nmax=n_max, conserve=conserve, filling=filling)
siteB = BosonSite(Nmax=n_max, conserve=conserve, filling=filling)
multi_sites_combine_charges([siteA, siteB])
return [siteA, siteB]

def init_lattice(self, model_params):
pairs = {'onsite': [(0, 1, np.array())], 'nearest_neighbors': [(0, 0, np.array()), (1, 1, np.array())]}
L = model_params.get('L', 10)
sites = self.init_sites(model_params)
lat = lattice.Lattice([L], sites, pairs = pairs)
return lat

def init_terms(self, model_params):
t = model_params.get('t', 1.)
U = model_params.get('U', 10.)
UAB = model_params.get('UAB', 0.)
mu = model_params.get('mu', 0)
for u in range(len(self.lat.unit_cell)):
self.add_onsite(-mu - U / 2., u, 'N')
for u1, u2, dx in self.lat.pairs['nearest_neighbors']:
self.add_coupling(-t, u1, 'Bd', u2, 'B', dx, plus_hc=True)
for u1, u2, dx in self.lat.pairs['onsite']:
self.add_coupling(UAB, u1, 'N', u2, 'N', dx)

With the initial state psi = MPS.from_lat_product_state(M.lat, [[1, 1]]) and by using the mixer I believe this works correctly.

It does seem to me, though, that it runs a little inefficiently, so perhaps my choice of geometry is suboptimal. I need a bond dimension of about 300 to get a converged result for 20 sites. I must say I've never tried to use MPS algorithms on the Bose-Hubbard model before, so it may just be my inexperience (in which case, too bad!) On the other hand I wonder if the MPS representation is somehow more efficient if I use a ladder geometry, with the _A_ and _B_ sites being on either side of every rung.
Johannes
Posts: 324
Joined: 21 Jul 2018, 12:52
Location: TU Munich

### Re: Two component Bose-Hubbard model

Your code looks right. I would have done it basically the same way In the newest version of TeNPy, tenpy.networks.site.multi_sites_combine_charges is deprecated in favor of tenpy.networks.site.set_common_charges, you should call it with set_common_charges([siteA, siteB], 'independent').
This should make sure that the numbers of A and B bosons are individually conserved (as in your code, I think).

Whether you use ladder or the way you do it now, will not make any difference for speed - the DMRG will do the exact same thing, because you generate the same H_MPO in the end.
Combining the sites will make DMRG only scale worse, I would not recommend it - unless you find that you have a much stronger entanglement between A and B sites in the same unit cell than between the rungs, and you are limited by truncation on that particular bond.

I'm not sure what n_max you've set. Keep in mind that the local Hilbert space of Bosons is larger than the one of Fermions, so even if you have the same correlation length of say 1 site, the bosons do require a larger bond dimension. The larger your onsite U, the more suppressed higher-occupied sites are, and you get back to the hard-core boson limit for $$U \gg t$$, which is equivalent to Fermions.
dehond
Posts: 2
Joined: 08 Feb 2021, 20:00

### Re: Two component Bose-Hubbard model

That's great, thanks so much for having a look at my code and for your input!

ksuzuki
Posts: 2
Joined: 09 Dec 2021, 14:49

### Re: Two component Bose-Hubbard model

I used TwoSiteDMRGEngine for this code under the specified initial state psi = MPS.from_lat_product_state(M.lat, [[1, 1]]), but it did not successfully find the ground state.
I would appreciate it if you could tell me how you used it.

Code: Select all

model_params=dict(L=L,n_max=n_max,t=t,U=U,UAB=UAB,mu=mu,conserve=None)
M=TwoComponentBoseHubbardModel(model_params)
psi=MPS.from_lat_product_state(M.lat,[[1,1]])
dmrg_params = {
'mixer': None,
'max_E_err': 1.e-10,
'trunc_params': {
'chi_max': 30,
'svd_min': 1.e-10
},
'combine': True
}
eng_dmrg = dmrg.TwoSiteDMRGEngine(psi,M,dmrg_params)
E, psi= eng_dmrg.run()

Last edited by ksuzuki on 10 Dec 2021, 06:29, edited 4 times in total.
Johannes