def Self_Consistency(self) : S.Transform_SymmetryBasis_toRealSpace (IN= S.Sigma, OUT = Sigma) # Embedding # Computes sum over BZ and returns density F = lambda mu : SK(mu = mu, Sigma = Sigma, field = None , result = G).total_density()/4 if Density_Required : self.Chemical_potential = dichotomy.dichotomy(function = F, x_init = self.Chemical_potential, y_value =Density_Required, precision_on_y = 0.01, delta_x=0.5, max_loops = 100, x_name="Chemical_Potential", y_name= "Total Density", verbosity = 3)[0] else: mpi.report("Total density = %.3f"%F(self.Chemical_potential)) S.Transform_RealSpace_to_SymmetryBasis (IN = G, OUT = S.G) # Extraction S.G0 = inverse(S.Sigma + inverse(S.G)) # Finally get S.G0
def GF_realomega(self,ommin,ommax,N_om,broadening=0.01): """Calculates the GF and spectral function on the real axis.""" delta_om = (ommax-ommin)/(1.0*(N_om-1)) omega = numpy.zeros([N_om],numpy.complex_) Mesh = numpy.zeros([N_om],numpy.float_) for i in range(N_om): omega[i] = ommin + delta_om * i + 1j * broadening Mesh[i] = ommin + delta_om * i temp = 1.0/self.beta gf,tail,self.atocc,self.atmag = gf_hi_fullu(e0f=self.ealmat, ur=self.ur, umn=self.umn, ujmn=self.ujmn, zmsb=omega, nmom=self.Nmoments, ns=self.Nspin, temp=temp, verbosity = self.Verbosity) for sig in self.a_list: for i in range(11): self.tailtempl[sig][i].array[:] *= 0.0 # transfer the data to the GF class: if (self.UseSpinOrbit): nlmtot = self.Nlm*2 # only one block in this case! else: nlmtot = self.Nlm M={} isp=-1 for a,al in self.GFStruct: isp+=1 #M[a] = gf[isp*self.Nlm:(isp+1)*self.Nlm,isp*self.Nlm:(isp+1)*self.Nlm,:] M[a] = gf[isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot,:] for i in range(min(self.Nmoments,10)): self.tailtempl[a][i+1].array[:] = tail[i][isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot] glist = lambda : [ GfReFreq(indices = al, beta = self.beta, mesh_array = Mesh, data =M[a], tail =self.tailtempl[a]) for a,al in self.GFStruct] # Indices for the upfolded G self.G = BlockGf(name_list = self.a_list, block_list = glist(),make_copies=False) # Self energy: self.G0 = self.G.copy() self.Sigma = self.G.copy() self.G0 <<= gf_init.A_Omega_Plus_B(A=1,B=1j*broadening) M = [ self.ealmat[isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot] for isp in range((2*self.Nlm)/nlmtot) ] self.G0 -= M self.Sigma <<= self.G0 - inverse(self.G) self.Sigma.note='ReFreq' # This is important for the put_Sigma routine!!!
from pytriqs.base.gf_local import GfReFreq, Omega, Wilson, inverse import numpy a = numpy.arange(-1.99, 2.00, 0.02) # Define the energy array eps_d, V = 0.3, 0.2 # Create the real-frequency Green's function and initialize it g = GfReFreq(indices=["s", "d"], beta=50, mesh_array=a, name="s+d") g["d", "d"] = Omega - eps_d g["d", "s"] = V g["s", "d"] = V g["s", "s"] = inverse(Wilson(1.0)) g.invert() # Plot it with matplotlib. 'S' means: spectral function ( -1/pi Imag (g) ) from pytriqs.base.plot.mpl_interface import oplot oplot(g["d", "d"], "-o", RI="S", x_window=(-1.8, 1.8), name="Impurity") oplot(g["s", "s"], "-x", RI="S", x_window=(-1.8, 1.8), name="Bath")
def Self_Consistency(G0,G): G0['0'] <<= inverse(Omega - (t**2)*G['0'])
# Import the Green's functions from pytriqs.base.gf_local import GfImFreq, iOmega_n, inverse # Create the Matsubara-frequency Green's function and initialize it g = GfImFreq(indices = [1], beta = 50, n_matsubara = 1000, name = "imp") g <<= inverse( iOmega_n + 0.5 ) from pytriqs.base.plot.mpl_interface import oplot oplot(g, '-o', x_window = (0,10))
from pytriqs.base.plot.mpl_interface import oplot from pytriqs.base.gf_local import GfImFreq, Omega, inverse g = GfImFreq(indices = [1], beta = 300, n_matsubara = 1000, name = "g") g <<= inverse( Omega + 0.5 ) # the data we want to fit... # The green function for omega \in [0,0.2] X,Y = g.x_data_view (x_window = (0,0.2), flatten_y = True ) from pytriqs.base.fit.fit import Fit, linear, quadratic fitl = Fit ( X,Y.imag, linear ) fitq = Fit ( X,Y.imag, quadratic ) oplot (g, '-o', x_window = (0,5) ) oplot (fitl , '-x', x_window = (0,0.5) ) oplot (fitq , '-x', x_window = (0,1) ) # a bit more complex, we want to fit with a one fermion level .... # Cf the definition of linear and quadratic in the lib one_fermion_level = lambda X, a,b : 1/(a * X *1j + b), r"${1}/(%f x + %f)$" , (1,1) fit1 = Fit ( X,Y, one_fermion_level ) oplot (fit1 , '-x', x_window = (0,3) )
def Solve(self,Iteration_Number=1,Test_Convergence=0.0001): """Calculation of the impurity Greens function using Hubbard-I""" # Test all a parameters before solutions print parameters.check(self.__dict__,self.Required,self.Optional) #SolverBase.Solve(self,is_last_iteration,Iteration_Number,Test_Convergence) if self.Converged : mpi.report("Solver %(name)s has already converted: SKIPPING"%self.__dict__) return self.__save_eal('eal.dat',Iteration_Number) mpi.report( "Starting Fortran solver %(name)s"%self.__dict__) self.Sigma_Old <<= self.Sigma self.G_Old <<= self.G # call the fortran solver: temp = 1.0/self.beta gf,tail,self.atocc,self.atmag = gf_hi_fullu(e0f=self.ealmat, ur=self.ur, umn=self.umn, ujmn=self.ujmn, zmsb=self.zmsb, nmom=self.Nmoments, ns=self.Nspin, temp=temp, verbosity = self.Verbosity) #self.sig = sigma_atomic_fullu(gf=self.gf,e0f=self.eal,zmsb=self.zmsb,ns=self.Nspin,nlm=self.Nlm) if (self.Verbosity==0): # No fortran output, so give basic results here mpi.report("Atomic occupancy in Hubbard I Solver : %s"%self.atocc) mpi.report("Atomic magn. mom. in Hubbard I Solver : %s"%self.atmag) # transfer the data to the GF class: if (self.UseSpinOrbit): nlmtot = self.Nlm*2 # only one block in this case! else: nlmtot = self.Nlm M={} isp=-1 for a,al in self.GFStruct: isp+=1 #M[a] = gf[isp*self.Nlm:(isp+1)*self.Nlm,isp*self.Nlm:(isp+1)*self.Nlm,:] M[a] = gf[isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot,:] for i in range(min(self.Nmoments,10)): self.tailtempl[a][i+1].array[:] = tail[i][isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot] glist = lambda : [ GfImFreq(indices = al, beta = self.beta, n_matsubara = self.Nmsb, data =M[a], tail =self.tailtempl[a]) for a,al in self.GFStruct] self.G = BlockGf(name_list = self.a_list, block_list = glist(),make_copies=False) # Self energy: self.G0 <<= gf_init.A_Omega_Plus_B(A=1,B=0.0) M = [ self.ealmat[isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot] for isp in range((2*self.Nlm)/nlmtot) ] self.G0 -= M self.Sigma <<= self.G0 - inverse(self.G) # invert G0 self.G0.invert() def test_distance(G1,G2, dist) : def f(G1,G2) : print abs(G1._data.array - G2._data.array) dS = max(abs(G1._data.array - G2._data.array).flatten()) aS = max(abs(G1._data.array).flatten()) return dS <= aS*dist return reduce(lambda x,y : x and y, [f(g1,g2) for (i1,g1),(i2,g2) in izip(G1,G2)]) mpi.report("\nChecking Sigma for convergence...\nUsing tolerance %s"%Test_Convergence) self.Converged = test_distance(self.Sigma,self.Sigma_Old,Test_Convergence) if self.Converged : mpi.report("Solver HAS CONVERGED") else : mpi.report("Solver has not yet converged")