Exemplo n.º 1
0
def comm_angular(x,y,z):
  from scipy.sparse import csc_matrix as csc
  xy = x*y - y*x
  xy = xy - 1j*z
  if np.abs(np.max(xy))>0.001:
    print csc(xy)
    raise
Exemplo n.º 2
0
def intra_super2d(h,n=1,central=None):
  """ Calculates the intra of a 2d system"""
  from scipy.sparse import bmat
  from scipy.sparse import csc_matrix as csc
  tx = csc(h.tx)
  ty = csc(h.ty)
  txy = csc(h.txy)
  txmy = csc(h.txmy)
  intra = csc(h.intra)
  for i in range(n):
    intrasuper[i][i] = intra # intracell
    (x1,y1) = inds[i]
    for j in range(n):
      (x2,y2) = inds[j]
      dx = x2-x1
      dy = y2-y1
      if dx==1 and  dy==0: intrasuper[i][j] = tx
      if dx==-1 and dy==0: intrasuper[i][j] = tx.H
      if dx==0 and  dy==1: intrasuper[i][j] = ty
      if dx==0 and  dy==-1: intrasuper[i][j] = ty.H
      if dx==1 and  dy==1: intrasuper[i][j] = txy
      if dx==-1 and dy==-1: intrasuper[i][j] = txy.H
      if dx==1 and  dy==-1: intrasuper[i][j] = txmy
      if dx==-1 and dy==1: intrasuper[i][j] = txmy.H
  # substitute the central cell if it is the case
  if central!=None:
    ic = (n-1)/2
    intrasuper[ic][ic] = central
  # now convert to matrix
  intrasuper = bmat(intrasuper).todense() # supercell
  return intrasuper
Exemplo n.º 3
0
def supercell(h,nsuper,sparse=False):
  """ Get a supercell of the system,
      h is the hamiltonian
      nsuper is the number of replicas """
  from scipy.sparse import csc_matrix as csc
  from scipy.sparse import bmat
  from copy import deepcopy
  hout = deepcopy(h) # output hamiltonian
  intra = csc(h.intra)  # intracell matrix
  inter = csc(h.inter)  # intercell matrix
  # crease supercells block matrices
  intra_super = [[None for i in range(nsuper)] for j in range(nsuper)] 
  inter_super = [[None for i in range(nsuper)] for j in range(nsuper)] 
  for i in range(nsuper):  # onsite part
    intra_super[i][i] = intra
    inter_super[i][i] = 0.0*intra
  for i in range(nsuper-1):  # inter minicell part
    intra_super[i][i+1] = inter
    intra_super[i+1][i] = inter.H
  inter_super[nsuper-1][0] = inter # inter supercell part
  inter_super[0][nsuper-1] = inter.H # inter supercell part
  # create dense matrices
  if not sparse:
    intra_super = bmat(intra_super).todense()
    inter_super = bmat(inter_super).todense()
  # add to the output hamiltonian
  hout.intra = intra_super
  hout.inter = inter_super
  import geometry
  hout.geometry = h.geometry.supercell(nsuper)
  return hout
Exemplo n.º 4
0
def hubbard(h,U=1.0,pairs = []):
  """ Creates mean field matrices for the input hamiltonian,
      returns list with mena field amtrix pairs in csc form"""
  hubm = [] # list with the hubbard mean field matrices
  if len(pairs)==0:
    de = len(h.intra) # dimension of the hamiltonian
    if h.has_eh:
      de = de/2 # only dimension of electrons (not holes!)
    pairs = range(de/2) # create list with oribtal indices
  for i in pairs: # loop over up down pairs
    # density density term    
    data = [1.0+0.j] # value of the term in the matrix
    ij = [[2*i],[2*i]] # indexes in the matrix
    a = csc((data,ij),shape=(de,de))
    ij = [[2*i+1],[2*i+1]] # indexes in the matrix
    b = csc((data,ij),shape=(de,de))
    hubm += [pair_mf(a,b,g=U)] # add mean field pair
    # exchange exchange term    
    data = [1.0+0.j] # value of the term in the matrix
    ij = [[2*i],[2*i+1]] # indexes in the matrix
    a = csc((data,ij),shape=(de,de))
    ij = [[2*i+1],[2*i]] # indexes in the matrix
    b = csc((data,ij),shape=(de,de))
    hubm += [pair_mf(a,b,g= -U)] # add mean field pair
  return hubm # return list with the pairs
Exemplo n.º 5
0
def supercell_selfenergy(h, e=0.0, delta=0.001, nk=100, nsuper=[1, 1]):
    """alculates the selfenergy of a certain supercell """
    try:  # if two number given
        nsuper1 = nsuper[0]
        nsuper2 = nsuper[1]
    except:  # if only one number given
        nsuper1 = nsuper
        nsuper2 = nsuper
    print "Supercell", nsuper1, "x", nsuper2
    ez = e + 1j * delta  # create complex energy
    import dyson2d

    g = dyson2d.dyson2d(h.intra, h.tx, h.ty, h.txy, h.txmy, nsuper1, nsuper2, 300, ez)
    g = np.matrix(g)  # convert to matrix
    n = nsuper1 * nsuper2  # number of cells
    intrasuper = [[None for j in range(n)] for i in range(n)]
    # create indexes (same order as in fortran routine)
    k = 0
    inds = []
    for i in range(nsuper1):
        for j in range(nsuper2):
            inds += [(i, j)]
            k += 1
    # create hamiltonian of the supercell
    from scipy.sparse import bmat
    from scipy.sparse import csc_matrix as csc

    tx = csc(h.tx)
    ty = csc(h.ty)
    txy = csc(h.txy)
    txmy = csc(h.txmy)
    intra = csc(h.intra)
    for i in range(n):
        intrasuper[i][i] = intra  # intracell
        (x1, y1) = inds[i]
        for j in range(n):
            (x2, y2) = inds[j]
            dx = x2 - x1
            dy = y2 - y1
            if dx == 1 and dy == 0:
                intrasuper[i][j] = tx
            if dx == -1 and dy == 0:
                intrasuper[i][j] = tx.H
            if dx == 0 and dy == 1:
                intrasuper[i][j] = ty
            if dx == 0 and dy == -1:
                intrasuper[i][j] = ty.H
            if dx == 1 and dy == 1:
                intrasuper[i][j] = txy
            if dx == -1 and dy == -1:
                intrasuper[i][j] = txy.H
            if dx == 1 and dy == -1:
                intrasuper[i][j] = txmy
            if dx == -1 and dy == 1:
                intrasuper[i][j] = txmy.H
    intrasuper = bmat(intrasuper).todense()  # supercell
    eop = np.matrix(np.identity(len(g), dtype=np.complex)) * (ez)
    selfe = eop - intrasuper - g.I
    return g, selfe
Exemplo n.º 6
0
def local_dos(m_in,i=0,n=200):
  """ Calculates local DOS using the KPM"""
  m = csc(m_in) # saprse matrix
  nd = m.shape[0] # length of the matrix
  mus = np.array([0.0j for j in range(2*n)])
  v = rand.random(nd)*0.
  v[i] = 1.0 # vector only in site i 
  v = csc(v).transpose()
  mus += get_moments(v,m,n=n) # get the chebychev moments
  return mus
Exemplo n.º 7
0
def full_trace_A(m_in,ntries=20,n=200,A=None):
  """ Calculates local DOS using the KPM"""
  m = csc(m_in) # saprse matrix
  nd = m.shape[0] # length of the matrix
  mus = np.array([0.0j for j in range(2*n)])
  for i in range(nd): # loop over tries
    #v = rand.random(nd) - .5
    v = rand.random(nd)*0.
    v[i] = 1.0 # vector only in site i 
    v = csc(v).transpose()
    mus += get_momentsA(v,m,n=n,A=A) # get the chebychev moments
  return mus/nd
Exemplo n.º 8
0
def random_trace(m_in,ntries=20,n=200):
  """ Calculates local DOS using the KPM"""
  m = csc(m_in) # saprse matrix
  nd = m.shape[0] # length of the matrix
  mus = np.array([0.0j for j in range(2*n)])
  for i in range(ntries): # loop over tries
    #v = rand.random(nd) - .5
    v = rand.random(nd) -.5 + 1j*rand.random(nd) -.5j
    v = v/np.sqrt(v.dot(v)) # normalize the vector
    v = csc(v).transpose()
    mus += get_moments(v,m,n=n) # get the chebychev moments
  return mus/ntries
Exemplo n.º 9
0
def full_trace(m_in,n=200,ntries=100):
  """ Get full trace of the matrix"""
  m = csc(m_in) # saprse matrix
  nd = m.shape[0] # length of the matrix
  mus = np.array([0.0j for i in range(2*n)])
#  for i in range(ntries):
  for i in range(nd/2-1,nd/2):
    v = rand.random(nd)*0.
    v[i] = 1.0 
#    v = v/np.sqrt(v.dot(v)) # normalize the vector
    v = csc(v).transpose()
    mus += get_moments(v,m,n=n)
  return mus/ntries
Exemplo n.º 10
0
def get_representation(wfs,A):
  """
  Gets the matrix representation of a certain operator
  """
  n = len(wfs) # number of eigenfunctions
  ma = np.zeros((n,n),dtype=np.complex) # representation of A
  sa = csc(A) # sparse matrix
  for i in range(n):
    vi = csc(np.conjugate(wfs[i])) # first wavefunction
    for j in range(n):
      vj = csc(wfs[j]).transpose() # second wavefunction
      data = (vi*sa*vj).todense()[0,0]
      ma[i,j] = data
  return ma
Exemplo n.º 11
0
def interface_multienergy(h1,h2,k=[0.0,0.,0.],energies=[0.0],delta=0.01,
        dh1=None,dh2=None):
  """Get the Green function of an interface"""
  from scipy.sparse import csc_matrix as csc
  from scipy.sparse import bmat
  fun1 = green_kchain_evaluator(h1,k=k,delta=delta,hs=None,
                   only_bulk=False,reverse=True) # surface green function 
  fun2 = green_kchain_evaluator(h2,k=k,delta=delta,hs=None,
                   only_bulk=False,reverse=False) # surface green function 
  out = [] # output
  for energy in energies: # loop
    gs1,sf1 = fun1(energy)
    gs2,sf2 = fun2(energy)
    #############
    ## 1  C  2 ##
    #############
    # Now apply the Dyson equation
    (ons1,hop1) = get1dhamiltonian(h1,k,reverse=True) # get 1D Hamiltonian
    (ons2,hop2) = get1dhamiltonian(h2,k,reverse=False) # get 1D Hamiltonian
    havg = (hop1.H + hop2)/2. # average hopping
    if dh1 is not None: ons1 = ons1 + dh1
    if dh2 is not None: ons2 = ons2 + dh2
    ons = bmat([[csc(ons1),csc(havg)],[csc(havg.H),csc(ons2)]]) # onsite
    self2 = bmat([[csc(ons1)*0.0,None],[None,csc(hop2@[email protected])]])
    self1 = bmat([[csc(hop1@[email protected]),None],[None,csc(ons2)*0.0]])
    # Dyson equation
    ez = (energy+1j*delta)*np.identity(ons1.shape[0]+ons2.shape[0]) # energy
    ginter = (ez - ons - self1 - self2).I # Green function
    # now return everything, first, second and hybrid
    out.append([gs1,sf1,gs2,sf2,ginter])
  return out # return output
Exemplo n.º 12
0
def random_trace(m_in,ntries=20,n=200,fun=None,operator=None):
  """ Calculates local DOS using the KPM"""
  if fun is not None: # check that dimensions are fine
    v0 = fun()
    if len(v0) != m_in.shape[0]: raise
  if fun is None:
#    def fun(): return rand.random(nd) -.5 + 1j*rand.random(nd) -.5j
    def fun(): return (rand.random(nd) - 0.5)*np.exp(2*1j*np.pi*rand.random(nd))
  m = csc(m_in) # saprse matrix
  nd = m.shape[0] # length of the matrix
  def pfun(x):
    v = fun()
    v = v/np.sqrt(v.dot(np.conjugate(v))) # normalize the vector
#    v = csc(v).transpose()
    if operator is None:
      mus = get_moments(v,m,n=n) # get the chebychev moments
    else:
      mus = get_momentsA(v,m,n=2*n,A=operator) # get the chebychev moments
    return mus
#  from . import parallel
  out = [pfun(i) for i in range(ntries)] # perform all the computations
#  out = parallel.pcall(pfun,range(ntries))
  mus = np.zeros(out[0].shape,dtype=np.complex)
  for o in out: mus = mus + o # add contribution
  return mus/ntries
Exemplo n.º 13
0
def loadAnyMat(fn, data_elem=None):
  '''
  Load up arbitrary.mat matrix as a csc matrix
  @param fn: the filename
  @param data_ele: the data element item name
  '''
  from scipy.io import loadmat
  from scipy.sparse import csc_matrix as csc

  G = loadmat(fn)
  if data_elem:
    try:
      G = G[data_elem]
    except:
      return "[IOERROR]: The data element '%s' you provided was not found." % data_elem

  else:
    key = set(G.keys()) - set(['__version__', '__header__', '__globals__'])
    key = list(key)
    if len(key) > 1:
      return "[ERROR]: Too many data elements to distinguish the graph - use only one data element or specify explicitly"
    else:
      G = G[key[0]]

  if not isinstance(G, csc):
    G = csc(G)
  return G
Exemplo n.º 14
0
def random_trace(m_in,ntries=20,n=200,fun=None):
  """ Calculates local DOS using the KPM"""
  if fun is not None: # check that dimensions are fine
    v0 = fun()
    if len(v0) != m_in.shape[0]: raise
  if fun is None:
    def fun(): return rand.random(nd) -.5 + 1j*rand.random(nd) -.5j
  m = csc(m_in) # saprse matrix
  nd = m.shape[0] # length of the matrix
  mus = np.array([0.0j for j in range(2*n)])
  for i in range(ntries): # loop over tries
    v = fun()
    v = v/np.sqrt(v.dot(np.conjugate(v))) # normalize the vector
    v = csc(v).transpose()
    mus += get_moments(v,m,n=n) # get the chebychev moments
  return mus/ntries
Exemplo n.º 15
0
def surface(h,cut = 2.,which="both"):
  """Return an operator which is non-zero in the upper surface"""
  zmax = np.max(h.geometry.z) # maximum z
  zmin = np.min(h.geometry.z) # maximum z
  dind = 1 # index to which divide the positions
  if h.has_spin:  dind *= 2 # duplicate for spin
  if h.has_eh:  dind *= 2  # duplicate for eh
  n = h.intra.shape[0] # number of elments of the hamiltonian
  data = [] # epmty list
  for i in range(n): # loop over elements
    z = h.geometry.z[i//dind]
    if which=="upper": # only the upper surface
      if np.abs(z-zmax) < cut:  data.append(1.)
      else: data.append(0.)
    elif which=="lower": # only the upper surface
      if np.abs(z-zmin) < cut:  data.append(1.)
      else: data.append(0.)
    elif which=="both": # only the upper surface
      if np.abs(z-zmax) < cut:  data.append(1.)
      elif np.abs(z-zmin) < cut:  data.append(-1.)
      else: data.append(0.)
    else: raise
  row, col = range(n),range(n)
  m = csc((data,(row,col)),shape=(n,n),dtype=np.complex)
  return m # return the operator
Exemplo n.º 16
0
def generate_soc(specie,value,input_file="wannier.win",nsuper=1):
  """Add SOC to a hamiltonian based on wannier.win"""
  o = open(".soc.status","w")
  iat = 1 # atom counter
  orbnames = names_soc_orbitals(specie) # get which are the orbitals
  ls = soc_l((len(orbnames)-1)/2) # get the SOC matrix
  norb = get_num_wannier(input_file) # number of wannier orbitals
  m = np.matrix([[0.0j for i in range(norb*2)] for j in range(norb*2)]) # matrix
  nat = get_num_atoms(specie,input_file) # number of atoms of this specie
  for iat in range(nat):
   # try:
#      fo.write("Attempting "+specie+"  "+str(iat+1)+"\n")
      for i in range(len(orbnames)): # loop over one index
        orbi = orbnames[i] 
        for j in range(len(orbnames)): # loop over other index
          orbj = orbnames[j]
          ii = get_index_orbital(specie,iat+1,orbi)  # index in wannier
          jj = get_index_orbital(specie,iat+1,orbj) # index in wannier
#          fo.write(str(ii)+"   "+str(jj)+"\n")
          ii += -1 # python starts in 0
          jj += -1 # python starts in 0
          m[2*ii,2*jj] = ls[2*i,2*j] # store the soc coupling
          m[2*ii+1,2*jj] = ls[2*i+1,2*j] # store the soc coupling
          m[2*ii,2*jj+1] = ls[2*i,2*j+1] # store the soc coupling
          m[2*ii+1,2*jj+1] = ls[2*i+1,2*j+1] # store the soc coupling
   #   return
   # except: break
#  fo.close()
  n = nsuper**2 # supercell
  mo = [[None for i in range(n)] for j in range(n)]
  for i in range(n): mo[i][i] = csc(m) # diagonal elements
  mo = bmat(mo).todense() # dense matrix
  return mo*value # return matrix
Exemplo n.º 17
0
def directional_abg(v = np.array([0.,0.,1.]),i=0,d=1,g=1.0):
  """Calculates a pair of mean field matrices for a particular site"""
  r = np.sqrt(v[0]**2 + v[1]**2)  # radial vector in xy
  theta = np.arctan2(r,v[2])  # calculate theta
  phi = np.arctan2(v[1],v[0])  # calculate phi
  t,p = theta, phi  # store in easiest variables
  ct,st = np.cos(t/2.0), np.sin(t/2.0)  # sin and cosine
  e, ce = np.exp(1j*p), np.exp(-1j*p)  # complex phase
  ij=[[2*i,2*i],[2*i,2*i+1],[2*i+1,2*i],[2*i+1,2*i+1]] # index
  row=[2*i,2*i,2*i+1,2*i+1] # index
  col=[2*i,2*i+1,2*i,2*i+1] # index
  data1=[ct*ct,ct*st*ce,ct*st*e,st*st] # values of the matrix A
  data2=[st*st,-ct*st*ce,-ct*st*e,ct*ct] # values of B
  a = csc((data1,(row,col)),shape=(d,d))   # create A
  b = csc((data2,(row,col)),shape=(d,d))   # create B
  abg = pair_mf(a,b,g=g) # create the A, B, coupling object
  return abg
Exemplo n.º 18
0
def add_interlayer(t,ri,rj,has_spin=True,is_sparse=True):
  """Calculate interlayer coupling"""
  m = np.matrix([[0. for i in ri] for j in rj])
  if has_spin: m = bmat([[csc(m),None],[None,csc(m)]]).todense()
  zi = [r[2] for r in ri]
  zj = [r[2] for r in rj]
  for i in range(len(ri)): # add the interlayer
    for j in range(len(ri)): # add the interlayer
      rij = ri[i] - rj[j] # distance between atoms
      dz = zi[i] - zj[j] # vertical distance
      if (3.99<rij.dot(rij)<4.01) and (3.99<(dz*dz)<4.01): # check if connect
        if has_spin: # spin polarized
          m[2*i,2*j] = t
          m[2*i+1,2*j+1] = t
        else:  # spin unpolarized
          m[i,j] = t
  return m
Exemplo n.º 19
0
def full_trace(m_in,n=200,use_fortran=True):
  """ Get full trace of the matrix"""
  m = csc(m_in) # saprse matrix
  nd = m.shape[0] # length of the matrix
  mus = np.array([0.0j for i in range(2*n)])
#  for i in range(ntries):
  for i in range(nd):
    mus += local_dos(m_in,i=i,n=n,use_fortran=use_fortran)
  return mus/nd
Exemplo n.º 20
0
def get_sz(h):
  """Operator for the calculation of Sz expectation value"""
  if h.has_eh: raise
  if not h.has_spin: raise
  if h.has_spin:
    op = np.zeros(h.intra.shape,dtype=np.complex) # initialize matrix
    for i in range(len(op)):   
      op[i,i] = (-1.)**i 
  if h.is_sparse: op = csc(op) # transform into sparse
  return op
Exemplo n.º 21
0
def supercell(h,nsuper,sparse=False):
  """ Get a supercell of the system,
      h is the hamiltonian
      nsuper is the number of replicas """
  from scipy.sparse import csc_matrix as csc
  from scipy.sparse import bmat
  from copy import deepcopy
  hout = deepcopy(h) # output hamiltonian
  intra = csc(h.intra)  # intracell matrix
  inter = csc(h.inter)  # intercell matrix
  # crease supercells block matrices
  intra_super = [[None for i in range(nsuper)] for j in range(nsuper)] 
  inter_super = [[None for i in range(nsuper)] for j in range(nsuper)] 
  for i in range(nsuper):  # onsite part
    intra_super[i][i] = intra
    inter_super[i][i] = 0.0*intra
  for i in range(nsuper-1):  # inter minicell part
    intra_super[i][i+1] = inter
    intra_super[i+1][i] = inter.H
  inter_super[nsuper-1][0] = inter # inter supercell part
  # create dense matrices
  if not sparse:
    intra_super = bmat(intra_super).todense()
    inter_super = bmat(inter_super).todense()
  # add to the output hamiltonian
  hout.intra = intra_super
  hout.inter = inter_super
  # get the old geometry geometry
  y = hout.geometry.y
  x = hout.geometry.x
  celldis = hout.geometry.celldis
  # position of the supercell
  yout = []
  xout = []
  for i in range(nsuper):
    yout += y.tolist()
    xout += (x+i*celldis).tolist()
  # now modify the geometry
  hout.geometry.x = np.array(xout)
  hout.geometry.y = np.array(yout)
  hout.geometry.celldis = celldis*nsuper
  return hout
Exemplo n.º 22
0
def eigenvectors(h,nk=10):
  import scipy.linalg as lg
  from scipy.sparse import csc_matrix as csc
  if h.dimensionality==0:
    vv = lg.eigh(h.intra)
    vecs = [csc(np.matrix(v).T) for v in vv[1].transpose()]
    return vv[0],vecs
  elif h.dimensionality==1:
    kp = np.linspace(0.,1.0,nk)
    eigvecs = [] # empty list with eigenvectors
    eigvals = [] # empty list with eigenvectors
    f = h.get_hk_gen()
    for k in kp: # loop over kpoints
      hk = f(k)  # kdependent hamiltonian
      vv = lg.eigh(hk) # diagonalize k hamiltonian
      eigvals += vv[0].tolist() # store eigenvalues
      vecs = [csc(np.matrix(v).T) for v in vv[1].transpose()]
      eigvecs += vecs # store eigenvectors in sparse form
    return eigvals,eigvecs
  else:
    raise
Exemplo n.º 23
0
def honeycomb2squareMoS2(h,check=True):
  """Transforms a honeycomb lattice into a square lattice"""
  ho = deepcopy(h) # output geometry
  g = h.geometry # geometry
  go = deepcopy(g) # output geometry
  go.a1 = g.a1 + g.a2 
  go.a2 = g.a1 - g.a2
  # now put the first vector along the x axis
  go.r = np.concatenate([g.r,g.r + g.a1])
  go.r2xyz()
  go = sculpt.rotate_a2b(go,go.a1,np.array([1.,0.,0.]))
  # perform a check to see if the supercell is well built  
  a1a2 = go.a1.dot(go.a2)
#  if a1a2>0.001: 
  if np.abs(go.a1)[1]>0.001 or np.abs(go.a2[0])>0.001: 
    ang = go.a1.dot(go.a2)
    print("The projection of lattice vectors is",ang)
    if check: raise
  go.r2xyz() # update r atribbute
  zero = csc(h.tx*0.)
  # define sparse
  intra = csc(h.intra)
  tx = csc(h.tx)
  ty = csc(h.ty)
  txy = csc(h.txy)
  txmy = csc(h.txmy)
  # define new hoppings
  ho.intra = bmat([[intra,tx],[tx.H,intra]]).todense()
  ho.tx = bmat([[txy,zero],[ty,txy]]).todense()
  ho.ty = bmat([[txmy,zero],[ty.H,txmy]]).todense()
  ho.txy = bmat([[zero,zero],[tx,zero]]).todense()
  ho.txmy = bmat([[zero,zero],[zero,zero]]).todense()
  ho.geometry = go
  return ho
Exemplo n.º 24
0
def honeycomb2square(h):
  """Transforms a honeycomb lattice into a square lattice"""
  ho = deepcopy(h) # output geometry
  g = h.geometry # geometry
  go = deepcopy(g) # output geometry
  go.a1 = - g.a1 - g.a2 
  go.a2 = g.a1 - g.a2
  go.x = np.concatenate([g.x,g.x-g.a1[0]])
  go.y = np.concatenate([g.y,g.y-g.a1[1]])
  go.z = np.concatenate([g.z,g.z])
  go.xyz2r() # update r atribbute
  zero = csc(h.tx*0.)
  # define sparse
  intra = csc(h.intra)
  tx = csc(h.tx)
  ty = csc(h.ty)
  txy = csc(h.txy)
  txmy = csc(h.txmy)
  # define new hoppings
  ho.intra = bmat([[intra,tx.H],[tx,intra]]).todense()
  ho.tx = bmat([[txy.H,zero],[ty.H,txy.H]]).todense()
  ho.ty = bmat([[txmy,ty.H],[txmy,zero]]).todense()
  ho.txy = bmat([[zero,None],[None,zero]]).todense()
  ho.txmy = bmat([[zero,zero],[tx.H,zero]]).todense()
  ho.geometry = go
  return ho
Exemplo n.º 25
0
def bulk2ribbon(h,n=10):
  """Converts a hexagonal bulk hamiltonian into a ribbon hamiltonian"""
  go = h.geometry.copy() # copy geometry
  ho = h.copy() # copy hamiltonian
  ho.dimensionality = 1 # reduce dimensionality
  ho.geometry.dimensionality = 1 # reduce dimensionality
  intra = [[None for i in range(n)] for j in range(n)]
  inter = [[None for i in range(n)] for j in range(n)]
  for i in range(n): # to the the sam index
    intra[i][i] = csc(h.intra)
    inter[i][i] = csc(h.tx)
  for i in range(n-1): # one more or less
    intra[i][i+1] = csc(h.ty)
    intra[i+1][i] = csc(h.ty.H)
    inter[i+1][i] = csc(h.txmy)
    inter[i][i+1] = csc(h.txy)
  ho.intra = bmat(intra).todense()
  ho.inter = bmat(inter).todense()
  # calculate the angle 
  import sculpt
  go = sculpt.rotate_a2b(go,go.a1,np.array([1.,0.,0.]))
  ho.geometry.celldis = go.a1[0] # first eigenvector
  r = []
  for i in range(n):
    for ri in go.r:
      r.append(ri+i*go.a2)
  ho.geometry.r = np.array(r)
  ho.geometry.r2xyz() # get r positions
  return ho
Exemplo n.º 26
0
def supercell_selfenergy(h,e=0.0,delta=0.001,nk=100,nsuper=1):
  """alculates the selfenergy of a certain supercell """
  ez = e + 1j*delta # create complex energy
  import dyson2d
  g = dyson2d.dyson2d(h.intra,h.tx,h.ty,h.txy,h.txmy,nsuper,nsuper,300,ez)
  g = np.matrix(g) # convert to matrix
  n = nsuper*nsuper # number of cells
  intrasuper = [[None for j in range(n)] for i in range(n)]
  # create indexes (same order as in fortran routine)
  k = 0
  inds = []
  for i in range(nsuper):
    for j in range(nsuper):
      inds += [(j,i)]
      k += 1 
  # create hamiltonian of the supercell
  from scipy.sparse import bmat
  from scipy.sparse import csc_matrix as csc
  tx = csc(h.tx)
  ty = csc(h.ty)
  txy = csc(h.txy)
  txmy = csc(h.txmy)
  intra = csc(h.intra)
  for i in range(n):
    intrasuper[i][i] = intra # intracell
    (x1,y1) = inds[i]
    for j in range(n):
      (x2,y2) = inds[j]
      if (x1-x2)==1 and (y1-y2)==0: intrasuper[i][j] = tx  
      if (x1-x2)==-1 and (y1-y2)==0: intrasuper[i][j] = tx.H  
      if (x1-x2)==0 and (y1-y2)==1: intrasuper[i][j] = ty  
      if (x1-x2)==0 and (y1-y2)==-1: intrasuper[i][j] = ty.H  
      if (x1-x2)==1 and (y1-y2)==1: intrasuper[i][j] = txy 
      if (x1-x2)==-1 and (y1-y2)==-1: intrasuper[i][j] = txy.H 
      if (x1-x2)==1 and (y1-y2)==-1: intrasuper[i][j] = txmy  
      if (x1-x2)==-1 and (y1-y2)==1: intrasuper[i][j] = txmy.H  
  intrasuper = bmat(intrasuper).todense() # supercell
  eop = np.matrix(np.identity(len(g),dtype=np.complex))*(ez)
  selfe = eop - intrasuper - g.I
  return g,selfe,intrasuper
Exemplo n.º 27
0
def get_rop(h,fun):
  """Operator for the calculation of a position expectation value"""
  rep = 1 # repetitions 
  if h.has_spin: rep *= 2
  if h.has_eh: rep *= 2
  data = []
  for ri in h.geometry.r: 
    for i in range(rep): data.append(fun(ri)) # store
  n = h.intra.shape[0]
  row = range(n)
  col = range(n)
  m = csc((data,(row,col)),shape=(n,n),dtype=np.complex)
  return m
Exemplo n.º 28
0
def interface1d(h,cut = 3.):
  dind = 1 # index to which divide the positions
  if h.has_spin:  dind *= 2 # duplicate for spin
  if h.has_eh:  dind *= 2  # duplicate for eh
  n = h.intra.shape[0] # number of elments of the hamiltonian
  data = [] # epmty list
  for i in range(n): # loop over elements
    y = h.geometry.y[i//dind]
    if np.abs(y)<cut: data.append(1.) # if it belongs to the interface
    else:  data.append(0.)  # otherwise
  row, col = range(n),range(n)
  m = csc((data,(row,col)),shape=(n,n),dtype=np.complex)
  return m # return the operator
Exemplo n.º 29
0
def ldos_finite(h,e=0.0,n=10,nwf=4,delta=0.0001):
  """Calculate the density of states for a finite system"""
  if h.dimensionality!=1: raise # if it is not one dimensional
  intra = csc(h.intra) # convert to sparse
  inter = csc(h.inter) # convert to sparse
  interH = inter.H # hermitian
  m = [[None for i in range(n)] for j in range(n)] # full matrix
  for i in range(n): # add intracell
    m[i][i] = intra
  for i in range(n-1): # add intercell
    m[i][i+1] = inter
    m[i+1][i] = interH
  m = bmat(m) # convert to matrix
  (ene,wfs) = slg.eigsh(m,k=nwf,which="LM",sigma=0.0) # diagonalize
  wfs = wfs.transpose() # transpose wavefunctions
  dos = (wfs[0].real)*0.0 # calculate dos
  for (ie,f) in zip(ene,wfs): # loop over waves
    c = 1./(1.+((ie-e)/delta)**2) # calculate coefficient
    dos += np.abs(f)*c # add contribution
  odos = spatial_dos(h,dos) # get the spatial distribution
  go = h.geometry.supercell(n) # get the supercell
  write_ldos(go.x,go.y,odos) # write in a file
  return dos # return the dos
Exemplo n.º 30
0
def interface1d(h,cut = 3.):
  dind = 1 # index to which divide the positions
  if h.has_spin:  dind *= 2 # duplicate for spin
  if h.has_eh:  dind *= 2  # duplicate for eh
  n = len(h.intra) # number of elments of the hamiltonian
  data = [] # epmty list
  for i in range(n): # loop over elements
    y = h.geometry.y[i/dind]
    if y < -cut:  data.append(-1.)
    elif y > cut: data.append(1.)
    else: data.append(0.)
  row, col = range(n),range(n)
  m = csc((data,(row,col)),shape=(n,n),dtype=np.complex)
  return m # return the operator
Exemplo n.º 31
0
def get_interface(h, fun=None):
    """Return an operator that projects onte the interface"""
    dind = 1  # index to which divide the positions
    if h.has_spin: dind *= 2  # duplicate for spin
    if h.has_eh: dind *= 2  # duplicate for eh
    iden = csc(np.matrix(np.identity(dind,
                                     dtype=np.complex)))  # identity matrix
    r = h.geometry.r  # positions
    out = [[None for ri in r] for rj in r]  # initialize
    if fun is None:  # no input function
        cut = 2.0  # cutoff
        if h.dimensionality == 1: index = 1
        elif h.dimensionality == 2: index = 2
        else: raise

        def fun(ri):  # define the function
            if np.abs(ri[index]) < cut: return 1.0
            else: return 0.0

    for i in range(len(r)):  # loop over positions
        out[i][i] = fun(r[i]) * iden
    return bmat(out)  # return matrix
Exemplo n.º 32
0
def generate_soc(specie,value,input_file="wannier.win",nsuper=1,path=None):
  """Add SOC to a hamiltonian based on wannier.win"""
  if path is not None: 
      inipath = os.getcwd() # current path
      os.chdir(path) # go there
  o = open(".soc.status","w")
  iat = 1 # atom counter
  orbnames = names_soc_orbitals(specie) # get which are the orbitals
  ls = soc_l((len(orbnames)-1)/2) # get the SOC matrix
  norb = get_num_wannier(input_file) # number of wannier orbitals
  m = np.matrix([[0.0j for i in range(norb*2)] for j in range(norb*2)]) # matrix
  nat = get_num_atoms(specie,input_file) # number of atoms of this specie
  for iat in range(nat):
   # try:
#      fo.write("Attempting "+specie+"  "+str(iat+1)+"\n")
      for i in range(len(orbnames)): # loop over one index
        orbi = orbnames[i] 
        for j in range(len(orbnames)): # loop over other index
          orbj = orbnames[j]
          ii = get_index_orbital(specie,iat+1,orbi)  # index in wannier
          jj = get_index_orbital(specie,iat+1,orbj) # index in wannier
#          fo.write(str(ii)+"   "+str(jj)+"\n")
          ii += -1 # python starts in 0
          jj += -1 # python starts in 0
          m[2*ii,2*jj] = ls[2*i,2*j] # store the soc coupling
          m[2*ii+1,2*jj] = ls[2*i+1,2*j] # store the soc coupling
          m[2*ii,2*jj+1] = ls[2*i,2*j+1] # store the soc coupling
          m[2*ii+1,2*jj+1] = ls[2*i+1,2*j+1] # store the soc coupling
   #   return
   # except: break
#  fo.close()
  n = nsuper**2 # supercell
  mo = [[None for i in range(n)] for j in range(n)]
  for i in range(n): mo[i][i] = csc(m) # diagonal elements
  mo = bmat(mo).todense() # dense matrix
  if path is not None: 
      os.chdir(inipath) # go there
      print(np.max(np.abs(mo)))
  return np.matrix(mo*value) # return matrix
Exemplo n.º 33
0
def get_surface(h, cut=0.5, which="both"):
    """Return an operator which is non-zero in the upper surface"""
    zmax = np.max(h.geometry.r[:, 2])  # maximum z
    zmin = np.min(h.geometry.r[:, 2])  # maximum z
    dind = 1  # index to which divide the positions
    n = len(h.geometry.r)  # number of elments of the hamiltonian
    data = []  # epmty list
    for i in range(n):  # loop over elements
        z = h.geometry.z[i]
        if which == "upper":  # only the upper surface
            if np.abs(z - zmax) < cut: data.append(1.)
            else: data.append(0.)
        elif which == "lower":  # only the upper surface
            if np.abs(z - zmin) < cut: data.append(1.)
            else: data.append(0.)
        elif which == "both":  # only the upper surface
            if np.abs(z - zmax) < cut: data.append(1.)
            elif np.abs(z - zmin) < cut: data.append(1.)
            else: data.append(0.)
        else: raise
    row, col = range(n), range(n)
    m = csc((data, (row, col)), shape=(n, n), dtype=np.complex)
    m = h.spinless2full(m)
    return m  # return the operator
Exemplo n.º 34
0
def random_trace(m_in,ntries=20,n=200,fun=None,operator=None):
  """ Calculates local DOS using the KPM"""
  if fun is not None: # check that dimensions are fine
    v0 = fun()
    if len(v0) != m_in.shape[0]: raise
  if fun is None:
#    def fun(): return rand.random(nd) -.5 + 1j*rand.random(nd) -.5j
    def fun(): return (rand.random(nd) - 0.5)*np.exp(2*1j*np.pi*rand.random(nd))
  m = csc(m_in) # saprse matrix
  nd = m.shape[0] # length of the matrix
  def pfun(x):
    v = fun()
    v = v/np.sqrt(v.dot(np.conjugate(v))) # normalize the vector
#    v = csc(v).transpose()
    if operator is None:
      mus = get_moments(v,m,n=n) # get the chebychev moments
    else:
      mus = get_momentsA(v,m,n=2*n,A=operator) # get the chebychev moments
    return mus
  from . import parallel
  out = parallel.pcall(pfun,range(ntries))
  mus = np.zeros(out[0].shape,dtype=np.complex)
  for o in out: mus = mus + o # add contribution
  return mus/ntries
Exemplo n.º 35
0
def bulk2ribbon(h, n=10):
    """Converts a hexagonal bulk hamiltonian into a ribbon hamiltonian"""
    go = h.geometry.copy()  # copy geometry
    ho = h.copy()  # copy hamiltonian
    ho.dimensionality = 1  # reduce dimensionality
    go.dimensionality = 1  # reduce dimensionality
    intra = [[None for i in range(n)] for j in range(n)]
    inter = [[None for i in range(n)] for j in range(n)]
    for i in range(n):  # to the the sam index
        intra[i][i] = csc(h.intra)
        inter[i][i] = csc(h.ty)
    for i in range(n - 1):  # one more or less
        intra[i][i + 1] = csc(h.tx)
        intra[i + 1][i] = csc(h.tx.H)
        inter[i + 1][i] = csc(h.txmy.H)
        inter[i][i + 1] = csc(h.txy)
    ho.intra = bmat(intra).todense()
    ho.inter = bmat(inter).todense()
    return ho
Exemplo n.º 36
0
def onsite_supercell(h,nsuper,mc=None):
    if h.dimensionality!=2: return NotImplemented
    inds = []
    k = 0
    n = nsuper*nsuper # number of cells
    intrasuper = [[None for j in range(n)] for i in range(n)]
    for i in range(nsuper):
      for j in range(nsuper):
        inds += [(i,j)]
        k += 1
    from scipy.sparse import bmat
    from scipy.sparse import csc_matrix as csc
    tx = csc(h.tx)
    ty = csc(h.ty)
    txy = csc(h.txy)
    txmy = csc(h.txmy)
    intra = csc(h.intra)
    if mc is None: mc = intra
    else: mc = csc(mc)
    for i in range(n):
      intrasuper[i][i] = intra # intracell
      (x1,y1) = inds[i]
      for j in range(n):
        (x2,y2) = inds[j]
        dx = x2-x1
        dy = y2-y1
        if dx==1 and  dy==0: intrasuper[i][j] = tx
        if dx==-1 and dy==0: intrasuper[i][j] = tx.H
        if dx==0 and  dy==1: intrasuper[i][j] = ty
        if dx==0 and  dy==-1: intrasuper[i][j] = ty.H
        if dx==1 and  dy==1: intrasuper[i][j] = txy
        if dx==-1 and dy==-1: intrasuper[i][j] = txy.H
        if dx==1 and  dy==-1: intrasuper[i][j] = txmy
        if dx==-1 and dy==1: intrasuper[i][j] = txmy.H
    if nsuper%2==1: # central cell
        ii=int(n/2)
        intrasuper[ii][ii] = mc # central onsite
    else:
        ii=int(n/2)
        ii = ii - int(nsuper/2)
        intrasuper[ii][ii] = mc # central onsite
    intrasuper = bmat(intrasuper).todense() # supercell
    return intrasuper
Exemplo n.º 37
0
def hamiltonian_bulk2ribbon(h, n=10, sparse=False, check=True):
    """Converts a hexagonal bulk hamiltonian into a ribbon hamiltonian"""
    from scipy.sparse import csc_matrix as csc
    from scipy.sparse import bmat
    go = h.geometry.copy()  # copy geometry
    ho = h.copy()  # copy hamiltonian
    if np.abs(go.a1.dot(go.a2)) > 0.01:
        if check: raise  # if axis non orthogonal
    ho.dimensionality = 1  # reduce dimensionality
    ho.geometry.dimensionality = 1  # reduce dimensionality
    intra = [[None for i in range(n)] for j in range(n)]
    inter = [[None for i in range(n)] for j in range(n)]
    for i in range(n):  # to the the sam index
        intra[i][i] = csc(h.intra)
        inter[i][i] = csc(h.tx)
    for i in range(n - 1):  # one more or less
        intra[i][i + 1] = csc(h.ty)
        intra[i + 1][i] = csc(h.ty.H)
        inter[i + 1][i] = csc(h.txmy)
        inter[i][i + 1] = csc(h.txy)
    if sparse:
        ho.intra = bmat(intra)
        ho.inter = bmat(inter)
        ho.is_sparse = True  # hamiltonian is sparse
    else:
        ho.intra = bmat(intra).todense()
        ho.inter = bmat(inter).todense()
    # calculate the angle
    import sculpt
    go = sculpt.rotate_a2b(go, go.a1, np.array([1., 0., 0.]))
    ho.geometry.celldis = go.a1[0]  # first eigenvector
    r = []
    for i in range(n):
        for ri in go.r:
            r.append(ri + i * go.a2)
    ho.geometry.r = np.array(r)
    ho.geometry.r2xyz()  # get r positions
    ho.geometry.center()
    ho.dimensionality = 1
    # for geometries with names
    if ho.geometry.atoms_have_names:
        ho.geometry.atoms_names = ho.geometry.atoms_names * n
    return ho
Exemplo n.º 38
0
def hamiltonian_bulk2ribbon(h, n=10, sparse=False, check=True):
    """Converts a hexagonal bulk hamiltonian into a ribbon hamiltonian"""
    from scipy.sparse import csc_matrix as csc
    from scipy.sparse import bmat
    go = h.geometry.copy()  # copy geometry
    ho = h.copy()  # copy hamiltonian
    #  if np.abs(go.a1.dot(go.a2))>0.01:
    #    if check: raise # if axis non orthogonal
    ho.dimensionality = 1  # reduce dimensionality
    ho.geometry.dimensionality = 1  # reduce dimensionality
    intra = [[None for i in range(n)] for j in range(n)]
    inter = [[None for i in range(n)] for j in range(n)]
    for i in range(n):  # to the the sam index
        intra[i][i] = csc(h.intra)
        inter[i][i] = csc(h.tx)
    for i in range(n - 1):  # one more or less
        intra[i][i + 1] = csc(h.ty)
        intra[i + 1][i] = csc(h.ty.H)
        inter[i + 1][i] = csc(h.txmy)
        inter[i][i + 1] = csc(h.txy)
    if sparse:
        ho.intra = bmat(intra)
        ho.inter = bmat(inter)
        ho.is_sparse = True  # hamiltonian is sparse
    else:
        ho.intra = bmat(intra).todense()
        ho.inter = bmat(inter).todense()
    # calculate the angle
    import sculpt
    ho.geometry = sculpt.rotate_a2b(ho.geometry, ho.geometry.a1,
                                    np.array([1., 0., 0.]))
    ho.geometry = h.geometry.supercell((1, n))  # create supercell
    ho.geometry.dimensionality = 1
    ho.geometry.a1 = h.geometry.a1  # add the unit cell vector
    ho.dimensionality = 1
    # for geometries with names
    if ho.geometry.atoms_have_names:
        ho.geometry.atoms_names = ho.geometry.atoms_names * n
    return ho
Exemplo n.º 39
0
def honeycomb2squareMoS2(h):
    """Transforms a honeycomb lattice into a square lattice"""
    ho = deepcopy(h)  # output geometry
    g = h.geometry  # geometry
    go = deepcopy(g)  # output geometry
    go.a1 = g.a1 + g.a2
    go.a2 = g.a1 - g.a2
    go.r = np.concatenate([g.r, g.r + g.a1])
    go.r2xyz()  # update r atribbute
    zero = csc(h.tx * 0.)
    # define sparse
    intra = csc(h.intra)
    tx = csc(h.tx)
    ty = csc(h.ty)
    txy = csc(h.txy)
    txmy = csc(h.txmy)
    # define new hoppings
    ho.intra = bmat([[intra, tx], [tx.H, intra]]).todense()
    ho.tx = bmat([[txy, zero], [ty, txy]]).todense()
    ho.ty = bmat([[txmy, zero], [ty.H, txmy]]).todense()
    ho.txy = bmat([[zero, zero], [tx, zero]]).todense()
    ho.txmy = bmat([[zero, zero], [zero, zero]]).todense()
    ho.geometry = go
    return ho
Exemplo n.º 40
0
def index(h, n=[0]):
    """Return a projector onto a site"""
    num = len(h.geometry.r)
    val = [1. for i in n]
    m = csc((val, (n, n)), shape=(num, num), dtype=np.complex)
    return h.spinless2full(m)  # return matrix
Exemplo n.º 41
0
 def mono2bi(m):
     """Increase the size of the matrices"""
     return bmat([[csc(m), None], [None, csc(m)]]).todense()
Exemplo n.º 42
0
 def mono2tri(m):
     """Increase the size of the matrices"""
     mo = [[None for i in range(3)] for j in range(3)]
     for i in range(3):
         mo[i][i] = csc(m)
     return bmat(mo).todense()
Exemplo n.º 43
0
 def mono2bi(m):
     """Increase the size of the matrices"""
     if h.is_sparse:
         return bmat([[csc(m), None], [None, csc(m)]])
     else:
         return bmat([[csc(m), None], [None, csc(m)]]).todense()
Exemplo n.º 44
0
def read_supercell_hamiltonian(input_file="hr_truncated.dat",
                               is_real=False,
                               nsuper=1):
    """Reads an output hamiltonian for a supercell from wannier"""
    mt = np.genfromtxt(input_file)  # get file
    m = mt.transpose()  # transpose matrix

    # read the hamiltonian matrices
    class Hopping:
        pass  # create empty class

    tlist = []

    def get_t(i, j, k):
        norb = np.max([np.max(np.abs(m[3])), np.max(np.abs(m[4]))])
        mo = np.matrix(np.zeros((norb, norb), dtype=np.complex))
        for l in mt:  # look into the file
            if i == int(l[0]) and j == int(l[1]) and k == int(l[2]):
                if is_real:
                    mo[int(l[3]) - 1, int(l[4]) - 1] = l[5]  # store element
                else:
                    mo[int(l[3]) - 1,
                       int(l[4]) - 1] = l[5] + 1j * l[6]  # store element
        return mo  # return the matrix

    # the previous is not used yet...
    g = geometry.kagome_lattice()  # create geometry
    h = g.get_hamiltonian()  # build hamiltonian
    nstot = nsuper**2
    intra = [[None for i in range(nstot)] for j in range(nstot)]
    tx = [[None for i in range(nstot)] for j in range(nstot)]
    ty = [[None for i in range(nstot)] for j in range(nstot)]
    txy = [[None for i in range(nstot)] for j in range(nstot)]
    txmy = [[None for i in range(nstot)] for j in range(nstot)]
    from scipy.sparse import csc_matrix as csc
    vecs = []
    # create the identifacion vectors
    inds = []
    acu = 0
    for i in range(nsuper):  # loop over first replica
        for j in range(nsuper):  # loop over second replica
            vecs.append(np.array([i, j]))  # append vector
            inds.append(acu)
            acu += 1  # increase counter
    for i in inds:  # loop over first vector
        for j in inds:  # loop over second vector
            v1 = vecs[i]
            v2 = vecs[j]
            dv = v1 - v2  # difference in vector
            intra[i][j] = csc(get_t(dv[0], dv[1], 0))
            tx[i][j] = csc(get_t(dv[0] + 1, dv[1], 0))
            ty[i][j] = csc(get_t(dv[0], dv[1] + 1, 0))
            txy[i][j] = csc(get_t(dv[0] + 1, dv[1] + 1, 0))
            txmy[i][j] = csc(get_t(dv[0] + 1, dv[1] - 1, 0))
    h.intra = bmat(intra).todense()
    h.tx = bmat(tx).todense()
    h.ty = bmat(tx).todense()
    h.txy = bmat(txy).todense()
    h.txmy = bmat(txmy).todense()
    h.geometry = read_geometry()  # read the geometry of the system
    h.geometry = h.geometry.supercell(nsuper)  # create supercell
    if len(h.geometry.r) != len(h.intra):
        print "Dimensions do not match", len(g.r), len(h.intra)
        print h.geometry.r
        raise  # error if dimensions dont match
    return h
Exemplo n.º 45
0
def get_eigenvectors(h, nk=10, kpoints=False, k=None, sparse=False, numw=None):
    from scipy.sparse import csc_matrix as csc
    shape = h.intra.shape
    if numw is not None: sparse = True
    if h.dimensionality == 0:
        vv = algebra.eigh(h.intra)
        vecs = [v for v in vv[1].transpose()]
        if kpoints: return vv[0], vecs, [[0., 0., 0.] for e in vv[0]]
        else: return vv[0], vecs
    elif h.dimensionality > 0:
        f = h.get_hk_gen()
        if k is None:
            kp = kmesh(h.dimensionality, nk=nk)  # generate a mesh
        else:
            kp = np.array([k])  # kpoint given on input
        #    vvs = [lg.eigh(f(k)) for k in kp] # diagonalize k hamiltonian
        nkp = len(kp)  # total number of k-points
        if sparse:  # sparse Hamiltonians
            fk = lambda k: slg.eigsh(
                csc(f(k)), k=numw, which="LM", sigma=0.0, tol=1e-5)
            vvs = parallel.pcall(fk, kp)
        else:  # dense Hamiltonians
            if parallel.cores > 1:  # in parallel
                #        vvs = parallel.multieigh([f(k) for k in kp]) # multidiagonalization
                vvs = parallel.pcall(lambda k: algebra.eigh(f(k)), kp)
            else:
                vvs = [algebra.eigh(f(k)) for k in kp]  #
        nume = sum([len(v[0])
                    for v in vvs])  # number of eigenvalues calculated
        eigvecs = np.zeros((nume, h.intra.shape[0]),
                           dtype=np.complex)  # eigenvectors
        eigvals = np.zeros(nume)  # eigenvalues

        #### New way ####
        #    eigvals = np.array([iv[0] for iv in vvs]).reshape(nkp*shape[0],order="F")
        #    eigvecs = np.array([iv[1].transpose() for iv in vvs]).reshape((nkp*shape[0],shape[1]),order="F")
        #    if kpoints: # return also the kpoints
        #      kvectors = [] # empty list
        #      for ik in kp:
        #        for i in range(h.intra.shape[0]): kvectors.append(ik) # store
        #      return eigvals,eigvecs,kvectors
        #    else:
        #      return eigvals,eigvecs

        #### Old way, slightly slower but clearer ####
        iv = 0
        kvectors = []  # empty list
        for ik in range(len(kp)):  # loop over kpoints
            vv = vvs[ik]  # get eigenvalues and eigenvectors
            for (e, v) in zip(vv[0], vv[1].transpose()):
                eigvecs[iv] = v.copy()
                eigvals[iv] = e.copy()
                kvectors.append(kp[ik])
                iv += 1
        if kpoints:  # return also the kpoints
            #      for iik in range(len(kp)):
            #        ik = kp[iik] # store kpoint
            #        for e in vvs[iik][0]: kvectors.append(ik) # store
            return eigvals, eigvecs, kvectors
        else:
            return eigvals, eigvecs
    else:
        raise
Exemplo n.º 46
0
def read_supercell_hamiltonian(input_file="hr_truncated.dat",
                               is_real=False,
                               nsuper=1):
    """Reads an output hamiltonian for a supercell from wannier"""
    mt = np.genfromtxt(input_file)  # get file
    m = mt.transpose()  # transpose matrix

    # read the hamiltonian matrices
    class Hopping:
        pass  # create empty class

    tlist = []

    def get_t(i, j, k):
        norb = int(np.max([np.max(np.abs(m[3])), np.max(np.abs(m[4]))]))
        mo = np.matrix(np.zeros((norb, norb), dtype=np.complex))
        for l in mt:  # look into the file
            if i == int(l[0]) and j == int(l[1]) and k == int(l[2]):
                if is_real:
                    mo[int(l[3]) - 1, int(l[4]) - 1] = l[5]  # store element
                else:
                    mo[int(l[3]) - 1,
                       int(l[4]) - 1] = l[5] + 1j * l[6]  # store element
        return mo  # return the matrix

    # this function will be called in a loop
    g = geometry.kagome_lattice()  # create geometry
    h = g.get_hamiltonian()  # build hamiltonian
    h.has_spin = False
    nstot = nsuper**2
    intra = [[None for i in range(nstot)] for j in range(nstot)]
    tx = [[None for i in range(nstot)] for j in range(nstot)]
    ty = [[None for i in range(nstot)] for j in range(nstot)]
    txy = [[None for i in range(nstot)] for j in range(nstot)]
    txmy = [[None for i in range(nstot)] for j in range(nstot)]
    from scipy.sparse import csc_matrix as csc
    vecs = []
    # create the identifacion vectors
    inds = []
    acu = 0
    try:  # read different supercells
        nsuperx = nsuper[0]
        nsupery = nsuper[1]
        nsuperz = nsuper[2]
    except:  # read different supercells
        nsuperx = nsuper
        nsupery = nsuper
        nsuperz = nsuper
    for i in range(nsuperx):  # loop over first replica
        for j in range(nsupery):  # loop over second replica
            vecs.append(np.array([i, j]))  # append vector
            inds.append(acu)
            acu += 1  # add one to the accumulator
    for i in inds:  # loop over first vector
        for j in inds:  # loop over second vector
            v1 = vecs[i]  # position of i esim cell
            v2 = vecs[j]  # position of j esim cell
            dv = v2 - v1  # difference in vector
            # get the different block elements
            intra[i][j] = csc(get_t(dv[0], dv[1], 0))
            tx[i][j] = csc(get_t(dv[0] + nsuper, dv[1], 0))
            ty[i][j] = csc(get_t(dv[0], dv[1] + nsuper, 0))
            txy[i][j] = csc(get_t(dv[0] + nsuper, dv[1] + nsuper, 0))
            txmy[i][j] = csc(get_t(dv[0] + nsuper, dv[1] - nsuper, 0))
    h.intra = bmat(intra).todense()
    h.tx = bmat(tx).todense()
    h.ty = bmat(ty).todense()
    h.txy = bmat(txy).todense()
    h.txmy = bmat(txmy).todense()
    h.geometry = read_geometry()  # read the geometry of the system
    if nsuper > 1:
        h.geometry = h.geometry.supercell(nsuper)  # create supercell
    if len(h.geometry.r) != len(h.intra):
        print("Dimensions do not match", len(g.r), len(h.intra))
        print(h.geometry.r)

#   raise # error if dimensions dont match
# names of the orbitals
    h.orbitals = get_all_orbitals() * nsuper**2

    return h
Exemplo n.º 47
0
            string.rstrip, reflists
        )  #Python's rstrip() method strips all kinds of trailing whitespace by default
        curr_item = reflists[0]
        reflists = reflists[1:]

        for item in reflists:
            if item in paperIdInd:
                rowList.append(paperIdInd[curr_item])
                columnList.append(paperIdInd[item])
                valueList.append(1)

        row += 1

#Create a sparse csc matrix
strucSpMat = csc(
    (np.array(valueList), (np.array(rowList), np.array(columnList))),
    shape=(len(df_paperId), len(df_paperId)))

strucSpMat_org = strucSpMat

print 'Processing structure ended'

#%%
#Processing the content

print 'Processing content started'

C = pd.read_csv(filepath + contentFile, header=None)
C = C.as_matrix(columns=None)

true_labels = pd.read_csv(filepath + fileLabels, header=None)