check_sign_coherence Function

public function check_sign_coherence(ilut, nI, ilut_sign, iRef, run) result(is_coherent)

Arguments

Type IntentOptional Attributes Name
integer(kind=n_int), intent(in) :: ilut(0:NIfTot)
integer, intent(in) :: nI(nel)
real(kind=dp), intent(in) :: ilut_sign(lenof_sign)
integer, intent(in) :: iRef
integer, intent(in) :: run

Return Value logical


Contents

Source Code


Source Code

    function check_sign_coherence(ilut, nI, ilut_sign, iRef, run) result(is_coherent)
        use Determinants, only: get_helement
        use SystemData, only: tHPHF
        use hphf_integrals, only: hphf_off_diag_helement
        use guga_matrixElements, only: calc_guga_matrix_element
        use guga_bitRepOps, only: CSF_Info_t
        use guga_data, only: ExcitationInformation_t
        implicit none
        integer(n_int), intent(in) :: ilut(0:NIfTot)
        integer, intent(in) :: iRef, run, nI(nel)
        real(dp), intent(in) :: ilut_sign(lenof_sign)
        logical :: is_coherent
        integer :: nJRef(nel)
        real(dp) :: signRef(lenof_sign)
#ifdef CMPLX_
        complex(dp) :: tmp
#endif
        type(ExcitationInformation_t) :: excitInfo
        HElement_t(dp) :: h_el

        is_coherent = .true.
        ! Obviously, we need the sign to compare coherence
        call extract_sign(ilutRefAdi(:, iRef), signRef)

        ! For getting the matrix element, we also need the determinants
        call decode_bit_det(nJRef, ilutRefAdi(:, iRef))

        ! Then, get the matrix element
        if (tHPHF) then
            h_el = hphf_off_diag_helement(nI, nJRef(:), ilut, ilutRefAdi(:, iRef))
        else if (tGUGA) then
            call calc_guga_matrix_element(&
                ilut, CSF_Info_t(ilut), ilutRefAdi(:, iref), &
                CSF_Info_t(ilutRefAdi(:, iref)), excitInfo, h_el, .true.)
        else
            h_el = get_helement(nI, nJRef(:), ilut, ilutRefAdi(:, iRef))
        end if
        ! if the determinants are not coupled, ignore them
        if (abs(h_el) < eps) return

        ! If the new ilut has sign 0, there is no need to do any check on this run
        if (mag_of_run(ilut_sign, run) > eps) then
#ifdef CMPLX_
            unused_var(run)
            ! The complex coherence check is more effortive, so only do it in complex builds
            ! Get the relative phase of the signs
            tmp = cmplx(signRef(min_part_type(run)), signRef(max_part_type(run)), dp) / &
                  cmplx(ilut_sign(min_part_type(run)), ilut_sign(max_part_type(run)), dp)
            ! and compare it to that of H
            if (aimag(h_el * tmp) > eps .or. real(h_el * tmp) > 0.0_dp) then
                is_coherent = .false.
                return
            end if
#else
            ! For the real comparison, we just compare the signs
            if (signRef(run) * ilut_sign(run) * h_el > 0.0_dp) then
                is_coherent = .false.
                return
            end if
#endif
        end if
    end function check_sign_coherence