Ejemplo n.º 1
0
    def GF_realomega(self, ommin, ommax, N_om, U_int, J_hund, T=None, verbosity=0, 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_)

        ur,umn,ujmn=self.__set_umatrix(U=U_int,J=J_hund,T=T)

        for i in range(N_om):
            omega[i] = ommin + delta_om * i + 1j * broadening

        tailtempl={}
        for sig,g in self.G:
            tailtempl[sig] = copy.deepcopy(g.tail)
            for i in range(9): tailtempl[sig][i] *= 0.0

        temp = 1.0/self.beta
        gf,tail,self.atocc,self.atmag = gf_hi_fullu(e0f=self.ealmat, ur=ur, umn=umn, ujmn=ujmn,
                                                    zmsb=omega, nmom=self.Nmoments, ns=self.Nspin, temp=temp, verbosity = verbosity)

        # 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.gf_struct:
            isp+=1
            M[a] = numpy.array(gf[isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot,:]).transpose(2,0,1).copy()
            for i in range(min(self.Nmoments,8)):
                tailtempl[a][i+1] = tail[i][isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot]

        #glist = lambda : [ GfReFreq(indices = al, window = (ommin, ommax), n_points = N_om, data = M[a], tail = self.tailtempl[a])
        #                   for a,al in self.gf_struct]       # Indices for the upfolded G
        glist = lambda : [ GfReFreq(indices = al, window = (ommin, ommax), n_points = N_om) for a,al in self.gf_struct]
        self.G = BlockGf(name_list = self.a_list, block_list = glist(),make_copies=False)

        self.__copy_Gf(self.G,M,tailtempl)

        # Self energy:
        self.G0 = self.G.copy()
        self.Sigma = self.G.copy()
        self.G0 <<= Omega + 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!!!
Ejemplo n.º 2
0
    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!!!
Ejemplo n.º 3
0
    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 : [ GFBloc_ReFreq(Indices = al, Beta = self.Beta, MeshArray = Mesh, Data=M[a], Tail=self.tailtempl[a]) 
                           for a,al in self.GFStruct]       # Indices for the upfolded G
        self.G = GF(NameList = self.a_list, BlockList = glist(),Copy=False)

        # Self energy:
        self.G0 = self.G.copy()
        self.Sigma = self.G.copy()
        self.G0 <<= GF_Initializers.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!!!
Ejemplo n.º 4
0
    def solve(self, U_int, J_hund, T=None, verbosity=0, Iteration_Number=1, Test_Convergence=0.0001):
        """Calculation of the impurity Greens function using Hubbard-I"""

        if self.Converged :
            mpi.report("Solver %(name)s has already converged: SKIPPING"%self.__dict__)
            return

        if mpi.is_master_node():
            self.verbosity = verbosity
        else:
            self.verbosity = 0

        #self.Nmoments = 5

        ur,umn,ujmn=self.__set_umatrix(U=U_int,J=J_hund,T=T)


        M = [x for x in self.G.mesh]
        self.zmsb = numpy.array([x for x in M],numpy.complex_)

        # for the tails:
        tailtempl={}
        for sig,g in self.G:
            tailtempl[sig] = copy.deepcopy(g.tail)
            for i in range(9): tailtempl[sig][i] *= 0.0

        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=ur, umn=umn, ujmn=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.gf_struct:
            isp+=1
            M[a] = numpy.array(gf[isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot,:]).transpose(2,0,1).copy()
            for i in range(min(self.Nmoments,8)):
                tailtempl[a][i+1] = tail[i][isp*nlmtot:(isp+1)*nlmtot,isp*nlmtot:(isp+1)*nlmtot]

        #glist = lambda : [ GfImFreq(indices = al, beta = self.beta, n_points = self.Nmsb, data =M[a], tail =self.tailtempl[a])
        #                   for a,al in self.gf_struct]
        glist = lambda : [ GfImFreq(indices = al, beta = self.beta, n_points = self.Nmsb) for a,al in self.gf_struct]
        self.G = BlockGf(name_list = self.a_list, block_list = glist(),make_copies=False)
        
        self.__copy_Gf(self.G,M,tailtempl)

        # Self energy:
        self.G0 <<= iOmega_n

        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 - G2.data)
                dS = max(abs(G1.data - G2.data).flatten())
                aS = max(abs(G1.data).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")
Ejemplo n.º 5
0
    def solve(self,
              U_int,
              J_hund,
              T=None,
              verbosity=0,
              Iteration_Number=1,
              Test_Convergence=0.0001):
        """Calculation of the impurity Greens function using Hubbard-I"""

        if self.Converged:
            mpi.report("Solver %(name)s has already converged: SKIPPING" %
                       self.__dict__)
            return

        self.verbosity = verbosity
        self.Nmoments = 5

        ur, umn, ujmn = self.__set_umatrix(U=U_int, J=J_hund, T=T)

        M = [x for x in self.G.mesh]
        self.zmsb = numpy.array([x for x in M], numpy.complex_)

        # for the tails:
        self.tailtempl = {}
        for sig, g in self.G:
            self.tailtempl[sig] = copy.deepcopy(g.tail)
            for i in range(9):
                self.tailtempl[sig][i] *= 0.0

        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=ur,
            umn=umn,
            ujmn=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.gf_struct:
            isp += 1
            M[a] = numpy.array(gf[isp * nlmtot:(isp + 1) * nlmtot,
                                  isp * nlmtot:(isp + 1) *
                                  nlmtot, :]).transpose(2, 0, 1).copy()
            for i in range(min(self.Nmoments, 8)):
                self.tailtempl[a][i +
                                  1] = tail[i][isp * nlmtot:(isp + 1) * nlmtot,
                                               isp * nlmtot:(isp + 1) * nlmtot]

        glist = lambda: [
            GfImFreq(indices=al,
                     beta=self.beta,
                     n_points=self.Nmsb,
                     data=M[a],
                     tail=self.tailtempl[a]) for a, al in self.gf_struct
        ]
        self.G = BlockGf(name_list=self.a_list,
                         block_list=glist(),
                         make_copies=False)

        # Self energy:
        self.G0 <<= iOmega_n

        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 - G2.data)
                dS = max(abs(G1.data - G2.data).flatten())
                aS = max(abs(G1.data).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")
Ejemplo n.º 6
0
    def GF_realomega(self,
                     ommin,
                     ommax,
                     N_om,
                     U_int,
                     J_hund,
                     T=None,
                     verbosity=0,
                     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_)

        ur, umn, ujmn = self.__set_umatrix(U=U_int, J=J_hund, T=T)

        for i in range(N_om):
            omega[i] = ommin + delta_om * i + 1j * broadening

        self.tailtempl = {}
        for sig, g in self.G:
            self.tailtempl[sig] = copy.deepcopy(g.tail)
            for i in range(9):
                self.tailtempl[sig][i] *= 0.0

        temp = 1.0 / self.beta
        gf, tail, self.atocc, self.atmag = gf_hi_fullu(e0f=self.ealmat,
                                                       ur=ur,
                                                       umn=umn,
                                                       ujmn=ujmn,
                                                       zmsb=omega,
                                                       nmom=self.Nmoments,
                                                       ns=self.Nspin,
                                                       temp=temp,
                                                       verbosity=verbosity)

        # 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.gf_struct:
            isp += 1
            M[a] = numpy.array(gf[isp * nlmtot:(isp + 1) * nlmtot,
                                  isp * nlmtot:(isp + 1) *
                                  nlmtot, :]).transpose(2, 0, 1).copy()
            for i in range(min(self.Nmoments, 8)):
                self.tailtempl[a][i +
                                  1] = tail[i][isp * nlmtot:(isp + 1) * nlmtot,
                                               isp * nlmtot:(isp + 1) * nlmtot]

        glist = lambda: [
            GfReFreq(indices=al,
                     window=(ommin, ommax),
                     n_points=N_om,
                     data=M[a],
                     tail=self.tailtempl[a]) for a, al in self.gf_struct
        ]  # 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 <<= Omega + 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!!!
Ejemplo n.º 7
0
    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")
Ejemplo n.º 8
0
    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)
       	#Solver_Base.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 : [ GFBloc_ImFreq(Indices = al, Beta = self.Beta, NFreqMatsubara = self.Nmsb, Data=M[a], Tail=self.tailtempl[a]) 
                           for a,al in self.GFStruct]
        self.G = GF(NameList = self.a_list, BlockList = glist(),Copy=False)
            
        # Self energy:
        self.G0 <<= GF_Initializers.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")