@brief This is the uniform singles excitation generator which uses precomputed indices to generate only GAS allowed excitations.
GAS_singles_PC_uniform_ExcGenerator_t
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(GAS_singles_PC_uniform_ExcGenerator_t), | intent(inout) | :: | this | |||
integer, | intent(in) | :: | nI(nel) | |||
integer(kind=n_int), | intent(in) | :: | ilutI(0:NIfTot) | |||
integer, | intent(out) | :: | nJ(nel) | |||
integer(kind=n_int), | intent(out) | :: | ilutJ(0:NifTot) | |||
integer, | intent(in) | :: | exFlag | |||
integer, | intent(out) | :: | ic | |||
integer, | intent(out) | :: | ex(2,maxExcit) | |||
logical, | intent(out) | :: | tParity | |||
real(kind=dp), | intent(out) | :: | pGen | |||
real(kind=dp), | intent(out) | :: | hel | |||
type(excit_gen_store_type), | intent(inout), | target | :: | store | ||
integer, | intent(in), | optional | :: | part_type |
subroutine GAS_singles_uniform_gen_exc(this, nI, ilutI, nJ, ilutJ, exFlag, ic, &
ex, tParity, pGen, hel, store, part_type)
class(GAS_singles_PC_uniform_ExcGenerator_t), intent(inout) :: this
integer, intent(in) :: nI(nel), exFlag
integer(n_int), intent(in) :: ilutI(0:NIfTot)
integer, intent(out) :: nJ(nel), ic, ex(2, maxExcit)
integer(n_int), intent(out) :: ilutJ(0:NifTot)
real(dp), intent(out) :: pGen
logical, intent(out) :: tParity
HElement_t(dp), intent(out) :: hel
type(excit_gen_store_type), intent(inout), target :: store
integer, intent(in), optional :: part_type
integer :: elec, src, tgt
integer, allocatable :: unoccupied(:)
#ifdef WARNING_WORKAROUND_
associate(exFlag => exFlag); end associate
associate(part_type => part_type); end associate
#endif
#ifdef WARNING_WORKAROUND_
hel = 0.0_dp
#endif
ic = 1
elec = int(genrand_real2_dSFMT() * nel) + 1
src = nI(elec)
unoccupied = this%get_possible_holes(nI, ilutI, src, this%use_lookup, store)
! NOTE: this is actually possible for some systems.
if (size(unoccupied) == 0) then
pgen = 1._dp / nEl
nJ(1) = 0
ilutJ = 0_n_int
return
end if
! NOTE: The `tgt` could be drawn from `unoccupied` with weights according
! to the matrix elements < nI | H | E_{src}^{tgt} nI >.
! Probably not worth it and I am too lazy to implement it now.
tgt = unoccupied(int(genrand_real2_dSFMT() * size(unoccupied)) + 1)
pgen = 1._dp / (nEl * size(unoccupied))
call make_single(nI, nJ, elec, tgt, ex, tParity)
ilutJ = ilutI
clr_orb(ilutJ, src)
set_orb(ilutJ, tgt)
end subroutine GAS_singles_uniform_gen_exc