subroutine hf_gradient(infos)
use io_constants, only: iw
use grd1, only: print_gradient
use dft, only: dft_initialize, dftclean, dftder
use strings, only: Cstring, fstring
use mod_dft_molgrid, only: dft_grid_t
use util, only: measure_time
use printing, only: print_module_info
implicit none
type(information), target, intent(inout) :: infos
integer :: b_size, c_size, s_size
type(basis_Set), pointer :: basis
logical :: urohf, dft
type(dft_grid_t) :: molGrid
! 3. LOG: Write: Main output file
open (unit=IW, file=infos%log_filename, position="append")
!
call print_module_info('HF_DFT_Gradient','Computing Gradient of HF/DFT')
urohf = infos%control%scftype == 2 .or. infos%control%scftype == 3
dft = infos%control%hamilton == 20
! Load basis set
basis => infos%basis
basis%atoms => infos%atoms
! Allocate memory
b_size = basis%nbf*(basis%nbf+1)/2
c_size = basis%nbf
s_size = (basis%nshell**2+basis%nshell)/2
! Compute 1e gradient
write(iw,"(/' ..... Beginning Gradient Calculation...'/)")
call flush(iw)
call hf_1e_grad(infos, basis)
write(iw,"(' ..... End Of 1-Eelectron Gradient ......')")
call measure_time(print_total=1, log_unit=iw)
call flush(iw)
! Calculate DFT contribution
if (dft) then
write(iw,"(/' ..... Gradient XC terms...'/)")
call dft_initialize(infos, basis, molGrid, verbose=.true.)
call dftder(basis, infos, molGrid)
call dftclean(infos)
write(iw,"(' ..... End of gradient XC terms......')")
call measure_time(print_total=1, log_unit=iw)
call flush(iw)
end if
! Compute 2e gradient
call hf_2e_grad(basis, infos)
write(iw, fmt="(' ...... End Of 2-Electron Gradient ......')")
call measure_time(print_total=1, log_unit=iw)
call flush(iw)
! Print out gradient
call print_gradient(infos)
! Print timings
call measure_time(print_total=1, log_unit=iw)
close(iw)
end subroutine hf_gradient