subroutine update_run_reference(ilut, run)
use adi_references, only: update_first_reference
! Update the reference used for a particular run to the one specified.
! Update the HPHF flipped arrays, and adjust the stored diagonal
! energies to account for the change if necessary.
use SystemData, only: BasisFn, nBasisMax
use sym_mod, only: writesym, getsym
integer(n_int), intent(in) :: ilut(0:NIfTot)
integer, intent(in) :: run
character(*), parameter :: this_routine = 'update_run_reference'
HElement_t(dp) :: h_tmp, hoff_tmp
real(dp) :: old_hii
integer :: i, det(nel)
logical :: tSwapped
Type(BasisFn) :: isym
iLutRef(:, run) = 0_n_int
iLutRef(0:nifd, run) = ilut(0:nifd)
call decode_bit_det(ProjEDet(:, run), iLutRef(:, run))
write(stdout, '(a,i3,a)', advance='no') 'Changing projected &
&energy reference determinant for run', run, &
' on the next update cycle to: '
call write_det(stdout, ProjEDet(:, run), .true.)
call GetSym(ProjEDet(:, run), nEl, G1, nBasisMax, isym)
write(stdout, "(A)", advance='no') " Symmetry: "
call writesym(stdout, isym%sym, .true.)
! if in guga run, i also need to recreate the list of connected
! determinnant to the new reference det
if (tGUGA) call fill_csf_i(ilutRef(:, run), csf_ref(run))
if (tHPHF) then
if (.not. Allocated(RefDetFlip)) then
allocate(RefDetFlip(NEl, inum_runs), &
ilutRefFlip(0:NifTot, inum_runs))
RefDetFlip = 0
iLutRefFlip = 0_n_int
end if
if (.not. TestClosedShellDet(iLutRef(:, run))) then
! Complications. We are now effectively projecting
! onto a LC of two dets. Ensure this is done correctly.
call ReturnAlphaOpenDet(ProjEDet(:, run), &
RefDetFlip(:, run), &
iLutRef(:, run), &
iLutRefFlip(:, run), &
.true., .true., tSwapped)
if (tSwapped) then
! The iLutRef should already be the correct
! one, since it was obtained by the normal
! calculation!
call stop_all(this_routine, &
"Error in changing reference determinant &
&to open shell HPHF")
end if
write(stdout, "(A,i3)") "Now projecting onto open-shell &
&HPHF as a linear combo of two determinants...&
& for run", run
tSpinCoupProjE(run) = .true.
end if
else
! In case it was already on, and is now projecting
! onto a CS HPHF.
tSpinCoupProjE(run) = .false.
end if
! We can't use Brillouin's theorem if not a converged,
! closed shell, ground state HF det.
tNoBrillouin = .true.
tRef_Not_HF = .true.
root_print "Ensuring that Brillouin's theorem is no &
&longer used."
! If this is the first replica, update the global reference
! energy.
if (run == 1) then
old_Hii = Hii
if (tZeroRef) then
h_tmp = 0.0_dp
else if (tHPHF) then
h_tmp = hphf_diag_helement(ProjEDet(:, 1), &
iLutRef(:, 1))
else
h_tmp = get_helement(ProjEDet(:, 1), &
ProjEDet(:, 1), 0)
end if
Hii = real(h_tmp, dp)
write(stdout, '(a, g25.15)') &
'Reference energy now set to: ', Hii
! Regenerate all the diagonal elements relative to the
! new reference det.
write(stdout, *) 'Regenerating the stored diagonal &
&HElements for all walkers.'
do i = 1, int(Totwalkers)
call decode_bit_det(det, CurrentDets(:, i))
h_tmp = get_diagonal_matel(det, CurrentDets(:, i))
hoff_tmp = get_off_diagonal_matel(det, CurrentDets(:, i))
call set_det_diagH(i, real(h_tmp, dp) - Hii)
call set_det_offdiagH(i, hoff_tmp)
end do
if (allocated(cs_replicas)) &
call recalc_core_hamil_diag(old_Hii, Hii)
if (tReplicaReferencesDiffer) then
! Ensure that the energy references for all of the runs are
! relative to the new Hii
do i = 1, inum_runs
proje_ref_energy_offsets(i) = proje_ref_energy_offsets(i) &
+ old_hii - hii
end do
end if
! All of the shift energies are relative to Hii, so they need to
! be offset
DiagSft = DiagSft + old_hii - hii
end if ! run == 1
! Ensure that our energy offsets for outputting the correct
! data have been updated correctly.
if (tHPHF) then
h_tmp = hphf_diag_helement(ProjEDet(:, run), &
ilutRef(:, run))
else
h_tmp = get_helement(ProjEDet(:, run), &
ProjEDet(:, run), 0)
end if
proje_ref_energy_offsets(run) = real(h_tmp, dp) - Hii
! Update the processor on which the reference is held
iRefProc(run) = DetermineDetNode(nel, ProjEDet(:, run), 0)
! [W.D] need to also change the virtual mask
if (t_back_spawn .or. t_back_spawn_flex) then
call setup_virtual_mask()
end if
! Also update ilutRefAdi - this has to be done completely
call update_first_reference()
! If using a reference-oriented excitgen, update it
if (t_pcpp_excitgen) call update_pcpp_excitgen()
end subroutine update_run_reference