subspace_extraction_sl Subroutine

public subroutine subspace_extraction_sl()

Arguments

None

Contents


Source Code

    subroutine subspace_extraction_sl()

        integer :: lwork, info, i
        real(dp), allocatable :: work(:), left_pert_overlaps(:), left_pert_overlaps_all(:)

        ! Scrap space for the diagonaliser.
        lwork = max(1, 3 * n_lanc_vecs_sl - 1)
        allocate(work(lwork))

        ! This routine diagonalises a symmetric matrix, A.
        ! V tells the routine to calculate eigenvalues *and* eigenvectors.
        ! U tells the routine to get the upper half of A (it is symmetric).
        ! n_lanc_vecs_sl is the number of rows and columns in A.
        ! A = sl_hamil. This matrix stores the eigenvectors in its columns on output.
        ! n_lanc_vecs_sl is the leading dimension of A.
        ! sl_h_eigv stores the eigenvalues on output.
        ! work is scrap space.
        ! lwork is the length of the work array.
        ! info = 0 on output if diagonalisation is successful.
        call dsyev('V', 'U', n_lanc_vecs_sl, sl_hamil, n_lanc_vecs_sl, sl_h_eigv, work, lwork, info)

        deallocate(work)

        ! The first Lanczos vector differs from the perturbed ground state only
        ! by a normalisation factor, which is accounted for here.
        trans_amps_right = sl_hamil(1, :) * right_pert_norm / sqrt(pops_norm)

        ! Calculate the overlaps between the left-perturbed ground state and all
        ! of the Lanczos vectors.
        allocate(left_pert_overlaps(n_lanc_vecs_sl))
        allocate(left_pert_overlaps_all(n_lanc_vecs_sl))
        left_pert_overlaps = matmul(pert_ground_left, sl_vecs)
        ! Sum the contributions to the overlaps from all processes.
        call MPISumAll(left_pert_overlaps, left_pert_overlaps_all)
        ! And then use these overlaps to calculate the overlaps of the
        ! left-perturbed ground state with the final eigenvectors.
        trans_amps_left = matmul(left_pert_overlaps_all, sl_hamil)
        deallocate(left_pert_overlaps)
        deallocate(left_pert_overlaps_all)

    end subroutine subspace_extraction_sl