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

Contents


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