4
1
mirror of https://github.com/pfloos/quack synced 2024-06-02 11:25:28 +02:00
quack/src/HF/RHF_search.f90

195 lines
6.1 KiB
Fortran
Raw Normal View History

2023-11-28 10:40:15 +01:00
subroutine RHF_search(maxSCF,thresh,max_diis,guess_type,level_shift,nNuc,ZNuc,rNuc,ENuc, &
nBas,nC,nO,nV,nR,S,T,V,Hc,ERI_AO,ERI_MO,dipole_int_AO,dipole_int_MO, &
X,ERHF,e,c,P)
2023-11-03 15:56:18 +01:00
2023-11-04 15:17:39 +01:00
! Search for RHF solutions
2023-11-03 15:56:18 +01:00
implicit none
include 'parameters.h'
integer,intent(in) :: maxSCF
integer,intent(in) :: max_diis
integer,intent(in) :: guess_type
double precision,intent(in) :: thresh
double precision,intent(in) :: level_shift
integer,intent(in) :: nBas
integer,intent(in) :: nC
integer,intent(in) :: nO
integer,intent(in) :: nV
integer,intent(in) :: nR
integer,intent(in) :: nNuc
double precision,intent(in) :: ZNuc(nNuc)
double precision,intent(in) :: rNuc(nNuc,ncart)
double precision,intent(in) :: ENuc
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_AO(nBas,nBas,nBas,nBas)
2023-11-28 10:40:15 +01:00
double precision,intent(inout):: ERI_MO(nBas,nBas,nBas,nBas)
2023-11-03 15:56:18 +01:00
double precision,intent(in) :: dipole_int_AO(nBas,nBas,ncart)
2023-11-28 10:40:15 +01:00
double precision,intent(inout):: dipole_int_MO(nBas,nBas,ncart)
2023-11-03 15:56:18 +01:00
! Local variables
double precision :: start_HF ,end_HF ,t_HF
double precision :: start_stab ,end_stab ,t_stab
double precision :: start_AOtoMO ,end_AOtoMO ,t_AOtoMO
logical :: unstab
integer :: guess
integer :: nS
integer,parameter :: maxS = 20
2023-11-04 12:02:38 +01:00
integer :: ia,i,a,mu
2023-11-03 15:56:18 +01:00
integer :: ispin
2023-11-03 19:48:12 +01:00
double precision,allocatable :: Aph(:,:)
double precision,allocatable :: Bph(:,:)
2023-11-03 15:56:18 +01:00
double precision,allocatable :: AB(:,:)
double precision,allocatable :: Om(:)
2023-11-07 10:25:52 +01:00
double precision,allocatable :: R(:,:)
double precision,allocatable :: ExpR(:,:)
2023-11-03 15:56:18 +01:00
2023-11-28 10:40:15 +01:00
integer :: ixyz
2023-11-03 15:56:18 +01:00
integer :: eig
! Output variables
2023-11-28 10:40:15 +01:00
double precision,intent(out) :: ERHF
2023-11-03 15:56:18 +01:00
double precision,intent(out) :: e(nBas)
double precision,intent(inout):: c(nBas,nBas)
double precision,intent(out) :: P(nBas,nBas)
! Memory allocation
write(*,*)
write(*,*) '****************************'
write(*,*) '* Search for RHF solutions *'
write(*,*) '****************************'
write(*,*)
!-------------------!
! Memory allocation !
!-------------------!
nS = (nO - nC)*(nV - nR)
2023-11-28 10:40:15 +01:00
allocate(Aph(nS,nS),Bph(nS,nS),AB(nS,nS),Om(nS),R(nBas,nBas),ExpR(nBas,nBas))
2023-11-03 15:56:18 +01:00
!------------------!
! Search algorithm !
!------------------!
unstab = .true.
guess = 0
do while(unstab)
!---------------------!
! Hartree-Fock module !
!---------------------!
call wall_time(start_HF)
2023-11-13 22:15:00 +01:00
call RHF(.false.,maxSCF,thresh,max_diis,guess,level_shift,nNuc,ZNuc,rNuc,ENuc, &
2023-11-28 10:40:15 +01:00
nBas,nO,S,T,V,Hc,ERI_AO,dipole_int_AO,X,ERHF,e,c,P)
2023-11-03 15:56:18 +01:00
call wall_time(end_HF)
t_HF = end_HF - start_HF
write(*,'(A65,1X,F9.3,A8)') 'Total CPU time for RHF = ',t_HF,' seconds'
write(*,*)
!----------------------------------!
! AO to MO integral transformation !
!----------------------------------!
call wall_time(start_AOtoMO)
write(*,*)
write(*,*) 'AO to MO transformation... Please be patient'
write(*,*)
2023-11-28 10:40:15 +01:00
do ixyz=1,ncart
call AOtoMO(nBas,c,dipole_int_AO(:,:,ixyz),dipole_int_MO(:,:,ixyz))
end do
2023-11-22 17:02:46 +01:00
call AOtoMO_ERI_RHF(nBas,c,ERI_AO,ERI_MO)
2023-11-03 15:56:18 +01:00
call wall_time(end_AOtoMO)
t_AOtoMO = end_AOtoMO - start_AOtoMO
write(*,'(A65,1X,F9.3,A8)') 'Total CPU time for AO to MO transformation = ',t_AOtoMO,' seconds'
write(*,*)
!-------------------------------------------------------------!
! Stability analysis: Real RHF -> Real RHF
!-------------------------------------------------------------!
ispin = 1
2023-11-03 19:48:12 +01:00
call phLR_A(ispin,.false.,nBas,nC,nO,nV,nR,nS,1d0,e,ERI_MO,Aph)
call phLR_B(ispin,.false.,nBas,nC,nO,nV,nR,nS,1d0,ERI_MO,Bph)
2023-11-03 15:56:18 +01:00
2023-11-08 10:48:54 +01:00
AB(:,:) = Aph(:,:) + Bph(:,:)
2023-11-03 15:56:18 +01:00
call diagonalize_matrix(nS,AB,Om)
2023-11-07 16:11:01 +01:00
Om(:) = 2d0*Om(:)
2023-11-07 10:25:52 +01:00
2023-11-03 15:56:18 +01:00
write(*,*)'-------------------------------------------------------------'
write(*,*)'| Stability analysis: Real RHF -> Real RHF |'
write(*,*)'-------------------------------------------------------------'
write(*,'(1X,A1,1X,A5,1X,A1,1X,A23,1X,A1,1X,A23,1X,A1,1X)') &
'|','State','|',' Excitation energy (au) ','|',' Excitation energy (eV) ','|'
write(*,*)'-------------------------------------------------------------'
do ia=1,min(nS,maxS)
write(*,'(1X,A1,1X,I5,1X,A1,1X,F23.6,1X,A1,1X,F23.6,1X,A1,1X)') &
'|',ia,'|',Om(ia),'|',Om(ia)*HaToeV,'|'
2023-12-03 18:47:30 +01:00
end do
2023-11-03 15:56:18 +01:00
write(*,*)'-------------------------------------------------------------'
2024-01-17 18:40:21 +01:00
if(minval(Om(:)) < 1d-7) then
2023-11-03 15:56:18 +01:00
2023-11-04 15:43:01 +01:00
write(*,'(1X,A40,1X)') 'Too bad, RHF solution is unstable!'
2023-11-03 15:56:18 +01:00
write(*,'(1X,A40,1X,F15.10,A3)') 'Largest negative eigenvalue:',Om(1),' au'
2023-11-28 10:40:15 +01:00
write(*,'(1X,A40,1X,F15.10,A3)') 'E(RHF) = ',ENuc + ERHF,' au'
2023-11-03 15:56:18 +01:00
write(*,*)
2023-11-04 15:43:01 +01:00
write(*,'(1X,A40,1X,A10)') 'Which one would you like to follow?','[Exit:0]'
2023-11-03 15:56:18 +01:00
read(*,*) eig
2023-11-04 12:02:38 +01:00
2023-11-04 15:17:39 +01:00
if(eig < 0 .or. eig > nS) then
2023-11-04 15:43:01 +01:00
write(*,'(1X,A40,1X,A10)') 'Invalid option...','Stop...'
2023-11-04 15:17:39 +01:00
write(*,*)
stop
end if
if(eig == 0) return
2023-11-07 16:47:34 +01:00
R(:,:) = 0d0
ia = 0
do i=nC+1,nO
do a=nO+1,nBas-nR
ia = ia + 1
R(a,i) = +AB(ia,eig)
R(i,a) = -AB(ia,eig)
end do
end do
call matrix_exponential(nBas,R,ExpR)
c = matmul(c,ExpR)
2023-11-07 10:25:52 +01:00
2023-11-03 15:56:18 +01:00
else
2023-11-04 15:43:01 +01:00
write(*,'(1X,A40,1X)') 'Well done, RHF solution is stable!'
2023-11-03 15:56:18 +01:00
write(*,'(1X,A40,1X,F15.10,A3)') 'Smallest eigenvalue: ',Om(1),' au'
2023-11-28 10:40:15 +01:00
write(*,'(1X,A40,1X,F15.10,A3)') 'E(RHF) = ',ENuc + ERHF,' au'
2023-11-03 15:56:18 +01:00
unstab = .false.
end if
write(*,*)'-------------------------------------------------------------'
write(*,*)
2023-11-04 15:17:39 +01:00
!---------------!
! End of Search !
!---------------!
2023-11-03 15:56:18 +01:00
end do
end subroutine