2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! 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 .
|
|
|
|
!
|
|
|
|
!-----------------------------------------------------------------------
|
2003-02-08 00:04:36 +08:00
|
|
|
subroutine localdos (ldos, ldoss, dos_ef)
|
2003-01-20 05:58:50 +08:00
|
|
|
!-----------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
! This routine compute the local and total density of state at Ef
|
|
|
|
!
|
|
|
|
! Note: this routine use psic as auxiliary variable. it should alread
|
|
|
|
! be defined
|
|
|
|
!
|
|
|
|
! NB: this routine works only with gamma
|
|
|
|
!
|
|
|
|
#include "machine.h"
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
use pwcom
|
2003-11-09 18:42:50 +08:00
|
|
|
USE wavefunctions_module, ONLY: evc, psic
|
2004-01-23 23:08:03 +08:00
|
|
|
USE kinds, only : DP
|
2003-02-08 00:04:36 +08:00
|
|
|
use phcom
|
2003-11-10 02:30:08 +08:00
|
|
|
USE io_files, ONLY: iunigk
|
2003-02-08 00:04:36 +08:00
|
|
|
implicit none
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
complex(kind=DP) :: ldos (nrxx, nspin), ldoss (nrxxs, nspin)
|
2004-03-07 21:47:42 +08:00
|
|
|
! output: the local density of states at Ef
|
|
|
|
! output: the local density of states at Ef without augmentation
|
2003-02-08 00:04:36 +08:00
|
|
|
real(kind=DP) :: dos_ef
|
2003-01-20 05:58:50 +08:00
|
|
|
! output: the density of states at Ef
|
|
|
|
!
|
|
|
|
! local variables for Ultrasoft PP's
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
integer :: ikb, jkb, ijkb0, ih, jh, na, ijh, nt
|
2004-05-12 05:08:21 +08:00
|
|
|
! counters
|
2003-02-08 00:04:36 +08:00
|
|
|
real(kind=DP), allocatable :: becsum1 (:,:,:)
|
2004-05-12 05:08:21 +08:00
|
|
|
complex(kind=DP), allocatable :: becp(:,:)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! local variables
|
|
|
|
!
|
2004-03-07 21:47:42 +08:00
|
|
|
real(kind=DP) :: weight, w1, wdelta
|
|
|
|
! weights
|
|
|
|
real(kind=DP), external :: w0gauss
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
integer :: ik, is, ig, ibnd, j
|
2004-03-07 21:47:42 +08:00
|
|
|
! counters
|
2003-02-08 00:04:36 +08:00
|
|
|
integer :: ios
|
2003-01-20 05:58:50 +08:00
|
|
|
! status flag for i/o
|
|
|
|
!
|
|
|
|
! initialize ldos and dos_ef
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
call start_clock ('localdos')
|
2004-05-12 05:08:21 +08:00
|
|
|
allocate (becsum1( (nhm * (nhm + 1)) / 2, nat, nspin), becp(nkb,nbnd) )
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2004-03-07 21:47:42 +08:00
|
|
|
becsum1 (:,:,:) = 0.d0
|
|
|
|
ldos (:,:) = (0d0, 0.0d0)
|
|
|
|
ldoss(:,:) = (0d0, 0.0d0)
|
2003-02-08 00:04:36 +08:00
|
|
|
dos_ef = 0.d0
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! loop over kpoints
|
|
|
|
!
|
2004-03-07 21:47:42 +08:00
|
|
|
if (nksq > 1) rewind (unit = iunigk)
|
2003-02-08 00:04:36 +08:00
|
|
|
do ik = 1, nksq
|
|
|
|
if (lsda) current_spin = isk (ik)
|
2004-03-07 21:47:42 +08:00
|
|
|
if (nksq > 1) then
|
2003-02-08 00:04:36 +08:00
|
|
|
read (iunigk, err = 100, iostat = ios) npw, igk
|
2003-02-21 22:57:00 +08:00
|
|
|
100 call errore ('solve_linter', 'reading igk', abs (ios) )
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
weight = wk (ik)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! unperturbed wfs in reciprocal space read from unit iuwfc
|
|
|
|
!
|
2004-03-07 21:47:42 +08:00
|
|
|
if (nksq > 1) call davcio (evc, lrwfc, iuwfc, ik, - 1)
|
2003-02-08 00:04:36 +08:00
|
|
|
call init_us_2 (npw, igk, xk (1, ik), vkb)
|
2004-03-07 21:47:42 +08:00
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
call ccalbec (nkb, npwx, npw, nbnd, becp, vkb, evc)
|
|
|
|
do ibnd = 1, nbnd_occ (ik)
|
2003-04-29 19:20:28 +08:00
|
|
|
wdelta = w0gauss ( (ef-et(ibnd,ik)) / degauss, ngauss) / degauss
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! unperturbed wf from reciprocal to real space
|
|
|
|
!
|
2004-03-07 21:47:42 +08:00
|
|
|
psic (:) = (0.d0, 0.d0)
|
2003-02-08 00:04:36 +08:00
|
|
|
do ig = 1, npw
|
|
|
|
psic (nls (igk (ig) ) ) = evc (ig, ibnd)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
call cft3s (psic, nr1s, nr2s, nr3s, nrx1s, nrx2s, nrx3s, + 1)
|
|
|
|
w1 = weight * wdelta / omega
|
|
|
|
do j = 1, nrxxs
|
2003-04-29 19:20:28 +08:00
|
|
|
ldoss (j, current_spin) = ldoss (j, current_spin) + &
|
|
|
|
w1 * (DREAL ( psic (j) ) **2 + DIMAG (psic (j) ) **2)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
!
|
|
|
|
! If we have a US pseudopotential we compute here the sumbec term
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
w1 = weight * wdelta
|
|
|
|
ijkb0 = 0
|
|
|
|
do nt = 1, ntyp
|
|
|
|
if (tvanp (nt) ) then
|
|
|
|
do na = 1, nat
|
2004-03-07 21:47:42 +08:00
|
|
|
if (ityp (na) == nt) then
|
2003-02-08 00:04:36 +08:00
|
|
|
ijh = 1
|
|
|
|
do ih = 1, nh (nt)
|
|
|
|
ikb = ijkb0 + ih
|
2003-01-20 05:58:50 +08:00
|
|
|
becsum1 (ijh, na, current_spin) = &
|
|
|
|
becsum1 (ijh, na, current_spin) + w1 * &
|
|
|
|
DREAL (conjg(becp(ikb,ibnd))*becp(ikb,ibnd) )
|
2003-02-08 00:04:36 +08:00
|
|
|
ijh = ijh + 1
|
|
|
|
do jh = ih + 1, nh (nt)
|
|
|
|
jkb = ijkb0 + jh
|
2003-01-20 05:58:50 +08:00
|
|
|
becsum1 (ijh, na, current_spin) = &
|
|
|
|
becsum1 (ijh, na, current_spin) + w1 * 2.d0 * &
|
|
|
|
DREAL(conjg(becp(ikb,ibnd))*becp(jkb,ibnd) )
|
2003-02-08 00:04:36 +08:00
|
|
|
ijh = ijh + 1
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
ijkb0 = ijkb0 + nh (nt)
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
|
|
|
do na = 1, nat
|
2004-03-07 21:47:42 +08:00
|
|
|
if (ityp (na) == nt) ijkb0 = ijkb0 + nh (nt)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
endif
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
dos_ef = dos_ef + weight * wdelta
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
if (doublegrid) then
|
|
|
|
do is = 1, nspin
|
|
|
|
call cinterpolate (ldos (1, is), ldoss (1, is), 1)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
2004-03-07 21:47:42 +08:00
|
|
|
ldos (:,:) = ldoss (:,:)
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
call addusldos (ldos, becsum1)
|
2003-02-21 22:57:00 +08:00
|
|
|
#ifdef __PARA
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! Collects partial sums on k-points from all pools
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
call poolreduce (2 * nrxxs * nspin, ldoss)
|
|
|
|
call poolreduce (2 * nrxx * nspin, ldos)
|
|
|
|
call poolreduce (1, dos_ef)
|
2003-01-20 05:58:50 +08:00
|
|
|
#endif
|
|
|
|
!check
|
|
|
|
! check =0.d0
|
|
|
|
! do is=1,nspin
|
|
|
|
! call cft3(ldos(1,is),nr1,nr2,nr3,nrx1,nrx2,nrx3,-1)
|
|
|
|
! check = check + omega*DREAL(ldos(nl(1),is))
|
|
|
|
! call cft3(ldos(1,is),nr1,nr2,nr3,nrx1,nrx2,nrx3,+1)
|
|
|
|
! end do
|
2003-11-06 03:01:20 +08:00
|
|
|
! WRITE( stdout,*) ' check ', check, dos_ef
|
2003-01-20 05:58:50 +08:00
|
|
|
!check
|
|
|
|
!
|
2004-05-12 05:08:21 +08:00
|
|
|
deallocate(becsum1, becp)
|
2003-02-08 00:04:36 +08:00
|
|
|
call stop_clock ('localdos')
|
|
|
|
return
|
2003-01-20 05:58:50 +08:00
|
|
|
end subroutine localdos
|