Beispiel #1
0
    def update_params(self, d):

      allparams = [
        ('QMC_N_cycles_MAX', 'N_Cycles'),
        ('NCycles', 'N_Cycles'),
        ('Hloc', 'H_Local'),
        ('QuantumNumbers', 'Quantum_Numbers'),
        ('Length_One_QMC_Cycle', 'Length_Cycle'),
        ('Number_Warming_Iteration', 'N_Warmup_Cycles'),
        ('Number_Frequencies_Accumulated', 'N_Frequencies_Accumulated'),
        ('Global_Move', 'Global_Moves'),
        ('UseSegmentPicture', 'Use_Segment_Picture'),
        ('Proba_Move_Insert_Remove_Kink', 'Proba_Insert_Remove'),
        ('Proba_Move_Move_Kink', 'Proba_Move'),
        ('OperatorsToAverage', 'Measured_Operators'),
        ('OpCorrToAverage', 'Measured_Time_Correlators'),
        ('KeepGF_MC_series', 'Keep_Full_MC_Series'),
        ('DecorrelationAnalysisG_NFreq', 'Decorrelation_Analysis_G_NFreq'),
        ('RecordStatisticConfigurations', 'Record_Statistics_Configurations')
      ]

      issue_warning = False
      for (old, new) in allparams:
        if old in d:
          val = d.pop(old)
          d.update({new:val})
          issue_warning = True

      msg = """
**********************************************************************************
 Warning: some parameters you used have a different name now and will be
 deprecated in future versions. Please check the documentation.
**********************************************************************************
"""
      if issue_warning: MPI.report(msg)
Beispiel #2
0
    def update_params(self, d):

      allparams = [
        ('QMC_N_cycles_MAX', 'N_Cycles'),
        ('NCycles', 'N_Cycles'),
        ('Hloc', 'H_Local'),
        ('QuantumNumbers', 'Quantum_Numbers'),
        ('Length_One_QMC_Cycle', 'Length_Cycle'),
        ('Number_Warming_Iteration', 'N_Warmup_Cycles'),
        ('Number_Frequencies_Accumulated', 'N_Frequencies_Accumulated'),
        ('Global_Move', 'Global_Moves'),
        ('UseSegmentPicture', 'Use_Segment_Picture'),
        ('Proba_Move_Insert_Remove_Kink', 'Proba_Insert_Remove'),
        ('Proba_Move_Move_Kink', 'Proba_Move'),
        ('OperatorsToAverage', 'Measured_Operators'),
        ('OpCorrToAverage', 'Measured_Time_Correlators'),
        ('KeepGF_MC_series', 'Keep_Full_MC_Series'),
        ('DecorrelationAnalysisG_NFreq', 'Decorrelation_Analysis_G_NFreq'),
        ('RecordStatisticConfigurations', 'Record_Statistics_Configurations')
      ]

      issue_warning = False
      for (old, new) in allparams:
        if old in d:
          val = d.pop(old)
          d.update({new:val})
          issue_warning = True

      msg = """
**********************************************************************************
 Warning: some parameters you used have a different name now and will be
 deprecated in future versions. Please check the documentation.
**********************************************************************************
"""
      if issue_warning: MPI.report(msg)
Beispiel #3
0
    def fitTails(self):
        """Fits the tails using the constant value for the Re Sigma calculated from F=Sigma*G.
           Works only for blocks of size one."""

        #if (len(self.GFStruct)==2*self.Norb):
        if (self.blocssizeone):
            spinblocs = [v for v in self.map]
            MPI.report("Fitting tails manually")

            known_coeff = numpy.zeros([1, 1, 2], numpy.float_)
            msh = [x.imag for x in self.G[self.map[spinblocs[0]][0]].mesh]
            fit_start = msh[self.Fitting_Frequency_Start]
            fit_stop = msh[self.N_Frequencies_Accumulated]

            # Fit the tail of G just to get the density
            for n, g in self.G:
                g.fitTail([[[0, 0, 1]]], 7, fit_start, 2 * fit_stop)
            densmat = self.G.density()

            for sig1 in spinblocs:
                for i in range(self.Norb):

                    coeff = 0.0

                    for sig2 in spinblocs:
                        for j in range(self.Norb):
                            if (sig1 == sig2):
                                coeff += self.U[self.offset + i, self.offset +
                                                j] * densmat[self.map[sig1]
                                                             [j]][0, 0].real
                            else:
                                coeff += self.Up[self.offset + i, self.offset +
                                                 j] * densmat[self.map[sig2]
                                                              [j]][0, 0].real

                    known_coeff[0, 0, 1] = coeff
                    self.Sigma[self.map[sig1][i]].fitTail(
                        fixed_coef=known_coeff,
                        order_max=3,
                        fit_start=fit_start,
                        fit_stop=fit_stop)

        else:

            for n, sig in self.Sigma:

                known_coeff = numpy.zeros([sig.N1, sig.N2, 1], numpy.float_)
                msh = [x.imag for x in sig.mesh]
                fit_start = msh[self.Fitting_Frequency_Start]
                fit_stop = msh[self.N_Frequencies_Accumulated]

                sig.fitTail(fixed_coef=known_coeff,
                            order_max=3,
                            fit_start=fit_start,
                            fit_stop=fit_stop)
    def __repack(self):
        """Calls the h5repack routine, in order to reduce the file size of the hdf5 archive.
           Should only be used BEFORE the first invokation of HDF_Archive in the program, otherwise
           the hdf5 linking is broken!!!"""

        import subprocess

        if not (MPI.IS_MASTER_NODE()): return

        MPI.report("Repacking the file %s"%self.HDFfile)

        retcode = subprocess.call(["h5repack","-i%s"%self.HDFfile, "-otemphgfrt.h5"])
        if (retcode!=0):
            MPI.report("h5repack failed!")
        else:
            subprocess.call(["mv","-f","temphgfrt.h5","%s"%self.HDFfile])
Beispiel #5
0
    def read_input_from_HDF(self, SubGrp, thingstoread, optionalthings=[]):
        """
        Reads data from the HDF file
        """

        retval = True
        # init variables on all nodes:
        for it in thingstoread:
            exec "self.%s = 0" % it
        for it in optionalthings:
            exec "self.%s = 0" % it

        if MPI.IS_MASTER_NODE():
            ar = HDF_Archive(self.HDFfile, "a")
            if SubGrp in ar:
                # first read the necessary things:
                for it in thingstoread:
                    if it in ar[SubGrp]:
                        exec "self.%s = ar['%s']['%s']" % (it, SubGrp, it)
                    else:
                        MPI.report("Loading %s failed!" % it)
                        retval = False

                if (retval) and (len(optionalthings) > 0):
                    # if necessary things worked, now read optional things:
                    retval = {}
                    for it in optionalthings:
                        if it in ar[SubGrp]:
                            exec "self.%s = ar['%s']['%s']" % (it, SubGrp, it)
                            retval["%s" % it] = True
                        else:
                            retval["%s" % it] = False
            else:
                MPI.report("Loading failed: No %s subgroup in HDF5!" % SubGrp)
                retval = False

            del ar

        # now do the broadcasting:
        for it in thingstoread:
            exec "self.%s = MPI.bcast(self.%s)" % (it, it)
        for it in optionalthings:
            exec "self.%s = MPI.bcast(self.%s)" % (it, it)

        retval = MPI.bcast(retval)

        return retval
Beispiel #6
0
    def __repack(self):
        """Calls the h5repack routine, in order to reduce the file size of the hdf5 archive.
           Should only be used BEFORE the first invokation of HDF_Archive in the program, otherwise
           the hdf5 linking is broken!!!"""

        import subprocess

        if not (MPI.IS_MASTER_NODE()): return

        MPI.report("Repacking the file %s" % self.HDFfile)

        retcode = subprocess.call(
            ["h5repack", "-i%s" % self.HDFfile, "-otemphgfrt.h5"])
        if (retcode != 0):
            MPI.report("h5repack failed!")
        else:
            subprocess.call(["mv", "-f", "temphgfrt.h5", "%s" % self.HDFfile])
   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 ,Res = G).total_density()/4 
      
      if Density_Required :
         self.Chemical_potential = Dichotomy.Dichotomy(Function = F,
                                                       xinit = self.Chemical_potential, yvalue =Density_Required,
                                                       Precision_on_y = 0.01, Delta_x=0.5,  MaxNbreLoop = 100, 
                                                       xname="Chemical_Potential", yname= "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 
Beispiel #8
0
  def run(self,N_Loops, Mixing_Coefficient = 0.5, MaxTime = 0 ):
    r"""
      Run the DMFT Loop with the following algorithm :: 
       
        while STOP_CONDITION : 
            self.Self_Consistency()
            for solver in Solver_List : S.solve()
            self.PostSolver() # defaults : does nothing

      where STOP_CONDITION is determined by the number of iterations.
        
      :param N_Loops:    Maximum number of iteration of the loop
      :param Mixing_Coefficient: 
      :param MaxTime: Maximum time of the loop.
    """

    # Set up the signal
    #   MPI.report("DMFTlab Job PID = %s"%os.getpid())
    # Set the signal handler and a 5-second alarm
    signal.signal(signal.SIGALRM, self.handler)
    signal.alarm(MaxTime)
 
    should_continue = True
    
    while (should_continue):
      MPI.report("------ Node : %d -------- Iteration Number = %d"%(MPI.rank,self.Iteration_Number))
      
      self.Self_Consistency()

      # call all solvers
      for n,sol in enumerate(self.SolverList) :
        if hasattr(self,"Chemical_potential") : sol.Chemical_potential=self.Chemical_potential
        sol.Iteration_Number=self.Iteration_Number
        sol.Solve()
        sol.Sigma  = sol.Sigma * Mixing_Coefficient + sol.Sigma_Old * (1-Mixing_Coefficient)
      
      # post-solver processing
      self.PostSolver()
                         
      self.Iteration_Number +=1
      should_continue = self.__should_continue(N_Loops)
 
    # end of the while loop
    MPI.report("----------- END of DMFT_Loop ----------------")
    MPI.barrier()
    def fitTails(self): 
	"""Fits the tails using the constant value for the Re Sigma calculated from F=Sigma*G.
           Works only for blocks of size one."""
	
	#if (len(self.GFStruct)==2*self.Norb):
        if (self.blocssizeone):
            spinblocs = [v for v in self.map]
            MPI.report("Fitting tails manually")
	
            known_coeff = numpy.zeros([1,1,2],numpy.float_)
            msh = [x.imag for x in self.G[self.map[spinblocs[0]][0]].mesh ]
            fit_start = msh[self.Fitting_Frequency_Start]
            fit_stop = msh[self.N_Frequencies_Accumulated]	
            
            # Fit the tail of G just to get the density
            for n,g in self.G:
                g.fitTail([[[0,0,1]]],7,fit_start,2*fit_stop) 
            densmat = self.G.density()

            for sig1 in spinblocs:
                for i in range(self.Norb):

                    coeff = 0.0

                    for sig2 in spinblocs:
                        for j in range(self.Norb):
                            if (sig1==sig2):
                                coeff += self.U[self.offset+i,self.offset+j] * densmat[self.map[sig1][j]][0,0].real
                            else:
                                coeff += self.Up[self.offset+i,self.offset+j] * densmat[self.map[sig2][j]][0,0].real

                    known_coeff[0,0,1] = coeff
                    self.Sigma[self.map[sig1][i]].fitTail(fixed_coef = known_coeff, order_max = 3, fit_start = fit_start, fit_stop = fit_stop)

        else:

            for n,sig in self.Sigma:

                known_coeff = numpy.zeros([sig.N1,sig.N2,1],numpy.float_)
                msh = [x.imag for x in sig.mesh]
                fit_start = msh[self.Fitting_Frequency_Start]
                fit_stop  = msh[self.N_Frequencies_Accumulated]
            
                sig.fitTail(fixed_coef = known_coeff, order_max = 3, fit_start = fit_start, fit_stop = fit_stop)
Beispiel #10
0
    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, Res=G).total_density(
        ) / 4

        if Density_Required:
            self.Chemical_potential = Dichotomy.Dichotomy(
                Function=F,
                xinit=self.Chemical_potential,
                yvalue=Density_Required,
                Precision_on_y=0.01,
                Delta_x=0.5,
                MaxNbreLoop=100,
                xname="Chemical_Potential",
                yname="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
Beispiel #11
0
    def __init__(self, HDFfile, mu = 0.0, hfield = 0.0, UseLDABlocs = False, LDAdata = 'SumK_LDA', Symmcorrdata = 'SymmCorr',
                 ParProjdata = 'SumK_LDA_ParProj', Symmpardata = 'SymmPar', Bandsdata = 'SumK_LDA_Bands'):
        """
        Initialises the class from data previously stored into an HDF5
        """

        if  not (type(HDFfile)==StringType):
            MPI.report("Give a string for the HDF5 filename to read the input!")
        else:
            self.HDFfile = HDFfile
            self.LDAdata = LDAdata
            self.ParProjdata = ParProjdata
            self.Bandsdata = Bandsdata
            self.Symmpardata = Symmpardata
            self.Symmcorrdata = Symmcorrdata
            self.blocnames= [ ['up','down'], ['ud'] ]
            self.NspinblocsGF = [2,1]
            self.Gupf = None
            self.hfield = hfield
            
            # read input from HDF:
            thingstoread = ['EnergyUnit','Nk','k_dep_projection','SP','SO','charge_below','Density_Required',
                            'symm_op','N_shells','shells','N_corr_shells','corr_shells','use_rotations','rotmat','rotmat_timeinv','Nreps',
                            'dim_reps','T','N_Orbitals','Proj_Mat','BZ_weights','Hopping']
            optionalthings = ['GFStruct_Solver','mapinv','map','Chemical_Potential','dc_imp','DCenerg','deg_shells']

            #ar=HDF_Archive(self.HDFfile,'a')
            #del ar

            self.retval = self.read_input_from_HDF(SubGrp=self.LDAdata,thingstoread=thingstoread,optionalthings=optionalthings)

            #ar=HDF_Archive(self.HDFfile,'a')
            #del ar

            if (self.SO) and (abs(self.hfield)>0.000001):
                self.hfield=0.0
                MPI.report("For SO, the external magnetic field is not implemented, setting it to 0!!")

           
            self.inequiv_shells(self.corr_shells)     # determine the number of inequivalent correlated shells

            # field to convert blocnames to indices
            self.names_to_ind = [{}, {}]
            for ibl in range(2):
                for inm in range(self.NspinblocsGF[ibl]): 
                    self.names_to_ind[ibl][self.blocnames[ibl][inm]] = inm * self.SP #(self.Nspinblocs-1)

            # GF structure used for the local things in the k sums
            self.GFStruct_corr = [ [ (al, range( self.corr_shells[i][3])) for al in self.blocnames[self.corr_shells[i][4]] ]  
                                   for i in xrange(self.N_corr_shells) ]

            if not (self.retval['GFStruct_Solver']):
                # No GFStruct was stored in HDF, so first set a standard one:
                self.GFStruct_Solver = [ [ (al, range( self.corr_shells[self.invshellmap[i]][3]) )
                                           for al in self.blocnames[self.corr_shells[self.invshellmap[i]][4]] ]
                                         for i in xrange(self.N_inequiv_corr_shells) ]
                self.map = [ {} for i in xrange(self.N_inequiv_corr_shells) ]
                self.mapinv = [ {} for i in xrange(self.N_inequiv_corr_shells) ]
                for i in xrange(self.N_inequiv_corr_shells):
                    for al in self.blocnames[self.corr_shells[self.invshellmap[i]][4]]:
                        self.map[i][al] = [al for j in range( self.corr_shells[self.invshellmap[i]][3] ) ]
                        self.mapinv[i][al] = al

            if not (self.retval['dc_imp']):
                # init the double counting:
                self.__initDC()

            if not (self.retval['Chemical_Potential']):
                self.Chemical_Potential = mu

            if not (self.retval['deg_shells']):
                self.deg_shells = [ [] for i in range(self.N_inequiv_corr_shells)]

            if self.symm_op:
                #MPI.report("Do the init for symm:")
                self.Symm_corr = Symmetry(HDFfile,subgroup=self.Symmcorrdata)

            # determine the smallest blocs, if wanted:
            if (UseLDABlocs): dm=self.analyse_BS()

          
            # now save things again to HDF5:
            if (MPI.IS_MASTER_NODE()):
                ar=HDF_Archive(self.HDFfile,'a')
                ar[self.LDAdata]['hfield'] = self.hfield
                del ar
            self.save()
Beispiel #12
0
    def Solve(self):
        """ Solve the impurity problem """

        # Find if an operator is in oplist
        def mysearch(op):
            l = [ k for (k,v) in OPdict.items() if (v-op).is_zero()]
            assert len(l) <=1
            return l[0] if l else None

        # Same but raises an error if pb
        def myfind(op):
            r = mysearch(op)
            if r==None : raise "Operator %s can not be found by myfind !"%r
            return r

        # For backward compatibility
        self.update_params(self.__dict__)

        # Test all a parameters before solutions
        MPI.report(Parameters.check(self.__dict__,self.Required,self.Optional))

        # We have to add the Hamiltonian the epsilon part of G0
        if type(self.H_Local) != type(Operator()) : raise "H_Local is not an operator"
        H = self.H_Local
        for a,alpha_list in  self.GFStruct :
            for mu in alpha_list : 
                for nu in alpha_list : 
                    H += real(self.G0[a]._tail[2][mu,nu]) * Cdag(a,mu)*C(a,nu)

        OPdict = {"Hamiltonian": H}
        MPI.report("Hamiltonian with Eps0 term  : ",H)
        
        # First separate the quantum Numbers that are operators and those which are symmetries.
        QuantumNumberOperators  = dict( (n,op) for (n,op) in self.Quantum_Numbers.items() if type(op) == type(Operator()))
        QuantumNumberSymmetries = dict( (n,op) for (n,op) in self.Quantum_Numbers.items() if type(op) != type(Operator()))

        # Check that the quantum numbers commutes with the Hamiltonian
        for name,op in QuantumNumberOperators.items():
            assert Commutator(self.H_Local ,op).is_zero(), "One quantum number is not commuting with Hamiltonian"
            OPdict[name]=op

        # Complete the OPdict with the fundamental operators
        OPdict, nf, nb, SymChar, NameOpFundamentalList = Operators.Complete_OperatorsList_with_Fundamentals(OPdict)

        # Add the operators to be averaged in OPdict and prepare the list for the C-code
        self.Measured_Operators_Results = {}
        self.twice_defined_Ops = {}
        self.Operators_To_Average_List = []
        for name, op in self.Measured_Operators.items():
          opn = mysearch(op)
          if opn == None : 
              OPdict[name] = op
              self.Measured_Operators_Results[name] = 0.0
              self.Operators_To_Average_List.append(name)
          else:
              MPI.report("Operator %s already defined as %s, using this instead for measuring"%(name,opn))
              self.twice_defined_Ops[name] = opn
              self.Measured_Operators_Results[opn] = 0.0
              if opn not in self.Operators_To_Average_List: self.Operators_To_Average_List.append(opn)

        # Time correlation functions are added
        self.OpCorr_To_Average_List = []
        for name, op in self.Measured_Time_Correlators.items():
          opn = mysearch(op[0])
          if opn == None : 
              OPdict[name] = op[0]
              self.OpCorr_To_Average_List.append(name)
          else:
              MPI.report("Operator %s already defined as %s, using this instead for measuring"%(name,opn))
              if opn not in self.OpCorr_To_Average_List: self.OpCorr_To_Average_List.append(opn)
        # Create storage for data:
        Nops = len(self.OpCorr_To_Average_List)
        f = lambda L : GFBloc_ImTime(Indices= [0], Beta = self.Beta, NTimeSlices=L )
        if (Nops>0):
            self.Measured_Time_Correlators_Results = GF(Name_Block_Generator = [ ( n,f(self.Measured_Time_Correlators[n][1]) ) for n in self.Measured_Time_Correlators], Copy=False)
        else:
            self.Measured_Time_Correlators_Results = GF(Name_Block_Generator = [ ( 'OpCorr',f(2) ) ], Copy=False)

        # Take care of the global moves

        # First, given a function (a,alpha,dagger) -> (a', alpha', dagger')
        # I construct a function on fundamental operators
        def Map_GM_to_Fund_Ops( GM ) :
            def f(fop) :
                a,alpha, dagger = fop.name + (fop.dag,)
                ap,alphap,daggerp = GM((a,alpha,dagger))
                return Cdag(ap,alphap) if daggerp else C(ap,alphap)
            return f

        # Complete the OpList so that it is closed under the global moves
        while 1:
            added_something = False
            for n,(proba,GM) in enumerate(self.Global_Moves):
                # F is a function that map all operators according to the global move
                F = Extend_Function_on_Fundamentals(Map_GM_to_Fund_Ops(GM))
                # Make sure that OPdict is complete, i.e. all images of OPdict operators are in OPdict
                for name,op in OPdict.items() :
                    op_im = F(op)
                    if mysearch(op_im)==None :
                        # find the key and put in in the dictionnary
                        i=0
                        while 1:
                            new_name = name + 'GM' +  i*'_' + "%s"%n
                            if new_name not in OPdict : break
                        added_something = True
                        OPdict[new_name] = op_im
            # break the while loop
            if not added_something: break

        # Now I have all operators, I make the transcription of the global moves
        self.Global_Moves_Mapping_List = []
        for n,(proba,GM) in enumerate(self.Global_Moves):
            F = Extend_Function_on_Fundamentals(Map_GM_to_Fund_Ops(GM))
            m = {}
            for name,op in OPdict.items() :
                op_im = F(op)
                n1,n2 = myfind(op),myfind(op_im)
                m[n1] = n2
            name = "%s"%n
            self.Global_Moves_Mapping_List.append((proba,m,name))
        #MPI.report ("Global_Moves_Mapping_List", self.Global_Moves_Mapping_List)

        # Now add the operator for F calculation if needed
        if self.Use_F :
            Hloc_WithoutQuadratic = self.H_Local.RemoveQuadraticTerms()
            for n,op in OPdict.items() :
                if op.is_Fundamental():
                    op2 = Commutator(Hloc_WithoutQuadratic,op)
                    if not mysearch(op2) : OPdict["%s_Comm_Hloc"%n] = op2

        # All operators have real coefficients. Check this and remove the 0j term
        # since the C++ expects operators with real numbers 
        for n,op in OPdict.items(): op.make_coef_real_and_check()

        # Transcription of operators for C++
        Oplist2 = Operators.Transcribe_OpList_for_C(OPdict)
        SymList = [sym for (n,sym) in SymChar.items() if n in QuantumNumberSymmetries]
        self.H_diag = C_Module.Hloc(nf,nb,Oplist2,QuantumNumberOperators,SymList,self.Quantum_Numbers_Selection,0) 

        # Create the C_Cag_Ops array which describes the grouping of (C,Cdagger) operator
        # for the MonteCarlo moves : (a, alpha) block structure [ [ (C_name, Cdag_name)]]
        self.C_Cdag_Ops = [ [ (myfind(C(a,alpha)), myfind(Cdag(a,alpha))) for alpha in al ] for a,al in self.GFStruct]

        # Define G0_inv and correct it to have G0 to have perfect 1/omega behavior
        self.G0_inv = inverse(self.G0)
        Delta = self.G0_inv.Delta()
        for n,g in self.G0_inv:
          assert(g.N1==g.N2)
          identity=numpy.identity(g.N1)
          self.G0[n] <<= GF_Initializers.A_Omega_Plus_B(identity, g._tail[0])
          self.G0[n] -= Delta[n]
          #self.G0[n] <<= iOmega_n + g._tail[0] - Delta[n]
        self.G0_inv <<= self.G0
        self.G0.invert()

        # Construct the function in tau
        f = lambda g,L : GFBloc_ImTime(Indices= g.Indices, Beta = g.Beta, NTimeSlices=L )
        self.Delta_tau = GF(Name_Block_Generator = [ (n,f(g,self.N_Time_Slices_Delta) )   for n,g in self.G], Copy=False, Name='D')
        self.G_tau = GF(Name_Block_Generator = [ (n,f(g,self.N_Time_Slices_Gtau) )    for n,g in self.G], Copy=False, Name='G')
        self.F_tau = GF(Name_Block_Generator = self.G_tau, Copy=True, Name='F')
        
        for (i,gt) in self.Delta_tau : gt.setFromInverseFourierOf(Delta[i])
        MPI.report("Inv Fourier done")
        if (self.Legendre_Accumulation):
            self.G_Legendre = GF(Name_Block_Generator = [ (n,GFBloc_ImLegendre(Indices=g.Indices, Beta=g.Beta, NLegendreCoeffs=self.N_Legendre_Coeffs) )   for n,g in self.G], Copy=False, Name='Gl')
        else:
            self.G_Legendre = GF(Name_Block_Generator = [ (n,GFBloc_ImLegendre(Indices=[1], Beta=g.Beta, NLegendreCoeffs=1) ) for n,g in self.G], Copy=False, Name='Gl') # G_Legendre must not be empty but is not needed in this case. So I make it as small as possible.
        
        # Starting the C++ code
        self.Sigma_Old <<= self.Sigma
        C_Module.MC_solve(self.__dict__ ) # C++ solver
        
        # Compute G on Matsubara axis possibly fitting the tail
        if self.Legendre_Accumulation:
          for s,g in self.G:
            identity=numpy.zeros([g.N1,g.N2],numpy.float)
            for i,m in enumerate (g._IndicesL):
              for j,n in enumerate (g._IndicesR):
                if m==n: identity[i,j]=1
            self.G_Legendre[s].enforce_discontinuity(identity) # set the known tail
            g <<= LegendreToMatsubara(self.G_Legendre[s])
        else:
          if (self.Time_Accumulation):
            for name, g in self.G_tau:
              identity=numpy.zeros([g.N1,g.N2],numpy.float)
              for i,m in enumerate (g._IndicesL):
                for j,n in enumerate (g._IndicesR):
                  if m==n: identity[i,j]=1
              g._tail.zero()
              g._tail[1] = identity
              self.G[name].setFromFourierOf(g)

          # This is very sick... but what can we do???
          self.Sigma <<= self.G0_inv - inverse(self.G)
          self.fitTails()
          self.G <<= inverse(self.G0_inv - self.Sigma)

        # Now find the self-energy
        self.Sigma <<= self.G0_inv - inverse(self.G)

        MPI.report("Solver %(Name)s has ended."%self.__dict__)

        # for operator averages: if twice defined operator, rename output:
        for op1,op2 in self.twice_defined_Ops.items():
            self.Measured_Operators_Results[op1] = self.Measured_Operators_Results[op2]
        for op1,op2 in self.twice_defined_Ops.items():
            if op2 in self.Measured_Operators_Results.keys(): del self.Measured_Operators_Results[op2]

        if self.Use_F :
            for (n,f) in self.F: f.setFromFourierOf(self.F_tau[n])
            self.G2 = self.G0 + self.G0 * self.F
            self.Sigma2 = self.F * inverse(self.G2)
    def convert_DMFT_input(self):
        """
        Reads the input files, and stores the data in the HDFfile
        """
        
                   
        if not (MPI.IS_MASTER_NODE()): return # do it only on master:
        MPI.report("Reading input from %s..."%self.LDA_file)

        # Read and write only on Master!!!
        # R is a generator : each R.Next() will return the next number in the file
        R = Read_Fortran_File(self.LDA_file)
        try:
            EnergyUnit = R.next()                         # read the energy convertion factor
            Nk = int(R.next())                            # read the number of k points
            k_dep_projection = 1                          
            SP = int(R.next())                            # flag for spin-polarised calculation
            SO = int(R.next())                            # flag for spin-orbit calculation
            charge_below = R.next()                       # total charge below energy window
            Density_Required = R.next()                   # total density required, for setting the chemical potential
            symm_op = 1                                   # Use symmetry groups for the k-sum

            # the information on the non-correlated shells is not important here, maybe skip:
            N_shells = int(R.next())                      # number of shells (e.g. Fe d, As p, O p) in the unit cell, 
                                                               # corresponds to index R in formulas
            # now read the information about the shells:
            shells = [ [ int(R.next()) for i in range(4) ] for icrsh in range(N_shells) ]    # reads iatom, sort, l, dim

            N_corr_shells = int(R.next())                 # number of corr. shells (e.g. Fe d, Ce f) in the unit cell, 
                                                          # corresponds to index R in formulas
            # now read the information about the shells:
            corr_shells = [ [ int(R.next()) for i in range(6) ] for icrsh in range(N_corr_shells) ]    # reads iatom, sort, l, dim, SO flag, irep

            self.inequiv_shells(corr_shells)              # determine the number of inequivalent correlated shells, has to be known for further reading...


            use_rotations = 1
            rotmat = [numpy.identity(corr_shells[icrsh][3],numpy.complex_) for icrsh in xrange(N_corr_shells)]
           
            # read the matrices
            rotmat_timeinv = [0 for i in range(N_corr_shells)]

            for icrsh in xrange(N_corr_shells):
                for i in xrange(corr_shells[icrsh][3]):    # read real part:
                    for j in xrange(corr_shells[icrsh][3]):
                        rotmat[icrsh][i,j] = R.next()
                for i in xrange(corr_shells[icrsh][3]):    # read imaginary part:
                    for j in xrange(corr_shells[icrsh][3]):
                        rotmat[icrsh][i,j] += 1j * R.next()

                if (SP==1):             # read time inversion flag:
                    rotmat_timeinv[icrsh] = int(R.next())
                    
                  
            
            # Read here the infos for the transformation of the basis:
            Nreps = [1 for i in range(self.N_inequiv_corr_shells)]
            dim_reps = [0 for i in range(self.N_inequiv_corr_shells)]
            T = []
            for icrsh in range(self.N_inequiv_corr_shells):
                Nreps[icrsh] = int(R.next())   # number of representatives ("subsets"), e.g. t2g and eg
                dim_reps[icrsh] = [int(R.next()) for i in range(Nreps[icrsh])]   # dimensions of the subsets
            
            # The transformation matrix:
            # it is of dimension 2l+1, if no SO, and 2*(2l+1) with SO!!
            #T = []
            #for ish in xrange(self.N_inequiv_corr_shells):
                ll = 2*corr_shells[self.invshellmap[icrsh]][2]+1
                lmax = ll * (corr_shells[self.invshellmap[icrsh]][4] + 1)
                T.append(numpy.zeros([lmax,lmax],numpy.complex_))
                
                # now read it from file:
                for i in xrange(lmax):
                    for j in xrange(lmax):
                        T[icrsh][i,j] = R.next()
                for i in xrange(lmax):
                    for j in xrange(lmax):
                        T[icrsh][i,j] += 1j * R.next()

    
            # Spin blocks to be read:
            Nspinblocs = SP + 1 - SO   # number of spins to read for Norbs and Ham, NOT Projectors
                 
        
            # read the list of N_Orbitals for all k points
            N_Orbitals = [ [0 for isp in range(Nspinblocs)] for ik in xrange(Nk)]
            for isp in range(Nspinblocs):
                for ik in xrange(Nk):
                    N_Orbitals[ik][isp] = int(R.next())
            #print N_Orbitals

            # Initialise the projectors:
            Proj_Mat = [ [ [numpy.zeros([corr_shells[icrsh][3], N_Orbitals[ik][isp]], numpy.complex_) 
                            for icrsh in range (N_corr_shells)] 
                           for isp in range(Nspinblocs)] 
                         for ik in range(Nk) ]

            # Read the projectors from the file:
            for ik in xrange(Nk):
                for icrsh in range(N_corr_shells):
                    no = corr_shells[icrsh][3]
                    # first Real part for BOTH spins, due to conventions in dmftproj:
                    for isp in range(Nspinblocs):
                        for i in xrange(no):
                            for j in xrange(N_Orbitals[ik][isp]):
                                Proj_Mat[ik][isp][icrsh][i,j] = R.next()
                    # now Imag part:
                    for isp in range(Nspinblocs):
                        for i in xrange(no):
                            for j in xrange(N_Orbitals[ik][isp]):
                                Proj_Mat[ik][isp][icrsh][i,j] += 1j * R.next()
            
          
            # now define the arrays for weights and hopping ...
            BZ_weights = numpy.ones([Nk],numpy.float_)/ float(Nk)  # w(k_index),  default normalisation 
            Hopping = [ [numpy.zeros([N_Orbitals[ik][isp],N_Orbitals[ik][isp]],numpy.complex_) 
                         for isp in range(Nspinblocs)] for ik in xrange(Nk) ]

                            
            # weights in the file
            for ik in xrange(Nk) : BZ_weights[ik] = R.next()         
                
            # if the sum over spins is in the weights, take it out again!!
            sm = sum(BZ_weights)
            BZ_weights[:] /= sm 
	    
            # Grab the H
            # we use now the convention of a DIAGONAL Hamiltonian!!!!
            for isp in range(Nspinblocs):
                for ik in xrange(Nk) :
                    no = N_Orbitals[ik][isp]
                    for i in xrange(no):
                        Hopping[ik][isp][i,i] = R.next() * EnergyUnit
            
            #keep some things that we need for reading parproj:
            self.N_shells = N_shells
            self.shells = shells
            self.N_corr_shells = N_corr_shells
            self.corr_shells = corr_shells
            self.Nspinblocs = Nspinblocs
            self.N_Orbitals = N_Orbitals
            self.Nk = Nk
            self.SO = SO
            self.SP = SP
            self.EnergyUnit = EnergyUnit
        except StopIteration : # a more explicit error if the file is corrupted.
            raise "SumK_LDA : reading file HMLT_file failed!"

        R.close()
        
        #print Proj_Mat[0]

        #-----------------------------------------
        # Store the input into HDF5:
        ar = HDF_Archive(self.HDFfile,'a')
        if not (self.LDASubGrp in ar): ar.create_group(self.LDASubGrp) 
        # The subgroup containing the data. If it does not exist, it is created.
        # If it exists, the data is overwritten!!!
        
        ar[self.LDASubGrp]['EnergyUnit'] = EnergyUnit
        ar[self.LDASubGrp]['Nk'] = Nk
        ar[self.LDASubGrp]['k_dep_projection'] = k_dep_projection
        ar[self.LDASubGrp]['SP'] = SP
        ar[self.LDASubGrp]['SO'] = SO
        ar[self.LDASubGrp]['charge_below'] = charge_below
        ar[self.LDASubGrp]['Density_Required'] = Density_Required
        ar[self.LDASubGrp]['symm_op'] = symm_op
        ar[self.LDASubGrp]['N_shells'] = N_shells
        ar[self.LDASubGrp]['shells'] = shells
        ar[self.LDASubGrp]['N_corr_shells'] = N_corr_shells
        ar[self.LDASubGrp]['corr_shells'] = corr_shells
        ar[self.LDASubGrp]['use_rotations'] = use_rotations
        ar[self.LDASubGrp]['rotmat'] = rotmat
        ar[self.LDASubGrp]['rotmat_timeinv'] = rotmat_timeinv
        ar[self.LDASubGrp]['Nreps'] = Nreps
        ar[self.LDASubGrp]['dim_reps'] = dim_reps
        ar[self.LDASubGrp]['T'] = T
        ar[self.LDASubGrp]['N_Orbitals'] = N_Orbitals
        ar[self.LDASubGrp]['Proj_Mat'] = Proj_Mat
        ar[self.LDASubGrp]['BZ_weights'] = BZ_weights
        ar[self.LDASubGrp]['Hopping'] = Hopping
        
        del ar
              
        # Symmetries are used, 
        # Now do the symmetries for correlated orbitals:
        self.read_Symmetry_input(orbits=corr_shells,symmfile=self.Symm_file,SymmSubGrp=self.SymmSubGrp,SO=SO,SP=SP)
Beispiel #14
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")
    def read_Symmetry_input(self,orbits,symmfile,SymmSubGrp,SO,SP):
        """
        Reads input for the symmetrisations from symmfile, which is case.sympar or case.symqmc.
        """

        if not (MPI.IS_MASTER_NODE()): return

        MPI.report("Reading symmetry input from %s..."%symmfile)

        N_orbits = len(orbits)
        R=Read_Fortran_File(symmfile)

        try:
            Ns = int(R.next())           # Number of symmetry operations
            Natoms = int(R.next())       # number of atoms involved
            perm = [ [int(R.next()) for i in xrange(Natoms)] for j in xrange(Ns) ]    # list of permutations of the atoms
            if SP: 
                timeinv = [ int(R.next()) for j in xrange(Ns) ]           # timeinversion for SO xoupling
            else:
                timeinv = [ 0 for j in xrange(Ns) ] 

            # Now read matrices:
            mat = []  
            for iNs in xrange(Ns):
                
                mat.append( [ numpy.zeros([orbits[orb][3], orbits[orb][3]],numpy.complex_) for orb in xrange(N_orbits) ] )
                for orb in range(N_orbits):
                    for i in xrange(orbits[orb][3]):
                        for j in xrange(orbits[orb][3]):
                            mat[iNs][orb][i,j] = R.next()            # real part
                    for i in xrange(orbits[orb][3]):
                        for j in xrange(orbits[orb][3]):
                            mat[iNs][orb][i,j] += 1j * R.next()      # imaginary part

            # determine the inequivalent shells:
            #SHOULD BE FINALLY REMOVED, PUT IT FOR ALL ORBITALS!!!!!
            #self.inequiv_shells(orbits)
            mat_tinv = [numpy.identity(orbits[orb][3],numpy.complex_)
                        for orb in range(N_orbits)]

            if ((SO==0) and (SP==0)):
                # here we need an additional time inversion operation, so read it:
                for orb in range(N_orbits):
                    for i in xrange(orbits[orb][3]):
                        for j in xrange(orbits[orb][3]):
                            mat_tinv[orb][i,j] = R.next()            # real part
                    for i in xrange(orbits[orb][3]):
                        for j in xrange(orbits[orb][3]):
                            mat_tinv[orb][i,j] += 1j * R.next()      # imaginary part
                


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

        # Save it to the HDF:
        ar=HDF_Archive(self.HDFfile,'a')
        if not (SymmSubGrp in ar): ar.create_group(SymmSubGrp)
        thingstowrite = ['Ns','Natoms','perm','orbits','SO','SP','timeinv','mat','mat_tinv']
        for it in thingstowrite: exec "ar['%s']['%s'] = %s"%(SymmSubGrp,it,it)
        del ar
Beispiel #16
0
    def convert_Parproj_input(self,
                              ParProjSubGrp='SumK_LDA_ParProj',
                              SymmParSubGrp='SymmPar'):
        """
        Reads the input for the partial charges projectors from case.parproj, and stores it in the SymmParSubGrp
        group in the HDF5.
        """

        if not (MPI.IS_MASTER_NODE()): return

        self.ParProjSubGrp = ParProjSubGrp
        self.SymmParSubGrp = SymmParSubGrp

        MPI.report("Reading parproj input from %s..." % self.Parproj_file)

        Dens_Mat_below = [[
            numpy.zeros([self.shells[ish][3], self.shells[ish][3]],
                        numpy.complex_) for ish in range(self.N_shells)
        ] for isp in range(self.Nspinblocs)]

        R = Read_Fortran_File(self.Parproj_file)
        #try:

        N_parproj = [int(R.next()) for i in range(self.N_shells)]

        # Initialise P, here a double list of matrices:
        Proj_Mat_pc = [[[[
            numpy.zeros([self.shells[ish][3], self.N_Orbitals[ik][isp]],
                        numpy.complex_) for ir in range(N_parproj[ish])
        ] for ish in range(self.N_shells)] for isp in range(self.Nspinblocs)]
                       for ik in range(self.Nk)]

        rotmat_all = [
            numpy.identity(self.shells[ish][3], numpy.complex_)
            for ish in xrange(self.N_shells)
        ]
        rotmat_all_timeinv = [0 for i in range(self.N_shells)]

        for ish in range(self.N_shells):
            #print ish
            # read first the projectors for this orbital:
            for ik in xrange(self.Nk):
                for ir in range(N_parproj[ish]):
                    for isp in range(self.Nspinblocs):

                        for i in xrange(
                                self.shells[ish][3]):  # read real part:
                            for j in xrange(self.N_Orbitals[ik][isp]):
                                Proj_Mat_pc[ik][isp][ish][ir][i, j] = R.next()

                    for isp in range(self.Nspinblocs):
                        for i in xrange(
                                self.shells[ish][3]):  # read imaginary part:
                            for j in xrange(self.N_Orbitals[ik][isp]):
                                Proj_Mat_pc[ik][isp][ish][ir][
                                    i, j] += 1j * R.next()

            # now read the Density Matrix for this orbital below the energy window:
            for isp in range(self.Nspinblocs):
                for i in xrange(self.shells[ish][3]):  # read real part:
                    for j in xrange(self.shells[ish][3]):
                        Dens_Mat_below[isp][ish][i, j] = R.next()
            for isp in range(self.Nspinblocs):
                for i in xrange(self.shells[ish][3]):  # read imaginary part:
                    for j in xrange(self.shells[ish][3]):
                        Dens_Mat_below[isp][ish][i, j] += 1j * R.next()
                if (self.SP == 0): Dens_Mat_below[isp][ish] /= 2.0

            # Global -> local rotation matrix for this shell:
            for i in xrange(self.shells[ish][3]):  # read real part:
                for j in xrange(self.shells[ish][3]):
                    rotmat_all[ish][i, j] = R.next()
            for i in xrange(self.shells[ish][3]):  # read imaginary part:
                for j in xrange(self.shells[ish][3]):
                    rotmat_all[ish][i, j] += 1j * R.next()

            #print Dens_Mat_below[0][ish],Dens_Mat_below[1][ish]

            if (self.SP):
                rotmat_all_timeinv[ish] = int(R.next())

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

        #-----------------------------------------
        # Store the input into HDF5:
        ar = HDF_Archive(self.HDFfile, 'a')
        if not (self.ParProjSubGrp in ar): ar.create_group(self.ParProjSubGrp)
        # The subgroup containing the data. If it does not exist, it is created.
        # If it exists, the data is overwritten!!!
        thingstowrite = [
            'Dens_Mat_below', 'N_parproj', 'Proj_Mat_pc', 'rotmat_all',
            'rotmat_all_timeinv'
        ]
        for it in thingstowrite:
            exec "ar['%s']['%s'] = %s" % (self.ParProjSubGrp, it, it)
        del ar

        # Symmetries are used,
        # Now do the symmetries for all orbitals:
        self.read_Symmetry_input(orbits=self.shells,
                                 symmfile=self.Symmpar_file,
                                 SymmSubGrp=self.SymmParSubGrp,
                                 SO=self.SO,
                                 SP=self.SP)
Beispiel #17
0
    def __init__(self,
                 Beta,
                 Norb,
                 U_interact=None,
                 J_Hund=None,
                 GFStruct=False,
                 map=False,
                 use_spinflip=False,
                 useMatrix=True,
                 l=2,
                 T=None,
                 dimreps=None,
                 irep=None,
                 deg_orbs=[],
                 Sl_Int=None):

        self.offset = 0
        self.use_spinflip = use_spinflip
        self.Norb = Norb

        if (useMatrix):

            if not (Sl_Int is None):
                Umat = Umatrix(l=l)
                assert len(Sl_Int) == (l + 1), "Sl_Int has the wrong length"
                if (type(Sl_Int) == ListType):
                    Rcl = numpy.array(Sl_Int)
                else:
                    Rcl = Sl_Int
                Umat(T=T, Rcl=Rcl)
            else:
                if ((U_interact == None) and (J_Hund == None)):
                    MPI.report("Give U,J or Slater integrals!!!")
                    assert 0
                Umat = Umatrix(U_interact=U_interact, J_Hund=J_Hund, l=l)
                Umat(T=T)

            Umat.ReduceMatrix()
            if (Umat.N == Umat.Nmat):
                # Transformation T is of size 2l+1
                self.U = Umat.U
                self.Up = Umat.Up
            else:
                # Transformation is of size 2(2l+1)
                self.U = Umat.U
            # now we have the reduced matrices U and Up, we need it for tail fitting anyways

            if (use_spinflip):
                #Take the 4index Umatrix
                # check for imaginary matrix elements:
                if (abs(Umat.Ufull.imag) > 0.0001).any():
                    MPI.report(
                        "WARNING: complex interaction matrix!! Ignoring imaginary part for the moment!"
                    )
                    MPI.report(
                        "If you want to change this, look into Wien2k/Solver_MultiBand.py"
                    )
                self.U4ind = Umat.Ufull.real

            # this will be changed for arbitrary irep:
            # use only one subgroup of orbitals?
            if not (irep is None):
                #print irep, dimreps
                assert not (dimreps is None
                            ), "Dimensions of the representatives are missing!"
                assert Norb == dimreps[
                    irep - 1], "Dimensions of dimrep and Norb do not fit!"
                for ii in range(irep - 1):
                    self.offset += dimreps[ii]

        else:
            if ((U_interact == None) and (J_Hund == None)):
                MPI.report("For Kanamori representation, give U and J!!")
                assert 0
            self.U = numpy.zeros([Norb, Norb], numpy.float_)
            self.Up = numpy.zeros([Norb, Norb], numpy.float_)
            for i in range(Norb):
                for j in range(Norb):
                    if (i == j):
                        self.Up[i, i] = U_interact + 2.0 * J_Hund
                    else:
                        self.Up[i, j] = U_interact
                        self.U[i, j] = U_interact - J_Hund

        if (GFStruct):
            assert map, "give also the mapping!"
            self.map = map
        else:
            # standard GFStruct and map
            GFStruct = [('%s' % (ud), [n for n in range(Norb)])
                        for ud in ['up', 'down']]
            self.map = {
                'up': ['up' for v in range(self.Norb)],
                'down': ['down' for v in range(self.Norb)]
            }

        #print GFStruct,self.map

        if (use_spinflip == False):
            Hamiltonian = self.__setHamiltonian_density()
        else:
            if (useMatrix):
                Hamiltonian = self.__setfullHamiltonian_Slater()
            else:
                Hamiltonian = self.__setfullHamiltonian_Kanamori(J_Hund=J_Hund)

        Quantum_Numbers = self.__setQuantumNumbers(GFStruct)

        # Determine if there are only blocs of size 1:
        self.blocssizeone = True
        for ib in GFStruct:
            if (len(ib[1]) > 1): self.blocssizeone = False

        # now initialize the solver with the stuff given above:
        Solver.__init__(self,
                        Beta=Beta,
                        GFstruct=GFStruct,
                        H_Local=Hamiltonian,
                        Quantum_Numbers=Quantum_Numbers)

        #self.SetGlobalMoves(deg_orbs)

        self.N_Cycles = 10000
        self.Nmax_Matrix = 100
        self.N_Time_Slices_Delta = 10000
        #if ((len(GFStruct)==2*Norb) and (use_spinflip==False)):
        if ((self.blocssizeone) and (use_spinflip == False)):
            self.Use_Segment_Picture = True
        else:
            self.Use_Segment_Picture = False
Beispiel #18
0
    def __init__(
        self,
        HDFfile,
        mu=0.0,
        hfield=0.0,
        UseLDABlocs=False,
        LDAdata="SumK_LDA",
        Symmcorrdata="SymmCorr",
        ParProjdata="SumK_LDA_ParProj",
        Symmpardata="SymmPar",
        Bandsdata="SumK_LDA_Bands",
    ):
        """
        Initialises the class from data previously stored into an HDF5
        """

        if not (type(HDFfile) == StringType):
            MPI.report("Give a string for the HDF5 filename to read the input!")
        else:
            self.HDFfile = HDFfile
            self.LDAdata = LDAdata
            self.ParProjdata = ParProjdata
            self.Bandsdata = Bandsdata
            self.Symmpardata = Symmpardata
            self.Symmcorrdata = Symmcorrdata
            self.blocnames = [["up", "down"], ["ud"]]
            self.NspinblocsGF = [2, 1]
            self.Gupf = None
            self.hfield = hfield

            # read input from HDF:
            thingstoread = [
                "EnergyUnit",
                "Nk",
                "k_dep_projection",
                "SP",
                "SO",
                "charge_below",
                "Density_Required",
                "symm_op",
                "N_shells",
                "shells",
                "N_corr_shells",
                "corr_shells",
                "use_rotations",
                "rotmat",
                "rotmat_timeinv",
                "Nreps",
                "dim_reps",
                "T",
                "N_Orbitals",
                "Proj_Mat",
                "BZ_weights",
                "Hopping",
            ]
            optionalthings = [
                "GFStruct_Solver",
                "mapinv",
                "map",
                "Chemical_Potential",
                "dc_imp",
                "DCenerg",
                "deg_shells",
            ]

            # ar=HDF_Archive(self.HDFfile,'a')
            # del ar

            self.retval = self.read_input_from_HDF(
                SubGrp=self.LDAdata, thingstoread=thingstoread, optionalthings=optionalthings
            )

            # ar=HDF_Archive(self.HDFfile,'a')
            # del ar

            if (self.SO) and (abs(self.hfield) > 0.000001):
                self.hfield = 0.0
                MPI.report("For SO, the external magnetic field is not implemented, setting it to 0!!")

            self.inequiv_shells(self.corr_shells)  # determine the number of inequivalent correlated shells

            # field to convert blocnames to indices
            self.names_to_ind = [{}, {}]
            for ibl in range(2):
                for inm in range(self.NspinblocsGF[ibl]):
                    self.names_to_ind[ibl][self.blocnames[ibl][inm]] = inm * self.SP  # (self.Nspinblocs-1)

            # GF structure used for the local things in the k sums
            self.GFStruct_corr = [
                [(al, range(self.corr_shells[i][3])) for al in self.blocnames[self.corr_shells[i][4]]]
                for i in xrange(self.N_corr_shells)
            ]

            if not (self.retval["GFStruct_Solver"]):
                # No GFStruct was stored in HDF, so first set a standard one:
                self.GFStruct_Solver = [
                    [
                        (al, range(self.corr_shells[self.invshellmap[i]][3]))
                        for al in self.blocnames[self.corr_shells[self.invshellmap[i]][4]]
                    ]
                    for i in xrange(self.N_inequiv_corr_shells)
                ]
                self.map = [{} for i in xrange(self.N_inequiv_corr_shells)]
                self.mapinv = [{} for i in xrange(self.N_inequiv_corr_shells)]
                for i in xrange(self.N_inequiv_corr_shells):
                    for al in self.blocnames[self.corr_shells[self.invshellmap[i]][4]]:
                        self.map[i][al] = [al for j in range(self.corr_shells[self.invshellmap[i]][3])]
                        self.mapinv[i][al] = al

            if not (self.retval["dc_imp"]):
                # init the double counting:
                self.__initDC()

            if not (self.retval["Chemical_Potential"]):
                self.Chemical_Potential = mu

            if not (self.retval["deg_shells"]):
                self.deg_shells = [[] for i in range(self.N_inequiv_corr_shells)]

            if self.symm_op:
                # MPI.report("Do the init for symm:")
                self.Symm_corr = Symmetry(HDFfile, subgroup=self.Symmcorrdata)

            # determine the smallest blocs, if wanted:
            if UseLDABlocs:
                dm = self.analyse_BS()

            # now save things again to HDF5:
            if MPI.IS_MASTER_NODE():
                ar = HDF_Archive(self.HDFfile, "a")
                ar[self.LDAdata]["hfield"] = self.hfield
                del ar
            self.save()
Beispiel #19
0
    def convert_DMFT_input(self):
        """
        Reads the input files, and stores the data in the HDFfile
        """

        if not (MPI.IS_MASTER_NODE()): return  # do it only on master:
        MPI.report("Reading input from %s..." % self.LDA_file)

        # Read and write only on Master!!!
        # R is a generator : each R.Next() will return the next number in the file
        R = Read_Fortran_File(self.LDA_file)
        try:
            EnergyUnit = R.next()  # read the energy convertion factor
            Nk = int(R.next())  # read the number of k points
            k_dep_projection = 1
            SP = int(R.next())  # flag for spin-polarised calculation
            SO = int(R.next())  # flag for spin-orbit calculation
            charge_below = R.next()  # total charge below energy window
            Density_Required = R.next(
            )  # total density required, for setting the chemical potential
            symm_op = 1  # Use symmetry groups for the k-sum

            # the information on the non-correlated shells is not important here, maybe skip:
            N_shells = int(R.next(
            ))  # number of shells (e.g. Fe d, As p, O p) in the unit cell,
            # corresponds to index R in formulas
            # now read the information about the shells:
            shells = [[int(R.next()) for i in range(4)]
                      for icrsh in range(N_shells)
                      ]  # reads iatom, sort, l, dim

            N_corr_shells = int(R.next(
            ))  # number of corr. shells (e.g. Fe d, Ce f) in the unit cell,
            # corresponds to index R in formulas
            # now read the information about the shells:
            corr_shells = [[int(R.next()) for i in range(6)]
                           for icrsh in range(N_corr_shells)
                           ]  # reads iatom, sort, l, dim, SO flag, irep

            self.inequiv_shells(
                corr_shells
            )  # determine the number of inequivalent correlated shells, has to be known for further reading...

            use_rotations = 1
            rotmat = [
                numpy.identity(corr_shells[icrsh][3], numpy.complex_)
                for icrsh in xrange(N_corr_shells)
            ]

            # read the matrices
            rotmat_timeinv = [0 for i in range(N_corr_shells)]

            for icrsh in xrange(N_corr_shells):
                for i in xrange(corr_shells[icrsh][3]):  # read real part:
                    for j in xrange(corr_shells[icrsh][3]):
                        rotmat[icrsh][i, j] = R.next()
                for i in xrange(corr_shells[icrsh][3]):  # read imaginary part:
                    for j in xrange(corr_shells[icrsh][3]):
                        rotmat[icrsh][i, j] += 1j * R.next()

                if (SP == 1):  # read time inversion flag:
                    rotmat_timeinv[icrsh] = int(R.next())

            # Read here the infos for the transformation of the basis:
            Nreps = [1 for i in range(self.N_inequiv_corr_shells)]
            dim_reps = [0 for i in range(self.N_inequiv_corr_shells)]
            T = []
            for icrsh in range(self.N_inequiv_corr_shells):
                Nreps[icrsh] = int(R.next(
                ))  # number of representatives ("subsets"), e.g. t2g and eg
                dim_reps[icrsh] = [int(R.next()) for i in range(Nreps[icrsh])
                                   ]  # dimensions of the subsets

                # The transformation matrix:
                # it is of dimension 2l+1, if no SO, and 2*(2l+1) with SO!!
                #T = []
                #for ish in xrange(self.N_inequiv_corr_shells):
                ll = 2 * corr_shells[self.invshellmap[icrsh]][2] + 1
                lmax = ll * (corr_shells[self.invshellmap[icrsh]][4] + 1)
                T.append(numpy.zeros([lmax, lmax], numpy.complex_))

                # now read it from file:
                for i in xrange(lmax):
                    for j in xrange(lmax):
                        T[icrsh][i, j] = R.next()
                for i in xrange(lmax):
                    for j in xrange(lmax):
                        T[icrsh][i, j] += 1j * R.next()

            # Spin blocks to be read:
            Nspinblocs = SP + 1 - SO  # number of spins to read for Norbs and Ham, NOT Projectors

            # read the list of N_Orbitals for all k points
            N_Orbitals = [[0 for isp in range(Nspinblocs)]
                          for ik in xrange(Nk)]
            for isp in range(Nspinblocs):
                for ik in xrange(Nk):
                    N_Orbitals[ik][isp] = int(R.next())
            #print N_Orbitals

            # Initialise the projectors:
            Proj_Mat = [[[
                numpy.zeros([corr_shells[icrsh][3], N_Orbitals[ik][isp]],
                            numpy.complex_) for icrsh in range(N_corr_shells)
            ] for isp in range(Nspinblocs)] for ik in range(Nk)]

            # Read the projectors from the file:
            for ik in xrange(Nk):
                for icrsh in range(N_corr_shells):
                    no = corr_shells[icrsh][3]
                    # first Real part for BOTH spins, due to conventions in dmftproj:
                    for isp in range(Nspinblocs):
                        for i in xrange(no):
                            for j in xrange(N_Orbitals[ik][isp]):
                                Proj_Mat[ik][isp][icrsh][i, j] = R.next()
                    # now Imag part:
                    for isp in range(Nspinblocs):
                        for i in xrange(no):
                            for j in xrange(N_Orbitals[ik][isp]):
                                Proj_Mat[ik][isp][icrsh][i, j] += 1j * R.next()

            # now define the arrays for weights and hopping ...
            BZ_weights = numpy.ones([Nk], numpy.float_) / float(
                Nk)  # w(k_index),  default normalisation
            Hopping = [[
                numpy.zeros([N_Orbitals[ik][isp], N_Orbitals[ik][isp]],
                            numpy.complex_) for isp in range(Nspinblocs)
            ] for ik in xrange(Nk)]

            # weights in the file
            for ik in xrange(Nk):
                BZ_weights[ik] = R.next()

            # if the sum over spins is in the weights, take it out again!!
            sm = sum(BZ_weights)
            BZ_weights[:] /= sm

            # Grab the H
            # we use now the convention of a DIAGONAL Hamiltonian!!!!
            for isp in range(Nspinblocs):
                for ik in xrange(Nk):
                    no = N_Orbitals[ik][isp]
                    for i in xrange(no):
                        Hopping[ik][isp][i, i] = R.next() * EnergyUnit

            #keep some things that we need for reading parproj:
            self.N_shells = N_shells
            self.shells = shells
            self.N_corr_shells = N_corr_shells
            self.corr_shells = corr_shells
            self.Nspinblocs = Nspinblocs
            self.N_Orbitals = N_Orbitals
            self.Nk = Nk
            self.SO = SO
            self.SP = SP
            self.EnergyUnit = EnergyUnit
        except StopIteration:  # a more explicit error if the file is corrupted.
            raise "SumK_LDA : reading file HMLT_file failed!"

        R.close()

        #print Proj_Mat[0]

        #-----------------------------------------
        # Store the input into HDF5:
        ar = HDF_Archive(self.HDFfile, 'a')
        if not (self.LDASubGrp in ar): ar.create_group(self.LDASubGrp)
        # The subgroup containing the data. If it does not exist, it is created.
        # If it exists, the data is overwritten!!!

        ar[self.LDASubGrp]['EnergyUnit'] = EnergyUnit
        ar[self.LDASubGrp]['Nk'] = Nk
        ar[self.LDASubGrp]['k_dep_projection'] = k_dep_projection
        ar[self.LDASubGrp]['SP'] = SP
        ar[self.LDASubGrp]['SO'] = SO
        ar[self.LDASubGrp]['charge_below'] = charge_below
        ar[self.LDASubGrp]['Density_Required'] = Density_Required
        ar[self.LDASubGrp]['symm_op'] = symm_op
        ar[self.LDASubGrp]['N_shells'] = N_shells
        ar[self.LDASubGrp]['shells'] = shells
        ar[self.LDASubGrp]['N_corr_shells'] = N_corr_shells
        ar[self.LDASubGrp]['corr_shells'] = corr_shells
        ar[self.LDASubGrp]['use_rotations'] = use_rotations
        ar[self.LDASubGrp]['rotmat'] = rotmat
        ar[self.LDASubGrp]['rotmat_timeinv'] = rotmat_timeinv
        ar[self.LDASubGrp]['Nreps'] = Nreps
        ar[self.LDASubGrp]['dim_reps'] = dim_reps
        ar[self.LDASubGrp]['T'] = T
        ar[self.LDASubGrp]['N_Orbitals'] = N_Orbitals
        ar[self.LDASubGrp]['Proj_Mat'] = Proj_Mat
        ar[self.LDASubGrp]['BZ_weights'] = BZ_weights
        ar[self.LDASubGrp]['Hopping'] = Hopping

        del ar

        # Symmetries are used,
        # Now do the symmetries for correlated orbitals:
        self.read_Symmetry_input(orbits=corr_shells,
                                 symmfile=self.Symm_file,
                                 SymmSubGrp=self.SymmSubGrp,
                                 SO=SO,
                                 SP=SP)
Beispiel #20
0
    def analyse_BS(self, threshold=0.00001, includeshells=None):
        """ Determines the Greens function block structure from the simple point integration"""

        dm = self.simplepointdensmat()

        densmat = [dm[self.invshellmap[ish]] for ish in xrange(self.N_inequiv_corr_shells)]

        if includeshells is None:
            includeshells = range(self.N_inequiv_corr_shells)
        for ish in includeshells:

            # self.GFStruct_Solver.append([])
            self.GFStruct_Solver[ish] = []

            a_list = [a for a, al in self.GFStruct_corr[self.invshellmap[ish]]]
            for a in a_list:

                dm = densmat[ish][a]
                dmbool = abs(dm) > threshold  # gives an index list of entries larger that threshold

                offdiag = []
                for i in xrange(len(dmbool)):
                    for j in xrange(i, len(dmbool)):
                        if (dmbool[i, j]) & (i != j):
                            offdiag.append([i, j])

                NBlocs = len(dmbool)
                blocs = [[i] for i in range(NBlocs)]

                for i in range(len(offdiag)):
                    if offdiag[i][0] != offdiag[i][1]:
                        for j in range(len(blocs[offdiag[i][1]])):
                            blocs[offdiag[i][0]].append(blocs[offdiag[i][1]][j])
                        del blocs[offdiag[i][1]]
                        for j in range(i + 1, len(offdiag)):
                            if offdiag[j][0] == offdiag[i][1]:
                                offdiag[j][0] = offdiag[i][0]
                            if offdiag[j][1] == offdiag[i][1]:
                                offdiag[j][1] = offdiag[i][0]
                            if offdiag[j][0] > offdiag[i][1]:
                                offdiag[j][0] -= 1
                            if offdiag[j][1] > offdiag[i][1]:
                                offdiag[j][1] -= 1
                            offdiag[j].sort()
                        NBlocs -= 1

                for i in range(NBlocs):
                    blocs[i].sort()
                    self.GFStruct_Solver[ish].append(("%s%s" % (a, i), blocs[i]))

                # map is the mapping of the blocs from the SK blocs to the CTQMC blocs:
                self.map[ish][a] = range(len(dmbool))
                for ibl in range(NBlocs):
                    for j in range(len(blocs[ibl])):
                        self.map[ish][a][blocs[ibl][j]] = "%s%s" % (a, ibl)
                        self.mapinv[ish]["%s%s" % (a, ibl)] = a

            # now calculate degeneracies of orbitals:
            dm = {}
            for bl in self.GFStruct_Solver[ish]:
                bln = bl[0]
                ind = bl[1]
                # get dm for the blocks:
                dm[bln] = numpy.zeros([len(ind), len(ind)], numpy.complex_)
                for i in range(len(ind)):
                    for j in range(len(ind)):
                        dm[bln][i, j] = densmat[ish][self.mapinv[ish][bln]][ind[i], ind[j]]

            for bl in self.GFStruct_Solver[ish]:
                for bl2 in self.GFStruct_Solver[ish]:
                    if dm[bl[0]].shape == dm[bl2[0]].shape:
                        if ((abs(dm[bl[0]] - dm[bl2[0]]) < threshold).all()) and (bl[0] != bl2[0]):
                            # check if it was already there:
                            ind1 = -1
                            ind2 = -2
                            for n, ind in enumerate(self.deg_shells[ish]):
                                if bl[0] in ind:
                                    ind1 = n
                                if bl2[0] in ind:
                                    ind2 = n
                            if (ind1 < 0) and (ind2 >= 0):
                                self.deg_shells[ish][ind2].append(bl[0])
                            elif (ind1 >= 0) and (ind2 < 0):
                                self.deg_shells[ish][ind1].append(bl2[0])
                            elif (ind1 < 0) and (ind2 < 0):
                                self.deg_shells[ish].append([bl[0], bl2[0]])

        if MPI.IS_MASTER_NODE():
            ar = HDF_Archive(self.HDFfile, "a")
            ar[self.LDAdata]["GFStruct_Solver"] = self.GFStruct_Solver
            ar[self.LDAdata]["map"] = self.map
            ar[self.LDAdata]["mapinv"] = self.mapinv
            try:
                ar[self.LDAdata]["deg_shells"] = self.deg_shells
            except:
                MPI.report("deg_shells not stored, degeneracies not found")
            del ar

        return densmat
Beispiel #21
0
    def read_Symmetry_input(self, orbits, symmfile, SymmSubGrp, SO, SP):
        """
        Reads input for the symmetrisations from symmfile, which is case.sympar or case.symqmc.
        """

        if not (MPI.IS_MASTER_NODE()): return

        MPI.report("Reading symmetry input from %s..." % symmfile)

        N_orbits = len(orbits)
        R = Read_Fortran_File(symmfile)

        try:
            Ns = int(R.next())  # Number of symmetry operations
            Natoms = int(R.next())  # number of atoms involved
            perm = [[int(R.next()) for i in xrange(Natoms)]
                    for j in xrange(Ns)]  # list of permutations of the atoms
            if SP:
                timeinv = [int(R.next()) for j in xrange(Ns)
                           ]  # timeinversion for SO xoupling
            else:
                timeinv = [0 for j in xrange(Ns)]

            # Now read matrices:
            mat = []
            for iNs in xrange(Ns):

                mat.append([
                    numpy.zeros([orbits[orb][3], orbits[orb][3]],
                                numpy.complex_) for orb in xrange(N_orbits)
                ])
                for orb in range(N_orbits):
                    for i in xrange(orbits[orb][3]):
                        for j in xrange(orbits[orb][3]):
                            mat[iNs][orb][i, j] = R.next()  # real part
                    for i in xrange(orbits[orb][3]):
                        for j in xrange(orbits[orb][3]):
                            mat[iNs][orb][i,
                                          j] += 1j * R.next()  # imaginary part

            # determine the inequivalent shells:
            #SHOULD BE FINALLY REMOVED, PUT IT FOR ALL ORBITALS!!!!!
            #self.inequiv_shells(orbits)
            mat_tinv = [
                numpy.identity(orbits[orb][3], numpy.complex_)
                for orb in range(N_orbits)
            ]

            if ((SO == 0) and (SP == 0)):
                # here we need an additional time inversion operation, so read it:
                for orb in range(N_orbits):
                    for i in xrange(orbits[orb][3]):
                        for j in xrange(orbits[orb][3]):
                            mat_tinv[orb][i, j] = R.next()  # real part
                    for i in xrange(orbits[orb][3]):
                        for j in xrange(orbits[orb][3]):
                            mat_tinv[orb][i,
                                          j] += 1j * R.next()  # imaginary part

        except StopIteration:  # a more explicit error if the file is corrupted.
            raise "Symmetry : reading file failed!"

        R.close()

        # Save it to the HDF:
        ar = HDF_Archive(self.HDFfile, 'a')
        if not (SymmSubGrp in ar): ar.create_group(SymmSubGrp)
        thingstowrite = [
            'Ns', 'Natoms', 'perm', 'orbits', 'SO', 'SP', 'timeinv', 'mat',
            'mat_tinv'
        ]
        for it in thingstowrite:
            exec "ar['%s']['%s'] = %s" % (SymmSubGrp, it, it)
        del ar
Beispiel #22
0
    def convert_bands_input(self, BandsSubGrp='SumK_LDA_Bands'):
        """
        Converts the input for momentum resolved spectral functions, and stores it in BandsSubGrp in the
        HDF5.
        """

        if not (MPI.IS_MASTER_NODE()): return

        self.BandsSubGrp = BandsSubGrp
        MPI.report("Reading bands input from %s..." % self.Band_file)

        R = Read_Fortran_File(self.Band_file)
        try:
            Nk = int(R.next())

            # read the list of N_Orbitals for all k points
            N_Orbitals = [[0 for isp in range(self.Nspinblocs)]
                          for ik in xrange(Nk)]
            for isp in range(self.Nspinblocs):
                for ik in xrange(Nk):
                    N_Orbitals[ik][isp] = int(R.next())

            # Initialise the projectors:
            Proj_Mat = [[[
                numpy.zeros([self.corr_shells[icrsh][3], N_Orbitals[ik][isp]],
                            numpy.complex_)
                for icrsh in range(self.N_corr_shells)
            ] for isp in range(self.Nspinblocs)] for ik in range(Nk)]

            # Read the projectors from the file:
            for ik in xrange(Nk):
                for icrsh in range(self.N_corr_shells):
                    no = self.corr_shells[icrsh][3]
                    # first Real part for BOTH spins, due to conventions in dmftproj:
                    for isp in range(self.Nspinblocs):
                        for i in xrange(no):
                            for j in xrange(N_Orbitals[ik][isp]):
                                Proj_Mat[ik][isp][icrsh][i, j] = R.next()
                    # now Imag part:
                    for isp in range(self.Nspinblocs):
                        for i in xrange(no):
                            for j in xrange(N_Orbitals[ik][isp]):
                                Proj_Mat[ik][isp][icrsh][i, j] += 1j * R.next()

            Hopping = [[
                numpy.zeros([N_Orbitals[ik][isp], N_Orbitals[ik][isp]],
                            numpy.complex_) for isp in range(self.Nspinblocs)
            ] for ik in xrange(Nk)]

            # Grab the H
            # we use now the convention of a DIAGONAL Hamiltonian!!!!
            for isp in range(self.Nspinblocs):
                for ik in xrange(Nk):
                    no = N_Orbitals[ik][isp]
                    for i in xrange(no):
                        Hopping[ik][isp][i, i] = R.next() * self.EnergyUnit

            # now read the partial projectors:
            N_parproj = [int(R.next()) for i in range(self.N_shells)]
            # Initialise P, here a double list of matrices:
            Proj_Mat_pc = [[[[
                numpy.zeros([self.shells[ish][3], N_Orbitals[ik][isp]],
                            numpy.complex_) for ir in range(N_parproj[ish])
            ] for ish in range(self.N_shells)]
                            for isp in range(self.Nspinblocs)]
                           for ik in range(Nk)]

            for ish in range(self.N_shells):

                for ik in xrange(Nk):
                    for ir in range(N_parproj[ish]):
                        for isp in range(self.Nspinblocs):

                            for i in xrange(
                                    self.shells[ish][3]):  # read real part:
                                for j in xrange(N_Orbitals[ik][isp]):
                                    Proj_Mat_pc[ik][isp][ish][ir][
                                        i, j] = R.next()

                            for i in xrange(self.shells[ish]
                                            [3]):  # read imaginary part:
                                for j in xrange(N_Orbitals[ik][isp]):
                                    Proj_Mat_pc[ik][isp][ish][ir][
                                        i, j] += 1j * R.next()

        except StopIteration:  # a more explicit error if the file is corrupted.
            raise "SumK_LDA : reading file HMLT_file failed!"

        R.close()
        # reading done!

        #-----------------------------------------
        # Store the input into HDF5:
        ar = HDF_Archive(self.HDFfile, 'a')
        if not (self.BandsSubGrp in ar): ar.create_group(self.BandsSubGrp)
        # The subgroup containing the data. If it does not exist, it is created.
        # If it exists, the data is overwritten!!!
        thingstowrite = [
            'Nk', 'N_Orbitals', 'Proj_Mat', 'Hopping', 'N_parproj',
            'Proj_Mat_pc'
        ]
        for it in thingstowrite:
            exec "ar['%s']['%s'] = %s" % (self.BandsSubGrp, it, it)

        #ar[self.BandsSubGrp]['Nk'] = Nk
        #ar[self.BandsSubGrp]['N_Orbitals'] = N_Orbitals
        #ar[self.BandsSubGrp]['Proj_Mat'] = Proj_Mat
        #self.Proj_Mat = Proj_Mat
        #self.N_Orbitals = N_Orbitals
        #self.Nk = Nk
        #self.Hopping = Hopping
        del ar
Beispiel #23
0
    def Solve(self):
        """ Solve the impurity problem """

        # Find if an operator is in oplist
        def mysearch(op):
            l = [ k for (k,v) in OPdict.items() if (v-op).is_zero()]
            assert len(l) <=1
            return l[0] if l else None

        # Same but raises an error if pb
        def myfind(op):
            r = mysearch(op)
            if r==None : raise "Operator %s can not be found by myfind !"%r
            return r

        # For backward compatibility
        self.update_params(self.__dict__)

        # Test all a parameters before solutions
        MPI.report(Parameters.check(self.__dict__,self.Required,self.Optional))

        # We have to add the Hamiltonian the epsilon part of G0
        if type(self.H_Local) != type(Operator()) : raise "H_Local is not an operator"
        H = self.H_Local
        for a,alpha_list in  self.GFStruct :
            for mu in alpha_list : 
                for nu in alpha_list : 
                    H += real(self.G0[a]._tail[2][mu,nu]) * Cdag(a,mu)*C(a,nu)

        OPdict = {"Hamiltonian": H}
        MPI.report("Hamiltonian with Eps0 term  : ",H)
        
        # First separate the quantum Numbers that are operators and those which are symmetries.
        QuantumNumberOperators  = dict( (n,op) for (n,op) in self.Quantum_Numbers.items() if type(op) == type(Operator()))
        QuantumNumberSymmetries = dict( (n,op) for (n,op) in self.Quantum_Numbers.items() if type(op) != type(Operator()))

        # Check that the quantum numbers commutes with the Hamiltonian
        for name,op in QuantumNumberOperators.items():
            assert Commutator(self.H_Local ,op).is_zero(), "One quantum number is not commuting with Hamiltonian"
            OPdict[name]=op

        # Complete the OPdict with the fundamental operators
        OPdict, nf, nb, SymChar, NameOpFundamentalList = Operators.Complete_OperatorsList_with_Fundamentals(OPdict)

        # Add the operators to be averaged in OPdict and prepare the list for the C-code
        self.Measured_Operators_Results = {}
        self.twice_defined_Ops = {}
        self.Operators_To_Average_List = []
        for name, op in self.Measured_Operators.items():
          opn = mysearch(op)
          if opn == None : 
              OPdict[name] = op
              self.Measured_Operators_Results[name] = 0.0
              self.Operators_To_Average_List.append(name)
          else:
              MPI.report("Operator %s already defined as %s, using this instead for measuring"%(name,opn))
              self.twice_defined_Ops[name] = opn
              self.Measured_Operators_Results[opn] = 0.0
              if opn not in self.Operators_To_Average_List: self.Operators_To_Average_List.append(opn)

        # Time correlation functions are added
        self.OpCorr_To_Average_List = []
        for name, op in self.Measured_Time_Correlators.items():
          opn = mysearch(op[0])
          if opn == None : 
              OPdict[name] = op[0]
              self.OpCorr_To_Average_List.append(name)
          else:
              MPI.report("Operator %s already defined as %s, using this instead for measuring"%(name,opn))
              if opn not in self.OpCorr_To_Average_List: self.OpCorr_To_Average_List.append(opn)
        # Create storage for data:
        Nops = len(self.OpCorr_To_Average_List)
        f = lambda L : GFBloc_ImTime(Indices= [0], Beta = self.Beta, NTimeSlices=L )
        if (Nops>0):
            self.Measured_Time_Correlators_Results = GF(Name_Block_Generator = [ ( n,f(self.Measured_Time_Correlators[n][1]) ) for n in self.Measured_Time_Correlators], Copy=False)
        else:
            self.Measured_Time_Correlators_Results = GF(Name_Block_Generator = [ ( 'OpCorr',f(2) ) ], Copy=False)

        # Take care of the global moves

        # First, given a function (a,alpha,dagger) -> (a', alpha', dagger')
        # I construct a function on fundamental operators
        def Map_GM_to_Fund_Ops( GM ) :
            def f(fop) :
                a,alpha, dagger = fop.name + (fop.dag,)
                ap,alphap,daggerp = GM((a,alpha,dagger))
                return Cdag(ap,alphap) if daggerp else C(ap,alphap)
            return f

        # Complete the OpList so that it is closed under the global moves
        while 1:
            added_something = False
            for n,(proba,GM) in enumerate(self.Global_Moves):
                # F is a function that map all operators according to the global move
                F = Extend_Function_on_Fundamentals(Map_GM_to_Fund_Ops(GM))
                # Make sure that OPdict is complete, i.e. all images of OPdict operators are in OPdict
                for name,op in OPdict.items() :
                    op_im = F(op)
                    if mysearch(op_im)==None :
                        # find the key and put in in the dictionnary
                        i=0
                        while 1:
                            new_name = name + 'GM' +  i*'_' + "%s"%n
                            if new_name not in OPdict : break
                        added_something = True
                        OPdict[new_name] = op_im
            # break the while loop
            if not added_something: break

        # Now I have all operators, I make the transcription of the global moves
        self.Global_Moves_Mapping_List = []
        for n,(proba,GM) in enumerate(self.Global_Moves):
            F = Extend_Function_on_Fundamentals(Map_GM_to_Fund_Ops(GM))
            m = {}
            for name,op in OPdict.items() :
                op_im = F(op)
                n1,n2 = myfind(op),myfind(op_im)
                m[n1] = n2
            name = "%s"%n
            self.Global_Moves_Mapping_List.append((proba,m,name))
        #MPI.report ("Global_Moves_Mapping_List", self.Global_Moves_Mapping_List)

        # Now add the operator for F calculation if needed
        if self.Use_F :
            Hloc_WithoutQuadratic = self.H_Local.RemoveQuadraticTerms()
            for n,op in OPdict.items() :
                if op.is_Fundamental():
                    op2 = Commutator(Hloc_WithoutQuadratic,op)
                    if not mysearch(op2) : OPdict["%s_Comm_Hloc"%n] = op2

        # All operators have real coefficients. Check this and remove the 0j term
        # since the C++ expects operators with real numbers 
        for n,op in OPdict.items(): op.make_coef_real_and_check()

        # Transcription of operators for C++
        Oplist2 = Operators.Transcribe_OpList_for_C(OPdict)
        SymList = [sym for (n,sym) in SymChar.items() if n in QuantumNumberSymmetries]
        self.H_diag = C_Module.Hloc(nf,nb,Oplist2,QuantumNumberOperators,SymList,self.Quantum_Numbers_Selection,0) 

        # Create the C_Cag_Ops array which describes the grouping of (C,Cdagger) operator
        # for the MonteCarlo moves : (a, alpha) block structure [ [ (C_name, Cdag_name)]]
        self.C_Cdag_Ops = [ [ (myfind(C(a,alpha)), myfind(Cdag(a,alpha))) for alpha in al ] for a,al in self.GFStruct]

        # Define G0_inv and correct it to have G0 to have perfect 1/omega behavior
        self.G0_inv = inverse(self.G0)
        Delta = self.G0_inv.Delta()
        for n,g in self.G0_inv:
          assert(g.N1==g.N2)
          identity=numpy.identity(g.N1)
          self.G0[n] <<= GF_Initializers.A_Omega_Plus_B(identity, g._tail[0])
          self.G0[n] -= Delta[n]
          #self.G0[n] <<= iOmega_n + g._tail[0] - Delta[n]
        self.G0_inv <<= self.G0
        self.G0.invert()

        # Construct the function in tau
        f = lambda g,L : GFBloc_ImTime(Indices= g.Indices, Beta = g.Beta, NTimeSlices=L )
        self.Delta_tau = GF(Name_Block_Generator = [ (n,f(g,self.N_Time_Slices_Delta) )   for n,g in self.G], Copy=False, Name='D')
        self.G_tau = GF(Name_Block_Generator = [ (n,f(g,self.N_Time_Slices_Gtau) )    for n,g in self.G], Copy=False, Name='G')
        self.F_tau = GF(Name_Block_Generator = self.G_tau, Copy=True, Name='F')
        
        for (i,gt) in self.Delta_tau : gt.setFromInverseFourierOf(Delta[i])
        MPI.report("Inv Fourier done")
        if (self.Legendre_Accumulation):
            self.G_Legendre = GF(Name_Block_Generator = [ (n,GFBloc_ImLegendre(Indices=g.Indices, Beta=g.Beta, NLegendreCoeffs=self.N_Legendre_Coeffs) )   for n,g in self.G], Copy=False, Name='Gl')
        else:
            self.G_Legendre = GF(Name_Block_Generator = [ (n,GFBloc_ImLegendre(Indices=[1], Beta=g.Beta, NLegendreCoeffs=1) ) for n,g in self.G], Copy=False, Name='Gl') # G_Legendre must not be empty but is not needed in this case. So I make it as small as possible.
        
        # Starting the C++ code
        self.Sigma_Old <<= self.Sigma
        C_Module.MC_solve(self.__dict__ ) # C++ solver
        
        # Compute G on Matsubara axis possibly fitting the tail
        if self.Legendre_Accumulation:
          for s,g in self.G:
            identity=numpy.zeros([g.N1,g.N2],numpy.float)
            for i,m in enumerate (g._IndicesL):
              for j,n in enumerate (g._IndicesR):
                if m==n: identity[i,j]=1
            self.G_Legendre[s].enforce_discontinuity(identity) # set the known tail
            g <<= LegendreToMatsubara(self.G_Legendre[s])
        else:
          if (self.Time_Accumulation):
            for name, g in self.G_tau:
              identity=numpy.zeros([g.N1,g.N2],numpy.float)
              for i,m in enumerate (g._IndicesL):
                for j,n in enumerate (g._IndicesR):
                  if m==n: identity[i,j]=1
              g._tail.zero()
              g._tail[1] = identity
              self.G[name].setFromFourierOf(g)

          # This is very sick... but what can we do???
          self.Sigma <<= self.G0_inv - inverse(self.G)
          self.fitTails()
          self.G <<= inverse(self.G0_inv - self.Sigma)

        # Now find the self-energy
        self.Sigma <<= self.G0_inv - inverse(self.G)

        MPI.report("Solver %(Name)s has ended."%self.__dict__)

        # for operator averages: if twice defined operator, rename output:
        for op1,op2 in self.twice_defined_Ops.items():
            self.Measured_Operators_Results[op1] = self.Measured_Operators_Results[op2]
        for op1,op2 in self.twice_defined_Ops.items():
            if op2 in self.Measured_Operators_Results.keys(): del self.Measured_Operators_Results[op2]

        if self.Use_F :
            for (n,f) in self.F: f.setFromFourierOf(self.F_tau[n])
            self.G2 = self.G0 + self.G0 * self.F
            self.Sigma2 = self.F * inverse(self.G2)
    def convert_Parproj_input(self,ParProjSubGrp='SumK_LDA_ParProj',SymmParSubGrp='SymmPar'):
        """
        Reads the input for the partial charges projectors from case.parproj, and stores it in the SymmParSubGrp
        group in the HDF5.
        """

        if not (MPI.IS_MASTER_NODE()): return

        self.ParProjSubGrp = ParProjSubGrp
        self.SymmParSubGrp = SymmParSubGrp

        MPI.report("Reading parproj input from %s..."%self.Parproj_file)

        Dens_Mat_below = [ [numpy.zeros([self.shells[ish][3],self.shells[ish][3]],numpy.complex_) for ish in range(self.N_shells)] 
                           for isp in range(self.Nspinblocs) ]

        R = Read_Fortran_File(self.Parproj_file)
        #try:

        N_parproj = [int(R.next()) for i in range(self.N_shells)]
                
        # Initialise P, here a double list of matrices:
        Proj_Mat_pc = [ [ [ [numpy.zeros([self.shells[ish][3], self.N_Orbitals[ik][isp]], numpy.complex_) 
                             for ir in range(N_parproj[ish])]
                            for ish in range (self.N_shells) ]
                          for isp in range(self.Nspinblocs) ]
                        for ik in range(self.Nk) ]

        rotmat_all = [numpy.identity(self.shells[ish][3],numpy.complex_) for ish in xrange(self.N_shells)]
        rotmat_all_timeinv = [0 for i in range(self.N_shells)]

        for ish in range(self.N_shells):
            #print ish   
            # read first the projectors for this orbital:
            for ik in xrange(self.Nk):
                for ir in range(N_parproj[ish]):
                    for isp in range(self.Nspinblocs):
                                    
                        for i in xrange(self.shells[ish][3]):    # read real part:
                            for j in xrange(self.N_Orbitals[ik][isp]):
                                Proj_Mat_pc[ik][isp][ish][ir][i,j] = R.next()
                            
                    for isp in range(self.Nspinblocs):
                        for i in xrange(self.shells[ish][3]):    # read imaginary part:
                            for j in xrange(self.N_Orbitals[ik][isp]):
                                Proj_Mat_pc[ik][isp][ish][ir][i,j] += 1j * R.next()
                                        
                    
            # now read the Density Matrix for this orbital below the energy window:
            for isp in range(self.Nspinblocs):
                for i in xrange(self.shells[ish][3]):    # read real part:
                    for j in xrange(self.shells[ish][3]):
                        Dens_Mat_below[isp][ish][i,j] = R.next()
            for isp in range(self.Nspinblocs):
                for i in xrange(self.shells[ish][3]):    # read imaginary part:
                    for j in xrange(self.shells[ish][3]):
                        Dens_Mat_below[isp][ish][i,j] += 1j * R.next()
                if (self.SP==0): Dens_Mat_below[isp][ish] /= 2.0

            # Global -> local rotation matrix for this shell:
            for i in xrange(self.shells[ish][3]):    # read real part:
                for j in xrange(self.shells[ish][3]):
                    rotmat_all[ish][i,j] = R.next()
            for i in xrange(self.shells[ish][3]):    # read imaginary part:
                for j in xrange(self.shells[ish][3]):
                    rotmat_all[ish][i,j] += 1j * R.next()
                    
            #print Dens_Mat_below[0][ish],Dens_Mat_below[1][ish]
            
            if (self.SP):
                rotmat_all_timeinv[ish] = int(R.next())

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

        #-----------------------------------------
        # Store the input into HDF5:
        ar = HDF_Archive(self.HDFfile,'a')
        if not (self.ParProjSubGrp in ar): ar.create_group(self.ParProjSubGrp) 
        # The subgroup containing the data. If it does not exist, it is created.
        # If it exists, the data is overwritten!!!
        thingstowrite = ['Dens_Mat_below','N_parproj','Proj_Mat_pc','rotmat_all','rotmat_all_timeinv']
        for it in thingstowrite: exec "ar['%s']['%s'] = %s"%(self.ParProjSubGrp,it,it)
        del ar

        # Symmetries are used, 
        # Now do the symmetries for all orbitals:
        self.read_Symmetry_input(orbits=self.shells,symmfile=self.Symmpar_file,SymmSubGrp=self.SymmParSubGrp,SO=self.SO,SP=self.SP)
    def __init__(self, Beta, Norb, U_interact=None, J_Hund=None, GFStruct=False, map=False, use_spinflip=False,
                 useMatrix = True, l=2, T=None, dimreps=None, irep=None, deg_orbs = [], Sl_Int = None):
    
        self.offset = 0
        self.use_spinflip = use_spinflip
        self.Norb = Norb
        
        if (useMatrix):
                                      
            if not (Sl_Int is None):
                Umat = Umatrix(l=l)
                assert len(Sl_Int)==(l+1),"Sl_Int has the wrong length"
                if (type(Sl_Int)==ListType):
                    Rcl = numpy.array(Sl_Int)
                else:
                    Rcl = Sl_Int
                Umat(T=T,Rcl=Rcl)
            else:
                if ((U_interact==None)and(J_Hund==None)):
                    MPI.report("Give U,J or Slater integrals!!!")
                    assert 0
                Umat = Umatrix(U_interact=U_interact, J_Hund=J_Hund, l=l)
                Umat(T=T)
            
            Umat.ReduceMatrix()
            if (Umat.N==Umat.Nmat):
                # Transformation T is of size 2l+1
                self.U = Umat.U
                self.Up = Umat.Up
            else:
                # Transformation is of size 2(2l+1)
                self.U = Umat.U
             # now we have the reduced matrices U and Up, we need it for tail fitting anyways

            if (use_spinflip):
                #Take the 4index Umatrix
                # check for imaginary matrix elements:
                if (abs(Umat.Ufull.imag)>0.0001).any():
                    MPI.report("WARNING: complex interaction matrix!! Ignoring imaginary part for the moment!")
                    MPI.report("If you want to change this, look into Wien2k/Solver_MultiBand.py")
                self.U4ind = Umat.Ufull.real
    
            # this will be changed for arbitrary irep:
            # use only one subgroup of orbitals?
            if not (irep is None):
                #print irep, dimreps
                assert not (dimreps is None), "Dimensions of the representatives are missing!"
                assert Norb==dimreps[irep-1],"Dimensions of dimrep and Norb do not fit!"
                for ii in range(irep-1):
                    self.offset += dimreps[ii]

               

        else:
            if ((U_interact==None)and(J_Hund==None)):
                MPI.report("For Kanamori representation, give U and J!!")
                assert 0
            self.U  = numpy.zeros([Norb,Norb],numpy.float_)
            self.Up = numpy.zeros([Norb,Norb],numpy.float_)
	    for i in range(Norb):
		for j in range(Norb):
		    if (i==j):
		        self.Up[i,i] = U_interact + 2.0*J_Hund
		    else:
			self.Up[i,j] = U_interact
			self.U[i,j]  = U_interact - J_Hund


        if (GFStruct):
            assert map, "give also the mapping!"
            self.map = map
        else:
            # standard GFStruct and map
            GFStruct = [ ('%s'%(ud),[n for n in range(Norb)]) for ud in ['up','down'] ]
            self.map = {'up' : ['up' for v in range(self.Norb)], 'down' : ['down' for v in range(self.Norb)]}

        #print GFStruct,self.map
        
        if (use_spinflip==False):
            Hamiltonian = self.__setHamiltonian_density()
        else:
            if (useMatrix):
                Hamiltonian = self.__setfullHamiltonian_Slater()
            else:
                Hamiltonian = self.__setfullHamiltonian_Kanamori(J_Hund = J_Hund)

        Quantum_Numbers = self.__setQuantumNumbers(GFStruct)
    
        # Determine if there are only blocs of size 1:
        self.blocssizeone = True
        for ib in GFStruct:
            if (len(ib[1])>1): self.blocssizeone = False

       
        # now initialize the solver with the stuff given above:
        Solver.__init__(self,
                        Beta = Beta,
                        GFstruct = GFStruct,
                        H_Local = Hamiltonian,
                        Quantum_Numbers = Quantum_Numbers )

        #self.SetGlobalMoves(deg_orbs)

        self.N_Cycles  = 10000
        self.Nmax_Matrix = 100
        self.N_Time_Slices_Delta= 10000
        #if ((len(GFStruct)==2*Norb) and (use_spinflip==False)): 
        if ((self.blocssizeone) and (use_spinflip==False)):
            self.Use_Segment_Picture = True
        else:
            self.Use_Segment_Picture = False
    def convert_bands_input(self,BandsSubGrp = 'SumK_LDA_Bands'):
        """
        Converts the input for momentum resolved spectral functions, and stores it in BandsSubGrp in the
        HDF5.
        """

        if not (MPI.IS_MASTER_NODE()): return

        self.BandsSubGrp = BandsSubGrp
        MPI.report("Reading bands input from %s..."%self.Band_file)

        R = Read_Fortran_File(self.Band_file)
        try:
            Nk = int(R.next())

            # read the list of N_Orbitals for all k points
            N_Orbitals = [ [0 for isp in range(self.Nspinblocs)] for ik in xrange(Nk)]
            for isp in range(self.Nspinblocs):
                for ik in xrange(Nk):
                    N_Orbitals[ik][isp] = int(R.next())

            # Initialise the projectors:
            Proj_Mat = [ [ [numpy.zeros([self.corr_shells[icrsh][3], N_Orbitals[ik][isp]], numpy.complex_) 
                            for icrsh in range (self.N_corr_shells)] 
                           for isp in range(self.Nspinblocs)] 
                         for ik in range(Nk) ]

            # Read the projectors from the file:
            for ik in xrange(Nk):
                for icrsh in range(self.N_corr_shells):
                    no = self.corr_shells[icrsh][3]
                    # first Real part for BOTH spins, due to conventions in dmftproj:
                    for isp in range(self.Nspinblocs):
                        for i in xrange(no):
                            for j in xrange(N_Orbitals[ik][isp]):
                                Proj_Mat[ik][isp][icrsh][i,j] = R.next()
                    # now Imag part:
                    for isp in range(self.Nspinblocs):
                        for i in xrange(no):
                            for j in xrange(N_Orbitals[ik][isp]):
                                Proj_Mat[ik][isp][icrsh][i,j] += 1j * R.next()

            Hopping = [ [numpy.zeros([N_Orbitals[ik][isp],N_Orbitals[ik][isp]],numpy.complex_) 
                         for isp in range(self.Nspinblocs)] for ik in xrange(Nk) ]
         	    
            # Grab the H
            # we use now the convention of a DIAGONAL Hamiltonian!!!!
            for isp in range(self.Nspinblocs):
                for ik in xrange(Nk) :
                    no = N_Orbitals[ik][isp]
                    for i in xrange(no):
                        Hopping[ik][isp][i,i] = R.next() * self.EnergyUnit

            # now read the partial projectors:
            N_parproj = [int(R.next()) for i in range(self.N_shells)]
            # Initialise P, here a double list of matrices:
            Proj_Mat_pc = [ [ [ [numpy.zeros([self.shells[ish][3], N_Orbitals[ik][isp]], numpy.complex_) 
                                 for ir in range(N_parproj[ish])]
                                for ish in range (self.N_shells) ]
                              for isp in range(self.Nspinblocs) ]
                            for ik in range(Nk) ]


            for ish in range(self.N_shells):
               
                for ik in xrange(Nk):
                    for ir in range(N_parproj[ish]):
                        for isp in range(self.Nspinblocs):
                                    
                            for i in xrange(self.shells[ish][3]):    # read real part:
                                for j in xrange(N_Orbitals[ik][isp]):
                                    Proj_Mat_pc[ik][isp][ish][ir][i,j] = R.next()
                            
                            for i in xrange(self.shells[ish][3]):    # read imaginary part:
                                for j in xrange(N_Orbitals[ik][isp]):
                                    Proj_Mat_pc[ik][isp][ish][ir][i,j] += 1j * R.next()

        except StopIteration : # a more explicit error if the file is corrupted.
            raise "SumK_LDA : reading file HMLT_file failed!"

        R.close()
        # reading done!

        #-----------------------------------------
        # Store the input into HDF5:
        ar = HDF_Archive(self.HDFfile,'a')
        if not (self.BandsSubGrp in ar): ar.create_group(self.BandsSubGrp) 
        # The subgroup containing the data. If it does not exist, it is created.
        # If it exists, the data is overwritten!!!
        thingstowrite = ['Nk','N_Orbitals','Proj_Mat','Hopping','N_parproj','Proj_Mat_pc']
        for it in thingstowrite: exec "ar['%s']['%s'] = %s"%(self.BandsSubGrp,it,it)

        #ar[self.BandsSubGrp]['Nk'] = Nk
        #ar[self.BandsSubGrp]['N_Orbitals'] = N_Orbitals
        #ar[self.BandsSubGrp]['Proj_Mat'] = Proj_Mat
        #self.Proj_Mat = Proj_Mat
        #self.N_Orbitals = N_Orbitals
        #self.Nk = Nk
        #self.Hopping = Hopping
        del ar
Beispiel #27
0
def Dichotomy(Function, xinit,yvalue,Precision_on_y,Delta_x, MaxNbreLoop=1000, xname="", yname="",verbosity=1):
    """
    Solver Function(x) = yvalue.
    
    Arguments :
      - Function : function (real valued) to be solved by dichotomy
      - xinit : Init value for x. On success, returns the new value of x
      - yvalue : 
      - precision : calculation stops for abs(f(x) - yvalue)<precision
      - MaxNbreLoop : maximum number of loops before failure. Default is 1000
      - xname, yname : name of the variable x, y for the report
      - verbosity : verbosity level.

    Returns :
       - A tuple (x,y). x is the value found, y is f(x).
       - (None,None) if the calculation failed.

    """
    def sign(x):
        if x>0.0 : return 1
        if x<0.0 : return -1
        return 0
    
    MPI.report("Dichotomy adjustment of %(xname)s to obtain %(yname)s = %(yvalue)f +/- %(Precision_on_y)f"%locals() )
    PR = "    "
    if xname=="" or yname==""  : verbosity = max(verbosity,1)
    x=xinit;Delta_x= abs(Delta_x)

    # First find the bounds
    y1 = Function(x)
    eps = sign(y1-yvalue)
    x1=x;y2=y1;x2=x1
    nbre_loop=0
    while (nbre_loop<= MaxNbreLoop) and (y2-yvalue)*eps>0 and abs(y2-yvalue)>Precision_on_y :
        nbre_loop +=1
        x2 -=  eps*Delta_x
        y2 = Function(x2)
        if xname!="" and verbosity>2:
            MPI.report("%(PR)s%(xname)s = %(x2)f  \n%(PR)s%(yname)s = %(y2)f"%locals())

    MPI.report("%(PR)s%(x1)f < %(xname)s < %(x2)f"%locals())
    MPI.report("%(PR)s%(y1)f < %(yname)s < %(y2)f"%locals())

    # Now mu is between mu1 and mu2
    yfound = y2
    # We found bounds. What if the next loop is never run ?
    # i.e. x1 or x2 are close to the solution
    # we have to know which one is the best .... 
    if abs(y1-yvalue)< abs(y2-yvalue) :
        x=x1
    else:
        x=x2
        
    #Now let's refine our mu....
    while (nbre_loop<= MaxNbreLoop) and (abs(yfound-yvalue)>Precision_on_y) :
        nbre_loop +=1
        x = x1  + (x2 - x1) * (yvalue - y1)/(y2-y1)
        yfound = Function(x)
        if (y1-yvalue)*(yfound - yvalue)>0 : 
            x1 = x; y1=yfound
        else :
            x2= x;y2=yfound;
        if verbosity>2 :
            MPI.report("%(PR)s%(x1)f < %(xname)s < %(x2)f"%locals())
            MPI.report("%(PR)s%(y1)f < %(yname)s < %(y2)f"%locals())
    if abs(yfound - yvalue) < Precision_on_y :
        if verbosity>0:
            MPI.report("%(PR)s%(xname)s found in %(nbre_loop)d iterations : "%locals())
            MPI.report("%(PR)s%(yname)s = %(yfound)f;%(xname)s = %(x)f"%locals())
        return (x,yfound)
    else : 
        if verbosity>0:
            MPI.report("%(PR)sFAILURE to adjust %(xname)s  to the value %(yvalue)f after %(nbre_loop)d iterations."%locals())
        return (None,None)
Beispiel #28
0
    def SetDoubleCounting(self, densmat, U_interact, J_Hund, orb=0, useDCformula=0, useval=None):
        """Sets the double counting term for inequiv orbital orb
           useDCformula=0: LDA+U FLL double counting, useDCformula=1: Held's formula. 
           useDCformula=2: AMF
           Be sure that you use the correct interaction Hamiltonian!"""

        # if (not hasattr(self,"dc_imp")): self.__initDC()

        dm = [{} for i in xrange(self.N_corr_shells)]
        for i in xrange(self.N_corr_shells):
            l = self.corr_shells[i][3]  # *(1+self.corr_shells[i][4])
            for j in xrange(len(self.GFStruct_corr[i])):
                dm[i]["%s" % self.GFStruct_corr[i][j][0]] = numpy.zeros([l, l], numpy.float_)

        for icrsh in xrange(self.N_corr_shells):

            iorb = self.shellmap[icrsh]  # iorb is the index of the inequivalent shell corresponding to icrsh

            if iorb == orb:
                # do this orbital

                l = self.corr_shells[icrsh][3]  # *(1+self.corr_shells[icrsh][4])
                for j in xrange(len(self.GFStruct_corr[icrsh])):
                    self.dc_imp[icrsh]["%s" % self.GFStruct_corr[icrsh][j][0]] = numpy.identity(l, numpy.float_)

                # transform the CTQMC blocks to the full matrix:
                for ibl in range(len(self.GFStruct_Solver[iorb])):
                    for i in range(len(self.GFStruct_Solver[iorb][ibl][1])):
                        for j in range(len(self.GFStruct_Solver[iorb][ibl][1])):
                            bl = self.GFStruct_Solver[iorb][ibl][0]
                            ind1 = self.GFStruct_Solver[iorb][ibl][1][i]
                            ind2 = self.GFStruct_Solver[iorb][ibl][1][j]
                            dm[icrsh][self.mapinv[iorb][bl]][ind1, ind2] = densmat[bl][
                                i, j
                            ].real  # only real part relevant for trace

                M = self.corr_shells[icrsh][3]
                Ncr = {}
                Ncrtot = 0.0
                a_list = [a for a, al in self.GFStruct_corr[icrsh]]
                for bl in a_list:
                    Ncr[bl] = dm[icrsh][bl].trace()
                    Ncrtot += Ncr[bl]

                # average the densities if there is no SP:
                if self.SP == 0:
                    for bl in a_list:
                        Ncr[bl] = Ncrtot / len(a_list)
                # correction for SO: we have only one block in this case, but in DC we need N/2
                elif self.SP == 1 and self.SO == 1:
                    for bl in a_list:
                        Ncr[bl] = Ncrtot / 2.0

                if useval is None:

                    if useDCformula == 0:
                        self.DCenerg[icrsh] = U_interact / 2.0 * Ncrtot * (Ncrtot - 1.0)
                        for bl in a_list:
                            Uav = U_interact * (Ncrtot - 0.5) - J_Hund * (Ncr[bl] - 0.5)
                            self.dc_imp[icrsh][bl] *= Uav
                            self.DCenerg[icrsh] -= J_Hund / 2.0 * (Ncr[bl]) * (Ncr[bl] - 1.0)
                            MPI.report("DC for shell %(icrsh)i and block %(bl)s = %(Uav)f" % locals())
                    elif useDCformula == 1:
                        self.DCenerg[icrsh] = (
                            (U_interact + J_Hund * (2.0 - (M - 1)) / (2 * M - 1)) / 2.0 * Ncrtot * (Ncrtot - 1.0)
                        )
                        for bl in a_list:
                            # Held's formula, with U_interact the interorbital onsite interaction
                            Uav = (U_interact + J_Hund * (2.0 - (M - 1)) / (2 * M - 1)) * (Ncrtot - 0.5)
                            self.dc_imp[icrsh][bl] *= Uav
                            MPI.report("DC for shell %(icrsh)i and block %(bl)s = %(Uav)f" % locals())
                    elif useDCformula == 2:
                        self.DCenerg[icrsh] = 0.5 * U_interact * Ncrtot * Ncrtot
                        for bl in a_list:
                            # AMF
                            Uav = U_interact * (Ncrtot - Ncr[bl] / M) - J_Hund * (Ncr[bl] - Ncr[bl] / M)
                            self.dc_imp[icrsh][bl] *= Uav
                            self.DCenerg[icrsh] -= (U_interact + (M - 1) * J_Hund) / M * 0.5 * Ncr[bl] * Ncr[bl]
                            MPI.report("DC for shell %(icrsh)i and block %(bl)s = %(Uav)f" % locals())

                    # output:
                    MPI.report("DC energy for shell %s = %s" % (icrsh, self.DCenerg[icrsh]))

                else:

                    a_list = [a for a, al in self.GFStruct_corr[icrsh]]
                    for bl in a_list:
                        self.dc_imp[icrsh][bl] *= useval

                    self.DCenerg[icrsh] = useval * Ncrtot

                    # output:
                    MPI.report("DC for shell %(icrsh)i = %(useval)f" % locals())
                    MPI.report("DC energy = %s" % self.DCenerg[icrsh])