2003-01-20 05:58:50 +08:00
|
|
|
!
|
2003-02-25 04:53:26 +08:00
|
|
|
! Copyright (C) 2001-2003 PWSCF group
|
2003-01-20 05:58:50 +08:00
|
|
|
! 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 work_function (wf)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! Print out the workfunction, calculated as the difference between the
|
|
|
|
! potential energy and the fermi energy.
|
|
|
|
! Written for supercells with the main axis along z.
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
use pwcom
|
2003-02-21 22:57:00 +08:00
|
|
|
#ifdef __PARA
|
2003-02-08 00:04:36 +08:00
|
|
|
use para
|
2003-02-25 04:53:26 +08:00
|
|
|
use mp
|
2003-01-20 05:58:50 +08:00
|
|
|
#endif
|
|
|
|
implicit none
|
|
|
|
|
2003-02-25 04:53:26 +08:00
|
|
|
integer :: ionode_id = 0
|
2003-01-20 05:58:50 +08:00
|
|
|
real(kind=DP) :: wmean1, wmean2, meancharge, wx1, wx2, wxm, vx, vc, ex, &
|
|
|
|
ec, rhox, rs, vcca, wf
|
2003-02-08 00:04:36 +08:00
|
|
|
integer :: n1, n2, ni, nmean
|
|
|
|
logical :: exst
|
|
|
|
real(kind=DP), allocatable :: raux1 (:), vaux1 (:), aux (:)
|
2003-01-20 05:58:50 +08:00
|
|
|
! auxiliary vectors for charge and potential
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
allocate (raux1( nrx1 * nrx2 * nrx3))
|
|
|
|
allocate (vaux1( nrx1 * nrx2 * nrx3))
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2003-02-25 04:53:26 +08:00
|
|
|
if (nspin .ne. 1) &
|
|
|
|
call errore ('work_function','spin polarization not implemented',1)
|
|
|
|
current_spin = 1
|
2003-02-21 22:57:00 +08:00
|
|
|
#ifdef __PARA
|
2003-02-25 04:53:26 +08:00
|
|
|
allocate (aux ( nrxx))
|
|
|
|
aux(:) = rho(:,current_spin) + rho_core(:)
|
2003-02-08 00:04:36 +08:00
|
|
|
call gather (aux, raux1)
|
2003-01-20 05:58:50 +08:00
|
|
|
#else
|
2003-02-25 04:53:26 +08:00
|
|
|
raux1(1:nrxx) = rho(1:nrxx,current_spin) + rho_core(1:nrxx)
|
2003-01-20 05:58:50 +08:00
|
|
|
#endif
|
2003-02-25 04:53:26 +08:00
|
|
|
!
|
2003-02-21 22:57:00 +08:00
|
|
|
#ifdef __PARA
|
2003-02-25 04:53:26 +08:00
|
|
|
aux(:) = vltot(:) + vr(:,current_spin)
|
2003-02-08 00:04:36 +08:00
|
|
|
call gather (aux, vaux1)
|
2003-01-20 05:58:50 +08:00
|
|
|
#else
|
2003-02-25 04:53:26 +08:00
|
|
|
vaux1(1:nrxx) = vltot(1:nrxx) + vr(1:nrxx,current_spin)
|
2003-01-20 05:58:50 +08:00
|
|
|
#endif
|
2003-02-25 04:53:26 +08:00
|
|
|
!
|
2003-02-21 22:57:00 +08:00
|
|
|
#ifdef __PARA
|
2003-02-25 04:53:26 +08:00
|
|
|
deallocate(aux)
|
2003-02-08 00:04:36 +08:00
|
|
|
if (me.eq.1.and.mypool.eq.1) then
|
2003-01-20 05:58:50 +08:00
|
|
|
#endif
|
2003-02-08 00:04:36 +08:00
|
|
|
call seqopn (17, 'workf', 'formatted', exst)
|
|
|
|
call seqopn (19, 'charge', 'formatted', exst)
|
|
|
|
nmean = (nr3 + 1) / 2
|
|
|
|
do nmean = 1, nr3
|
|
|
|
wmean1 = 0.d0
|
|
|
|
wmean2 = 0.d0
|
|
|
|
meancharge = 0.d0
|
|
|
|
wx1 = 0.d0
|
|
|
|
wx2 = 0.d0
|
|
|
|
wxm = 0.d0
|
|
|
|
do n2 = 1, nr2
|
|
|
|
do n1 = 1, nr1
|
|
|
|
ni = n1 + (n2 - 1) * nrx1 + (nmean - 1) * nrx1 * nrx2
|
|
|
|
meancharge = meancharge+raux1 (ni)
|
|
|
|
wxm = wxm + raux1 (ni) **2
|
|
|
|
wmean1 = wmean1 + vaux1 (ni)
|
|
|
|
wx1 = wx1 + vaux1 (ni) **2
|
|
|
|
rhox = abs (raux1 (ni) )
|
|
|
|
vx = 0.d0
|
|
|
|
if (rhox.gt.1.0e-30) then
|
|
|
|
call xc (rhox, ex, ec, vx, vc)
|
|
|
|
vx = e2 * (vx + vc)
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
wmean2 = wmean2 + vaux1 (ni) - vx
|
|
|
|
wx2 = wx2 + (vaux1 (ni) - vx) **2
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
wmean1 = wmean1 / dfloat (nr1 * nr2)
|
|
|
|
wmean2 = wmean2 / dfloat (nr1 * nr2)
|
|
|
|
meancharge = meancharge / dfloat (nr1 * nr2)
|
|
|
|
wx1 = dsqrt (wx1 / dfloat (nr1 * nr2) - wmean1 * wmean1)
|
|
|
|
wx2 = dsqrt (wx2 / dfloat (nr1 * nr2) - wmean2 * wmean2)
|
|
|
|
wxm = dsqrt (wxm / dfloat (nr1 * nr2) - meancharge**2)
|
|
|
|
if (nmean.eq. (nr3 + 1) / 2) wf = wmean2 - ef
|
2003-01-20 05:58:50 +08:00
|
|
|
write (17, * ) nmean, (wmean1 - ef) * rytoev, wx1 * rytoev, &
|
|
|
|
(wmean2 - ef) * rytoev, wx2 * rytoev
|
2003-02-08 00:04:36 +08:00
|
|
|
write (19, * ) nmean, meancharge, wxm
|
|
|
|
if (nmean.eq. (nr3 + 1) / 2) then
|
2003-01-20 05:58:50 +08:00
|
|
|
write (6, 9130) rytoev * (wmean1 - ef), wx1 * rytoev, &
|
|
|
|
rytoev * (wmean2 - ef), wx2 * rytoev
|
|
|
|
endif
|
|
|
|
enddo
|
2003-02-21 22:57:00 +08:00
|
|
|
#ifdef __PARA
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
2003-02-25 04:53:26 +08:00
|
|
|
CALL mp_bcast( wf, ionode_id )
|
2003-01-20 05:58:50 +08:00
|
|
|
#endif
|
2003-02-08 00:04:36 +08:00
|
|
|
write (6, '(/5x,"Work function written on file workf")')
|
2003-02-25 04:53:26 +08:00
|
|
|
write (6, '( 5x,"Planar mean charge written on file charge")')
|
2003-01-20 05:58:50 +08:00
|
|
|
|
|
|
|
9130 format (/' workfunction = ',f10.4,' +- ',f6.4,' eV', &
|
2003-02-25 04:53:26 +08:00
|
|
|
& /' without exchcorr = ',f10.4,' +- ',f6.4,' eV')
|
|
|
|
close (17)
|
|
|
|
close (19)
|
|
|
|
deallocate(raux1)
|
|
|
|
deallocate(vaux1)
|
|
|
|
return
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2003-02-25 04:53:26 +08:00
|
|
|
end subroutine work_function
|