subroutine FinalizeNewOrbs()
! At the end of the orbital rotation, have a set of coefficients CoeffT1 which transform
! the HF orbitals into a set of linear
! combinations ui which minimise |<ij|kl>|^2. This is the final subroutine after
! all iterations (but before the memory deallocation)
! that calculates the final 4 index integrals to be used in the NECI calculation.
use sym_mod, only: GenSymStatePairs
integer :: i, a, j
real(dp) :: TotGSConstraints, GSConstraint(TotNoConstraints)
HElement_t(dp) :: CoeffTemp(SpatOrbs, SpatOrbs)
! First need to do a final explicit orthonormalisation. The orbitals
! are very close to being orthonormal, but not exactly. Need to make
! sure they are exact orthonormal using Gram Schmit.
if (tStoreSpinOrbs .and. (.not. tMaxHLGap)) then
CoeffTemp(:, :) = 0.0_dp
do i = 1, SpatOrbs
do j = 1, SpatOrbs
CoeffTemp(i, j) = CoeffT1(2 * i, 2 * j)
end do
end do
call GRAMSCHMIDT_NECI(CoeffTemp, SpatOrbs)
CoeffT1(:, :) = 0.0_dp
do i = 1, SpatOrbs
do j = 1, SpatOrbs
CoeffT1(2 * i, 2 * j) = CoeffTemp(i, j)
CoeffT1((2 * i) - 1, (2 * j) - 1) = CoeffTemp(i, j)
end do
end do
else if (.not. tMaxHLGap) then
call GRAMSCHMIDT_NECI(CoeffT1, NoOrbs)
end if
! Put routine in here that takes this rotation matrix, CoeffT1, and forms raises it to the power of a small number, alpha.
! Changeing this number allows us to see the change in plateau level with various rotations.
! Write out some final results of interest, like values of the constraints, values of new coefficients.
write(stdout, *) 'The final transformation coefficients after gram schmidt orthonormalisation'
do i = 1, NoOrbs
do a = 1, NoOrbs
write(stdout, '(F10.4)', advance='no') CoeffT1(a, i)
end do
write(stdout, *) ''
end do
call WriteTransformMat()
call CalcConstraints(CoeffT1, GSConstraint, TotGSConstraints)
write(stdout, *) 'Final Potential Energy before orthogonalisation', PotEnergy
call Transform2ElInts()
! Use these final coefficients to find the FourIndInts(i,j,k,l).
! These are now the <ij|kl> integrals we now want to use instead of the HF UMat.
! New potential energy is calculated in this routine using the orthogonalised coefficients.
! Compare to that before this, to make sure the orthogonalisation hasn't shifted them back to a non-minimal place.
write(stdout, *) 'Final Potential Energy after orthogonalisation', PotEnergy
! Calculate the fock matrix, and print it out to see how much the off diagonal terms contribute.
! Also print out the sum of the diagonal elements to compare to the original value.
call CalcFOCKMatrix()
call RefillUMATandTMAT2D()
! UMat is the 4 index integral matrix (2 electron), whereas TMAT2D is the 2 index integral (1 el) matrix
! This is the keyword that tells the NECI calculation that the orbitals are not HF. It means that contributions to
! the energy from walkers on singly occupied determinants are included in the values printed.
! Making it true here allows us to go directly from a Rotation into a spawn if required.
tRotatedOrbs = .true.
call GENSymStatePairs(SpatOrbs, .false.)
end subroutine FinalizeNewOrbs