Skip to content

Commit dc25c10

Browse files
committed
Added Example 1 with plotting script
1 parent bf252c7 commit dc25c10

2 files changed

Lines changed: 175 additions & 0 deletions

File tree

examples/E1/Bethe_1orb.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
######################################################################
2+
# Example 1
3+
# Finite temperature calculations for the half-filled Hubbard model
4+
# on the Bethe lattice. Storing total energy and entropy per site
5+
######################################################################
6+
7+
import numpy as np
8+
from gem.fragment import Fragment
9+
from gem.lattice import Lattice
10+
from gem.solvers.simple_ed import SimpleED
11+
12+
# Parameters that determine the physical dimentions
13+
# 1 orbital with 2 spins, B=3 bath per orbital, total 8
14+
B = 3
15+
nimp = 2
16+
nbath = nimp*B
17+
ntot = nimp+nbath
18+
19+
# Physical Parameters
20+
U = 2.0
21+
Tlist = np.hstack( (np.array([0.0]), np.logspace(np.log10(1e-2), np.log10(1.0), 41)) )
22+
mu = 0.0
23+
24+
# Self-consistency Parameters
25+
itmax = 300
26+
mix = 0.1
27+
tol = 1e-4
28+
spin_pen = 0.0
29+
Tsmearing = 1e-4
30+
31+
# Non-interacting density of states and lattice object
32+
e_list = np.linspace(-1, 1, 5001)
33+
wks = np.sqrt(1 - e_list**2)
34+
wks /= np.sum(wks)
35+
eks = e_list[:, None, None] * np.eye(2, dtype=np.complex128)
36+
37+
lattice = Lattice(eks, wk_list=wks)
38+
39+
# Local Hamiltonian
40+
eloc = np.zeros((nimp, nimp))
41+
eloc[0,0] = -U/2.
42+
eloc[1,1] = -U/2.
43+
# Interaction tensor of the embedded space
44+
Utensor = np.zeros((nimp, nimp, nimp, nimp))
45+
Utensor[0,0,1,1] = U
46+
Utensor[1,1,0,0] = U
47+
48+
# SimpleED solver initialization
49+
edsolver = SimpleED(ntot, use_Ntot=True, use_Sz=True,
50+
N_sector=None, Sz_sector=None, dtype=np.float64,
51+
solver_params={'spin_pen': spin_pen})
52+
53+
# Fragment initialization
54+
Lambda0 = None; R0 = None
55+
fragment = Fragment(nimp, nbath, eloc, Utensor, edsolver, Lambda=Lambda0, R=R0, verbose=2)
56+
57+
def check_convergence(R_new,L_new, R_old,L_old):
58+
# Only 1 spin and gauge invariant difference
59+
L_eval_new, UL_new = np.linalg.eigh(L_new[::2,::2])
60+
L_eval_old, UL_old = np.linalg.eigh(L_old[::2,::2])
61+
diff_R = np.abs(np.abs(UL_old @ R_old[::2,::2]) - np.abs(UL_new @ R_new[::2,::2])).max()
62+
diff_Lambda = np.abs(L_eval_new - L_eval_old).max()
63+
diff = max(diff_R, diff_Lambda)
64+
return diff
65+
66+
Elist = []
67+
Slist = []
68+
docclist = []
69+
70+
for T in Tlist:
71+
print('--------------------------------------')
72+
print(f'GEM loop started with U={U} and T={T}')
73+
74+
# Self consistency loop
75+
for it in range(itmax):
76+
print(f"----- ghost-RISB iteration {it} / {itmax} -----")
77+
78+
lattice.solve_qp([fragment], T=T, Tsmearing=Tsmearing)
79+
80+
fragment.update_hybridization(T=T, use_Sz=True)
81+
82+
fragment.solve_impurity(mu, T=T)
83+
84+
Lambda_old = fragment.Lambda.copy()
85+
R_old = fragment.R.copy()
86+
87+
fragment.update_self_energy(T=T, use_Sz=True)
88+
89+
Lambda_new = fragment.Lambda
90+
R_new = fragment.R
91+
92+
diff = check_convergence(R_new,Lambda_new, R_old,Lambda_old)
93+
print(f"iteration: {it} diff={diff}")
94+
95+
fragment.Lambda = (1 - mix) * Lambda_new + mix * Lambda_old
96+
fragment.R = (1 - mix) * R_new + mix * R_old
97+
98+
99+
if (diff < tol and it > 2) or it == itmax - 1:
100+
print(f"----- Exiting loop with diff={diff} after {it} iterations (max={itmax}) -----")
101+
break
102+
103+
104+
docc = fragment.E2loc/U
105+
docclist.append(docc)
106+
ekin = lattice.compute_ekin([fragment],T=T,Tsmearing=Tsmearing)
107+
eimp = fragment.compute_energy()
108+
etot = (eimp+ekin).real
109+
# Free-energy functional
110+
L = lattice.compute_functional([fragment],T=T, Tsmearing=Tsmearing).real
111+
S = (etot-L)/T if T > 0 else 0.0
112+
113+
Elist.append(etot)
114+
Slist.append(S)
115+
116+
print('--------------------------------------')
117+
print(f'GEM loop ended with U={U} and T={T}')
118+
print(f'returning docc={docc}, Etot={etot} and S={S}')
119+
print('--------------------------------------')
120+
121+
122+
np.savetxt('Tlist.dat',Tlist)
123+
np.savetxt('Elist.dat',Elist)
124+
np.savetxt('Slist.dat',Slist)
125+
np.savetxt('docclist.dat',docclist)

examples/E1/plot_E1.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
4+
T=np.loadtxt('Tlist.dat')
5+
docc=np.loadtxt('docclist.dat',dtype=np.complex128)
6+
E=np.loadtxt('Elist.dat')
7+
S=np.loadtxt('Slist.dat')
8+
9+
cp='blue'
10+
cl='red'
11+
12+
plt.figure(figsize=(4,4))
13+
plt.plot(T[1:],E[1:],marker='.',color=cp,label='E(T>0)')
14+
plt.axhline(E[0],color=cl,linestyle=':',label='E(T=0)')
15+
plt.xlabel('T/D')
16+
plt.ylabel('E(T)/D')
17+
plt.xscale('log')
18+
plt.legend()
19+
plt.tight_layout()
20+
plt.savefig('Eplot.svg')
21+
plt.show()
22+
23+
24+
plt.figure(figsize=(4,4))
25+
plt.plot(T[1:],S[1:],marker='.',color=cp,label='S(T>0)')
26+
plt.axhline(S[0],color=cl,linestyle=':',label='S(T=0)')
27+
plt.xlabel('T/D')
28+
plt.ylabel('S(T)')
29+
plt.xscale('log')
30+
plt.legend()
31+
plt.tight_layout()
32+
plt.savefig('Splot.svg')
33+
plt.show()
34+
35+
36+
plt.figure(figsize=(4,4))
37+
plt.plot(T[1:],docc[1:],marker='.',color=cp,label='docc(T>0)')
38+
plt.axhline(docc[0],color=cl,linestyle=':',label='docc(T=0)')
39+
plt.xlabel('T/D')
40+
plt.ylabel(r'$\langle n_{\uparrow} n_{\downarrow}\rangle$')
41+
plt.xscale('log')
42+
plt.legend()
43+
plt.tight_layout()
44+
plt.savefig('doccplot.svg')
45+
plt.show()
46+
47+
48+
49+
50+

0 commit comments

Comments
 (0)