def simple_test(): beta = params['beta'] nw = params['nw'] tau = linspace(0, beta, 2 * nw + 1) wn = (2.0 * arange(nw) + 1.0) * pi / beta vn = (2.0 * arange(nw + 1)) * pi / beta E1 = 0.2 E2 = 0.8 Gw1 = 1.0 / (1j * wn - E1) Gw2 = 1.0 / (1j * wn - E2) nF1 = 1.0 / (exp(beta * E1) + 1.0) nF2 = 1.0 / (exp(beta * E2) + 1.0) exact = (nF1 - nF2) / (1j * vn + E1 - E2) wr = random.randn(nw) + 1j * random.randn(nw) t1 = fourier.w2t(wr, beta, 0, 'fermion', -1) w1, jump = fourier.t2w(t1, beta, 0, 'fermion') print('jump\n', jump) print('diff\n', mean(abs(w1 - wr))) figure() plot(wr.real - w1.real) show() t1 = fourier.w2t(wr, beta, 0, 'boson') w1 = fourier.t2w(t1, beta, 0, 'boson') print('diff\n', mean(abs(w1 - wr))) figure() plot(wr.real - w1.real) show()
def get_pade(D, beta, ikx, iky, w): Dt = D[ikx, iky] Dw = fourier.t2w(Dt, beta, 0, 'boson') nw = len(Dw) ivns = 1j * 2 * np.arange(nw) * np.pi / beta #print('shape Dw', Dw.shape) #print('ivns shape', ivns.shape) # extend to negative freqs # (would be different for fermions) ivns = np.concatenate((-ivns[1:][::-1], ivns)) Dw = np.concatenate((Dw[1:][::-1], Dw)) #print('ivns shape', ivns.shape) #print('Dw shape', Dw.shape) #plt.figure() #plt.plot(ivns.real, Dw.real) #plt.title('Dw') i0 = nw - 0 i1 = nw + 10 inds = range(i0, i1, 1) #print('zs ', ivns[inds]) p = pade.fit(ivns[inds], Dw[inds]) return -1.0 / np.pi * np.array([p(x) for x in w]).imag
def dyson(wn, beta, H, St, axis): dim = np.shape(H)[0] Sw, jumpS = fourier.t2w(St, beta, axis, 'fermion') tau0 = np.identity(dim) Gw = np.linalg.inv(1j*wn[:,None,None]*tau0 - H[None,:,:] - Sw) jumpG = -np.identity(dim)[None,:,:] return fourier.w2t(Gw, beta, axis, 'fermion', jumpG)
def compute_jjcorr(self, savedir, G, D): ''' input is G(tau) returns jjcorr(q=0, tau) ''' ks = np.arange(-np.pi, np.pi, 2 * np.pi / self.nk) sin = np.sin(ks) cos = np.cos(ks) fk = (-2 * self.t * sin[:, None] - 4 * self.tp * sin[:, None] * cos[None, :]) jj0t = 2.0 / self.nk**2 * np.sum( (fk**2)[:, :, None] * G * G[:, :, ::-1], axis=(0, 1)) path = os.path.join(savedir, 'jj0t') np.save(path, jj0t) vn = 2 * np.arange(self.nw + 1) * np.pi / self.beta D0w = self.compute_D(vn, 0) jj0v = fourier.t2w(jj0t, self.beta, 0, 'boson') jjv = jj0v / (1 + self.g0**2 * D0w[0, 0] * jj0v) #jjv = jj0v / (1 + self.g0**2 * (-2 / self.omega) * jj0v) path = os.path.join(savedir, 'jj0v') np.save(path, jj0v) path = os.path.join(savedir, 'jjv') np.save(path, jjv)
def old_test_dyson(): ''' embedding selfenergy test ''' beta = 16.0 nw = 128 dim = 1 norb = 3 wn = (2 * np.arange(nw) + 1) * np.pi / beta H = np.random.randn(norb, norb) H += np.transpose(H) # solve full dyson for bare Green's function tau0 = np.identity(norb) Gw_exact = np.linalg.inv(1j * wn[:, None, None] * tau0 - H[None, :, :]) jump = -np.identity(norb) Gt_exact = fourier.w2t(Gw_exact, beta, 0, 'fermion', jump) figure() plot(Gt_exact[:, 0, 0].real) plot(Gt_exact[:, 0, 0].imag) title('exact G') # solve for 11 component using embedding selfenergy tau0 = np.identity(norb - dim) Gw_bath = np.linalg.inv(1j * wn[:, None, None] * tau0 - H[None, dim:, dim:]) jump = -np.identity(norb - dim) Gt_bath = fourier.w2t(Gw_bath, beta, 0, 'fermion', jump) St = np.einsum('ab,wbc,cd->wad', H[:dim, dim:], Gt_bath, H[dim:, :dim]) Sw = fourier.t2w(St, beta, 0, 'fermion')[0] tau0 = np.identity(dim) Gw = np.linalg.inv(1j * wn[:, None, None] * tau0 - H[None, :dim, :dim] - Sw) jump = -np.identity(dim) Gt = fourier.w2t(Gw, beta, 0, 'fermion', jump) print('diff') print(np.mean(np.abs(Gt - Gt_exact[:, :dim, :dim]))) figure() plot(Gt[:, 0, 0].real) plot(Gt[:, 0, 0].imag) title('embedding test') show()
def dyson_fermion(self, wn, ek, mu, S, axis): Sw, jumpS = fourier.t2w(S, self.beta, axis, 'fermion') if hasattr(self, 'fixed_mu'): mu = self.fixed_mu else: if abs(self.dens - 1.0) > 1e-10: mu_new = optimize.fsolve( lambda mu: self.compute_fill(self.compute_G( wn, ek, mu, Sw)) + self.compute_n_tail(wn, ek, mu) - self.dens, mu)[0] mu = mu_new * 0.9 + mu * 0.1 else: mu = 0 # old way : misses the contribution to n from the sum in the tails ''' else: if abs(self.dens-1.0)>1e-10: mu_new = optimize.fsolve(lambda mu : self.compute_fill(self.compute_G(wn,ek,mu,Sw))-self.dens, mu)[0] mu = mu_new*0.9 + mu*0.1 else: mu = 0 ''' ''' # this is for density based on sum over iwn. # But this is not jump corrected (missing the infinite tail so, probably it is less accurate than using the tau value) else: if abs(self.dens-1.0)>1e-10: mu_new = optimize.fsolve(lambda mu : self.compute_fill(self.compute_G(wn,ek,mu,Sw))-self.dens, mu)[0] mu = mu_new*0.9 + mu*0.1 else: mu = 0 ''' Gw = self.compute_G(wn, ek, mu, Sw) if len(shape(S)) == self.dim + 3: # superconducting case shp = ones(self.dim + 3, int) shp[-2] = 2 shp[-1] = 2 jumpG = -reshape(identity(2), shp) else: jumpG = -1 return mu, fourier.w2t(Gw, self.beta, axis, 'fermion', jumpG)
def compute_jjcorr(self, savedir, G, GR): wn, vn, ek, w, nB, nF, DRbareinv = self.setup_realaxis() # convert to imaginary frequency G = fourier.t2w(G, self.beta, self.dim, 'fermion')[0] # compute Gsum Gsum = np.zeros([self.nk, self.nk, self.nr], dtype=complex) for i in range(self.nr): Gsum[:, :, i] = np.sum(G / ( (w[i] + 1j * wn)[None, None, :]), axis=2) / self.beta # handle sum over pos and negative freqs Gsum += np.conj(Gsum) print('finished Gsum') del G ks = np.arange(-np.pi, np.pi, 2 * np.pi / self.nk) sin = np.sin(ks) cos = np.cos(ks) fk = (-2 * self.t * sin[:, None] - 4 * self.tp * sin[:, None] * cos[None, :]) GA = np.conj(GR) A = -1.0 / np.pi * GR.imag A *= (fk**2)[:, :, None] jj0w = 2.0 * self.dw / self.nk**2 * np.sum( basic_conv(A, Gsum, ['z,w-z'], [2], [False], izero=self.izero)[:,:,:self.nr] \ -basic_conv(A, GA*nF[None,None,:], ['w+z,z'], [2], [False], izero=self.izero)[:,:,:self.nr] \ +basic_conv(A*nF[None,None,:], GA, ['w+z,z'], [2], [False], izero=self.izero)[:,:,:self.nr], axis=(0,1)) path = os.path.join(savedir, 'jj0w') np.save(path, jj0w) del GA del A del Gsum print('done jj0w') DR0 = 1 / DRbareinv jjw = jj0w / (1 + self.g0**2 * DR0 * jj0w) path = os.path.join(savedir, 'jjw') np.save(path, jjw)
def err_sigma(plotting=False): beta = params['beta'] N = params['nw'] tau = linspace(0, beta, 2 * N + 1) wn = (2.0 * arange(N) + 1.0) * pi / beta vn = (2.0 * arange(N + 1)) * pi / beta E = 0.2 omega = 0.5 Gw0 = 1.0 / (1j * wn - E) Dv0 = -2 * omega / (vn**2 + omega**2) nF = 1.0 / (exp(beta * E) + 1.0) nB = 1.0 / (exp(beta * omega) - 1.0) exact = (nB + nF) / (1j * wn - E + omega) + (nB + 1 - nF) / (1j * wn - E - omega) #Iw = -1.0 * conv(Gw0, Dv0, ['m,n-m'], [0], [False], beta, kinds=('fermion', 'boson', 'fermion')) Gt0 = fourier.w2t(Gw0, beta, 0, 'fermion', -1) Dt0 = fourier.w2t(Dv0, beta, 0, 'boson') prod = Gt0 * Dt0 Iw = -1.0 * fourier.t2w(prod, beta, 0, 'fermion')[0] if plotting: figure() plot(exact.real) plot(Iw.real) xlim(0, 200 / beta) title('real Sigma') figure() plot(exact.imag) plot(Iw.imag) xlim(0, 200 / beta) title('imag Sigma') show() return mean(abs(Iw - exact))
def err_pi(plotting=False): beta = params['beta'] N = params['nw'] tau = linspace(0, beta, 2 * N + 1) wn = (2.0 * arange(N) + 1.0) * pi / beta vn = (2.0 * arange(N + 1)) * pi / beta E1 = 0.2 E2 = 0.8 Gw1 = 1.0 / (1j * wn - E1) Gw2 = 1.0 / (1j * wn - E2) nF1 = 1.0 / (exp(beta * E1) + 1.0) nF2 = 1.0 / (exp(beta * E2) + 1.0) exact = (nF1 - nF2) / (1j * vn + E1 - E2) Gt1 = fourier.w2t(Gw1, beta, 0, 'fermion', jump=-1) Gt2 = fourier.w2t(Gw2, beta, 0, 'fermion', jump=-1) prod = -Gt1[::-1] * Gt2 Iw = fourier.t2w(prod, beta, 0, 'boson') if plotting: figure() plot(exact.real) plot(Iw.real) xlim(0, 200 / beta) title('real PI') figure() plot(exact.imag) plot(Iw.imag) xlim(0, 200 / beta) title('imag PI') show() return mean(abs(Iw - exact))
def test_single_iteration(): basedir = '/scratch/users/bln/elph/debug/' lamb = 0.6 W = 8.0 params['g0'] = sqrt(0.5 * lamb / 2.4 * params['omega'] * W) params['nk'] = 2 params['nw'] = 512 params['beta'] = 16.0 params['dens'] = 0.8 params['omega'] = 0.5 omega = params['omega'] migdal = Migdal(params, basedir) S0, PI0, sc_iter = None, None, 1 savedir, G, D, S, GG = migdal.selfconsistency(sc_iter, S0=S0, PI0=PI0, frac=1.0) PI = params['g0']**2 * GG S = fourier.t2w(S, params['beta'], 2, 'fermion')[0] PI = fourier.t2w(PI, params['beta'], 2, 'boson') print('S from migdal') print(shape(S)) savedir, wn, vn, ek, mu, deriv, dndmu = migdal.setup() print('E = ', params['band'](params['nk'], 1.0, params['tp'])) nk = params['nk'] nw = params['nw'] beta = params['beta'] wn = (2.0 * arange(nw) + 1.0) * pi / beta vn = (2.0 * arange(nw + 1)) * pi / beta ekmu = params['band'](nk, 1.0, params['tp']) - mu Dv0 = -2.0 * omega / (vn**2 + omega**2) nB = 1.0 / (exp(beta * omega) - 1.0) S_ = zeros((nk, nk, nw), dtype=complex) for ik1 in range(nk): for ik2 in range(nk): for iq1 in range(nk): for iq2 in range(nk): E = ekmu[iq1, iq2] nF = 1.0 / (exp(beta * E) + 1.0) S_[ik1, ik2, :] += (nB + nF) / (1j * wn - E + omega) + ( nB + 1 - nF) / (1j * wn - E - omega) S_ *= params['g0']**2 / nk**2 print('S-S_', mean(abs(S - S_))) figure() plot(ravel(S).imag - ravel(S_).imag) plot(ravel(S).real - ravel(S_).real) title('diff Skw') #savefig('figs/diff Skw.png') figure() plot(ravel(S).imag) plot(ravel(S_).imag) plot(ravel(S).real) plot(ravel(S_).real) title('Skw') #savefig('figs/Skw.png') show() PI_ = zeros((nk, nk, nw + 1), dtype=complex) for ik1 in range(nk): for ik2 in range(nk): for iq1 in range(nk): for iq2 in range(nk): ip1 = ((ik1 + iq1) - nk // 2) % nk ip2 = ((ik2 + iq2) - nk // 2) % nk E1 = ekmu[ik1, ik2] E2 = ekmu[ip1, ip2] nF1 = 1.0 / (exp(beta * E1) + 1.0) nF2 = 1.0 / (exp(beta * E2) + 1.0) if abs(E1 - E2) < 1e-14: PI_[iq1, iq2, 0] += -beta * nF1 * (1 - nF1) PI_[iq1, iq2, 1:] += (nF1 - nF2) / (1j * vn[1:] + E1 - E2) else: PI_[iq1, iq2, :] += (nF1 - nF2) / (1j * vn + E1 - E2) PI_ *= 2.0 * params['g0']**2 / nk**2 print('PI-PI_', mean(abs(PI - PI_))) ''' figure() plot(ravel(PI).imag-ravel(PI_).imag) plot(ravel(PI).real-ravel(PI_).real) title('re diff PIkw') #savefig('figs/diff_PIkw.png') ''' figure() plot(ravel(PI).imag) plot(ravel(PI_).imag) title('Im PIkw') figure() plot(ravel(PI).real) plot(ravel(PI_).real) title('Re PIkw') show()
def susceptibilities(self, savedir, sc_iter, G, D, GG, frac=0.8): print('\nComputing Susceptibilities\n--------------------------') assert self.sc == 0 if not self.renormalized: GG = self.compute_GG(G) # convert to imaginary frequency G = fourier.t2w(G, self.beta, self.dim, 'fermion')[0] D = fourier.t2w(D, self.beta, self.dim, 'boson') GG = fourier.t2w(GG, self.beta, self.dim, 'boson') # compute the CDW susceptibility Xcdw = None X0 = -GG[..., 0] Xcdw = real(X0 / (1.0 - 2.0 * self.g0**2 / self.omega * X0)) Xcdw = ravel(Xcdw) a = argmax(abs(Xcdw)) print('Xcdw = %1.4f' % Xcdw[a]) F0 = G * conj(G) # confirm that F0 has no jump ''' jumpF0 = np.zeros((self.nk, self.nk, 1)) F0tau = fourier.w2t_fermion_alpha0(F0, self.beta, 2, jumpF0) figure() plot(F0tau[0,0].real) plot(F0tau[self.nk//2, self.nk//2].rel) savefig(self.basedir+'F0tau') exit() ''' jumpx = np.zeros([self.nk] * self.dim + [1]) # momentum and frequency convolution # the jump for F0 is zero jumpF0 = np.zeros([self.nk] * self.dim + [1]) jumpD = None #gamma0 = 1 #self.compute_gamma(F0, D, jumpF0, jumpD) path = os.path.join(savedir, 'gamma.npy') if os.path.exists(path): gamma = np.load(path) else: gamma = np.ones([self.nk] * self.dim + [self.nw], dtype=complex) jumpF0gamma = np.zeros([self.nk] * self.dim + [1], dtype=complex) iteration = 0 #gamma = np.ones([self.nk]*self.dim+[self.nw], dtype=complex) while iteration < sc_iter: gamma0 = gamma.copy() F0gamma = F0 * gamma # compute jumpF0gamma F0gamma_tau = fourier.w2t(F0gamma, self.beta, self.dim, 'fermion', jumpF0gamma) jumpF0gamma = F0gamma_tau[..., 0] + F0gamma_tau[..., -1] jumpF0gamma = jumpF0gamma[..., None] #print('size of jumpF0gamma {:.5e}'.format(np.amax(np.abs(jumpF0gamma)))) gamma = self.compute_gamma(F0gamma, D, jumpF0gamma, jumpD) change = mean( abs(gamma - gamma0)) / (mean(abs(gamma + gamma0)) + 1e-10) gamma = frac * gamma + (1 - frac) * gamma0 if change < 1e-12: break #if iteration%max(sc_iter//20,1)==0: #print(f'change {change:.4e}') print('change ', change) if change < 1e-3: Xsc = 1.0 / (self.beta * self.nk**self.dim) * 2.0 * sum( F0 * gamma).real np.save(savedir + 'Xsc.npy', [Xsc]) np.save(savedir + 'Xcdw.npy', Xcdw) np.save(savedir + 'gamma.npy', gamma) iteration += 1 #print(f'change {change:.4e}') print('change ', change) if change > 1e-5: print('Susceptibility failed to converge') return None, None #Xsc = 1.0 / (self.beta * self.nk**self.dim) * 2.0*sum(F0*(1+x)).real Xsc = 1.0 / (self.beta * self.nk**self.dim) * 2.0 * sum( F0 * gamma).real print(f'Xsc {Xsc:.4f}') if any(Xcdw < 0.0) or np.isnan(a): print('Xcdw blew up') return Xsc, None return Xsc, Xcdw
def corrected_a2F_imag(basedir, folder, ntheta=5): wr, nr, nk, SR, DR, mu, t, tp, g0, omega = load(basedir, folder) dtheta = np.pi / (2 * ntheta) thetas = np.arange(dtheta / 2, np.pi / 2, dtheta) assert len(thetas) == ntheta corners = ((0, -np.pi, -np.pi), (-np.pi / 2, -np.pi, np.pi), (-np.pi, np.pi, np.pi), (np.pi / 2, np.pi, -np.pi)) kxfs = [] kyfs = [] dEdks = [] vels = [] rs = [] Is = interpS(SR, wr, nr, nk, izero) for corner in corners: for theta in thetas: (kx, ky), r, dEdk = corrected_kF(Is, theta, corner[0], corner[1], corner[2], t, tp, mu) kxfs.append(kx) kyfs.append(ky) rs.append(r) dEdks.append(dEdk) #v = vel(kx, ky, dEdk, Is, wr, nr) vels.append(np.abs(dEdk)) # compute normalization factor dos = 0 for ik in range(ntheta): dos += rs[ik] / vels[ik] * dtheta lamb = 0 lambk = np.zeros(ntheta) # extend D D = np.load(basedir + 'data/' + folder + '/D.npy') D = np.concatenate((D, D[0, :, :][None, :, :]), axis=0) D = np.concatenate((D, D[:, 0, :][:, None, :]), axis=1) # fourier transform.... beta = np.load(basedir + 'data/' + folder + '/beta.npy')[0] dim = 2 D = fourier.t2w(D, beta, dim, 'boson') plt.figure() plt.imshow(D[:, :, 0].real, origin='lower') plt.colorbar() plt.savefig(basedir + 'data/' + folder + '/Diw0') plt.close() ks = np.linspace(-np.pi, np.pi, nk + 1) #I = interp2d(ks, ks, B[:,:,iw], kind='linear') I = interp2d(ks, ks, D[:, :, 0].real, kind='linear') print('size of maximum real part : ', np.amax(np.real(D[:, :, 0]))) #print('size of imag part : ', np.amax(np.imag(D[:,:,0]))) for ik in range(ntheta): a2Fk = 0 for ikp in range(4 * ntheta): dkx = kxfs[ikp] - kxfs[ik] dky = kyfs[ikp] - kyfs[ik] a2Fk += -I(dkx, dky) / vels[ikp] / (2 * np.pi)**2 * rs[ikp] * dtheta lambk[ik] = a2Fk lamb += lambk[ik] / vels[ik] * rs[ik] * dtheta lambk *= g0**2 lamb *= g0**2 / dos print('lamb a2F imag', lamb) np.save(basedir + 'data/' + folder + '/lambk_a2F_imag.npy', lambk) np.save(basedir + 'data/' + folder + '/lamb_a2F_imag.npy', lamb) return lambk, np.array(rs) / np.array(vels)
#------------------------------------------------------------- # compare renormalized and unrenormalized print('comparing renormalized and unrenormalized') basedir = '/scratch/users/bln/migdal_check_vs_ilya/single_particle/' folder = 'data_renormalized_nk12_abstp0.300_dim2_g00.33665_nw512_omega0.170_dens0.800_beta16.0000_QNone/' params = read_params(basedir, folder) lamb = g02lamb_ilya(params['g0'], params['omega'], 8) print('lambda = ', lamb) S = np.load(basedir + 'data/' + folder + 'S.npy') wn = (2*np.arange(params['nw'])+1)*np.pi/params['beta'] S = fourier.t2w(S, params['beta'], 2, 'fermion')[0] nk = params['nk'] basedir = '/scratch/users/bln/migdal_check_vs_ilya/single_particle_unrenorm/' folder = 'data_unrenormalized_nk12_abstp0.300_dim2_g00.33665_nw512_omega0.170_dens0.800_beta16.0000_QNone/' uS = np.load(basedir + 'data/' + folder + 'S.npy') uS = fourier.t2w(uS, params['beta'], 2, 'fermion')[0] plt.figure() plt.plot(wn, -S[nk//2+3, nk//2+2, :].imag, '.--', color='orange') plt.plot(wn, -S[0, nk//2+1, :].imag, '.--', color='green') plt.plot(wn, -uS[0, 0, :].imag, '.--', color='red') plt.xlim(0, 2) plt.ylim(0, 0.3)
def selfconsistency(self, sc_iter, frac=0.5, fracR=0.5, alpha=0.5, S0=None, PI0=None, mu0=None, cont=False, interp=None): savedir, mu, G, D, S, GG = super().selfconsistency(sc_iter, frac=frac, alpha=alpha, S0=S0, PI0=PI0, mu0=mu0, cont=False) # imag axis failed to converge if savedir is None: exit() savedir = savedir[:-1] + '_idelta{:.4f}_w{:.4f}_{:.4f}/'.format( self.idelta.imag, np.abs(self.wmin), self.wmax) if not os.path.exists(savedir): os.makedirs(savedir) for key in self.keys: np.save(savedir + key, [getattr(self, key)]) np.save(savedir + 'mu', [mu]) print('savedir ', savedir) del D del GG del S print('\nReal-axis selfconsistency') print('---------------------------------') wn, vn, ek, w, nB, nF, DRbareinv = self.setup_realaxis() if interp is not None: SR = interp.SR PIR = interp.PIR if os.path.exists(savedir + 'SR.npy'): if cont: print('CONTINUING FROM EXISTING REAL AXIS DATA') SR = np.load(savedir + 'SR.npy') PIR = np.load(savedir + 'PIR.npy') else: print( 'data exists. Not continuing. Set cont=True or delete data.' ) exit() else: SR = np.zeros([self.nk, self.nk, self.nr, 2, 2], dtype=complex) PIR = np.zeros([self.nk, self.nk, self.nr], dtype=complex) GR = self.compute_GR(w, ek, mu, SR) DR = self.compute_DR(DRbareinv, PIR) # convert to imaginary frequency G = fourier.t2w(G, self.beta, self.dim, 'fermion')[0] # compute Gsum if self.renormalized: tau3Gsum_plustau3 = np.zeros([self.nk, self.nk, self.nr, 2, 2], dtype=complex) tau3Gsum_minustau3 = np.zeros([self.nk, self.nk, self.nr, 2, 2], dtype=complex) for i in range(self.nr): if self.renormalized: tau3Gsum_plustau3[:, :, i] = np.sum(G / ( (w[i] + 1j * wn)[None, None, :, None, None]), axis=2) / self.beta tau3Gsum_minustau3[:, :, i] = np.sum(G / ( (w[i] - 1j * wn)[None, None, :, None, None]), axis=2) / self.beta # handle sum over pos and negative freqs if self.renormalized: tau3Gsum_plustau3 += np.conj(tau3Gsum_plustau3) tau3Gsum_plustau3 = np.einsum('ab,...bc,cd->...ad', Migdal.tau3, tau3Gsum_plustau3, Migdal.tau3) tau3Gsum_minustau3 += np.conj(tau3Gsum_minustau3) tau3Gsum_minustau3 = np.einsum('ab,...bc,cd->...ad', Migdal.tau3, tau3Gsum_minustau3, Migdal.tau3) print('finished Gsum') np.save(os.path.join(savedir, 'tau3Gsum_minustau3.npy'), tau3Gsum_minustau3) if self.renormalized: np.save(os.path.join(savedir, 'tau3Gsum_plustau3.npy'), tau3Gsum_plustau3) del G # can I always use Gsum_plus[::-1]? what if w's are not symmetric? #AMSR = AndersonMixing(alpha=alpha) #AMPIR = AndersonMixing(alpha=alpha) # selfconsistency loop change = [0, 0] best_chg = None for i in range(sc_iter): SR0 = SR[:] PIR0 = PIR[:] SR = self.compute_SR(GR, tau3Gsum_minustau3, DR, nB, nF) #SR = AMSR.step(SR0, SR) SR = fracR * SR + (1.0 - fracR) * SR0 GR = self.compute_GR(w, ek, mu, SR) change[0] = np.mean(np.abs(SR - SR0)) / np.mean(np.abs(SR + SR0)) if self.renormalized: PIR = self.compute_PIR(GR, tau3Gsum_plustau3, nF) #PIR = AMPIR.step(PIR0, PIR) PIR = fracR * PIR + (1.0 - fracR) * PIR0 DR = self.compute_DR(DRbareinv, PIR) change[1] = np.mean(np.abs(PIR - PIR0)) / np.mean( np.abs(PIR + PIR0)) if i % 1 == 0: print('change = %1.3e, %1.3e' % (change[0], change[1])) if best_chg is None or np.mean(change) < best_chg: best_chg = np.mean(change) np.save(savedir + 'savedir.npy', [savedir]) np.save(savedir + 'realchg.npy', [np.mean(change)]) np.save(savedir + 'w', w) np.save(savedir + 'GR', GR) np.save(savedir + 'SR', SR) np.save(savedir + 'DR', DR) np.save(savedir + 'PIR', PIR) np.save(savedir + 'GRbackup', GR) np.save(savedir + 'SRbackup', SR) np.save(savedir + 'DRbackup', DR) np.save(savedir + 'PIRbackup', PIR) if i > 5 and np.sum(change) < 2e-15: break
def conv(a, b, indices_list, axes, circular_list, beta=None, kinds=(None, None, None), op='...,...', jumps=(None, None)): ''' todo: write optional zeros argument - if x is the repeated index, then yz-xz=0 and xz=0 and yz=0 a and b must be the same size the length of each axis must be even indices_list specifies the way in which to convovle for the corresponding axes in 'axes' the repeated index is summed over the single index is the remaining index after convolution for example, indices = ['x,y-x'] will perform the sum over x of a(x)*b(y-x) options for each entry of indices_list is one of four forms (you can change the letter names): 'x,y-x' or 'x,x+y' or 'y-x,x' or 'x+y,x' every convolution can be put into one of these forms by relabeling the index which is summed over note that 'x,x-y' is not in one of these forms but after the relabeling x->x+y it becomes 'x+y,x' axes specify the axes over which convolutions occur circular_list specifies whether to do a circular or a regular convolution for each axis kinds = (kind of a, kind of b, kind of out). Either 'fermion' or 'boson' op specifies the tensor operation which to perform to the ffts it is a string which becomes the first argument to numpy.einsum by default it is elementwise multiplication ''' for indices, axis, circular in zip(indices_list, axes, circular_list): if circular: a = fft.fft(a, axis=axis) b = fft.fft(b, axis=axis) else: a = fourier.w2t(a, beta, axis, kind=kinds[0], jump=jumps[0]) b = fourier.w2t(b, beta, axis, kind=kinds[1], jump=jumps[1]) comma = indices.index(',') if '+' in indices: if comma == 1: a = flip(a, axis=axis) if not circular and kinds[0] == 'fermion': a *= -1.0 if circular: a = roll(a, 1, axis=axis) elif comma == 3: b = flip(b, axis=axis) if not circular and kinds[1] == 'fermion': b *= -1.0 if circular: b = roll(b, 1, axis=axis) else: raise ValueError x = einsum(op, a, b) for axis, circular in zip(axes, circular_list): if circular: x = fft.ifft(x, axis=axis) else: x = fourier.t2w(x, beta, axis, kind=kinds[2])[0] for axis, circular in zip(axes, circular_list): if circular: x = roll(x, shape(a)[axis] // 2, axis=axis) return x
def dyson_boson(self, vn, PI, axis): PIw = fourier.t2w(PI, self.beta, axis, 'boson') Dw = self.compute_D(vn, PIw) return fourier.w2t(Dw, self.beta, axis, 'boson')
def selfconsistency(self, sc_iter, frac=0.5, alpha=0.5, S0=None, PI0=None, mu0=None): savedir, mu, G, D, S, GG = super().selfconsistency(sc_iter, frac=frac, alpha=alpha, S0=S0, PI0=PI0, mu0=mu0) del D del S del GG print('\nReal-axis selfconsistency') print('---------------------------------') # imag axis failed to converge if savedir is None: exit() wn, vn, ek, w, nB, nF, DRbareinv = self.setup_realaxis() SR = np.zeros([self.nk, self.nk, self.nr, 2, 2], dtype=complex) PIR = np.zeros([self.nk, self.nk, self.nr], dtype=complex) GR = self.compute_GR(w, ek, mu, SR) DR = self.compute_DR(DRbareinv, PIR) # convert to imaginary frequency G = fourier.t2w(G, self.beta, self.dim, 'fermion')[0] # compute Gsum if self.renormalized: Gsum_plus = np.zeros([self.nk, self.nk, self.nr, 2, 2], dtype=complex) Gsum_minus = np.zeros([self.nk, self.nk, self.nr, 2, 2], dtype=complex) for i in range(self.nr): if self.renormalized: Gsum_plus[:, :, i] = np.sum(G / ( (w[i] + 1j * wn)[None, None, :, None, None]), axis=2) / self.beta Gsum_minus[:, :, i] = np.sum(G / ( (w[i] - 1j * wn)[None, None, :, None, None]), axis=2) / self.beta # handle sum over pos and negative freqs if self.renormalized: Gsum_plus += np.conj(Gsum_plus) Gsum_minus += np.conj(Gsum_minus) print('finished Gsum') del G # can I always use Gsum_plus[::-1]? what if w's are not symmetric? #AMSR = AndersonMixing(alpha=alpha) #AMPIR = AndersonMixing(alpha=alpha) # selfconsistency loop change = [0, 0] fracR = 0.8 for i in range(10): SR0 = SR[:] PIR0 = PIR[:] SR = self.compute_SR(GR, Gsum_minus, DR, nB, nF) #SR = AMSR.step(SR0, SR) SR = fracR * SR + (1.0 - fracR) * SR0 GR = self.compute_GR(w, ek, mu, SR) change[0] = np.mean(np.abs(SR - SR0)) / np.mean(np.abs(SR + SR0)) if self.renormalized: PIR = self.compute_PIR(GR, Gsum_plus, nF) #PIR = AMPIR.step(PIR0, PIR) PIR = fracR * PIR + (1.0 - fracR) * PIR0 DR = self.compute_DR(DRbareinv, PIR) change[1] = np.mean(np.abs(PIR - PIR0)) / np.mean( np.abs(PIR + PIR0)) if i % 1 == 0: print('change = %1.3e, %1.3e' % (change[0], change[1])) if i > 5 and np.sum(change) < 2e-15: break np.save('savedir.npy', [savedir]) np.save(savedir + 'w', w) np.save(savedir + 'GR', GR) np.save(savedir + 'SR', SR) np.save(savedir + 'DR', DR) np.save(savedir + 'PIR', PIR)
def a2F_imag(basedir, folder, ntheta=5, separate_imag_folder=None): if separate_imag_folder: i1 = len(folder) for _ in range(3): i1 = folder.rfind('_', 0, i1 - 1) folder_ = folder[:i1] else: folder_ = folder params = read_params(basedir, folder_) t = params['t'] tp = params['tp'] mu = params['mu'] nk = params['nk'] g0 = params['g0'] print('beta', params['beta']) dtheta = np.pi / (2 * ntheta) thetas = np.arange(dtheta / 2, np.pi / 2, dtheta) assert len(thetas) == ntheta corners = ((0, -np.pi, -np.pi), (-np.pi / 2, -np.pi, np.pi), (-np.pi, np.pi, np.pi), (np.pi / 2, np.pi, -np.pi)) kxfs = [] kyfs = [] dEdks = [] vels = [] rs = [] for corner in corners: for theta in thetas: (kx, ky), r, dEdk = kF(theta, corner[0], corner[1], corner[2], t, tp, mu) kxfs.append(kx) kyfs.append(ky) rs.append(r) dEdks.append(dEdk) vels.append(np.abs(dEdk)) # compute normalization factor dos = 0 for ik in range(ntheta): dos += rs[ik] / vels[ik] * dtheta lamb = 0 lambk = np.zeros(ntheta) # compute D PI = np.load(basedir + 'data/' + folder_ + '/PI.npy') PI = fourier.t2w(PI, params['beta'], 2, kind='boson') if len(np.shape(PI)) == 3: migdal = RME2d(params, basedir) elif len(np.shape(PI)) == 5: migdal = RME2dsc(params, basedir) vn = 2 * np.arange(params['nw'] + 1) * np.pi / params['beta'] D = migdal.compute_D(vn, PI) #D = np.load(basedir + 'data/' + folder + '/D.npy') # extend D D = np.concatenate((D, D[0, :, :][None, :, :]), axis=0) D = np.concatenate((D, D[:, 0, :][:, None, :]), axis=1) # fourier transform.... #beta = np.load(basedir + 'data/' + folder + '/beta.npy')[0] #dim = 2 #D = fourier.t2w(D, beta, dim, 'boson') plt.figure() plt.imshow(D[:, :, 0].real, origin='lower') plt.colorbar() plt.savefig(basedir + 'data/' + folder + '/Diw0') plt.close() ks = np.linspace(-np.pi, np.pi, nk + 1) #I = interp2d(ks, ks, B[:,:,iw], kind='linear') I = interp2d(ks, ks, D[:, :, 0].real, kind='linear') print('size of maximum real part : ', np.amax(np.real(D[:, :, 0]))) #print('size of imag part : ', np.amax(np.imag(D[:,:,0]))) for ik in range(ntheta): a2Fk = 0 for ikp in range(4 * ntheta): dkx = kxfs[ikp] - kxfs[ik] dky = kyfs[ikp] - kyfs[ik] a2Fk += -I(dkx, dky) / vels[ikp] / (2 * np.pi)**2 * rs[ikp] * dtheta lambk[ik] = a2Fk lamb += lambk[ik] / vels[ik] * rs[ik] * dtheta lambk *= g0**2 lamb *= g0**2 / dos print('lamb a2F imag', lamb) np.save(basedir + 'data/' + folder + '/lambk_a2F_imag.npy', lambk) np.save(basedir + 'data/' + folder + '/lamb_a2F_imag.npy', lamb) return lambk, np.array(rs) / np.array(vels)