Esempio n. 1
0
def write_berry(h,
                kpath=None,
                dk=0.01,
                window=None,
                max_waves=None,
                mode="Wilson",
                delta=0.001,
                reciprocal=False,
                operator=None):
    """Calculate and write in file the Berry curvature"""
    if kpath is None: kpath = klist.default(h.geometry)  # take default kpath
    fo = open("BERRY_CURVATURE.OUT", "w")  # open file
    tr = timing.Testimator("BERRY CURVATURE")
    ik = 0
    if operator is not None: mode = "Green"  # Green function mode
    for k in kpath:
        tr.remaining(ik, len(kpath))
        if reciprocal: k = h.geometry.get_k2K_generator()(k)  # convert
        ik += 1
        if mode == "Wilson":
            b = berry_curvature(h,
                                k,
                                dk=dk,
                                window=window,
                                max_waves=max_waves)
        if mode == "Green":
            f = h.get_gk_gen(delta=delta)  # get generator
            b = berry_green(f, k=k, operator=operator)
        fo.write(str(k[0]) + "   ")
        fo.write(str(k[1]) + "   ")
        fo.write(str(b) + "\n")
        fo.flush()
    fo.close()  # close file
Esempio n. 2
0
def get_bands_2d(h,kpath=None,operator=None,num_bands=None):
  """Get a 2d bandstructure"""
  if num_bands is None: # all the bands
    if operator is not None: diagf = lg.eigh # all eigenvals and eigenfuncs
    else: diagf = lg.eigvalsh # all eigenvals and eigenfuncs
  else: # using arpack
    h.turn_sparse() # sparse Hamiltonian
    def diagf(m):
      eig,eigvec = slg.eigsh(m,k=num_bands,which="LM",sigma=0.0)
      if operator is None: return eig
      else: return (eig,eigvec)
  # open file and get generator
  f = open("BANDS.OUT","w") # open bands file
  hkgen = h.get_hk_gen() # generator hamiltonian
  if operator is not None: operator=np.matrix(operator) # convert to matrix
  if kpath is None:
    import klist
    kpath = klist.default(h.geometry) # generate default klist
  for k in range(len(kpath)): # loop over kpoints
    print("Doing kpoint",k)
    hk = hkgen(kpath[k]) # get hamiltonian
    if operator is None:
      es = diagf(hk)
      for e in es:  # loop over energies
        f.write(str(k)+"   "+str(e)+"\n") # write in file
    else:
      es,ws = diagf(hk)
      ws = ws.transpose() # transpose eigenvectors
      for (e,w) in zip(es,ws):  # loop over waves
        w = np.matrix(w) # convert to matrix
        waw = (w.T).H*operator*w.T # expectation value
        waw = waw[0,0].real # real part
        f.write(str(k)+"   "+str(e)+"  "+str(waw)+"\n") # write in file
  f.close()
  return np.genfromtxt("BANDS.OUT").transpose() # return data
Esempio n. 3
0
def kdos_bands(h,
               use_kpm=True,
               kpath=None,
               scale=10.0,
               ewindow=4.0,
               ne=1000,
               delta=0.01,
               ntries=10):
    """Calculate the KDOS bands using the KPM"""
    if not use_kpm: raise  # nope
    hkgen = h.get_hk_gen()  # get generator
    if kpath is None: kpath = klist.default(h.geometry)  # default
    fo = open("KDOS_BANDS.OUT", "w")  # open file
    ik = 0
    tr = timing.Testimator("KDOS")  # generate object
    for k in kpath:  # loop over kpoints
        tr.remaining(ik, len(kpath))
        hk = hkgen(k)  # get Hamiltonian
        npol = int(scale / delta)  # number of polynomials
        (x, y) = kpm.tdos(hk,
                          scale=scale,
                          npol=npol,
                          ne=ne,
                          ewindow=ewindow,
                          ntries=ntries)  # compute
        for (ix, iy) in zip(x, y):  # loop
            fo.write(str(ik / len(kpath)) + "   ")
            fo.write(str(ix) + "   ")
            fo.write(str(iy) + "\n")
        fo.flush()
        ik += 1
    fo.close()
Esempio n. 4
0
File: kdos.py Progetto: zx-sdu/pygra
def interface(h1,
              h2,
              energies=np.linspace(-1., 1., 100),
              operator=None,
              delta=0.01,
              kpath=None):
    """Get the surface DOS of an interface"""
    from scipy.sparse import csc_matrix, bmat
    if kpath is None:
        if h1.dimensionality == 3:
            g2d = h1.geometry.copy()  # copy Hamiltonian
            import sculpt
            g2d = sculpt.set_xy_plane(g2d)
            kpath = klist.default(g2d, nk=100)
        elif h1.dimensionality == 2:
            kpath = [[k, 0., 0.] for k in np.linspace(0., 1., 40)]
        else:
            raise
    fo = open("KDOS_INTERFACE.OUT", "w")
    fo.write("# k, E, Bulk1, Surf1, Bulk2, Surf2, interface\n")
    tr = timing.Testimator("KDOS")  # generate object
    ik = 0
    h1 = h1.get_multicell()  # multicell Hamiltonian
    h2 = h2.get_multicell()  # multicell Hamiltonian
    for k in kpath:
        tr.remaining(ik, len(kpath))  # generate object
        ik += 1
        #    for energy in energies:
        #  (b1,s1,b2,s2,b12) = green.interface(h1,h2,k=k,energy=energy,delta=delta)
        #      out = green.interface(h1,h2,k=k,energy=energy,delta=delta)
        outs = green.interface_multienergy(h1,
                                           h2,
                                           k=k,
                                           energies=energies,
                                           delta=delta)
        for (energy, out) in zip(energies, outs):
            if operator is None:
                op = np.identity(h1.intra.shape[0] * 2)  # normal cell
                ops = np.identity(h1.intra.shape[0])  # supercell


#      elif callable(operator): op = callable(op)
            else:
                op = operator  # normal cell
                ops = bmat([[csc_matrix(operator), None],
                            [None, csc_matrix(operator)]])
            # write everything
            fo.write(str(ik) + "   " + str(energy) + "   ")
            for g in out:  # loop
                if g.shape[0] == op.shape[0]:
                    d = -(g * op).trace()[0, 0].imag  # bulk
                else:
                    d = -(g * ops).trace()[0, 0].imag  # interface
                fo.write(str(d) + "   ")
            fo.write("\n")
            fo.flush()  # flush
    fo.close()
Esempio n. 5
0
def lowest_bands(h,
                 nkpoints=100,
                 nbands=10,
                 operator=None,
                 info=False,
                 kpath=None,
                 discard=None):
    """ Returns a figure with the bandstructure of the system"""
    from scipy.sparse import csc_matrix
    if kpath is None:
        k = klist.default(h.geometry)  # default path
    else:
        k = kpath
    import gc  # garbage collector
    fo = open("BANDS.OUT", "w")
    if operator is None:  # if there is not an operator
        if h.dimensionality == 0:  # dot
            eig, eigvec = slg.eigsh(csc_matrix(h.intra),
                                    k=nbands,
                                    which="LM",
                                    sigma=0.0,
                                    tol=arpack_tol,
                                    maxiter=arpack_maxiter)
            eigvec = eigvec.transpose()  # transpose
            iw = 0
            for i in range(len(eig)):
                if discard is not None:  # use the function
                    v = eigvec[i]  # eigenfunction
                    if discard(v): continue
                fo.write(str(iw) + "     " + str(eig[i]) + "\n")
                iw += 1  # increase counter
        elif h.dimensionality > 0:
            hkgen = h.get_hk_gen()  # get generator
            for ik in k:  # ribbon
                hk = hkgen(ik)  # get hamiltonians
                gc.collect()  # clean memory
                eig, eigvec = slg.eigsh(hk, k=nbands, which="LM", sigma=0.0)
                del eigvec  # clean eigenvectors
                del hk  # clean hk
                for e in eig:
                    fo.write(str(ik) + "     " + str(e) + "\n")
                if info: print("Done", ik, end="\r")
        else: raise  # ups
    else:  # if there is an operator
        if h.dimensionality == 1:
            hkgen = h.get_hk_gen()  # get generator
            for ik in k:
                hk = hkgen(ik)  # get hamiltonians
                eig, eigvec = slg.eigsh(hk, k=nbands, which="LM", sigma=0.0)
                eigvec = eigvec.transpose()  # tranpose the matrix
                if info: print("Done", ik, end="\r")
                for (e, v) in zip(eig, eigvec):  # loop over eigenvectors
                    a = braket_wAw(v, operator)
                    fo.write(
                        str(ik) + "     " + str(e) + "     " + str(a) + "\n")
    fo.close()
Esempio n. 6
0
def surface(h1,
            energies=np.linspace(-1., 1., 100),
            operator=None,
            delta=0.01,
            kpath=None,
            hs=None):
    """Get the surface DOS of an interface"""
    from scipy.sparse import csc_matrix, bmat
    if kpath is None:
        if h1.dimensionality == 3:
            g2d = h1.geometry.copy()  # copy Hamiltonian
            import sculpt
            g2d = sculpt.set_xy_plane(g2d)
            kpath = klist.default(g2d, nk=100)
        elif h1.dimensionality == 2:
            kpath = [[k, 0., 0.] for k in np.linspace(0., 1., 40)]
        else:
            raise
    fo = open("KDOS.OUT", "w")
    fo.write("# k, E, Surface, Bulk\n")
    tr = timing.Testimator("KDOS")  # generate object
    ik = 0
    h1 = h1.get_multicell()  # multicell Hamiltonian
    for k in kpath:
        tr.remaining(ik, len(kpath))  # generate object
        ik += 1
        outs = green.surface_multienergy(h1,
                                         k=k,
                                         energies=energies,
                                         delta=delta,
                                         hs=hs)
        for (energy, out) in zip(energies, outs):
            # write everything
            fo.write(str(ik) + "   " + str(energy) + "   ")
            for g in out:  # loop
                if operator is None:
                    d = -g.trace()[0, 0].imag  # only the trace
                elif callable(operator):
                    d = operator(g, k=k)  # call the operator
                else:
                    d = -(g *
                          operator).trace()[0, 0].imag  # assume it is a matrix
                fo.write(str(d) + "   ")  # write in a file
            fo.write("\n")  # next line
            fo.flush()  # flush
    fo.close()
Esempio n. 7
0
def multi_states(h, ewindow=[-0.5, 0.5], signed=False, ks=None):
    """Calculate the bands and states in an energy window,
  and write them in a folder"""
    import os
    if ks is None:
        import klist
        ks = klist.default(h.geometry)  # generate default klist
    os.system("rm -rf MULTISTATES_KPATH")  # delete folder
    os.system("mkdir MULTISTATES_KPATH")  # create folder
    os.chdir("MULTISTATES_KPATH")  # go to the folder
    ik = 0
    for k in ks:  # loop over kpoints
        print("MULTISTATES for", k)
        states2d(h,
                 ewindow=ewindow,
                 signed=signed,
                 k=k,
                 prefix="K_" + str(ik) + "_")
        ik += 1
    os.chdir("..")  # go to the folder
Esempio n. 8
0
def get_bands_2d(h, kpath=None, operator=None, num_bands=None):
    """Get a 2d bandstructure"""
    if num_bands is None:  # all the bands
        if operator is not None:
            diagf = lg.eigh  # all eigenvals and eigenfuncs
        else:
            diagf = lg.eigvalsh  # all eigenvals and eigenfuncs
    else:  # using arpack
        h.turn_sparse()  # sparse Hamiltonian

        def diagf(m):
            eig, eigvec = slg.eigsh(m, k=num_bands, which="LM", sigma=0.0)
            if operator is None: return eig
            else: return (eig, eigvec)

    # open file and get generator
    f = open("BANDS.OUT", "w")  # open bands file
    hkgen = h.get_hk_gen()  # generator hamiltonian
    if operator is not None:
        operator = np.matrix(operator)  # convert to matrix
    if kpath is None:
        import klist
        kpath = klist.default(h.geometry)  # generate default klist
    for k in range(len(kpath)):  # loop over kpoints
        print("Doing kpoint", k)
        hk = hkgen(kpath[k])  # get hamiltonian
        if operator is None:
            es = diagf(hk)
            for e in es:  # loop over energies
                f.write(str(k) + "   " + str(e) + "\n")  # write in file
        else:
            es, ws = diagf(hk)
            ws = ws.transpose()  # transpose eigenvectors
            for (e, w) in zip(es, ws):  # loop over waves
                w = np.matrix(w)  # convert to matrix
                waw = (w.T).H * operator * w.T  # expectation value
                waw = waw[0, 0].real  # real part
                f.write(str(k) + "   " + str(e) + "  " + str(waw) +
                        "\n")  # write in file
    f.close()
    return np.genfromtxt("BANDS.OUT").transpose()  # return data
Esempio n. 9
0
import geometry  # library to create crystal geometries
import hamiltonians  # library to work with hamiltonians
import input_tb90 as in90
import heterostructures
import sys
import sculpt  # to modify the geometry
import numpy as np
import klist
import pylab as py
import green
import topology

g = geometry.honeycomb_lattice()  # create a honeycomb lattice
h = g.get_hamiltonian() # create the hamiltonian
h.add_sublattice_imbalance(.1)
#h.add_rashba(.01)
#h.add_zeeman([0.,0.,.2])
h.add_kane_mele(0.1)
#h.remove_spin()
kl = klist.default(h,100)
#be = [topology.berry_curvature(h,k) for k in kl]
print topology.z2_invariant(h,nk=100)
#print topology.chern(h,nk=50)

#py.plot(kl,be)
#py.show()
Esempio n. 10
0
def get_bands_2d(h,
                 kpath=None,
                 operator=None,
                 num_bands=None,
                 callback=None,
                 central_energy=0.0):
    """Get a 2d bandstructure"""
    if num_bands is None:  # all the bands
        if operator is not None:

            def diagf(m):  # diagonalization routine
                if h.is_sparse and h.intra.shape[0] < maxdim:
                    return lg.eigh(m.todense())  # all eigenvals and eigenfuncs
                else:
                    return lg.eigh(m)  # all eigenvals and eigenfuncs
        else:

            def diagf(m):  # diagonalization routine
                if h.is_sparse and h.intra.shape[0] < maxdim:
                    return lg.eigvalsh(
                        m.todense())  # all eigenvals and eigenfuncs
                else:
                    return lg.eigvalsh(m)  # all eigenvals and eigenfuncs
    else:  # using arpack
        h = h.copy()
        h.turn_sparse()  # sparse Hamiltonian

        def diagf(m):
            eig, eigvec = slg.eigsh(m,
                                    k=num_bands,
                                    which="LM",
                                    sigma=central_energy,
                                    tol=arpack_tol,
                                    maxiter=arpack_maxiter)
            if operator is None: return eig
            else: return (eig, eigvec)

    # open file and get generator
    f = open("BANDS.OUT", "w")  # open bands file
    hkgen = h.get_hk_gen()  # generator hamiltonian
    if kpath is None:
        import klist
        kpath = klist.default(h.geometry)  # generate default klist
    tr = timing.Testimator("BANDSTRUCTURE")  # generate object
    for k in range(len(kpath)):  # loop over kpoints
        #    print("Bands in kpoint",k,"of",len(kpath),end="\r")
        tr.remaining(k, len(kpath))
        hk = hkgen(kpath[k])  # get hamiltonian
        if operator is None:
            es = diagf(hk)
            for e in es:  # loop over energies
                f.write(str(k) + "   " + str(e) + "\n")  # write in file
            if callback is not None: callback(k, es)  # call the function
        else:
            es, ws = diagf(hk)
            ws = ws.transpose()  # transpose eigenvectors
            for (e, w) in zip(es, ws):  # loop over waves
                if callable(operator):
                    try:
                        waw = operator(w, k=kpath[k])  # call the operator
                    except:
                        print("Check out the k optional argument in operator")
                        waw = operator(w)  # call the operator
                else:
                    waw = braket_wAw(
                        w, operator).real  # calculate expectation value
                f.write(str(k) + "   " + str(e) + "  " + str(waw) +
                        "\n")  # write in file
            # callback function in each iteration
            if callback is not None: callback(k, es, ws)  # call the function
        f.flush()
    f.close()
    print("\nBANDS finished")
    return np.genfromtxt("BANDS.OUT").transpose()  # return data
Esempio n. 11
0
import geometry  # library to create crystal geometries
import hamiltonians  # library to work with hamiltonians
import input_tb90 as in90
import heterostructures
import sys
import sculpt  # to modify the geometry
import numpy as np
import klist
import pylab as py
import green
import topology

g = geometry.honeycomb_lattice()  # create a honeycomb lattice
h = g.get_hamiltonian()  # create the hamiltonian
h.add_sublattice_imbalance(.1)
#h.add_rashba(.01)
#h.add_zeeman([0.,0.,.2])
h.add_kane_mele(0.1)
#h.remove_spin()
kl = klist.default(h, 100)
#be = [topology.berry_curvature(h,k) for k in kl]
print topology.z2_invariant(h, nk=100)
#print topology.chern(h,nk=50)

#py.plot(kl,be)
#py.show()