コード例 #1
0
ファイル: aseinterface.py プロジェクト: pastewka/hotbit
    def get_band_energies(self, kpts=None, shift=True, rs='kappa', h1=False):
        '''
        Return band energies for explicitly given list of k-points.

        parameters:
        ===========
        kpts:      list of k-points; e.g. kpts=[(0,0,0),(pi/2,0,0),(pi,0,0)]
                   k- or kappa-points, depending on parameter rs.
                   if None, return for all k-points in the calculation
        shift:     shift zero to the Fermi-level
        rs:        use 'kappa'- or 'k'-points in reciprocal space
        h1:        Add Coulomb part to hamiltonian matrix. Required for consistent use of SCC.
        '''
        if kpts == None:
            e = self.st.e * Hartree
        else:
            if rs == 'k':
                klist = k_to_kappa_points(kpts, self.el.atoms)
            elif rs == 'kappa':
                klist = kpts
            e = self.st.get_band_energies(klist, h1) * Hartree

        if shift:
            return e - self.get_fermi_level()
        else:
            return e
コード例 #2
0
ファイル: aseinterface.py プロジェクト: pekkosk/hotbit
    def get_band_energies(self, kpts=None, shift=True, rs="kappa", h1=False):
        """
        Return band energies for explicitly given list of k-points.

        parameters:
        ===========
        kpts:      list of k-points; e.g. kpts=[(0,0,0),(pi/2,0,0),(pi,0,0)]
                   k- or kappa-points, depending on parameter rs.
                   if None, return for all k-points in the calculation
        shift:     shift zero to the Fermi-level
        rs:        use 'kappa'- or 'k'-points in reciprocal space
        h1:        Add Coulomb part to hamiltonian matrix. Required for consistent use of SCC.
        """
        if kpts == None:
            e = self.st.e * Hartree
        else:
            if rs == "k":
                klist = k_to_kappa_points(kpts, self.el.atoms)
            elif rs == "kappa":
                klist = kpts
            e = self.st.get_band_energies(klist, h1) * Hartree

        if shift:
            return e - self.get_fermi_level()
        else:
            return e
コード例 #3
0
ファイル: states.py プロジェクト: molguin-qc/hotbit
 def setup_k_sampling(self,kpts,physical=True,rs='kappa'):
     '''
     Setup the k-point sampling and their weights.
     
     @param kpts: 3-tuple: number of k-points in different directions
                  list of 3-tuples: k-points given explicitly
     @param physical: No meaning for infinite periodicities. For physically
                  periodic systems only certain number of k-points are allowed.
                  (like wedge of angle 2*pi/N, only number of k-points that 
                  divides N, is physically allowed). If physical=False,
                  allow interpolation of this k-sampling.
     rs:          use 'kappa'- or 'k'-point sampling
     '''
     if (len(kpts)==1 or isinstance(kpts,tuple) and kpts!=(1,1,1)) and self.calc.get('width')<1E-10:
         raise AssertionError('With k-point sampling width must be>0!')
         
     M = self.calc.el.get_number_of_transformations()
     if isinstance(kpts,tuple):
         table = self.calc.el.atoms.container.get_table()
         # set up equal-weighted and spaced k-point mesh
         if 0 in kpts:
             raise AssertionError('Each direction must have at least one k-point! (Gamma-point)')
         
         kl=[]
         for i in range(3):
             if M[i]==np.Inf:
                 # arbitrary sampling is allowed
                 spacing = 2*pi/kpts[i]
                 kl.append( np.linspace(-pi+spacing/2,pi-spacing/2,kpts[i]) )
             else:
                 # TODO: choose the closest number of k-points if
                 # sampling should be physical
                 # first calculate possible numer of k-points, then
                 # select the ones closest to the desired one
                 # nks = M/divisors(M) 
                 # nk1 = nks[abs(nks-nk).argmin()]                  
                 # discrete, well-defined sampling; any k-point is not allowed 
                 if kpts[i] not in mix.divisors(M[i]) and physical:
                     print 'Allowed k-points for direction',i,'are',mix.divisors(M[i])
                     raise Warning('Non-physical k-point sampling! ')
                 else:
                     kl.append( np.linspace(0,2*pi-2*pi/kpts[i],kpts[i]) )
                     
         k=[]    
         wk=[]
         kpt_indices = []
         nk0 = np.prod(kpts)
         for a in range(kpts[0]):
             for b in range(kpts[1]):
                 for c in range(kpts[2]):
                     newk = np.array([kl[0][a], kl[1][b], kl[2][c]])
                     newind = (a,b,c)
                     one_equivalent = False
                     for i in range(3):
                         if 'equivalent' in table[i]:
                             if one_equivalent:
                                 raise NotImplementedError('Surprising type of new symmetry; reconsider implementation.')
                             one_equivalent = True
                             n = table[i]['equivalent'] # symmetry op i is equivalent to tuple n
                             assert n[i]==0
                             newk[i] = newk[i] + 1.0*np.dot(n,newk)/M[i]
                             
                             
                     inv_exists = False
                     # if newk's inverse exists, increase its weight by default
                     for ik, oldk in enumerate(k):
                         if np.linalg.norm(oldk+newk)<1E-10: 
                             inv_exists = True
                             wk[ik]+=1.0/nk0
                     # newk's inverse does not exist; make new k-point
                     if not inv_exists:                        
                         k.append( newk )
                         wk.append( 1.0/nk0 ) 
                         kpt_indices.append( newind )
         nk=len(k)            
         k=np.array(k)
         wk=np.array(wk)
     else:
         # work with a given set of k-points
         nk=len(kpts)
         if rs=='k':
             k = k_to_kappa_points(kpts,self.calc.el.atoms)
         else:
             k=np.array(kpts)
         wk=np.ones(nk)/nk
         kl=None
         kpt_indices=[]
         
     # now sampling is set up. Check consistency.
     pbc = self.calc.el.get_pbc()
     self.kpt_indices = np.array(kpt_indices)
     for i in range(3):
         for kp in k:
             if kp[i]>1E-10 and not pbc[i]:
                 raise AssertionError('Do not set (non-zero) k-points in non-periodic direction!')
     
     return nk, k, kl, wk