Out-of-Equilibrium Bose-Fermi Mixtures

This example shows how to code up the Bose-Fermi mixture Hamiltonian:

\[\begin{split}H(t) &=& H_\mathrm{b} + H_\mathrm{f}(t) + H_\mathrm{bf},\nonumber\\ H_\mathrm{b} &=& -J_\mathrm{b}\sum_{j}\left(b^\dagger_{j+1}b_j + \mathrm{h.c.}\right) - \frac{U_\mathrm{bb}}{2}\sum_j n^\mathrm{b}_j + \frac{U_\mathrm{bb}}{2}\sum_j n^\mathrm{b}_jn^\mathrm{b}_j,\nonumber\\ H_\mathrm{f}(t) &=& -J_\mathrm{f}\sum_{j}\left(c^\dagger_{j+1}c_j - c_{j+1}c^\dagger_j\right) + A\cos\Omega t\sum_j (-1)^j n^\mathrm{f}_j + U_\mathrm{ff}\sum_j n^\mathrm{f}_jn^\mathrm{f}_{j+1},\nonumber\\ H_\mathrm{bf} &=& U_\mathrm{bf}\sum_j n^\mathrm{b}_jn^\mathrm{f}_j\end{split}\]

Details about the code below can be found in SciPost Phys. 7, 020 (2019).

Script

download script

  1########################################################################
  2#                            example 10                                #
  3#   In this script we demonstrate how to use QuSpin's                  #
  4#   tensor basis class to build Hamiltonians for mixtures of different #
  5#   species. We use this to study the non-equilibrium dynamics         #
  6#   in a Bose-Fermi mixture. The example also shows how to compute     #
  7#   the entanglement entropy shared between the species.               #
  8########################################################################
  9from quspin.operators import hamiltonian  # Hamiltonians and operators
 10from quspin.basis import (
 11    tensor_basis,
 12    spinless_fermion_basis_1d,
 13    boson_basis_1d,
 14)  # bases
 15from quspin.tools.measurements import obs_vs_time  # calculating dynamics
 16from quspin.tools.Floquet import Floquet_t_vec  # period-spaced time vector
 17import numpy as np  # general math functions
 18import matplotlib.pyplot as plt  # plotting library
 19
 20#
 21##### setting up parameters for simulation
 22# physical parameters
 23L = 6  # system size
 24Nf, Nb = L // 2, L  # number of fermions, bosons
 25N = Nf + Nb  # total number of particles
 26Jb, Jf = 1.0, 1.0  # boson, fermon hopping strength
 27Uff, Ubb, Ubf = -2.0, 0.5, 5.0  # bb, ff, bf interaction
 28# define time-dependent perturbation
 29A = 2.0
 30Omega = 1.0
 31
 32
 33def drive(t, Omega):
 34    return np.sin(Omega * t)
 35
 36
 37drive_args = [Omega]
 38#
 39###### create the basis
 40# build the two bases to tensor together to a bose-fermi mixture
 41basis_b = boson_basis_1d(L, Nb=Nb, sps=3)  # boson basis
 42basis_f = spinless_fermion_basis_1d(L, Nf=Nf)  # fermion basis
 43basis = tensor_basis(basis_b, basis_f)  # BFM
 44#
 45##### create model
 46# define site-coupling lists
 47hop_b = [[-Jb, i, (i + 1) % L] for i in range(L)]  # b hopping
 48int_list_bb = [[Ubb / 2.0, i, i] for i in range(L)]  # bb onsite interaction
 49int_list_bb_lin = [[-Ubb / 2.0, i] for i in range(L)]  # bb interaction, linear term
 50#
 51hop_f_right = [[-Jf, i, (i + 1) % L] for i in range(L)]  # f hopping right
 52hop_f_left = [[Jf, i, (i + 1) % L] for i in range(L)]  # f hopping left
 53int_list_ff = [
 54    [Uff, i, (i + 1) % L] for i in range(L)
 55]  # ff nearest-neighbour interaction
 56drive_f = [[A * (-1.0) ** i, i] for i in range(L)]  # density staggered drive
 57#
 58int_list_bf = [[Ubf, i, i] for i in range(L)]  # bf onsite interaction
 59# create static lists
 60static = [
 61    ["+-|", hop_b],  # bosons hop left
 62    ["-+|", hop_b],  # bosons hop right
 63    ["n|", int_list_bb_lin],  # bb onsite interaction
 64    ["nn|", int_list_bb],  # bb onsite interaction
 65    #
 66    ["|+-", hop_f_left],  # fermions hop left
 67    ["|-+", hop_f_right],  # fermions hop right
 68    ["|nn", int_list_ff],  # ff nn interaction
 69    #
 70    ["n|n", int_list_bf],  # bf onsite interaction
 71]
 72dynamic = [["|n", drive_f, drive, drive_args]]  # drive couples to fermions only
 73#
 74###### set up Hamiltonian and initial states
 75no_checks = dict(check_pcon=False, check_symm=False, check_herm=False)
 76H_BFM = hamiltonian(static, dynamic, basis=basis, **no_checks)
 77# define initial Fock state through strings
 78s_f = "".join("1" for i in range(Nf)) + "".join("0" for i in range(L - Nf))
 79s_b = "".join("1" for i in range(Nb))
 80# basis.index accepts strings and returns the index which corresponds to that state in the basis list
 81i_0 = basis.index(s_b, s_f)  # find index of product state in basis
 82psi_0 = np.zeros(basis.Ns)  # allocate space for state
 83psi_0[i_0] = 1.0  # set MB state to be the given product state
 84print("H-space size: {:d}, initial state: |{:s}>|{:s}>".format(basis.Ns, s_b, s_f))
 85#
 86###### time evolve initial state and measure entanglement between species
 87t = Floquet_t_vec(
 88    Omega, 10, len_T=10
 89)  # t.vals=times, t.i=initial time, t.T=drive period
 90psi_t = H_BFM.evolve(psi_0, t.i, t.vals, iterate=True)
 91# measure observable
 92Sent_args = dict(basis=basis, sub_sys_A="left")
 93meas = obs_vs_time(psi_t, t.vals, {}, Sent_args=Sent_args)
 94# read off measurements
 95Entropy_t = meas["Sent_time"]["Sent_A"]
 96#
 97######
 98# configuring plots
 99plt.plot(t / t.T, Entropy_t)
100plt.xlabel("$\\mathrm{driving\\ cycle}$", fontsize=18)
101plt.ylabel("$S_\\mathrm{ent}(t)$", fontsize=18)
102plt.grid(True)
103plt.tick_params(labelsize=16)
104plt.tight_layout()
105plt.savefig("BFM.pdf", bbox_inches="tight")
106# plt.show()
107plt.close()