def save_readable(hamiltonian, output_file="hamiltonian.wan"): """Saves a wannier hamiltonian in xml format""" strf = "{:10.8f}".format # float format hamiltonian = multicell.turn_multicell(hamiltonian) #### start write the hamiltonian ### fo = open(output_file, "w") # human readable fo.write("# nx, ny, nz, i, j, real, imaginary\n") # intracell object (workaround) class ObjHop: pass intraobj = ObjHop() intraobj.dir = [0, 0, 0] # store direction intraobj.m = hamiltonian.intra # store matrix for hop in [intraobj] + hamiltonian.hopping: d = hop.dir # direction m = hop.m # hopping matrix m = coo_matrix(m) # to coo matrix ii = m.row # row index jj = m.col # column idex data = m.data # data for (i, j, mij) in zip(ii, jj, data): # loop over elements # human readable fo.write(" " + str(d[0]) + " " + str(d[1]) + " " + str(d[2]) + " ") fo.write(str(i + 1) + " " + str(j + 1) + " ") fo.write(strf(mij.real) + " " + strf(mij.imag) + "\n") fo.close() # close hamiltonian file
def save_readable(hamiltonian,output_file="hamiltonian.wan"): """Saves a wannier hamiltonian in xml format""" strf = "{:10.8f}".format # float format hamiltonian = multicell.turn_multicell(hamiltonian) #### start write the hamiltonian ### fo = open(output_file,"w") # human readable fo.write("# nx, ny, nz, i, j, real, imaginary\n") # intracell object (workaround) class ObjHop: pass intraobj = ObjHop() intraobj.dir = [0,0,0] # store direction intraobj.m = hamiltonian.intra # store matrix for hop in [intraobj]+hamiltonian.hopping: d = hop.dir # direction m = hop.m # hopping matrix m = coo_matrix(m) # to coo matrix ii = m.row # row index jj = m.col # column idex data = m.data # data for (i,j,mij) in zip(ii,jj,data): # loop over elements # human readable fo.write(" "+str(d[0])+" "+str(d[1])+" "+str(d[2])+" ") fo.write(str(i+1)+" "+str(j+1)+" ") fo.write(strf(mij.real)+" "+strf(mij.imag)+"\n") fo.close() # close hamiltonian file
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
def operator_berry_bands(hin,k=[0.,0.],operator=None,delta=0.00001): """Calculates the Berry curvature using an arbitrary operator""" h = multicell.turn_multicell(hin) # turn to multicell form dhdx = multicell.derivative(h,k,order=[1,0]) # derivative dhdy = multicell.derivative(h,k,order=[0,1]) # derivative hkgen = h.get_hk_gen() # get generator hk = hkgen(k) # get hamiltonian (es,ws) = lg.eigh(hkgen(k)) # initial waves ws = np.conjugate(np.transpose(ws)) # transpose the waves from berry_curvaturef90 import berry_curvature_bands as bcb90 if operator is None: operator = np.identity(dhdx.shape[0],dtype=np.complex) bs = bcb90(dhdx,dhdy,ws,es,operator,delta) # berry curvatures return (es,bs*np.pi*np.pi*8) # normalize so the sum is 2pi Chern
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
def operator_berry_bands(hin, k=[0., 0.], operator=None, delta=0.00001): """Calculates the Berry curvature using an arbitrary operator""" h = multicell.turn_multicell(hin) # turn to multicell form dhdx = multicell.derivative(h, k, order=[1, 0]) # derivative dhdy = multicell.derivative(h, k, order=[0, 1]) # derivative hkgen = h.get_hk_gen() # get generator hk = hkgen(k) # get hamiltonian (es, ws) = lg.eigh(hkgen(k)) # initial waves ws = np.conjugate(np.transpose(ws)) # transpose the waves from berry_curvaturef90 import berry_curvature_bands as bcb90 if operator is None: operator = np.identity(dhdx.shape[0], dtype=np.complex) bs = bcb90(dhdx, dhdy, ws, es, operator, delta) # berry curvatures return (es, bs * np.pi * np.pi * 8) # normalize so the sum is 2pi Chern
def effective2d(hin,k0 = 0.0,ewindow = [-1.0,1.0]): """Calculates the effective Hamiltonian for a 2d system""" h = multicell.turn_multicell(hin) # multicell form hkgen = h.get_hk_gen() # get hamiltonian generator (es,ws) = lg.eigh(hkgen(k0)) # initial waves ws = np.transpose(ws) # transpose the waves wf0 = [] # list to store waves for i in range(len(es)): # loop over energies if ewindow[0]<ewindow[1]: # check whether in window wf0.append(ws[i]) # store this wave # now calculate the effective Hamiltonian raise for order in orders: # loop over orders dh = multicell.derivative(h,k0,order=order) # derivative of the hamiltonian
def effective2d(hin, k0=0.0, ewindow=[-1.0, 1.0]): """Calculates the effective Hamiltonian for a 2d system""" h = multicell.turn_multicell(hin) # multicell form hkgen = h.get_hk_gen() # get hamiltonian generator (es, ws) = lg.eigh(hkgen(k0)) # initial waves ws = np.transpose(ws) # transpose the waves wf0 = [] # list to store waves for i in range(len(es)): # loop over energies if ewindow[0] < ewindow[1]: # check whether in window wf0.append(ws[i]) # store this wave # now calculate the effective Hamiltonian raise for order in orders: # loop over orders dh = multicell.derivative(h, k0, order=order) # derivative of the hamiltonian
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
import geometry import multicell import hall g = geometry.honeycomb_lattice() # g = geometry.square_lattice() h = g.get_hamiltonian() h.remove_spin() h = multicell.turn_multicell(h) #h = multicell.rotate(h) hr = hall.bulk2ribbon(h, mag_field=0.01, n=80, sparse=True) # hr = multicell.bulk2ribbon(h,n=40,sparse=False) #hr.geometry.write() hr.get_bands()
def save(output_file="wannier.xml", hamiltonian=None): """Saves a wannier hamiltonian in xml format""" import xml.etree.cElementTree as ET strf = "{:10.8f}".format # float format if hamiltonian is None: # no hamiltonian provided hamiltonian = read_multicell_hamiltonian() # read hamiltonian else: hamiltonian = multicell.turn_multicell(hamiltonian) root = ET.Element("wannier") # root element try: orbs = hamiltonian.orbitals # name of the orbitals except: orbs = ["X,Y" for i in range(hamiltonian.intra.shape[0])] geo = hamiltonian.geometry # geometry of the crystal #### start write the orbitals ### orbxml = ET.SubElement(root, "orbitals") # subelement orbitals fo = open("orbitals.wan", "w") # human readable ffrac = open("fractional_coordinates.wan", "w") # human readable freal = open("real_coordinates.wan", "w") # human readable fo.write("# index, name, position\n") ffrac.write("# position\n") freal.write("# position\n") for i in range(len(geo.r)): orbital = ET.SubElement(orbxml, "orbital") # subelement orbital ET.SubElement(orbital, "index").text = str(i) ET.SubElement(orbital, "atom_name").text = orbs[i].split(",")[0] ET.SubElement(orbital, "orbital_name").text = orbs[i].split(",")[1] ET.SubElement(orbital, "x").text = strf(geo.x[i]) ET.SubElement(orbital, "y").text = strf(geo.y[i]) ET.SubElement(orbital, "z").text = strf(geo.z[i]) ET.SubElement(orbital, "frac_x").text = strf(geo.frac_x[i]) ET.SubElement(orbital, "frac_y").text = strf(geo.frac_y[i]) ET.SubElement(orbital, "frac_z").text = strf(geo.frac_z[i]) # human readable fo.write(" " + str(i + 1) + " " + orbs[i] + " ") fo.write( strf(geo.x[i]) + " " + strf(geo.y[i]) + " " + strf(geo.z[i]) + " ") freal.write( strf(geo.x[i]) + " " + strf(geo.y[i]) + " " + strf(geo.z[i]) + "\n") fo.write( strf(geo.frac_x[i]) + " " + strf(geo.frac_y[i]) + " " + strf(geo.frac_z[i]) + "\n") ffrac.write( strf(geo.frac_x[i]) + " " + strf(geo.frac_y[i]) + " " + strf(geo.frac_z[i]) + "\n") #### end write the orbitals ### fo.close() ffrac.close() freal.close() #### start write the geometry ### geoxml = ET.SubElement(root, "geometry") # subelement orbitals aname = ["a1", "a2", "a3"] # name of unit vectors aobj = [geo.a1, geo.a2, geo.a3] fg = open("geometry.wan", "w") # geometry file fg.write("# unit cell vectors\n") for (an, ao) in zip(aname, aobj): # loop over vectors a1xml = ET.SubElement(geoxml, an) # subelement orbital ET.SubElement(a1xml, "x").text = strf(ao[0]) ET.SubElement(a1xml, "y").text = strf(ao[1]) ET.SubElement(a1xml, "z").text = strf(ao[2]) fg.write(strf(ao[0]) + " " + strf(ao[1]) + " " + strf(ao[2]) + "\n") fg.close() #### end write the geometry ### #### start write the hamiltonian ### ham = ET.SubElement(root, "hamiltonian") # subelement hamiltonian fo = open("hamiltonian.wan", "w") # human readable fo.write("# nx, ny, nz, i, j, real, imaginary\n") # intracell object (workaround) intraobj = deepcopy(hamiltonian.hopping[0]) intraobj.dir = [0, 0, 0] # store direction intraobj.m = hamiltonian.intra # store matrix for hop in [intraobj] + hamiltonian.hopping: d = hop.dir # direction m = hop.m # hopping matrix m = coo_matrix(m) # to coo matrix ii = m.row # row index jj = m.col # column idex data = m.data # data for (i, j, mij) in zip(ii, jj, data): # loop over elements dist = geo.r[i] - (geo.r[j] + d[0] * geo.a1 + d[1] * geo.a2 + d[2] * geo.a3) dist = np.sqrt(dist.dot(dist)) element = ET.SubElement(ham, "hopping") # subelement hamiltonian ET.SubElement(element, "nx").text = str(d[0]) # element ET.SubElement(element, "ny").text = str(d[1]) # element ET.SubElement(element, "nz").text = str(d[2]) # element ET.SubElement(element, "i").text = str(i + 1) # element ET.SubElement(element, "j").text = str(j + 1) # element ET.SubElement(element, "iname").text = orbs[i] # element ET.SubElement(element, "jname").text = orbs[j] # element ET.SubElement(element, "real_amplitude").text = strf(mij.real) # element ET.SubElement(element, "imag_amplitude").text = strf(mij.imag) # element ET.SubElement(element, "distance").text = strf(dist) # element # human readable fo.write(" " + str(d[0]) + " " + str(d[1]) + " " + str(d[2]) + " ") fo.write(str(i + 1) + " " + str(j + 1) + " ") fo.write(strf(mij.real) + " " + strf(mij.imag) + "\n") fo.close() # close hamiltonian file #### end write the hamiltonian ### #### save everything ### tree = ET.ElementTree(root) # create whole tree tree.write("wannier.xml") # write tree import xml.dom.minidom xml = xml.dom.minidom.parse("wannier.xml") open("wannier.xml", "w").write(xml.toprettyxml())
def save(output_file="wannier.xml",hamiltonian=None): """Saves a wannier hamiltonian in xml format""" import xml.etree.cElementTree as ET strf = "{:10.8f}".format # float format if hamiltonian is None: # no hamiltonian provided hamiltonian = read_multicell_hamiltonian() # read hamiltonian else: hamiltonian = multicell.turn_multicell(hamiltonian) root = ET.Element("wannier") # root element try: orbs = hamiltonian.orbitals # name of the orbitals except: orbs = ["X,Y" for i in range(hamiltonian.intra.shape[0])] geo = hamiltonian.geometry # geometry of the crystal #### start write the orbitals ### orbxml = ET.SubElement(root, "orbitals") # subelement orbitals fo = open("orbitals.wan","w") # human readable ffrac = open("fractional_coordinates.wan","w") # human readable freal = open("real_coordinates.wan","w") # human readable fo.write("# index, name, position\n") ffrac.write("# position\n") freal.write("# position\n") for i in range(len(geo.r)): orbital = ET.SubElement(orbxml, "orbital") # subelement orbital ET.SubElement(orbital, "index").text = str(i) ET.SubElement(orbital, "atom_name").text = orbs[i].split(",")[0] ET.SubElement(orbital, "orbital_name").text = orbs[i].split(",")[1] ET.SubElement(orbital, "x").text = strf(geo.x[i]) ET.SubElement(orbital, "y").text = strf(geo.y[i]) ET.SubElement(orbital, "z").text = strf(geo.z[i]) ET.SubElement(orbital, "frac_x").text = strf(geo.frac_x[i]) ET.SubElement(orbital, "frac_y").text = strf(geo.frac_y[i]) ET.SubElement(orbital, "frac_z").text = strf(geo.frac_z[i]) # human readable fo.write(" "+str(i+1)+" "+orbs[i]+" ") fo.write(strf(geo.x[i])+" "+strf(geo.y[i])+" "+strf(geo.z[i])+" ") freal.write(strf(geo.x[i])+" "+strf(geo.y[i])+" "+strf(geo.z[i])+"\n") fo.write(strf(geo.frac_x[i])+" "+strf(geo.frac_y[i])+" "+strf(geo.frac_z[i])+"\n") ffrac.write(strf(geo.frac_x[i])+" "+strf(geo.frac_y[i])+" "+strf(geo.frac_z[i])+"\n") #### end write the orbitals ### fo.close() ffrac.close() freal.close() #### start write the geometry ### geoxml = ET.SubElement(root, "geometry") # subelement orbitals aname = ["a1","a2","a3"] # name of unit vectors aobj = [geo.a1,geo.a2,geo.a3] fg = open("geometry.wan","w") # geometry file fg.write("# unit cell vectors\n") for (an,ao) in zip(aname,aobj): # loop over vectors a1xml = ET.SubElement(geoxml, an) # subelement orbital ET.SubElement(a1xml, "x").text = strf(ao[0]) ET.SubElement(a1xml, "y").text = strf(ao[1]) ET.SubElement(a1xml, "z").text = strf(ao[2]) fg.write(strf(ao[0])+" "+strf(ao[1])+" "+strf(ao[2])+"\n") fg.close() #### end write the geometry ### #### start write the hamiltonian ### ham = ET.SubElement(root, "hamiltonian") # subelement hamiltonian fo = open("hamiltonian.wan","w") # human readable fo.write("# nx, ny, nz, i, j, real, imaginary\n") # intracell object (workaround) intraobj = deepcopy(hamiltonian.hopping[0]) intraobj.dir = [0,0,0] # store direction intraobj.m = hamiltonian.intra # store matrix for hop in [intraobj]+hamiltonian.hopping: d = hop.dir # direction m = hop.m # hopping matrix m = coo_matrix(m) # to coo matrix ii = m.row # row index jj = m.col # column idex data = m.data # data for (i,j,mij) in zip(ii,jj,data): # loop over elements dist = geo.r[i] - (geo.r[j]+d[0]*geo.a1+d[1]*geo.a2+d[2]*geo.a3) dist = np.sqrt(dist.dot(dist)) element = ET.SubElement(ham, "hopping") # subelement hamiltonian ET.SubElement(element, "nx").text = str(d[0]) # element ET.SubElement(element, "ny").text = str(d[1]) # element ET.SubElement(element, "nz").text = str(d[2]) # element ET.SubElement(element, "i").text = str(i+1) # element ET.SubElement(element, "j").text = str(j+1) # element ET.SubElement(element, "iname").text = orbs[i] # element ET.SubElement(element, "jname").text = orbs[j] # element ET.SubElement(element, "real_amplitude").text = strf(mij.real) # element ET.SubElement(element, "imag_amplitude").text = strf(mij.imag) # element ET.SubElement(element, "distance").text = strf(dist) # element # human readable fo.write(" "+str(d[0])+" "+str(d[1])+" "+str(d[2])+" ") fo.write(str(i+1)+" "+str(j+1)+" ") fo.write(strf(mij.real)+" "+strf(mij.imag)+"\n") fo.close() # close hamiltonian file #### end write the hamiltonian ### #### save everything ### tree = ET.ElementTree(root) # create whole tree tree.write("wannier.xml") # write tree import xml.dom.minidom xml = xml.dom.minidom.parse("wannier.xml") open("wannier.xml","w").write(xml.toprettyxml())
def get_multicell(self): """Return a multicell Hamiltonian""" return multicell.turn_multicell(self)