Beispiel #1
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
Beispiel #2
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
Beispiel #3
0
def supercell1d(g, nsuper):
    """Creates a supercell of the system"""
    # get the old geometry
    y = g.y
    x = g.x
    z = g.z
    celldis = g.a1[0]
    if np.abs(g.a1.dot(g.a1) - g.a1[0]**2) > 0.001:
        print("Something weird in supercell 1d")
        return supercell1d(sculpt.rotate_a2b(g, g.a1, np.sqrt([1., 0., 0.])))
    # position of the supercell
    yout = []
    xout = []
    for i in range(nsuper):
        yout += y.tolist()
        xout += (x + i * celldis).tolist()
    # now modify the geometry
    go = deepcopy(g)
    go.x = np.array(xout)
    go.y = np.array(yout)
    # and shift to zero
    go.z = np.array(z.tolist() * nsuper)
    go.center()  # center the unit cell
    go.celldis = celldis * nsuper
    go.a1 = g.a1 * nsuper  # supercell
    go.xyz2r()  # update r
    if g.has_sublattice:  # if has sublattice, keep the indexes
        go.sublattice = np.concatenate([g.sublattice for i in range(nsuper)
                                        ])  # store the keeped atoms
#    print(nsuper)
    if g.atoms_have_names:  # supercell sublattice
        go.atoms_names = g.atoms_names * nsuper
    return go
Beispiel #4
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
Beispiel #5
0
def build_island(h, n=5, angle=30, nedges=6):
    """ Build an island starting from a 2d geometry"""
    gin = geometry.triangular_lattice()  # create lattice
    angle = sculpt.get_angle(h.geometry.a1, h.geometry.a2) / np.pi * 180
    if np.abs(angle - 60) < 1.: gin.a2 = -gin.a2  # change the unit cell
    g = sculpt.build_island(gin, n=n, angle=angle, nedges=nedges,
                            clear=False)  # get the island
    angle2 = sculpt.get_angle(gin.a1, gin.a2) / np.pi * 180
    if np.abs(angle - angle2) > 1.: raise  # error in the angles
    gh = sculpt.rotate_a2b(h.geometry, h.geometry.a1,
                           gin.a1)  # use the same axis
    # now define a function to select the correct hopping
    (w1, w2, w3) = sculpt.reciprocal(gin.a1, gin.a2)  # get reciprocal vectors

    def get_rij(r):
        """Provide a vector r, return this vector expressed in the basis cell"""
        i = r.dot(w1)  # first projection
        j = r.dot(w2)  # second projection
        return i, j  # return indexes

    # turn into multicell
    if not h.is_multicell: h = multicell.turn_multicell(h)
    h.turn_sparse()  # convert into sparse
    intra = [[None for ri in g.r] for rj in g.r]
    # loop over the skeleton
    for i in range(len(g.r)):  # loop over i
        ri = g.r[i]
        for j in range(len(g.r)):  # loop over j
            rj = g.r[j]
            vi, vj = get_rij(ri - rj)  # get the vector
            if np.abs(vi) > 2 or np.abs(vj) > 2: continue
            m = multicell.get_tij(h, rij=np.array([vi, vj,
                                                   0]))  # return the matrix
            intra[i][j] = m  # store in the matrix
    # fic the new hamiltonian
    ho = h.copy()  # copy hamiltonian object
    from scipy.sparse import bmat
    ho.dimensionality = 0  # zero dimensional
    ho.intra = bmat(intra)  # store hamiltonian
    # fix the new geometry
    go = h.geometry.copy()  # copy the original geometry
    go.dimensionality = 0  # zero dimensional
    rs = []  # empty list
    for rd in g.r:
        for r in h.geometry.r:
            vi, vj = get_rij(rd)  # get the vector
            ri = r + vi * h.geometry.a1 + vj * h.geometry.a2
            rs.append(ri)  # append the vector
    rs = np.array(rs)  # convert to array
    go.r = rs  # store
    if go.atoms_have_names:  # if the atoms have names, expand
        go.atoms_names = go.atoms_names * len(g.r)  # enlarge the list
    go.r2xyz()  # fill the xyz values
    ho.geometry = go  # store in the hamiltonian
    go.write()
    return ho
Beispiel #6
0
def build_island(h,n=5,angle=30,nedges=6):
  """ Build an island starting from a 2d geometry"""
  gin = geometry.triangular_lattice() # create lattice
  angle = sculpt.get_angle(h.geometry.a1,h.geometry.a2)/np.pi*180
  if np.abs(angle-60)<1.: gin.a2 = -gin.a2 # change the unit cell
  g = sculpt.build_island(gin,n=n,angle=angle,nedges=nedges,clear=False) # get the island
  angle2 = sculpt.get_angle(gin.a1,gin.a2)/np.pi*180
  if np.abs(angle-angle2)>1.: raise # error in the angles
  gh = sculpt.rotate_a2b(h.geometry,h.geometry.a1,gin.a1) # use the same axis
  # now define a function to select the correct hopping
  (w1,w2,w3) = sculpt.reciprocal(gin.a1,gin.a2) # get reciprocal vectors
  def get_rij(r):
    """Provide a vector r, return this vector expressed in the basis cell""" 
    i = r.dot(w1) # first projection
    j = r.dot(w2) # second projection
    return i,j # return indexes
  # turn into multicell
  if not h.is_multicell: h = multicell.turn_multicell(h) 
  h.turn_sparse() # convert into sparse
  intra = [[None for ri in g.r] for rj in g.r ]
  # loop over the skeleton
  for i in range(len(g.r)): # loop over i
    ri = g.r[i]
    for j in range(len(g.r)): # loop over j
      rj = g.r[j]
      vi,vj = get_rij(ri-rj) # get the vector
      if np.abs(vi)>2 or np.abs(vj)>2: continue
      m = multicell.get_tij(h,rij=np.array([vi,vj,0])) # return the matrix
      intra[i][j] = m # store in the matrix
  # fic the new hamiltonian
  ho = h.copy() # copy hamiltonian object
  from scipy.sparse import bmat
  ho.dimensionality = 0 # zero dimensional
  ho.intra = bmat(intra) # store hamiltonian
  # fix the new geometry
  go = h.geometry.copy() # copy the original geometry
  go.dimensionality = 0 # zero dimensional
  rs = [] # empty list
  for rd in g.r:
    for r in h.geometry.r:
      vi,vj = get_rij(rd) # get the vector
      ri = r +vi*h.geometry.a1 + vj*h.geometry.a2
      rs.append(ri) # append the vector
  rs = np.array(rs) # convert to array
  go.r = rs # store
  if go.atoms_have_names: # if the atoms have names, expand
    go.atoms_names = go.atoms_names*len(g.r) # enlarge the list
  go.r2xyz() # fill the xyz values
  ho.geometry = go # store in the hamiltonian
  go.write()
  return ho
Beispiel #7
0
def hamiltonian_ribbon(hin, n=10):
    """Return the Hamiltonian of a film"""
    h = hin.copy()  # copy Hamiltonian
    import multicell
    h = multicell.supercell_hamiltonian(h, nsuper=[1, n, 1])
    hopout = []  # list
    for i in range(len(h.hopping)):  # loop over hoppings
        if abs(h.hopping[i].dir[2]) < 0.1:
            if abs(h.hopping[i].dir[1]) < 0.1:
                hopout.append(h.hopping[i])
    h.hopping = hopout
    h.dimensionality = 1
    h.geometry.dimensionality = 1
    import sculpt
    h.geometry = sculpt.rotate_a2b(h.geometry, h.geometry.a1,
                                   np.array([1., 0., 0.]))
    return h
Beispiel #8
0
def bulk2ribbon(hin, n=10, sparse=True, nxt=6, ncut=6):
    """ Create a ribbon hamiltonian object"""
    if not hin.is_multicell: h = turn_multicell(hin)
    else: h = hin  # nothing othrwise
    hr = h.copy()  # copy hamiltonian
    if sparse: hr.is_sparse = True  # sparse output
    hr.dimensionality = 1  # reduce dimensionality
    # stuff about geometry
    hr.geometry = h.geometry.supercell((1, n))  # create supercell
    hr.geometry.dimensionality = 1
    hr.geometry.a1 = h.geometry.a1  # add the unit cell vector
    import sculpt  # rotate the geometry
    hr.geometry = sculpt.rotate_a2b(hr.geometry, hr.geometry.a1,
                                    np.array([1., 0., 0.]))
    hr.geometry.celldis = hr.geometry.a1[0]

    def superhopping(dr=[0, 0, 0]):
        """ Return a matrix with the hopping of the supercell"""
        intra = [[None for i in range(n)] for j in range(n)]  # intracell term
        for ii in range(n):  # loop over ii
            for jj in range(n):  # loop over jj
                d = np.array([dr[0], ii - jj + dr[1], dr[2]])
                if d.dot(d) > ncut * ncut: continue  # skip iteration
                m = get_tij(h, rij=d)  # get the matrix
                if m is not None: intra[ii][jj] = csc_matrix(m)  # store
                else:
                    if ii == jj: intra[ii][jj] = csc_matrix(h.intra * 0.)
        intra = bmat(intra)  # convert to matrix
        if not sparse: intra = intra.todense()  # dense matrix
        return intra

    # get the intra matrix
    hr.intra = superhopping()
    # now do the same for the interterm
    hoppings = []  # list of hopings
    for i in range(-nxt, nxt + 1):  # loop over hoppings
        if i == 0: continue  # skip the 0
        d = np.array([i, 0., 0.])
        hopp = Hopping()  # create object
        hopp.m = superhopping(dr=d)  # get hopping of the supercell
        hopp.dir = d
        hoppings.append(hopp)
    hr.hopping = hoppings  # store the list
    hr.dimensionality = 1
    return hr
Beispiel #9
0
def orthogonalize_geometry(g):
  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.has_sublattice = False
  go.r2xyz() # update r atribbute
  return go
Beispiel #10
0
def bulk2ribbon(hin,n=10,sparse=True,nxt=6,ncut=6):
  """ Create a ribbon hamiltonian object"""
  if not hin.is_multicell: h = turn_multicell(hin)
  else: h = hin # nothing othrwise
  hr = h.copy() # copy hamiltonian
  if sparse: hr.is_sparse = True # sparse output
  hr.dimensionality = 1 # reduce dimensionality
  # stuff about geometry
  hr.geometry = h.geometry.supercell((1,n)) # create supercell
  hr.geometry.dimensionality = 1
  hr.geometry.a1 = h.geometry.a1 # add the unit cell vector
  import sculpt # rotate the geometry
  hr.geometry = sculpt.rotate_a2b(hr.geometry,hr.geometry.a1,np.array([1.,0.,0.]))
  hr.geometry.celldis = hr.geometry.a1[0]

  def superhopping(dr=[0,0,0]): 
    """ Return a matrix with the hopping of the supercell"""
    intra = [[None for i in range(n)] for j in range(n)] # intracell term
    for ii in range(n): # loop over ii
      for jj in range(n): # loop over jj
        d = np.array([dr[0],ii-jj+dr[1],dr[2]])
        if d.dot(d)>ncut*ncut: continue # skip iteration
        m = get_tij(h,rij=d) # get the matrix
        if m is not None: intra[ii][jj] = csc_matrix(m) # store
        else: 
          if ii==jj: intra[ii][jj] = csc_matrix(h.intra*0.)
    intra = bmat(intra) # convert to matrix
#    print intra
    if not sparse: intra = intra.todense() # dense matrix
    return intra
  # get the intra matrix
  hr.intra = superhopping()
  # now do the same for the interterm
  hoppings = [] # list of hopings
  for i in range(-nxt,nxt+1): # loop over hoppings
    if i==0: continue # skip the 0
    d = np.array([i,0.,0.])
    hopp = Hopping() # create object
    hopp.m = superhopping(dr=d) # get hopping of the supercell
    hopp.dir = d
    hoppings.append(hopp)
  hr.hopping = hoppings # store the list
  return hr 
Beispiel #11
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
Beispiel #12
0
def bulk2ribbon(g, boundary=[1, 0], n=10, clean=True):
    """Return the geometry of a ribbon"""
    go = g.copy()  # copy
    m = [[boundary[0], boundary[1], 0], [0, 1, 0], [0, 0, 1]]  # supercell
    if boundary[0] != 1 or boundary[1] != 0:
        go = supercell.non_orthogonal_supercell(go, m, mode="brute")
    go = go.supercell((1, n))  # create a supercell
    go = sculpt.rotate_a2b(go, go.a1, np.array([1., 0., 0.]))
    go.dimensionality = 1  # zero dimensional
    go.a2 = np.array([0., 1., 0.])
    if clean:
        go = go.clean(iterative=True)
        if len(go.r) == 0:
            print("Ribbon is not wide enough")
            raise
    go.real2fractional()
    go.fractional2real()
    go.celldis = go.a1[0]
    go.center()
    return go
Beispiel #13
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
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()
  return ho
Beispiel #15
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
Beispiel #16
0
def triangular_ribbon(n):
    g = triangular_lattice()  # create geometry
    go = g.copy()  # copy geometry
    r0 = []  # empty list
    for ir in g.r:
        r0.append(ir)  # supercell
        r0.append(ir + g.a1)  # supercell
    rs = []
    dr = g.a1 + g.a2  # displacement vector
    for i in range(n):  # loop over replicas
        for ir in r0:  # loop over unit cell
            rs.append(dr * i + ir)  # append atom
    go.r = np.array(rs)  # save coordinates
    go.r2xyz()  # update
    go.a1 = g.a1 - g.a2  #
    go.center()
    go.dimensionality = 1
    # now rotate the geometry
    import sculpt
    go = sculpt.rotate_a2b(go, go.a1, np.array([1.0, 0.0, 0.0]))
    # setup the cell dis parameter (deprecated)
    go.celldis = go.a1[0]
    return go
Beispiel #17
0
def triangular_ribbon(n):
  g = triangular_lattice() # create geometry
  go = g.copy() # copy geometry
  r0 = [] # empty list
  for ir in g.r:
    r0.append(ir) # supercell
    r0.append(ir+g.a1) # supercell
  rs = []
  dr = g.a1+g.a2 # displacement vector
  for i in range(n): # loop over replicas
    for ir in r0: # loop over unit cell
      rs.append(dr*i + ir) # append atom
  go.r = np.array(rs) # save coordinates
  go.r2xyz() # update
  go.a1 = g.a1 - g.a2 #
  go.center()
  go.dimensionality = 1
  # now rotate the geometry
  import sculpt
  go = sculpt.rotate_a2b(go,go.a1,np.array([1.0,0.0,0.0]))
  # setup the cell dis parameter (deprecated)
  go.celldis = go.a1[0]
  return go
Beispiel #18
0
def build_ribbon(hin,g=None,n=20):
  """ Build a supercell using a certain geometry as skeleton"""
  if g is None: # if skeleton not provided
    h.geometry.get_lattice_name()
    if h.geometry.lattice_name=="square": # square lattice
      g = geometry.square_ribbon(n) 
    else: raise # not implemented
  # now build the hamiltonian
  h = hin.copy() # generate hamiltonian
  # if the hamiltonian is not multicell, turn it so
  if not h.is_multicell: h = multicell.turn_multicell(h)
  gin = h.geometry # geometry of the hamiltonian input
# use the same axis
  gh = sculpt.rotate_a2b(h.geometry,h.geometry.a1,np.array([0.,1.,0.])) 
#  if np.abs(h.geometry.a1.dot(h.geometry.a2)) > 0.01: raise # orthogonal
#  gh = h.geometry
  def normalize(v): # normalize a vector
    return v/np.sqrt(v.dot(v))
# get reciprocal vectors
  (w1,w2,w3) = sculpt.reciprocal(normalize(gh.a1),normalize(gh.a2)) 
#  exit()
  def get_rij(r):
    """Provide a vector r, return this vector expressed in the basis cell""" 
    i = r.dot(w1) # first projection
    j = r.dot(w2) # second projection
    i,j = round(i),round(j)
    print i,j
    return [i,j,0] # return indexes
  ho = h.copy() # generate hamiltonian
  intra = [[None for i in range(len(g.r))] for j in range(len(g.r))]
  hoppings = [] # empty list for the hoppings
  for i in range(len(g.r)): # loop over positions
    intra[i][i] = h.intra # intracell hopping
  for i in range(len(g.r)): # hopping up to third cells
    for j in range(len(g.r)): # hopping up to third cells
      rij = g.r[i] - g.r[j] # distance between replicas
      intra[i][j] = multicell.get_tij(h,rij=get_rij(rij)) 
  ho.intra = csc_matrix(bmat(intra)) # add the intracell matrix
  for nn in [-3,-2,-1,1,2,3]: # hopping up to third cells
    inter = [[None for i in range(len(g.r))] for j in range(len(g.r))]
    print "Next"
    for i in range(len(g.r)): # hopping up to third cells
      for j in range(len(g.r)): # hopping up to third cells
        rij = g.r[i] - g.r[j] # distance between replicas
        rij += nn*h.geometry.a1 # add the displacement
        if i==j: # for diagonal, at least zeros
          mm = multicell.get_tij(h,rij=get_rij(rij)) 
          if mm is None: inter[i][j] = h.intra*0.0 # store zero
          else: inter[i][j] = mm # store matrix
        else: inter[i][j] = multicell.get_tij(h,rij=get_rij(rij)) 
    hopping = multicell.Hopping() # create object
    hopping.m = csc_matrix(bmat(inter)) # store matrix
    hopping.dir = np.array([nn,0.,0.]) # store vector
    hoppings.append(hopping) # store hopping
  gout = g.copy() # copy geometry for the hamiltonian
  rs = []
  for jr in g.r: # loop over skeleton geometry
    for ir in h.geometry.r: # loop over basis
      rs.append(ir + jr[0]*h.geometry.a1 + jr[1]*h.geometry.a2)
  gout.r = np.array(rs) # store
  gout.r2xyz() # update
  gout.celldis = h.geometry.a1[0] # this has to be well done
  ho.geometry = gout # assign geometry
  ho.hopping = hoppings # store the full hoppings list
  ho.dimensionality = 1 # one dimensional
  ho.is_multicell = True # multicell Hamiltonian
  ho.is_sparse = True # sparse Hamiltonian
  return ho # return ribbon hamiltonian