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
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
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()
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()
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()
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()
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
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
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()
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
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()