# project_hamiltonian Subroutine

## public subroutine project_hamiltonian(this, basis_index)

### Arguments

Type IntentOptional Attributes Name
type(DavidsonCalcType), intent(inout) :: this
integer, intent(in) :: basis_index

## Source Code

    subroutine project_hamiltonian(this, basis_index)

type(DavidsonCalcType), intent(inout) :: this
integer, intent(in) :: basis_index
integer :: i

if (iProcIndex == root) then
! Multiply the new basis_vector by the hamiltonian and store the result in
! multiplied_basis_vectors.
call multiply_hamil_and_vector(this%super, real(this%super%basis_vectors(:, basis_index), dp), &
this%multiplied_basis_vectors(:, basis_index))

! Now multiply U^T by (H U) to find projected_hamil. The projected Hamiltonian will
! only differ in the new final column and row. Also, projected_hamil is symmetric.
! Hence, we only need to calculate the final column, and use this to update the final
! row also.
do i = 1, basis_index
this%super%projected_hamil(i, basis_index) = &
dot_product(this%super%basis_vectors(:, i), this%multiplied_basis_vectors(:, basis_index))
this%super%projected_hamil(basis_index, i) = this%super%projected_hamil(i, basis_index)
end do

! We will use the scrap Hamiltonian to pass into the diagonaliser later, since it
! overwrites this input matrix with the eigenvectors. Hence, make sure the scrap space
! stores the updated projected Hamiltonian.
this%super%projected_hamil_work = this%super%projected_hamil
else
call multiply_hamil_and_vector(this%super, this%temp_in, this%temp_out)
end if

end subroutine project_hamiltonian