Fermi-Hubbard model without doubly-occupied sites
This example shows how to construct the Fermi-Hubbard model of spinful fermions in the subspace without doubly-occupied sites using the user_basis.
\[H = P\left[ -J\sum_{\langle i,j\rangle, \sigma}\left(c^\dagger_{i\sigma} c_{j\sigma} + \mathrm{h.c.}\right) - \mu\sum_{j,\sigma} n_{j\sigma} + U\sum_j n_{j\uparrow}n_{j\downarrow} \right]P,\]
where \(P\) projects out doubly-occupied sites.
The procedure is the same as for the spinful_fermion_basis_general class, but it makes use of the optional argument double_occupancy=False in the basis constructor (added from v.0.3.3 onwards).
Arbitrary post selection of basis states (which generalizes eliminating double occupancies to more complex examples and models), can be done in QuSpin using the user_basis class, see user_basis tutorial.
Script
1#
2import sys, os
3
4os.environ["KMP_DUPLICATE_LIB_OK"] = (
5 "True" # uncomment this line if omp error occurs on OSX for python 3
6)
7os.environ["OMP_NUM_THREADS"] = "1" # set number of OpenMP threads to run in parallel
8os.environ["MKL_NUM_THREADS"] = "1" # set number of MKL threads to run in parallel
9#
10
11###########################################################################
12# example 13 #
13# In this script we demonstrate how to construct a spinful fermion basis #
14# with no doubly occupancid sites in the Fermi-Hubbard model, #
15# using the spinful_fermion_ basis_general class. #
16###########################################################################
17from quspin.basis import spinful_fermion_basis_general
18from quspin.operators import hamiltonian
19import numpy as np
20
21#
22###### define model parameters ######
23Lx, Ly = 3, 3 # linear dimension of spin 1 2d lattice
24N_2d = Lx * Ly # number of sites for spin 1
25#
26J = 1.0 # hopping matrix element
27U = 2.0 # onsite interaction
28mu = 0.5 # chemical potential
29#
30###### setting up user-defined BASIC symmetry transformations for 2d lattice ######
31s = np.arange(N_2d) # sites [0,1,2,...,N_2d-1] in simple notation
32x = s % Lx # x positions for sites
33y = s // Lx # y positions for sites
34T_x = (x + 1) % Lx + Lx * y # translation along x-direction
35T_y = x + Lx * ((y + 1) % Ly) # translation along y-direction
36P_x = x + Lx * (Ly - y - 1) # reflection about x-axis
37P_y = (Lx - x - 1) + Lx * y # reflection about y-axis
38S = -(s + 1) # fermion spin inversion in the simple case
39#
40###### setting up bases ######
41basis_2d = spinful_fermion_basis_general(
42 N_2d,
43 Nf=(3, 3),
44 double_occupancy=False,
45 kxblock=(T_x, 0),
46 kyblock=(T_y, 0),
47 pxblock=(P_x, 1),
48 pyblock=(P_y, 0), # contains GS
49 sblock=(S, 0),
50)
51print(basis_2d)
52#
53###### setting up hamiltonian ######
54# setting up site-coupling lists for simple case
55hopping_left = [[-J, i, T_x[i]] for i in range(N_2d)] + [
56 [-J, i, T_y[i]] for i in range(N_2d)
57]
58hopping_right = [[+J, i, T_x[i]] for i in range(N_2d)] + [
59 [+J, i, T_y[i]] for i in range(N_2d)
60]
61potential = [[-mu, i] for i in range(N_2d)]
62interaction = [[U, i, i] for i in range(N_2d)]
63#
64static = [
65 ["+-|", hopping_left], # spin up hops to left
66 ["-+|", hopping_right], # spin up hops to right
67 ["|+-", hopping_left], # spin down hopes to left
68 ["|-+", hopping_right], # spin up hops to right
69 ["n|", potential], # onsite potenial, spin up
70 ["|n", potential], # onsite potential, spin down
71 ["n|n", interaction],
72] # spin up-spin down interaction
73# build hamiltonian
74H = hamiltonian(static, [], basis=basis_2d, dtype=np.float64)
75# compute GS of H
76E_GS, psi_GS = H.eigsh(k=1, which="SA")