calc_pgen_doubles_pcpp Function

public function calc_pgen_doubles_pcpp(ilutI, ex) result(pgen)

Returns the probability of generating a double excitation using the pcpp excitation generator @param[in] ilutI starting determinant of the excitation in the ilut format @param[in] ex excitation as a 2-D integer array of size 2x2 @return pgen probability of picking ex as an excitation from ilutI with pcpp mode (does not account for 1.0-pSingles)

Arguments

Type IntentOptional Attributes Name
integer(kind=n_int), intent(in) :: ilutI(0:NIfTot)
integer, intent(in) :: ex(2,2)

Return Value real(kind=dp)


Contents


Source Code

    function calc_pgen_doubles_pcpp(ilutI,ex) result(pgen)
        integer(n_int), intent(in) :: ilutI(0:NIfTot)
        integer, intent(in) :: ex(2,2)

        real(dp) :: pgen
        real(dp) :: pHoles, pElecs
        integer :: umElec1, umElec2
        integer :: elec_map(nel)

        elec_map = create_elec_map(ilutI)
        associate(tgt1 => ex(2,1), tgt2 => ex(2,2), src1 => ex(1,1), src2 => ex(1,2))
          ! Get the probability of drawing the two holes (in either order)
          pHoles = pgen_holes(tgt1, tgt2) + pgen_holes(tgt2, tgt1)

          ! Recover the originally drawn electrons by inverting the map
          umElec1 = custom_findloc(elec_map, src1)
          umElec2 = custom_findloc(elec_map, src2)

          ! Get the probability of drawing the two electrons (again, in either order)
          pElecs = pgen_elecs(umElec1, umElec2, src1) &
              + pgen_elecs(umElec2, umElec1, elec_map(umElec2))

          pgen = pHoles * pElecs
          ! If the spins are different, both combinations could have been chosen,
          ! so pgen is halved
          if(G1(tgt2)%Ms /= G1(tgt1)%Ms) pgen = pgen * 0.5
        end associate

    contains

        function pgen_holes(t1, t2) result(pH)
            integer, intent(in) :: t1, t2
            real(dp) :: pH
            real(dp):: pTGen1, pTGen2

            pTGen2 = double_hole_two_sampler(ex(1,2), G1(t2)%sym%s, getSpinIndex(t2))%get_prob(t2)
            pTGen1 = double_hole_one_sampler(ex(1,1), getSpinIndex(t1))%get_prob(t1)
            pH = pTGen1*pTGen2
        end function pgen_holes

        function pgen_elecs(s1, s2, sI) result(pE)
            integer, intent(in) :: s1, s2, sI
            real(dp) :: pE
            real(dp) :: pSGen1, pSGen2

            pSGen1 = double_elec_one_sampler%get_prob(s1)
            pSGen2 = double_elec_two_sampler(sI)%get_prob(s2)
            pE = pSGen1*pSGen2
        end function pgen_elecs

    end function calc_pgen_doubles_pcpp