calcDoubleL2R2L_stochastic Subroutine

public subroutine calcDoubleL2R2L_stochastic(ilut, csf_i, excitInfo, t, branch_pgen, posSwitches, negSwitches, opt_weight)

Arguments

Type IntentOptional Attributes Name
integer(kind=n_int), intent(in) :: ilut(0:nifguga)
type(CSF_Info_t), intent(in) :: csf_i
type(ExcitationInformation_t), intent(in) :: excitInfo
integer(kind=n_int), intent(out) :: t(0:nifguga)
real(kind=dp), intent(out) :: branch_pgen
real(kind=dp), intent(in) :: posSwitches(nSpatOrbs)
real(kind=dp), intent(in) :: negSwitches(nSpatOrbs)
type(WeightObj_t), intent(in), optional :: opt_weight

Contents


Source Code

    subroutine calcDoubleL2R2L_stochastic(ilut, csf_i, excitInfo, t, branch_pgen, &
                                          posSwitches, negSwitches, opt_weight)
        integer(n_int), intent(in) :: ilut(0:nifguga)
        type(CSF_Info_t), intent(in) :: csf_i
        type(ExcitationInformation_t), intent(in) :: excitInfo
        integer(n_int), intent(out) :: t(0:nifguga)
        real(dp), intent(out) :: branch_pgen
        real(dp), intent(in) :: posSwitches(nSpatOrbs), negSwitches(nSpatOrbs)
        type(WeightObj_t), intent(in), optional :: opt_weight
        character(*), parameter :: this_routine = "calcDoubleL2R2L_stochastic"

        integer :: iOrb, start2, ende1, ende2, start1, switch
        type(WeightObj_t) :: weights
        real(dp) :: temp_pgen
        HElement_t(dp) :: integral

        ! have to create this additional routine to more efficiently
        ! incorporate the integral contributions, since it is vastly different
        ! when involving mixed generators, but thats still todo!
        ASSERT(.not. isZero(ilut, excitInfo%fullStart))
        ASSERT(.not. isThree(ilut, excitInfo%secondStart))
        ASSERT(.not. isZero(ilut, excitInfo%firstEnd))
        ASSERT(.not. isThree(ilut, excitInfo%fullEnd))

        start1 = excitInfo%fullStart
        start2 = excitInfo%secondStart
        ende1 = excitInfo%firstEnd
        ende2 = excitInfo%fullEnd

        if (present(opt_weight)) then
            weights = opt_weight
        else
            ! : create correct weights:
            weights = init_fullDoubleWeight(csf_i, start2, ende1, ende2, negSwitches(start2), &
                                            negSwitches(ende1), posSwitches(start2), posSwitches(ende1), &
                                            csf_i%B_real(start2), csf_i%B_real(ende1))
        end if

        call createStochasticStart_single(ilut, csf_i, excitInfo, weights, posSwitches, &
                                          negSwitches, t, branch_pgen)

        ! check validity (defined in macros.h)
        check_abort_excit(branch_pgen, t)

        do iOrb = start1 + 1, start2 - 1
            call singleStochasticUpdate(ilut, csf_i, iOrb, excitInfo, weights, posSwitches, &
                                        negSwitches, t, temp_pgen)
            ! check validity
            branch_pgen = branch_pgen * temp_pgen

            check_abort_excit(branch_pgen, t)

        end do

        ! change weights... maybe need both single and double type weights
        ! then do lowering semi start
        weights = weights%ptr

        call calcRaisingSemiStartStochastic(ilut, csf_i, excitInfo, weights, negSwitches, &
                                            posSwitches, t, branch_pgen)

        ! check validity
        check_abort_excit(branch_pgen, t)

        do iOrb = start2 + 1, ende1 - 1
            call doubleUpdateStochastic(ilut, csf_i, iOrb, excitInfo, weights, negSwitches, &
                                        posSwitches, t, branch_pgen)
            ! check validity
            check_abort_excit(branch_pgen, t)

        end do

        ! then update weights and and to lowering semi-stop
        weights = weights%ptr

        call calcRaisingSemiStopStochastic(ilut, csf_i, excitInfo, weights, negSwitches, &
                                           posSwitches, t, branch_pgen)

        ! check validity
        check_abort_excit(branch_pgen, t)

        do iOrb = ende1 + 1, ende2 - 1
            call singleStochasticUpdate(ilut, csf_i, iOrb, excitInfo, weights, posSwitches, &
                                        negSwitches, t, temp_pgen)
            ! check validity
            branch_pgen = branch_pgen * temp_pgen

            check_abort_excit(branch_pgen, t)

        end do

        ! and finally to end step
        call singleStochasticEnd(csf_i, excitInfo, t)

        ! if we do RDMs also store the x0 and x1 coupling coeffs
        if (tFillingStochRDMOnFly) then
            call encode_stochastic_rdm_info(GugaBits, t, rdm_ind= &
                contract_2_rdm_ind(excitInfo%i, excitInfo%j, excitInfo%k, excitInfo%l, &
                                           excit_lvl=2, excit_typ=excitInfo%typ), &
                                            x0=extract_matrix_element(t, 1), &
                                            x1=extract_matrix_element(t, 2))
        end if

        ! todo: think about the additional integral contributions and the
        ! relative sign of different order influences...
        ! and not sure yet if in this case i can use this function generally
        ! for R, RR, RR, R
        ! and L -> RL -> RL -> L
        ! since the integral/order influences are different maybe... todo!
        ! see above too!
        ! but yeah matrix elements definitly depends on excitation here.
        ! if there is no change in the overlap region, there is also the
        ! non-overlap contribution! otherwise not. maybe set some flag to
        ! indicate if such a stepvector change happened or not.

        ! update: on the matrix elements..
        ! i have to consider the non-overlap excitation, which can lead to
        ! the same excitation if there is no change in the stepvector
        ! in the overlap region
        ! the problem with the L2R2L and R2L2R funcitons is that the
        ! generator type changes for the non-overlap excitation so the
        ! matrix elements have to be changed more than in the R2L and L2R case

        ! if a switch happend -> also no additional contribution
        switch = findFirstSwitch(ilut, t, start2 + 1, ende1)

        if (switch > 0) then
            integral = extract_matrix_element(t, 2) * (get_umat_el(ende2, start2, start1, ende1) + &
                                                       get_umat_el(start2, ende2, ende1, start1)) / 2.0_dp

            if (near_zero(integral)) then
                branch_pgen = 0.0_dp
                t = 0_n_int
            else
                call encode_matrix_element(t, 0.0_dp, 2)
                call encode_matrix_element(t, integral, 1)
            end if

        else
            ! the no switch happened i have to get the additional contributions
            ! by the non-overlap version, but now the generator type at the
            ! end is different as the on-the fly calculated ...
            ! so the x0 matrix element changes by more (or even recalculate?)
            ! the bottom contribution, stays the same -sqrt(2) to cancel the
            ! -t
            ! the contribution at the semi-stop stays the same +t
            ! so those to get to -2.0_dp
            ! and bullshit that generator changes!! is also the same
            ! so it is exactly the same as in the R2L and L2R cases!! phew

            ! have also check if the non-overlap matrix elements is 0...
            ! this can happen unfortunately
            integral = (-extract_matrix_element(t, 1) * (get_umat_el(start2, ende2, start1, ende1) + &
                                                     get_umat_el(ende2, start2, ende1, start1)) * 2.0_dp + (extract_matrix_element(t, 1) + &
                                                              extract_matrix_element(t, 2)) * (get_umat_el(ende2, start2, start1, ende1) + &
                                                                                        get_umat_el(start2, ende2, ende1, start1))) / 2.0_dp

            if (near_zero(integral)) then
                branch_pgen = 0.0_dp
                t = 0_n_int
            else
                call encode_matrix_element(t, 0.0_dp, 2)
                call encode_matrix_element(t, integral, 1)
            end if
        end if

    end subroutine calcDoubleL2R2L_stochastic