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

Contents

Source Code


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