2004-05-14 23:33:08 +08:00
|
|
|
!
|
2005-03-21 22:33:57 +08:00
|
|
|
! Copyright (C) 2004 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 .
|
|
|
|
!
|
|
|
|
!
|
2004-05-14 23:33:08 +08:00
|
|
|
!---------------------------------------------------------------
|
2007-08-12 08:08:53 +08:00
|
|
|
subroutine compute_solution(lam,jam,e,mesh,ndm,grid,vpot,y,beta,ddd,&
|
|
|
|
qq,nbeta,nwfx,lls,jjs,ikk)
|
2004-12-10 23:33:00 +08:00
|
|
|
!---------------------------------------------------------------
|
|
|
|
!
|
|
|
|
! numerical integration of the radial schroedinger equation for
|
|
|
|
! bound states in a local potential.
|
|
|
|
!
|
|
|
|
! This routine works at fixed e
|
|
|
|
! It allows a nonlocal potential and an overlap
|
|
|
|
! operator. Therefore it can solve a general schroedinger
|
|
|
|
! equation necessary to solve a US pseudopotential
|
|
|
|
!
|
2007-06-26 15:38:38 +08:00
|
|
|
use io_global, only : stdout
|
2004-12-10 23:33:00 +08:00
|
|
|
use kinds, only : DP
|
2007-08-12 08:08:53 +08:00
|
|
|
use radial_grids, only: radial_grid_type, series
|
|
|
|
|
2004-12-10 23:33:00 +08:00
|
|
|
implicit none
|
2004-05-14 23:33:08 +08:00
|
|
|
|
2007-08-12 08:08:53 +08:00
|
|
|
type(radial_grid_type), intent(in) :: grid
|
2004-12-10 23:33:00 +08:00
|
|
|
integer :: &
|
|
|
|
lam, & ! l angular momentum
|
|
|
|
mesh,& ! size of radial mesh
|
|
|
|
ndm, & ! maximum radial mesh
|
|
|
|
nbeta,& ! number of beta function
|
|
|
|
nwfx, & ! maximum number of beta functions
|
|
|
|
lls(nbeta),&! for each beta the angular momentum
|
|
|
|
ikk(nbeta) ! for each beta the point where it become zero
|
2004-05-14 23:33:08 +08:00
|
|
|
|
2005-08-28 22:09:42 +08:00
|
|
|
real(DP) :: &
|
2004-12-10 23:33:00 +08:00
|
|
|
e, & ! output eigenvalue
|
|
|
|
jam, & ! j angular momentum
|
|
|
|
vpot(mesh),&! the local potential
|
|
|
|
y(mesh), & ! the output solution
|
|
|
|
jjs(nwfx), & ! the j angular momentum
|
|
|
|
beta(ndm,nwfx),& ! the beta functions
|
|
|
|
ddd(nwfx,nwfx),qq(nwfx,nwfx) ! parameters for computing B_ij
|
|
|
|
!
|
|
|
|
! the local variables
|
|
|
|
!
|
2005-08-28 22:09:42 +08:00
|
|
|
real(DP) :: &
|
2004-12-10 23:33:00 +08:00
|
|
|
ddx12, & ! dx**2/12 used for Numerov integration
|
|
|
|
sqlhf, & ! the term for angular momentum in equation
|
|
|
|
ze2, & ! possible coulomb term aroun the origin (set 0)
|
|
|
|
b(0:3), & ! coefficients of taylor expansion of potential
|
2009-02-25 23:58:53 +08:00
|
|
|
sum, &! auxiliary
|
2004-12-10 23:33:00 +08:00
|
|
|
yln, xp, expn,& ! used to compute the tail of the solution
|
|
|
|
int_0_inf_dr ! integral function
|
2004-05-14 23:33:08 +08:00
|
|
|
|
2005-08-28 22:09:42 +08:00
|
|
|
real(DP), allocatable :: &
|
2004-12-10 23:33:00 +08:00
|
|
|
f(:), & ! the f function
|
|
|
|
el(:),c(:) ! auxiliary for inward integration
|
2004-05-14 23:33:08 +08:00
|
|
|
|
2004-12-10 23:33:00 +08:00
|
|
|
integer :: &
|
|
|
|
n, & ! counter on mesh points
|
|
|
|
ik, & ! matching point
|
|
|
|
ns, & ! counter on beta functions
|
|
|
|
l1, & ! lam+1
|
|
|
|
nst, & ! used in the integration routine
|
|
|
|
ierr, &
|
|
|
|
nstart ! starting point for inward integration
|
2004-05-14 23:33:08 +08:00
|
|
|
|
2007-08-12 08:08:53 +08:00
|
|
|
if (mesh.ne.grid%mesh) call errore('compute_solution','mesh dimension is not as expected',1)
|
2004-12-10 23:33:00 +08:00
|
|
|
!
|
|
|
|
! set up constants and allocate variables the
|
|
|
|
!
|
|
|
|
allocate(f(mesh), stat=ierr)
|
|
|
|
allocate(el(mesh), stat=ierr)
|
|
|
|
allocate(c(mesh), stat=ierr)
|
2004-05-14 23:33:08 +08:00
|
|
|
|
2007-08-12 08:08:53 +08:00
|
|
|
ddx12=grid%dx*grid%dx/12.0_dp
|
2004-12-10 23:33:00 +08:00
|
|
|
l1=lam+1
|
|
|
|
nst=l1*2
|
2005-08-28 22:09:42 +08:00
|
|
|
sqlhf=(DBLE(lam)+0.5_dp)**2
|
2004-12-10 23:33:00 +08:00
|
|
|
!
|
|
|
|
! series developement of the potential near the origin
|
|
|
|
!
|
|
|
|
ze2=0.0_dp
|
|
|
|
do n=1,4
|
2007-08-12 08:08:53 +08:00
|
|
|
y(n)=vpot(n)-ze2/grid%r(n)
|
2004-12-10 23:33:00 +08:00
|
|
|
enddo
|
2007-08-12 08:08:53 +08:00
|
|
|
call series(y,grid%r,grid%r2,b)
|
2004-12-10 23:33:00 +08:00
|
|
|
|
2007-06-26 15:38:38 +08:00
|
|
|
! write(stdout,*) 'eneter lam,eup,elw,e',lam,nbeta,eup,elw,e
|
2004-12-10 23:33:00 +08:00
|
|
|
!
|
|
|
|
! set up the f-function and determine the position of its last
|
|
|
|
! change of sign
|
|
|
|
! f < 0 (approximatively) means classically allowed region
|
|
|
|
! f > 0 " " " forbidden "
|
|
|
|
!
|
|
|
|
ik=0
|
2007-08-12 08:08:53 +08:00
|
|
|
f(1)=ddx12*(grid%r2(1)*(vpot(1)-e)+sqlhf)
|
2004-12-10 23:33:00 +08:00
|
|
|
do n=2,mesh
|
2007-08-12 08:08:53 +08:00
|
|
|
f(n)=ddx12*(grid%r2(n)*(vpot(n)-e)+sqlhf)
|
2004-12-10 23:33:00 +08:00
|
|
|
if( f(n).ne.sign(f(n),f(n-1)).and.n.lt.mesh-5 ) ik=n
|
|
|
|
enddo
|
|
|
|
if (ik.eq.0.and.nbeta.eq.0) ik=mesh*3/4
|
|
|
|
|
|
|
|
if(ik.ge.mesh-2) then
|
|
|
|
do n=1,mesh
|
2007-08-12 08:08:53 +08:00
|
|
|
write(stdout,*) grid%r(n), vpot(n), f(n)
|
2004-12-10 23:33:00 +08:00
|
|
|
enddo
|
2007-06-26 15:38:38 +08:00
|
|
|
call errore('compute_solution', 'No point found for matching',1)
|
2004-12-10 23:33:00 +08:00
|
|
|
endif
|
|
|
|
!
|
|
|
|
! determine if ik is sufficiently large
|
|
|
|
!
|
|
|
|
do ns=1,nbeta
|
|
|
|
if (lls(ns).eq.lam.and.ikk(ns).gt.ik) ik=ikk(ns)
|
|
|
|
enddo
|
|
|
|
!
|
|
|
|
! if everything is ok continue the integration and define f
|
|
|
|
!
|
|
|
|
do n=1,mesh
|
|
|
|
f(n)=1.0_dp-f(n)
|
|
|
|
enddo
|
|
|
|
!
|
|
|
|
! determination of the wave-function in the first two points by
|
|
|
|
! series developement
|
|
|
|
!
|
2010-01-25 17:50:47 +08:00
|
|
|
call start_scheq( lam, e, b, grid, ze2, y )
|
2004-12-10 23:33:00 +08:00
|
|
|
!
|
|
|
|
! outward integration before ik
|
|
|
|
!
|
2007-08-12 08:08:53 +08:00
|
|
|
call integrate_outward (lam,jam,e,mesh,ndm,grid,f, b,y,beta,ddd,qq,&
|
2007-09-03 14:32:31 +08:00
|
|
|
nbeta,nwfx,lls,jjs,ikk,ik)
|
2004-12-10 23:33:00 +08:00
|
|
|
!
|
|
|
|
! inward integration up to ik
|
|
|
|
!
|
2007-08-12 08:08:53 +08:00
|
|
|
call integrate_inward(e,mesh,ndm,grid,f,y,c,el,ik,nstart)
|
2004-12-10 23:33:00 +08:00
|
|
|
!
|
|
|
|
! exponential tail of the solution if it was not computed
|
|
|
|
!
|
|
|
|
if (nstart.lt.mesh) then
|
|
|
|
do n=nstart,mesh-1
|
|
|
|
if (y(n) == 0.0_dp) then
|
|
|
|
y(n+1)=0.0_dp
|
|
|
|
else
|
|
|
|
yln=log(abs(y(n)))
|
|
|
|
xp=-sqrt(12.0_dp*abs(1.0_dp-f(n)))
|
|
|
|
expn=yln+xp
|
|
|
|
if (expn.lt.-80.0_dp) then
|
|
|
|
y(n+1)=0.0_dp
|
|
|
|
else
|
|
|
|
y(n+1)=sign(exp(expn),y(n))
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
enddo
|
|
|
|
endif
|
|
|
|
!
|
|
|
|
! normalize the eigenfunction and exit
|
|
|
|
!
|
|
|
|
do n=1,mesh
|
2007-08-12 08:08:53 +08:00
|
|
|
el(n)=grid%r(n)*y(n)*y(n)
|
2004-12-10 23:33:00 +08:00
|
|
|
enddo
|
2007-08-12 08:08:53 +08:00
|
|
|
sum=int_0_inf_dr(el,grid,mesh,nst)
|
2004-12-10 23:33:00 +08:00
|
|
|
sum=sqrt(sum)
|
|
|
|
do n=1,mesh
|
2007-08-12 08:08:53 +08:00
|
|
|
y(n)=grid%sqr(n)*y(n)/sum
|
2004-12-10 23:33:00 +08:00
|
|
|
enddo
|
2004-05-14 23:33:08 +08:00
|
|
|
|
2004-12-10 23:33:00 +08:00
|
|
|
deallocate(el)
|
|
|
|
deallocate(f )
|
|
|
|
deallocate(c )
|
|
|
|
return
|
2004-05-14 23:33:08 +08:00
|
|
|
|
2004-12-10 23:33:00 +08:00
|
|
|
end subroutine compute_solution
|