# project_hamiltonian_ss Subroutine

## public subroutine project_hamiltonian_ss(this, basis_index)

### Arguments

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

## Source Code

    subroutine project_hamiltonian_ss(this, basis_index)

type(davidson_ss), intent(inout) :: this
integer, intent(in) :: basis_index

integer :: i
real(dp) :: dot_prod, dot_prod_all

! Multiply the new basis_vector by the hamiltonian and store the result in
! multiplied_basis_vectors.
call multiply_hamil_and_vector_ss(real(this%basis_vectors(:, basis_index), dp), &
this%multiplied_basis_vectors(:, basis_index), this%full_vector, this%sizes, this%displs, this%run)

! 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
if (this%space_size_this_proc > 0) then
dot_prod = dot_product(this%basis_vectors(:, i), this%multiplied_basis_vectors(:, basis_index))
else
dot_prod = 0.0_dp
end if

call MPISumAll(dot_prod, dot_prod_all)

this%projected_hamil(i, basis_index) = dot_prod_all
this%projected_hamil(basis_index, i) = dot_prod_all
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%projected_hamil_work = this%projected_hamil

end subroutine project_hamiltonian_ss