#include "macros.h" module replica_data use constants use MPI_wrapper use FciMCData use CalcData use util_mod use kp_fciqmc_data_mod use SystemData, only: NEl use IntegralsData, only: NFrozen use LoggingData, only: tLogEXLEVELStats use real_time_data, only: TotPartsStorage, TotPartsLastAlpha implicit none contains subroutine init_replica_arrays() ! We run the specified number of replicas in parallel. ! ! This is initialisation of _global_ data that depends on the number ! of character(*), parameter :: this_routine = 'init_replica_arrays' character(120) :: error_message integer :: ierr if (inum_runs > inum_runs_max .or. lenof_sign > lenof_sign_max) then write(stdout, *) "System has too many replicas" write(stdout, *) "This breaks the use of initiator flags, and & &potentially other things." call stop_all(this_routine, "Too many replicas requested") end if ! Global simulation properties, which apply per particle stream (i.e. ! depend on lenof_sign). There will be tow of these per simulation if ! complex walkers are used. allocate(InstNoatHF(lenof_sign), & SumNoatHF(lenof_sign), AllSumNoatHF(lenof_sign), & NoatHF(lenof_sign), AllNoAtHF(lenof_sign), & OldAllNoatHF(lenof_sign), & TotParts(lenof_sign), AllTotParts(lenof_sign), & TotPartsOld(lenof_sign), AllTotPartsOld(lenof_sign), & TotPartsStorage(lenof_sign), TotPartsLastAlpha(lenof_sign), & AllTotPartsLastOutput(lenof_sign), & ! n.b. AllHFCyc is in inum_runs, with different type HFCyc(lenof_sign), HFOut(lenof_sign), & proje_denominator_cyc(lenof_sign), & proje_denominator_sum(lenof_sign), & InitialPartVec(lenof_sign), & NoAborted(lenof_sign), AllNoAborted(lenof_sign), & AllNoAbortedOld(lenof_sign), & NoRemoved(lenof_sign), AllNoRemoved(lenof_sign), & AllNoRemovedOld(lenof_sign), & ! Initiator related NoAddedInitiators(lenof_sign), & NoInitDets(lenof_sign), NoNonInitDets(lenof_sign), & NoInitWalk(lenof_sign), NoNonInitWalk(lenof_sign), & NoExtraInitDoubs(lenof_sign), InitRemoved(lenof_sign), & ! And initiator accumulator related AllNoAddedInitiators(lenof_sign), & AllNoInitDets(lenof_sign), AllNoNonInitDets(lenof_sign), & AllNoInitWalk(lenof_sign), AllNoNonInitWalk(lenof_sign), & AllNoExtraInitDoubs(lenof_sign), AllInitRemoved(lenof_sign), & AllGrowRateAbort(lenof_sign), & stat=ierr) ! Global simulation properties that apply per simulation, i.e. will ! not be duplicated if complex walkers are used. --> inum_runs allocate ( & ! Track the dynamics NoBorn(inum_runs), AllNoBorn(inum_runs), & NoDied(inum_runs), AllNoDied(inum_runs), & Annihilated(inum_runs), AllAnnihilated(inum_runs), & Acceptances(inum_runs), AllAcceptances(inum_runs), & SpawnFromSing(inum_runs), AllSpawnFromSing(inum_runs), & iRefProc(inum_runs), proje_ref_energy_offsets(inum_runs), & iHighestPop(inum_runs), & replica_overlaps_real(inum_runs, inum_runs), & all_norms(inum_runs), & all_overlaps(inum_runs, inum_runs), & #ifdef CMPLX_ replica_overlaps_imag(inum_runs, inum_runs), & #endif tSpinCoupProjE(inum_runs), & NoatDoubs(inum_runs), AllNoatDoubs(inum_runs), & AccRat(inum_runs), AllHFOut(inum_runs), & AllHFCyc(inum_runs), OldAllHFCyc(inum_runs), & ENumCyc(inum_runs), AllENumCyc(inum_runs), & ENumOut(inum_runs), AllENumOut(inum_runs), & ENumCycAbs(inum_runs), AllENumCycAbs(inum_runs), & ProjECyc(inum_runs), & AllGrowRate(inum_runs), & SumWalkersCyc(inum_runs), AllSumWalkersCyc(inum_runs), & SumWalkersOut(inum_runs), AllSumWalkersOut(inum_runs), & OldAllAvWalkersCyc(inum_runs), & proj_e_for_precond(lenof_sign), & ! Overall wavefunction properties norm_psi(inum_runs), norm_psi_squared(inum_runs), & all_norm_psi_squared(inum_runs), old_norm_psi(inum_runs), & norm_semistoch(inum_runs), norm_semistoch_squared(inum_runs), & curr_S2(inum_runs), curr_S2_init(inum_runs), & ! Wavefunction output values SumENum(inum_runs), AllSumENum(inum_runs), & InitsENumCyc(inum_runs), AllInitsENumCyc(inum_runs), & ProjectionE(inum_runs), & proje_iter(inum_runs), & inits_proje_iter(inum_runs), & AbsProjE(inum_runs), & trial_numerator(inum_runs), tot_trial_numerator(inum_runs), & trial_denom(inum_runs), tot_trial_denom(inum_runs), & trial_num_inst(inum_runs), tot_trial_num_inst(inum_runs), & trial_denom_inst(inum_runs), tot_trial_denom_inst(inum_runs), & init_trial_denom(inum_runs), init_trial_numerator(inum_runs), & tot_init_trial_denom(inum_runs), tot_init_trial_numerator(inum_runs), & sum_proje_denominator(inum_runs), & all_sum_proje_denominator(inum_runs), & cyc_proje_denominator(inum_runs), & all_cyc_proje_denominator(inum_runs), & ! Control variables iBlockingIter(inum_runs), & TargetGrowRate(inum_runs), TargetGrowRateWalk(inum_runs), & ! Variables to do with the shift VaryShiftCycles(inum_runs), VaryShiftIter(inum_runs), & HFShift(inum_runs), & InstShift(inum_runs), & AvDiagSft(inum_runs), SumDiagSft(inum_runs), & DiagSft(inum_runs), & hdf5_diagsft(inum_runs), & DiagSftRe(inum_runs), & DiagSftIm(inum_runs), & tSinglePartPhase(inum_runs), stat=ierr) if (ierr /= MPI_SUCCESS) then write(error_message, '(A, I0)') & 'Error during allocation. ierr = ', ierr call Stop_All(this_routine, error_message) end if ! Variables which are only used conditionally. ! NB, NFrozen has not been subtracted from NEl yet! if (tLogEXLEVELStats) allocate ( & EXLEVEL_WNorm(0:2, 0:NEl - NFrozen, inum_runs), & AllEXLEVEL_WNorm(0:2, 0:NEl - NFrozen, inum_runs), stat=ierr) ! Iteration data call allocate_iter_data(iter_data_fciqmc) ! real-time FCIQMC: keep track of first and second Runge-Kutta step ! seperately, think of which stats i need for it! ! maybe move that to real-time init module.. ! KPFCIQMC allocate(TotPartsInit(lenof_sign), & AllTotPartsInit(lenof_sign), & tSinglePartPhaseKPInit(inum_runs), stat=ierr) ! Hacky bugfixes, for variables that aren't clearly set elsewhere. VaryShiftIter = 0 proj_e_for_precond = 0.0_dp end subroutine subroutine clean_replica_arrays() ! The reverse of the above routine... deallocate (InstNoatHF, & SumNoatHF, AllSumNoatHF, & NoatHF, AllNoatHF, OldAllNoatHF, & iRefProc, proje_ref_energy_offsets, & iHighestPop, & replica_overlaps_real, & all_norms, & all_overlaps, & #ifdef CMPLX_ replica_overlaps_imag, & #endif tSpinCoupProjE, & TotPartsStorage, TotPartsLastAlpha, & TotParts, AllTotParts, & TotPartsOld, AllTotPartsOld, AllTotPartsLastOutput, & HFCyc, HFOut, & proje_denominator_cyc, proje_denominator_sum, & InitialPartVec, & NoAborted, AllNoAborted, AllNoAbortedOld, & NoRemoved, AllNoRemoved, AllNoRemovedOld, & ! Initiator related NoAddedInitiators, & NoInitDets, NoNonInitDets, & NoInitWalk, NoNonInitWalk, & NoExtraInitDoubs, InitRemoved, & ! And initiator accumulator related AllNoAddedInitiators, & AllNoInitDets, AllNoNonInitDets, & AllNoInitWalk, AllNoNonInitWalk, & AllNoExtraInitDoubs, AllInitRemoved, & ! Track the dynamics NoBorn, AllNoBorn, & NoDied, AllNoDied, & Annihilated, AllAnnihilated, & Acceptances, AllAcceptances, & SpawnFromSing, AllSpawnFromSing, & AllGrowRateAbort, & NoatDoubs, AllNoatDoubs, & AccRat, & AllHFCyc, OldAllHFCyc, AllHFOut, & ENumCyc, AllENumCyc, ENumCycAbs, AllENumCycAbs, & ENumOut, AllENumOut, & InitsENumCyc, AllInitsEnumCyc, & ProjECyc, & AllGrowRate, & SumWalkersCyc, AllSumWalkersCyc, & SumWalkersOut, AllSumWalkersOut, & OldAllAvWalkersCyc, & proj_e_for_precond, & norm_psi, norm_psi_squared, & all_norm_psi_squared, old_norm_psi, & norm_semistoch, norm_semistoch_squared, & curr_S2, curr_S2_init, & SumENum, AllSumENum, ProjectionE, & proje_iter, AbsProjE, & inits_proje_iter, & trial_numerator, tot_trial_numerator, & trial_denom, tot_trial_denom, & trial_num_inst, tot_trial_num_inst, & trial_denom_inst, tot_trial_denom_inst, & init_trial_denom, init_trial_numerator, & tot_init_trial_denom, tot_init_trial_numerator, & sum_proje_denominator, all_sum_proje_denominator, & cyc_proje_denominator, all_cyc_proje_denominator, & ! Control variables iBlockingIter, & TargetGrowRate, TargetGrowRateWalk, & ! Variables to do with the shift VaryShiftCycles, VaryShiftIter, & HFShift, & InstShift, & AvDiagSft, SumDiagSft, & DiagSft, & hdf5_diagsft, & DiagSftRe, & DiagSftIm, & tSinglePartPhase, & ! KPFCIQMC TotPartsInit, & AllTotPartsInit, & tSinglePartPhaseKPInit) if (tLogEXLEVELStats) deallocate(EXLEVEL_WNorm, AllEXLEVEL_WNorm) call clean_iter_data(iter_data_fciqmc) end subroutine subroutine allocate_iter_data(iter_data) type(fcimc_iter_data), intent(inout) :: iter_data integer :: ierr allocate(iter_data%nborn(lenof_sign), & iter_data%ndied(lenof_sign), & iter_data%nannihil(lenof_sign), & iter_data%naborted(lenof_sign), & iter_data%nremoved(lenof_sign), & iter_data%update_growth(lenof_sign), & iter_data%update_growth_tot(lenof_sign), & iter_data%tot_parts_old(lenof_sign), stat=ierr) ! initialize to 0 iter_data%update_growth_tot = 0.0_dp end subroutine subroutine clean_iter_data(iter_data) type(fcimc_iter_data), intent(inout) :: iter_data deallocate (iter_data%nborn, & iter_data%ndied, & iter_data%nannihil, & iter_data%naborted, & iter_data%nremoved, & iter_data%update_growth, & iter_data%update_growth_tot, & iter_data%tot_parts_old) end subroutine subroutine set_initial_global_data(ndets, ilut_list) use bit_rep_data, only: NIfTot, nifd, extract_sign use Parallel_neci, only: iProcIndex, MPISumAll ! Take in a list of determinants and calculate and set all of the ! global data needed for the start of a FCIQMC calculation. integer(int64), intent(in) :: ndets integer(n_int), intent(inout) :: ilut_list(0:NIfTot, ndets) integer :: run integer(int64) :: i real(dp) :: real_sign(lenof_sign) character(*), parameter :: t_r = 'set_initial_global_data' TotParts = 0.0_dp NoAtHF = 0.0_dp iHighestPop = 0 ! First, find the population of the walkers in walker_list. do i = 1, ndets call extract_sign(ilut_list(:, i), real_sign) TotParts = TotParts + abs(real_sign) if (all(ilut_list(0:nifd, i) == iLutRef(0:nifd, 1))) NoAtHF = real_sign do run = 1, inum_runs if (abs_sign(real_sign(min_part_type(run):max_part_type(run))) > iHighestPop(run)) then iHighestPop(run) = int(abs_sign(real_sign(min_part_type(run):max_part_type(run)))) HighestPopDet(:, run) = ilut_list(:, i) end if end do end do TotWalkers = ndets TotWalkersOld = TotWalkers call MPISumAll(TotWalkers, AllTotWalkers) AllTotWalkersOld = AllTotWalkers TotPartsOld = TotParts call MPISumAll(TotParts, AllTotParts) AllTotPartsOld = AllTotParts call MPISumAll(NoatHF, AllNoatHF) OldAllNoatHF = AllNoatHF #ifdef PROG_NUMRUNS_ do run = 1, inum_runs OldAllAvWalkersCyc(run) = sum(AllTotParts(min_part_type(run):max_part_type(run))) end do #else #ifdef CMPLX_ OldAllAvWalkersCyc = sum(AllTotParts) #else OldAllAvWalkersCyc = AllTotParts #endif #endif do run = 1, inum_runs OldAllHFCyc(run) = ARR_RE_OR_CPLX(AllNoatHF, run) end do AllNoAbortedOld(:) = 0.0_dp iter_data_fciqmc%tot_parts_old = AllTotParts do run = 1, inum_runs ! Calculate the projected energy for this iteration. if (.not. near_zero(ARR_RE_OR_CPLX(AllSumNoAtHF, run))) & ProjectionE(run) = AllSumENum(run) / ARR_RE_OR_CPLX(AllSumNoatHF, run) if (iProcIndex == iRefProc(run)) then do i = min_part_type(run), max_part_type(run) SumNoatHF(i) = AllSumNoatHF(i) InstNoatHF(i) = NoatHF(i) end do SumENum(run) = AllSumENum(run) end if end do end subroutine set_initial_global_data end module