This documentation was intended for users who want a brief introduction how to use the spinpackage for the Hubbard model. We choose an N=8 chain for demonstration.
We choose the N=8 Hubbard chain with periodic boundary conditions (PBC) as an example to exercise the use of spinpack. This model is big enough to see the use of symmetries and small enough to get results by other programs which dont use symmetries. Using symmetries (p.e. the translation and reflection) we are able to reduce the Hilbert space by a factor of N to 2N for chains. The hamiltonian is
H = t1 \sum_{i,j,s} c^+(is)c^-(j,s) + U \sum_{i} n_{iu}n_{id}where i,j are neighbours of a chain, c^+ and c^- the fermionic creation and annihilation operators and n the number operator.
Download the latest spinpack package
and untar the tgz file (you probably did already).
Go to the spinpack directory and start ./configure
.
If you want special
features (parallel processing etc.) study the documentation. I skip
over this features becourse we dont need it for our example.
If you download a newer version than v2.41 reading doc/history.tex
is probably a good idea.
After that start make test
to get a default configuration
and test files. You also should check that in the file
src/config.h
NN is set to 8 (or bigger),
VecType is set to 5 and - most important - CM(JJ,tJ,tU) is set to tU
which stands for the Hubbard model.
If it set otherwise correct the values and
compile again using make
.
Now enter the working path exe
to go to next step.
First we have to generate the model file (daten.def).
For first daten.def is created by hand or the version
generated by make test
should be modified. Later
the programs in the models-path can be used to create more complicated
models.
The file daten.def should look like this:
# def-file, 1D-chain # automaticly generated by m_1D v0.1 n0=8 PBC #===edge=== 8 0 0 999 #+++model+++ # NN=Number_of_sites Nw=Number_of_bonds 8 8 0 # Sites: only column s and U# is important, ignore the rest for first # s X Y Z e# U# (s=siteindex (X Y Z)=position #=index of parameter) 0 1.0 0.0 0.0 e8 u7 1 2.0 0.0 0.0 e8 u7 2 3.0 0.0 0.0 e8 u7 3 4.0 0.0 0.0 e8 u7 4 5.0 0.0 0.0 e8 u7 5 6.0 0.0 0.0 e8 u7 6 6.0 0.0 0.0 e8 u7 7 7.0 0.0 0.0 e8 u7 # Bonds: column 2 and 3 list the connected sites, # Bond s1 s2 t# j# v# w# 0 0 1 t3 j1 v0 w4 1 1 2 t3 j1 v0 w4 2 2 3 t3 j1 v0 w4 3 3 4 t3 j1 v0 w4 4 4 5 t3 j1 v0 w4 5 5 6 t3 j1 v0 w4 6 6 7 t3 j1 v0 w4 7 7 0 t3 j1 v0 w4 + #---model--- # note: for v2.48 j1 j2 t3 t4 v0 w5 w6 u7 e8 is used by (m_1d 8)All parameters (e#, U#, t#, J#, V#, w#) are indexed. In our case all hopping integrals t (or t#) are indexed via parameter p1 and Coulomb integrales U (or U#) are indexed via parameter p7. The indexes could be choosen freely, only index 0 is reserved for "unused". The value t and U itself is set in the parameter file
daten.i
and has no influence to the symmetry of the model.
The plus-sign is ignored and is only set to signal the periodic bound
to some scripts (not explained here), which generate graphics from this
file.
Next we have to edit the parameter file daten.i
.
Have a look to the spinpack documentation to get an overview about all
possible parameters. At the moment it is enough to check that pew is set to 2,
nev is set to 1 and sisj is set to 1.
param
is the parameter list where the index of
daten.def points to. We need to set the 1st and the 7nd value, which stands
for t and U. Set the rest to zero. nud
is the number of up-
and down-spins. sym_ud
is the expectation value of the
spin inversion symmetry for the case nu=nd and can be set to +1 or -1.
sym_ud
can also be set to 0 to ignore
spin inversion.
sym_ud
is ignored for the nonsymmetric case nu!=nd
(!= stands for nonequal).
sym_k
is a list of symmetries and will described later.
a0
is the trigger for starting the lanczos algorithm.
Here is a short excerpt of the relevant part of the parameter file
daten.i:
# set t=p3=1.0 and U=p7=8.0 param= 0, 0, 1.0, 0, 0, 0, 8.0 # set nu=4 and nd=4 nud=4,4 # sym_k (4 numbers follow which are described here) # -2 stands for "ignore 1st two found symmetries" (we are not interested in exotic symmetries) # 0 stands for k_translation=0 (also 1,2,...7 and -1 for "dont use" possible) # 0 stands for k_reflection=0 (also 1 for pi and -1 for "dont use" possible) # -1000 ignore the rest of symmetries (do not think about it) sym_k= -2 0 0 -1000 sym_ud=+1 # u/d-symmetry (only +1,-1 possible, used in case nu=nd) a0
Now you can start spinpack by calling
nohup nice ./spin >ooo &
. Output is written to the
file ooo.
The lowest energy we get for the choosen symmetry sector is -2.23595770,
which is the second excitation for (nu=nd=4)
and not the overall groundstate energy. You find this energy in the
output file on the line starting with erg=
.
To get the groundstate energy, we need to choose the right symmetry sector.
Simplest method to get this sector is to search all possible sectors.
The input file looks like this:
# this is an daten.i excerpt
nev=0 # now we are only interested on energies not eigenvectors
nud=4,4 # 4 up- and 4 down-spins
sym_ud=+1 # even spin inversion symmetry
sym_k= -2 0 0 -1000 # translation + reflection (kt=0, kr=0 in units of 2pi/l)
a0 # trigger diagonalization
sym_k= -2 0 1 -1000 # translation + reflection (kt=0, kr=1)
a0 # trigger diagonalization
sym_k= -2 1 -1000 # for kt=1 we have no additional reflection symmetry
a0
sym_k= -2 2 -1000 # kt=2
a0
sym_k= -2 3 -1000 # kt=3
a0
sym_k= -2 4 0 -1000 # kt=4, again we can use reflection kr=0
a0
sym_k= -2 4 1 -1000 # kt=4, again we can use reflection kr=1
a0
# we do not need kt=5,6,7 because its symmetric to kt=3,2,1
# now repeat with odd symmetry
sym_ud=-1 # odd spin inversion symmetry
sym_k= -2 0 0 -1000 # translation + reflection (kt=0, kr=0 in units of 2pi/l)
a0 # trigger diagonalization
sym_k= -2 0 1 -1000 # translation + reflection (kt=0, kr=1)
a0 # trigger diagonalization
sym_k= -2 1 -1000 # for kt=1 we have no additional reflection symmetry
a0
sym_k= -2 2 -1000 # kt=2
a0
sym_k= -2 3 -1000 # kt=3
a0
sym_k= -2 4 0 -1000 # kt=4, again we can use reflection kr=0
a0
sym_k= -2 4 1 -1000 # kt=4, again we can use reflection kr=1
a0
# we do not need kt=5,6,7 because its symmetric to kt=3,2,1
Now start ./spin again and look at the output file.
To get a better overview use a script to sort the results
(../utils/o2tower.sh < ooo
).
What you get is something like
# computed by spinpack v2.21, v2.41
# o2tower.sh v2.36
# t=1 U=8 N=8 ud=4,4
#S erg ea? sym remark
0 -2.6661474 1 q_4_1+ low # lowest energy (ground state)
0 -2.4265639 1 q_0_1-
0 -2.23595770 1 q_0_0+ # n1=181
0 -2.1145210 1 q_3-
0 -1.9665456 1 q_1-
0 -1.8323557 1 q_2-
0 -1.7960959 1 q_4_1+
0 -1.7702362 1 q_1+
0 -1.7239598 1 q_2+
0 -1.5543477 1 q_2+
0 -1.5246340 1 q_0_1-
0 -1.4927340 1 q_3+
0 -1.4362851 1 q_4_0-
0 -1.3688978 1 q_1-
0 -1.3260505 1 q_0_0+
0 -1.3072995 1 q_4_1+
0 -1.2550183 1 q_3-
0 -1.2476331 1 q_2-
0 -1.2062132 1 q_3-
0 -1.1701277 1 q_4_1+
0 -1.1598897 1 q_1+
...,
where energy is listed in the 2nd column and symmetry is listed in the
4th column.
# further remarks (JS-2010+2018) # make test uses t=-1 (which is symmetric to t=+1) # t=1 U=8 N=8 ud=4,4 sym_ud=+1 sym_k=-2 4 1 n1= 164 # sym_ud=0 sym_k=-9999 nud=4,4 n1=(4of8)^2=70^2=4900 # ud=4,4 E0=-2.66614755 ud=+1 sym_k=-2 4 1 ZMag= 0.09635516 XYMag= 0.19271043 # ud=4,4: maxDiag(cfg=0x0f)=4*U=32.00000000 ud=+1 sym_k=-2 0 0 # but maxE=34.66614742 ud=+1 sym_k=-2 0 0 # t=1 U=8 N=8 ud=2,1 n1=224 hnz/n1=6.43 #2S erg ea? sym remark 1 -4.82842712 # lower than ud=4,4! 1 -4.82138265 1 -4.30697923 ... # t=1 U=8 N=3 ud=2,1 NOS1SYM must be set! n1=9 hnz/n1=5.00 using a4 #2S erg ea? sym remark 1 -0.71663480 2 3 0.00000000 1 1 6.66074634 2 1 8.00000000 2 1 10.05588846 2 # all! # t=1 U=0 N=3 ud=2,1 NOS1SYM must be set! n1=9 hnz/n1=5.00 using a4 #2S erg ea? sym remark 1 -3.00000000 2 3 0.00000000 1 1 0.00000000 4 1 3.00000000 2 # all!
# NN=40 1.2GHz v2.48 2014-05 # N=8 4+4 n1=181 -2.23595738 E0/N= -0.27949467 8s # N=16 4+4 n1=52e3 -11.27232776 E0/N= -0.70452049 59s (25s get_maxscfg) # N=16 8+8 n1=2.6e6 -5.06002381 E0/N= -0.31625149 2.6m # rns=1m pns=5m++ SH=20m++ (v2.43 80m++) NN=16 SH=1.4m PRF: scfg1 t[s]= 3.78 loops= 65536 t/cfg[ns]= 57739.9 old v2.43 NN=40 PRF: scfg1 t[s]= 1.18 loops= 65536 t/cfg[ns]= 17980.4 new v2.48 t/3 PRF: scfg4 t[s]= 2.42 loops= 65536 t/cfg[ns]= 36983.8 0 PRF: scfg2 t[s]= 4.30 loops= 65536 t/cfg[ns]= 65612.8 PRF: scfg3 t[s]= 7.76 loops= 65536 t/cfg[ns]= 118382.0 PRF: scfg1 t[s]= 1.36 loops= 1048576 t/cfg[ns]= 1295.5 new NN=16 SH=1.4m # N=32 chain speed 2014 1.2GHz v2.48 PRF: scfg1 t[s]= 4.25 loops= 65536 t/cfg[ns]= 64828.1 PRF: scfg4 t[s]= 6.33 loops= 65536 t/cfg[ns]= 96513.7 0 PRF: scfg2 t[s]= 11.58 loops= 65536 t/cfg[ns]= 176668.4 PRF: scfg3 t[s]= 10.82 loops= 65536 t/cfg[ns]= 165107.9 get_maxscfg vvv=3