update_run_reference Subroutine

public subroutine update_run_reference(ilut, run)


Type IntentOptional Attributes Name
integer(kind=n_int), intent(in) :: ilut(0:NIfTot)
integer, intent(in) :: run


Source Code

Source Code

    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
            ! 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))
                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))
            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