4
1
mirror of https://github.com/pfloos/quack synced 2024-06-30 00:44:31 +02:00
quack/src/eDFT/eDFT.f90

202 lines
6.9 KiB
Fortran
Raw Normal View History

2022-02-02 15:06:51 +01:00
subroutine eDFT(maxSCF,thresh,max_diis,guess_type,mix,level_shift,nNuc,ZNuc,rNuc,ENuc,nBas,nEl,nC,nO,nV,nR, &
2020-10-14 09:44:03 +02:00
nShell,TotAngMomShell,CenterShell,KShell,DShell,ExpShell, &
2021-02-15 17:27:06 +01:00
max_ang_mom,min_exponent,max_exponent,S,T,V,Hc,X,ERI,dipole_int,Ew,eKS,cKS,PKS,Vxc)
2019-03-13 11:07:31 +01:00
! exchange-correlation density-functional theory calculations
2021-01-26 21:28:05 +01:00
! use xc_f90_lib_m
2020-10-13 13:44:24 +02:00
2019-07-09 16:17:10 +02:00
implicit none
2019-03-13 11:07:31 +01:00
include 'parameters.h'
2020-10-14 09:27:42 +02:00
! Input variables
2020-10-14 09:44:03 +02:00
integer,intent(in) :: maxSCF
integer,intent(in) :: max_diis
integer,intent(in) :: guess_type
2021-01-31 23:24:25 +01:00
logical,intent(in) :: mix
2022-02-02 15:06:51 +01:00
logical,intent(in) :: level_shift
2020-10-14 09:44:03 +02:00
double precision,intent(in) :: thresh
2020-10-14 09:27:42 +02:00
integer,intent(in) :: nNuc
integer,intent(in) :: nBas
integer,intent(in) :: nEl(nspin)
integer,intent(in) :: nC(nspin)
integer,intent(in) :: nO(nspin)
integer,intent(in) :: nV(nspin)
integer,intent(in) :: nR(nspin)
2020-10-14 09:44:03 +02:00
double precision,intent(in) :: ENuc
2020-10-14 09:27:42 +02:00
double precision,intent(in) :: ZNuc(nNuc)
double precision,intent(in) :: rNuc(nNuc,ncart)
2020-10-14 09:44:03 +02:00
integer,intent(in) :: nShell
2020-10-14 09:27:42 +02:00
double precision,intent(in) :: CenterShell(maxShell,ncart)
integer,intent(in) :: TotAngMomShell(maxShell)
integer,intent(in) :: KShell(maxShell)
double precision,intent(in) :: DShell(maxShell,maxK)
double precision,intent(in) :: ExpShell(maxShell,maxK)
integer,intent(in) :: max_ang_mom(nNuc)
double precision,intent(in) :: min_exponent(nNuc,maxL+1)
double precision,intent(in) :: max_exponent(nNuc)
double precision,intent(in) :: S(nBas,nBas)
double precision,intent(in) :: T(nBas,nBas)
double precision,intent(in) :: V(nBas,nBas)
double precision,intent(in) :: Hc(nBas,nBas)
double precision,intent(in) :: X(nBas,nBas)
double precision,intent(in) :: ERI(nBas,nBas,nBas,nBas)
double precision,intent(in) :: dipole_int(nBas,nBas,ncart)
! Local variables
2019-03-13 11:07:31 +01:00
character(len=8) :: method
2019-03-13 11:07:31 +01:00
integer :: x_rung,c_rung
2021-10-25 12:20:25 +02:00
integer :: x_DFA,c_DFA
logical :: LDA_centered = .true.
2020-03-25 11:25:48 +01:00
2019-03-13 11:07:31 +01:00
integer :: SGn
2020-03-25 11:25:48 +01:00
double precision :: radial_precision
integer :: nRad
integer :: nAng
integer :: nGrid
2019-03-13 11:07:31 +01:00
double precision,allocatable :: root(:,:)
double precision,allocatable :: weight(:)
integer :: nCC
double precision,allocatable :: aCC(:,:)
2020-03-25 11:25:48 +01:00
2019-03-13 11:07:31 +01:00
double precision,allocatable :: AO(:,:)
double precision,allocatable :: dAO(:,:,:)
double precision :: start_KS,end_KS,t_KS
2020-03-14 23:00:44 +01:00
double precision :: start_int,end_int,t_int
2019-03-13 11:07:31 +01:00
2020-09-29 11:47:18 +02:00
integer :: nEns
logical :: doNcentered
2019-03-13 11:07:31 +01:00
double precision,allocatable :: wEns(:)
2020-08-04 12:30:52 +02:00
double precision,allocatable :: occnum(:,:,:)
integer :: Cx_choice
2020-10-14 09:27:42 +02:00
integer :: i,vmajor,vminor,vmicro
2021-02-15 22:31:41 +01:00
integer :: iBas,iEns,ispin
2021-10-25 12:20:25 +02:00
integer :: icart,iGrid
2020-10-13 13:44:24 +02:00
2021-02-14 22:24:52 +01:00
! Output variables
double precision,intent(out) :: Ew
double precision,intent(out) :: eKS(nBas,nspin)
double precision,intent(out) :: cKS(nBas,nBas,nspin)
double precision,intent(out) :: PKS(nBas,nBas,nspin)
2021-02-15 17:27:06 +01:00
double precision,intent(out) :: Vxc(nBas,nspin)
2021-02-14 22:24:52 +01:00
2019-03-13 11:07:31 +01:00
! Hello World
write(*,*)
write(*,*) '******************************************'
write(*,*) '* eDFT: density-functional for ensembles *'
write(*,*) '******************************************'
write(*,*)
!------------------------------------------------------------------------
2019-07-09 16:17:10 +02:00
! DFT options
2019-03-13 11:07:31 +01:00
!------------------------------------------------------------------------
2020-10-14 09:44:03 +02:00
! Allocate ensemble weights and MO coefficients
2020-09-11 11:55:04 +02:00
2021-11-24 13:06:46 +01:00
allocate(wEns(maxEns),aCC(maxCC,maxEns-1),occnum(nBas,nspin,maxEns))
call read_options_dft(nBas,method,x_rung,x_DFA,c_rung,c_DFA,SGn,nEns,wEns,nCC,aCC, &
2020-10-14 09:44:03 +02:00
doNcentered,occnum,Cx_choice)
2019-03-13 11:07:31 +01:00
!------------------------------------------------------------------------
! Construct quadrature grid
!------------------------------------------------------------------------
2021-10-25 12:20:25 +02:00
if(SGn == -1) then
write(*,*) '*** Quadrature grid on atomic sites ! ***'
write(*,*)
nGrid = nNuc
allocate(root(ncart,nGrid),weight(nGrid))
2020-03-25 10:39:45 +01:00
2021-10-25 12:20:25 +02:00
do icart=1,ncart
do iGrid=1,nGrid
root(icart,iGrid) = rNuc(iGrid,icart)
end do
end do
weight(:) = 1d0
2019-03-13 11:07:31 +01:00
2021-10-25 12:20:25 +02:00
else
2019-03-13 11:07:31 +01:00
2021-10-25 12:20:25 +02:00
call read_grid(SGn,radial_precision,nRad,nAng,nGrid)
call allocate_grid(nNuc,ZNuc,max_ang_mom,min_exponent,max_exponent,radial_precision,nAng,nGrid)
allocate(root(ncart,nGrid),weight(nGrid))
call build_grid(nNuc,ZNuc,rNuc,max_ang_mom,min_exponent,max_exponent, &
radial_precision,nRad,nAng,nGrid,weight,root)
end if
2020-03-23 17:26:12 +01:00
2019-03-13 11:07:31 +01:00
!------------------------------------------------------------------------
! Calculate AO values at grid points
!------------------------------------------------------------------------
allocate(AO(nBas,nGrid),dAO(ncart,nBas,nGrid))
2019-07-09 16:17:10 +02:00
call AO_values_grid(nBas,nShell,CenterShell,TotAngMomShell,KShell,DShell,ExpShell,nGrid,root,AO,dAO)
2019-03-13 11:07:31 +01:00
!------------------------------------------------------------------------
2021-02-15 22:31:41 +01:00
! Compute UKS energy
!------------------------------------------------------------------------
if(method == 'UKS') then
! Reset occupation numbers for conventional UKS calculation
occnum(:,:,:) = 0d0
do ispin=1,nspin
do iBas=1,nO(ispin)
do iEns=1,nEns
occnum(iBas,ispin,iEns) = 1d0
end do
end do
end do
call cpu_time(start_KS)
2022-02-02 15:06:51 +01:00
call UKS(x_rung,x_DFA,c_rung,c_DFA,nEns,wEns,nCC,aCC(1:nCC,1:nEns-1),nGrid,weight, &
maxSCF,thresh,max_diis,guess_type,mix,level_shift,nNuc,ZNuc,rNuc,ENuc, &
nBas,AO,dAO,S,T,V,Hc,ERI,dipole_int,X,occnum,Cx_choice,doNcentered,Ew,eKS,cKS,PKS,Vxc)
2021-02-15 22:31:41 +01:00
call cpu_time(end_KS)
t_KS = end_KS - start_KS
write(*,'(A65,1X,F9.3,A8)') 'Total CPU time for UKS = ',t_KS,' seconds'
write(*,*)
end if
!------------------------------------------------------------------------
! Compute UKS energy for ensembles
!------------------------------------------------------------------------
if(method == 'eDFT-UKS') then
call cpu_time(start_KS)
2022-02-02 15:06:51 +01:00
call UKS(x_rung,x_DFA,c_rung,c_DFA,nEns,wEns,nCC,aCC(1:nCC,1:nEns-1),nGrid,weight, &
maxSCF,thresh,max_diis,guess_type,mix,level_shift,nNuc,ZNuc,rNuc,ENuc, &
nBas,AO,dAO,S,T,V,Hc,ERI,dipole_int,X,occnum,Cx_choice,doNcentered,Ew,eKS,cKS,PKS,Vxc)
call cpu_time(end_KS)
t_KS = end_KS - start_KS
write(*,'(A65,1X,F9.3,A8)') 'Total CPU time for UKS = ',t_KS,' seconds'
write(*,*)
end if
2019-03-13 11:07:31 +01:00
!------------------------------------------------------------------------
! End of eDFT
!------------------------------------------------------------------------
2020-10-14 09:44:03 +02:00
end subroutine eDFT