def DMFT_SCC(fDelta, fileGf): """This subroutine creates Delta.inp from Gf.out for DMFT on bethe lattice: Delta=t^2*G If Gf.out does not exist, it creates Gf.out which corresponds to the non-interacting model In the latter case also creates the inpurity cix file, which contains information about the atomic states.""" w_n = gf.matsubara_freq(BETA, 3 * BETA) try: hyb = 0.25 * np.squeeze(np.load(fileGf)) # If output file exists, start from previous iteration delta = np.array([w_n, hyb.real, hyb.imag]) if args.AFM: delta = np.array( [w_n, hyb[1].real, hyb[1].imag, hyb[0].real, hyb[0].imag]) except Exception: # otherwise start from non-interacting limit print('Starting from non-interacting model at beta' + str(BETA)) hyb = 0.25 * gf.greenF(w_n) if args.insulator: hyb = 0.25 * gf.greenF(w_n, sigma=-1j * args.U[0]**2 / 4 / w_n) # creating impurity cix file with open(params['cix'][0], 'w') as f: f.write(icix) # Preparing input file Delta.inp delta = np.array([w_n, hyb.real, hyb.imag]) if args.AFM: delta = np.array([w_n, hyb.real, hyb.imag, hyb.real, hyb.imag]) np.savetxt(fDelta, delta.T)
def test_pade(): """Test pade Analytical Continuation for the semi-circular DOS""" w_n = gf.matsubara_freq(200) giw = gf.greenF(w_n) omega = np.linspace(-0.7, 0.7, 100) # avoid semicircle edges gw_ref = gf.greenF(-1j * omega + 1e-5) pade_c = gf.pade_coefficients(giw, w_n) gw_cont = gf.pade_rec(pade_c, omega, w_n) assert np.allclose(gw_ref, gw_cont, 1e-3)
def gf_met(omega, mu, tp, t, tn): """Double semi-circular density of states to represent the non-interacting dimer """ g_1 = gf.greenF(omega, mu=mu - tp, D=2 * (t + tn)) g_2 = gf.greenF(omega, mu=mu + tp, D=2 * abs(t - tn)) g_d = .5 * (g_1 + g_2) g_o = .5 * (g_1 - g_2) return g_d, g_o
def energies(beta, filestr='SB_PM_B{}.h5'): """returns the potential, and kinetic energy Parameters ---------- beta : float, inverse temperature filestr : string, results file name, beta is replaced in format Returns ------- tuple of 3 ndarrays Contains, potential energy, Kinetic energy, values of U """ tau, w_n = gf.tau_wn_setup(dict(BETA=beta, N_MATSUBARA=beta)) giw_free = gf.greenF(w_n) e_mean = ipt.e_mean(beta) ekin = [] epot = [] with h5.File(filestr.format(beta), 'r') as results: for u_str in results: last_iter = results[u_str].keys()[-1] _, giw = get_giw(results[u_str], last_iter, tau, w_n) siw = get_sigmaiw(results[u_str], last_iter, tau, w_n) u_int = float(u_str[1:]) epot.append(ipt.epot(giw, siw, u_int, beta, w_n)) ekin.append(ipt.ekin(giw, siw, beta, w_n, e_mean, giw_free)) ur = np.array([float(u_str[1:]) for u_str in results]) return np.array(epot), np.array(ekin), ur
def free_energy_change(beta, u_int, mix_grid): tau, w_n = tau_wn_setup(dict(BETA=beta, N_MATSUBARA=2**11)) ig_iwn, is_iwn = dmft_loop(u_int, 0.5, -1.j / (w_n - 1 / w_n), w_n, tau, conv=1e-10) mg_iwn, ms_iwn = dmft_loop(u_int, 0.5, greenF(w_n), w_n, tau, conv=1e-10) solution_diff = mg_iwn - ig_iwn integrand = [] for l in mix_grid: g_in = mix(mg_iwn, ig_iwn, l) g_grad = one_loop(g_in, 0.5, U, w_n, tau) - g_in integrand.append(np.dot(g_grad, solution_diff).real / beta) return np.array([0] + [ trapz(integrand[:i], mix_grid[:i]) for i in range(2, len(mix_grid) + 1) ])
def hysteresis(beta, D_range): log_g_sig = [] tau, w_n = tau_wn_setup(dict(BETA=beta, N_MATSUBARA=2**11)) g_iwn = greenF(w_n, D=1) for D in D_range: g_iwn, sigma = dmft_loop(1, D / 2, g_iwn, w_n, tau) log_g_sig.append((g_iwn, sigma)) return log_g_sig
def hysteresis(beta, u_range): log_g_sig = [] tau, w_n = tau_wn_setup(dict(BETA=beta, N_MATSUBARA=beta)) g_iwn = greenF(w_n) for u_int in u_range: g_iwn, sigma = dmft_loop(u_int, 0.5, g_iwn, w_n, tau) log_g_sig.append((g_iwn, sigma)) return log_g_sig
def extract_double_occupation(beta, u_range): docc = [] tau, w_n = gf.tau_wn_setup(dict(BETA=beta, N_MATSUBARA=beta)) g_iwn = gf.greenF(w_n) for u_int in u_range: g_iwn, sigma = ipt.dmft_loop(u_int, 0.5, g_iwn, w_n, tau, conv=1e-4) docc.append(ipt.epot(g_iwn, sigma, u_int, beta, w_n) * 2 / u_int) return np.array(docc)
def setup_PM_sim(parms): tau, w_n = tau_wn_setup(parms) gw = greenF(w_n, mu=parms['MU'], D=2 * parms['t']) gt = gw_invfouriertrans(gw, tau, w_n) gt = interpol(gt, parms['n_tau_mc']) parms['dtau_mc'] = parms['BETA'] / parms['n_tau_mc'] v = ising_v(parms['dtau_mc'], parms['U'], L=parms['n_tau_mc']) return tau, w_n, gt, gw, v
def setup_PM_sim(parms): tau, w_n = tau_wn_setup(parms) gw = greenF(w_n, mu=parms['MU'], D=2*parms['t']) gt = gw_invfouriertrans(gw, tau, w_n) gt = interpol(gt, parms['n_tau_mc']) parms['dtau_mc'] = parms['BETA']/parms['n_tau_mc'] v = ising_v(parms['dtau_mc'], parms['U'], L=parms['n_tau_mc']) return tau, w_n, gt, gw, v
def test_ipt_pm_g(u_int, result, beta=50., n_tau=2**11, n_matsubara=64): parms = {'BETA': beta, 'N_TAU': n_tau, 'N_MATSUBARA': n_matsubara, 't': 0.5, 'MU': 0, 'U': u_int, } tau, w_n = tau_wn_setup(parms) g_iwn0 = greenF(w_n, D=2*parms['t']) g_iwn_log, sigma_iwn = ipt_imag.dmft_loop(100, parms['U'], parms['t'], g_iwn0, w_n, tau) assert np.allclose(result, g_iwn_log[-1][32:], atol=1e-3 )
def test_fourier_trasforms(chempot, beta=50., n_matsubara=128): """Test the tail improved fourier transforms""" parms = {'BETA': beta, 'N_MATSUBARA': n_matsubara} tau, w_n = gf.tau_wn_setup(parms) giw = gf.greenF(w_n, mu=chempot) for gwr in [giw, np.array([giw, giw])]: g_tau = gf.gw_invfouriertrans(gwr, tau, w_n, [1., -chempot, 0.25]) g_iomega = gf.gt_fouriertrans(g_tau, tau, w_n, [1., -chempot, 0.25]) assert np.allclose(gwr, g_iomega)
def test_fourier_trasforms(chempot, beta=50., n_tau=2**11, n_matsubara=64): """Test the tail improved fourier transforms""" parms = {'BETA': beta, 'N_TAU': n_tau, 'N_MATSUBARA': n_matsubara} tau, w_n = tau_wn_setup(parms) gw = greenF(w_n, mu=chempot) for gwr in [gw, np.array([gw, gw])]: g_tau = gw_invfouriertrans(gwr, tau, w_n) g_iomega = gt_fouriertrans(g_tau, tau, w_n) assert np.allclose(gwr, g_iomega)
def test_hilbert_trans_integral(halfbandwidth): """Test hilbert transform of semi-circle to direct integral""" w = np.linspace(-3, 3, 2**9) w_n = gf.matsubara_freq(20) giw = gf.greenF(w_n, D=halfbandwidth) rho_w = dos.bethe_lattice(w, halfbandwidth / 2) Apiw = np.array([simps(rho_w / (1j * iw - w), w) for iw in w_n]) assert np.allclose(Apiw, giw, 2e-4)
def test_tail_fit_semicirc(): wn = gf.matsubara_freq(50) gci = gf.greenF(wn) tailn = np.sum( np.random.randn(len(wn), 2) * 0.00006 * np.array( (1, 1j)), 1) / (wn**2 + 3) tail = gci + tailn fit_moments = gf.lin_tail_fit(wn, tail, -45, 45)[1] moment = np.array((-1, 0, 0.25)) print(fit_moments - moment) assert np.allclose(moment, fit_moments, atol=7e-3)
def setup_PM_sim(parms): """Setup the default state for a Paramagnetic simulation""" tau, w_n = tau_wn_setup(parms) giw = greenF(w_n, mu=parms['MU'], D=2 * parms['t']) gtau = gw_invfouriertrans(giw, tau, w_n) parms['dtau_mc'] = tau[1] intm = interaction_matrix(parms.get('BANDS', 1)) v = ising_v(parms['dtau_mc'], parms['U'], len(tau) * parms['SITES'], intm.shape[1], parms['spin_polarization']) return tau, w_n, gtau, giw, v, intm
def test_hilbert_trans_func(halfbandwidth): """Test Hilbert transforms of semi-circle""" # Match in the 2 forms w_n = gf.matsubara_freq(200) giw = gf.greenF(w_n, sigma=-1j / w_n, mu=-0.2, D=halfbandwidth) ss = gf.semi_circle_hiltrans(1j * w_n - .2 + 1j / w_n, D=halfbandwidth) assert np.allclose(ss, giw) # corresponds to semi-circle w = np.linspace(-3, 3, 2**9) ss = gf.semi_circle_hiltrans(w + 1e-5j, D=halfbandwidth) assert np.allclose(dos.bethe_lattice(w, halfbandwidth / 2), -ss.imag / np.pi, atol=1e-4)
def test_ipt_pm_g(u_int, result, beta=50., n_matsubara=64): """Test the solution of the single band impurity problem""" parms = { 'BETA': beta, 'N_MATSUBARA': n_matsubara, 't': 0.5, 'MU': 0, 'U': u_int, } tau, w_n = tau_wn_setup(parms) g_iwn0 = greenF(w_n, D=2 * parms['t']) g_iwn, _ = ipt_imag.dmft_loop(parms['U'], parms['t'], g_iwn0, w_n, tau) assert np.allclose(result, g_iwn, atol=3e-3)
def test_ipt_pm_g(u_int, result, beta=50., n_tau=2**11, n_matsubara=64): parms = { 'BETA': beta, 'N_TAU': n_tau, 'N_MATSUBARA': n_matsubara, 't': 0.5, 'MU': 0, 'U': u_int, } tau, w_n = tau_wn_setup(parms) g_iwn0 = greenF(w_n, D=2 * parms['t']) g_iwn_log, sigma_iwn = ipt_imag.dmft_loop(100, parms['U'], parms['t'], g_iwn0, w_n, tau) assert np.allclose(result, g_iwn_log[-1][32:], atol=1e-3)
def energy(beta, u_range, g_s_results): g_s_iw_log, w_n, tau = g_s_results g_iwfree = greenF(w_n) mu = fsolve(n_half, 0., beta)[0] e_mean = quad(dos.bethe_fermi_ene, -1., 1., args=(1., mu, 0.5, beta))[0] kin = np.asarray([ ekin(g_iw, s_iw, beta, w_n, e_mean, g_iwfree) for g_iw, s_iw in g_s_iw_log ]) pot = np.asarray([ epot(g_iw, s_iw, u, beta, w_n) for (g_iw, s_iw), u in zip(g_s_iw_log, u_range) ]) return kin, pot
def DMFT_SCC(fDelta): """This subroutine creates Delta.inp from Gf.out for DMFT on bethe lattice: Delta=t^2*G If Gf.out does not exist, it creates Gf.out which corresponds to the non-interacting model In the latter case also creates the inpurity cix file, which contains information about the atomic states.""" fileGf = 'Gf.out' try: Gf = np.loadtxt(fileGf).T # If output file exists, start from previous iteration except Exception: # otherwise start from non-interacting limit print('Starting from non-interacting model at beta' + str(BETA)) w_n = gf.matsubara_freq(BETA) Gf = gf.greenF(w_n) Gf = np.array([w_n, Gf.real, Gf.imag]) # Preparing input file Delta.inp delta = np.array( [Gf[0], 0.25 * Gf[1], 0.25 * Gf[2], 0.25 * Gf[1], 0.25 * Gf[2]]).T np.savetxt(fDelta, delta)
def test_fit_gf(): """Test the interpolation of Green function in Bethe Lattice""" w_n = gf.matsubara_freq(100, 3) giw = gf.greenF(w_n).imag cont_g = gf.fit_gf(w_n, giw) assert abs(cont_g(0.) + 2.) < 1e-4
0.5, -1.j / (w_n - 1 / w_n), w_n, tau, conv=1e-12) igw = pade_continuation(ig_iwn, w_n, omega, np.arange(100)) isigma_w = pade_continuation(is_iwn, w_n, omega, np.arange(100)) lat_gf = 1 / (np.add.outer(-eps_k, omega + 4e-2j) - isigma_w) lat_Aw = -lat_gf.imag / np.pi icond = optical_conductivity(lat_Aw, lat_Aw, nf, omega, dosde) ############################################################################### # Metal Calculations # ------------------ mg_iwn, s_iwn = dmft_loop(U, 0.5, greenF(w_n), w_n, tau, conv=1e-10) mgw = pade_continuation(mg_iwn, w_n, omega, np.arange(100)) msigma_w = omega - 0.25 * mgw - 1 / mgw lat_gf = 1 / (np.add.outer(-eps_k, omega + 4e-2j) - msigma_w) lat_Aw = -lat_gf.imag / np.pi mcond = optical_conductivity(lat_Aw, lat_Aw, nf, omega, dosde) ############################################################################### # Plots # ----- fig_giw, giw_ax = plt.subplots() fig_gw, gw_ax = plt.subplots() fig_sw, sw_ax = plt.subplots(1, 2, sharex=True) fig_cond, cond_ax = plt.subplots()
ax.set_zlim3d(-2., 1.) ############################################################################### # Results from IPT # ---------------- # # Starting from the Metallic seed on the Bethe Lattice the DMFT # equations are solved iteratively in by perturbation theory in the # Matsubara axis. The resulting Green's function is then approximated # by its Padé approximant which allows to evaluate it on the upper # complex plane. beta = 90. U = 2.7 tau, w_n = tau_wn_setup(dict(BETA=beta, N_MATSUBARA=1024)) g_iwn0 = greenF(w_n) g_iwn, s_iwn = dmft_loop(U, 0.5, g_iwn0, w_n, tau, conv=1e-12) x = int(2 * beta) w_set = np.arange(x) pc = pade_coefficients(g_iwn[w_set], w_n[w_set]) ax = plot_complex_gf(omega, np.linspace(1e-3, 1.2, 30), w_n[:17], lambda z: pade_rec(pc, z, w_n[w_set])) ax.view_init(15, -64) ax.set_zlim3d([-2, 1]) ############################################################################### # For the insulating solution U = 3.2
from dmft import ipt_imag from dmft.common import greenF, tau_wn_setup import numpy as np import matplotlib.pylab as plt parms = { 'BETA': 50, 'MU': 0, 'U': 3, 't': 0.5, 'N_TAU': 2**10, 'N_MATSUBARA': 64 } tau, w_n = tau_wn_setup(parms) g_iwn0 = greenF(w_n, D=2 * parms['t']) g_iwn_log, sigma_iwn = ipt_imag.dmft_loop(100, parms['U'], parms['t'], g_iwn0, w_n, tau) g_iwn = g_iwn_log[-1] fig_gw, gw_ax = plt.subplots() gw_ax.plot(w_n, g_iwn.real, '+-', label='RE') gw_ax.plot(w_n, g_iwn.imag, 's-', label='IM') plt.plot(w_n, -1 / w_n, label='high w tail ') gw_ax.set_xlim([0, 6.5]) cut = int(6.5 * parms['BETA'] / np.pi) gw_ax.set_ylim([g_iwn.imag[:cut].min() * 1.1, 0]) plt.legend(loc=0) plt.ylabel(r'$G(i\omega_n)$') plt.xlabel(r'$i\omega_n$') plt.title(r'$G(i\omega_n)$ at $\beta= {}$, $U= {}$'.format(
""" # Author: Óscar Nájera from __future__ import division, absolute_import, print_function import dmft.common as gf import matplotlib.pyplot as plt plt.matplotlib.rcParams.update({'figure.figsize': (8, 8), 'axes.labelsize': 22, 'axes.titlesize': 22, 'figure.autolayout': True}) tau, w_n = gf.tau_wn_setup(dict(BETA=64, N_MATSUBARA=128)) fig, ax = plt.subplots(2, 1) c_v = ['b', 'g', 'r', 'y'] for mu, c in zip([0, 0.3, 0.6, 1.], c_v): giw = gf.greenF(w_n, mu=mu) gtau = gf.gw_invfouriertrans(giw, tau, w_n, [1., -mu, 0.25]) ax[0].plot(w_n, giw.real, c+'o:', label=r'$\Re G$, $\mu={}$'.format(mu)) ax[0].plot(w_n, giw.imag, c+'s:') ax[1].plot(tau, gtau, c, lw=2, label=r'$\mu={}$'.format(mu)) ax[0].set_xlim([0, 6]) ax[0].set_xlabel(r'$i\omega_n$') ax[0].set_ylabel(r'$G(i\omega_n)$') ax[1].set_xlabel(r'$\tau$') ax[1].set_ylabel(r'$G(\tau)$') ax[1].set_xlim([0, 64]) ax[0].legend(loc=0) ax[1].legend(loc=0)
plt.ylabel(r'$\Sigma(\omega)$') plt.xlabel(r'$\omega$') plt.title(r'$\Sigma(\omega)$ at $U= {}$'.format(U)) plt.legend(loc=0) plt.ylim([-3.5, 2]) ############################################################################### # The Green Function # ------------------ plt.figure() g_b = 1 / (w + tp - sb) plt.plot(w, g_b.real, label=r"Re Bond") plt.plot(w, g_b.imag, label=r"Im Bond") plt.figure() g_b = gf.greenF(-1j * w, sb, tp) zeta = w + tp - sb g_b = 2 * zeta * (1 - np.sqrt(1 - 1 / zeta**2)) g_b = 1 / (g0_1_b - sb) plt.plot(w, g_b.real, label=r"Re Bond") plt.plot(w, g_b.imag, label=r"Im Bond") plt.plot(w, sb.real - w - tp, label=r'$\Sigma_{S} - w + t_\perp$') plt.ylabel(r'$G(\omega)$') plt.xlabel(r'$\omega$') plt.title(r'$G(\omega)$ at $U= {}$'.format(U)) plt.ylim([-3.5, 2]) plt.legend(loc=0) ############################################################################### # The Band Dispersion
from dmft.common import greenF, tau_wn_setup from dmft.twosite import matsubara_Z import numpy as np import matplotlib.pylab as plt U = np.linspace(0, 2.7, 36) U = np.concatenate((U, U[-2:11:-1])) parms = {'MU': 0, 't': 0.5, 'N_TAU': 2**10, 'N_MATSUBARA': 2**7} lop_g=[] for beta in [16, 25, 50]: u_zet = [] parms['BETA'] = beta tau, w_n = tau_wn_setup(parms) g_iwn0 = greenF(w_n, D=2*parms['t']) for u_int in U: mix = 0.4 if u_int > 1.5 else 1 g_iwn_log, sigma = ipt_imag.dmft_loop(100, u_int, parms['t'], g_iwn0, w_n, tau, mix) g_iwn0 = g_iwn_log[-1] lop_g.append(g_iwn_log) u_zet.append(matsubara_Z(sigma.imag, beta)) plt.plot(U, u_zet, label='$\\beta={}$'.format(beta)) plt.title('Hysteresis loop of the quasiparticle weigth') plt.legend() plt.ylabel('Z') plt.xlabel('U/D')