Пример #1
0
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()
Пример #2
0
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()
Пример #3
0
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)
Пример #4
0
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))
Пример #5
0
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))
Пример #6
0
    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)
Пример #7
0
    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
Пример #8
0
 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')
Пример #9
0
def weak_coupling():
    
    w = np.linspace(-4, 4, 20000)
    width = 0.001
    #width = 0.1
    #g, ec = 0.1, 0.1
    lmax = 10
    beta = 20
    #g, ec = 0.05, 0.05
    g, ec = 5.5, 0
    omega = 1
    
    
    A = one_site_zero_T(w, g, ec, lmax, width)
    plt.figure()
    plt.plot(w, A)
    print('norm', np.trapz(A, dx=(w[-1]-w[0])/(len(w)-1)))
    
    '''
    g = 5.5
    
    w = np.linspace(-10, 10, 1000)
    A = one_site_zero_T(w, g, ec, lmax, width)
    plt.figure()
    plt.plot(w, A)
    plt.xlim(-5, 5)
    '''
    
    
    G = one_site_G(w, g, ec, lmax, width, beta)
    
    A = -1/np.pi * G.imag
    plt.figure()
    plt.plot(w, A)
    plt.xlim(-2.5, 2.5)
    plt.ylabel('$A(\omega)$', fontsize=14)
    plt.xlabel('$\omega$', fontsize=14)
    plt.tight_layout()
    plt.savefig('data/Aexact')
    
    
    nF = 1/(np.exp(w*beta) + 1)
    dw = (w[-1]-w[0])/(len(w)-1)
    print('norm', np.trapz(A, dx=dw))
    print('filling from A(k,w) : ', 2*np.trapz(A*nF, dx=dw))
    
    S = S_from_G(G, w, ec, width)
    plt.figure()
    plt.plot(w, S.real)
    plt.plot(w, S.imag)
    plt.xlim(-1, 5)
    plt.title('S')
    
    
    nw = 2048
    iwn = np.pi*(2*np.arange(nw)+1)*1j/beta
    
    G_matsubara = one_site_G_matsubara(iwn, g, ec, lmax, beta)
    
    n = (1.0 + 2./beta * 2.0*sum(G_matsubara)).real
    baresum = 1 + np.tanh(-beta*ec/2)
    bareGw = 1.0/(iwn - ec)
    ntail = baresum - (1 + 2/beta * 2*np.sum(bareGw.real))
    
    print('filling from Gw ', n + ntail)
    
    Gtau = fourier.w2t(G_matsubara, beta, axis=0, kind='fermion', jump=-1)
    
    print('filling from Gtau ', -2*Gtau[-1].real)
    
    
    tau = np.linspace(0, beta, 200)[:,None]
    w_ = w[None,:]
    K =  np.exp(-tau*w_) / (1 + np.exp(-beta*w_))   # plus sign?
    Gtau_from_Akw = - np.dot(K, A) * dw
    
    plt.figure()
    plt.plot(np.linspace(0, beta, len(Gtau)), Gtau.real)
    plt.plot(np.linspace(0, beta, len(Gtau_from_Akw)), Gtau_from_Akw.real)
    plt.title('Gtaus') 
    plt.ylim(-1, 0)
    
    print('filling from Gtau_from_Akw', -2*Gtau_from_Akw[-1].real)
    
    
    #Gtau_ume = np.load('/scratch/users/bln/elph/data/onesite/data/data_unrenormalized_nk0_abstp0.000_dim0_g00.31623_nw2048_omega1.000_dens0.905_beta20.0000_QNone/G.npy')
    #Gtau_rme = np.load('/scratch/users/bln/elph/data/onesite/data/data_renormalized_nk0_abstp0.000_dim0_g00.31623_nw2048_omega1.000_dens0.905_beta20.0000_QNone/G.npy')
    
    Gtau_ume = np.load('/scratch/users/bln/elph/data/onesite/data/data_unrenormalized_nk0_abstp0.000_dim0_g00.22361_nw2048_omega1.000_dens0.951_beta20.0000_QNone/G.npy')
    Gtau_rme = np.load('/scratch/users/bln/elph/data/onesite/data/data_renormalized_nk0_abstp0.000_dim0_g00.22361_nw2048_omega1.000_dens0.951_beta20.0000_QNone/G.npy')
    
    
    # -----------------------------------------------------------------------------
    # G single iter:
    def get_Gw_si(mu):
        Ec = ec - mu
        nB = 1/(np.exp(beta*omega) - 1)
        nF = 1/(np.exp(beta*Ec) + 1)
        S = 1.0 / beta * ((nB + 1 - nF)/(iwn - Ec - omega) + (nB + nF)/(iwn - Ec + omega))
        return 1/(iwn - Ec - S)
        
    def get_Gtau_si(mu):
        Gw = get_Gw_si(mu)
        return fourier.w2t(Gw, beta, axis=0, kind='fermion', jump=-1)
    
    def get_fill(mu):
        Gw = get_Gw_si(mu)
        Ec = ec - mu
    
        n = (1.0 + 2./beta * 2.0*sum(Gw)).real
    
        baresum = 1 + np.tanh(-beta*Ec/2)
        bareGw = 1.0/(iwn - Ec)
        ntail = baresum - (1 + 2/beta * 2*np.sum(bareGw.real))
        
        return n + ntail
    
    #mu = 0
    mu_new = optimize.fsolve(lambda mu : get_fill(mu) - 0.951, 0)[0]
    Gtau_si = get_Gtau_si(mu_new)
    Gw_si = get_Gw_si(mu_new)
    print('filling si', -2*Gtau_si[-1].real)
    #----------------------------------------------------------
    
    S_matsubara = iwn - ec - 1/G_matsubara
    S_si = iwn - (ec - mu_new)  - 1/Gw_si
    S_rme = np.load('/scratch/users/bln/elph/data/onesite/data/data_renormalized_nk0_abstp0.000_dim0_g00.22361_nw2048_omega1.000_dens0.951_beta20.0000_QNone/S.npy')
    
    plt.figure()
    plt.plot(iwn.imag, G_matsubara.real)
    plt.plot(iwn.imag, Gw_si.real)
    plt.xlim(0, 3)
    plt.title('Gw')
    
    plt.figure()
    plt.plot(iwn.imag, S_matsubara.real)
    plt.plot(iwn.imag, S_si.real)
    wn_rme = (2*np.arange(len(S_rme))+1)*np.pi/beta
    plt.plot(wn_rme, S_rme.real)
    plt.xlim(0, 3)
    plt.title('Sw')
    
    
    f = plt.figure()
    ax = f.add_axes([0.16, 0.13, 0.82, 0.82])
    ax.plot(np.linspace(0, beta, len(Gtau)), Gtau.real)
    ax.plot(np.linspace(0, beta, len(Gtau_ume)), Gtau_ume.real)
    ax.plot(np.linspace(0, beta, len(Gtau_rme)), Gtau_rme.real)
    ax.legend(['exact', 'unrenormalized ME', 'renormalized ME'])
    ax.set_ylabel(r'$G(\tau)$', fontsize=14)
    ax.set_xlabel(r'$\tau$', fontsize=14)
    plt.savefig('data/Gtau')
    
    
    A_ume = np.load('/scratch/users/bln/elph/data/onesite/data/data_unrenormalized_nk0_abstp0.000_dim0_g00.22361_nw2048_omega1.000_dens0.951_beta20.0000_QNone/GR.npy')
    A_rme = np.load('/scratch/users/bln/elph/data/onesite/data/data_renormalized_nk0_abstp0.000_dim0_g00.22361_nw2048_omega1.000_dens0.951_beta20.0000_QNone/GR.npy')
    ws = np.load('/scratch/users/bln/elph/data/onesite/data/data_unrenormalized_nk0_abstp0.000_dim0_g00.22361_nw2048_omega1.000_dens0.951_beta20.0000_QNone/w.npy')
    
    A_ume = -1/np.pi * A_ume.imag
    A_rme = -1/np.pi * A_rme.imag
    
    plt.figure()
    plt.plot(w, A)
    plt.plot(ws, A_ume, '--')
    plt.plot(ws, A_rme*4)
    plt.legend(['$A_{exact}$', '$A_{UME}$', r'$4 \times A_{RME}$'], loc=2)
    plt.ylabel('$A(\omega)$', fontsize=14)
    plt.xlabel('$\omega$', fontsize=14)
    plt.ylim(0, 20)
    plt.xlim(-2.1, 2.1)
    plt.savefig('data/A')
Пример #10
0
 def get_Gtau_si(mu):
     Gw = get_Gw_si(mu)
     return fourier.w2t(Gw, beta, axis=0, kind='fermion', jump=-1)
Пример #11
0
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