def bloch_selfenergy(h,nk=100,energy = 0.0, delta = 0.01,mode="full", error=0.00001): """ Calculates the selfenergy of a cell defect, input is a hamiltonian class""" if mode=="adaptative": mode = "adaptive" def gr(ons,hop): """ Calculates G by renormalization""" gf,sf = green_renormalization(ons,hop,energy=energy,nite=None, error=error,info=False,delta=delta) return gf,sf hk_gen = h.get_hk_gen() # generator of k dependent hamiltonian if h.is_multicell: mode = "full" # multicell hamiltonians only have full mode print("Changed to full mode in selfenergy") d = h.dimensionality # dimensionality of the system g = h.intra *0.0j # initialize green function e = np.matrix(np.identity(len(g)))*(energy + delta*1j) # complex energy if mode=="full": # full integration if d==1: # one dimensional ks = np.linspace(0.,1.,nk,endpoint=False) elif d==2: # two dimensional ks = [] kk = np.linspace(0.,1.,nk,endpoint=False) # interval 0,1 for ikx in kk: for iky in kk: ks.append([ikx,iky]) ks = np.array(ks) # all the kpoints else: raise # raise error for k in ks: # loop in BZ g += (e - hk_gen(k)).I # add green function g = g/len(ks) # normalize ##################################################### ##################################################### if mode=="renormalization": if d==1: # full renormalization g,s = gr(h.intra,h.inter) # perform renormalization elif d==2: # two dimensional, loop over k's ks = np.linspace(0.,1.,nk,endpoint=False) for k in ks: # loop over k in y direction # add contribution to green function g += green_kchain(h,k=k,energy=energy,delta=delta,error=error) g = g/len(ks) ##################################################### ##################################################### if mode=="adaptive": if d==1: # full renormalization g,s = gr(h.intra,h.inter) # perform renormalization elif d==2: # two dimensional, loop over k's ks = np.linspace(0.,1.,nk,endpoint=False) import integration def fint(k): """ Function to integrate """ return green_kchain(h,k=k,energy=energy,delta=delta,error=error) # eps is error, might work.... g = integration.integrate_matrix(fint,xlim=[0.,1.],eps=error) # chain in the y direction else: raise # now calculate selfenergy selfenergy = e - h.intra - g.I return g,selfenergy
def chi1d(h,energies = [0.],t=0.0001,delta=0.01,q=0.001,nk=1000,U=None,adaptive=True,ks=None): hkgen = h.get_hk_gen() # get the generating hamiltonian n = len(h.geometry.x) # initialice response m = np.zeros((len(energies),n*n),dtype=np.complex) # initialice if not adaptive: # full algorithm if ks==None: ks = np.linspace(0.,1.,nk) # create klist for k in ks: # print "Doing k=",k hk = hkgen(k) # fist point e1,ev1 = lg.eigh(hk) # get eigenvalues hk = hkgen(k+q) # second point e2,ev2 = lg.eigh(hk) # get eigenvalues ct = calculate_xychi(ev1.T,e1,ev2.T,e2,energies,t,delta) # contribution m += ct m = m/nk # normalice by the number of kpoints ms = [m[i,:].reshape(n,n) for i in range(len(m))] # convert to matrices if adaptive: # adaptive algorithm from integration import integrate_matrix def get_chik(k): # function which returns a matrix """ Get response at a cetain energy""" hk = hkgen(k) # first point e1,ev1 = lg.eigh(hk) # get eigenvalues hk = hkgen(k+q) # second point e2,ev2 = lg.eigh(hk) # get eigenvalues ct = calculate_xychi(ev1.T,e1,ev2.T,e2,energies,t,delta) # contribution return ct # return response ms = [] m = integrate_matrix(get_chik,xlim=[0.,1.],eps=.1,only_imag=False) # add energy ms = [m[i,:].reshape(n,n) for i in range(len(m))] # convert to matrices if U==None: # raw calculation return ms else: # RPA calculation return rpachi(ms,U=U)
def get_chik_dim2(kx): # first integration def get_chik_dim1(ky): # redefine the function, second integration return get_chik(np.array([kx, ky])) ct = integrate_matrix(get_chik_dim1, xlim=[0., 1.], eps=delta / 100., only_imag=False) return ct # return second integration
def berry_green_map(h, emin=-10.0, k=[0., 0., 0.], ne=100, dk=0.0001, operator=None, delta=0.002): """Return the Berry curvature map at a certain kpoint""" f = h.get_gk_gen(delta=delta) # green function generator fgreen = berry_green_generator(f, k=k, dk=dk, operator=operator, full=True) def fint(x): # print(x) # print(x) # return fgreen(x).trace()[0,0] # return diagonal return np.diag(fgreen(x)) # return diagonal es = np.linspace(emin, 0., ne) # energies used for the integration ### The original function is defined in the coplex plane, # we will do a change of variables of the form z = re^(iphi) - r0 # so that dz = re^(iphi) i dphi def fint2(x): """Function to integrate using a complex contour, from 0 to 1""" z0 = emin * np.exp(-1j * x * np.pi) / 2. z = z0 + emin / 2. print("Evaluating", x) return -(fint(z) * z0).imag * np.pi # integral after the change of variables out = np.zeros(h.intra.shape[0], dtype=np.complex) # initialize from integration import integrate_matrix out = integrate_matrix(fint2, xlim=[0., 1.], eps=1e-8) # tr = timing.Testimator("BERRY MAP") # initialize # ix = 0 # ne = 500 # for x in np.linspace(0.,1.,ne): # ix += 1 # tr.remaining(ix,ne) # out = out + fint2(x) # add contribution out = out.real # turn real print("Sum", np.sum(out)) import geometry geometry.write_profile(h.geometry, out, name="BERRY_MAP.OUT", nrep=2) return out
def berry_green_map(h, emin=-10.0, k=[0., 0., 0.], ne=100, dk=0.0001, operator=None, delta=0.002, nrep=2, integral=True): """Return the Berry curvature map at a certain kpoint""" f = h.get_gk_gen(delta=delta, canonical_phase=True) # green function generator fgreen = berry_green_generator(f, k=k, dk=dk, operator=operator, full=True) def fint(x): # return fgreen(x).trace()[0,0] # return diagonal return np.diag(fgreen(x)) # return diagonal es = np.linspace(emin, 0., ne) # energies used for the integration ### The original function is defined in the complex plane, # we will do a change of variables of the form z = re^(iphi) - r0 # so that dz = re^(iphi) i dphi if integral: # integrate up to the fermi energy def fint2(x): """Function to integrate using a complex contour, from 0 to 1""" z0 = emin * np.exp(-1j * x * np.pi) / 2. z = z0 + emin / 2. print("Evaluating", x) return -(fint(z) * z0).imag * np.pi # integral after the change of variables from integration import integrate_matrix out = integrate_matrix(fint2, xlim=[0., 1.], eps=1e-1) out = out.real # turn real else: # evaluate at the fermi energy out = fint(0.0).real print("Sum", np.sum(out)) import geometry from ldos import spatial_dos geometry.write_profile(h.geometry, spatial_dos(h, out), name="BERRY_MAP.OUT", nrep=nrep) return out
def chi2d(h,energies = [0.],t=0.0001,delta=0.01,q=np.array([0.001,0.0]),nk=20,U=None,ks=None,collinear=False,adaptive=False): hkgen = h.get_hk_gen() # get the generating hamiltonian n = len(h.geometry.x) # initialice response m = np.zeros((len(energies),n*n),dtype=np.complex) # initialice ############################## def get_chik(k): """Function to integrate""" hk = hkgen(k) # fist point if collinear: hk = np.matrix([[hk[2*i,2*j] for i in range(len(hk)/2)] for j in range(len(hk)/2)]) # up component e1,ev1 = lg.eigh(hk) # get eigenvalues hk = hkgen(k+q) # second point if collinear: hk = np.matrix([[hk[2*i+1,2*j+1] for i in range(len(hk)/2)] for j in range(len(hk)/2)]) # down component e2,ev2 = lg.eigh(hk) # get eigenvalues if collinear: ct = collinear_xychi(ev1.T,e1,ev2.T,e2,energies,t,delta) # contribution else: ct = calculate_xychi(ev1.T,e1,ev2.T,e2,energies,t,delta) # contribution return ct ######################### if adaptive: # adaptive integration from integration import integrate_matrix def get_chik_dim2(kx): # first integration def get_chik_dim1(ky): # redefine the function, second integration return get_chik(np.array([kx,ky])) ct = integrate_matrix(get_chik_dim1,xlim=[0.,1.],eps=delta/100.,only_imag=False) return ct # return second integration m = integrate_matrix(get_chik_dim2,xlim=[0.,1.],eps=delta/100.,only_imag=False) # add energy else: # normal integration ks = np.linspace(0.,1.,nk) # create klist for kx in ks: for ky in ks: k = np.array([kx,ky]) ct = get_chik(k) m += ct m = m/(nk**2) # normalice by the number of kpoints ms = [m[i,:].reshape(n,n) for i in range(len(m))] # convert to matrices if U==None: # raw calculation return ms else: # RPA calculation return rpachi(ms,U=U)
def get_chik_dim2(kx): # first integration def get_chik_dim1(ky): # redefine the function, second integration return get_chik(np.array([kx,ky])) ct = integrate_matrix(get_chik_dim1,xlim=[0.,1.],eps=delta/100.,only_imag=False) return ct # return second integration