subroutine calcFullStartLowering(ilut, csf_i, excitInfo, excitations, nExcits, &
posSwitches, negSwitches)
integer(n_int), intent(in) :: ilut(0:nifguga)
type(CSF_Info_t), intent(in) :: csf_i
type(ExcitationInformation_t), intent(inout) :: excitInfo
integer(n_int), intent(out), allocatable :: excitations(:, :)
integer, intent(out) :: nExcits
real(dp), intent(in) :: posSwitches(nSpatOrbs), negSwitches(nSpatOrbs)
character(*), parameter :: this_routine = "calcFullStartLowering"
integer :: nMax, iOrb, start, ende, semi, gen
integer(n_int) :: t(0:nifguga)
real(dp) :: tempWeight, minusWeight, plusWeight, bVal, nOpen
type(WeightObj_t) :: weights
integer(n_int), allocatable :: tempExcits(:, :)
ASSERT(isThree(ilut, excitInfo%fullStart))
ASSERT(isProperCSF_ilut(ilut))
! create the fullStart
start = excitInfo%fullStart
ende = excitInfo%fullEnd
semi = excitInfo%firstEnd
gen = excitInfo%firstGen
bVal = csf_i%B_real(semi)
! first have to allocate both arrays for the determinant and weight list
! worse then worst case for single excitations are 2^|i-j| excitations
! for a given CSF -> for now use that to allocate the arrays first
! update only need the number of open orbitals between i and j, and
! some additional room if 0/3 at start
! use already provided open orbital counting function.
! nMax = 2**(ende - start)
nMax = 2 + 2**count_open_orbs_ij(csf_i, start, ende)
allocate(tempExcits(0:nifguga, nMax))
t = ilut
! have to make the switch and store the first matrix element in it too
! additionally also already calculate the sign coming from the
! pseudo double excitation which only depends on the number of open
! orbitals in the overlap region
! just also count the semi here to take that additional -sign into account
nOpen = real(count_open_orbs_ij(csf_i, start, semi), dp)
! set 3->0
clr_orb(t, 2 * start)
clr_orb(t, 2 * start - 1)
! since only the 0 branch is taken, where there are now changes in
! the stepvector and the matrix element is just a sign i can directly
! go to the lowering semi stop
! i could write it specifically here, and i should for efficiency
! have to calc. weights here, which are only the normel single
! excitation weights
weights = init_singleWeight(csf_i, ende)
minusWeight = weights%proc%minus(negSwitches(semi), bVal, weights%dat)
plusWeight = weights%proc%plus(posSwitches(semi), bVal, weights%dat)
ASSERT(.not. isThree(ilut, semi))
ASSERT(minusWeight + plusWeight > 0.0_dp)
call encode_matrix_element(t, 0.0_dp, 2)
select case (csf_i%stepvector(semi))
case (0)
! have to check a few things with 0 start
if (minusWeight > 0.0_dp .and. plusWeight > 0.0_dp) then
! both +1 and -1 excitations possible
! do 0->1 first -1 branch first
set_orb(t, 2 * semi - 1)
call getDoubleMatrixElement(1, 0, 0, gen_type%L, gen_type%L, bVal, 1.0_dp, tempWeight)
call encode_matrix_element(t, Root2 * tempWeight * ((-1.0_dp)**nOpen), 1)
call setDeltaB(-1, t)
tempExcits(:, 1) = t
! then do 0->2: +1 branch
clr_orb(t, 2 * semi - 1)
set_orb(t, 2 * semi)
call getDoubleMatrixElement(2, 0, 0, gen_type%L, gen_type%L, bVal, 1.0_dp, tempWeight)
call encode_matrix_element(t, Root2 * tempWeight * ((-1.0_dp)**nOpen), 1)
call setDeltaB(1, t)
tempExcits(:, 2) = t
nExcits = 2
else if (near_zero(plusWeight)) then
! only -1 branch possible
! do 0->1 first -1 branch first
set_orb(t, 2 * semi - 1)
call getDoubleMatrixElement(1, 0, 0, gen_type%L, gen_type%L, bVal, 1.0_dp, tempWeight)
call encode_matrix_element(t, Root2 * tempWeight * ((-1.0_dp)**nOpen), 1)
call setDeltaB(-1, t)
tempExcits(:, 1) = t
nExcits = 1
else if (near_zero(minusWeight)) then
! only +1 branch possible
! then do 0->2: +1 branch
set_orb(t, 2 * semi)
call getDoubleMatrixElement(2, 0, 0, gen_type%L, gen_type%L, bVal, 1.0_dp, tempWeight)
call encode_matrix_element(t, Root2 * tempWeight * ((-1.0_dp)**nOpen), 1)
call setDeltaB(1, t)
tempExcits(:, 1) = t
nExcits = 1
else
! something went wrong, or i have to cancel exciation.. todo how
call stop_all(this_routine, "something went wrong. shouldnt be here!")
end if
case (1)
! only one excitation possible, which also has to have
! non-zero weight or otherwise i wouldnt even be here
! and reuse already provided t
! 1 -> 3
set_orb(t, 2 * semi)
call setDeltaB(1, t)
! encode fullstart contribution and pseudo overlap region here
! too in one go. one additional -1 due to semistop
call encode_matrix_element(t, ((-1.0_dp)**nOpen), 1)
tempExcits(:, 1) = t
nExcits = 1
case (2)
! here we have
! 2 -> 3
set_orb(t, 2 * semi - 1)
call setDeltaB(-1, t)
! encode fullstart contribution and pseudo overlap region here
! too in one go. one additional -1 due to semistop
call encode_matrix_element(t, ((-1.0_dp)**nOpen), 1)
tempExcits(:, 1) = t
nExcits = 1
end select
! and then we have to do just a regular single excitation
excitInfo%currentGen = excitInfo%lastGen
do iOrb = semi + 1, ende - 1
call singleUpdate(ilut, csf_i, iOrb, excitInfo, posSwitches, negSwitches, &
weights, tempExcits, nExcits)
end do
! and do a regular end step
call singleEnd(ilut, csf_i, excitInfo, tempExcits, nExcits, excitations)
! that should be it...
end subroutine calcFullStartLowering