예제 #1
0
파일: multicell.py 프로젝트: zx-sdu/pygra
def parametric_hopping_hamiltonian(h, cutoff=5, fc=None, rcut=5.0):
    """ Gets a first neighbor hamiltonian"""
    from neighbor import parametric_hopping
    if fc is None:
        rcut = 2.1  # stop in this neighbor

        def fc(r1, r2):
            r = r1 - r2
            r = r.dot(r)
            if 0.9 < r < 1.1: return 1.0
            else: return 0.0

    r = h.geometry.r  # x coordinate
    g = h.geometry
    h.is_multicell = True
    # first neighbors hopping, all the matrices
    a1, a2, a3 = g.a1, g.a2, g.a3
    h.intra = h.spinless2full(parametric_hopping(r, r, fc))  # intra matrix
    # generate directions
    dirs = h.geometry.neighbor_directions()  # directions of the hoppings
    # generate hoppings
    h.hopping = []  # empty list
    for d in dirs:  # loop over directions
        i1, i2, i3 = d[0], d[1], d[2]  # extract indexes
        if i1 == 0 and i2 == 0 and i3 == 0: continue
        t = Hopping()  # hopping class
        da = a1 * i1 + a2 * i2 + a3 * i3  # direction
        r2 = [ri + da for ri in r]
        if not close_enough(r, r2, rcut=rcut):  # check if we can skip this one
            #          print("Skipping hopping",[i1,i2,i3])
            continue
        t.m = h.spinless2full(parametric_hopping(r, r2, fc))
        t.dir = [i1, i2, i3]  # store direction
        h.hopping.append(t)  # append
    return h
예제 #2
0
def set_couplings(g,f=None):
  """Set the exchange couplings"""
  js = []
  xs = []
  ys = []
  if callable(f): # callable function
    m = neighbor.parametric_hopping(g.r,g.r)
  else: raise
  return m # return pairs
예제 #3
0
def generate_parametric_hopping(h,f):
  """ Adds a parametric hopping to the hamiltonian based on an input function"""
  rs = h.geometry.r # positions
  g = h.geometry # geometry
  h.has_spin = False
  if h.is_sparse:
    data = []
    rows = []
    cols = []
    if h.dimensionality == 0:
      for i in range(len(rs)):
        for j in range(len(rs)):
          c = f(rs[i],rs[j]) # get coupling
          if np.abs(c)>0.001: #cutoff
             rows.append(i)
             cols.append(j)
             data.append(c)
      n = len(rs) # dimension of the matrix
      h.intra = csc_matrix((data,(rows,cols)),shape=(n,n)) # store in hamil
    else: raise # error if not 0d
    return h
  else: # not sparse 
    h.intra = parametric_hopping(rs,rs,f)
    if h.dimensionality == 0: pass
    elif h.dimensionality == 1:
      dr = np.array([g.celldis,0.,0.])
      h.inter = parametric_hopping(rs,rs+dr,f)
    elif h.dimensionality == 2:
      h.tx = parametric_hopping(rs,rs+g.a1,f)
      h.ty = parametric_hopping(rs,rs+g.a2,f)
      h.txy = parametric_hopping(rs,rs+g.a1+g.a2,f)
      h.txmy = parametric_hopping(rs,rs+g.a1-g.a2,f)
    else: raise
    return h
예제 #4
0
    def biterminal(self,
                   right_g=None,
                   left_g=None,
                   central_g=None,
                   fun=None,
                   disorder=0.0):
        """Create the matrices for a biterminal device, based on geometries"""
        if fun is None:  # no function provided

            def fun(r1, r2):
                dr = r1 - r2
                if .7 < dr.dot(dr) < 1.3: return True
                else: return False

        leadr = Lead()  # right lead
        leadl = Lead()  # left lead
        Rr = right_g.r  # positions
        Lr = left_g.r  # positions
        Cr = central_g.r  # positions
        leadr.intra = neighbor.parametric_hopping(Rr, Rr, fun)  # intra term
        leadl.intra = neighbor.parametric_hopping(Lr, Lr, fun)  # intra term
        intra = neighbor.parametric_hopping(Cr, Cr, fun)  # intra term
        for i in range(intra.shape[0]):  # add disorder
            intra[i, i] += disorder * (np.random.random() - .5)
        self.intra = intra  # store
        leadr.coupling = neighbor.parametric_hopping(Rr, Cr, fun)  # coupling
        leadl.coupling = neighbor.parametric_hopping(Lr, Cr, fun)  # coupling
        # now coupling within the lead
        Rr_dis = [r - right_g.a1 for r in Rr]  # displace
        Lr_dis = [r - left_g.a1 for r in Lr]  # displace
        leadr.inter = neighbor.parametric_hopping(Rr, Rr_dis,
                                                  fun)  # intra term
        leadl.inter = neighbor.parametric_hopping(Lr, Lr_dis,
                                                  fun)  # intra term
        # store positions
        leadr.r = Rr
        leadl.r = Lr
        self.r = Cr
        # store leads
        self.leads = [leadr, leadl]  # store the leads