quantum-espresso/PW/efermit.f90

117 lines
3.4 KiB
Fortran
Raw Normal View History

!
! Copyright (C) 2001 PWSCF group
! This file is distributed under the terms of the
! GNU General Public License. See the file `License'
! in the root directory of the present distribution,
! or http://www.gnu.org/copyleft/gpl.txt .
!
!
!--------------------------------------------------------------------
subroutine efermit (et, nbndx, nbnd, nks, nelec, nspin, ntetra, &
tetra, ef)
!--------------------------------------------------------------------
!
! Finds the Fermi energy - tetrahedron method (Bloechl)
!
use parameters
implicit none
integer :: nks, nbndx, nbnd, nspin, ntetra, tetra (4, ntetra)
! input: the number of k points
! input: the maximum number of bands
! input: the number of bands
! input: the number of spin components
! input: the number of tetrahedra
! input: the vertices of a tetrahedron
real(kind=DP) :: et (nbndx, nks), nelec, ef
! input: the eigenvalues
! input: the number of electrons
! output: the fermi energy
!
! two parameters
!
integer :: maxiter
! the maximum number of iterations in
real(kind=DP) :: rydtoev, eps
! the transformation Ry to eV
! a small quantity
parameter (maxiter = 300, rydtoev = 13.6058d0, eps = 1.0d-10)
!
! here the local variables
!
integer :: nlw, ik, iter
! the minimum energy band
! counter on k points
! counter on iterations
real(kind=DP) :: elw, eup, sumkup, sumklw, sumkt, sumkmid
! the lower limit of the fermi ener
! the upper limit of the fermi ener
! the number of states with eup
! the number of states with elw
! the sum over the states below E_f
! the number of states with ef
real(kind=DP) :: efbetter, better
external sumkt, error
!
! find bounds for the Fermi energy.
!
nlw = max (1, nint (nelec / 2.0 - 5.0) )
elw = et (nlw, 1)
eup = et (nbnd, 1)
do ik = 2, nks
elw = min (elw, et (nlw, ik) )
eup = max (eup, et (nbnd, ik) )
enddo
!
! Bisection method
!
sumkup = sumkt (et, nbndx, nbnd, nks, nspin, ntetra, tetra, eup)
sumklw = sumkt (et, nbndx, nbnd, nks, nspin, ntetra, tetra, elw)
if ( (sumkup - nelec) .lt. - eps.or. (sumklw - nelec) .gt.eps) &
call error ('efermit', 'unexpected error', 1)
better = 1.0e+10
do iter = 1, maxiter
ef = (eup + elw) / 2.0
sumkmid = sumkt (et, nbndx, nbnd, nks, nspin, ntetra, tetra, ef)
if (abs (sumkmid-nelec) .lt.better) then
better = abs (sumkmid-nelec)
efbetter = ef
endif
! converged
if (abs (sumkmid-nelec) .lt.eps) then
goto 100
elseif ( (sumkmid-nelec) .lt. - eps) then
elw = ef
else
eup = ef
endif
enddo
! unconverged exit:
! the best available ef is used . Needed in some difficult cases
ef = efbetter
sumkmid = sumkt (et, nbndx, nbnd, nks, nspin, ntetra, tetra, ef)
write (6, 9010) ef * rydtoev, sumkmid
! converged exit:
100 continue
! Check if Fermi level is above any of the highest eigenvalues
do ik = 1, nks
if (ef.gt.et (nbnd, ik) + 1.d-4) write (6, 9020) ef * rydtoev, ik, &
et (nbnd, ik) * rydtoev
enddo
return
9010 format (/5x,'Warning: too many iterations in bisection'/ &
& 5x,'ef = ',f10.6,' sumk = ',f10.6,' electrons')
9020 format (/5x,'Warning: ef =',f10.6, &
& ' is above the highest band at k-point',i4,/5x,9x, &
& 'e = ',f10.6)
end subroutine efermit