Ejemplo n.º 1
0
    def constr_Sigma_ME(self, Filename, Beta, N_om, orb=0):
        """Uses Data from files to construct a GF object on the real axis."""

        #first get the mesh out of one of the files:
        if (len(self.GFStruct_Solver[orb][0][1]) == 1):
            Fname = Filename + '_' + self.GFStruct_Solver[orb][0][0] + '.dat'
        else:
            Fname = Filename + '_' + self.GFStruct_Solver[orb][0][
                0] + '/' + str(self.GFStruct_Solver[orb][0][1][0]) + '_' + str(
                    self.GFStruct_Solver[orb][0][1][0]) + '.dat'

        R = Read_Fortran_File(Fname)
        mesh = numpy.zeros([N_om], numpy.float_)
        try:
            for i in xrange(N_om):
                mesh[i] = R.next()
                sk = R.next()
                sk = R.next()

        except StopIteration:  # a more explicit error if the file is corrupted.
            raise "SumK_LDA.read_Sigma_ME : reading file failed!"
        R.close()

        # now initialize the GF with the mesh
        a_list = [a for a, al in self.GFStruct_Solver[orb]]
        glist = lambda: [
            GFBloc_ReFreq(Indices=al, Beta=Beta, MeshArray=mesh)
            for a, al in self.GFStruct_Solver[orb]
        ]
        SigmaME = GF(NameList=a_list, BlockList=glist(), Copy=False)
        SigmaME.load(Filename)
        SigmaME.Note = 'ReFreq'  # This is important for the put_Sigma routine!!!

        return SigmaME
Ejemplo n.º 2
0
    def __init__(self,Beta,GFstruct,**param):
        self.Beta = float(Beta)
        Parameters.check_no_parameters_not_in_union_of_dicts (param,self.Required, self.Optional)
        #DataTestTools.EnsureAllParametersMakeSense(self,param)
        if 'Nmsb' not in param : param['Nmsb'] = 1025
        if 'Nspin' not in param : param['Nspin'] = 2

        Solver_Base.__init__(self,GFstruct,param)

        # construct Greens functions:
        self.a_list = [a for a,al in self.GFStruct]
        glist = lambda : [ GFBloc_ImFreq(Indices = al, Beta = self.Beta, NFreqMatsubara = self.Nmsb) for a,al in self.GFStruct]
        self.G = GF(NameList = self.a_list, BlockList = glist(),Copy=False)
        self.G_Old = self.G.copy()
        self.G0 = self.G.copy()
        self.Sigma = self.G.copy()
        self.Sigma_Old = self.G.copy()
        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(11): self.tailtempl[sig][i].array[:] *= 0.0
    
        self.Name=''

        # effective atomic levels:
        if self.UseSpinOrbit: self.NSpin=2

        self.ealmat = numpy.zeros([self.Nlm*self.Nspin,self.Nlm*self.Nspin],numpy.complex_)
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 partial_charges(self):
        """Calculates the orbitally-resolved density matrix for all the orbitals considered in the input.
           The theta-projectors are used, hence case.parproj data is necessary"""

        #thingstoread = ['Dens_Mat_below','N_parproj','Proj_Mat_pc','rotmat_all']
        #retval = self.read_input_from_HDF(SubGrp=self.ParProjdata,thingstoread=thingstoread)
        retval = self.read_ParProj_input_from_HDF()
        if not retval: return retval
        if self.symm_op:
            self.Symm_par = Symmetry(self.HDFfile, subgroup=self.Symmpardata)

        # Density matrix in the window
        bln = self.blocnames[self.SO]
        ntoi = self.names_to_ind[self.SO]
        self.Dens_Mat_window = [[
            numpy.zeros([self.shells[ish][3], self.shells[ish][3]],
                        numpy.complex_) for ish in range(self.N_shells)
        ] for isp in range(len(bln))]  # init the density matrix

        mu = self.Chemical_Potential
        GFStruct_proj = [[(al, range(self.shells[i][3])) for al in bln]
                         for i in xrange(self.N_shells)]
        if hasattr(self, "Sigmaimp"):
            Gproj = [
                GF(Name_Block_Generator=[
                    (a, GFBloc_ImFreq(Indices=al, Mesh=self.Sigmaimp[0].mesh))
                    for a, al in GFStruct_proj[ish]
                ],
                   Copy=False) for ish in xrange(self.N_shells)
            ]
        else:
            Gproj = [
                GF(Name_Block_Generator=[(a, GFBloc_ImFreq(Indices=al,
                                                           Beta=40))
                                         for a, al in GFStruct_proj[ish]],
                   Copy=False) for ish in xrange(self.N_shells)
            ]

        for ish in xrange(self.N_shells):
            Gproj[ish].zero()

        ikarray = numpy.array(range(self.Nk))
        #print MPI.rank, MPI.slice_array(ikarray)
        #print "K-Sum starts on node",MPI.rank," at ",datetime.now()

        for ik in MPI.slice_array(ikarray):
            #print MPI.rank, ik, datetime.now()
            S = self.latticeGF_Matsubara(ik=ik, mu=mu)
            S *= self.BZ_weights[ik]

            for ish in xrange(self.N_shells):
                tmp = Gproj[ish].copy()
                for ir in xrange(self.N_parproj[ish]):
                    for sig, gf in tmp:
                        tmp[sig] <<= self.downfold_pc(ik, ir, ish, sig, S[sig],
                                                      gf)
                    Gproj[ish] += tmp

        #print "K-Sum done on node",MPI.rank," at ",datetime.now()
        #collect data from MPI:
        for ish in xrange(self.N_shells):
            Gproj[ish] <<= MPI.all_reduce(MPI.world, Gproj[ish],
                                          lambda x, y: x + y)
        MPI.barrier()

        #print "Data collected on node",MPI.rank," at ",datetime.now()

        # Symmetrisation:
        if (self.symm_op != 0): Gproj = self.Symm_par.symmetrise(Gproj)
        #print "Symmetrisation done on node",MPI.rank," at ",datetime.now()

        for ish in xrange(self.N_shells):

            # Rotation to local:
            if (self.use_rotations):
                for sig, gf in Gproj[ish]:
                    Gproj[ish][sig] <<= self.rotloc_all(ish,
                                                        gf,
                                                        direction='toLocal')

            isp = 0
            for sig, gf in Gproj[ish]:  #dmg.append(Gproj[ish].density()[sig])
                self.Dens_Mat_window[isp][ish] = Gproj[ish].density()[sig]
                isp += 1

        # add Density matrices to get the total:
        Dens_Mat = [[
            self.Dens_Mat_below[ntoi[bln[isp]]][ish] +
            self.Dens_Mat_window[isp][ish] for ish in range(self.N_shells)
        ] for isp in range(len(bln))]

        return Dens_Mat
Ejemplo n.º 5
0
    def spaghettis(self,
                   broadening,
                   shift=0.0,
                   plotrange=None,
                   ishell=None,
                   invertAkw=False,
                   Fermisurface=False):
        """ Calculates the correlated band structure with a real-frequency self energy. 
            ATTENTION: Many things from the original input file are are overwritten!!!"""

        assert hasattr(self, "Sigmaimp"), "Set Sigma First!!"
        thingstoread = [
            'Nk', 'N_Orbitals', 'Proj_Mat', 'Hopping', 'N_parproj',
            'Proj_Mat_pc'
        ]
        retval = self.read_input_from_HDF(SubGrp=self.Bandsdata,
                                          thingstoread=thingstoread)
        if not retval: return retval

        if Fermisurface: ishell = None

        # print hamiltonian for checks:
        if ((self.SP == 1) and (self.SO == 0)):
            f1 = open('hamup.dat', 'w')
            f2 = open('hamdn.dat', 'w')

            for ik in xrange(self.Nk):
                for i in xrange(self.N_Orbitals[ik][0]):
                    f1.write('%s    %s\n' %
                             (ik, self.Hopping[ik][0][i, i].real))
                for i in xrange(self.N_Orbitals[ik][1]):
                    f2.write('%s    %s\n' %
                             (ik, self.Hopping[ik][1][i, i].real))
                f1.write('\n')
                f2.write('\n')
            f1.close()
            f2.close()
        else:
            f = open('ham.dat', 'w')
            for ik in xrange(self.Nk):
                for i in xrange(self.N_Orbitals[ik][0]):
                    f.write('%s    %s\n' %
                            (ik, self.Hopping[ik][0][i, i].real))
                f.write('\n')
            f.close()

        #=========================================
        # calculate A(k,w):

        mu = self.Chemical_Potential
        bln = self.blocnames[self.SO]

        # init DOS:
        M = [x for x in self.Sigmaimp[0].mesh]
        N_om = len(M)

        if plotrange is None:
            omminplot = M[0] - 0.001
            ommaxplot = M[N_om - 1] + 0.001
        else:
            omminplot = plotrange[0]
            ommaxplot = plotrange[1]

        if (ishell is None):
            Akw = {}
            for ibn in bln:
                Akw[ibn] = numpy.zeros([self.Nk, N_om], numpy.float_)
        else:
            Akw = {}
            for ibn in bln:
                Akw[ibn] = numpy.zeros([self.shells[ishell][3], self.Nk, N_om],
                                       numpy.float_)

        if Fermisurface:
            omminplot = -2.0 * broadening
            ommaxplot = 2.0 * broadening
            Akw = {}
            for ibn in bln:
                Akw[ibn] = numpy.zeros([self.Nk, 1], numpy.float_)

        if not (ishell is None):
            GFStruct_proj = [(al, range(self.shells[ishell][3])) for al in bln]
            Gproj = GF(Name_Block_Generator=[
                (a, GFBloc_ReFreq(Indices=al, Mesh=self.Sigmaimp[0].mesh))
                for a, al in GFStruct_proj
            ],
                       Copy=False)
            Gproj.zero()

        for ik in xrange(self.Nk):

            S = self.latticeGF_realfreq(ik=ik, mu=mu, broadening=broadening)
            if (ishell is None):
                # non-projected A(k,w)
                for iom in range(N_om):
                    if (M[iom] > omminplot) and (M[iom] < ommaxplot):
                        if Fermisurface:
                            for sig, gf in S:
                                Akw[sig][
                                    ik,
                                    0] += gf._data.array[:, :, iom].imag.trace(
                                    ) / (-3.1415926535) * (M[1] - M[0])
                        else:
                            for sig, gf in S:
                                Akw[sig][
                                    ik,
                                    iom] += gf._data.array[:, :,
                                                           iom].imag.trace(
                                                           ) / (-3.1415926535)
                            Akw[sig][
                                ik,
                                iom] += ik * shift  # shift Akw for plotting in xmgrace

            else:
                # projected A(k,w):
                Gproj.zero()
                tmp = Gproj.copy()
                for ir in xrange(self.N_parproj[ishell]):
                    for sig, gf in tmp:
                        tmp[sig] <<= self.downfold_pc(ik, ir, ishell, sig,
                                                      S[sig], gf)
                    Gproj += tmp

                # TO BE FIXED:
                # rotate to local frame
                #if (self.use_rotations):
                #    for sig,gf in Gproj: Gproj[sig] <<= self.rotloc(0,gf,direction='toLocal')

                for iom in range(N_om):
                    if (M[iom] > omminplot) and (M[iom] < ommaxplot):
                        for ish in range(self.shells[ishell][3]):
                            for ibn in bln:
                                Akw[ibn][ish, ik,
                                         iom] = Gproj[ibn]._data.array[
                                             ish, ish,
                                             iom].imag / (-3.1415926535)

        # END k-LOOP
        if (MPI.IS_MASTER_NODE()):
            if (ishell is None):

                for ibn in bln:
                    # loop over GF blocs:

                    if (invertAkw):
                        maxAkw = Akw[ibn].max()
                        minAkw = Akw[ibn].min()

                    # open file for storage:
                    if Fermisurface:
                        f = open('FS_' + ibn + '.dat', 'w')
                    else:
                        f = open('Akw_' + ibn + '.dat', 'w')

                    for ik in range(self.Nk):
                        if Fermisurface:
                            if (invertAkw):
                                Akw[ibn][ik, 0] = 1.0 / (minAkw - maxAkw) * (
                                    Akw[ibn][ik, iom] - maxAkw)
                            f.write('%s    %s\n' % (ik, Akw[ibn][ik, 0]))
                        else:
                            for iom in range(N_om):
                                if (M[iom] > omminplot) and (M[iom] <
                                                             ommaxplot):
                                    if (invertAkw):
                                        Akw[ibn][
                                            ik,
                                            iom] = 1.0 / (minAkw - maxAkw) * (
                                                Akw[ibn][ik, iom] - maxAkw)
                                    if (shift > 0.0001):
                                        f.write('%s      %s\n' %
                                                (M[iom], Akw[ibn][ik, iom]))
                                    else:
                                        f.write(
                                            '%s     %s      %s\n' %
                                            (ik, M[iom], Akw[ibn][ik, iom]))

                            f.write('\n')

                    f.close()

            else:
                for ibn in bln:
                    for ish in range(self.shells[ishell][3]):

                        if (invertAkw):
                            maxAkw = Akw[ibn][ish, :, :].max()
                            minAkw = Akw[ibn][ish, :, :].min()

                        f = open('Akw_' + ibn + '_proj' + str(ish) + '.dat',
                                 'w')

                        for ik in range(self.Nk):
                            for iom in range(N_om):
                                if (M[iom] > omminplot) and (M[iom] <
                                                             ommaxplot):
                                    if (invertAkw):
                                        Akw[ibn][ish, ik, iom] = 1.0 / (
                                            minAkw - maxAkw
                                        ) * (Akw[ibn][ish, ik, iom] - maxAkw)
                                    if (shift > 0.0001):
                                        f.write(
                                            '%s      %s\n' %
                                            (M[iom], Akw[ibn][ish, ik, iom]))
                                    else:
                                        f.write('%s     %s      %s\n' %
                                                (ik, M[iom], Akw[ibn][ish, ik,
                                                                      iom]))

                            f.write('\n')

                        f.close()
Ejemplo n.º 6
0
    def DOSpartial(self, broadening=0.01):
        """calculates the orbitally-resolved DOS"""

        assert hasattr(self, "Sigmaimp"), "Set Sigma First!!"

        #thingstoread = ['Dens_Mat_below','N_parproj','Proj_Mat_pc','rotmat_all']
        #retval = self.read_input_from_HDF(SubGrp=self.ParProjdata, thingstoread=thingstoread)
        retval = self.read_ParProj_input_from_HDF()
        if not retval: return retval
        if self.symm_op:
            self.Symm_par = Symmetry(self.HDFfile, subgroup=self.Symmpardata)

        mu = self.Chemical_Potential

        GFStruct_proj = [[(al, range(self.shells[i][3]))
                          for al in self.blocnames[self.SO]]
                         for i in xrange(self.N_shells)]
        Gproj = [
            GF(Name_Block_Generator=[
                (a, GFBloc_ReFreq(Indices=al, Mesh=self.Sigmaimp[0].mesh))
                for a, al in GFStruct_proj[ish]
            ],
               Copy=False) for ish in xrange(self.N_shells)
        ]
        for ish in range(self.N_shells):
            Gproj[ish].zero()

        Msh = [x for x in self.Sigmaimp[0].mesh]
        N_om = len(Msh)

        DOS = {}
        for bn in self.blocnames[self.SO]:
            DOS[bn] = numpy.zeros([N_om], numpy.float_)

        DOSproj = [{} for ish in range(self.N_shells)]
        DOSproj_orb = [{} for ish in range(self.N_shells)]
        for ish in range(self.N_shells):
            for bn in self.blocnames[self.SO]:
                dl = self.shells[ish][3]
                DOSproj[ish][bn] = numpy.zeros([N_om], numpy.float_)
                DOSproj_orb[ish][bn] = numpy.zeros([dl, dl, N_om],
                                                   numpy.float_)

        ikarray = numpy.array(range(self.Nk))

        for ik in MPI.slice_array(ikarray):

            S = self.latticeGF_realfreq(ik=ik, mu=mu, broadening=broadening)
            S *= self.BZ_weights[ik]

            # non-projected DOS
            for iom in range(N_om):
                for sig, gf in S:
                    DOS[sig][iom] += gf._data.array[:, :, iom].imag.trace() / (
                        -3.1415926535)

            #projected DOS:
            for ish in xrange(self.N_shells):
                tmp = Gproj[ish].copy()
                for ir in xrange(self.N_parproj[ish]):
                    for sig, gf in tmp:
                        tmp[sig] <<= self.downfold_pc(ik, ir, ish, sig, S[sig],
                                                      gf)
                    Gproj[ish] += tmp

        # collect data from MPI:
        for sig in DOS:
            DOS[sig] = MPI.all_reduce(MPI.world, DOS[sig], lambda x, y: x + y)
        for ish in xrange(self.N_shells):
            Gproj[ish] <<= MPI.all_reduce(MPI.world, Gproj[ish],
                                          lambda x, y: x + y)
        MPI.barrier()

        if (self.symm_op != 0): Gproj = self.Symm_par.symmetrise(Gproj)

        # rotation to local coord. system:
        if (self.use_rotations):
            for ish in xrange(self.N_shells):
                for sig, gf in Gproj[ish]:
                    Gproj[ish][sig] <<= self.rotloc_all(ish,
                                                        gf,
                                                        direction='toLocal')

        for ish in range(self.N_shells):
            for sig, gf in Gproj[ish]:
                for iom in range(N_om):
                    DOSproj[ish][sig][
                        iom] += gf._data.array[:, :, iom].imag.trace() / (
                            -3.1415926535)
                DOSproj_orb[ish][
                    sig][:, :, :] += gf._data.array[:, :, :].imag / (
                        -3.1415926535)

        if (MPI.IS_MASTER_NODE()):
            # output to files
            for bn in self.blocnames[self.SO]:
                f = open('./DOScorr%s.dat' % bn, 'w')
                for i in range(N_om):
                    f.write("%s    %s\n" % (Msh[i], DOS[bn][i]))
                f.close()

                # partial
                for ish in range(self.N_shells):
                    f = open('DOScorr%s_proj%s.dat' % (bn, ish), 'w')
                    for i in range(N_om):
                        f.write("%s    %s\n" % (Msh[i], DOSproj[ish][bn][i]))
                    f.close()

                    for i in range(self.shells[ish][3]):
                        for j in range(i, self.shells[ish][3]):
                            Fname = './DOScorr' + bn + '_proj' + str(
                                ish) + '_' + str(i) + '_' + str(j) + '.dat'
                            f = open(Fname, 'w')
                            for iom in range(N_om):
                                f.write("%s    %s\n" %
                                        (Msh[iom], DOSproj_orb[ish][bn][i, j,
                                                                        iom]))
                            f.close()
Ejemplo n.º 7
0
    def check_inputDOS(self, ommin, ommax, N_om, Beta=10, broadening=0.01):

        delta_om = (ommax - ommin) / (N_om - 1)
        Mesh = numpy.zeros([N_om], numpy.float_)

        DOS = {}
        for bn in self.blocnames[self.SO]:
            DOS[bn] = numpy.zeros([N_om], numpy.float_)

        DOSproj = [{} for icrsh in range(self.N_inequiv_corr_shells)]
        DOSproj_orb = [{} for icrsh in range(self.N_inequiv_corr_shells)]
        for icrsh in range(self.N_inequiv_corr_shells):
            for bn in self.blocnames[self.corr_shells[self.invshellmap[icrsh]]
                                     [4]]:
                dl = self.corr_shells[self.invshellmap[icrsh]][3]
                DOSproj[icrsh][bn] = numpy.zeros([N_om], numpy.float_)
                DOSproj_orb[icrsh][bn] = numpy.zeros([dl, dl, N_om],
                                                     numpy.float_)

        for i in range(N_om):
            Mesh[i] = ommin + delta_om * i

        # init:
        Gloc = []
        for icrsh in range(self.N_corr_shells):
            b_list = [a for a, al in self.GFStruct_corr[icrsh]]
            glist = lambda: [
                GFBloc_ReFreq(Indices=al, Beta=Beta, MeshArray=Mesh)
                for a, al in self.GFStruct_corr[icrsh]
            ]
            Gloc.append(GF(NameList=b_list, BlockList=glist(), Copy=False))
        for icrsh in xrange(self.N_corr_shells):
            Gloc[icrsh].zero()  # initialize to zero

        for ik in xrange(self.Nk):

            Gupf = self.latticeGF_realfreq(ik=ik,
                                           mu=self.Chemical_Potential,
                                           broadening=broadening,
                                           Beta=Beta,
                                           Mesh=Mesh,
                                           withSigma=False)
            Gupf *= self.BZ_weights[ik]

            # non-projected DOS
            for iom in range(N_om):
                for sig, gf in Gupf:
                    asd = gf._data.array[:, :,
                                         iom].imag.trace() / (-3.1415926535)
                    DOS[sig][iom] += asd

            for icrsh in xrange(self.N_corr_shells):
                tmp = Gloc[icrsh].copy()
                for sig, gf in tmp:
                    tmp[sig] <<= self.downfold(ik, icrsh, sig, Gupf[sig],
                                               gf)  # downfolding G
                Gloc[icrsh] += tmp

        if (self.symm_op != 0): Gloc = self.Symm_corr.symmetrise(Gloc)

        if (self.use_rotations):
            for icrsh in xrange(self.N_corr_shells):
                for sig, gf in Gloc[icrsh]:
                    Gloc[icrsh][sig] <<= self.rotloc(icrsh,
                                                     gf,
                                                     direction='toLocal')

        # Gloc can now also be used to look at orbitally resolved quantities
        for ish in range(self.N_inequiv_corr_shells):
            for sig, gf in Gloc[self.invshellmap[ish]]:  # loop over spins
                for iom in range(N_om):
                    DOSproj[ish][sig][
                        iom] += gf._data.array[:, :, iom].imag.trace() / (
                            -3.1415926535)

                DOSproj_orb[ish][
                    sig][:, :, :] += gf._data.array[:, :, :].imag / (
                        -3.1415926535)

        # output:
        if (MPI.IS_MASTER_NODE()):
            for bn in self.blocnames[self.SO]:
                f = open('DOS%s.dat' % bn, 'w')
                for i in range(N_om):
                    f.write("%s    %s\n" % (Mesh[i], DOS[bn][i]))
                f.close()

                for ish in range(self.N_inequiv_corr_shells):
                    f = open('DOS%s_proj%s.dat' % (bn, ish), 'w')
                    for i in range(N_om):
                        f.write("%s    %s\n" % (Mesh[i], DOSproj[ish][bn][i]))
                    f.close()

                    for i in range(self.corr_shells[self.invshellmap[ish]][3]):
                        for j in range(
                                i, self.corr_shells[self.invshellmap[ish]][3]):
                            Fname = 'DOS' + bn + '_proj' + str(
                                ish) + '_' + str(i) + '_' + str(j) + '.dat'
                            f = open(Fname, 'w')
                            for iom in range(N_om):
                                f.write("%s    %s\n" %
                                        (Mesh[iom], DOSproj_orb[ish][bn][i, j,
                                                                         iom]))
                            f.close()
Ejemplo n.º 8
0
    def latticeGF_realfreq(self,
                           ik,
                           mu,
                           broadening,
                           Mesh=None,
                           Beta=40,
                           withSigma=True):
        """Calculates the lattice Green function on the real frequency axis. If self energy is
           present and withSigma=True, the mesh is taken from Sigma. Otherwise, the mesh has to be given."""

        ntoi = self.names_to_ind[self.SO]
        bln = self.blocnames[self.SO]

        if (not hasattr(self, "Sigmaimp")): withSigma = False
        if (withSigma):
            assert self.Sigmaimp[
                0].Note == 'ReFreq', "Real frequency Sigma needed for latticeGF_realfreq!"
            Beta = self.Sigmaimp[0].Beta
            stmp = self.add_DC()
        else:
            assert (not (Mesh is None)
                    ), "Without Sigma, give the mesh for latticeGF_realfreq!"

        if (self.Gupf_refreq is None):
            # first setting up of Gupf_refreq
            BS = [range(self.N_Orbitals[ik][ntoi[ib]]) for ib in bln]
            GFStruct = [(bln[ib], BS[ib])
                        for ib in range(self.NspinblocsGF[self.SO])]
            a_list = [a for a, al in GFStruct]
            if (withSigma):
                glist = lambda: [
                    GFBloc_ReFreq(Indices=al, Mesh=self.Sigmaimp[0].mesh)
                    for a, al in GFStruct
                ]
            else:
                glist = lambda: [
                    GFBloc_ReFreq(Indices=al, Beta=Beta, MeshArray=Mesh)
                    for a, al in GFStruct
                ]
            self.Gupf_refreq = GF(NameList=a_list,
                                  BlockList=glist(),
                                  Copy=False)
            self.Gupf_refreq.zero()

        GFsize = [gf.N1 for sig, gf in self.Gupf_refreq]
        unchangedsize = all([
            self.N_Orbitals[ik][ntoi[bln[ib]]] == GFsize[ib]
            for ib in range(self.NspinblocsGF[self.SO])
        ])

        if (not unchangedsize):
            BS = [range(self.N_Orbitals[ik][ntoi[ib]]) for ib in bln]
            GFStruct = [(bln[ib], BS[ib])
                        for ib in range(self.NspinblocsGF[self.SO])]
            a_list = [a for a, al in GFStruct]
            if (withSigma):
                glist = lambda: [
                    GFBloc_ReFreq(Indices=al, Mesh=self.Sigmaimp[0].mesh)
                    for a, al in GFStruct
                ]
            else:
                glist = lambda: [
                    GFBloc_ReFreq(Indices=al, Beta=Beta, MeshArray=Mesh)
                    for a, al in GFStruct
                ]
            self.Gupf_refreq = GF(NameList=a_list,
                                  BlockList=glist(),
                                  Copy=False)
            self.Gupf_refreq.zero()

        idmat = [
            numpy.identity(self.N_Orbitals[ik][ntoi[bl]], numpy.complex_)
            for bl in bln
        ]

        self.Gupf_refreq <<= GF_Initializers.A_Omega_Plus_B(A=1,
                                                            B=1j * broadening)
        M = copy.deepcopy(idmat)
        for ibl in range(self.NspinblocsGF[self.SO]):
            ind = ntoi[bln[ibl]]
            M[ibl] = self.Hopping[ik][ind] - (idmat[ibl] *
                                              mu) - (idmat[ibl] * self.hfield *
                                                     (1 - 2 * ibl))
        self.Gupf_refreq -= M

        if (withSigma):
            tmp = self.Gupf_refreq.copy()  # init temporary storage
            for icrsh in xrange(self.N_corr_shells):
                for sig, gf in tmp:
                    tmp[sig] <<= self.upfold(ik, icrsh, sig, stmp[icrsh][sig],
                                             gf)
                self.Gupf_refreq -= tmp  # adding to the upfolded GF

        self.Gupf_refreq.invert()

        return self.Gupf_refreq
Ejemplo n.º 9
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")