def calculate_surface_green(self, energy=0.0, delta=0.0001, error=0.0000001): """Calculate the surface Green function""" delta = self.delta # Right intra = self.right_intra inter = self.right_inter gbulk, g = green.green_renormalization(intra, inter, error=error, energy=energy, delta=delta) self.right_green = g # save green function # Left intra = self.left_intra inter = self.left_inter gbulk, g = green.green_renormalization(intra, inter, error=error, energy=energy, delta=delta) self.left_green = g # save green function self.energy_green = energy # energy of the Green function
def effective_central_hamiltonian(hetero, energy=0.0, delta=0.001, write=False): """ Plots the local density of states in the central part""" from green import green_renormalization from green import dyson from hamiltonians import is_number if not hetero.block_diagonal: intra = hetero.central_intra # central intraterm if hetero.block_diagonal: intra = hetero.central_intra[0][0] # when it is diagonal # perform dyson calculation intra = hetero.right_intra inter = hetero.right_inter # gr = dyson(intra,inter,is_sparse=hetero.is_sparse) ggg, gr = green_renormalization(intra, inter, energy=energy, delta=delta) hetero.right_green = gr # save green function # left green function intra = hetero.left_intra inter = hetero.left_inter # gl = dyson(intra,inter,is_sparse=hetero.is_sparse) ggg, gl = green_renormalization(intra, inter, energy=energy, delta=delta) hetero.left_green = gl # save green function # save green functions # hetero.write_green() # print "Saved green functions" # left selfenergy inter = hetero.left_coupling selfl = inter * gl * inter.H # left selfenergy # right selfenergy inter = hetero.right_coupling selfr = inter * gr * inter.H # right selfenergy # central green function intra = hetero.central_intra # dyson equation for the center # full matrix if not hetero.block_diagonal: heff = intra + selfl + selfr hetero.heff = heff if save_heff: print "Saving effective hamiltonian in ", hetero.file_heff if write: # save hamiltonian if desired hetero.write_heff() # reduced matrix if hetero.block_diagonal: from copy import deepcopy heff = deepcopy(intra) heff[0][0] = intra[0][0] + selfl heff[-1][-1] = intra[-1][-1] + selfr # save the green function from scipy.sparse import bmat hetero.heff = bmat(heff) if write: # save hamiltonian print "Saving effective hamiltonian in ", hetero.file_heff hetero.write_heff()
def effective_central_hamiltonian(hetero,energy=0.0,delta=0.001,write=False): """ Plots the local density of states in the central part""" from green import green_renormalization from green import dyson from hamiltonians import is_number if not hetero.block_diagonal: intra = hetero.central_intra # central intraterm if hetero.block_diagonal: intra = hetero.central_intra[0][0] # when it is diagonal # perform dyson calculation intra = hetero.right_intra inter = hetero.right_inter # gr = dyson(intra,inter,is_sparse=hetero.is_sparse) ggg,gr = green_renormalization(intra,inter,energy=energy,delta=delta) hetero.right_green = gr # save green function # left green function intra = hetero.left_intra inter = hetero.left_inter # gl = dyson(intra,inter,is_sparse=hetero.is_sparse) ggg,gl = green_renormalization(intra,inter,energy=energy,delta=delta) hetero.left_green = gl # save green function # save green functions # hetero.write_green() # print "Saved green functions" # left selfenergy inter = hetero.left_coupling selfl = inter*gl*inter.H # left selfenergy # right selfenergy inter = hetero.right_coupling selfr = inter*gr*inter.H # right selfenergy # central green function intra = hetero.central_intra # dyson equation for the center # full matrix if not hetero.block_diagonal: heff = intra + selfl + selfr hetero.heff = heff if save_heff: print "Saving effective hamiltonian in ",hetero.file_heff if write: # save hamiltonian if desired hetero.write_heff() # reduced matrix if hetero.block_diagonal: from copy import deepcopy heff = deepcopy(intra) heff[0][0] = intra[0][0] + selfl heff[-1][-1] = intra[-1][-1] + selfr # save the green function from scipy.sparse import bmat hetero.heff = bmat(heff) if write: # save hamiltonian print "Saving effective hamiltonian in ",hetero.file_heff hetero.write_heff()
def get_bulk_green(hetero,energy=0.0,delta=0.0001): """Calculate left and right bulk green functions""" from green import green_renormalization # right lead intra = hetero.right_intra inter = hetero.right_inter gr,gr2 = green_renormalization(intra,inter,energy=energy,delta=delta) # hetero.right_green = gr # save green function # left lead intra = hetero.left_intra inter = hetero.left_inter gl,gl2 = green_renormalization(intra,inter,energy=energy,delta=delta) return (gl,gr)
def get_bulk_green(hetero, energy=0.0, delta=0.0001): """Calculate left and right bulk green functions""" from green import green_renormalization # right lead intra = hetero.right_intra inter = hetero.right_inter gr, gr2 = green_renormalization(intra, inter, energy=energy, delta=delta) # hetero.right_green = gr # save green function # left lead intra = hetero.left_intra inter = hetero.left_inter gl, gl2 = green_renormalization(intra, inter, energy=energy, delta=delta) return (gl, gr)
def calculate_surface_green(self,energy=0.0,delta=0.0001,error=0.0000001): """Calculate the surface Green function""" # Right intra = self.right_intra inter = self.right_inter gbulk,g = green.green_renormalization(intra,inter,error=error, energy=energy,delta=delta) self.right_green = g # save green function # Left intra = self.left_intra inter = self.left_inter gbulk,g = green.green_renormalization(intra,inter,error=error, energy=energy,delta=delta) self.left_green = g # save green function self.energy_green = energy # energy of the Green function
def get_selfenergy(self, energy, delta=0.0001, lead=0, pristine=False): """Return self energy of iesim lead""" # if the interpolation function has been created if self.interpolated_selfenergy: if lead == 0: return np.matrix(self.selfgen[0](energy)) # return selfenergy if lead == 1: return np.matrix(self.selfgen[1](energy)) # return selfenergy # run the calculation else: from green import green_renormalization if lead == 0: intra = self.left_intra inter = self.left_inter if pristine: cou = self.left_inter else: cou = self.left_coupling if lead == 1: intra = self.right_intra inter = self.right_inter if pristine: cou = self.right_inter else: cou = self.right_coupling ggg, gr = green_renormalization(intra, inter, energy=energy, delta=delta) selfr = cou * gr * cou.H # selfenergy return selfr # return selfenergy
def get_green(self, energy, error=0.00001, delta=0.00001): """ Get surface green function""" import green grb, gr = green.green_renormalization(self.intra, self.inter, error=error, energy=energy, delta=delta) return gr
def ldos1d(h,e=0.0,delta=0.001,nrep=3): """ Calculate DOS for a 1d system""" import green if h.dimensionality!=1: raise # only for 1d gb,gs = green.green_renormalization(h.intra,h.inter,energy=e,delta=delta) d = [ -(gb[i,i]).imag for i in range(len(gb))] # get imaginary part d = spatial_dos(h,d) # convert to spatial resolved DOS g = h.geometry # store geometry x,y = g.x,g.y # get the coordinates go = h.geometry.copy() # copy geometry go = go.supercell(nrep) # create supercell write_ldos(go.x,go.y,d.tolist()*nrep) # write in file return d
def dos_surface(h,output_file="DOS.OUT", energies=np.linspace(-1.,1.,20),delta=0.001): """Calculates the DOS of a surface, and writes in file""" if h.dimensionality!=1: raise # only for 1d fo = open(output_file,"w") fo.write("# energy, DOS surface, DOS bulk\n") for e in energies: # loop over energies print "Done",e gb,gs = green.green_renormalization(h.intra,h.inter,energy=e,delta=delta) gb = -gb.trace()[0,0].imag gs = -gs.trace()[0,0].imag fo.write(str(e)+" "+str(gs)+" "+str(gb)+"\n") fo.close()
def get_selfenergy(self,energy,delta=0.0001,lead=0,pristine=False): """Return self energy of iesim lead""" # if the interpolation function has been created if self.interpolated_selfenergy: if lead==0: return np.matrix(self.selfgen[0](energy)) # return selfenergy if lead==1: return np.matrix(self.selfgen[1](energy)) # return selfenergy # run the calculation else: from green import green_renormalization if lead==0: intra = self.left_intra inter = self.left_inter if pristine: cou = self.left_inter else: cou = self.left_coupling if lead==1: intra = self.right_intra inter = self.right_inter if pristine: cou = self.right_inter else: cou = self.right_coupling ggg,gr = green_renormalization(intra,inter,energy=energy,delta=delta) selfr = cou*gr*cou.H # selfenergy return selfr # return selfenergy
#h.add_swave(delta = .05) h.plot_bands() py.figure() from time import clock es = np.linspace(-3.0, 3.0, 500) told = clock() if True: bulk = [] surf = [] for e in es: dos_bulk, dos_surf = green.green_renormalization(h.intra, h.inter, energy=e) bulk.append(-dos_bulk.trace()[0, 0].imag) surf.append(-dos_surf.trace()[0, 0].imag) py.plot(es, surf, color="blue", marker="o") py.plot(es, bulk, color="red", marker="x") print told - clock() told = clock() if False: for e in es: dos = green.dyson(h.intra, h.inter, energy=e) dos = -dos.trace()[0, 0].imag py.scatter(e, dos, color="red", marker="x") print told - clock()
def landauer(hetero, energy=0.0, delta=0.0001, error=0.0000001, do_leads=True, gr=None, gl=None, has_eh=False): """ Calculates transmission using Landauer formula""" try: # if it is a list return [ landauer(hetero, energy=e, delta=delta, error=error, do_leads=do_leads, gr=gr, gl=gl, has_eh=has_eh) for e in energy ] except: # contnue if it is not a list pass import green from hamiltonians import is_number if not hetero.block_diagonal: intra = hetero.central_intra # central intraterm dimhc = len(intra) # dimension of the central part if hetero.block_diagonal: intra = hetero.central_intra[0][0] # when it is diagonal # dimension of the central part dimhc = len(hetero.central_intra) * len(intra) iden = np.matrix(np.identity(len(intra), dtype=complex)) # create idntity intra = hetero.right_intra inter = hetero.right_inter if do_leads: grb, gr = green.green_renormalization(intra, inter, error=error, energy=energy, delta=delta) hetero.right_green = gr # save green function else: gr = hetero.right_green # get the saved green function # left green function intra = hetero.left_intra inter = hetero.left_inter if do_leads: glb, gl = green.green_renormalization(intra, inter, error=error, energy=energy, delta=delta) hetero.left_green = gl # save green function else: gl = hetero.left_green # get the saved green function # left selfenergy inter = hetero.left_coupling selfl = inter * gl * inter.H # left selfenergy # right selfenergy inter = hetero.right_coupling selfr = inter * gr * inter.H # right selfenergy ################################# # calculate spectral functions ################################# gammar = 1j * (selfr - selfr.H) gammal = 1j * (selfl - selfl.H) ################################# # dyson equation for the center ################################# # central green function intra = hetero.central_intra # full matrix if not hetero.block_diagonal: heff = intra + selfl + selfr hetero.heff = heff gc = (energy + 1j * delta) * iden - heff gc = gc.I # calculate inverse if has_eh: # if it has electron-hole, trace over electrons raise G = (gammar * gc * gammal.H * gc.H) G = np.sum([G[2 * i, 2 * i] for i in range(len(G) / 2)]).real else: G = (gammar * gc * gammal.H * gc.H).trace()[0, 0].real return G # reduced matrix if hetero.block_diagonal: from copy import deepcopy heff = deepcopy(intra) heff[0][0] = intra[0][0] + selfl heff[-1][-1] = intra[-1][-1] + selfr dd = (energy + 1j * delta) * iden for i in range(len(intra)): # add the diagonal energy part heff[i][i] = heff[i][i] - dd # this has the wrong sign!! # now change the sign for i in range(len(intra)): for j in range(len(intra)): try: heff[i][j] = -heff[i][j] except: heff[i][j] = heff[i][j] # calculate green function from green import gauss_inverse # routine to invert the matrix # calculate only some elements of the central green function gc1n = gauss_inverse(heff, 0, len(heff) - 1) # calculate element 1,n # and apply Landauer formula if has_eh: # if it has electron-hole, trace over electrons raise G = (gammal * gc1n * gammar.H * gc1n.H) G = np.sum([G[2 * i, 2 * i] for i in range(len(G) / 2)]).real else: G = (gammal * gc1n * gammar.H * gc1n.H).trace()[0, 0].real return G # return transmission
def get_green(self,energy,error=0.0001,delta=0.0001): """ Get surface green function""" import green grb,gr = green.green_renormalization(self.intra,self.inter,error=error, energy=energy,delta=delta) return gr
def landauer(hetero,energies=0.0,delta = 0.001,error=0.00001): """ Calculates transmission using Landauer formula""" from green import dyson from green import gf_convergence import green from hamiltonians import is_number if not hetero.block_diagonal: intra = hetero.central_intra # central intraterm dimhc = len(intra) # dimension of the central part if hetero.block_diagonal: intra = hetero.central_intra[0][0] # when it is diagonal # dimension of the central part dimhc = len(hetero.central_intra)*len(intra) iden = np.matrix(np.identity(len(intra),dtype=complex)) # create idntity trans = [] # list with the transmission for energy in energies: # loop over energies intra = hetero.right_intra inter = hetero.right_inter grb,gr = green.green_renormalization(intra,inter,error=error, energy=energy,delta=delta) # gr = dyson(intra,inter,energy=energy,gf=gf) hetero.right_green = gr # save green function # left green function intra = hetero.left_intra inter = hetero.left_inter glb,gl = green.green_renormalization(intra,inter,error=error, energy=energy,delta=delta) hetero.left_green = gl # save green function # left selfenergy inter = hetero.left_coupling selfl = inter*gl*inter.H # left selfenergy # right selfenergy inter = hetero.right_coupling selfr = inter*gr*inter.H # right selfenergy ################################# # calculate spectral functions ################################# gammar = selfr-selfr.H gammal = selfl-selfl.H ################################# # dyson equation for the center ################################# # central green function intra = hetero.central_intra # full matrix if not hetero.block_diagonal: heff = intra + selfl + selfr hetero.heff = heff gc = (energy+1j*delta)*iden - heff gc = gc.I # calculate inverse G = (gammar*gc*gammal.H*gc.H).trace()[0,0].real trans.append(G) # reduced matrix if hetero.block_diagonal: from copy import deepcopy heff = deepcopy(intra) heff[0][0] = intra[0][0] + selfl heff[-1][-1] = intra[-1][-1] + selfr dd = (energy+1j*delta)*iden for i in range(len(intra)): # add the diagonal energy part heff[i][i] = heff[i][i] - dd # this has the wrong sign!! # now change the sign for i in range(len(intra)): for j in range(len(intra)): try: heff[i][j] = -heff[i][j] except: heff[i][j] = heff[i][j] # calculate green function from green import gauss_inverse # routine to invert the matrix # calculate only some elements of the central green function gc1n = gauss_inverse(heff,0,len(heff)-1) # calculate element 1,n # and apply Landauer formula G = (gammal*gc1n*gammar.H*gc1n.H).trace()[0,0].real trans.append(G) print "Landauer transmission E=",energy,"G=",G return trans # return transmission
def landauer(hetero,energy=0.0,delta = 0.0001,error=0.0000001,do_leads=True, gr=None,gl=None,has_eh=False): """ Calculates transmission using Landauer formula""" try: # if it is a list return [landauer(hetero,energy=e,delta=delta,error=error, do_leads=do_leads,gr=gr,gl=gl,has_eh=has_eh) for e in energy] except: # contnue if it is not a list pass import green from hamiltonians import is_number if not hetero.block_diagonal: intra = hetero.central_intra # central intraterm dimhc = len(intra) # dimension of the central part if hetero.block_diagonal: intra = hetero.central_intra[0][0] # when it is diagonal # dimension of the central part dimhc = len(hetero.central_intra)*len(intra) iden = np.matrix(np.identity(len(intra),dtype=complex)) # create idntity intra = hetero.right_intra inter = hetero.right_inter if do_leads: grb,gr = green.green_renormalization(intra,inter,error=error, energy=energy,delta=delta) hetero.right_green = gr # save green function else: gr = hetero.right_green # get the saved green function # left green function intra = hetero.left_intra inter = hetero.left_inter if do_leads: glb,gl = green.green_renormalization(intra,inter,error=error, energy=energy,delta=delta) hetero.left_green = gl # save green function else: gl = hetero.left_green # get the saved green function # left selfenergy inter = hetero.left_coupling selfl = inter*gl*inter.H # left selfenergy # right selfenergy inter = hetero.right_coupling selfr = inter*gr*inter.H # right selfenergy ################################# # calculate spectral functions ################################# gammar = 1j*(selfr-selfr.H) gammal = 1j*(selfl-selfl.H) ################################# # dyson equation for the center ################################# # central green function intra = hetero.central_intra # full matrix if not hetero.block_diagonal: heff = intra + selfl + selfr hetero.heff = heff gc = (energy+1j*delta)*iden - heff gc = gc.I # calculate inverse # print has_eh if has_eh: # if it has electron-hole, trace over electrons raise G = (gammar*gc*gammal.H*gc.H) G = np.sum([G[2*i,2*i] for i in range(len(G)/2)]).real else: G = (gammar*gc*gammal.H*gc.H).trace()[0,0].real return G # reduced matrix if hetero.block_diagonal: # print has_eh from copy import deepcopy heff = deepcopy(intra) heff[0][0] = intra[0][0] + selfl heff[-1][-1] = intra[-1][-1] + selfr dd = (energy+1j*delta)*iden for i in range(len(intra)): # add the diagonal energy part heff[i][i] = heff[i][i] - dd # this has the wrong sign!! # now change the sign for i in range(len(intra)): for j in range(len(intra)): try: heff[i][j] = -heff[i][j] except: heff[i][j] = heff[i][j] # calculate green function from green import gauss_inverse # routine to invert the matrix # calculate only some elements of the central green function gc1n = gauss_inverse(heff,0,len(heff)-1) # calculate element 1,n # and apply Landauer formula if has_eh: # if it has electron-hole, trace over electrons raise G = (gammal*gc1n*gammar.H*gc1n.H) G = np.sum([G[2*i,2*i] for i in range(len(G)/2)]).real else: G = (gammal*gc1n*gammar.H*gc1n.H).trace()[0,0].real # print "Landauer transmission E=",energy,"G=",G return G # return transmission
#h.add_zeeman([.2,0.,0.]) #h.add_swave(delta = .05) h.plot_bands() py.figure() from time import clock es = np.linspace(-3.0,3.0,500) told = clock() if True: bulk = [] surf = [] for e in es: dos_bulk,dos_surf = green.green_renormalization(h.intra, h.inter,energy=e) bulk.append(-dos_bulk.trace()[0,0].imag) surf.append(-dos_surf.trace()[0,0].imag) py.plot(es,surf,color="blue",marker="o") py.plot(es,bulk,color="red",marker="x") print told-clock() told = clock() if False: for e in es: dos = green.dyson(h.intra,h.inter,energy = e) dos = -dos.trace()[0,0].imag py.scatter(e,dos,color="red",marker="x") print told-clock()