TABLE OF CONTENTS


ABINIT/m_occ [ Modules ]

[ Top ] [ Modules ]

NAME

 m_occ

FUNCTION

  Low-level functions for occupation factors.

COPYRIGHT

  Copyright (C) 2008-2024 ABINIT group (XG, AF)
  This file is distributed under the terms of the
  GNU General Public License, see ~abinit/COPYING
  or http://www.gnu.org/copyleft/gpl.txt .

SOURCE

16 #if defined HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19 
20 #include "abi_common.h"
21 
22 module m_occ
23 
24  use defs_basis
25  use m_errors
26  use m_abicore
27  use m_splines
28  use m_xmpi
29  use m_extfpmd
30 
31  use m_time,         only : timab, cwtime, cwtime_report
32  use m_fstrings,     only : sjoin, itoa
33 
34  implicit none
35 
36  private

m_abinit/getnel [ Functions ]

[ Top ] [ Functions ]

NAME

 getnel

FUNCTION

 Option = 1:
   Get the total number of electrons nelect, given a trial fermienergy fermie.
   For this, compute new occupation numbers at each k point,
   from eigenenergies eigen, according to the
   smearing scheme defined by occopt (and smearing width tsmear or tphysel).

 Option = 2:
   Compute and output the smeared density of states, and the integrated density
   of states, then write these data

 Warning: this routine assumes checks have been done in the calling
 routine, and that the values of the arguments are sensible

 NOTE
 In order to speed the calculation, it would be easy to
 compute the entropy only when the fermi energy is well converged

INPUTS

 dosdeltae= DOS delta of Energy (needed if Option=2)
 eigen(mband*nkpt*nsppol)=eigenvalues (input or init to large number), hartree
 fermie= fermi energy/ fermi energy for excited electrons if occopt = 9 (Hartree) ! CP description modified
 fermih= fermi energy for excited holes (Hartree)
 maxocc=asymptotic maximum occupation number per band
 mband=maximum number of bands
 nband(nkpt*nsppol)=number of bands at each k point
 nkpt=number of k points
 nsppol=1 for unpolarized, 2 for spin-polarized
 occopt=option for occupancies, or re-smearing scheme if dblsmr /= 0
 option=see above
 tphysel="physical" electronic temperature with FD occupations
 tsmear=smearing width (or temperature)
 unitdos=unit number of output of the DOS. Not needed if option==1
 wtk(nkpt)=k point weights
 iB1, iB2 = band min and max between which to calculate the number of electrons
 extfpmd_nbdbuf=Number of bands in the buffer to converge scf cycle with extfpmd models

OUTPUT

 doccde(mband*nkpt*nsppol)=derivative of occupancies wrt the energy for each band and k point.
 entropy= entropy associated with the smearing (adimensional)
 nelect=number of electrons per unit cell
 occ(mband*nkpt*nsppol)=occupancies for each band and k point.

NOTES

 Modified beginning 23/11/2000 by MV
 Add an additional smearing on top of a FD type, in order to improve k-point
 convergence: tsmear = 0 and tphysel ~= 2.e-3 corresponds to a small (300K)
 temperature on the electrons insufficient for convergence purposes.
 Feed re-smeared "Dirac delta" to the rest of ABINIT with only one parameter,
 tphysel, which is the physical temperature.
 encorr = correction to energy for terms of order tsmear^2:

       $  E_{phys} = E_{free} - encorr*(E_{int}-E_{free}) + O(tsmear^3)  $

SOURCE

123 subroutine getnel(doccde, dosdeltae, eigen, entropy, fermie, fermih, maxocc, mband, nband, &
124                   nelect, nkpt, nsppol, occ, occopt, option, tphysel, tsmear, unitdos, wtk, &
125                   iB1, iB2, extfpmd_nbdbuf) ! optional parameters
126 
127 !Arguments ------------------------------------
128 !scalars
129  integer,intent(in) :: mband,nkpt,nsppol,occopt,option,unitdos
130  real(dp),intent(in) :: dosdeltae,fermie,fermih,maxocc,tphysel,tsmear
131  real(dp),intent(out) :: entropy,nelect
132 !arrays
133  integer,intent(in) :: nband(nkpt*nsppol)
134  real(dp),intent(in) :: eigen(mband*nkpt*nsppol),wtk(nkpt)
135  real(dp),intent(out) :: doccde(mband*nkpt*nsppol)
136  real(dp),intent(inout) :: occ(mband*nkpt*nsppol)
137  integer, intent(in), optional:: iB1, iB2 !! CP: added optional arguments to get number of electrons between bands iB1 and iB2
138  integer, intent(in), optional :: extfpmd_nbdbuf
139  !! Used only when occopt = 9
140 
141 !Local variables-------------------------------
142 ! nptsdiv2 is the number of integration points, divided by 2.
143 ! tratio  = ratio tsmear/tphysel for convoluted smearing function
144 ! save values so we can impose recalculation of smdfun when
145 ! the smearing or electronic temperature change between datasets
146 ! corresponds roughly to delta_FD (maxFDarg) = 1.0d-100
147 !
148 ! return fermi-dirac smearing function analytically
149 ! real(dp) :: smdFD
150 ! smdFD (tt) = 1.0_dp / (exp(-tt/2.0_dp) + exp(tt/2.0_dp))**2
151 !scalars
152  integer,parameter :: prtdos1=1
153  integer :: iband,iene,ikpt,index,index_tot,index_start,isppol,nene,nptsdiv2
154  integer :: low_band_index, high_band_index, number_of_bands
155  real(dp) :: buffer,deltaene,dosdbletot,doshalftot,dostot, wk
156  real(dp) :: enemax,enemin,enex,intdostot,limit,tsmearinv
157  !real(dp) :: cpu, wall, gflops
158  character(len=500) :: msg
159 !arrays
160  real(dp),allocatable :: entfun(:,:),occfun(:,:)
161  real(dp),allocatable :: smdfun(:,:),xgrid(:)
162  real(dp),allocatable :: arg(:),derfun(:),dos(:),dosdble(:),doshalf(:),ent(:)
163  real(dp),allocatable :: intdos(:)
164  real(dp),allocatable :: occ_tmp(:),ent_tmp(:),doccde_tmp(:)
165 
166 ! *************************************************************************
167 
168  !call cwtime(cpu, wall, gflops, "start")
169 
170  if (option/=1 .and. option/=2)then
171    ABI_BUG(sjoin('Option must be either 1 or 2. It is:', itoa(option)))
172  end if
173 
174  ! Initialize the occupation function and generalized entropy function,
175  ! at the beginning, or if occopt changed
176 
177  if (occopt==9) then
178     low_band_index  = iB1
179     high_band_index = iB2
180     number_of_bands = (iB2-iB1+1)*nkpt*nsppol
181  else
182     low_band_index  = 1
183     high_band_index = nband(1)
184     number_of_bands = sum(nband(:))
185  end if
186  ABI_MALLOC(occ_tmp,(number_of_bands))
187  ABI_MALLOC(ent_tmp,(number_of_bands))
188  ABI_MALLOC(doccde_tmp,(number_of_bands))
189 
190  ! Just get the number nptsdiv2 and allocate entfun, occfun, smdfun and xgrid accordingly
191  nptsdiv2 = nptsdiv2_def
192 
193  ABI_MALLOC(entfun,(-nptsdiv2:nptsdiv2,2))
194  ABI_MALLOC(occfun,(-nptsdiv2:nptsdiv2,2))
195  ABI_MALLOC(smdfun,(-nptsdiv2:nptsdiv2,2))
196  ABI_MALLOC(xgrid,(-nptsdiv2:nptsdiv2))
197 
198  call init_occ_ent(entfun, limit, nptsdiv2, occfun, occopt, option, smdfun, tphysel, tsmear, tsmearinv, xgrid)
199  ! The initialisation of occfun and entfun is done
200 
201 !---------------------------------------------------------------------
202 
203  ! write(std_out,*)' getnel : debug  tphysel, tsmear = ', tphysel, tsmear
204  ABI_MALLOC(arg,(number_of_bands))
205  ABI_MALLOC(derfun,(number_of_bands))
206  ABI_MALLOC(ent,(number_of_bands))
207  if (option==1) then
208    ! normal evaluation of occupations and entropy
209 
210    index = 0
211    index_tot = 0
212    do isppol=1,nsppol
213       do ikpt=1,nkpt
214          if (occopt == 2) high_band_index=nband(ikpt+nkpt*(isppol-1))
215          do iband=low_band_index,high_band_index
216             index = index + 1
217             if (tsmear==0) then
218                arg(index) = sign(huge_tsmearinv,fermie-eigen(index_tot + iband))
219             else
220                arg(index)=(fermie-eigen(index_tot + iband))*tsmearinv
221             end if
222          end do
223          index_tot = index_tot + nband(ikpt+nkpt*(isppol-1))
224       end do
225    end do
226 
227    ! MG TODO: This part is expensive for dense k-meshes
228    ! Compute the values of the occupation function, and the entropy function
229    ! Note: splfit also takes care of the points outside of the interval,
230    ! and assign to them the value of the closest extremal point,
231    ! which is what is needed here.
232 
233    call splfit(xgrid, doccde_tmp, occfun, 1, arg, occ_tmp, (2*nptsdiv2+1), number_of_bands)
234    call splfit(xgrid, derfun, entfun, 0, arg, ent, (2*nptsdiv2+1), number_of_bands)
235 
236    ! Normalize occ and ent, and sum number of electrons and entropy
237    ! Use different loops for nelect and entropy because bantot may be quite large in the EPH code
238    ! when we use very dense k-meshes.
239    
240    ! Manage number of bands in buffer for extfpmd calculation, when extfpmd_nbdbuf not 0.
241    ! Set occupation and entropy of buffered bands to zero.
242    if(present(extfpmd_nbdbuf)) then
243      index=0
244      index_tot=0
245      do isppol=1,nsppol
246         do ikpt=1,nkpt
247            if (occopt == 2) high_band_index=nband(ikpt+nkpt*(isppol-1))
248            do iband=low_band_index,high_band_index
249               index=index+1
250               if (iband>high_band_index-extfpmd_nbdbuf) then
251                 ent(index)     = zero
252                 occ_tmp(index) = zero
253               end if
254            end do
255            index_tot=index_tot+nband(ikpt+nkpt*(isppol-1))
256         end do
257      end do
258    end if
259 
260    nelect=zero; entropy=zero
261    index=0
262    index_tot = 0
263    do isppol=1,nsppol
264       do ikpt=1,nkpt
265          wk = wtk(ikpt)
266          if (occopt == 2) high_band_index=nband(ikpt+nkpt*(isppol-1))
267          do iband=low_band_index,high_band_index
268             index = index + 1
269             ent(index)                = ent(index)*maxocc
270             occ(iband + index_tot)    = occ_tmp(index)*maxocc
271             doccde(iband + index_tot) = -doccde_tmp(index)*maxocc*tsmearinv
272             entropy                   = entropy + wk*ent(index)
273             nelect                    = nelect + wk*occ(iband + index_tot)
274          end do
275          index_tot = index_tot + nband(ikpt+nkpt*(isppol-1))
276       end do
277    end do
278 
279    !write(std_out,*) ' getnel : debug   wtk, occ, eigen = ', wtk, occ, eigen
280    !write(std_out,*)xgrid(-nptsdiv2),xgrid(nptsdiv2)
281    !write(std_out,*)'fermie',fermie
282    !do ii=1,bantot
283    !write(std_out,*)ii,arg(ii),doccde(ii)
284    !end do
285    !write(std_out,*)'eigen',eigen(:)
286    !write(std_out,*)'arg',arg(:)
287    !write(std_out,*)'occ',occ(:)
288    !write(std_out,*)'nelect',nelect
289 
290  else if (option==2) then
291    ! evaluate DOS for smearing, half smearing, and double.
292 
293    buffer=limit/tsmearinv*.5_dp
294 
295    ! A Similar section is present is dos_calcnwrite. Should move all DOS stuff to m_ebands
296    ! Choose the lower and upper energies
297    enemax=maxval(eigen(1:number_of_bands))+buffer
298    enemin=minval(eigen(1:number_of_bands))-buffer
299 
300    ! Extend the range to a nicer value
301    enemax=0.1_dp*ceiling(enemax*10._dp)
302    enemin=0.1_dp*floor(enemin*10._dp)
303 
304    ! Choose the energy increment
305    if(abs(dosdeltae)<tol10)then
306      deltaene=0.001_dp
307      if(prtdos1>=2)deltaene=0.0005_dp ! Higher resolution possible (and wanted) for tetrahedron
308    else
309      deltaene=dosdeltae
310    end if
311    nene=nint((enemax-enemin)/deltaene)+1
312 
313    ! Write the header of the DOS file, and also decides the energy range and increment
314    call dos_hdr_write(deltaene,eigen,enemax,enemin,fermie,fermih,mband,nband,nene,&
315            nkpt,nsppol,occopt,prtdos1,tphysel,tsmear,unitdos)
316    !ABI_MALLOC(dos,(bantot))
317    !ABI_MALLOC(dosdble,(bantot))
318    !ABI_MALLOC(doshalf,(bantot))
319    !ABI_MALLOC(intdos,(bantot))
320    ABI_MALLOC(dos,(number_of_bands))
321    ABI_MALLOC(dosdble,(number_of_bands))
322    ABI_MALLOC(doshalf,(number_of_bands))
323    ABI_MALLOC(intdos,(number_of_bands))
324 
325    do isppol=1,nsppol
326 
327      if (nsppol==2) then
328        if(isppol==1) write(msg,'(a,16x,a)')  '#','Spin-up DOS'
329        if(isppol==2) write(msg,'(2a,16x,a)')  ch10,'#','Spin-dn DOS '
330        call wrtout(unitdos,msg)
331      end if
332      index_start=0
333      if(isppol==2)then
334        do ikpt=1,nkpt
335           if (occopt == 2) high_band_index = nband(ikpt + nkpt*(isppol - 1))
336           index_start=index_start + high_band_index - low_band_index + 1
337        end do
338      end if
339 
340      enex=enemin
341      do iene=1,nene
342 
343        ! Compute the arguments of the dos and occupation function
344        arg(:)=(enex-eigen(1:number_of_bands))*tsmearinv
345 
346        call splfit(xgrid,derfun,smdfun,0,arg,dos,(2*nptsdiv2+1),number_of_bands)
347        call splfit(xgrid,derfun,occfun,0,arg,intdos,(2*nptsdiv2+1),number_of_bands)
348 
349        ! Also compute the dos with tsmear halved and doubled
350        arg(:)=arg(:)*2.0_dp
351        !call splfit(xgrid,derfun,smdfun,0,arg,doshalf,(2*nptsdiv2+1),bantot)
352        call splfit(xgrid,derfun,smdfun,0,arg,doshalf,(2*nptsdiv2+1),number_of_bands)
353 
354        ! Since arg was already doubled, must divide by four
355        arg(:)=arg(:)*0.25_dp
356        !call splfit(xgrid,derfun,smdfun,0,arg,dosdble,(2*nptsdiv2+1),bantot)
357        call splfit(xgrid,derfun,smdfun,0,arg,dosdble,(2*nptsdiv2+1),number_of_bands)
358 
359        ! Now, accumulate the contribution from each eigenenergy
360        dostot=zero
361        intdostot=zero
362        doshalftot=zero
363        dosdbletot=zero
364        index=index_start
365 
366        do ikpt=1,nkpt
367           if (occopt == 2) high_band_index=nband(ikpt+nkpt*(isppol-1))
368           do iband=low_band_index,high_band_index
369              index=index+1
370              dostot=dostot+wtk(ikpt)*maxocc*dos(index)*tsmearinv
371              intdostot=intdostot+wtk(ikpt)*maxocc*intdos(index)
372              doshalftot=doshalftot+wtk(ikpt)*maxocc*doshalf(index)*tsmearinv*2.0_dp
373              dosdbletot=dosdbletot+wtk(ikpt)*maxocc*dosdble(index)*tsmearinv*0.5_dp
374           end do
375        end do
376 
377        ! Print the data for this energy
378        write(unitdos, '(f8.3,2f14.6,2f14.3)' )enex,dostot,intdostot,doshalftot,dosdbletot
379 
380        enex=enex+deltaene
381      end do ! iene
382    end do ! isppol
383 
384    ABI_FREE(dos)
385    ABI_FREE(dosdble)
386    ABI_FREE(doshalf)
387    ABI_FREE(intdos)
388 
389    ! MG: It does not make sense to close the unit here since the routines
390    ! did not open the file here!
391    ! Close the DOS file
392    close(unitdos)
393  end if
394 
395  ABI_FREE(arg)
396  ABI_FREE(derfun)
397  ABI_FREE(ent)
398  ABI_FREE(entfun)
399  ABI_FREE(occfun)
400  ABI_FREE(smdfun)
401  ABI_FREE(xgrid)
402  ABI_FREE(occ_tmp)
403  ABI_FREE(doccde_tmp)
404  ABI_FREE(ent_tmp)
405 
406  !call cwtime_report(" getnel", cpu, wall, gflops, end_str=ch10)
407 
408 end subroutine getnel

m_occ/dos_hdr_write [ Functions ]

[ Top ] [ m_occ ] [ Functions ]

NAME

 dos_hdr_write

FUNCTION

 Write the header of the DOS files, for both smearing and tetrahedron methods.

INPUTS

 deltaene=increment of DOS energy arguments
 enemax=maximal value of the DOS energy argument
 enemin=minimal value of the DOS energy argument
 nene=number of DOS energy argument
 eigen(mband*nkpt*nsppol)=eigenvalues (input or init to large number), hartree
 fermie=fermi energy useful for band alignment...
 fermih= fermi energy of thermalized excited holes when occopt = 9
 mband=maximum number of bands
 nband(nkpt*nsppol)=number of bands at each k point
 nkpt=number of k points
 nsppol=1 for unpolarized, 2 for spin-polarized
 occopt=option for occupancies, or re-smearing scheme if dblsmr /= 0
 prtdos=1 for smearing technique, 2 or 3 for tetrahedron technique
 tphysel="physical" electronic temperature with FD occupations
 tsmear=smearing width (or temperature)
 unitdos=unit number of output of the DOS.

OUTPUT

   Only writing.

SOURCE

1844 subroutine dos_hdr_write(deltaene,eigen,enemax,enemin,fermie,fermih,mband,nband,nene,&
1845                          nkpt,nsppol,occopt,prtdos,tphysel,tsmear,unitdos)
1846 
1847 !Arguments ------------------------------------
1848 !scalars
1849  integer,intent(in) :: mband,nkpt,nsppol,occopt,prtdos,unitdos,nene
1850  ! CP modify
1851  real(dp),intent(in) :: fermie,fermih,tphysel,tsmear
1852  ! End CP modify
1853  real(dp),intent(in) :: deltaene,enemax,enemin
1854 !arrays
1855  integer,intent(in) :: nband(nkpt*nsppol)
1856  real(dp),intent(in) :: eigen(mband*nkpt*nsppol)
1857 
1858 !Local variables-------------------------------
1859 !scalars
1860  character(len=500) :: msg
1861 
1862 ! *************************************************************************
1863 
1864  ! Write the DOS file
1865  write(msg, '(7a,i2,a,i5,a,i4)' ) "#",ch10, &
1866   '# ABINIT package : DOS file  ',ch10,"#",ch10,&
1867   '# nsppol =',nsppol,', nkpt =',nkpt,', nband(1)=',nband(1)
1868  call wrtout(unitdos, msg)
1869 
1870  if (any(prtdos== [1,4])) then
1871    write(msg, '(a,i2,a,f6.3,a,f6.3,a)' )  &
1872     '# Smearing technique, occopt =',occopt,', tsmear=',tsmear,' Hartree, tphysel=',tphysel,' Hartree'
1873  else
1874    write(msg, '(a)' ) '# Tetrahedron method '
1875  end if
1876  call wrtout(unitdos, msg)
1877 
1878  if (mband*nkpt*nsppol>=3) then
1879    write(msg, '(a,3f8.3,2a)' )'# For identification : eigen(1:3)=',eigen(1:3),ch10,"#"
1880  else
1881    write(msg, '(a,3f8.3)' ) '# For identification : eigen=',eigen
1882    write(msg, '(3a)')trim(msg),ch10,"#"
1883  end if
1884  call wrtout(unitdos, msg)
1885 
1886  if (occopt == 9) then
1887     write(msg, '(a,f16.8, f16.8)' ) '# Fermi energy for electrons and holes ', fermie, fermih
1888  else
1889     write(msg, '(a,f16.8)' ) '# Fermi energy : ', fermie
1890  end if
1891  call wrtout(unitdos, msg)
1892 
1893  if (prtdos==1) then
1894    write(msg, '(5a)' ) "#",ch10,&
1895     '# The DOS (in electrons/Hartree/cell) and integrated DOS (in electrons/cell),',&
1896     ch10,'# as well as the DOS with tsmear halved and doubled, are computed,'
1897 
1898  else if (prtdos==2)then
1899    write(msg, '(3a)' ) "#",ch10,&
1900     '# The DOS (in electrons/Hartree/cell) and integrated DOS (in electrons/cell) are computed,'
1901 
1902  else if (any(prtdos == [3, 4])) then
1903    write(msg, '(5a)' ) "#",ch10,&
1904     '# The local DOS (in electrons/Hartree for one atomic sphere)',ch10,&
1905     '# and integrated local DOS (in electrons for one atomic sphere) are computed.'
1906 
1907  else if (prtdos==5)then
1908    write(msg, '(9a)' ) "#",ch10,&
1909    '# The spin component DOS (in electrons/Hartree/cell)',ch10,&
1910    '# and integrated spin component DOS (in electrons/cell) are computed.',ch10,&
1911    '# Remember that the wf are eigenstates of S_z and S^2, not S_x and S_y',ch10,&
1912    '#   so the latter will not always sum to 0 for paired electronic states.'
1913  end if
1914  call wrtout(unitdos, msg)
1915 
1916  write(msg, '(a,i5,a,a,a,f9.4,a,f9.4,a,f8.5,a,a,a)' )&
1917   '# at ',nene,' energies (in Hartree) covering the interval ',ch10,&
1918   '# between ',enemin,' and ',enemax,' Hartree by steps of ',deltaene,' Hartree.',ch10,"#"
1919  call wrtout(unitdos, msg)
1920 
1921  if (prtdos==1) then
1922    write(msg, '(a,a)' )&
1923     '#       energy        DOS       Integr. DOS   ','     DOS           DOS    '
1924    call wrtout(unitdos,msg)
1925 
1926    write(msg, '(a)' )&
1927     '#                                              (tsmear/2)    (tsmear*2) '
1928    call wrtout(unitdos,msg)
1929  else
1930    write(msg, '(a)' ) '#       energy        DOS '
1931  end if
1932 
1933 end subroutine dos_hdr_write

m_occ/init_occ_ent [ Functions ]

[ Top ] [ m_occ ] [ Functions ]

NAME

 init_occ_ent

FUNCTION

INPUTS

  argin(sizein)=description

OUTPUT

  argout(sizeout)=description

SOURCE

1008 subroutine init_occ_ent(entfun,limit,nptsdiv2,occfun,occopt,option,smdfun,tphysel,tsmear,tsmearinv,xgrid)
1009 
1010 !Arguments ------------------------------------
1011 !scalars
1012  integer,intent(in) :: occopt,option
1013  real(dp),intent(in) :: tphysel,tsmear
1014  integer,intent(inout) :: nptsdiv2
1015  real(dp),intent(out) :: limit,tsmearinv
1016  real(dp),intent(inout) :: entfun(-nptsdiv2:nptsdiv2,2),occfun(-nptsdiv2:nptsdiv2,2)
1017  real(dp),intent(inout) :: smdfun(-nptsdiv2:nptsdiv2,2),xgrid(-nptsdiv2:nptsdiv2)
1018 
1019 !Local variables-------------------------------
1020 !scalars
1021  integer :: algo,ii,jj,nconvd2
1022  integer :: nmaxFD,nminFD
1023  integer,save :: dblsmr,occopt_prev=-9999
1024  real(dp),save :: convlim,incconv,limit_occ,tphysel_prev=-9999,tsmear_prev=-9999
1025  real(dp) :: aa,dsqrpi,encorr,factor
1026  real(dp) :: expinc,expx22,expxo2,gauss,increm
1027  real(dp) :: resFD1,resFD2,resFD3,resFD4,resmom,resmom1,resmom2
1028  real(dp) :: resmom3,resmom4,secmom,smom1,smom2,thdmom,tmom1,tmom2,tmpexpsum
1029  real(dp) :: tmpsmdfun,tratio,tt,xx,yp1,ypn
1030  character(len=500) :: msg
1031 !arrays
1032  real(dp),save :: entfun_prev(-nptsdiv2_def:nptsdiv2_def,2),occfun_prev(-nptsdiv2_def:nptsdiv2_def,2)
1033  real(dp),save :: smdfun_prev(-nptsdiv2_def:nptsdiv2_def,2),xgrid_prev(-nptsdiv2_def:nptsdiv2_def)
1034  real(dp),allocatable :: entder(:),occder(:),smd1(:),smd2(:)
1035  real(dp),allocatable :: smdder(:),tgrid(:),work(:),workfun(:)
1036 
1037 ! *************************************************************************
1038 
1039  ! Initialize the occupation function and generalized entropy function,
1040  ! at the beginning, or if occopt changed
1041 
1042  if(option==-1)then
1043    nptsdiv2 = nptsdiv2_def
1044    return
1045  end if
1046 
1047  if (occopt_prev/=occopt .or. abs(tsmear_prev-tsmear)  >tol12 .or. abs(tphysel_prev-tphysel)>tol12) then
1048    occopt_prev=occopt
1049    tsmear_prev=tsmear
1050    tphysel_prev=tphysel
1051 
1052    ! Check whether input values of tphysel tsmear and occopt are consistent
1053    dblsmr = 0
1054    if (abs(tphysel)>tol12) then
1055      ! Use re-smearing scheme
1056      if (abs(tsmear)>tol12) then
1057        dblsmr = 1
1058        ! Use FD occupations (one smearing) only with "physical" temperature tphysel
1059      ! CP modify
1060      !else if (occopt /= 3) then
1061      !  write(msg, '(a,i6,a)' )' tphysel /= 0, tsmear == 0, but occopt is not = 3, but ',occopt,'.'
1062      else if (occopt /= 3 .and. occopt/=9) then
1063        write(msg, '(a,i6,a)' )' tphysel /= 0, tsmear == 0, but occopt is not = 3 or 9, but ',occopt,'.'
1064      ! End CP modify
1065        ABI_ERROR(msg)
1066      end if
1067    end if
1068 
1069    ABI_MALLOC(entder,(-nptsdiv2_def:nptsdiv2_def))
1070    ABI_MALLOC(occder,(-nptsdiv2_def:nptsdiv2_def))
1071    ABI_MALLOC(smdder,(-nptsdiv2_def:nptsdiv2_def))
1072    ABI_MALLOC(workfun,(-nptsdiv2_def:nptsdiv2_def))
1073    ABI_MALLOC(work,(-nptsdiv2_def:nptsdiv2_def))
1074 
1075    ! Prepare the points on the grid
1076    ! limit is the value of the argument that will give 0.0 or 1.0 , with
1077    ! less than about 1.0d-15 error for 4<=occopt<=8, and less than about 1.0d-12
1078    ! error for occopt==3. It is not worth to compute the function beyond
1079    ! that point. Even with a less severe requirement, it is significantly
1080    ! larger for occopt==3, with an exponential
1081    ! tail, than for the other occupation functions, with a Gaussian tail.
1082    ! Note that these values are useful in newocc.f also.
1083    limit_occ=6.0_dp
1084    ! CP modify
1085    !if(occopt==3)limit_occ=30.0_dp
1086    if(occopt==3 .or. occopt==9)limit_occ=30.0_dp
1087    ! End CP modify
1088    if(dblsmr /= 0) then
1089      tratio = tsmear / tphysel
1090      limit_occ=30.0_dp + 6.0_dp*tratio
1091    end if
1092 
1093    ! With nptsdiv2_def=6000 (thus increm=0.001 for 4<=occopt<=8,
1094    ! and increm=0.005 for occopt==3, the O(1/N4) algorithm gives 1.0d-12
1095    ! accuracy on the stored values occfun and entfun. These, together
1096    ! with smdfun and xgrid_prev, need permanently about 0.67 MB, which is affordable.
1097    increm=limit_occ/nptsdiv2_def
1098    do ii=-nptsdiv2_def,nptsdiv2_def
1099      xgrid_prev(ii)=ii*increm
1100    end do
1101 
1102    !  ---------------------------------------------------------
1103    !  Ordinary (unique) smearing function
1104    !  ---------------------------------------------------------
1105    if (dblsmr == 0) then
1106 
1107      ! Compute the unnormalized smeared delta function between -limit_occ and +limit_occ
1108      ! (well, they are actually normalized ...)
1109 
1110      ! CP modify
1111      !if(occopt==3)then
1112      if(occopt==3 .or. occopt==9)then
1113      ! End CP modify
1114        ! Fermi-Dirac
1115        do ii=0,nptsdiv2_def
1116          xx=xgrid_prev(ii)
1117          smdfun_prev( ii,1)=0.25_dp/(cosh(xx/2.0_dp)**2)
1118          smdfun_prev(-ii,1)=smdfun_prev(ii,1)
1119        end do
1120 
1121      else if(occopt==4 .or. occopt==5)then
1122        ! Cold smearing of Marzari, two values of the "a" parameter being possible
1123        ! first value gives minimization of the bump
1124        if(occopt==4)aa=-.5634
1125        ! second value gives monotonic occupation function
1126        if(occopt==5)aa=-.8165
1127 
1128        dsqrpi=1.0_dp/sqrt(pi)
1129        do ii=0,nptsdiv2_def
1130          xx=xgrid_prev(ii)
1131          gauss=dsqrpi*exp(-xx**2)
1132          smdfun_prev( ii,1)=gauss*(1.5_dp+xx*(-aa*1.5_dp+xx*(-1.0_dp+aa*xx)))
1133          smdfun_prev(-ii,1)=gauss*(1.5_dp+xx*( aa*1.5_dp+xx*(-1.0_dp-aa*xx)))
1134        end do
1135 
1136      else if(occopt==6)then
1137 
1138        ! First order Hermite-Gaussian of Paxton and Methfessel
1139        dsqrpi=1.0_dp/sqrt(pi)
1140        do ii=0,nptsdiv2_def
1141          xx=xgrid_prev(ii)
1142          smdfun_prev( ii,1)=dsqrpi*(1.5_dp-xx**2)*exp(-xx**2)
1143          smdfun_prev(-ii,1)=smdfun_prev(ii,1)
1144        end do
1145 
1146      else if(occopt==7)then
1147 
1148        ! Gaussian smearing
1149        dsqrpi=1.0_dp/sqrt(pi)
1150        do ii=0,nptsdiv2_def
1151          xx=xgrid_prev(ii)
1152          smdfun_prev( ii,1)=dsqrpi*exp(-xx**2)
1153          smdfun_prev(-ii,1)=smdfun_prev(ii,1)
1154        end do
1155 
1156      else if(occopt==8)then
1157 
1158        ! Constant value of the delta function over the smearing interval, for testing purposes only.
1159        do ii=0,nptsdiv2_def
1160          xx=xgrid_prev(ii)
1161          if(xx>half+tol8)then
1162            smdfun_prev( ii,1)=zero
1163          else if(xx<half-tol8)then
1164            smdfun_prev( ii,1)=one
1165          else
1166            smdfun_prev( ii,1)=half
1167          end if
1168          smdfun_prev(-ii,1)=smdfun_prev(ii,1)
1169        end do
1170 
1171      else
1172        ABI_BUG(sjoin('Occopt: ', itoa(occopt),' is not allowed in getnel.'))
1173      end if
1174 
1175    else if (dblsmr /= 0) then
1176      !    ---------------------------------------------------------
1177      !    smear FD delta with occopt delta calculated in smdfun_prev
1178      !    ---------------------------------------------------------
1179 
1180      nconvd2 = 6000
1181      convlim = 10.0_dp
1182      incconv = convlim / nconvd2
1183 
1184      ! store smearing functions in smd1 and smd2
1185      ABI_MALLOC(smd1,(-nconvd2:nconvd2))
1186      ABI_MALLOC(smd2,(-nconvd2:nconvd2))
1187      ABI_MALLOC(tgrid,(-nconvd2:nconvd2))
1188 
1189      ! FD function in smd1( ii) and second smearing delta in smd2( ii)
1190      !
1191      ! smd1(:) contains delta_FD ( x )
1192      do ii=0,nconvd2
1193        tgrid(ii)=ii*incconv
1194        tgrid(-ii)=-tgrid(ii)
1195        tt=tgrid(ii)
1196        smd1( ii)=0.25_dp/(cosh(tt/2.0_dp)**2)
1197        smd1(-ii)=smd1(ii)
1198      end do
1199 
1200      ! check input values of occopt and fill smd2(:) with appropriate data:
1201      ! smd2(:) contains delta_resmear ( x )
1202      ! CP modify
1203      !if(occopt == 3) then
1204      if(occopt == 3 .or. occopt==9) then
1205      ! End CP modify
1206        write(msg, '(a,a)' )&
1207         'Occopt=3 is not allowed as a re-smearing.', &
1208         'Use a single FD, or re-smear with a different delta type (faster cutoff). '
1209        ABI_ERROR(msg)
1210      else if(occopt==4 .or. occopt==5)then
1211        ! Cold smearing of Marzari, two values of the "a" parameter being possible
1212        ! first value gives minimization of the bump
1213        if(occopt==4)aa=-.5634
1214        ! second value gives monotonic occupation function
1215        if(occopt==5)aa=-.8165
1216 
1217        dsqrpi=1.0_dp/sqrt(pi)
1218        do ii=0,nconvd2
1219          tt=tgrid(ii)
1220          gauss=dsqrpi*exp(-tt**2)
1221          smd2( ii)=gauss*(1.5_dp+tt*(-aa*1.5_dp+tt*(-1.0_dp+aa*tt)))
1222          smd2(-ii)=gauss*(1.5_dp+tt*( aa*1.5_dp+tt*(-1.0_dp-aa*tt)))
1223        end do
1224      else if(occopt==6)then
1225        dsqrpi=1.0_dp/sqrt(pi)
1226        do ii=0,nconvd2
1227          tt=tgrid(ii)
1228          smd2( ii)=dsqrpi*(1.5_dp-tt**2)*exp(-tt**2)
1229          smd2(-ii)=smd2(ii)
1230        end do
1231      else if(occopt==7)then
1232        dsqrpi=1.0_dp/sqrt(pi)
1233        do ii=0,nconvd2
1234          tt=tgrid(ii)
1235          smd2( ii)=dsqrpi*exp(-tt**2)
1236          smd2(-ii)=smd2(ii)
1237        end do
1238      else if(occopt==8)then
1239        do ii=0,nconvd2
1240          tt=tgrid(ii)
1241          if(tt>half+tol8)then
1242            smd2( ii)=zero
1243          else if(tt<half-tol8)then
1244            smd2( ii)=one
1245          else
1246            smd2( ii)=half
1247          end if
1248          smd2(-ii)=smd2(ii)
1249        end do
1250      else
1251        ABI_BUG(sjoin('Occopt: ', itoa(occopt),' is not allowed in getnel.'))
1252      end if
1253 
1254      ! Use O(1/N4) algorithm from Num Rec (see below)
1255      !
1256      ! The grid for the convoluted delta is taken (conservatively)
1257      ! to be that for the FD delta ie 6000 pts in [-limit_occ;limit_occ]
1258      ! Smearing functions are given on [-dbllim;dbllim] and the grid must
1259      ! superpose the normal grid on [-limit_occ:limit_occ]
1260      ! The maximal interval for integration of the convolution is
1261      ! [-dbllim+limit_occ+lim(delta2);dbllim-limit_occ-lim(delta2)] =
1262      ! [-dbllim+36;dbllim-36]
1263 
1264      ! test the smdFD function for extreme values:
1265      ! do jj=-nptsdiv2_def,-nptsdiv2_def
1266      ! do ii=-nconvd2+4,nconvd2
1267      ! call smdFD(xgrid_prev(jj) - tgrid(ii)*tratio, resFD)
1268      ! write(std_out,*) 'ii jj = ', ii,jj, ' smdFD (', xgrid_prev(jj) - tgrid(ii)*tratio, ') ', resFD
1269      ! end do
1270      ! end do
1271 
1272      expinc = exp(half*incconv*tratio)
1273 
1274      ! jj = position of point at which we are calculating smdfun_prev
1275      do jj=-nptsdiv2_def,nptsdiv2_def
1276        ! Do not care about the 8 boundary points,
1277        ! where the values should be extremely small anyway
1278        smdfun_prev(jj,1)=0.0_dp
1279        ! only add contribution with delta_FD > 1.0d-100
1280        nmaxFD = floor  (( maxFDarg+xgrid_prev(jj)) / tratio / incconv )
1281        nmaxFD = min (nmaxFD, nconvd2)
1282        nminFD = ceiling((-maxFDarg+xgrid_prev(jj)) / tratio / incconv )
1283        nminFD = max (nminFD, -nconvd2)
1284 
1285        ! Calculate the Fermi-Dirac distrib at point xgrid_prev(jj)-tgrid(ii)*tratio
1286        expxo2 = exp (-half*(xgrid_prev(jj) - (nminFD)*incconv*tratio))
1287        expx22 = expxo2*expxo2
1288        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
1289        resFD4 = tmpexpsum * tmpexpsum
1290        expxo2 = expxo2*expinc
1291        expx22 = expxo2*expxo2
1292        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
1293        resFD3 = tmpexpsum * tmpexpsum
1294        expxo2 = expxo2*expinc
1295        expx22 = expxo2*expxo2
1296        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
1297        resFD2 = tmpexpsum * tmpexpsum
1298        expxo2 = expxo2*expinc
1299        expx22 = expxo2*expxo2
1300        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
1301        resFD1 = tmpexpsum * tmpexpsum
1302 
1303        ! core contribution to the integral with constant weight (48)
1304        tmpsmdfun = 0.0_dp
1305        do ii=nminFD+4,nmaxFD-4
1306          expxo2 = expxo2*expinc
1307          ! tmpexpsum = 1.0_dp / (expxo2 + 1.0_dp / expxo2 )
1308          expx22 = expxo2*expxo2
1309          tmpexpsum = expxo2 / (expx22 + 1.0_dp)
1310          tmpsmdfun = tmpsmdfun + smd2(ii) * tmpexpsum * tmpexpsum
1311        end do
1312 
1313        ! Add on end contributions for show (both functions smd and smdFD are very small
1314        smdfun_prev(jj,1)=smdfun_prev(jj,1)       +48.0_dp*tmpsmdfun             &
1315          + 31.0_dp*smd2(nminFD+3)*resFD1 -11.0_dp*smd2(nminFD+2)*resFD2 &
1316          +  5.0_dp*smd2(nminFD+1)*resFD3 -       smd2(nminFD)*resFD4
1317 
1318        expxo2 = expxo2*expinc
1319        expx22 = expxo2*expxo2
1320        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
1321        resFD1 = tmpexpsum * tmpexpsum
1322        expxo2 = expxo2*expinc
1323        expx22 = expxo2*expxo2
1324        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
1325        resFD2 = tmpexpsum * tmpexpsum
1326        expxo2 = expxo2*expinc
1327        expx22 = expxo2*expxo2
1328        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
1329        resFD3 = tmpexpsum * tmpexpsum
1330        expxo2 = expxo2*expinc
1331        expx22 = expxo2*expxo2
1332        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
1333        resFD4 = tmpexpsum * tmpexpsum
1334 
1335        ! Contribution above
1336        smdfun_prev(jj,1)=smdfun_prev(jj,1)                                      &
1337          + 31.0_dp*smd2(nmaxFD-3)*resFD1  -11.0_dp*smd2(nmaxFD-2)*resFD2 &
1338          +  5.0_dp*smd2(nmaxFD-1)*resFD3  -       smd2(nmaxFD)*resFD4
1339        smdfun_prev(jj,1)=incconv*smdfun_prev(jj,1)/48.0_dp
1340      end do
1341 
1342      secmom = 0.0_dp
1343      thdmom = 0.0_dp
1344      resmom4 = xgrid_prev(-nptsdiv2_def  )*xgrid_prev(-nptsdiv2_def  )*smdfun_prev(-nptsdiv2_def  ,  1)
1345      resmom3 = xgrid_prev(-nptsdiv2_def+1)*xgrid_prev(-nptsdiv2_def+1)*smdfun_prev(-nptsdiv2_def+1,  1)
1346      resmom2 = xgrid_prev(-nptsdiv2_def+2)*xgrid_prev(-nptsdiv2_def+2)*smdfun_prev(-nptsdiv2_def+2,  1)
1347      resmom1 = xgrid_prev(-nptsdiv2_def+3)*xgrid_prev(-nptsdiv2_def+3)*smdfun_prev(-nptsdiv2_def+3,  1)
1348      resmom  = xgrid_prev(-nptsdiv2_def+4)*xgrid_prev(-nptsdiv2_def+4)*smdfun_prev(-nptsdiv2_def+4,  1)
1349      do ii=-nptsdiv2_def+4,nptsdiv2_def-1
1350        secmom = secmom +                                   &
1351 &       ( 17.0_dp*xgrid_prev(ii)  *xgrid_prev(ii)  *smdfun_prev(ii,  1)   &
1352 &       +42.0_dp*xgrid_prev(ii-1)*xgrid_prev(ii-1)*smdfun_prev(ii-1,1)   &
1353 &       -16.0_dp*xgrid_prev(ii-2)*xgrid_prev(ii-2)*smdfun_prev(ii-2,1)   &
1354 &       + 6.0_dp*xgrid_prev(ii-3)*xgrid_prev(ii-3)*smdfun_prev(ii-3,1)   &
1355 &       -       xgrid_prev(ii-4)*xgrid_prev(ii-4)*smdfun_prev(ii-4,1)  )
1356        resmom4 = resmom3
1357        resmom3 = resmom2
1358        resmom2 = resmom1
1359        resmom1 = resmom
1360        resmom  = xgrid_prev(ii+1)  *xgrid_prev(ii+1)  *smdfun_prev(ii+1,  1)
1361      end do
1362      secmom=increm * secmom / 48.0_dp
1363      ! thdmom=increm * thdmom / 48.0_dp
1364      !
1365      ! smom1  = second moment of delta in smd1(:)
1366      ! smom2  = second moment of delta in smd2(:)
1367      !
1368      smom1  = 0.0_dp
1369      smom2  = 0.0_dp
1370      tmom1  = 0.0_dp
1371      tmom2  = 0.0_dp
1372      do ii=-nconvd2+4,nconvd2
1373        smom1 = smom1+                                       &
1374 &       ( 17.0_dp*tgrid(ii)  *tgrid(ii)  *smd1(ii)         &
1375 &       +42.0_dp*tgrid(ii-1)*tgrid(ii-1)*smd1(ii-1)       &
1376 &       -16.0_dp*tgrid(ii-2)*tgrid(ii-2)*smd1(ii-2)       &
1377 &       + 6.0_dp*tgrid(ii-3)*tgrid(ii-3)*smd1(ii-3)       &
1378 &       -       tgrid(ii-4)*tgrid(ii-4)*smd1(ii-4)  )
1379        smom2 = smom2+                                       &
1380 &       ( 17.0_dp*tgrid(ii)  *tgrid(ii)  *smd2(ii  )     &
1381 &       +42.0_dp*tgrid(ii-1)*tgrid(ii-1)*smd2(ii-1)     &
1382 &       -16.0_dp*tgrid(ii-2)*tgrid(ii-2)*smd2(ii-2)     &
1383 &       + 6.0_dp*tgrid(ii-3)*tgrid(ii-3)*smd2(ii-3)     &
1384 &       -       tgrid(ii-4)*tgrid(ii-4)*smd2(ii-4)  )
1385      end do
1386      smom1 =incconv * smom1  / 48.0_dp
1387      smom2 =incconv * smom2  / 48.0_dp
1388 !    tmom1 =incconv * tmom1  / 48.0_dp
1389 !    tmom2 =incconv * tmom2  / 48.0_dp
1390 
1391      encorr =  smom2*tratio*tratio/secmom
1392 
1393      ABI_FREE(tgrid)
1394      ABI_FREE(smd1)
1395      ABI_FREE(smd2)
1396 
1397    end if
1398 
1399    !  --------------------------------------------------------
1400    !  end of smearing function initialisation, dblsmr case
1401    !  --------------------------------------------------------
1402 
1403 
1404    !  Now that the smeared delta function has been initialized, compute the
1405    !  occupation function
1406    occfun_prev(-nptsdiv2_def,1)=zero
1407    entfun_prev(-nptsdiv2_def,1)=zero
1408 
1409    !  Different algorithms are possible, corresponding to the formulas
1410    !  (4.1.11), (4.1.12) and (4.1.14) in Numerical recipes (pp 107 and 108),
1411    !  with respective O(1/N2), O(1/N3), O(1/N4) convergence, where N is the
1412    !  number of points in the interval.
1413    algo=4
1414 
1415    if(algo==2)then
1416 
1417      ! Extended trapezoidal rule (4.1.11), taken in a cumulative way
1418      do ii=-nptsdiv2_def+1,nptsdiv2_def
1419        occfun_prev(ii,1)=occfun_prev(ii-1,1)+increm*(smdfun_prev(ii,1)+smdfun_prev(ii-1,1))/2.0_dp
1420        entfun_prev(ii,1)=entfun_prev(ii-1,1)+increm*&
1421 &       ( -xgrid_prev(ii)*smdfun_prev(ii,1) -xgrid_prev(ii-1)*smdfun_prev(ii-1,1) )/2.0_dp
1422      end do
1423 
1424    else if(algo==3)then
1425 
1426      ! Derived from (4.1.12). Converges as O(1/N3).
1427      ! Do not care about the following points,
1428      ! where the values are extremely small anyway
1429      occfun_prev(-nptsdiv2_def+1,1)=0.0_dp ;   entfun_prev(-nptsdiv2_def+1,1)=0.0_dp
1430      do ii=-nptsdiv2_def+2,nptsdiv2_def
1431        occfun_prev(ii,1)=occfun_prev(ii-1,1)+increm*&
1432 &       ( 5.0_dp*smdfun_prev(ii,1) + 8.0_dp*smdfun_prev(ii-1,1) - smdfun_prev(ii-2,1) )/12.0_dp
1433        entfun_prev(ii,1)=entfun_prev(ii-1,1)+increm*&
1434 &       ( 5.0_dp*(-xgrid_prev(ii)  )*smdfun_prev(ii,1)  &
1435 &       +8.0_dp*(-xgrid_prev(ii-1))*smdfun_prev(ii-1,1)&
1436 &       -      (-xgrid_prev(ii-2))*smdfun_prev(ii-2,1) )/12.0_dp
1437      end do
1438 
1439    else if(algo==4)then
1440 
1441      ! Derived from (4.1.14)- alternative extended Simpsons rule. Converges as O(1/N4).
1442      ! Do not care about the following points,
1443      ! where the values are extremely small anyway
1444      occfun_prev(-nptsdiv2_def+1,1)=0.0_dp ;   entfun_prev(-nptsdiv2_def+1,1)=0.0_dp
1445      occfun_prev(-nptsdiv2_def+2,1)=0.0_dp ;   entfun_prev(-nptsdiv2_def+2,1)=0.0_dp
1446      occfun_prev(-nptsdiv2_def+3,1)=0.0_dp ;   entfun_prev(-nptsdiv2_def+3,1)=0.0_dp
1447      do ii=-nptsdiv2_def+4,nptsdiv2_def
1448        occfun_prev(ii,1)=occfun_prev(ii-1,1)+increm*&
1449 &       ( 17.0_dp*smdfun_prev(ii,1)  &
1450 &       +42.0_dp*smdfun_prev(ii-1,1)&
1451 &       -16.0_dp*smdfun_prev(ii-2,1)&
1452 &       + 6.0_dp*smdfun_prev(ii-3,1)&
1453 &       -       smdfun_prev(ii-4,1) )/48.0_dp
1454        entfun_prev(ii,1)=entfun_prev(ii-1,1)+increm*&
1455 &       ( 17.0_dp*(-xgrid_prev(ii)  )*smdfun_prev(ii,1)  &
1456 &       +42.0_dp*(-xgrid_prev(ii-1))*smdfun_prev(ii-1,1)&
1457 &       -16.0_dp*(-xgrid_prev(ii-2))*smdfun_prev(ii-2,1)&
1458 &       + 6.0_dp*(-xgrid_prev(ii-3))*smdfun_prev(ii-3,1)&
1459 &       -       (-xgrid_prev(ii-4))*smdfun_prev(ii-4,1) )/48.0_dp
1460      end do
1461 
1462    end if ! End of choice between different algorithms for integration
1463 
1464    ! Normalize the functions (actually not needed for occopt=3..7)
1465    factor=1.0_dp/occfun_prev(nptsdiv2_def,1)
1466    smdfun_prev(:,1)=smdfun_prev(:,1)*factor
1467    occfun_prev(:,1)=occfun_prev(:,1)*factor
1468    entfun_prev(:,1)=entfun_prev(:,1)*factor
1469 
1470    !  Compute the cubic spline fitting of the smeared delta function
1471    yp1=0.0_dp ; ypn=0.0_dp
1472    workfun(:)=smdfun_prev(:,1)
1473    call spline(xgrid_prev, workfun, (2*nptsdiv2_def+1), yp1, ypn, smdder)
1474    smdfun_prev(:,2)=smdder(:)
1475 
1476    ! Compute the cubic spline fitting of the occupation function
1477    yp1=0.0_dp ; ypn=0.0_dp
1478    workfun(:)=occfun_prev(:,1)
1479    call spline(xgrid_prev, workfun, (2*nptsdiv2_def+1), yp1, ypn, occder)
1480    occfun_prev(:,2)=occder(:)
1481 
1482    ! Compute the cubic spline fitting of the entropy function
1483    yp1=0.0_dp ; ypn=0.0_dp
1484    workfun(:)=entfun_prev(:,1)
1485    call spline(xgrid_prev, workfun, (2*nptsdiv2_def+1), yp1, ypn, entder)
1486    entfun_prev(:,2)=entder(:)
1487 
1488    ABI_FREE(entder)
1489    ABI_FREE(occder)
1490    ABI_FREE(smdder)
1491    ABI_FREE(work)
1492    ABI_FREE(workfun)
1493 
1494  end if
1495 
1496  if (abs(tphysel)<tol12) then
1497    if (tsmear == zero) then
1498      tsmearinv = huge_tsmearinv
1499    else
1500      tsmearinv=one/tsmear
1501    end if
1502  else
1503    tsmearinv=one/tphysel
1504  end if
1505 
1506  entfun(:,:) = entfun_prev(:,:)
1507  occfun(:,:) = occfun_prev(:,:)
1508  smdfun(:,:) = smdfun_prev(:,:)
1509  xgrid(:) = xgrid_prev(:)
1510  limit = limit_occ
1511  nptsdiv2 = nptsdiv2_def
1512 
1513 end subroutine init_occ_ent

m_occ/newocc [ Functions ]

[ Top ] [ m_occ ] [ Functions ]

NAME

 newocc

FUNCTION

 Compute new occupation numbers at each k point,
 from eigenenergies eigen, according to the
 smearing scheme defined by occopt (smearing width tsmear and
 physical temperature tphysel),
 with the constraint of number of valence electrons per unit cell nelect.

INPUTS

  eigen(mband*nkpt*nsppol)=eigenvalues (input or init to large number), hartree
  spinmagntarget=if differ from -99.99_dp, fix the magnetic moment (in Bohr magneton)
  mband=maximum number of bands
  nband(nkpt)=number of bands at each k point
  nelect=number of electrons per unit cell
  ne_qFD, nh_qFD=number of thermalized excited electrons (resp. holes) in bands > ivalence (resp. <= ivalence) 
  ivalence= band index of the last valence band
  nkpt=number of k points
  nspinor=number of spinorial components of the wavefunctions
  nsppol=1 for unpolarized, 2 for spin-polarized
  occopt=option for occupancies
  prtstm=optional, might govern the band-by-band decomposition of the stm charge density
  prtvol=control print volume and debugging output
  stmbias= optional, if non-zero, compute occupation numbers for STM (non-zero around the Fermi energy)
   NOTE: in this case, only fermie and occ are meaningful outputs.
  tphysel="physical" electronic temperature with FD occupations
  tsmear=smearing width (or temperature)
  wtk(nkpt)=k point weights

OUTPUT

  doccde(maxval(nband(:))*nkpt*nsppol)=derivative of occupancies wrt
           the energy for each band and k point
  entropy= entropy associated with the smearing (adimensional)
  fermie= fermi energy (Hartree)/fermi level for thermalized excited electrons in bands > ivalence when occopt=9
  fermih= fermi level for thermalized excited holes in bands <= ivalence
  occ(maxval(nband(:))*nkpt*nsppol)=occupancies for each band and k point

SOURCE

452 subroutine newocc(doccde, eigen, entropy, fermie, fermih, ivalence, spinmagntarget, mband, nband, &
453   nelect, ne_qFD, nh_qFD, nkpt, nspinor, nsppol, occ, occopt, prtvol, tphysel, tsmear, wtk, &
454   prtstm, stmbias, extfpmd) ! Optional argument
455 
456 !Arguments ------------------------------------
457 !scalars
458  integer,intent(in) :: ivalence,mband,nkpt,nspinor,nsppol,occopt,prtvol
459  integer,intent(in),optional :: prtstm
460  real(dp),intent(in) :: spinmagntarget,nelect,tphysel,tsmear,ne_qFD, nh_qFD
461  real(dp),intent(in),optional :: stmbias
462  real(dp),intent(out) :: entropy,fermie,fermih
463  type(extfpmd_type),pointer,intent(inout),optional :: extfpmd
464 !arrays
465  integer,intent(in) :: nband(nkpt*nsppol)
466  real(dp),intent(in) :: eigen(mband*nkpt*nsppol),wtk(nkpt)
467  real(dp),intent(out) :: doccde(mband*nkpt*nsppol)
468  real(dp),intent(inout) :: occ(mband*nkpt*nsppol)
469 
470 !Local variables-------------------------------
471  integer,parameter :: niter_max=120,nkpt_max=2,fake_unit=-666,option1=1
472  integer :: cnt,cnt2,cnt3,ib,iban,ibantot,ii,ik,ikpt,is,isppol,nban,nkpt_eff,sign
473  integer :: extfpmd_nbdbuf=0
474  integer,allocatable :: nbandt(:)
475  real(dp),parameter :: tol = tol14
476  !real(dp),parameter :: tol = tol10
477  real(dp) :: dosdeltae,entropy_tmp,fermie_hi,fermie_lo,fermie_mid,fermie_mid_tmp
478  real(dp) :: fermih_lo,fermih_mid,fermih_hi
479  real(dp) :: fermie_biased,maxocc
480  real(dp) :: nelect_tmp,nelecthi,nelectlo,nelectmid,nelect_biased
481  real(dp) :: nholeshi,nholeslo,nholesmid
482  real(dp) :: entropyet(2),fermie_hit(2),fermie_lot(2),fermie_midt(2),nelecthit(2)
483  real(dp) :: nelectlot(2),nelectt(2),tsec(2)
484  real(dp) :: entropye, entropyh
485  real(dp),allocatable :: doccdet(:),eigent(:),occt(:)
486  character(len=500) :: msg
487  logical::not_enough_bands=.false.
488 
489 ! *************************************************************************
490 
491  DBG_ENTER("COLL")
492 
493  call timab(74,1,tsec)
494 
495  ! Here treat the case where occopt does not correspond to a metallic occupation scheme
496  if (occopt < 3 .or. occopt > 9) then
497    ABI_BUG(sjoin(' occopt= ',itoa(occopt),', a value not allowed in newocc.'))
498  end if
499 
500  ! Check whether nband is a constant for all k point and spin-pol
501  do isppol=1,nsppol
502    do ikpt=1,nkpt
503      if(nband(ikpt+(isppol-1)*nkpt)/=nband(1))then
504        write(msg,'(3a,i0,a,i0,a,i0,a)')&
505         'The number of bands must be the same for all k-points ',ch10,&
506         'but nband(1)= ',nband(1),' is different of nband(',ikpt+(isppol-1)*nkpt,') = ',nband(ikpt+(isppol-1)*nkpt),'.'
507        ABI_BUG(msg)
508      end if
509    end do
510  end do
511 
512  ! Check whether nelect is strictly positive
513  if (nelect <= zero) then
514    write(msg,'(3a,es16.8,a)')&
515    'nelect must be a positive number, while ',ch10, 'the calling routine asks nelect= ',nelect,'.'
516    ABI_BUG(msg)
517  end if
518 
519  ! Check whether the number of holes and electrons if positive
520  if (occopt == 9) then
521     if ( (ne_qFD < zero) .or. (nh_qFD < zero) ) then
522        write(msg,'(3a,es16.8,a,es16.8,a)')&
523 &   'ne_qFD or nh_qFD must be positive numbers, while ',ch10,&
524 &   'the calling routine asks ne_qFD= ',ne_qFD,' and nh_qFD= ',nh_qFD, '.'
525    ABI_BUG(msg)
526     end if
527  end if
528 
529  maxocc = two / (nsppol * nspinor)
530 
531  ! Check whether nelect is coherent with nband (nband(1) is enough,
532  ! since it was checked that nband is independent of k-point and spin-pol
533  if (nelect > nband(1) * nsppol * maxocc) then
534    write(msg,'(3a,es16.8,a,i0,a,es16.8,a)' )&
535    'nelect must be smaller than nband*maxocc, while ',ch10,&
536    'the calling routine gives nelect= ',nelect,', nband= ',nband(1),' and maxocc= ',maxocc,'.'
537    ABI_BUG(msg)
538  end if
539 
540 ! Providing additional checks to ensure that there are enough valence and conduction bands
541 ! to accomodate ne_qFD and nh_qFD
542  if( occopt==9 .and. ne_qFD > (nband(1)-ivalence)*nsppol*maxocc )then
543    write(msg,'(a,es16.8,2a,es16.8,a)') 'ne_qFD = ', ne_qFD ,ch10, &
544 &   'must be smaller than (nband-ivalence)*maxocc*nsppol = ', &
545 &   (nband(1)-ivalence)*nsppol*maxocc,'.'
546    ABI_BUG(msg)
547  else if( occopt==9 .and. (nh_qFD > ivalence*nsppol*maxocc .or. &
548 &                          nelect - nh_qFD > ivalence*nsppol*maxocc ) )then
549    write(msg,'(a,es16.8,2a,es16.8,2a,es16.8,a)') 'nh_qFD = ', nh_qFD ,ch10, &
550 &   'and nelect-nh_qFD = ', nelect - nh_qFD,ch10, ' must be smaller than ivalence*maxocc*nsppol = ', &
551 &   ivalence*nsppol*maxocc,'.'
552    ABI_BUG(msg)
553   end if
554 
555  ! Set extfpmd band buffer if needed
556  if(present(extfpmd)) then
557    if(associated(extfpmd)) then
558      extfpmd_nbdbuf=extfpmd%nbdbuf
559    end if
560  end if
561 
562  ! Use bisection algorithm to find fermi energy
563  ! This choice is due to the fact that it will always give sensible
564  ! result (because the answer is bounded, even if the smearing function
565  ! is non-monotonic (which is the case for occopt=4 or 6)
566  ! Might speed up it, if needed !
567 
568  ! Lowest and largest trial fermi energies, and corresponding number of electrons
569  ! They are obtained from the smallest or largest eigenenergy, plus a range of
570  ! energy that allows for complete occupation of all bands, or, on the opposite,
571  ! for zero occupation of all bands (see getnel.f)
572 
573  dosdeltae = zero  ! the DOS is not computed, with option=1
574  fermie_lo = minval(eigen(1:nband(1)*nkpt*nsppol)) - 6.001_dp * tsmear ! fermi_lo ->fermie_lo
575  if (occopt == 3 .or. occopt==9) fermie_lo = fermie_lo - 24.0_dp * tsmear
576  if(occopt==9) fermih_lo = fermie_lo ! Take into account holes
577 
578  if(occopt >= 3 .and. occopt <= 8) then
579     call getnel(doccde,dosdeltae,eigen,entropye,fermie_lo,fermie_lo,maxocc,mband,nband,&
580 & nelectlo,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk,1,nband(1),&
581 & extfpmd_nbdbuf=extfpmd_nbdbuf)
582  else if (occopt == 9) then
583     call getnel(doccde,dosdeltae,eigen,entropye,fermie_lo,fermie_lo,maxocc,mband,nband,&
584 & nelectlo,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk, ivalence+1, nband(1)) ! Excited electrons
585     call getnel(doccde,dosdeltae,eigen,entropyh,fermih_lo,fermih_lo,maxocc,mband,nband,&
586 & nholeslo,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk,1, ivalence)
587  end if
588 
589  fermie_hi = maxval(eigen(1:nband(1)*nkpt*nsppol)) + 6.001_dp * tsmear
590  ! Safety value
591  fermie_hi = min(fermie_hi, 1.e6_dp)
592  if(occopt == 3 .or. occopt == 9) fermie_hi = fermie_hi + 24.0_dp * tsmear
593  if(occopt == 9) fermih_hi=fermie_hi
594  
595  if (occopt >= 3 .and. occopt <= 8) then
596     call getnel(doccde,dosdeltae,eigen,entropye,fermie_hi,fermie_hi,maxocc,mband,nband,&
597 & nelecthi,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk,1,nband(1),&
598 & extfpmd_nbdbuf=extfpmd_nbdbuf)
599  else if (occopt == 9) then
600     call getnel(doccde,dosdeltae,eigen,entropye,fermie_hi,fermie_hi,maxocc,mband,nband,&
601 & nelecthi,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk, ivalence+1, nband(1)) ! Excited electrons
602     fermih_hi=fermie_hi
603     call getnel(doccde,dosdeltae,eigen,entropyh,fermih_hi,fermih_hi,maxocc,mband,nband,&
604 & nholeshi,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk,1, ivalence)
605  end if
606 
607  ! Compute the number of free electrons with corresponding chemical
608  ! potential and add to nelect bounds.
609  if(present(extfpmd)) then
610    if(associated(extfpmd)) then
611      call extfpmd%compute_nelect(fermie_lo,nelectlo,tsmear)
612      call extfpmd%compute_nelect(fermie_hi,nelecthi,tsmear)
613    end if
614  end if
615 
616 !Prepare fixed moment calculation
617  if(abs(spinmagntarget+99.99_dp)>1.0d-10)then
618    if (occopt==9)then
619       write(msg,'(a)') 'occopt=9 and spinmagntarget not implemented.'
620       ABI_ERROR(msg)
621    end if
622    sign = 1
623    do is = 1, nsppol
624      fermie_hit(is) = fermie_hi 
625      fermie_lot(is) = fermie_lo 
626      nelectt(is) = half*(nelect+sign*spinmagntarget)
627      sign = -sign
628      nelecthit(is) = nelecthi
629      nelectlot(is) = nelectlo
630    end do
631  end if
632 
633 
634  ! If the target nelect is not between nelectlo and nelecthi, exit
635  if ((nelect < nelectlo .or. nelect > nelecthi) .and. (occopt <= 8)) then
636    not_enough_bands = .true.
637    write(msg, '(a,a,a,a,d16.8,a,a,d16.8,a,d16.8,a,a,d16.8,a,d16.8)') ch10,&
638     ' newocc: ',ch10,&
639     '  The calling routine gives nelect= ',nelect,ch10,&
640     '  The lowest bound is ',fermie_lo,', with nelect=',nelectlo,ch10,&
641     '  The highest bound is ',fermie_hi,', with nelect=',nelecthi
642    call wrtout(std_out, msg)
643    ABI_BUG(msg)
644  end if
645 
646  if( occopt==9 ) then
647     if ((nelect-nh_qFD)<nholeslo .or. (nelect-nh_qFD)>nholeshi) then
648        not_enough_bands = .true.
649        write(msg,'(a,a,a,d16.8,a,a,d16.8,a,d16.8,a)') 'newocc : ',ch10, &
650 &      'The calling routine gives nelect-nh_qFD = ', nelect-nh_qFD, ch10, &
651 &       'The lowest (highest resp.) bound for nelect-nh_qFD is ', &
652 &   nholeslo, ' ( ', nholeshi, ' ).'
653        ABI_BUG(msg)
654     endif
655     if ((ne_qFD < nelectlo) .or. (ne_qFD > nelecthi) ) then
656        not_enough_bands = .true.
657        write(msg,'(a,a,a,d16.8,a,a,d16.8,a,d16.8,a)') 'newocc : ',ch10, &
658 &   'The calling routine gives ne_qFD = ', ne_qFD, ch10, 'The lowest (highest resp.) bound for ne_qFD are ',&
659 &   nelectlo, ' ( ', nelecthi, ' ) .'
660        ABI_BUG(msg)
661     endif
662 
663    if (not_enough_bands) then
664       write(msg, '(11a)' )&
665 &      'In order to get the right number of carriers,',ch10,&
666 &      'it seems that the Fermi energies must be outside the range',ch10,&
667 &      'of eigenenergies, plus 6 or 30 times the smearing, which is strange.',ch10,&
668 &      'It might be that your number of bands (nband) corresponds to the strictly',ch10,&
669 &      'minimum number of bands to accomodate your electrons (so, OK for an insulator),',ch10,&
670 &      'while you are trying to describe a metal. In this case, increase nband, otherwise ...'
671       ABI_BUG(msg)
672    end if
673  end if
674 
675  if( abs(spinmagntarget+99.99_dp) < tol10) then
676 
677    ! Usual bisection loop
678    do ii=1,niter_max
679      fermie_mid = (fermie_hi + fermie_lo) * half 
680      if (occopt == 9) fermih_mid=(fermih_hi+fermih_lo)*half
681      ! Produce nelectmid from fermimid
682      if (occopt /= 9) then
683 
684        call getnel(doccde,dosdeltae,eigen,entropye,fermie_mid,fermie_mid,maxocc,mband,nband,&
685 &     nelectmid,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk, 1, nband(1),&
686 &     extfpmd_nbdbuf=extfpmd_nbdbuf)
687 
688        ! Compute the number of free electrons of the extfpmd model
689        ! with corresponding chemical potential and add to nelect bounds.
690        if(present(extfpmd)) then
691          if(associated(extfpmd)) then
692            call extfpmd%compute_nelect(fermie_mid,nelectmid,tsmear)
693          end if
694        end if
695 
696       !write(std_out,'(a,i0,1x, 3(a,es13.5))' ) " iter: ", ii, &
697       !  ' fermi_mid: ',fermimid * Ha_eV, ', n_mid: ',nelectmid, &
698       !  ", (n_mid-nelect)/nelect: ", (nelectmid - nelect) / nelect
699 
700       !if (nelectmid > nelect * (one - tol)) then
701       !  fermihi = fermimid
702       !  nelecthi = nelectmid
703       !end if
704       !if (nelectmid < nelect * (one + tol)) then
705       !  fermilo = fermimid
706       !  nelectlo = nelectmid
707       !end if
708        if(nelectmid>nelect*(one-tol14))then
709          fermie_hi=fermie_mid
710          nelecthi=nelectmid
711        end if
712        if(nelectmid<nelect*(one+tol14))then
713          fermie_lo=fermie_mid
714          nelectlo=nelectmid
715        end if
716 
717      else
718 
719        call getnel(doccde,dosdeltae,eigen,entropye,fermie_mid,fermie_mid,maxocc,mband,nband,&
720 &     nelectmid,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk, ivalence+1, nband(1))
721        call getnel(doccde,dosdeltae,eigen,entropyh,fermih_mid,fermih_mid,maxocc,mband,nband,&
722 &     nholesmid,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk,1,ivalence)
723        if(nelectmid>ne_qFD*(one-tol14))then
724          fermie_hi = fermie_mid
725          nelecthi  = nelectmid
726        else if (nelectmid<ne_qFD*(one-tol14))then
727          fermie_lo = fermie_mid
728          nelectlo  = nelectmid
729        end if
730        if(nholesmid>(nelect-nh_qFD)*(one-tol14))then
731          fermih_hi = fermih_mid
732          nholeshi  = nholesmid
733        else if(nholesmid<(nelect-nh_qFD)*(one+tol14))then
734          fermih_lo = fermih_mid
735          nholeslo  = nholesmid
736        end if
737 
738      end if
739 
740      !if (abs(nelectmid - nelect) <= nelect*two*tol) exit
741      !write(std_out,'(2(a,es13.5))' )' bisection move: fermi_lo: ',fermilo * Ha_eV,", fermi_hi: ", fermihi * Ha_eV
742 
743 !     if (abs(nelecthi - nelectlo) <= nelect*two*tol .or. &
744 !         abs(fermihi - fermilo) <= tol * abs(fermihi + fermilo) ) exit
745      if (occopt /= 9) then
746         if( abs(nelecthi-nelectlo) <= nelect*two*tol14 .or. abs(fermie_hi-fermie_lo) <= tol14*abs(fermie_hi+fermie_lo) ) exit
747      else
748         if( ( abs(nelecthi-nelectlo) <= ne_qFD*two*tol14 .or. &
749 &             abs(fermie_hi-fermie_lo) <= tol14*abs(fermie_hi+fermie_lo) ) .and. &
750             ( abs(nholeshi-nholeslo) <= (nelect-nh_qFD)*two*tol14 .or. &
751 &             abs(fermih_hi-fermih_lo) <= tol14*abs(fermih_hi+fermih_lo) ) ) exit
752      end if
753 
754      if (ii == niter_max) then
755        write(msg,'(a,i0,3a,es22.14,a,es22.14,a)')&
756         'It was not possible to find Fermi energy in ',niter_max,' max bisections.',ch10,&
757         'nelecthi: ',nelecthi,', and nelectlo: ',nelectlo,'.'
758        ABI_BUG(msg)
759        if (occopt == 9) then
760           write(msg,'(a,es22.14,a,es22.14,a)')&
761           'nholesi = ',nholeshi,', and holeslo = ',nholeslo,'.'
762        end if
763      end if
764    end do ! End of bisection loop
765 
766    fermie = fermie_mid 
767    entropy= entropye 
768 
769    if (occopt /= 9) then
770       write(msg, '(2(a,f14.6),a,i0)' ) &
771 &   ' newocc: new Fermi energy is ',fermie,' , with nelect=',nelectmid,', Number of bisection calls: ',ii
772    else
773       fermih=fermih_mid
774       entropy = entropy + entropyh ! CP: adding entropy of the holes subsystem
775       write(msg, '(2(a,f14.6),a,i0)' ) &
776 &   ' newocc: new Fermi energy for excited electrons is ',fermie,' , with ne_qFD=',nelectmid,', Number of bisection calls: ',ii
777       call wrtout(std_out,msg,'COLL')
778       write(msg, '(2(a,f14.6),a,i0)' ) &
779 &   ' newocc: new Fermi energy for excited holes     is ',fermih,' , with nh_qFD=',nelect-nholesmid,&
780 &   ', Number of bisection calls: ',ii
781    end if
782    call wrtout(std_out,msg)
783 
784    !  Compute occupation numbers for prtstm/=0, close to the Fermi energy
785    if (present(stmbias)) then
786 
787      if (abs(stmbias) > tol10) then
788 
789         ! Prevent use with occopt = 9 so far
790         ! XG220804 : This test is not needed, as prtstm/=0 must be used with occopt==7,
791         !  as tested in chkinp.F90
792         if (occopt == 9) then
793            write(msg,'(a)') 'Occopt 9 and prtstm /=0 not implemented together. Change occopt or prtstm.'
794            ABI_ERROR(msg)
795         end if
796 
797        fermie_biased = fermie - stmbias 
798        ABI_MALLOC(occt,(mband*nkpt*nsppol))
799 
800        call getnel(doccde,dosdeltae,eigen,entropy,fermie_biased,fermie_biased,maxocc,mband,nband,&
801 &         nelect_biased,nkpt,nsppol,occt,occopt,option1,tphysel,tsmear,fake_unit,wtk,1,nband(1),&
802 &         extfpmd_nbdbuf=extfpmd_nbdbuf)
803        occ(:)=occ(:)-occt(:)
804 
805  !     Possibly filter a specific band contribution
806        if (present(prtstm)) then
807          if (prtstm < 0)then
808            ibantot=1
809            do isppol=1,nsppol
810              do ikpt=1,nkpt
811                nban=nband(ikpt+(isppol-1)*nkpt)
812                do iban=1,nban
813                  if(iban/=abs(prtstm)) occ(ibantot)=zero
814                  ibantot=ibantot+1
815                end do ! iban
816              end do ! ikpt
817            end do ! isppol
818          end if ! prtstm < 0
819        end if ! present(prtstm)
820 
821        nelect_biased = abs(nelectmid - nelect_biased)
822        ! Here, arrange to have globally positive occupation numbers, irrespective of the stmbias sign
823        if (-stmbias > tol10) occ(:) = -occ(:)
824        ABI_FREE(occt)
825 
826        write(msg,'(a,f14.6)')' newocc: the number of electrons in the STM range is nelect_biased=',nelect_biased
827        call wrtout(std_out,msg)
828      end if
829    endif ! present(stmbias)
830 
831 
832  else
833    ! Calculations with a specified moment
834    ! Bisection loop
835    cnt2=0
836    cnt3=0
837    entropy=zero
838    maxocc=one
839    ABI_MALLOC(doccdet,(nkpt*mband))
840    ABI_MALLOC(eigent,(nkpt*mband))
841    ABI_MALLOC(occt,(nkpt*mband))
842    ABI_MALLOC(nbandt,(nkpt))
843 
844    do is = 1, nsppol
845      nelect_tmp = nelectt(is)
846      fermie_hi = fermie_hit(is) ! CP modify name
847      fermie_lo = fermie_lot(is) ! CP modify name
848      nelecthi = nelecthit(is)
849      nelectlo = nelectlot(is)
850      ! write(std_out,'(a,i1,3(f8.4,1x))') "Spin, N(spin):", is, nelect, fermihi, fermilo
851      ! write(std_out,'(a,2(f8.4,1x))') "Hi, lo:", nelecthi, nelectlo
852 
853      do ii=1,niter_max
854        fermie_mid_tmp=(fermie_hi+fermie_lo)/2.0_dp ! CP modify name
855        ! temporary arrays
856        cnt = 0
857        do ik = 1, nkpt
858          nbandt(ik) = mband
859          do ib = 1, mband
860            cnt = cnt + 1
861            eigent(cnt) = eigen(cnt+cnt2)
862            occt(cnt) = occ(cnt+cnt2)
863            doccdet(cnt) = doccde(cnt+cnt2)
864          end do
865        end do
866 
867        ! Produce nelectmid from fermimid
868        call getnel(doccdet,dosdeltae,eigent,entropy_tmp,fermie_mid_tmp,fermie_mid_tmp,maxocc,mband,nbandt,&
869          nelectmid,nkpt,1,occt,occopt,option1,tphysel,tsmear,fake_unit,wtk,1,nband(1),&
870 &        extfpmd_nbdbuf=extfpmd_nbdbuf)
871 
872        entropyet(is) = entropy_tmp
873        fermie_midt(is) = fermie_mid_tmp
874        fermie_mid = fermie_midt(is)
875 
876        ! temporary arrays
877        cnt = 0
878        do ik = 1, nkpt
879          do ib = 1, mband
880            cnt = cnt + 1
881            occ(cnt+cnt2) = occt(cnt)
882            doccde(cnt+cnt2) = doccdet(cnt)
883          end do
884        end do
885        ! write(std_out,'(a,es24.16,a,es24.16)' )' newocc: from fermi=',fermimid,', getnel gives nelect=',nelectmid
886 
887        if(nelectmid>=nelect_tmp)then
888          fermie_hi=fermie_mid_tmp 
889          nelecthi=nelectmid
890        else
891          fermie_lo=fermie_mid_tmp 
892          nelectlo=nelectmid
893        end if
894        if( abs(nelecthi-nelectlo) <= 1.0d-13 .or. abs(fermie_hi-fermie_lo) <= 0.5d-14*abs(fermie_hi+fermie_lo) ) exit
895 
896        if(ii==niter_max)then
897          write(msg,'(a,i3,3a,es22.14,a,es22.14,a)')&
898           'It was not possible to find Fermi energy in ',niter_max,' bisections.',ch10,&
899           'nelecthi: ',nelecthi,', and nelectlo: ',nelectlo,'.'
900          ABI_BUG(msg)
901        end if
902      end do ! End of bisection loop
903 
904      cnt2 = cnt2 + nkpt*mband
905      entropy = entropy + entropyet(is)
906      fermie=fermie_mid 
907      write(msg, '(a,i2,a,f14.6,a,f14.6,a,a,i4)' ) &
908        ' newocc: new Fermi energy for spin ', is, ' is ',fermie,' , with nelect: ',nelectmid,ch10,&
909        '  Number of bisection calls =',ii
910      call wrtout(std_out,msg)
911 
912    end do ! spin
913 
914    ABI_FREE(doccdet)
915    ABI_FREE(eigent)
916    ABI_FREE(nbandt)
917    ABI_FREE(occt)
918 
919  end if ! End of logical on fixed moment calculations
920 
921  !write(std_out,*) "kT*Entropy:", entropy*tsmear
922 
923  ! MG: If you are wondering why this part is npw disabled by default consider that this output
924  ! is produced many times in the SCF cycle and in EPH we have to call this routine for
925  ! several temperature and the log becomes unreadable.
926  ! If you really need to look at the occupation factors use prtvol > 0.
927  nkpt_eff = nkpt
928  if (prtvol == 0) nkpt_eff = 0
929  if (prtvol == 1) nkpt_eff = min(nkpt_max, nkpt)
930 
931  if (nsppol == 1)then
932 
933    if (nkpt_eff /= 0) then
934      write(msg, '(a,i0,a)' )' newocc: computed new occ. numbers for occopt= ',occopt,' , spin-unpolarized case. '
935      call wrtout(std_out,msg)
936      do ikpt=1,nkpt_eff
937        write(msg,'(a,i4,a)' ) ' k-point number ',ikpt,' :'
938        do ii=0,(nband(1)-1)/12
939          if (ii == 3 .and. prtvol /= 0) exit
940          write(msg,'(12f6.3)') occ(1+ii*12+(ikpt-1)*nband(1):min(12+ii*12,nband(1))+(ikpt-1)*nband(1))
941          call wrtout(std_out,msg)
942        end do
943      end do
944      if (nkpt /= nkpt_eff) call wrtout(std_out,' newocc: prtvol=0, stop printing more k-point information')
945 
946      !call wrtout(std_out,' newocc: corresponding derivatives are ')
947      !do ikpt=1,nkpt_eff
948      !write(msg,'(a,i4,a)' ) ' k-point number ',ikpt,' :'
949      !do ii=0,(nband(1)-1)/12
950      !write(msg,'(12f6.1)') doccde(1+ii*12+(ikpt-1)*nband(1):min(12+ii*12,nband(1))+(ikpt-1)*nband(1))
951      !call wrtout(std_out,msg)
952      !end do
953      !end do
954      !if(nkpt/=nkpt_eff)then
955      !  call wrtout(std_out,'newocc: prtvol=0, stop printing more k-point information')
956      !end if
957    end if
958 
959  else
960 
961    if (nkpt_eff /= 0) then
962      write(msg, '(a,i0,2a)' )' newocc: computed new occupation numbers for occopt= ',occopt,ch10,'  (1) spin up   values  '
963      call wrtout(std_out, msg)
964      do ikpt=1,nkpt_eff
965        write(msg,'(a,i0,a)' ) ' k-point number ',ikpt,':'
966        do ii=0,(nband(1)-1)/12
967          if (ii == 3 .and. prtvol /= 0) exit
968          write(msg,'(12f6.3)') occ(1+ii*12+(ikpt-1)*nband(1):min(12+ii*12,nband(1))+(ikpt-1)*nband(1))
969          call wrtout(std_out,msg)
970        end do
971      end do
972      if (nkpt/=nkpt_eff) call wrtout(std_out,' newocc: prtvol=0, stop printing more k-point information')
973 
974      call wrtout(std_out,'  (2) spin down values  ')
975      do ikpt=1,nkpt_eff
976        do ii=0,(nband(1)-1)/12
977          if (ii == 3 .and. prtvol /= 0) exit
978          write(msg,'(12f6.3)') occ( 1+ii*12+(ikpt-1+nkpt)*nband(1):min(12+ii*12,nband(1))+(ikpt-1+nkpt)*nband(1) )
979          call wrtout(std_out,msg)
980        end do
981      end do
982      if(nkpt/=nkpt_eff) call wrtout(std_out,' newocc: prtvol=0, stop printing more k-point information')
983    end if
984 
985  end if ! End choice based on spin
986 
987  call timab(74,2,tsec)
988 
989  DBG_EXIT("COLL")
990 
991 end subroutine newocc

m_occ/occ_be [ Functions ]

[ Top ] [ m_occ ] [ Functions ]

NAME

  occ_be

FUNCTION

   Bose-Einstein statistics  1 / [(exp((e - mu)/ KT) - 1]

INPUTS

   ee=Single particle energy in Ha
   kT=Value of K_Boltzmann x T in Ha.
   mu=Chemical potential in Ha (usually zero)

SOURCE

1740 elemental real(dp) function occ_be(ee, kT, mu)
1741 
1742 !Arguments ------------------------------------
1743  real(dp),intent(in) :: ee, kT, mu
1744 
1745 !Local variables ------------------------------
1746  real(dp) :: ee_mu, arg
1747 ! *************************************************************************
1748 
1749  ee_mu = ee - mu
1750 
1751  ! 1 kelvin [K] = 3.16680853419133E-06 Hartree
1752  if (kT > tol12) then
1753    arg = ee_mu / kT
1754    if (arg > tol12 .and. arg < maxBEarg) then
1755      occ_be = one / (exp(arg) - one)
1756    else
1757      occ_be = zero
1758    end if
1759  else
1760    ! No condensate for T --> 0
1761    occ_be = zero
1762  end if
1763 
1764 end function occ_be

m_occ/occ_dbe [ Functions ]

[ Top ] [ m_occ ] [ Functions ]

NAME

  occ_dbe

FUNCTION

   Derivative of Bose-Einstein statistics  (exp((e - mu)/ KT) / KT[(exp((e - mu)/ KT) - 1]^2
   Note that kT is given in Hartree so the derivative as well

INPUTS

   ee=Single particle energy in Ha
   kT=Value of K_Boltzmann x T in Ha.
   mu=Chemical potential in Ha (usually zero)

SOURCE

1784 elemental real(dp) function occ_dbe(ee, kT, mu)
1785 
1786 !Arguments ------------------------------------
1787  real(dp),intent(in) :: ee, kT, mu
1788 
1789 !Local variables ------------------------------
1790  real(dp) :: ee_mu, arg
1791 ! *************************************************************************
1792 
1793  ee_mu = ee - mu
1794 
1795  ! 1 kelvin [K] = 3.16680853419133E-06 Hartree
1796  if (kT > tol12) then
1797    arg = ee_mu / kT
1798    if (arg > tol12 .and. arg < maxDBEarg) then
1799      occ_dbe = exp(arg) / (kT * (exp(arg) - one)**2)
1800    else
1801      occ_dbe = zero
1802    end if
1803  else
1804    ! No condensate for T --> 0
1805    occ_dbe = zero
1806  end if
1807 
1808 end function occ_dbe

m_occ/occ_dfde [ Functions ]

[ Top ] [ m_occ ] [ Functions ]

NAME

  occ_dfde

FUNCTION

  Derivative of Fermi-Dirac statistics: - (exp((e - mu)/ KT) / KT[(exp((e - mu)/ KT) + 1]^2
  Note that kT is given in Hartree so the derivative as well

INPUTS

   ee=Single particle energy in Ha
   kT=Value of K_Boltzmann x T in Ha.
   mu=Chemical potential in Ha.

SOURCE

1696 elemental real(dp) function occ_dfde(ee, kT, mu)
1697 
1698 !Arguments ------------------------------------
1699  real(dp),intent(in) :: ee, kT, mu
1700 
1701 !Local variables ------------------------------
1702  real(dp) :: ee_mu,arg
1703 ! *************************************************************************
1704 
1705  ee_mu = ee - mu
1706 
1707  ! 1 kelvin [K] = 3.16680853419133E-06 Hartree
1708  if (kT > tol6) then
1709    arg = ee_mu / kT
1710    if (arg > maxDFDarg) then
1711      occ_dfde = zero
1712    else if (arg < -maxDFDarg) then
1713      occ_dfde = zero
1714    else
1715      occ_dfde = - exp(arg) / (exp(arg) + one)**2 / kT
1716    end if
1717  else
1718    occ_dfde = zero
1719  end if
1720 
1721 end function occ_dfde

m_occ/occ_fd [ Functions ]

[ Top ] [ m_occ ] [ Functions ]

NAME

  occ_fd

FUNCTION

  Fermi-Dirac statistics: 1 / [(exp((e - mu)/ KT) + 1]
  Note that occ_fs in [0, 1] so the spin factor is not included, unlike the
  occupations stored in ebands%occ.

INPUTS

   ee=Single particle energy in Ha
   kT=Value of K_Boltzmann x T in Ha.
   mu=Chemical potential in Ha.

SOURCE

1644 elemental real(dp) function occ_fd(ee, kT, mu)
1645 
1646 !Arguments ------------------------------------
1647  real(dp),intent(in) :: ee, kT, mu
1648 
1649 !Local variables ------------------------------
1650  real(dp) :: ee_mu,arg
1651 ! *************************************************************************
1652 
1653  ee_mu = ee - mu
1654 
1655  ! 1 kelvin [K] = 3.16680853419133E-06 Hartree
1656  if (kT > tol6) then
1657    arg = ee_mu / kT
1658    if (arg > maxFDarg) then
1659      occ_fd = zero
1660    else if (arg < -maxFDarg) then
1661      occ_fd = one
1662    else
1663      occ_fd = one / (exp(arg) + one)
1664    end if
1665  else
1666    ! Heaviside
1667    if (ee_mu > zero) then
1668      occ_fd = zero
1669    else if (ee_mu < zero) then
1670      occ_fd = one
1671    else
1672      occ_fd = half
1673    end if
1674  end if
1675 
1676 end function occ_fd

m_occ/occeig [ Functions ]

[ Top ] [ m_occ ] [ Functions ]

NAME

 occeig

FUNCTION

 For each pair of active bands (m,n), generates ratios
 that depend on the difference between occupation numbers and eigenvalues.

INPUTS

  doccde_k(nband_k)=derivative of occ_k wrt the energy
  doccde_kq(nband_k)=derivative of occ_kq wrt the energy
  eig0_k(nband_k)=GS eigenvalues at k
  eig0_kq(nband_k)=GS eigenvalues at k+q
  nband_k=number of bands
  occopt=option for occupancies
  occ_k(nband_k)=occupation number for each band at k
  occ_kq(nband_k)=occupation number for each band at k+q

OUTPUT

  rocceig(nband_k,nband_k)$= (occ_{k,q}(m)-occ_k(n))/(eig0_{k,q}(m)-eig0_k(n))$,
   if this ratio has been attributed to the band n, 0.0_dp otherwise

NOTES

 Supposing the occupations numbers differ:
 if $abs(occ_{k,q}(m)) < abs(occ_k(n))$
  $rocceig(m,n)=(occ_{k,q}(m)-occ_k(n))/(eig0_{k,q}(m)-eig0_k(n)) $
 if $abs(occ_{k,q}(m))>abs(occ_k(n))$
  rocceig(m,n)=0.0_dp

 If the occupation numbers are close enough, then
 if the eigenvalues are also close, take the derivative
  $ rocceig(m,n)=\frac{1}{2}*docc/deig0 $
 otherwise,
  $ rocceig(m,n)=\frac{1}{2}*(occ_{k,q}(m)-occ_k(n))/(eig0_{k,q}(m)-eig0_k(n))$

SOURCE

1553 subroutine occeig(doccde_k,doccde_kq,eig0_k,eig0_kq,nband_k,occopt,occ_k,occ_kq,rocceig)
1554 
1555 !Arguments ------------------------------------
1556 !scalars
1557  integer,intent(in) :: nband_k,occopt
1558 !arrays
1559  real(dp),intent(in) :: doccde_k(nband_k),doccde_kq(nband_k),eig0_k(nband_k)
1560  real(dp),intent(in) :: eig0_kq(nband_k),occ_k(nband_k),occ_kq(nband_k)
1561  real(dp),intent(out) :: rocceig(nband_k,nband_k)
1562 
1563 !Local variables-------------------------------
1564 !scalars
1565  integer :: ibandk,ibandkq
1566  real(dp) :: diffabsocc,diffeig,diffocc,ratio,sumabsocc
1567  character(len=500) :: msg
1568 
1569 ! *************************************************************************
1570 
1571  !The parameter tol5 defines the treshhold for degeneracy, and the width of the step function
1572 
1573  rocceig(:,:) = zero
1574 
1575  do ibandk=1,nband_k
1576    do ibandkq=1,nband_k
1577      diffeig=eig0_kq(ibandkq)-eig0_k(ibandk)
1578      diffocc=occ_kq(ibandkq)-occ_k(ibandk)
1579 
1580      if( abs(diffeig) > tol5 ) then
1581        ratio=diffocc/diffeig
1582      else
1583        if(occopt<3)then
1584          ! In a non-metallic case, if the eigenvalues are degenerate,
1585          ! the occupation numbers must also be degenerate, in which
1586          ! case there is no contribution from this pair of bands
1587          if( abs(diffocc) > tol5 ) then
1588            write(msg,'(a,a,a,a,a,a,a,2(a,i4,a,es16.6,a,es16.6,a,a),a)' ) &
1589            'In a non-metallic case (occopt<3), for a RF calculation,',ch10,&
1590            'if the eigenvalues are degenerate,',' the occupation numbers must also be degenerate.',ch10,&
1591            'However, the following pair of states gave :',ch10,&
1592            'k -state, band number',ibandk,', occ=',occ_k(ibandk),'eigenvalue=',eig0_k(ibandk),',',ch10,&
1593            ' kq-state, band number',ibandkq,', occ=',occ_kq(ibandkq),', eigenvalue=',eig0_kq(ibandkq),'.',ch10,&
1594            'Action: change occopt, consistently, in GS and RF calculations.'
1595            ABI_ERROR(msg)
1596          end if
1597          ratio=0.0_dp
1598        else
1599          ! In the metallic case, one can compute a better approximation of the
1600          ! ratio by using derivatives doccde
1601          ratio=0.5_dp*(doccde_kq(ibandkq)+doccde_k(ibandk))
1602          ! write(std_out,*)' occeig : ibandkq,doccde_kq(ibandkq)',ibandkq,doccde_kq(ibandkq)
1603          ! write(std_out,*)'          ibandk ,doccde_k (ibandk )',ibandk,doccde_k(ibandk)
1604        end if
1605      end if
1606 
1607      ! Here, must pay attention to the smallness of some coefficient
1608      diffabsocc=abs(occ_k(ibandk))-abs(occ_kq(ibandkq))
1609      sumabsocc=abs(occ_k(ibandk))+abs(occ_kq(ibandkq))
1610      if(sumabsocc>tol8)then
1611        if( diffabsocc > sumabsocc*tol5 ) then
1612          rocceig(ibandkq,ibandk)=ratio
1613        else if ( diffabsocc >= -sumabsocc*tol5 ) then
1614          rocceig(ibandkq,ibandk)=0.5_dp*ratio
1615        else
1616          rocceig(ibandkq,ibandk)=0.0_dp
1617        end if
1618      end if
1619 
1620    end do ! ibandkq
1621  end do ! ibandk
1622 
1623 end subroutine occeig