Esempio n. 1
0
 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
Esempio n. 2
0
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()
Esempio n. 3
0
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() 
Esempio n. 4
0
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)
Esempio n. 5
0
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)
Esempio n. 6
0
 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
Esempio n. 7
0
    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
Esempio n. 8
0
 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
Esempio n. 9
0
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
Esempio n. 10
0
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
Esempio n. 11
0
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()
Esempio n. 12
0
  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
Esempio n. 13
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()
Esempio n. 14
0
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
Esempio n. 15
0
 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
Esempio n. 16
0
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
Esempio n. 17
0
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
Esempio n. 18
0
#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()