def dos_heterostructure(hetero,energies=[0.0],num_rep=100, mixing=0.7,eps=0.0001,green_guess=None,max_error=0.0001): """ Calculates the density of states of a heterostructure by a green function approach, input is a heterostructure class""" dos = [] # list with the density of states iden = np.matrix(np.identity(len(intra),dtype=complex)) # create idntity for energy in energies: # loop over energies # right green function intra = hetero.right_intra inter = hetero.right_inter gr = dyson(intra,inter,energy=energy,num_rep=num_rep,mixing=mixing, eps=eps,green_guess=green_guess,max_error=max_error) # left green function intra = hetero.right_intra inter = hetero.right_inter gl = dyson(intra,inter,energy=energy,num_rep=num_rep,mixing=mixing, eps=eps,green_guess=green_guess,max_error=max_error) # central green function selfl = inter.H*gl*inter # left selfenergy selfr = inter*gr*inter.H # right selfenergy gc = energy*iden -intra -selfl -selfr # dyson equation for the center gc = gc.I # calculate inverse dos.append(-gc.trace()[0,0].imag) # calculate the trace of the Green function return dos
def dos_semiinfinite(intra,inter,energies=[0.0],num_rep=100, mixing=0.7,eps=0.0001,green_guess=None,max_error=0.0001): """ Calculates the surface density of states by using a green function approach""" dos = [] # list with the density of states for energy in energies: # loop over energies gf = dyson(intra,inter,energy=energy,num_rep=num_rep,mixing=mixing, eps=eps,green_guess=green_guess,max_error=max_error) dos.append(-gf.trace()[0,0].imag) # calculate the trace of the Green function return dos
def dyson(intra, inter, energy=0.0, gf=None, is_sparse=False, initial=None): """ Solves the dyson equation for a one dimensional system with intra matrix 'intra' and inter to the nerest cell 'inter'""" # get parameters if gf == None: gf = gf_convergence("lead") mixing = gf.mixing eps = gf.eps max_error = gf.max_error num_rep = gf.num_rep optimal = gf.optimal try: intra = intra.todense() inter = inter.todense() except: a = 1 if initial == None: # if green not provided. initialize at zero from numpy import zeros g_guess = intra * 0.0j else: g_guess = initial # calculate using fortran if optimal: print "Fortran dyson calculation" from green_fortran import dyson # import fortran subroutine (g, num_redo) = dyson(intra, inter, energy, num_rep, mixing=mixing, eps=eps, green_guess=g_guess, max_error=max_error) print " Converged in ", num_redo, "iterations\n" from numpy import matrix g = matrix(g) # calculate using python if not optimal: g_old = g_guess # first iteration iden = np.matrix(np.identity(len(intra), dtype=complex)) # create identity e = iden * (energy + 1j * eps) # complex energy while True: # loop over iterations self = inter * g_old * inter.H # selfenergy g = (e - intra - self).I # dyson equation if np.max(np.abs(g - g_old)) < gf.max_error: break # print np.max(np.abs(g-g_old)) g_old = mixing * g + (1. - mixing) * g_old # new green function if is_sparse: from scipy.sparse import csc_matrix g = csc_matrix(g) return g
def dyson(intra, inter, energy=0.0, gf=None, is_sparse=False, initial=None): """ Solves the dyson equation for a one dimensional system with intra matrix 'intra' and inter to the nerest cell 'inter'""" # get parameters if gf == None: gf = gf_convergence("lead") mixing = gf.mixing eps = gf.eps max_error = gf.max_error num_rep = gf.num_rep optimal = gf.optimal try: intra = intra.todense() inter = inter.todense() except: a = 1 if initial == None: # if green not provided. initialize at zero from numpy import zeros g_guess = intra * 0.0j else: g_guess = initial # calculate using fortran if optimal: print "Fortran dyson calculation" from green_fortran import dyson # import fortran subroutine (g, num_redo) = dyson( intra, inter, energy, num_rep, mixing=mixing, eps=eps, green_guess=g_guess, max_error=max_error ) print " Converged in ", num_redo, "iterations\n" from numpy import matrix g = matrix(g) # calculate using python if not optimal: g_old = g_guess # first iteration iden = np.matrix(np.identity(len(intra), dtype=complex)) # create identity e = iden * (energy + 1j * eps) # complex energy while True: # loop over iterations self = inter * g_old * inter.H # selfenergy g = (e - intra - self).I # dyson equation if np.max(np.abs(g - g_old)) < gf.max_error: break # print np.max(np.abs(g-g_old)) g_old = mixing * g + (1.0 - mixing) * g_old # new green function if is_sparse: from scipy.sparse import csc_matrix g = csc_matrix(g) return g