LCOV - code coverage report
Current view: top level - src/61_occeig - m_occ.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 82.4 % 790 651
Test Date: 2026-09-21 19:39:32 Functions: 90.0 % 10 9

            Line data    Source code
       1              : !!****m* ABINIT/m_occ
       2              : !! NAME
       3              : !! m_occ
       4              : !!
       5              : !! FUNCTION
       6              : !!  Low-level functions for occupation factors.
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 2008-2026 ABINIT group (XG, AF, MG)
      10              : !!  This file is distributed under the terms of the
      11              : !!  GNU General Public License, see ~abinit/COPYING
      12              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! SOURCE
      15              : 
      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              :  use m_rcpaw,        only : rcpaw_type
      34              : 
      35              :  implicit none
      36              : 
      37              :  private
      38              : !!***
      39              : 
      40              :  public :: getnel        ! Compute total number of electrons from efermi or DOS
      41              :  public :: newocc        ! Compute new occupation numbers at each k point,
      42              :  public :: occeig        ! (occ_{k,q}(m)-occ_k(n))/(eig0_{k,q}(m)-eig0_k(n))$,
      43              :  public :: occ_fd        ! Fermi-Dirac statistics 1 / [(exp((e - mu)/ KT) + 1]
      44              :  public :: occ_dfde      ! Derivative of Fermi-Dirac statistics wrt e: (exp((e - mu)/ KT) / KT[(exp((e - mu)/ KT) + 1]^2
      45              :  public :: occ_be        ! Bose-Einstein statistics  1 / [(exp((e - mu)/ KT) - 1]
      46              :  public :: occ_dbe       ! Derivative of Bose-Einstein statistics  (exp((e - mu)/ KT) / KT[(exp((e - mu)/ KT) - 1]^2
      47              :  public :: dos_hdr_write
      48              :  public :: get_fact_spin_tol_empty
      49              : 
      50              : 
      51              :  integer,parameter :: nptsdiv2_def=6000
      52              :  ! This parameter is used in init_occ_ent and getnel
      53              :  ! nptsdiv2 is the number of integration points, divided by 2.
      54              : 
      55              :  real(dp),parameter :: huge_tsmearinv = 1e50_dp
      56              :  real(dp),parameter :: maxFDarg = 500.0_dp
      57              :  real(dp),parameter :: maxDFDarg = 200.0_dp
      58              :  real(dp),parameter :: maxBEarg = 600.0_dp
      59              :  real(dp),parameter :: maxDBEarg = 200.0_dp
      60              : 
      61              : 
      62              : contains
      63              : !!***
      64              : 
      65              : !!****f* m_abinit/getnel
      66              : !! NAME
      67              : !! getnel
      68              : !!
      69              : !! FUNCTION
      70              : !! Option = 1:
      71              : !!   Get the total number of electrons nelect, given a trial fermienergy fermie.
      72              : !!   For this, compute new occupation numbers at each k point,
      73              : !!   from eigenenergies eigen, according to the
      74              : !!   smearing scheme defined by occopt (and smearing width tsmear or tphysel).
      75              : !!
      76              : !! Option = 2:
      77              : !!   Compute and output the smeared density of states, and the integrated density
      78              : !!   of states, then write these data
      79              : !!
      80              : !! Warning: this routine assumes checks have been done in the calling
      81              : !! routine, and that the values of the arguments are sensible
      82              : !!
      83              : !! NOTE
      84              : !! In order to speed the calculation, it would be easy to
      85              : !! compute the entropy only when the fermi energy is well converged
      86              : !!
      87              : !! INPUTS
      88              : !! dosdeltae= DOS delta of Energy (needed if Option=2)
      89              : !! eigen(mband*nkpt*nsppol)=eigenvalues (input or init to large number), hartree
      90              : !! fermie= fermi energy/ fermi energy for excited electrons if occopt = 9 (Hartree) ! CP description modified
      91              : !! fermih= fermi energy for excited holes (Hartree)
      92              : !! maxocc=asymptotic maximum occupation number per band
      93              : !! mband=maximum number of bands
      94              : !! nband(nkpt*nsppol)=number of bands at each k point
      95              : !! nkpt=number of k points
      96              : !! nsppol=1 for unpolarized, 2 for spin-polarized
      97              : !! occopt=option for occupancies, or re-smearing scheme if dblsmr /= 0
      98              : !! option=see above
      99              : !! tphysel="physical" electronic temperature with FD occupations
     100              : !! tsmear=smearing width (or temperature)
     101              : !! unitdos=unit number of output of the DOS. Not needed if option==1
     102              : !! wtk(nkpt)=k point weights
     103              : !! iB1, iB2 = band min and max between which to calculate the number of electrons
     104              : !! extfpmd_nbdbuf=--optional--number of bands forced to be unoccupied for extfpmd calculations
     105              : !!
     106              : !! OUTPUT
     107              : !! doccde(mband*nkpt*nsppol)=derivative of occupancies wrt the energy for each band and k point.
     108              : !! entropy= entropy associated with the smearing (adimensional)
     109              : !! nelect=number of electrons per unit cell
     110              : !! occ(mband*nkpt*nsppol)=occupancies for each band and k point.
     111              : !!
     112              : !! NOTES
     113              : !! Modified beginning 23/11/2000 by MV
     114              : !! Add an additional smearing on top of a FD type, in order to improve k-point
     115              : !! convergence: tsmear = 0 and tphysel ~= 2.e-3 corresponds to a small (300K)
     116              : !! temperature on the electrons insufficient for convergence purposes.
     117              : !! Feed re-smeared "Dirac delta" to the rest of ABINIT with only one parameter,
     118              : !! tphysel, which is the physical temperature.
     119              : !! encorr = correction to energy for terms of order tsmear^2:
     120              : !!
     121              : !!       $  E_{phys} = E_{free} - encorr*(E_{int}-E_{free}) + O(tsmear^3)  $
     122              : !!
     123              : !! SOURCE
     124              : 
     125       549521 : subroutine getnel(doccde,dosdeltae,eigen,entropy,fermie,fermih,maxocc,mband,nband,&
     126       549521 :                   nelect,nkpt,nsppol,occ,occopt,option,tphysel,tsmear,unitdos,wtk,&
     127              :                   iB1,iB2,extfpmd_nbdbuf,rcpaw) ! optional parameters
     128              : 
     129              : !Arguments ------------------------------------
     130              : !scalars
     131              :  integer,intent(in) :: mband,nkpt,nsppol,occopt,option,unitdos
     132              :  real(dp),intent(in) :: dosdeltae,fermie,fermih,maxocc,tphysel,tsmear
     133              :  real(dp),intent(out) :: entropy,nelect
     134              : !arrays
     135              :  integer,intent(in) :: nband(nkpt*nsppol)
     136              :  real(dp),intent(in) :: eigen(mband*nkpt*nsppol),wtk(nkpt)
     137              :  real(dp),intent(out) :: doccde(mband*nkpt*nsppol)
     138              :  real(dp),intent(inout) :: occ(mband*nkpt*nsppol)
     139              :  integer, intent(in), optional:: iB1, iB2 !! CP: added optional arguments to get number of electrons between bands iB1 and iB2
     140              :  integer, intent(in), optional :: extfpmd_nbdbuf
     141              :  !! Used only when occopt = 9
     142              :  type(rcpaw_type),pointer,intent(inout),optional :: rcpaw
     143              : 
     144              : !Local variables-------------------------------
     145              : ! nptsdiv2 is the number of integration points, divided by 2.
     146              : ! tratio  = ratio tsmear/tphysel for convoluted smearing function
     147              : ! save values so we can impose recalculation of smdfun when
     148              : ! the smearing or electronic temperature change between datasets
     149              : ! corresponds roughly to delta_FD (maxFDarg) = 1.0d-100
     150              : !
     151              : ! return fermi-dirac smearing function analytically
     152              : ! real(dp) :: smdFD
     153              : ! smdFD (tt) = 1.0_dp / (exp(-tt/2.0_dp) + exp(tt/2.0_dp))**2
     154              : !scalars
     155              :  integer,parameter :: prtdos1=1
     156              :  integer :: iband,iene,ikpt,index,index_tot,index_start,isppol,nene,nptsdiv2
     157              :  integer :: low_band_index, high_band_index,number_of_bands,itypat,iln,isppol_cor
     158              :  real(dp) :: buffer,deltaene,dosdbletot,doshalftot,dostot, wk
     159              :  real(dp) :: enemax,enemin,enex,intdostot,limit,tsmearinv,tsmear_eff
     160              :  !real(dp) :: cpu, wall, gflops
     161              :  character(len=500) :: msg
     162              : !arrays
     163       549521 :  real(dp),allocatable :: entfun(:,:),occfun(:,:), smdfun(:,:),xgrid(:)
     164       549521 :  real(dp),allocatable :: arg(:),derfun(:),dos(:),dosdble(:),doshalf(:),ent(:), intdos(:)
     165       549521 :  real(dp),allocatable :: occ_tmp(:),ent_tmp(:),doccde_tmp(:)
     166       549521 :  real(dp),allocatable :: dos_core(:),dosdble_core(:),doshalf_core(:),intdos_core(:)
     167       549521 :  real(dp),allocatable :: occ_tmp_core(:),doccde_tmp_core(:),arg_core(:)
     168       549521 :  real(dp),allocatable :: ent_core(:), derfun_core(:)
     169              : ! *************************************************************************
     170              : 
     171              :  !call cwtime(cpu, wall, gflops, "start")
     172              : 
     173       549521 :  if (option/=1 .and. option/=2)then
     174            0 :    ABI_BUG(sjoin('Option must be either 1 or 2. It is:', itoa(option)))
     175              :  end if
     176              : 
     177              :  ! Initialize the occupation function and generalized entropy function,
     178              :  ! at the beginning, or if occopt changed
     179              : 
     180       549521 :  if (occopt==9) then
     181         1000 :     low_band_index  = iB1
     182         1000 :     high_band_index = iB2
     183         1000 :     number_of_bands = (iB2-iB1+1)*nkpt*nsppol
     184              :  else
     185       548521 :     low_band_index  = 1
     186       548521 :     high_band_index = nband(1)
     187      8494557 :     number_of_bands = sum(nband(:))
     188              :  end if
     189      1648563 :  ABI_MALLOC(occ_tmp,(number_of_bands))
     190      1099042 :  ABI_MALLOC(ent_tmp,(number_of_bands))
     191      1099042 :  ABI_MALLOC(doccde_tmp,(number_of_bands))
     192              : 
     193              :  ! Just get the number nptsdiv2 and allocate entfun, occfun, smdfun and xgrid accordingly
     194       549521 :  nptsdiv2 = nptsdiv2_def
     195              : 
     196       549521 :  ABI_MALLOC(entfun,(-nptsdiv2:nptsdiv2,2))
     197       549521 :  ABI_MALLOC(occfun,(-nptsdiv2:nptsdiv2,2))
     198       549521 :  ABI_MALLOC(smdfun,(-nptsdiv2:nptsdiv2,2))
     199       549521 :  ABI_MALLOC(xgrid,(-nptsdiv2:nptsdiv2))
     200              : 
     201       549521 :  call init_occ_ent(entfun, limit, nptsdiv2, occfun, occopt, option, smdfun, tphysel, tsmear, tsmearinv, xgrid)
     202              :  ! The initialisation of occfun and entfun is done
     203              : 
     204              : !---------------------------------------------------------------------
     205              : 
     206              :  ! write(std_out,*)' getnel : debug  tphysel, tsmear = ', tphysel, tsmear
     207      1099042 :  ABI_MALLOC(arg,(number_of_bands))
     208      1099042 :  ABI_MALLOC(derfun,(number_of_bands))
     209      1099042 :  ABI_MALLOC(ent,(number_of_bands))
     210       549521 :  if (option==1) then
     211              :    ! normal evaluation of occupations and entropy
     212              : 
     213              :    index = 0
     214              :    index_tot = 0
     215      1181608 :    do isppol=1,nsppol
     216      9137468 :       do ikpt=1,nkpt
     217      7955860 :          if (occopt == 2) high_band_index=nband(ikpt+nkpt*(isppol-1))
     218     91564139 :          do iband=low_band_index,high_band_index
     219     83608279 :             index = index + 1
     220     91564139 :             if (tsmear==0) then
     221       262533 :                arg(index) = sign(huge_tsmearinv,fermie-eigen(index_tot + iband))
     222              :             else
     223     83345746 :                arg(index)=(fermie-eigen(index_tot + iband))*tsmearinv
     224              :             end if
     225              :          end do
     226      8587956 :          index_tot = index_tot + nband(ikpt+nkpt*(isppol-1))
     227              :       end do
     228              :    end do
     229              : 
     230              :    ! MG TODO: This part is expensive for dense k-meshes
     231              :    ! Compute the values of the occupation function, and the entropy function
     232              :    ! Note: splfit also takes care of the points outside of the interval,
     233              :    ! and assign to them the value of the closest extremal point,
     234              :    ! which is what is needed here.
     235              : 
     236       549512 :    call splfit(xgrid, doccde_tmp, occfun, 1, arg, occ_tmp, (2*nptsdiv2+1), number_of_bands)
     237       549512 :    call splfit(xgrid, derfun, entfun, 0, arg, ent, (2*nptsdiv2+1), number_of_bands)
     238              : 
     239              :    ! Normalize occ and ent, and sum number of electrons and entropy
     240              :    ! Use different loops for nelect and entropy because bantot may be quite large in the EPH code
     241              :    ! when we use very dense k-meshes.
     242              : 
     243              :    ! Manage number of bands in buffer for extfpmd calculation, when extfpmd_nbdbuf not 0.
     244              :    ! Set occupation and entropy of buffered bands to zero.
     245       549512 :    if(present(extfpmd_nbdbuf)) then
     246              :      index=0
     247              :      index_tot=0
     248      1178591 :      do isppol=1,nsppol
     249      9077567 :         do ikpt=1,nkpt
     250      7898976 :            if (occopt == 2) high_band_index=nband(ikpt+nkpt*(isppol-1))
     251     91164791 :            do iband=low_band_index,high_band_index
     252     83265815 :               index=index+1
     253     91164791 :               if (iband>high_band_index-extfpmd_nbdbuf) then
     254        56680 :                 ent(index)     = zero
     255        56680 :                 occ_tmp(index) = zero
     256              :               end if
     257              :            end do
     258      8529549 :            index_tot=index_tot+nband(ikpt+nkpt*(isppol-1))
     259              :         end do
     260              :      end do
     261              :    end if
     262              : 
     263       549512 :    nelect=zero; entropy=zero
     264       549512 :    index=0
     265       549512 :    index_tot = 0
     266      1181608 :    do isppol=1,nsppol
     267      9137468 :       do ikpt=1,nkpt
     268      7955860 :          wk = wtk(ikpt)
     269      7955860 :          if (occopt == 2) high_band_index=nband(ikpt+nkpt*(isppol-1))
     270     91564139 :          do iband=low_band_index,high_band_index
     271     83608279 :             index = index + 1
     272     83608279 :             ent(index)                = ent(index)*maxocc
     273     83608279 :             occ(iband + index_tot)    = occ_tmp(index)*maxocc
     274     83608279 :             doccde(iband + index_tot) = -doccde_tmp(index)*maxocc*tsmearinv
     275     83608279 :             entropy                   = entropy + wk*ent(index)
     276     91564139 :             nelect                    = nelect + wk*occ(iband + index_tot)
     277              :          end do
     278      8587956 :          index_tot = index_tot + nband(ikpt+nkpt*(isppol-1))
     279              :       end do
     280              :    end do
     281              : 
     282       549512 :    if(present(rcpaw)) then
     283       538896 :      if(associated(rcpaw)) then
     284          700 :        if(.not.rcpaw%frocc.or.(rcpaw%frocc.and.rcpaw%istep<=rcpaw%updateocc)) then
     285          700 :          rcpaw%entropy=zero
     286          700 :          rcpaw%nelect_core=zero
     287         1400 :          do itypat=1,rcpaw%ntypat
     288         1400 :            if(rcpaw%atm(itypat)%zcore_orig>zero) then
     289          700 :              rcpaw%atm(itypat)%zcore=zero
     290         1400 :              do isppol=1,rcpaw%atm(itypat)%nsppol
     291         2100 :                ABI_MALLOC(occ_tmp_core,(rcpaw%atm(itypat)%ln_size))
     292         1400 :                ABI_MALLOC(doccde_tmp_core,(rcpaw%atm(itypat)%ln_size))
     293         1400 :                ABI_MALLOC(arg_core,(rcpaw%atm(itypat)%ln_size))
     294         1400 :                ABI_MALLOC(derfun_core,(rcpaw%atm(itypat)%ln_size))
     295         1400 :                ABI_MALLOC(ent_core,(rcpaw%atm(itypat)%ln_size))
     296         2800 :                do iln=1,rcpaw%atm(itypat)%ln_size
     297         2800 :                  if (tsmear==0) then
     298            0 :                    arg_core(iln)=sign(huge_tsmearinv,fermie-rcpaw%atm(itypat)%eig(iln,isppol))
     299              :                  else
     300         2100 :                    arg_core(iln)=(fermie-rcpaw%atm(itypat)%eig(iln,isppol))*tsmearinv
     301              :                  end if
     302              :                enddo
     303          700 :                call splfit(xgrid, doccde_tmp_core, occfun, 1,arg_core,occ_tmp_core,(2*nptsdiv2+1),rcpaw%atm(itypat)%ln_size)
     304          700 :                call splfit(xgrid, derfun_core, entfun, 0, arg_core, ent_core,(2*nptsdiv2+1),rcpaw%atm(itypat)%ln_size)
     305         2800 :                do iln=1,rcpaw%atm(itypat)%ln_size
     306         2100 :                  rcpaw%atm(itypat)%occ(iln,isppol)=rcpaw%atm(itypat)%max_occ(iln,isppol)*occ_tmp_core(iln)
     307         2100 :                  rcpaw%atm(itypat)%zcore=rcpaw%atm(itypat)%zcore+rcpaw%atm(itypat)%occ(iln,isppol)
     308         2800 :                  rcpaw%entropy=rcpaw%entropy+ ent_core(iln)*rcpaw%atm(itypat)%max_occ(iln,isppol)*rcpaw%atm(itypat)%mult
     309              :                enddo
     310          700 :                ABI_FREE(occ_tmp_core)
     311          700 :                ABI_FREE(doccde_tmp_core)
     312          700 :                ABI_FREE(arg_core)
     313          700 :                ABI_FREE(derfun_core)
     314         1400 :                ABI_FREE(ent_core)
     315              :              enddo
     316          700 :              rcpaw%nelect_core=rcpaw%nelect_core+rcpaw%atm(itypat)%zcore*rcpaw%atm(itypat)%mult
     317              :            endif
     318              :          end do
     319          700 :          nelect=nelect+rcpaw%nelect_core
     320              :        endif
     321          700 :        entropy=entropy+rcpaw%entropy
     322              :      endif
     323              :    endif
     324              : 
     325              :    !write(std_out,*) ' getnel : debug   wtk, occ, eigen = ', wtk, occ, eigen
     326              :    !write(std_out,*)xgrid(-nptsdiv2),xgrid(nptsdiv2)
     327              :    !write(std_out,*)'fermie',fermie
     328              :    !do ii=1,bantot
     329              :    !write(std_out,*)ii,arg(ii),doccde(ii)
     330              :    !end do
     331              :    !write(std_out,*)'eigen',eigen(:)
     332              :    !write(std_out,*)'arg',arg(:)
     333              :    !write(std_out,*)'occ',occ(:)
     334              :    !write(std_out,*)'nelect',nelect
     335              : 
     336            9 :  else if (option==2) then
     337              :    ! evaluate DOS for smearing, half smearing, and double.
     338            9 :    if(tsmearinv>two*Ha_eV) then
     339            8 :      tsmear_eff=tsmear
     340              :    else ! Dirty fix for high temperatures (T>0.5eV)
     341            1 :      tsmearinv=two*Ha_eV
     342            1 :      tsmear_eff=half*ev_Ha
     343              :    endif
     344            9 :    buffer=limit/tsmearinv*.5_dp
     345              :    ! A Similar section is present is dos_calcnwrite. Should move all DOS stuff to m_ebands
     346              :    ! Choose the lower and upper energies
     347         1744 :    enemax=maxval(eigen(1:number_of_bands))+buffer
     348         1744 :    enemin=minval(eigen(1:number_of_bands))-buffer
     349            9 :    if(present(rcpaw)) then
     350            9 :      if(associated(rcpaw)) then
     351            0 :        do itypat=1,rcpaw%ntypat
     352            0 :          enemin=min(enemin,rcpaw%atm(itypat)%eig(1,1)-buffer)
     353              :        enddo
     354              :      endif
     355              :    endif
     356              : 
     357              :    ! Extend the range to a nicer value
     358            9 :    enemax=0.1_dp*ceiling(enemax*10._dp)
     359            9 :    enemin=0.1_dp*floor(enemin*10._dp)
     360              : 
     361              :    ! Choose the energy increment
     362            9 :    if(abs(dosdeltae)<tol10)then
     363            9 :      deltaene=0.001_dp
     364              :      if(prtdos1>=2)deltaene=0.0005_dp ! Higher resolution possible (and wanted) for tetrahedron
     365              :    else
     366            0 :      deltaene=dosdeltae
     367              :    end if
     368            9 :    nene=nint((enemax-enemin)/deltaene)+1
     369              : 
     370              : 
     371              :    ! Write the header of the DOS file, and also decides the energy range and increment
     372              :    call dos_hdr_write(deltaene,eigen,enemax,enemin,fermie,fermih,mband,nband,nene,&
     373            9 :            nkpt,nsppol,occopt,prtdos1,tphysel,tsmear_eff,unitdos)
     374              : 
     375           18 :    ABI_MALLOC(dos,(number_of_bands))
     376           18 :    ABI_MALLOC(dosdble,(number_of_bands))
     377           18 :    ABI_MALLOC(doshalf,(number_of_bands))
     378           18 :    ABI_MALLOC(intdos,(number_of_bands))
     379              : 
     380           21 :    do isppol=1,nsppol
     381              : 
     382           12 :      if (nsppol==2) then
     383            6 :        if(isppol==1) write(msg,'(a,16x,a)')  '#','Spin-up DOS'
     384            6 :        if(isppol==2) write(msg,'(2a,16x,a)')  ch10,'#','Spin-dn DOS '
     385            6 :        call wrtout(unitdos,msg)
     386              :      end if
     387           12 :      index_start=0
     388           12 :      if(isppol==2)then
     389           23 :        do ikpt=1,nkpt
     390           20 :           if (occopt == 2) high_band_index = nband(ikpt + nkpt*(isppol - 1))
     391           23 :           index_start=index_start + high_band_index - low_band_index + 1
     392              :        end do
     393              :      end if
     394              : 
     395           12 :      enex=enemin
     396        39933 :      do iene=1,nene
     397              : 
     398              :        ! Compute the arguments of the dos and occupation function
     399     11342918 :        arg(:)=(enex-eigen(1:number_of_bands))*tsmearinv
     400              : 
     401        39912 :        call splfit(xgrid,derfun,smdfun,0,arg,dos,(2*nptsdiv2+1),number_of_bands)
     402        39912 :        call splfit(xgrid,derfun,occfun,0,arg,intdos,(2*nptsdiv2+1),number_of_bands)
     403              : 
     404              :        ! Also compute the dos with tsmear halved and doubled
     405     11342918 :        arg(:)=arg(:)*2.0_dp
     406              :        !call splfit(xgrid,derfun,smdfun,0,arg,doshalf,(2*nptsdiv2+1),bantot)
     407        39912 :        call splfit(xgrid,derfun,smdfun,0,arg,doshalf,(2*nptsdiv2+1),number_of_bands)
     408              : 
     409              :        ! Since arg was already doubled, must divide by four
     410     11342918 :        arg(:)=arg(:)*0.25_dp
     411              :        !call splfit(xgrid,derfun,smdfun,0,arg,dosdble,(2*nptsdiv2+1),bantot)
     412        39912 :        call splfit(xgrid,derfun,smdfun,0,arg,dosdble,(2*nptsdiv2+1),number_of_bands)
     413              : 
     414              :        ! Now, accumulate the contribution from each eigenenergy
     415        39912 :        dostot=zero
     416        39912 :        intdostot=zero
     417        39912 :        doshalftot=zero
     418        39912 :        dosdbletot=zero
     419        39912 :        index=index_start
     420              : 
     421       455288 :        do ikpt=1,nkpt
     422       415376 :           if (occopt == 2) high_band_index=nband(ikpt+nkpt*(isppol-1))
     423      6869414 :           do iband=low_band_index,high_band_index
     424      6414126 :              index=index+1
     425      6414126 :              dostot=dostot+wtk(ikpt)*maxocc*dos(index)*tsmearinv
     426      6414126 :              intdostot=intdostot+wtk(ikpt)*maxocc*intdos(index)
     427      6414126 :              doshalftot=doshalftot+wtk(ikpt)*maxocc*doshalf(index)*tsmearinv*2.0_dp
     428      6829502 :              dosdbletot=dosdbletot+wtk(ikpt)*maxocc*dosdble(index)*tsmearinv*0.5_dp
     429              :           end do
     430              :        end do
     431              : 
     432        39912 :        if(present(rcpaw)) then
     433        39912 :          if(associated(rcpaw)) then
     434            0 :            do itypat=1,rcpaw%ntypat
     435            0 :              if(rcpaw%atm(itypat)%zcore_orig>zero) then
     436            0 :                do isppol_cor=1,rcpaw%atm(itypat)%nsppol
     437            0 :                  ABI_MALLOC(arg_core,(rcpaw%atm(itypat)%ln_size))
     438            0 :                  ABI_MALLOC(dos_core,(rcpaw%atm(itypat)%ln_size))
     439            0 :                  ABI_MALLOC(intdos_core,(rcpaw%atm(itypat)%ln_size))
     440            0 :                  ABI_MALLOC(doshalf_core,(rcpaw%atm(itypat)%ln_size))
     441            0 :                  ABI_MALLOC(dosdble_core,(rcpaw%atm(itypat)%ln_size))
     442            0 :                  do iln=1,rcpaw%atm(itypat)%ln_size
     443            0 :                     arg_core(iln)=(enex-rcpaw%atm(itypat)%eig(iln,isppol_cor))*tsmearinv
     444              :                  enddo
     445            0 :                  call splfit(xgrid, derfun_core, smdfun, 0, arg_core,dos_core,(2*nptsdiv2+1),rcpaw%atm(itypat)%ln_size)
     446            0 :                  call splfit(xgrid, derfun_core, occfun, 0, arg_core,intdos_core,(2*nptsdiv2+1),rcpaw%atm(itypat)%ln_size)
     447            0 :                  arg_core=arg_core*2.0_dp
     448            0 :                  call splfit(xgrid, derfun_core, smdfun,0, arg_core,doshalf_core,(2*nptsdiv2+1),rcpaw%atm(itypat)%ln_size)
     449            0 :                  arg_core=arg_core*0.25_dp
     450            0 :                  call splfit(xgrid, derfun_core, smdfun,0,arg_core,dosdble_core,(2*nptsdiv2+1),rcpaw%atm(itypat)%ln_size)
     451            0 :                  do iln=1,rcpaw%atm(itypat)%ln_size
     452              :                    dostot=dostot+rcpaw%atm(itypat)%max_occ(iln,isppol_cor)*dos_core(iln)*tsmearinv*rcpaw%atm(itypat)%mult/&
     453            0 :                                  nsppol
     454              :                    intdostot=intdostot+rcpaw%atm(itypat)%max_occ(iln,isppol_cor)*intdos_core(iln)*rcpaw%atm(itypat)%mult/&
     455            0 :                                        nsppol
     456              :                    doshalftot=doshalftot+rcpaw%atm(itypat)%max_occ(iln,isppol_cor)*doshalf_core(iln)*tsmearinv*2.0_dp*&
     457            0 :                                          rcpaw%atm(itypat)%mult/nsppol
     458              :                    dosdbletot=dosdbletot+rcpaw%atm(itypat)%max_occ(iln,isppol_cor)*dosdble_core(iln)*tsmearinv*0.5_dp*&
     459            0 :                                          rcpaw%atm(itypat)%mult/nsppol
     460              :                  enddo
     461            0 :                  ABI_FREE(arg_core)
     462            0 :                  ABI_FREE(dos_core)
     463            0 :                  ABI_FREE(intdos_core)
     464            0 :                  ABI_FREE(doshalf_core)
     465            0 :                  ABI_FREE(dosdble_core)
     466              :                enddo
     467              :              endif
     468              :            enddo
     469              :          endif
     470              :        endif
     471              : 
     472              :        ! Print the data for this energy
     473        39912 :        write(unitdos, '(f8.3,2f14.6,2f14.3)' )enex,dostot,intdostot,doshalftot,dosdbletot
     474              : 
     475        39924 :        enex=enex+deltaene
     476              :      end do ! iene
     477              :    end do ! isppol
     478              : 
     479            9 :    ABI_FREE(dos)
     480            9 :    ABI_FREE(dosdble)
     481            9 :    ABI_FREE(doshalf)
     482            9 :    ABI_FREE(intdos)
     483              : 
     484              :    ! MG: It does not make sense to close the unit here since the routines
     485              :    ! did not open the file here!
     486              :    ! Close the DOS file
     487            9 :    close(unitdos)
     488              :  end if
     489              : 
     490       549521 :  ABI_FREE(arg)
     491       549521 :  ABI_FREE(derfun)
     492       549521 :  ABI_FREE(ent)
     493       549521 :  ABI_FREE(entfun)
     494       549521 :  ABI_FREE(occfun)
     495       549521 :  ABI_FREE(smdfun)
     496       549521 :  ABI_FREE(xgrid)
     497       549521 :  ABI_FREE(occ_tmp)
     498       549521 :  ABI_FREE(doccde_tmp)
     499       549521 :  ABI_FREE(ent_tmp)
     500              : 
     501              :  !call cwtime_report(" getnel", cpu, wall, gflops, end_str=ch10)
     502              : 
     503       549521 : end subroutine getnel
     504              : !!***
     505              : 
     506              : !!****f* m_occ/newocc
     507              : !! NAME
     508              : !! newocc
     509              : !!
     510              : !! FUNCTION
     511              : !! Compute new occupation numbers at each k point,
     512              : !! from eigenenergies eigen, according to the
     513              : !! smearing scheme defined by occopt (smearing width tsmear and
     514              : !! physical temperature tphysel),
     515              : !! with the constraint of number of valence electrons per unit cell nelect.
     516              : !!
     517              : !! INPUTS
     518              : !!  eigen(mband*nkpt*nsppol)=eigenvalues (input or init to large number), hartree
     519              : !!  spinmagntarget=if differ from -99.99_dp, fix the magnetic moment (in Bohr magneton)
     520              : !!  mband=maximum number of bands
     521              : !!  nband(nkpt)=number of bands at each k point
     522              : !!  nelect=number of electrons per unit cell
     523              : !!  ne_qFD, nh_qFD=number of thermalized excited electrons (resp. holes) in bands > ivalence (resp. <= ivalence)
     524              : !!  ivalence= band index of the last valence band
     525              : !!  nkpt=number of k points
     526              : !!  nspinor=number of spinorial components of the wavefunctions
     527              : !!  nsppol=1 for unpolarized, 2 for spin-polarized
     528              : !!  occopt=option for occupancies
     529              : !!  prtstm=optional, might govern the band-by-band decomposition of the stm charge density
     530              : !!  prtvol=control print volume and debugging output
     531              : !!  stmbias= optional, if non-zero, compute occupation numbers for STM (non-zero around the Fermi energy)
     532              : !!   NOTE: in this case, only fermie and occ are meaningful outputs.
     533              : !!  extfpmd <type(extfpmd_type)>=--optional--extended first-principles molecular dynamics type
     534              : !!  tphysel="physical" electronic temperature with FD occupations
     535              : !!  tsmear=smearing width (or temperature)
     536              : !!  wtk(nkpt)=k point weights
     537              : !!
     538              : !! OUTPUT
     539              : !!  doccde(maxval(nband(:))*nkpt*nsppol)=derivative of occupancies wrt
     540              : !!           the energy for each band and k point
     541              : !!  entropy= entropy associated with the smearing (adimensional)
     542              : !!  fermie= fermi energy (Hartree)/fermi level for thermalized excited electrons in bands > ivalence when occopt=9
     543              : !!  fermih= fermi level for thermalized excited holes in bands <= ivalence
     544              : !!  occ(maxval(nband(:))*nkpt*nsppol)=occupancies for each band and k point
     545              : !!
     546              : !! SOURCE
     547              : 
     548        14188 : subroutine newocc(doccde,eigen,entropy,fermie,fermih,ivalence,spinmagntarget,mband,nband,&
     549        14188 :   nelect,ne_qFD,nh_qFD,nkpt,nspinor,nsppol,occ,occopt,prtvol,tphysel,tsmear,wtk,&
     550              :   prtstm,stmbias,extfpmd,rcpaw) ! Optional argument
     551              : 
     552              : !Arguments ------------------------------------
     553              : !scalars
     554              :  integer,intent(in) :: ivalence,mband,nkpt,nspinor,nsppol,occopt,prtvol
     555              :  integer,intent(in),optional :: prtstm
     556              :  real(dp),intent(in) :: spinmagntarget,nelect,tphysel,tsmear,ne_qFD, nh_qFD
     557              :  real(dp),intent(in),optional :: stmbias
     558              :  real(dp),intent(out) :: entropy,fermie,fermih
     559              :  type(extfpmd_type),pointer,intent(inout),optional :: extfpmd
     560              :  type(rcpaw_type),pointer,intent(inout),optional :: rcpaw
     561              : !arrays
     562              :  integer,intent(in) :: nband(nkpt*nsppol)
     563              :  real(dp),intent(in) :: eigen(mband*nkpt*nsppol),wtk(nkpt)
     564              :  real(dp),intent(out) :: doccde(mband*nkpt*nsppol)
     565              :  real(dp),intent(inout) :: occ(mband*nkpt*nsppol)
     566              : 
     567              : !Local variables-------------------------------
     568              :  integer,parameter :: niter_max=120,nkpt_max=2,fake_unit=-666,option1=1
     569              :  integer :: cnt,cnt2,cnt3,ib,iban,ibantot,ii,ik,ikpt,is,isppol,nban,nkpt_eff,sign
     570              :  integer :: extfpmd_nbdbuf=0,itypat
     571        14188 :  integer,allocatable :: nbandt(:)
     572              :  real(dp),parameter :: tol = tol14
     573              :  type(rcpaw_type),pointer :: rcpaw_getnel => null()
     574              :  !real(dp),parameter :: tol = tol10
     575              :  real(dp) :: dosdeltae,entropy_tmp,fermie_hi,fermie_lo,fermie_mid,fermie_mid_tmp
     576              :  real(dp) :: fermih_lo,fermih_mid,fermih_hi
     577              :  real(dp) :: fermie_biased,maxocc,rcpaw_nelect
     578              :  real(dp) :: nelect_tmp,nelecthi,nelectlo,nelectmid,nelect_biased
     579              :  real(dp) :: nholeshi,nholeslo,nholesmid
     580              :  real(dp) :: entropyet(2),fermie_hit(2),fermie_lot(2),fermie_midt(2),nelecthit(2)
     581              :  real(dp) :: nelectlot(2),nelectt(2),tsec(2)
     582              :  real(dp) :: entropye, entropyh
     583        14188 :  real(dp),allocatable :: doccdet(:),eigent(:),occt(:)
     584              :  character(len=500) :: msg
     585              :  logical:: not_enough_bands=.false.
     586              : ! *************************************************************************
     587              : 
     588              :  DBG_ENTER("COLL")
     589              : 
     590        14188 :  call timab(74,1,tsec)
     591              : 
     592        14188 :  rcpaw_nelect=zero
     593        14188 :  if(present(rcpaw)) then
     594        13651 :    if(associated(rcpaw))  then
     595           21 :      rcpaw_getnel=>rcpaw
     596           21 :      rcpaw_nelect=rcpaw%nelect_core
     597           42 :      do itypat=1,rcpaw%ntypat
     598           42 :        if(rcpaw%atm(itypat)%zcore_orig>zero) then
     599          126 :          rcpaw%atm(itypat)%occ_res=-rcpaw%atm(itypat)%occ
     600              :        endif
     601              :      enddo
     602              :    endif
     603              :  endif
     604              : 
     605              :  ! Here treat the case where occopt does not correspond to a metallic occupation scheme
     606        14188 :  if (occopt < 3 .or. occopt > 9) then
     607            0 :    ABI_BUG(sjoin(' occopt= ',itoa(occopt),', a value not allowed in newocc.'))
     608              :  end if
     609              : 
     610              :  ! Check whether nband is a constant for all k point and spin-pol
     611        30187 :  do isppol=1,nsppol
     612       220744 :    do ikpt=1,nkpt
     613       206556 :      if(nband(ikpt+(isppol-1)*nkpt)/=nband(1)) then
     614              :        write(msg,'(3a,i0,a,i0,a,i0,a)')&
     615            0 :        'The number of bands must be the same for all k-points ',ch10,&
     616            0 :        'but nband(1)= ',nband(1),' is different of nband(',ikpt+(isppol-1)*nkpt,') = ',nband(ikpt+(isppol-1)*nkpt),'.'
     617            0 :        ABI_BUG(msg)
     618              :      end if
     619              :    end do
     620              :  end do
     621              : 
     622              :  ! Check whether nelect is strictly positive
     623        14188 :  if (nelect <= zero) then
     624              :    write(msg,'(3a,es16.8,a)')&
     625            0 :    'nelect must be a positive number, while ',ch10, 'the calling routine asks nelect= ',nelect,'.'
     626            0 :    ABI_BUG(msg)
     627              :  end if
     628              : 
     629              :  ! Check whether the number of holes and electrons if positive
     630        14188 :  if (occopt == 9) then
     631           10 :    if ( (ne_qFD < zero) .or. (nh_qFD < zero) ) then
     632              :      write(msg,'(3a,es16.8,a,es16.8,a)')&
     633            0 :      &   'ne_qFD or nh_qFD must be positive numbers, while ',ch10,&
     634            0 :      &   'the calling routine asks ne_qFD= ',ne_qFD,' and nh_qFD= ',nh_qFD, '.'
     635            0 :      ABI_BUG(msg)
     636              :    end if
     637              :  end if
     638              : 
     639        14188 :  maxocc = two / (nsppol * nspinor)
     640              : 
     641              :  ! Check whether nelect is coherent with nband (nband(1) is enough,
     642              :  ! since it was checked that nband is independent of k-point and spin-pol
     643        14188 :  if (nelect > nband(1) * nsppol * maxocc+rcpaw_nelect) then
     644              :    write(msg,'(3a,es16.8,a,i0,a,es16.8,a)' )&
     645            0 :    'nelect must be smaller than nband*maxocc, while ',ch10,&
     646            0 :    'the calling routine gives nelect= ',nelect,', nband= ',nband(1),' and maxocc= ',maxocc,'.'
     647            0 :    ABI_BUG(msg)
     648              :  end if
     649              : 
     650              : ! Providing additional checks to ensure that there are enough valence and conduction bands
     651              : ! to accomodate ne_qFD and nh_qFD
     652        14188 :  if( occopt==9 .and. ne_qFD > (nband(1)-ivalence)*nsppol*maxocc )then
     653            0 :    write(msg,'(a,es16.8,2a,es16.8,a)') 'ne_qFD = ', ne_qFD ,ch10, &
     654            0 : &   'must be smaller than (nband-ivalence)*maxocc*nsppol = ', &
     655            0 : &   (nband(1)-ivalence)*nsppol*maxocc,'.'
     656            0 :    ABI_BUG(msg)
     657        14188 :  else if( occopt==9 .and. (nh_qFD > ivalence*nsppol*maxocc .or. &
     658              : &                          nelect - nh_qFD > ivalence*nsppol*maxocc ) )then
     659            0 :    write(msg,'(a,es16.8,2a,es16.8,2a,es16.8,a)') 'nh_qFD = ', nh_qFD ,ch10, &
     660            0 : &   'and nelect-nh_qFD = ', nelect - nh_qFD,ch10, ' must be smaller than ivalence*maxocc*nsppol = ', &
     661            0 : &   ivalence*nsppol*maxocc,'.'
     662            0 :    ABI_BUG(msg)
     663              :   end if
     664              : 
     665              :  ! Set extfpmd band buffer if needed
     666        14188 :  if(present(extfpmd)) then
     667        13675 :    if(associated(extfpmd)) then
     668           90 :      extfpmd_nbdbuf=extfpmd%nbdbuf
     669              :    end if
     670              :  end if
     671              : 
     672              :  ! Use bisection algorithm to find fermi energy
     673              :  ! This choice is due to the fact that it will always give sensible
     674              :  ! result (because the answer is bounded, even if the smearing function
     675              :  ! is non-monotonic (which is the case for occopt=4 or 6)
     676              :  ! Might speed up it, if needed !
     677              : 
     678              :  ! Lowest and largest trial fermi energies, and corresponding number of electrons
     679              :  ! They are obtained from the smallest or largest eigenenergy, plus a range of
     680              :  ! energy that allows for complete occupation of all bands, or, on the opposite,
     681              :  ! for zero occupation of all bands (see getnel.f)
     682              : 
     683        14188 :  dosdeltae = zero  ! the DOS is not computed, with option=1
     684      2066602 :  fermie_lo = minval(eigen(1:nband(1)*nkpt*nsppol)) - 6.001_dp * tsmear ! fermi_lo ->fermie_lo
     685        14188 :  if (occopt == 3 .or. occopt==9) fermie_lo = fermie_lo - 24.0_dp * tsmear
     686        14188 :  if(occopt==9) fermih_lo = fermie_lo ! Take into account holes
     687              : 
     688        14188 :  if(occopt >= 3 .and. occopt <= 8) then
     689              :     call getnel(doccde,dosdeltae,eigen,entropye,fermie_lo,fermie_lo,maxocc,mband,nband,&
     690              : & nelectlo,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk,1,nband(1),&
     691        14178 : & extfpmd_nbdbuf=extfpmd_nbdbuf,rcpaw=rcpaw_getnel)
     692           10 :  else if (occopt == 9) then
     693              :     call getnel(doccde,dosdeltae,eigen,entropye,fermie_lo,fermie_lo,maxocc,mband,nband,&
     694           10 : & nelectlo,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk, ivalence+1, nband(1)) ! Excited electrons
     695              :     call getnel(doccde,dosdeltae,eigen,entropyh,fermih_lo,fermih_lo,maxocc,mband,nband,&
     696           10 : & nholeslo,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk,1, ivalence)
     697              :  end if
     698              : 
     699      2066602 :  fermie_hi = maxval(eigen(1:nband(1)*nkpt*nsppol)) + 6.001_dp * tsmear
     700              :  ! Safety value
     701        14188 :  fermie_hi = min(fermie_hi, 1.e6_dp)
     702        14188 :  if(occopt == 3 .or. occopt == 9) fermie_hi = fermie_hi + 24.0_dp * tsmear
     703        14188 :  if(occopt == 9) fermih_hi=fermie_hi
     704              : 
     705        14188 :  if (occopt >= 3 .and. occopt <= 8) then
     706              :     call getnel(doccde,dosdeltae,eigen,entropye,fermie_hi,fermie_hi,maxocc,mband,nband,&
     707              : & nelecthi,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk,1,nband(1),&
     708        14178 : & extfpmd_nbdbuf=extfpmd_nbdbuf,rcpaw=rcpaw_getnel)
     709           10 :  else if (occopt == 9) then
     710              :     call getnel(doccde,dosdeltae,eigen,entropye,fermie_hi,fermie_hi,maxocc,mband,nband,&
     711           10 : & nelecthi,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk, ivalence+1, nband(1)) ! Excited electrons
     712           10 :     fermih_hi=fermie_hi
     713              :     call getnel(doccde,dosdeltae,eigen,entropyh,fermih_hi,fermih_hi,maxocc,mband,nband,&
     714           10 : & nholeshi,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk,1, ivalence)
     715              :  end if
     716              : 
     717              :  ! Compute the number of free electrons with corresponding chemical
     718              :  ! potential and add to nelect bounds.
     719        14188 :  if(present(extfpmd)) then
     720        13675 :    if(associated(extfpmd)) then
     721           90 :      call extfpmd%compute_nelect(fermie_lo,nband,nelectlo,nkpt,nspinor,nsppol,wtk)
     722           90 :      call extfpmd%compute_nelect(fermie_hi,nband,nelecthi,nkpt,nspinor,nsppol,wtk)
     723              :    end if
     724              :  end if
     725              : 
     726              : !Prepare fixed moment calculation
     727        14188 :  if(abs(spinmagntarget+99.99_dp)>1.0d-10)then
     728          132 :    if (occopt==9)then
     729            0 :       ABI_ERROR('occopt=9 and spinmagntarget not implemented.')
     730              :    end if
     731          132 :    sign = 1
     732          396 :    do is = 1, nsppol
     733          264 :      fermie_hit(is) = fermie_hi
     734          264 :      fermie_lot(is) = fermie_lo
     735          264 :      nelectt(is) = half*(nelect+sign*spinmagntarget)
     736          264 :      sign = -sign
     737          264 :      nelecthit(is) = nelecthi
     738          396 :      nelectlot(is) = nelectlo
     739              :    end do
     740              :  end if
     741              : 
     742              : 
     743              :  ! If the target nelect is not between nelectlo and nelecthi, exit
     744        14188 :  if ((nelect < nelectlo - tol8 .or. nelect > nelecthi + tol8) .and. (occopt <= 8)) then
     745            0 :    not_enough_bands = .true.
     746            0 :    write(msg, '(a,a,a,a,d16.8,a,a,d16.8,a,d16.8,a,a,d16.8,a,d16.8)') ch10,&
     747            0 :     ' newocc: ',ch10,&
     748            0 :     '  The calling routine gives nelect= ',nelect,ch10,&
     749            0 :     '  The lowest bound is ',fermie_lo,', with nelect=',nelectlo,ch10,&
     750            0 :     '  The highest bound is ',fermie_hi,', with nelect=',nelecthi
     751            0 :    call wrtout(std_out, msg)
     752            0 :    ABI_BUG(msg)
     753              :  end if
     754              : 
     755        14188 :  if( occopt==9 ) then
     756           10 :     if ((nelect-nh_qFD)<nholeslo .or. (nelect-nh_qFD)>nholeshi) then
     757            0 :        not_enough_bands = .true.
     758            0 :        write(msg,'(a,a,a,d16.8,a,a,d16.8,a,d16.8,a)') 'newocc : ',ch10, &
     759            0 :       'The calling routine gives nelect-nh_qFD = ', nelect-nh_qFD, ch10, &
     760            0 :        'The lowest (highest resp.) bound for nelect-nh_qFD is ', nholeslo, ' ( ', nholeshi, ' ).'
     761            0 :        ABI_BUG(msg)
     762              :     endif
     763           10 :     if ((ne_qFD < nelectlo) .or. (ne_qFD > nelecthi) ) then
     764            0 :        not_enough_bands = .true.
     765            0 :        write(msg,'(a,a,a,d16.8,a,a,d16.8,a,d16.8,a)') 'newocc : ',ch10, &
     766            0 :         'The calling routine gives ne_qFD = ', ne_qFD, ch10, 'The lowest (highest resp.) bound for ne_qFD are ',&
     767            0 :          nelectlo, ' ( ', nelecthi, ' ) .'
     768            0 :        ABI_BUG(msg)
     769              :     endif
     770              : 
     771           10 :    if (not_enough_bands) then
     772              :       write(msg, '(11a)' )&
     773            0 :        'In order to get the right number of carriers,',ch10,&
     774            0 :        'it seems that the Fermi energies must be outside the range',ch10,&
     775            0 :        'of eigenenergies, plus 6 or 30 times the smearing, which is strange.',ch10,&
     776            0 :        'It might be that your number of bands (nband) corresponds to the strictly',ch10,&
     777            0 :        'minimum number of bands to accomodate your electrons (so, OK for an insulator),',ch10,&
     778            0 :        'while you are trying to describe a metal. In this case, increase nband, otherwise ...'
     779            0 :       ABI_BUG(msg)
     780              :    end if
     781              :  end if
     782              : 
     783        14188 :  if( abs(spinmagntarget+99.99_dp) < tol10) then
     784              : 
     785              :    ! Usual bisection loop
     786       511020 :    do ii=1,niter_max
     787       511020 :      fermie_mid = (fermie_hi + fermie_lo) * half
     788       511020 :      if (occopt == 9) fermih_mid=(fermih_hi+fermih_lo)*half
     789              :      ! Produce nelectmid from fermimid
     790       511020 :      if (occopt /= 9) then
     791              : 
     792              :        call getnel(doccde,dosdeltae,eigen,entropye,fermie_mid,fermie_mid,maxocc,mband,nband,&
     793              :          nelectmid,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk, 1, nband(1),&
     794       510540 :          extfpmd_nbdbuf=extfpmd_nbdbuf,rcpaw=rcpaw_getnel)
     795              : 
     796              :        ! Compute the number of free electrons of the extfpmd model
     797              :        ! with corresponding chemical potential and add to nelect bounds.
     798       510540 :        if(present(extfpmd)) then
     799       495002 :          if(associated(extfpmd)) then
     800         4461 :            call extfpmd%compute_nelect(fermie_mid,nband,nelectmid,nkpt,nspinor,nsppol,wtk)
     801              :          end if
     802              :        end if
     803              : 
     804              :       !write(std_out,'(a,i0,1x, 3(a,es13.5))' ) " iter: ", ii, &
     805              :       !  ' fermi_mid: ',fermimid * Ha_eV, ', n_mid: ',nelectmid, &
     806              :       !  ", (n_mid-nelect)/nelect: ", (nelectmid - nelect) / nelect
     807              : 
     808              :       !if (nelectmid > nelect * (one - tol)) then
     809              :       !  fermihi = fermimid
     810              :       !  nelecthi = nelectmid
     811              :       !end if
     812              :       !if (nelectmid < nelect * (one + tol)) then
     813              :       !  fermilo = fermimid
     814              :       !  nelectlo = nelectmid
     815              :       !end if
     816       510540 :        if(nelectmid>nelect*(one-tol14))then
     817       254597 :          fermie_hi=fermie_mid
     818       254597 :          nelecthi=nelectmid
     819              :        end if
     820       510540 :        if(nelectmid<nelect*(one+tol14))then
     821       267926 :          fermie_lo=fermie_mid
     822       267926 :          nelectlo=nelectmid
     823              :        end if
     824              : 
     825              :      else
     826              : 
     827              :        call getnel(doccde,dosdeltae,eigen,entropye,fermie_mid,fermie_mid,maxocc,mband,nband,&
     828          480 :          nelectmid,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk, ivalence+1, nband(1))
     829              :        call getnel(doccde,dosdeltae,eigen,entropyh,fermih_mid,fermih_mid,maxocc,mband,nband,&
     830          480 :          nholesmid,nkpt,nsppol,occ,occopt,option1,tphysel,tsmear,fake_unit,wtk,1,ivalence)
     831              : 
     832          480 :        if(nelectmid>ne_qFD*(one-tol14))then
     833          260 :          fermie_hi = fermie_mid
     834          260 :          nelecthi  = nelectmid
     835          220 :        else if (nelectmid<ne_qFD*(one-tol14))then
     836          220 :          fermie_lo = fermie_mid
     837          220 :          nelectlo  = nelectmid
     838              :        end if
     839          480 :        if(nholesmid>(nelect-nh_qFD)*(one-tol14))then
     840          266 :          fermih_hi = fermih_mid
     841          266 :          nholeshi  = nholesmid
     842          214 :        else if(nholesmid<(nelect-nh_qFD)*(one+tol14))then
     843          214 :          fermih_lo = fermih_mid
     844          214 :          nholeslo  = nholesmid
     845              :        end if
     846              : 
     847              :      end if
     848              : 
     849              :      !if (abs(nelectmid - nelect) <= nelect*two*tol) exit
     850              :      !write(std_out,'(2(a,es13.5))' )' bisection move: fermi_lo: ',fermilo * Ha_eV,", fermi_hi: ", fermihi * Ha_eV
     851              : 
     852              : !     if (abs(nelecthi - nelectlo) <= nelect*two*tol .or. &
     853              : !         abs(fermihi - fermilo) <= tol * abs(fermihi + fermilo) ) exit
     854       511020 :      if (occopt /= 9) then
     855       510540 :         if( abs(nelecthi-nelectlo) <= nelect*two*tol14 .or. abs(fermie_hi-fermie_lo) <= tol14*abs(fermie_hi+fermie_lo) ) exit
     856              :      else
     857              :         if( ( abs(nelecthi-nelectlo) <= ne_qFD*two*tol14 .or. &
     858          480 : &             abs(fermie_hi-fermie_lo) <= tol14*abs(fermie_hi+fermie_lo) ) .and. &
     859              :             ( abs(nholeshi-nholeslo) <= (nelect-nh_qFD)*two*tol14 .or. &
     860              : &             abs(fermih_hi-fermih_lo) <= tol14*abs(fermih_hi+fermih_lo) ) ) exit
     861              :      end if
     862              : 
     863       511020 :      if (ii == niter_max) then
     864              :        write(msg,'(a,i0,3a,es22.14,a,es22.14,a)')&
     865            0 :         'It was not possible to find Fermi energy in ',niter_max,' max bisections.',ch10,&
     866            0 :         'nelecthi: ',nelecthi,', and nelectlo: ',nelectlo,'.'
     867            0 :        ABI_BUG(msg)
     868            0 :        if (occopt == 9) then
     869              :           write(msg,'(a,es22.14,a,es22.14,a)')&
     870            0 :           'nholesi = ',nholeshi,', and holeslo = ',nholeslo,'.'
     871              :        end if
     872              :      end if
     873              :    end do ! End of bisection loop
     874              : 
     875        14056 :    fermie = fermie_mid
     876        14056 :    entropy= entropye
     877              : 
     878        14056 :    if (occopt /= 9) then
     879              :       write(msg, '(2(a,f14.6),a,i0)' ) &
     880        14046 : &   ' newocc: new Fermi energy is ',fermie,' , with nelect=',nelectmid,', Number of bisection calls: ',ii
     881              :    else
     882           10 :       fermih=fermih_mid
     883           10 :       entropy = entropy + entropyh ! CP: adding entropy of the holes subsystem
     884              :       write(msg, '(2(a,f14.6),a,i0)' ) &
     885           10 : &   ' newocc: new Fermi energy for excited electrons is ',fermie,' , with ne_qFD=',nelectmid,', Number of bisection calls: ',ii
     886           10 :       call wrtout(std_out,msg,'COLL')
     887              :       write(msg, '(2(a,f14.6),a,i0)' ) &
     888           10 : &   ' newocc: new Fermi energy for excited holes     is ',fermih,' , with nh_qFD=',nelect-nholesmid,&
     889           20 : &   ', Number of bisection calls: ',ii
     890              :    end if
     891        14056 :    call wrtout(std_out,msg)
     892              : 
     893              :    !  Compute occupation numbers for prtstm/=0, close to the Fermi energy
     894        14056 :    if (present(stmbias)) then
     895              : 
     896        13575 :      if (abs(stmbias) > tol10) then
     897              : 
     898              :         ! Prevent use with occopt = 9 so far
     899              :         ! XG220804: This test is not needed, as prtstm/=0 must be used with occopt==7, as tested in chkinp.F90
     900            3 :         if (occopt == 9) then
     901            0 :           ABI_ERROR('Occopt 9 and prtstm /=0 not implemented together. Change occopt or prtstm.')
     902              :         end if
     903              : 
     904            3 :        fermie_biased = fermie - stmbias
     905            9 :        ABI_MALLOC(occt,(mband*nkpt*nsppol))
     906              : 
     907              :        call getnel(doccde,dosdeltae,eigen,entropy,fermie_biased,fermie_biased,maxocc,mband,nband,&
     908              : &         nelect_biased,nkpt,nsppol,occt,occopt,option1,tphysel,tsmear,fake_unit,wtk,1,nband(1),&
     909            3 : &         extfpmd_nbdbuf=extfpmd_nbdbuf)
     910          273 :        occ(:)=occ(:)-occt(:)
     911              : 
     912              :  !     Possibly filter a specific band contribution
     913            3 :        if (present(prtstm)) then
     914            3 :          if (prtstm < 0)then
     915              :            ibantot=1
     916            2 :            do isppol=1,nsppol
     917            8 :              do ikpt=1,nkpt
     918            6 :                nban=nband(ikpt+(isppol-1)*nkpt)
     919           97 :                do iban=1,nban
     920           90 :                  if(iban/=abs(prtstm)) occ(ibantot)=zero
     921           96 :                  ibantot=ibantot+1
     922              :                end do ! iban
     923              :              end do ! ikpt
     924              :            end do ! isppol
     925              :          end if ! prtstm < 0
     926              :        end if ! present(prtstm)
     927              : 
     928            3 :        nelect_biased = abs(nelectmid - nelect_biased)
     929              :        ! Here, arrange to have globally positive occupation numbers, irrespective of the stmbias sign
     930           93 :        if (-stmbias > tol10) occ(:) = -occ(:)
     931            3 :        ABI_FREE(occt)
     932              : 
     933            3 :        write(msg,'(a,f14.6)')' newocc: the number of electrons in the STM range is nelect_biased=',nelect_biased
     934            3 :        call wrtout(std_out,msg)
     935              :      end if
     936              :    endif ! present(stmbias)
     937              : 
     938              :  else
     939              :    ! Calculations with a specified moment
     940              :    ! Bisection loop
     941          132 :    cnt2=0
     942          132 :    cnt3=0
     943          132 :    entropy=zero
     944          132 :    maxocc=one
     945          396 :    ABI_MALLOC(doccdet,(nkpt*mband))
     946          264 :    ABI_MALLOC(eigent,(nkpt*mband))
     947          264 :    ABI_MALLOC(occt,(nkpt*mband))
     948          396 :    ABI_MALLOC(nbandt,(nkpt))
     949              : 
     950          396 :    do is = 1, nsppol
     951          264 :      nelect_tmp = nelectt(is)
     952          264 :      fermie_hi = fermie_hit(is) ! CP modify name
     953          264 :      fermie_lo = fermie_lot(is) ! CP modify name
     954          264 :      nelecthi = nelecthit(is)
     955          264 :      nelectlo = nelectlot(is)
     956              :      ! write(std_out,'(a,i1,3(f8.4,1x))') "Spin, N(spin):", is, nelect, fermihi, fermilo
     957              :      ! write(std_out,'(a,2(f8.4,1x))') "Hi, lo:", nelecthi, nelectlo
     958              : 
     959         9119 :      do ii=1,niter_max
     960         9119 :        fermie_mid_tmp=(fermie_hi+fermie_lo)/2.0_dp ! CP modify name
     961              :        ! temporary arrays
     962         9119 :        cnt = 0
     963        25965 :        do ik = 1, nkpt
     964        16846 :          nbandt(ik) = mband
     965       222689 :          do ib = 1, mband
     966       196724 :            cnt = cnt + 1
     967       196724 :            eigent(cnt) = eigen(cnt+cnt2)
     968       196724 :            occt(cnt) = occ(cnt+cnt2)
     969       213570 :            doccdet(cnt) = doccde(cnt+cnt2)
     970              :          end do
     971              :        end do
     972              : 
     973              :        ! Produce nelectmid from fermimid
     974              :        call getnel(doccdet,dosdeltae,eigent,entropy_tmp,fermie_mid_tmp,fermie_mid_tmp,maxocc,mband,nbandt,&
     975              :          nelectmid,nkpt,1,occt,occopt,option1,tphysel,tsmear,fake_unit,wtk,1,nband(1),&
     976         9119 :          extfpmd_nbdbuf=extfpmd_nbdbuf)
     977              : 
     978         9119 :        entropyet(is) = entropy_tmp
     979              :        fermie_midt(is) = fermie_mid_tmp
     980         9119 :        fermie_mid = fermie_midt(is)
     981              : 
     982              :        ! temporary arrays
     983         9119 :        cnt = 0
     984        25965 :        do ik = 1, nkpt
     985       222689 :          do ib = 1, mband
     986       196724 :            cnt = cnt + 1
     987       196724 :            occ(cnt+cnt2) = occt(cnt)
     988       213570 :            doccde(cnt+cnt2) = doccdet(cnt)
     989              :          end do
     990              :        end do
     991              :        ! write(std_out,'(a,es24.16,a,es24.16)' )' newocc: from fermi=',fermimid,', getnel gives nelect=',nelectmid
     992              : 
     993         9119 :        if(nelectmid>=nelect_tmp)then
     994         4474 :          fermie_hi=fermie_mid_tmp
     995         4474 :          nelecthi=nelectmid
     996              :        else
     997         4645 :          fermie_lo=fermie_mid_tmp
     998         4645 :          nelectlo=nelectmid
     999              :        end if
    1000         9119 :        if( abs(nelecthi-nelectlo) <= 1.0d-13 .or. abs(fermie_hi-fermie_lo) <= 0.5d-14*abs(fermie_hi+fermie_lo) ) exit
    1001              : 
    1002         9119 :        if(ii==niter_max)then
    1003              :          write(msg,'(a,i3,3a,es22.14,a,es22.14,a)')&
    1004            0 :           'It was not possible to find Fermi energy in ',niter_max,' bisections.',ch10,&
    1005            0 :           'nelecthi: ',nelecthi,', and nelectlo: ',nelectlo,'.'
    1006            0 :          ABI_BUG(msg)
    1007              :        end if
    1008              :      end do ! End of bisection loop
    1009              : 
    1010          264 :      cnt2 = cnt2 + nkpt*mband
    1011          264 :      entropy = entropy + entropyet(is)
    1012          264 :      fermie=fermie_mid
    1013              :      write(msg, '(a,i2,a,f14.6,a,f14.6,a,a,i4)' ) &
    1014          264 :        ' newocc: new Fermi energy for spin ', is, ' is ',fermie,' , with nelect: ',nelectmid,ch10,&
    1015          528 :        '  Number of bisection calls =',ii
    1016          396 :      call wrtout(std_out,msg)
    1017              : 
    1018              :    end do ! spin
    1019              : 
    1020          132 :    ABI_FREE(doccdet)
    1021          132 :    ABI_FREE(eigent)
    1022          132 :    ABI_FREE(nbandt)
    1023          132 :    ABI_FREE(occt)
    1024              : 
    1025              :  end if ! End of logical on fixed moment calculations
    1026              : 
    1027        14188 :  if(present(rcpaw)) then
    1028        13651 :    if(associated(rcpaw))  then
    1029           42 :      do itypat=1,rcpaw%ntypat
    1030           42 :        if(rcpaw%atm(itypat)%zcore_orig>zero) then
    1031          126 :          rcpaw%atm(itypat)%occ_res=rcpaw%atm(itypat)%occ_res+rcpaw%atm(itypat)%occ
    1032              :        endif
    1033              :      enddo
    1034              :    endif
    1035              :  endif
    1036              : 
    1037              :  !write(std_out,*) "kT*Entropy:", entropy*tsmear
    1038              : 
    1039              :  ! MG: If you are wondering why this part is now disabled by default consider that this output
    1040              :  ! is produced many times in the SCF cycle and in EPH we have to call this routine for
    1041              :  ! several temperature and the log becomes unreadable.
    1042              :  ! If you really need to look at the occupation factors use prtvol > 0.
    1043        14188 :  nkpt_eff = nkpt
    1044        14188 :  if (prtvol == 0) nkpt_eff = 0
    1045        14188 :  if (prtvol == 1) nkpt_eff = min(nkpt_max, nkpt)
    1046              : 
    1047        14188 :  if (nsppol == 1)then
    1048              : 
    1049        12377 :    if (nkpt_eff /= 0) then
    1050         2489 :      write(msg, '(a,i0,a)' )' newocc: computed new occ. numbers for occopt= ',occopt,' , spin-unpolarized case. '
    1051         2489 :      call wrtout(std_out,msg)
    1052        20346 :      do ikpt=1,nkpt_eff
    1053        17857 :        write(msg,'(a,i4,a)' ) ' k-point number ',ikpt,' :'
    1054        45481 :        do ii=0,(nband(1)-1)/12
    1055        25299 :          if (ii == 3 .and. prtvol /= 0) exit
    1056        25135 :          write(msg,'(12f6.3)') occ(1+ii*12+(ikpt-1)*nband(1):min(12+ii*12,nband(1))+(ikpt-1)*nband(1))
    1057        42992 :          call wrtout(std_out,msg)
    1058              :        end do
    1059              :      end do
    1060         2489 :      if (nkpt /= nkpt_eff) call wrtout(std_out,' newocc: prtvol=0, stop printing more k-point information')
    1061              : 
    1062              :      !call wrtout(std_out,' newocc: corresponding derivatives are ')
    1063              :      !do ikpt=1,nkpt_eff
    1064              :      !write(msg,'(a,i4,a)' ) ' k-point number ',ikpt,' :'
    1065              :      !do ii=0,(nband(1)-1)/12
    1066              :      !write(msg,'(12f6.1)') doccde(1+ii*12+(ikpt-1)*nband(1):min(12+ii*12,nband(1))+(ikpt-1)*nband(1))
    1067              :      !call wrtout(std_out,msg)
    1068              :      !end do
    1069              :      !end do
    1070              :      !if(nkpt/=nkpt_eff)then
    1071              :      !  call wrtout(std_out,'newocc: prtvol=0, stop printing more k-point information')
    1072              :      !end if
    1073              :    end if
    1074              : 
    1075              :  else
    1076              : 
    1077         1811 :    if (nkpt_eff /= 0) then
    1078          721 :      write(msg, '(a,i0,2a)' )' newocc: computed new occupation numbers for occopt= ',occopt,ch10,'  (1) spin up   values  '
    1079          721 :      call wrtout(std_out, msg)
    1080         6291 :      do ikpt=1,nkpt_eff
    1081         5570 :        write(msg,'(a,i0,a)' ) ' k-point number ',ikpt,':'
    1082        16282 :        do ii=0,(nband(1)-1)/12
    1083         9991 :          if (ii == 3 .and. prtvol /= 0) exit
    1084         9991 :          write(msg,'(12f6.3)') occ(1+ii*12+(ikpt-1)*nband(1):min(12+ii*12,nband(1))+(ikpt-1)*nband(1))
    1085        15561 :          call wrtout(std_out,msg)
    1086              :        end do
    1087              :      end do
    1088          721 :      if (nkpt/=nkpt_eff) call wrtout(std_out,' newocc: prtvol=0, stop printing more k-point information')
    1089              : 
    1090          721 :      call wrtout(std_out,'  (2) spin down values  ')
    1091         6291 :      do ikpt=1,nkpt_eff
    1092        16282 :        do ii=0,(nband(1)-1)/12
    1093         9991 :          if (ii == 3 .and. prtvol /= 0) exit
    1094         9991 :          write(msg,'(12f6.3)') occ( 1+ii*12+(ikpt-1+nkpt)*nband(1):min(12+ii*12,nband(1))+(ikpt-1+nkpt)*nband(1) )
    1095        15561 :          call wrtout(std_out,msg)
    1096              :        end do
    1097              :      end do
    1098          721 :      if(nkpt/=nkpt_eff) call wrtout(std_out,' newocc: prtvol=0, stop printing more k-point information')
    1099              :    end if
    1100              : 
    1101              :  end if ! End choice based on spin
    1102              : 
    1103        14188 :  rcpaw_getnel=>null()
    1104              : 
    1105        14188 :  call timab(74,2,tsec)
    1106              : 
    1107              :  DBG_EXIT("COLL")
    1108              : 
    1109        14188 : end subroutine newocc
    1110              : !!***
    1111              : 
    1112              : !!****f* m_occ/init_occ_ent
    1113              : !! NAME
    1114              : !! init_occ_ent
    1115              : !!
    1116              : !! FUNCTION
    1117              : !!
    1118              : !! INPUTS
    1119              : !!
    1120              : !! OUTPUT
    1121              : !!
    1122              : !! SOURCE
    1123              : 
    1124       549521 : subroutine init_occ_ent(entfun,limit,nptsdiv2,occfun,occopt,option,smdfun,tphysel,tsmear,tsmearinv,xgrid)
    1125              : 
    1126              : !Arguments ------------------------------------
    1127              : !scalars
    1128              :  integer,intent(in) :: occopt,option
    1129              :  real(dp),intent(in) :: tphysel,tsmear
    1130              :  integer,intent(inout) :: nptsdiv2
    1131              :  real(dp),intent(out) :: limit,tsmearinv
    1132              :  real(dp),intent(inout) :: entfun(-nptsdiv2:nptsdiv2,2),occfun(-nptsdiv2:nptsdiv2,2)
    1133              :  real(dp),intent(inout) :: smdfun(-nptsdiv2:nptsdiv2,2),xgrid(-nptsdiv2:nptsdiv2)
    1134              : 
    1135              : !Local variables-------------------------------
    1136              : !scalars
    1137              :  integer :: algo,ii,jj,nconvd2,nmaxFD,nminFD
    1138              :  integer,save :: dblsmr,occopt_prev=-9999
    1139              :  real(dp),save :: convlim,incconv,limit_occ,tphysel_prev=-9999,tsmear_prev=-9999
    1140              :  real(dp) :: aa,dsqrpi,encorr,factor
    1141              :  real(dp) :: expinc,expx22,expxo2,gauss,increm
    1142              :  real(dp) :: resFD1,resFD2,resFD3,resFD4,resmom,resmom1,resmom2
    1143              :  real(dp) :: resmom3,resmom4,secmom,smom1,smom2,thdmom,tmom1,tmom2,tmpexpsum
    1144              :  real(dp) :: tmpsmdfun,tratio,tt,xx,yp1,ypn
    1145              :  character(len=500) :: msg
    1146              : !arrays
    1147              :  real(dp),save :: entfun_prev(-nptsdiv2_def:nptsdiv2_def,2),occfun_prev(-nptsdiv2_def:nptsdiv2_def,2)
    1148              :  real(dp),save :: smdfun_prev(-nptsdiv2_def:nptsdiv2_def,2),xgrid_prev(-nptsdiv2_def:nptsdiv2_def)
    1149       549521 :  real(dp),allocatable :: entder(:),occder(:),smd1(:),smd2(:)
    1150       549521 :  real(dp),allocatable :: smdder(:),tgrid(:),work(:),workfun(:)
    1151              : ! *************************************************************************
    1152              : 
    1153              :  ! Initialize the occupation function and generalized entropy function,
    1154              :  ! at the beginning, or if occopt changed
    1155              : 
    1156       549521 :  if(option==-1)then
    1157            0 :    nptsdiv2 = nptsdiv2_def
    1158            0 :    return
    1159              :  end if
    1160              : 
    1161       549521 :  if (occopt_prev/=occopt .or. abs(tsmear_prev-tsmear)  >tol12 .or. abs(tphysel_prev-tphysel)>tol12) then
    1162          753 :    occopt_prev=occopt
    1163          753 :    tsmear_prev=tsmear
    1164          753 :    tphysel_prev=tphysel
    1165              : 
    1166              :    ! Check whether input values of tphysel tsmear and occopt are consistent
    1167          753 :    dblsmr = 0
    1168          753 :    if (abs(tphysel)>tol12) then
    1169              :      ! Use re-smearing scheme
    1170           10 :      if (abs(tsmear)>tol12) then
    1171           10 :        dblsmr = 1
    1172              :        ! Use FD occupations (one smearing) only with "physical" temperature tphysel
    1173              :      ! CP modify
    1174              :      !else if (occopt /= 3) then
    1175              :      !  write(msg, '(a,i6,a)' )' tphysel /= 0, tsmear == 0, but occopt is not = 3, but ',occopt,'.'
    1176            0 :      else if (occopt /= 3 .and. occopt/=9) then
    1177            0 :        write(msg, '(a,i6,a)' )' tphysel /= 0, tsmear == 0, but occopt is not = 3 or 9, but ',occopt,'.'
    1178              :      ! End CP modify
    1179            0 :        ABI_ERROR(msg)
    1180              :      end if
    1181              :    end if
    1182              : 
    1183          753 :    ABI_MALLOC(entder,(-nptsdiv2_def:nptsdiv2_def))
    1184          753 :    ABI_MALLOC(occder,(-nptsdiv2_def:nptsdiv2_def))
    1185          753 :    ABI_MALLOC(smdder,(-nptsdiv2_def:nptsdiv2_def))
    1186          753 :    ABI_MALLOC(workfun,(-nptsdiv2_def:nptsdiv2_def))
    1187          753 :    ABI_MALLOC(work,(-nptsdiv2_def:nptsdiv2_def))
    1188              : 
    1189              :    ! Prepare the points on the grid
    1190              :    ! limit is the value of the argument that will give 0.0 or 1.0 , with
    1191              :    ! less than about 1.0d-15 error for 4<=occopt<=8, and less than about 1.0d-12
    1192              :    ! error for occopt==3. It is not worth to compute the function beyond
    1193              :    ! that point. Even with a less severe requirement, it is significantly
    1194              :    ! larger for occopt==3, with an exponential
    1195              :    ! tail, than for the other occupation functions, with a Gaussian tail.
    1196              :    ! Note that these values are useful in newocc.f also.
    1197          753 :    limit_occ=6.0_dp
    1198              :    ! CP modify
    1199              :    !if(occopt==3)limit_occ=30.0_dp
    1200          753 :    if(occopt==3 .or. occopt==9)limit_occ=30.0_dp
    1201              :    ! End CP modify
    1202          753 :    if(dblsmr /= 0) then
    1203           10 :      tratio = tsmear / tphysel
    1204           10 :      limit_occ=30.0_dp + 6.0_dp*tratio
    1205              :    end if
    1206              : 
    1207              :    ! With nptsdiv2_def=6000 (thus increm=0.001 for 4<=occopt<=8,
    1208              :    ! and increm=0.005 for occopt==3, the O(1/N4) algorithm gives 1.0d-12
    1209              :    ! accuracy on the stored values occfun and entfun. These, together
    1210              :    ! with smdfun and xgrid_prev, need permanently about 0.67 MB, which is affordable.
    1211          753 :    increm=limit_occ/nptsdiv2_def
    1212      9037506 :    do ii=-nptsdiv2_def,nptsdiv2_def
    1213      9037506 :      xgrid_prev(ii)=ii*increm
    1214              :    end do
    1215              : 
    1216              :    !  ---------------------------------------------------------
    1217              :    !  Ordinary (unique) smearing function
    1218              :    !  ---------------------------------------------------------
    1219          753 :    if (dblsmr == 0) then
    1220              : 
    1221              :      ! Compute the unnormalized smeared delta function between -limit_occ and +limit_occ
    1222              :      ! (well, they are actually normalized ...)
    1223              : 
    1224              :      ! CP modify
    1225              :      !if(occopt==3)then
    1226              :      if(occopt==3 .or. occopt==9)then
    1227              :      ! End CP modify
    1228              :        ! Fermi-Dirac
    1229      2448816 :        do ii=0,nptsdiv2_def
    1230      2448408 :          xx=xgrid_prev(ii)
    1231      2448408 :          smdfun_prev( ii,1)=0.25_dp/(cosh(xx/2.0_dp)**2)
    1232      2448816 :          smdfun_prev(-ii,1)=smdfun_prev(ii,1)
    1233              :        end do
    1234              : 
    1235              :      else if(occopt==4 .or. occopt==5)then
    1236              :        ! Cold smearing of Marzari, two values of the "a" parameter being possible
    1237              :        ! first value gives minimization of the bump
    1238              :        if(occopt==4)aa=-.5634
    1239              :        ! second value gives monotonic occupation function
    1240          122 :        if(occopt==5)aa=-.8165
    1241              : 
    1242          122 :        dsqrpi=1.0_dp/sqrt(pi)
    1243       732244 :        do ii=0,nptsdiv2_def
    1244       732122 :          xx=xgrid_prev(ii)
    1245       732122 :          gauss=dsqrpi*exp(-xx**2)
    1246       732122 :          smdfun_prev( ii,1)=gauss*(1.5_dp+xx*(-aa*1.5_dp+xx*(-1.0_dp+aa*xx)))
    1247       732244 :          smdfun_prev(-ii,1)=gauss*(1.5_dp+xx*( aa*1.5_dp+xx*(-1.0_dp-aa*xx)))
    1248              :        end do
    1249              : 
    1250              :      else if(occopt==6)then
    1251              : 
    1252              :        ! First order Hermite-Gaussian of Paxton and Methfessel
    1253        30010 :        dsqrpi=1.0_dp/sqrt(pi)
    1254        30010 :        do ii=0,nptsdiv2_def
    1255        30005 :          xx=xgrid_prev(ii)
    1256        30005 :          smdfun_prev( ii,1)=dsqrpi*(1.5_dp-xx**2)*exp(-xx**2)
    1257        30010 :          smdfun_prev(-ii,1)=smdfun_prev(ii,1)
    1258              :        end do
    1259              : 
    1260              :      else if(occopt==7)then
    1261              : 
    1262              :        ! Gaussian smearing
    1263      1248416 :        dsqrpi=1.0_dp/sqrt(pi)
    1264      1248416 :        do ii=0,nptsdiv2_def
    1265      1248208 :          xx=xgrid_prev(ii)
    1266      1248208 :          smdfun_prev( ii,1)=dsqrpi*exp(-xx**2)
    1267      1248416 :          smdfun_prev(-ii,1)=smdfun_prev(ii,1)
    1268              :        end do
    1269              : 
    1270              :      else if(occopt==8)then
    1271              : 
    1272              :        ! Constant value of the delta function over the smearing interval, for testing purposes only.
    1273            0 :        do ii=0,nptsdiv2_def
    1274            0 :          xx=xgrid_prev(ii)
    1275            0 :          if(xx>half+tol8)then
    1276            0 :            smdfun_prev( ii,1)=zero
    1277            0 :          else if(xx<half-tol8)then
    1278            0 :            smdfun_prev( ii,1)=one
    1279              :          else
    1280            0 :            smdfun_prev( ii,1)=half
    1281              :          end if
    1282            0 :          smdfun_prev(-ii,1)=smdfun_prev(ii,1)
    1283              :        end do
    1284              : 
    1285              :      else
    1286            0 :        ABI_BUG(sjoin('Occopt: ', itoa(occopt),' is not allowed in getnel.'))
    1287              :      end if
    1288              : 
    1289              :    else if (dblsmr /= 0) then
    1290              :      !    ---------------------------------------------------------
    1291              :      !    smear FD delta with occopt delta calculated in smdfun_prev
    1292              :      !    ---------------------------------------------------------
    1293              : 
    1294           10 :      nconvd2 = 6000
    1295           10 :      convlim = 10.0_dp
    1296           10 :      incconv = convlim / nconvd2
    1297              : 
    1298              :      ! store smearing functions in smd1 and smd2
    1299           10 :      ABI_MALLOC(smd1,(-nconvd2:nconvd2))
    1300           10 :      ABI_MALLOC(smd2,(-nconvd2:nconvd2))
    1301           10 :      ABI_MALLOC(tgrid,(-nconvd2:nconvd2))
    1302              : 
    1303              :      ! FD function in smd1( ii) and second smearing delta in smd2( ii)
    1304              :      !
    1305              :      ! smd1(:) contains delta_FD ( x )
    1306        60020 :      do ii=0,nconvd2
    1307        60010 :        tgrid(ii)=ii*incconv
    1308        60010 :        tgrid(-ii)=-tgrid(ii)
    1309        60010 :        tt=tgrid(ii)
    1310        60010 :        smd1( ii)=0.25_dp/(cosh(tt/2.0_dp)**2)
    1311        60020 :        smd1(-ii)=smd1(ii)
    1312              :      end do
    1313              : 
    1314              :      ! check input values of occopt and fill smd2(:) with appropriate data:
    1315              :      ! smd2(:) contains delta_resmear ( x )
    1316              :      ! CP modify
    1317              :      !if(occopt == 3) then
    1318              :      if(occopt == 3 .or. occopt==9) then
    1319              :      ! End CP modify
    1320              :        write(msg, '(a,a)' )&
    1321            0 :         'Occopt=3 is not allowed as a re-smearing.', &
    1322            0 :         'Use a single FD, or re-smear with a different delta type (faster cutoff). '
    1323            0 :        ABI_ERROR(msg)
    1324              :      else if(occopt==4 .or. occopt==5)then
    1325              :        ! Cold smearing of Marzari, two values of the "a" parameter being possible
    1326              :        ! first value gives minimization of the bump
    1327              :        if(occopt==4)aa=-.5634
    1328              :        ! second value gives monotonic occupation function
    1329           10 :        if(occopt==5)aa=-.8165
    1330              : 
    1331           10 :        dsqrpi=1.0_dp/sqrt(pi)
    1332        60020 :        do ii=0,nconvd2
    1333        60010 :          tt=tgrid(ii)
    1334        60010 :          gauss=dsqrpi*exp(-tt**2)
    1335        60010 :          smd2( ii)=gauss*(1.5_dp+tt*(-aa*1.5_dp+tt*(-1.0_dp+aa*tt)))
    1336        60020 :          smd2(-ii)=gauss*(1.5_dp+tt*( aa*1.5_dp+tt*(-1.0_dp-aa*tt)))
    1337              :        end do
    1338              :      else if(occopt==6)then
    1339            0 :        dsqrpi=1.0_dp/sqrt(pi)
    1340            0 :        do ii=0,nconvd2
    1341            0 :          tt=tgrid(ii)
    1342            0 :          smd2( ii)=dsqrpi*(1.5_dp-tt**2)*exp(-tt**2)
    1343            0 :          smd2(-ii)=smd2(ii)
    1344              :        end do
    1345              :      else if(occopt==7)then
    1346            0 :        dsqrpi=1.0_dp/sqrt(pi)
    1347            0 :        do ii=0,nconvd2
    1348            0 :          tt=tgrid(ii)
    1349            0 :          smd2( ii)=dsqrpi*exp(-tt**2)
    1350            0 :          smd2(-ii)=smd2(ii)
    1351              :        end do
    1352              :      else if(occopt==8)then
    1353            0 :        do ii=0,nconvd2
    1354            0 :          tt=tgrid(ii)
    1355            0 :          if(tt>half+tol8)then
    1356            0 :            smd2( ii)=zero
    1357            0 :          else if(tt<half-tol8)then
    1358            0 :            smd2( ii)=one
    1359              :          else
    1360            0 :            smd2( ii)=half
    1361              :          end if
    1362            0 :          smd2(-ii)=smd2(ii)
    1363              :        end do
    1364              :      else
    1365            0 :        ABI_BUG(sjoin('Occopt: ', itoa(occopt),' is not allowed in getnel.'))
    1366              :      end if
    1367              : 
    1368              :      ! Use O(1/N4) algorithm from Num Rec (see below)
    1369              :      !
    1370              :      ! The grid for the convoluted delta is taken (conservatively)
    1371              :      ! to be that for the FD delta ie 6000 pts in [-limit_occ;limit_occ]
    1372              :      ! Smearing functions are given on [-dbllim;dbllim] and the grid must
    1373              :      ! superpose the normal grid on [-limit_occ:limit_occ]
    1374              :      ! The maximal interval for integration of the convolution is
    1375              :      ! [-dbllim+limit_occ+lim(delta2);dbllim-limit_occ-lim(delta2)] =
    1376              :      ! [-dbllim+36;dbllim-36]
    1377              : 
    1378              :      ! test the smdFD function for extreme values:
    1379              :      ! do jj=-nptsdiv2_def,-nptsdiv2_def
    1380              :      ! do ii=-nconvd2+4,nconvd2
    1381              :      ! call smdFD(xgrid_prev(jj) - tgrid(ii)*tratio, resFD)
    1382              :      ! write(std_out,*) 'ii jj = ', ii,jj, ' smdFD (', xgrid_prev(jj) - tgrid(ii)*tratio, ') ', resFD
    1383              :      ! end do
    1384              :      ! end do
    1385              : 
    1386           10 :      expinc = exp(half*incconv*tratio)
    1387              : 
    1388              :      ! jj = position of point at which we are calculating smdfun_prev
    1389       120020 :      do jj=-nptsdiv2_def,nptsdiv2_def
    1390              :        ! Do not care about the 8 boundary points,
    1391              :        ! where the values should be extremely small anyway
    1392       120010 :        smdfun_prev(jj,1)=0.0_dp
    1393              :        ! only add contribution with delta_FD > 1.0d-100
    1394       120010 :        nmaxFD = floor  (( maxFDarg+xgrid_prev(jj)) / tratio / incconv )
    1395       120010 :        nmaxFD = min (nmaxFD, nconvd2)
    1396       120010 :        nminFD = ceiling((-maxFDarg+xgrid_prev(jj)) / tratio / incconv )
    1397       120010 :        nminFD = max (nminFD, -nconvd2)
    1398              : 
    1399              :        ! Calculate the Fermi-Dirac distrib at point xgrid_prev(jj)-tgrid(ii)*tratio
    1400       120010 :        expxo2 = exp (-half*(xgrid_prev(jj) - (nminFD)*incconv*tratio))
    1401       120010 :        expx22 = expxo2*expxo2
    1402       120010 :        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
    1403       120010 :        resFD4 = tmpexpsum * tmpexpsum
    1404       120010 :        expxo2 = expxo2*expinc
    1405       120010 :        expx22 = expxo2*expxo2
    1406       120010 :        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
    1407       120010 :        resFD3 = tmpexpsum * tmpexpsum
    1408       120010 :        expxo2 = expxo2*expinc
    1409       120010 :        expx22 = expxo2*expxo2
    1410       120010 :        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
    1411       120010 :        resFD2 = tmpexpsum * tmpexpsum
    1412       120010 :        expxo2 = expxo2*expinc
    1413       120010 :        expx22 = expxo2*expxo2
    1414       120010 :        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
    1415       120010 :        resFD1 = tmpexpsum * tmpexpsum
    1416              : 
    1417              :        ! core contribution to the integral with constant weight (48)
    1418       120010 :        tmpsmdfun = 0.0_dp
    1419   1339688356 :        do ii=nminFD+4,nmaxFD-4
    1420   1339568346 :          expxo2 = expxo2*expinc
    1421              :          ! tmpexpsum = 1.0_dp / (expxo2 + 1.0_dp / expxo2 )
    1422   1339568346 :          expx22 = expxo2*expxo2
    1423   1339568346 :          tmpexpsum = expxo2 / (expx22 + 1.0_dp)
    1424   1339688356 :          tmpsmdfun = tmpsmdfun + smd2(ii) * tmpexpsum * tmpexpsum
    1425              :        end do
    1426              : 
    1427              :        ! Add on end contributions for show (both functions smd and smdFD are very small
    1428              :        smdfun_prev(jj,1)=smdfun_prev(jj,1)       +48.0_dp*tmpsmdfun             &
    1429              :          + 31.0_dp*smd2(nminFD+3)*resFD1 -11.0_dp*smd2(nminFD+2)*resFD2 &
    1430       120010 :          +  5.0_dp*smd2(nminFD+1)*resFD3 -       smd2(nminFD)*resFD4
    1431              : 
    1432       120010 :        expxo2 = expxo2*expinc
    1433       120010 :        expx22 = expxo2*expxo2
    1434       120010 :        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
    1435       120010 :        resFD1 = tmpexpsum * tmpexpsum
    1436       120010 :        expxo2 = expxo2*expinc
    1437       120010 :        expx22 = expxo2*expxo2
    1438       120010 :        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
    1439       120010 :        resFD2 = tmpexpsum * tmpexpsum
    1440       120010 :        expxo2 = expxo2*expinc
    1441       120010 :        expx22 = expxo2*expxo2
    1442       120010 :        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
    1443       120010 :        resFD3 = tmpexpsum * tmpexpsum
    1444       120010 :        expxo2 = expxo2*expinc
    1445       120010 :        expx22 = expxo2*expxo2
    1446       120010 :        tmpexpsum = expxo2 / (expx22 + 1.0_dp)
    1447       120010 :        resFD4 = tmpexpsum * tmpexpsum
    1448              : 
    1449              :        ! Contribution above
    1450              :        smdfun_prev(jj,1)=smdfun_prev(jj,1)                                      &
    1451              :          + 31.0_dp*smd2(nmaxFD-3)*resFD1  -11.0_dp*smd2(nmaxFD-2)*resFD2 &
    1452       120010 :          +  5.0_dp*smd2(nmaxFD-1)*resFD3  -       smd2(nmaxFD)*resFD4
    1453       120020 :        smdfun_prev(jj,1)=incconv*smdfun_prev(jj,1)/48.0_dp
    1454              :      end do
    1455              : 
    1456           10 :      secmom = 0.0_dp
    1457           10 :      thdmom = 0.0_dp
    1458           10 :      resmom4 = xgrid_prev(-nptsdiv2_def  )*xgrid_prev(-nptsdiv2_def  )*smdfun_prev(-nptsdiv2_def  ,  1)
    1459           10 :      resmom3 = xgrid_prev(-nptsdiv2_def+1)*xgrid_prev(-nptsdiv2_def+1)*smdfun_prev(-nptsdiv2_def+1,  1)
    1460           10 :      resmom2 = xgrid_prev(-nptsdiv2_def+2)*xgrid_prev(-nptsdiv2_def+2)*smdfun_prev(-nptsdiv2_def+2,  1)
    1461           10 :      resmom1 = xgrid_prev(-nptsdiv2_def+3)*xgrid_prev(-nptsdiv2_def+3)*smdfun_prev(-nptsdiv2_def+3,  1)
    1462           10 :      resmom  = xgrid_prev(-nptsdiv2_def+4)*xgrid_prev(-nptsdiv2_def+4)*smdfun_prev(-nptsdiv2_def+4,  1)
    1463           10 :      do ii=-nptsdiv2_def+4,nptsdiv2_def-1
    1464              :        secmom = secmom +                                   &
    1465              : &       ( 17.0_dp*xgrid_prev(ii)  *xgrid_prev(ii)  *smdfun_prev(ii,  1)   &
    1466              : &       +42.0_dp*xgrid_prev(ii-1)*xgrid_prev(ii-1)*smdfun_prev(ii-1,1)   &
    1467              : &       -16.0_dp*xgrid_prev(ii-2)*xgrid_prev(ii-2)*smdfun_prev(ii-2,1)   &
    1468              : &       + 6.0_dp*xgrid_prev(ii-3)*xgrid_prev(ii-3)*smdfun_prev(ii-3,1)   &
    1469              : &       -       xgrid_prev(ii-4)*xgrid_prev(ii-4)*smdfun_prev(ii-4,1)  )
    1470              :        resmom4 = resmom3
    1471              :        resmom3 = resmom2
    1472              :        resmom2 = resmom1
    1473              :        resmom1 = resmom
    1474              :        resmom  = xgrid_prev(ii+1)  *xgrid_prev(ii+1)  *smdfun_prev(ii+1,  1)
    1475              :      end do
    1476           10 :      secmom=increm * secmom / 48.0_dp
    1477              :      ! thdmom=increm * thdmom / 48.0_dp
    1478              :      !
    1479              :      ! smom1  = second moment of delta in smd1(:)
    1480              :      ! smom2  = second moment of delta in smd2(:)
    1481              :      !
    1482              :      smom1  = 0.0_dp
    1483              :      smom2  = 0.0_dp
    1484              :      tmom1  = 0.0_dp
    1485              :      tmom2  = 0.0_dp
    1486              :      do ii=-nconvd2+4,nconvd2
    1487              :        smom1 = smom1+                                       &
    1488              : &       ( 17.0_dp*tgrid(ii)  *tgrid(ii)  *smd1(ii)         &
    1489              : &       +42.0_dp*tgrid(ii-1)*tgrid(ii-1)*smd1(ii-1)       &
    1490              : &       -16.0_dp*tgrid(ii-2)*tgrid(ii-2)*smd1(ii-2)       &
    1491              : &       + 6.0_dp*tgrid(ii-3)*tgrid(ii-3)*smd1(ii-3)       &
    1492              : &       -       tgrid(ii-4)*tgrid(ii-4)*smd1(ii-4)  )
    1493              :        smom2 = smom2+                                       &
    1494              : &       ( 17.0_dp*tgrid(ii)  *tgrid(ii)  *smd2(ii  )     &
    1495              : &       +42.0_dp*tgrid(ii-1)*tgrid(ii-1)*smd2(ii-1)     &
    1496              : &       -16.0_dp*tgrid(ii-2)*tgrid(ii-2)*smd2(ii-2)     &
    1497              : &       + 6.0_dp*tgrid(ii-3)*tgrid(ii-3)*smd2(ii-3)     &
    1498              : &       -       tgrid(ii-4)*tgrid(ii-4)*smd2(ii-4)  )
    1499              :      end do
    1500           10 :      smom1 =incconv * smom1  / 48.0_dp
    1501           10 :      smom2 =incconv * smom2  / 48.0_dp
    1502              : !    tmom1 =incconv * tmom1  / 48.0_dp
    1503              : !    tmom2 =incconv * tmom2  / 48.0_dp
    1504              : 
    1505           10 :      encorr =  smom2*tratio*tratio/secmom
    1506              : 
    1507           10 :      ABI_FREE(tgrid)
    1508           10 :      ABI_FREE(smd1)
    1509           10 :      ABI_FREE(smd2)
    1510              : 
    1511              :    end if
    1512              : 
    1513              :    !  --------------------------------------------------------
    1514              :    !  end of smearing function initialisation, dblsmr case
    1515              :    !  --------------------------------------------------------
    1516              : 
    1517              : 
    1518              :    !  Now that the smeared delta function has been initialized, compute the
    1519              :    !  occupation function
    1520          753 :    occfun_prev(-nptsdiv2_def,1)=zero
    1521          753 :    entfun_prev(-nptsdiv2_def,1)=zero
    1522              : 
    1523              :    !  Different algorithms are possible, corresponding to the formulas
    1524              :    !  (4.1.11), (4.1.12) and (4.1.14) in Numerical recipes (pp 107 and 108),
    1525              :    !  with respective O(1/N2), O(1/N3), O(1/N4) convergence, where N is the
    1526              :    !  number of points in the interval.
    1527          753 :    algo=4
    1528              : 
    1529              :    if(algo==2)then
    1530              : 
    1531              :      ! Extended trapezoidal rule (4.1.11), taken in a cumulative way
    1532              :      do ii=-nptsdiv2_def+1,nptsdiv2_def
    1533              :        occfun_prev(ii,1)=occfun_prev(ii-1,1)+increm*(smdfun_prev(ii,1)+smdfun_prev(ii-1,1))/2.0_dp
    1534              :        entfun_prev(ii,1)=entfun_prev(ii-1,1)+increm*&
    1535              : &       ( -xgrid_prev(ii)*smdfun_prev(ii,1) -xgrid_prev(ii-1)*smdfun_prev(ii-1,1) )/2.0_dp
    1536              :      end do
    1537              : 
    1538              :    else if(algo==3)then
    1539              : 
    1540              :      ! Derived from (4.1.12). Converges as O(1/N3).
    1541              :      ! Do not care about the following points,
    1542              :      ! where the values are extremely small anyway
    1543              :      occfun_prev(-nptsdiv2_def+1,1)=0.0_dp ;   entfun_prev(-nptsdiv2_def+1,1)=0.0_dp
    1544              :      do ii=-nptsdiv2_def+2,nptsdiv2_def
    1545              :        occfun_prev(ii,1)=occfun_prev(ii-1,1)+increm*&
    1546              : &       ( 5.0_dp*smdfun_prev(ii,1) + 8.0_dp*smdfun_prev(ii-1,1) - smdfun_prev(ii-2,1) )/12.0_dp
    1547              :        entfun_prev(ii,1)=entfun_prev(ii-1,1)+increm*&
    1548              : &       ( 5.0_dp*(-xgrid_prev(ii)  )*smdfun_prev(ii,1)  &
    1549              : &       +8.0_dp*(-xgrid_prev(ii-1))*smdfun_prev(ii-1,1)&
    1550              : &       -      (-xgrid_prev(ii-2))*smdfun_prev(ii-2,1) )/12.0_dp
    1551              :      end do
    1552              : 
    1553              :    else if(algo==4)then
    1554              : 
    1555              :      ! Derived from (4.1.14)- alternative extended Simpsons rule. Converges as O(1/N4).
    1556              :      ! Do not care about the following points,
    1557              :      ! where the values are extremely small anyway
    1558          753 :      occfun_prev(-nptsdiv2_def+1,1)=0.0_dp ;   entfun_prev(-nptsdiv2_def+1,1)=0.0_dp
    1559          753 :      occfun_prev(-nptsdiv2_def+2,1)=0.0_dp ;   entfun_prev(-nptsdiv2_def+2,1)=0.0_dp
    1560          753 :      occfun_prev(-nptsdiv2_def+3,1)=0.0_dp ;   entfun_prev(-nptsdiv2_def+3,1)=0.0_dp
    1561      9034494 :      do ii=-nptsdiv2_def+4,nptsdiv2_def
    1562              :        occfun_prev(ii,1)=occfun_prev(ii-1,1)+increm*&
    1563              : &       ( 17.0_dp*smdfun_prev(ii,1)  &
    1564              : &       +42.0_dp*smdfun_prev(ii-1,1)&
    1565              : &       -16.0_dp*smdfun_prev(ii-2,1)&
    1566              : &       + 6.0_dp*smdfun_prev(ii-3,1)&
    1567      9033741 : &       -       smdfun_prev(ii-4,1) )/48.0_dp
    1568              :        entfun_prev(ii,1)=entfun_prev(ii-1,1)+increm*&
    1569              : &       ( 17.0_dp*(-xgrid_prev(ii)  )*smdfun_prev(ii,1)  &
    1570              : &       +42.0_dp*(-xgrid_prev(ii-1))*smdfun_prev(ii-1,1)&
    1571              : &       -16.0_dp*(-xgrid_prev(ii-2))*smdfun_prev(ii-2,1)&
    1572              : &       + 6.0_dp*(-xgrid_prev(ii-3))*smdfun_prev(ii-3,1)&
    1573      9034494 : &       -       (-xgrid_prev(ii-4))*smdfun_prev(ii-4,1) )/48.0_dp
    1574              :      end do
    1575              : 
    1576              :    end if ! End of choice between different algorithms for integration
    1577              : 
    1578              :    ! Normalize the functions (actually not needed for occopt=3..7)
    1579          753 :    factor=1.0_dp/occfun_prev(nptsdiv2_def,1)
    1580      9037506 :    smdfun_prev(:,1)=smdfun_prev(:,1)*factor
    1581      9037506 :    occfun_prev(:,1)=occfun_prev(:,1)*factor
    1582      9037506 :    entfun_prev(:,1)=entfun_prev(:,1)*factor
    1583              : 
    1584              :    !  Compute the cubic spline fitting of the smeared delta function
    1585          753 :    yp1=0.0_dp ; ypn=0.0_dp
    1586      9037506 :    workfun(:)=smdfun_prev(:,1)
    1587          753 :    call spline(xgrid_prev, workfun, (2*nptsdiv2_def+1), yp1, ypn, smdder)
    1588      9037506 :    smdfun_prev(:,2)=smdder(:)
    1589              : 
    1590              :    ! Compute the cubic spline fitting of the occupation function
    1591              :    yp1=0.0_dp ; ypn=0.0_dp
    1592      9037506 :    workfun(:)=occfun_prev(:,1)
    1593          753 :    call spline(xgrid_prev, workfun, (2*nptsdiv2_def+1), yp1, ypn, occder)
    1594      9037506 :    occfun_prev(:,2)=occder(:)
    1595              : 
    1596              :    ! Compute the cubic spline fitting of the entropy function
    1597              :    yp1=0.0_dp ; ypn=0.0_dp
    1598      9037506 :    workfun(:)=entfun_prev(:,1)
    1599          753 :    call spline(xgrid_prev, workfun, (2*nptsdiv2_def+1), yp1, ypn, entder)
    1600      9037506 :    entfun_prev(:,2)=entder(:)
    1601              : 
    1602          753 :    ABI_FREE(entder)
    1603          753 :    ABI_FREE(occder)
    1604          753 :    ABI_FREE(smdder)
    1605          753 :    ABI_FREE(work)
    1606          753 :    ABI_FREE(workfun)
    1607              : 
    1608              :  end if
    1609              : 
    1610       549521 :  if (abs(tphysel)<tol12) then
    1611       547224 :    if (tsmear == zero) then
    1612          325 :      tsmearinv = huge_tsmearinv
    1613              :    else
    1614       546899 :      tsmearinv=one/tsmear
    1615              :    end if
    1616              :  else
    1617         2297 :    tsmearinv=one/tphysel
    1618              :  end if
    1619              : 
    1620  13191251605 :  entfun(:,:) = entfun_prev(:,:)
    1621  13191251605 :  occfun(:,:) = occfun_prev(:,:)
    1622  13191251605 :  smdfun(:,:) = smdfun_prev(:,:)
    1623   6595351042 :  xgrid(:) = xgrid_prev(:)
    1624       549521 :  limit = limit_occ
    1625       549521 :  nptsdiv2 = nptsdiv2_def
    1626              : 
    1627              : end subroutine init_occ_ent
    1628              : !!***
    1629              : 
    1630              : !!****f* m_occ/occeig
    1631              : !! NAME
    1632              : !! occeig
    1633              : !!
    1634              : !! FUNCTION
    1635              : !! For each pair of active bands (m,n), generates ratios
    1636              : !! that depend on the difference between occupation numbers and eigenvalues.
    1637              : !!
    1638              : !! INPUTS
    1639              : !!  doccde_k(nband_k)=derivative of occ_k wrt the energy
    1640              : !!  doccde_kq(nband_k)=derivative of occ_kq wrt the energy
    1641              : !!  eig0_k(nband_k)=GS eigenvalues at k
    1642              : !!  eig0_kq(nband_k)=GS eigenvalues at k+q
    1643              : !!  nband_k=number of bands
    1644              : !!  occopt=option for occupancies
    1645              : !!  occ_k(nband_k)=occupation number for each band at k
    1646              : !!  occ_kq(nband_k)=occupation number for each band at k+q
    1647              : !!
    1648              : !! OUTPUT
    1649              : !!  rocceig(nband_k,nband_k)$= (occ_{k,q}(m)-occ_k(n))/(eig0_{k,q}(m)-eig0_k(n))$,
    1650              : !!   if this ratio has been attributed to the band n, 0.0_dp otherwise
    1651              : !!
    1652              : !! NOTES
    1653              : !! Supposing the occupations numbers differ:
    1654              : !! if $abs(occ_{k,q}(m)) < abs(occ_k(n))$
    1655              : !!  $rocceig(m,n)=(occ_{k,q}(m)-occ_k(n))/(eig0_{k,q}(m)-eig0_k(n)) $
    1656              : !! if $abs(occ_{k,q}(m))>abs(occ_k(n))$
    1657              : !!  rocceig(m,n)=0.0_dp
    1658              : !!
    1659              : !! If the occupation numbers are close enough, then
    1660              : !! if the eigenvalues are also close, take the derivative
    1661              : !!  $ rocceig(m,n)=\frac{1}{2}*docc/deig0 $
    1662              : !! otherwise,
    1663              : !!  $ rocceig(m,n)=\frac{1}{2}*(occ_{k,q}(m)-occ_k(n))/(eig0_{k,q}(m)-eig0_k(n))$
    1664              : !!
    1665              : !! SOURCE
    1666              : 
    1667       855197 : subroutine occeig(doccde_k,doccde_kq,eig0_k,eig0_kq,nband_k,occopt,occ_k,occ_kq,rocceig)
    1668              : 
    1669              : !Arguments ------------------------------------
    1670              : !scalars
    1671              :  integer,intent(in) :: nband_k,occopt
    1672              : !arrays
    1673              :  real(dp),intent(in) :: doccde_k(nband_k),doccde_kq(nband_k),eig0_k(nband_k)
    1674              :  real(dp),intent(in) :: eig0_kq(nband_k),occ_k(nband_k),occ_kq(nband_k)
    1675              :  real(dp),intent(out) :: rocceig(nband_k,nband_k)
    1676              : 
    1677              : !Local variables-------------------------------
    1678              : !scalars
    1679              :  integer :: ibandk,ibandkq
    1680              :  real(dp) :: diffabsocc,diffeig,diffocc,ratio,sumabsocc
    1681              :  character(len=500) :: msg
    1682              : ! *************************************************************************
    1683              : 
    1684              :  ! The parameter tol5 defines the treshhold for degeneracy, and the width of the step function
    1685              : 
    1686     40873801 :  rocceig(:,:) = zero
    1687              : 
    1688      5388783 :  do ibandk=1,nband_k
    1689     40873801 :    do ibandkq=1,nband_k
    1690     35485018 :      diffeig=eig0_kq(ibandkq)-eig0_k(ibandk)
    1691     35485018 :      diffocc=occ_kq(ibandkq)-occ_k(ibandk)
    1692              : 
    1693     35485018 :      if( abs(diffeig) > tol5 ) then
    1694     32384630 :        ratio=diffocc/diffeig
    1695              :      else
    1696      3100388 :        if(occopt<3)then
    1697              :          ! In a non-metallic case, if the eigenvalues are degenerate,
    1698              :          ! the occupation numbers must also be degenerate, in which
    1699              :          ! case there is no contribution from this pair of bands
    1700      2537164 :          if( abs(diffocc) > tol5 ) then
    1701              :            write(msg,'(a,a,a,a,a,a,a,2(a,i4,a,es16.6,a,es16.6,a,a),a)' ) &
    1702            0 :            'In a non-metallic case (occopt<3), for a RF calculation,',ch10,&
    1703            0 :            'if the eigenvalues are degenerate,',' the occupation numbers must also be degenerate.',ch10,&
    1704            0 :            'However, the following pair of states gave :',ch10,&
    1705            0 :            'k -state, band number',ibandk,', occ=',occ_k(ibandk),'eigenvalue=',eig0_k(ibandk),',',ch10,&
    1706            0 :            ' kq-state, band number',ibandkq,', occ=',occ_kq(ibandkq),', eigenvalue=',eig0_kq(ibandkq),'.',ch10,&
    1707            0 :            'Action: change occopt, consistently, in GS and RF calculations.'
    1708            0 :            ABI_ERROR(msg)
    1709              :          end if
    1710              :          ratio=0.0_dp
    1711              :        else
    1712              :          ! In the metallic case, one can compute a better approximation of the
    1713              :          ! ratio by using derivatives doccde
    1714       563224 :          ratio=0.5_dp*(doccde_kq(ibandkq)+doccde_k(ibandk))
    1715              :          ! write(std_out,*)' occeig : ibandkq,doccde_kq(ibandkq)',ibandkq,doccde_kq(ibandkq)
    1716              :          ! write(std_out,*)'          ibandk ,doccde_k (ibandk )',ibandk,doccde_k(ibandk)
    1717              :        end if
    1718              :      end if
    1719              : 
    1720              :      ! Here, must pay attention to the smallness of some coefficient
    1721     35485018 :      diffabsocc=abs(occ_k(ibandk))-abs(occ_kq(ibandkq))
    1722     35485018 :      sumabsocc=abs(occ_k(ibandk))+abs(occ_kq(ibandkq))
    1723     40018604 :      if(sumabsocc>tol8)then
    1724     25770634 :        if( diffabsocc > sumabsocc*tol5 ) then
    1725      4057275 :          rocceig(ibandkq,ibandk)=ratio
    1726     21713359 :        else if ( diffabsocc >= -sumabsocc*tol5 ) then
    1727     17655526 :          rocceig(ibandkq,ibandk)=0.5_dp*ratio
    1728              :        else
    1729      4057833 :          rocceig(ibandkq,ibandk)=0.0_dp
    1730              :        end if
    1731              :      end if
    1732              : 
    1733              :    end do ! ibandkq
    1734              :  end do ! ibandk
    1735              : 
    1736       855197 : end subroutine occeig
    1737              : !!***
    1738              : 
    1739              : !----------------------------------------------------------------------
    1740              : 
    1741              : !!****f* m_occ/occ_fd
    1742              : !! NAME
    1743              : !!  occ_fd
    1744              : !!
    1745              : !! FUNCTION
    1746              : !!  Fermi-Dirac statistics: 1 / [(exp((e - mu)/ KT) + 1]
    1747              : !!  Note that occ_fs in [0, 1] so the spin factor is not included, unlike the
    1748              : !!  occupations stored in ebands%occ.
    1749              : !!
    1750              : !! INPUTS
    1751              : !!   ee=Single particle energy in Ha
    1752              : !!   kT=Value of K_Boltzmann x T in Ha.
    1753              : !!   mu=Chemical potential in Ha.
    1754              : !!
    1755              : !! SOURCE
    1756              : 
    1757     41421098 : elemental real(dp) function occ_fd(ee, kT, mu)
    1758              : 
    1759              : !Arguments ------------------------------------
    1760              :  real(dp),intent(in) :: ee, kT, mu
    1761              : 
    1762              : !Local variables ------------------------------
    1763              :  real(dp) :: ee_mu,arg
    1764              : ! *************************************************************************
    1765              : 
    1766     41421098 :  ee_mu = ee - mu
    1767              : 
    1768              :  ! 1 kelvin [K] = 3.16680853419133E-06 Hartree
    1769     41421098 :  if (kT > tol6) then
    1770     23910079 :    arg = ee_mu / kT
    1771     23910079 :    if (arg > maxFDarg) then
    1772              :      occ_fd = zero
    1773     15098260 :    else if (arg < -maxFDarg) then
    1774              :      occ_fd = one
    1775              :    else
    1776      6984950 :      occ_fd = one / (exp(arg) + one)
    1777              :    end if
    1778              :  else
    1779              :    ! Heaviside
    1780     17511019 :    if (ee_mu > zero) then
    1781              :      occ_fd = zero
    1782      8791513 :    else if (ee_mu < zero) then
    1783              :      occ_fd = one
    1784              :    else
    1785     41421098 :      occ_fd = half
    1786              :    end if
    1787              :  end if
    1788              : 
    1789     41421098 : end function occ_fd
    1790              : !!***
    1791              : 
    1792              : !----------------------------------------------------------------------
    1793              : 
    1794              : !!****f* m_occ/occ_dfde
    1795              : !! NAME
    1796              : !!  occ_dfde
    1797              : !!
    1798              : !! FUNCTION
    1799              : !!  Derivative of Fermi-Dirac statistics: - (exp((e - mu)/ KT) / KT[(exp((e - mu)/ KT) + 1]^2
    1800              : !!  Note that kT is given in Hartree so the derivative as well
    1801              : !!
    1802              : !! INPUTS
    1803              : !!   ee=Single particle energy in Ha
    1804              : !!   kT=Value of K_Boltzmann x T in Ha.
    1805              : !!   mu=Chemical potential in Ha.
    1806              : !!
    1807              : !! SOURCE
    1808              : 
    1809    204693600 : elemental real(dp) function occ_dfde(ee, kT, mu)
    1810              : 
    1811              : !Arguments ------------------------------------
    1812              :  real(dp),intent(in) :: ee, kT, mu
    1813              : 
    1814              : !Local variables ------------------------------
    1815              :  real(dp) :: ee_mu,arg
    1816              : ! *************************************************************************
    1817              : 
    1818    204693600 :  ee_mu = ee - mu
    1819              : 
    1820              :  ! 1 kelvin [K] = 3.16680853419133E-06 Hartree
    1821    204693600 :  if (kT > tol6) then
    1822    102736146 :    arg = ee_mu / kT
    1823    102736146 :    if (arg > maxDFDarg) then
    1824              :      occ_dfde = zero
    1825     57105075 :    else if (arg < -maxDFDarg) then
    1826              :      occ_dfde = zero
    1827              :    else
    1828     11474029 :      occ_dfde = - exp(arg) / (exp(arg) + one)**2 / kT
    1829              :    end if
    1830              :  else
    1831              :    occ_dfde = zero
    1832              :  end if
    1833              : 
    1834    204693600 : end function occ_dfde
    1835              : !!***
    1836              : 
    1837              : !----------------------------------------------------------------------
    1838              : 
    1839              : !!****f* m_occ/occ_be
    1840              : !! NAME
    1841              : !!  occ_be
    1842              : !!
    1843              : !! FUNCTION
    1844              : !!   Bose-Einstein statistics  1 / [(exp((e - mu)/ KT) - 1]
    1845              : !!
    1846              : !! INPUTS
    1847              : !!   ee=Single particle energy in Ha
    1848              : !!   kT=Value of K_Boltzmann x T in Ha.
    1849              : !!   mu=Chemical potential in Ha (usually zero)
    1850              : !!
    1851              : !! SOURCE
    1852              : 
    1853      4470992 : elemental real(dp) function occ_be(ee, kT, mu)
    1854              : 
    1855              : !Arguments ------------------------------------
    1856              :  real(dp),intent(in) :: ee, kT, mu
    1857              : 
    1858              : !Local variables ------------------------------
    1859              :  real(dp) :: ee_mu, arg
    1860              : ! *************************************************************************
    1861              : 
    1862      4470992 :  ee_mu = ee - mu
    1863              : 
    1864              :  ! 1 kelvin [K] = 3.16680853419133E-06 Hartree
    1865      4470992 :  if (kT > tol12) then
    1866      4193278 :    arg = ee_mu / kT
    1867      4193278 :    if (arg > tol12 .and. arg < maxBEarg) then
    1868      4193278 :      occ_be = one / (exp(arg) - one)
    1869              :    else
    1870              :      occ_be = zero
    1871              :    end if
    1872              :  else
    1873              :    ! No condensate for T --> 0
    1874              :    occ_be = zero
    1875              :  end if
    1876              : 
    1877      4470992 : end function occ_be
    1878              : !!***
    1879              : 
    1880              : !----------------------------------------------------------------------
    1881              : 
    1882              : !!****f* m_occ/occ_dbe
    1883              : !! NAME
    1884              : !!  occ_dbe
    1885              : !!
    1886              : !! FUNCTION
    1887              : !!   Derivative of Bose-Einstein statistics  (exp((e - mu)/ KT) / KT[(exp((e - mu)/ KT) - 1]^2
    1888              : !!   Note that kT is given in Hartree so the derivative as well
    1889              : !!
    1890              : !! INPUTS
    1891              : !!   ee=Single particle energy in Ha
    1892              : !!   kT=Value of K_Boltzmann x T in Ha.
    1893              : !!   mu=Chemical potential in Ha (usually zero)
    1894              : !!
    1895              : !! SOURCE
    1896              : 
    1897            0 : elemental real(dp) function occ_dbe(ee, kT, mu)
    1898              : 
    1899              : !Arguments ------------------------------------
    1900              :  real(dp),intent(in) :: ee, kT, mu
    1901              : 
    1902              : !Local variables ------------------------------
    1903              :  real(dp) :: ee_mu, arg
    1904              : ! *************************************************************************
    1905              : 
    1906            0 :  ee_mu = ee - mu
    1907              : 
    1908              :  ! 1 kelvin [K] = 3.16680853419133E-06 Hartree
    1909            0 :  if (kT > tol12) then
    1910            0 :    arg = ee_mu / kT
    1911            0 :    if (arg > tol12 .and. arg < maxDBEarg) then
    1912            0 :      occ_dbe = exp(arg) / (kT * (exp(arg) - one)**2)
    1913              :    else
    1914              :      occ_dbe = zero
    1915              :    end if
    1916              :  else
    1917              :    ! No condensate for T --> 0
    1918              :    occ_dbe = zero
    1919              :  end if
    1920              : 
    1921            0 : end function occ_dbe
    1922              : !!***
    1923              : 
    1924              : !----------------------------------------------------------------------
    1925              : 
    1926              : !!****f* m_occ/dos_hdr_write
    1927              : !!
    1928              : !! NAME
    1929              : !! dos_hdr_write
    1930              : !!
    1931              : !! FUNCTION
    1932              : !! Write the header of the DOS files, for both smearing and tetrahedron methods.
    1933              : !!
    1934              : !! INPUTS
    1935              : !! deltaene=increment of DOS energy arguments
    1936              : !! enemax=maximal value of the DOS energy argument
    1937              : !! enemin=minimal value of the DOS energy argument
    1938              : !! nene=number of DOS energy argument
    1939              : !! eigen(mband*nkpt*nsppol)=eigenvalues (input or init to large number), hartree
    1940              : !! fermie=fermi energy useful for band alignment...
    1941              : !! fermih= fermi energy of thermalized excited holes when occopt = 9
    1942              : !! mband=maximum number of bands
    1943              : !! nband(nkpt*nsppol)=number of bands at each k point
    1944              : !! nkpt=number of k points
    1945              : !! nsppol=1 for unpolarized, 2 for spin-polarized
    1946              : !! occopt=option for occupancies, or re-smearing scheme if dblsmr /= 0
    1947              : !! prtdos=1 for smearing technique, 2 or 3 for tetrahedron technique
    1948              : !! tphysel="physical" electronic temperature with FD occupations
    1949              : !! tsmear=smearing width (or temperature)
    1950              : !! unitdos=unit number of output of the DOS.
    1951              : !!
    1952              : !! OUTPUT
    1953              : !!   Only writing.
    1954              : !!
    1955              : !! SOURCE
    1956              : 
    1957           76 : subroutine dos_hdr_write(deltaene,eigen,enemax,enemin,fermie,fermih,mband,nband,nene,&
    1958              :                          nkpt,nsppol,occopt,prtdos,tphysel,tsmear,unitdos)
    1959              : 
    1960              : !Arguments ------------------------------------
    1961              : !scalars
    1962              :  integer,intent(in) :: mband,nkpt,nsppol,occopt,prtdos,unitdos,nene
    1963              :  real(dp),intent(in) :: fermie,fermih,tphysel,tsmear
    1964              :  real(dp),intent(in) :: deltaene,enemax,enemin
    1965              : !arrays
    1966              :  integer,intent(in) :: nband(nkpt*nsppol)
    1967              :  real(dp),intent(in) :: eigen(mband*nkpt*nsppol)
    1968              : 
    1969              : !Local variables-------------------------------
    1970              :  character(len=500) :: msg
    1971              : ! *************************************************************************
    1972              : 
    1973              :  ! Write the DOS file
    1974           76 :  write(msg, '(7a,i2,a,i5,a,i4)' ) "#",ch10, &
    1975           76 :   '# ABINIT package : DOS file  ',ch10,"#",ch10,&
    1976          152 :   '# nsppol =',nsppol,', nkpt =',nkpt,', nband(1)=',nband(1)
    1977           76 :  call wrtout(unitdos, msg)
    1978              : 
    1979           76 :  if (any(prtdos== [1,4])) then
    1980              :    write(msg, '(a,i2,a,f6.3,a,f6.3,a)' )  &
    1981            9 :     '# Smearing technique, occopt =',occopt,', tsmear=',tsmear,' Hartree, tphysel=',tphysel,' Hartree'
    1982              :  else
    1983           67 :    write(msg, '(a)' ) '# Tetrahedron method '
    1984              :  end if
    1985           76 :  call wrtout(unitdos, msg)
    1986              : 
    1987           76 :  if (mband*nkpt*nsppol>=3) then
    1988           76 :    write(msg, '(a,3f8.3,2a)' )'# For identification : eigen(1:3)=',eigen(1:3),ch10,"#"
    1989              :  else
    1990            0 :    write(msg, '(a,3f8.3)' ) '# For identification : eigen=',eigen
    1991            0 :    write(msg, '(3a)')trim(msg),ch10,"#"
    1992              :  end if
    1993           76 :  call wrtout(unitdos, msg)
    1994              : 
    1995           76 :  if (occopt == 9) then
    1996            0 :     write(msg, '(a,f16.8, f16.8)' ) '# Fermi energy for electrons and holes ', fermie, fermih
    1997              :  else
    1998           76 :     write(msg, '(a,f16.8)' ) '# Fermi energy : ', fermie
    1999              :  end if
    2000           76 :  call wrtout(unitdos, msg)
    2001              : 
    2002           76 :  if (prtdos==1) then
    2003            9 :    write(msg, '(5a)' ) "#",ch10,&
    2004            9 :     '# The DOS (in electrons/Hartree/cell) and integrated DOS (in electrons/cell),',&
    2005           18 :     ch10,'# as well as the DOS with tsmear halved and doubled, are computed,'
    2006              : 
    2007           67 :  else if (prtdos==2)then
    2008            4 :    write(msg, '(3a)' ) "#",ch10,&
    2009            8 :     '# The DOS (in electrons/Hartree/cell) and integrated DOS (in electrons/cell) are computed,'
    2010              : 
    2011           63 :  else if (any(prtdos == [3, 4])) then
    2012           62 :    write(msg, '(5a)' ) "#",ch10,&
    2013           62 :     '# The local DOS (in electrons/Hartree for one atomic sphere)',ch10,&
    2014          124 :     '# and integrated local DOS (in electrons for one atomic sphere) are computed.'
    2015              : 
    2016            1 :  else if (prtdos==5)then
    2017            1 :    write(msg, '(9a)' ) "#",ch10,&
    2018            1 :    '# The spin component DOS (in electrons/Hartree/cell)',ch10,&
    2019            1 :    '# and integrated spin component DOS (in electrons/cell) are computed.',ch10,&
    2020            1 :    '# Remember that the wf are eigenstates of S_z and S^2, not S_x and S_y',ch10,&
    2021            2 :    '#   so the latter will not always sum to 0 for paired electronic states.'
    2022              :  end if
    2023           76 :  call wrtout(unitdos, msg)
    2024              : 
    2025              :  write(msg, '(a,i5,a,a,a,f9.4,a,f9.4,a,f8.5,a,a,a)' )&
    2026           76 :   '# at ',nene,' energies (in Hartree) covering the interval ',ch10,&
    2027          152 :   '# between ',enemin,' and ',enemax,' Hartree by steps of ',deltaene,' Hartree.',ch10,"#"
    2028           76 :  call wrtout(unitdos, msg)
    2029              : 
    2030           76 :  if (prtdos==1) then
    2031              :    write(msg, '(a,a)' )&
    2032            9 :     '#       energy        DOS       Integr. DOS   ','     DOS           DOS    '
    2033            9 :    call wrtout(unitdos,msg)
    2034              : 
    2035              :    write(msg, '(a)' )&
    2036            9 :     '#                                              (tsmear/2)    (tsmear*2) '
    2037            9 :    call wrtout(unitdos,msg)
    2038              :  else
    2039           67 :    write(msg, '(a)' ) '#       energy        DOS '
    2040              :  end if
    2041              : 
    2042           76 : end subroutine dos_hdr_write
    2043              : !!***
    2044              : 
    2045              : !!****f* m_occ/get_fact_spin_tol_empty
    2046              : !! NAME
    2047              : !! get_fact_spin_tol_empty
    2048              : !!
    2049              : !! FUNCTION
    2050              : !!
    2051              : !! INPUTS
    2052              : !!
    2053              : !! OUTPUT
    2054              : !!
    2055              : !! SOURCE
    2056              : 
    2057         1118 : subroutine get_fact_spin_tol_empty(nsppol, nspinor, tol_empty_in, fact_spin, tol_empty)
    2058              : 
    2059              :  integer,intent(in) :: nsppol, nspinor
    2060              :  real(dp),intent(in) :: tol_empty_in
    2061              :  real(dp),intent(out) :: fact_spin, tol_empty
    2062              : 
    2063         2222 :  select case (nsppol)
    2064              :  case (1)
    2065         1104 :    fact_spin = half; tol_empty = tol_empty_in          ! below this value the state is assumed empty
    2066         1104 :    if (nspinor == 2) then
    2067           17 :      fact_spin = one; tol_empty = half * tol_empty_in  ! below this value the state is assumed empty
    2068              :    end if
    2069              :  case (2)
    2070           14 :    fact_spin = one; tol_empty = half * tol_empty_in  ! to be consistent and obtain similar results if a metallic
    2071              :  case default                                        ! spin unpolarized system is treated using nsppol==2
    2072         1118 :    ABI_BUG(sjoin('Wrong nsppol:', itoa(nsppol)))
    2073              :  end select
    2074              : 
    2075         1118 : end subroutine get_fact_spin_tol_empty
    2076              : !!***
    2077              : 
    2078              : end module m_occ
    2079              : !!***
        

Generated by: LCOV version 2.3-1