#include "macros.h" module global_det_data use SystemData, only: nel use CalcData, only: tContTimeFCIMC, tContTimeFull, tStoredDets, tActivateLAS, & tSeniorInitiators, tAutoAdaptiveShift, tPairedReplicas, & tReplicaEstimates, tMoveGlobalDetData, tScaleBlooms use LoggingData, only: tRDMonFly, tExplicitAllRDM, tTransitionRDMs, tAccumPops use FciMCData, only: MaxWalkersPart use MemoryManager, only: LogMemAlloc, LogMemDeAlloc use constants, only: dp, int32, int64, n_int, inum_runs, lenof_sign, eps use util_mod, only: stop_all, operator(.div.) use constants, only: stdout implicit none private public :: writeFVals, readFVals, write_max_ratio, set_all_max_ratios, & writeAPVals, readAPVals, writeFValsAsInt, & readFValsAsInt, & writeAPValsAsInt, readAPValsAsInt, len_av_sgn_tot, len_iter_occ_tot, & get_determinant, set_det_diagH, det_diagH, set_det_offdiagH, & det_offdiagH, max_ratio_size, fvals_size, apvals_size, & global_determinant_data, global_determinant_data_tmp, & set_spawn_rate, set_all_spawn_pops, reset_all_tau_ints, & reset_all_shift_ints, store_decoding, & reset_all_tot_spawns, reset_all_acc_spawns, & get_iter_occ_tot, get_av_sgn_tot, & set_av_sgn_tot, get_spawn_pop, get_tau_int, get_shift_int, & get_neg_spawns, get_pos_spawns, set_iter_occ_tot, get_pops_sum_full, & clean_global_det_data, init_global_det_data, store_spawn, & update_acc_spawns, update_tot_spawns, get_tot_spawns, get_acc_spawns, & replica_est_len, get_spawn_rate, reset_tau_int, get_all_spawn_pops, & reset_shift_int, update_shift_int, update_tau_int, set_spawn_pop, & update_pops_sum_all, get_pops_iter, get_max_ratio, update_max_ratio, & set_supergroup_idx, get_supergroup_idx #ifdef USE_HDF_ public :: set_max_ratio_hdf5Int, write_max_ratio_as_int #endif ! for unit tests public :: pos_acc_spawns, pos_tot_spawns, set_max_ratio ! This is the tag for allocation/deallocation. integer :: glob_tag = 0, glob_det_tag = 0, glob_tmp_tag = 0 ! This is the data used to find the elements inside the storage array. ! The diagonal matrix element is always stored. As it is a real value it ! always has a length of 1 (never cplx). Therefore, encode these values ! as parameters to assist optimisation. integer, parameter :: pos_hel = 1, len_hel = 1 ! The off-diagonal matrix element <D0|H|D>. integer :: pos_hel_off, len_hel_off ! The supergroup_idx is always an int64 and should have the same length ! as real64 integer :: pos_sg_idx integer, parameter :: len_sg_idx = 1 !The initial population of a determinant at spawning time. integer :: pos_spawn_pop, len_spawn_pop !The integral of imaginary time since the spawing of this determinant. integer :: pos_tau_int, len_tau_int !The integral of shift since the spawning of this determinant. integer :: pos_shift_int, len_shift_int ! Total spawns and the number of successful ones according the initiator criterion integer :: len_tot_spawns, len_acc_spawns integer :: pos_tot_spawns, pos_acc_spawns ! total size of acc + tot spawns integer :: fvals_size ! Accumlated sum of population and the last iteration it was increased integer :: len_pops_sum, len_pops_iter integer :: pos_pops_sum, pos_pops_iter !total size of pops sum and iter integer :: apvals_size ! Average sign and first occupation of iteration. integer :: pos_av_sgn, len_av_sgn integer :: pos_iter_occ, len_iter_occ ! Average sign and first occupation of iteration, for transition RDMs. integer :: pos_av_sgn_transition, len_av_sgn_transition integer :: pos_iter_occ_transition, len_iter_occ_transition ! The total length of average sign and first occupation iteration, for ! both the standard and transition RDMs. integer :: len_av_sgn_tot, len_iter_occ_tot integer :: pos_spawn_rate, len_spawn_rate ! global storage of history of determinants: number of pos/neg spawns and ! time since a determinant died integer :: len_pos_spawns, len_neg_spawns integer :: pos_pos_spawns, pos_neg_spawns ! lenght of the determinant and its position integer :: len_det_orbs ! position + length of the maximum Hij/pgen ration per determinant integer :: pos_max_ratio, len_max_ratio, max_ratio_size ! Legth of arrays storing estimates to be written to the replica_est file integer :: replica_est_len ! And somewhere to store the actual data. real(dp), pointer :: global_determinant_data(:, :) => null() integer, pointer :: global_determinants(:, :) => null() real(dp), pointer :: global_determinant_data_tmp(:, :) => null() ! Routines for setting the properties of both standard and transition ! RDMs in a combined manner. interface set_av_sgn_tot module procedure set_av_sgn_tot_sgl module procedure set_av_sgn_tot_all end interface interface set_iter_occ_tot module procedure set_iter_occ_tot_sgl module procedure set_iter_occ_tot_all end interface ! Routines for extracting the properties of both standard and transition RDMs. interface get_av_sgn_tot module procedure get_av_sgn_tot_sgl module procedure get_av_sgn_tot_all end interface interface get_iter_occ_tot module procedure get_iter_occ_tot_sgl module procedure get_iter_occ_tot_all end interface contains subroutine init_global_det_data(nrdms_standard, nrdms_transition) use FciMCData, only: var_e_num, rep_est_overlap use FciMCData, only: var_e_num_all, rep_est_overlap_all use FciMCData, only: e_squared_num, e_squared_num_all use FciMCData, only: en2_pert, en2_pert_all use FciMCData, only: en2_new, en2_new_all use FciMCData, only: precond_e_num, precond_denom use FciMCData, only: precond_e_num_all, precond_denom_all ! Initialise the global storage of determinant specific persistent ! data ! ! --> This is the data that should not be transmitted with each ! particle ! --> It is not stored in the bit representation integer, intent(in) :: nrdms_standard, nrdms_transition integer :: tot_len integer :: ierr character(*), parameter :: this_routine = 'init_global_det_data' ! The position and size of diagonal matrix elements in the array. ! This is set as a module wide parameter, rather than as runtime, as ! it is constant, and this aids optimisation. ! pos_hel = 1 ! len_hel = 1 #ifdef CMPLX_ len_hel_off = 1 #else len_hel_off = 2 #endif len_spawn_pop = lenof_sign if (tSeniorInitiators) then len_tau_int = inum_runs len_shift_int = inum_runs else len_tau_int = 0 len_shift_int = 0 end if if (tAutoAdaptiveShift) then len_tot_spawns = inum_runs len_acc_spawns = inum_runs else len_tot_spawns = 0 len_acc_spawns = 0 end if fvals_size = len_tot_spawns + len_acc_spawns if (tAccumPops) then len_pops_sum = lenof_sign len_pops_iter = 1 else len_pops_sum = 0 len_pops_iter = 0 end if apvals_size = len_pops_sum + len_pops_iter ! If we are using calculating RDMs stochastically, need to include the ! average sign and the iteration on which it became occupied. if (tRDMonFly .and. .not. tExplicitAllRDM) then len_av_sgn = 2 * nrdms_standard len_iter_occ = 2 * nrdms_standard ! The total lengths, including both standard and transition RDMs. len_av_sgn_tot = 2 * nrdms_standard len_iter_occ_tot = 2 * nrdms_standard ! If we are calculating transition RDMs, then we also need to ! include sign averages over different sets of blocks, ! corresponding to the ground state combined with all other ! excited states. if (tTransitionRDMs) then len_av_sgn_transition = 2 * nrdms_transition len_iter_occ_transition = 2 * nrdms_transition len_av_sgn_tot = len_av_sgn + len_av_sgn_transition len_iter_occ_tot = len_iter_occ + len_iter_occ_transition end if write (stdout, '(" The average current signs before death will be stored& & for use in the RDMs.")') else len_av_sgn = 0 len_iter_occ = 0 end if ! If we are using continuous time, and storing the spawning rates len_spawn_rate = 0 if (tContTimeFCIMC .and. tContTimeFull) then len_spawn_rate = 1 end if if (tStoredDets) then len_det_orbs = nel else len_det_orbs = 0 end if if (tActivateLAS) then len_pos_spawns = lenof_sign len_neg_spawns = lenof_sign else len_pos_spawns = 0 len_neg_spawns = 0 end if max_ratio_size = 1 if (tScaleBlooms) then len_max_ratio = max_ratio_size else len_max_ratio = 0 end if ! Get the starting positions pos_hel_off = pos_hel + len_hel pos_spawn_pop = pos_hel_off + len_hel_off pos_tau_int = pos_spawn_pop + len_spawn_pop pos_shift_int = pos_tau_int + len_tau_int pos_tot_spawns = pos_shift_int + len_shift_int pos_acc_spawns = pos_tot_spawns + len_tot_spawns pos_pops_sum = pos_acc_spawns + len_acc_spawns pos_pops_iter = pos_pops_sum + len_pops_sum pos_av_sgn = pos_pops_iter + len_pops_iter pos_av_sgn_transition = pos_av_sgn + len_av_sgn pos_iter_occ = pos_av_sgn_transition + len_av_sgn_transition pos_iter_occ_transition = pos_iter_occ + len_iter_occ pos_spawn_rate = pos_iter_occ_transition + len_iter_occ_transition pos_pos_spawns = pos_spawn_rate + len_spawn_rate pos_neg_spawns = pos_pos_spawns + len_pos_spawns pos_max_ratio = pos_neg_spawns + len_neg_spawns pos_sg_idx = pos_max_ratio + len_max_ratio tot_len = len_hel + len_hel_off + len_spawn_pop + len_tau_int + & len_shift_int + len_tot_spawns + len_acc_spawns + & len_pops_sum + len_pops_iter + len_av_sgn_tot + & len_iter_occ_tot + len_pos_spawns + len_neg_spawns + & len_max_ratio + len_sg_idx if (tPairedReplicas) then replica_est_len = lenof_sign.div.2 else replica_est_len = lenof_sign end if if (tReplicaEstimates) then allocate(var_e_num(replica_est_len)) allocate(rep_est_overlap(replica_est_len)) allocate(var_e_num_all(replica_est_len)) allocate(rep_est_overlap_all(replica_est_len)) allocate(e_squared_num(replica_est_len)) allocate(e_squared_num_all(replica_est_len)) allocate(en2_pert(replica_est_len)) allocate(en2_pert_all(replica_est_len)) allocate(en2_new(replica_est_len)) allocate(en2_new_all(replica_est_len)) allocate(precond_e_num(replica_est_len)) allocate(precond_denom(replica_est_len)) allocate(precond_e_num_all(replica_est_len)) allocate(precond_denom_all(replica_est_len)) end if ! Allocate and log the required memory (globally) allocate(global_determinant_data(tot_len, MaxWalkersPart), stat=ierr) block use constants, only: int64 use util_mod, only: operator(.div.) if (ierr /= 0) then call stop_all(this_routine, 'Error in allocation of global_determinant_data.') end if call LogMemAlloc("global_determinant_data", size(global_determinant_data, kind=int64), int(sizeof(global_determinant_data),& & kind=int64) .div. size(global_determinant_data, kind=int64), this_routine, glob_tag, ierr) end block if (tMoveGlobalDetData) then allocate(global_determinant_data_tmp(tot_len, MaxWalkersPart), stat=ierr) block use constants, only: int64 use util_mod, only: operator(.div.) if (ierr /= 0) then call stop_all(this_routine, 'Error in allocation of global_determinant_data_tmp.') end if call LogMemAlloc("global_determinant_data_tmp", size(global_determinant_data_tmp, kind=int64),& & int(sizeof(global_determinant_data_tmp), kind=int64) .div. size(global_determinant_data_tmp, kind=int64), this_routine,& & glob_tmp_tag, ierr) end block end if if (tStoredDets) then allocate(global_determinants(len_det_orbs, MaxWalkersPart), stat=ierr) block use constants, only: int64 use util_mod, only: operator(.div.) if (ierr /= 0) then call stop_all(this_routine, 'Error in allocation of global_determinants.') end if call LogMemAlloc("global_determinants", size(global_determinants, kind=int64), int(sizeof(global_determinants), kind=int64) .div.& & size(global_determinants, kind=int64), this_routine, glob_det_tag, ierr) end block end if write(stdout, '(a,f14.6,a)') & ' Determinant related persistent storage requires: ', & (4.0_dp * real(len_det_orbs * MaxWalkersPart, dp) & + 8.0_dp * real(tot_len * MaxWalkersPart, dp)) / 1048576_dp, & ' Mb / processor' ! As an added safety feature global_determinant_data = 0.0_dp if (tStoredDets) global_determinants = 0 if (tMoveGlobalDetData) global_determinant_data_tmp = 0.0_dp end subroutine subroutine clean_global_det_data() character(*), parameter :: this_routine = 'clean_global_det_data' ! Cleanup the global storage for determinant specific data if (associated(global_determinants)) then deallocate(global_determinants) log_dealloc(glob_det_tag) glob_det_tag = 0 nullify (global_determinants) end if if (associated(global_determinant_data)) then deallocate(global_determinant_data) log_dealloc(glob_tag) glob_tag = 0 nullify (global_determinant_data) end if if (associated(global_determinant_data_tmp)) then deallocate(global_determinant_data_tmp) log_dealloc(glob_tmp_tag) glob_tmp_tag = 0 nullify (global_determinant_data_tmp) end if end subroutine ! These are accessor functions to currentH --> they are data access/setting ! ! Access the global_determinant_data structure by site index (j). subroutine set_det_diagH(j, hel_r) ! Diagonal matrix elements are real --> store a real value integer, intent(in) :: j real(dp), intent(in) :: hel_r global_determinant_data(pos_hel, j) = hel_r end subroutine function det_diagH(j) result(hel_r) integer, intent(in) :: j real(dp) :: hel_r hel_r = global_determinant_data(pos_hel, j) end function subroutine set_det_offdiagH(j, hel) integer, intent(in) :: j HElement_t(dp), intent(in) :: hel #ifdef CMPLX_ global_determinant_data(pos_hel_off, j) = real(hel,dp) global_determinant_data(pos_hel_off+1, j) = aimag(hel) #else global_determinant_data(pos_hel_off, j) = hel #endif end subroutine function det_offdiagH(j) result(hel) integer, intent(in) :: j HElement_t(dp) :: hel #ifdef CMPLX_ hel = cmplx( global_determinant_data(pos_hel_off, j), & global_determinant_data(pos_hel_off+1, j), dp) #else hel = global_determinant_data(pos_hel_off, j) #endif end function ! Store the supergroup index for a given determinant. subroutine set_supergroup_idx(j, sg_idx) integer, intent(in) :: j integer, intent(in) :: sg_idx global_determinant_data(pos_sg_idx, j) = transfer(int(sg_idx, int64), mold=global_determinant_data(pos_sg_idx, j)) end subroutine pure function get_supergroup_idx(j) result(sg_idx) integer, intent(in) :: j integer :: sg_idx integer(int64) :: sg_idx_tmp sg_idx_tmp = transfer(global_determinant_data(pos_sg_idx, j), mold=sg_idx_tmp) sg_idx = int(sg_idx_tmp) end function subroutine set_spawn_pop(j, part, t) integer, intent(in) :: j, part real(dp), intent(in) :: t global_determinant_data(pos_spawn_pop + part - 1, j) = t end subroutine function get_spawn_pop(j, part) result(t) integer, intent(in) :: j, part real(dp) :: t t = global_determinant_data(pos_spawn_pop + part - 1, j) end function subroutine set_all_spawn_pops(j, t) integer, intent(in) :: j real(dp), dimension(lenof_sign), intent(in) :: t global_determinant_data(pos_spawn_pop:pos_spawn_pop + len_spawn_pop - 1, j) = t(:) end subroutine function get_all_spawn_pops(j) result(t) integer, intent(in) :: j real(dp), dimension(lenof_sign) :: t t(:) = global_determinant_data(pos_spawn_pop:pos_spawn_pop + len_spawn_pop - 1, j) end function subroutine reset_all_tau_ints(j) integer, intent(in) :: j global_determinant_data(pos_tau_int:pos_tau_int + len_tau_int - 1, j) = 0.0_dp end subroutine subroutine reset_tau_int(j, run) integer, intent(in) :: j, run global_determinant_data(pos_tau_int + run - 1, j) = 0.0_dp end subroutine subroutine update_tau_int(j, run, t) integer, intent(in) :: j, run real(dp), intent(in) :: t global_determinant_data(pos_tau_int + run - 1, j) = global_determinant_data(pos_tau_int + run - 1, j) + t end subroutine function get_tau_int(j, run) result(t) integer, intent(in) :: j, run real(dp) :: t t = global_determinant_data(pos_tau_int + run - 1, j) end function subroutine reset_all_shift_ints(j) integer, intent(in) :: j global_determinant_data(pos_shift_int:pos_shift_int + len_shift_int - 1, j) = 0.0_dp end subroutine subroutine reset_shift_int(j, run) integer, intent(in) :: j, run global_determinant_data(pos_shift_int + run - 1, j) = 0.0_dp end subroutine subroutine update_shift_int(j, run, t) integer, intent(in) :: j, run real(dp), intent(in) :: t global_determinant_data(pos_shift_int + run - 1, j) = global_determinant_data(pos_shift_int + run - 1, j) + t end subroutine function get_shift_int(j, run) result(t) integer, intent(in) :: j, run real(dp) :: t t = global_determinant_data(pos_shift_int + run - 1, j) end function subroutine reset_all_tot_spawns(j) integer, intent(in) :: j global_determinant_data(pos_tot_spawns:pos_tot_spawns + len_tot_spawns - 1, j) = 0.0_dp end subroutine subroutine update_tot_spawns(j, run, t) integer, intent(in) :: j, run real(dp), intent(in) :: t global_determinant_data(pos_tot_spawns + run - 1, j) = global_determinant_data(pos_tot_spawns + run - 1, j) + t end subroutine pure function get_tot_spawns(j, run) result(t) integer, intent(in) :: j, run real(dp) :: t t = global_determinant_data(pos_tot_spawns + run - 1, j) end function subroutine readFVals(fvals, ndets, initial) implicit none real(dp), intent(in) :: fvals(2 * inum_runs, ndets) integer, intent(in) :: ndets integer, intent(in), optional :: initial integer :: start integer :: j integer :: run def_default(start, initial, 1) ! set all values of tot/acc spawns using the read-in values from fvals ! this is used in popsfile read-in to get the values from the previous calculation do j = 1, ndets do run = 1, inum_runs global_determinant_data(pos_acc_spawns + run - 1, j + start - 1) = & fvals(run, j) global_determinant_data(pos_tot_spawns + run - 1, j + start - 1) = & fvals(inum_runs + run, j) end do end do end subroutine readFVals subroutine readFValsAsInt(fvals, j) implicit none integer(n_int), intent(in) :: fvals(:) integer, intent(in) :: j integer :: run real(dp) :: realVal = 0.0_dp ! Read the acc. and tot. spawns from a contiguous integer array of size (2*inum_runs) ! This is useful for HDF5 subroutines which currently only accept integer arrays ! Check the input's size if (size(fvals) >= (2 * inum_runs)) then do run = 1, inum_runs global_determinant_data(pos_acc_spawns + run - 1, j) = transfer(fvals(run), realVal) global_determinant_data(pos_tot_spawns + run - 1, j) = transfer(fvals(run + inum_runs), realVal) end do else print *, "WARNING: Dimension mismatch in readFValsAsInt. Ignoring read data" end if end subroutine readFValsAsInt subroutine writeFValsAsInt(fvals, j) implicit none integer(n_int), intent(inout) :: fvals(:) integer, intent(in) :: j integer :: k ! Write the acc. and tot. spawns in a contiguous integer array of size (2*inum_runs) ! This is useful for HDF5 subroutines which currently only accept integer arrays if (size(fvals) >= 2 * inum_runs) then do k = 1, inum_runs fvals(k) = transfer(get_acc_spawns(j, k), fvals(k)) end do do k = 1, inum_runs fvals(k + inum_runs) = transfer(get_tot_spawns(j, k), fvals(k)) end do else ! the buffer has unsuitable size, print a warning print *, "WARNING: Dimension mismatch in writeFValsAsInt. Writing 0" fvals = 0 end if end subroutine writeFValsAsInt subroutine writeFVals(fvals, ndets, initial) implicit none real(dp), intent(inout) :: fvals(:, :) integer, intent(in) :: ndets integer, intent(in), optional :: initial integer :: j, k, start def_default(start, initial, 1) ! write the acc. and tot. spawns per determinant in a contiguous array ! fvals(:,j) = (acc, tot) for determinant j (2*inum_runs in size) do j = 1, nDets do k = 1, inum_runs fvals(k, j) = get_acc_spawns(j + start - 1, k) end do do k = 1, inum_runs fvals(k + inum_runs, j) = get_tot_spawns(j + start - 1, k) end do end do end subroutine writeFVals !------------------------------------------------------------------------------------------! subroutine reset_all_acc_spawns(j) integer, intent(in) :: j global_determinant_data(pos_acc_spawns:pos_acc_spawns + len_acc_spawns - 1, j) = 0.0_dp end subroutine subroutine update_acc_spawns(j, run, t) integer, intent(in) :: j, run real(dp), intent(in) :: t global_determinant_data(pos_acc_spawns + run - 1, j) = global_determinant_data(pos_acc_spawns + run - 1, j) + t end subroutine pure function get_acc_spawns(j, run) result(t) integer, intent(in) :: j, run real(dp) :: t t = global_determinant_data(pos_acc_spawns + run - 1, j) end function !------------------------------------------------------------------------------------------! subroutine update_pops_sum_all(ndets, iter) use FciMCData, only: CurrentDets use bit_rep_data, only: extract_sign integer(int64), intent(in) :: ndets integer, intent(in) :: iter real(dp) :: CurrentSign(lenof_sign) integer :: j do j = 1, int(ndets) call extract_sign(CurrentDets(:, j), CurrentSign) if (IsUnoccDet(CurrentSign)) cycle global_determinant_data(pos_pops_sum:pos_pops_sum + len_pops_sum - 1, j) & = global_determinant_data(pos_pops_sum:pos_pops_sum + len_pops_sum - 1, j) & + CurrentSign(:) global_determinant_data(pos_pops_iter, j) = DBLE(iter) end do end subroutine pure function get_pops_sum(j, part) result(AccSign) integer, intent(in) :: j, part real(dp) :: AccSign AccSign = global_determinant_data(pos_pops_sum + part - 1, j) end function pure function get_pops_sum_full(j) result(AccSign) integer, intent(in) :: j real(dp) :: AccSign(lenof_sign) AccSign(:) = global_determinant_data(pos_pops_sum:pos_pops_sum + len_pops_sum - 1, j) end function pure function get_pops_iter(j) result(iter) integer, intent(in) :: j real(dp) :: iter iter = global_determinant_data(pos_pops_iter, j) end function subroutine writeAPValsAsInt(apvals, j) implicit none integer(n_int), intent(inout) :: apvals(:) integer, intent(in) ::j integer :: k ! Write the accumlated population values (pops_sum and pop_iter) ! in a contiguous integer array of size (lenof_sing+1). ! This is useful for HDF5 subroutines which currently only accept integer arrays if (size(apvals, dim=1) >= lenof_sign + 1) then do k = 1, lenof_sign apvals(k) = transfer(get_pops_sum(j, k), apvals(k)) end do apvals(lenof_sign + 1) = transfer(get_pops_iter(j), apvals(k)) else ! the buffer has unsuitable size, print a warning print *, "WARNING: Dimension mismatch in writeAPValsAsInt. Writing 0" apvals = 0 end if end subroutine writeAPValsAsInt subroutine readAPValsAsInt(apvals, j) implicit none integer(n_int), intent(in) :: apvals(:) integer, intent(in) :: j integer :: k real(dp) :: realVal = 0.0_dp ! Read the accumlated population values (pops_sum and pop_iter) ! in a contiguous integer array of size (lenof_sing+1). ! This is useful for HDF5 subroutines which currently only accept integer arrays if (size(apvals, dim=1) >= lenof_sign + 1) then do k = 1, lenof_sign global_determinant_data(pos_pops_sum + k - 1, j) = transfer(apvals(k), realVal) end do global_determinant_data(pos_pops_iter, j) = transfer(apvals(lenof_sign + 1), realVal) else print *, "WARNING: Dimension mismatch in readAPValsAsInt. Ignoring read data" end if end subroutine readAPValsAsInt subroutine readAPVals(apvals, ndets, initial) implicit none integer, intent(in) :: ndets real(dp), intent(in) :: apvals(lenof_sign + 1, ndets) integer, intent(in), optional :: initial integer :: j, k, start ! set all values of pops sum/iter using the read-in values from apvals ! this is used in popsfile read-in to get the values from the previous calculation def_default(start, initial, 1) do j = 1, ndets do k = 1, lenof_sign global_determinant_data(pos_pops_sum + k - 1, j) = apvals(k, j) end do global_determinant_data(pos_pops_iter, j) = apvals(lenof_sign + 1, j) end do end subroutine readAPVals subroutine writeAPVals(apvals, ndets, initial) implicit none real(dp), intent(inout) :: apvals(:, :) integer, intent(in) :: ndets integer, intent(in), optional :: initial integer :: j, k, start def_default(start, initial, 1) ! write the pops sum/iter per determinant in a contiguous array ! apvals(:,j) = (sum, iter) for determinant j (lenof_sign+1 in size) do j = 1, nDets do k = 1, lenof_sign apvals(k, j) = get_pops_sum(j + start - 1, k) end do apvals(lenof_sign + 1, j) = get_pops_iter(j + start - 1) end do end subroutine writeAPVals !------------------------------------------------------------------------------------------! subroutine set_av_sgn_tot_sgl(j, part, av_sgn) integer, intent(in) :: j, part real(dp), intent(in) :: av_sgn global_determinant_data(pos_av_sgn + part - 1, j) = av_sgn end subroutine subroutine set_av_sgn_tot_all(j, av_sgn) integer, intent(in) :: j real(dp), intent(in) :: av_sgn(len_av_sgn_tot) global_determinant_data(pos_av_sgn:pos_av_sgn + len_av_sgn_tot - 1, j) = & av_sgn end subroutine subroutine set_iter_occ_tot_sgl(j, part, iter_occ) ! It is unusual, but all the RDM code uses real(dp) values for the ! current iteration. As floats store integers exactly up to a ! sensible limit, this is just fine, and simplifies this code. ! ! But it is weird. integer, intent(in) :: j, part real(dp), intent(in) :: iter_occ global_determinant_data(pos_iter_occ + part - 1, j) = iter_occ end subroutine subroutine set_iter_occ_tot_all(j, iter_occ) ! It is unusual, but all the RDM code uses real(dp) values for the ! current iteration. As floats store integers exactly up to a ! sensible limit, this is just fine, and simplifies this code. ! ! But it is weird. integer, intent(in) :: j real(dp), intent(in) :: iter_occ(len_iter_occ_tot) global_determinant_data(pos_iter_occ: & pos_iter_occ + len_iter_occ_tot - 1, j) = iter_occ end subroutine ! -----Routines for extracting the properties of both standard and-------- ! -----transition RDMs together------------------------------------------- function get_av_sgn_tot_sgl(j, part) result(av_sgn) integer, intent(in) :: j, part real(dp) :: av_sgn av_sgn = global_determinant_data(pos_av_sgn + part - 1, j) end function function get_av_sgn_tot_all(j) result(av_sgn) integer, intent(in) :: j real(dp) :: av_sgn(len_av_sgn_tot) av_sgn = global_determinant_data(pos_av_sgn: & pos_av_sgn + len_av_sgn_tot - 1, j) end function function get_iter_occ_tot_sgl(j, part) result(iter_occ) integer, intent(in) :: j, part real(dp) :: iter_occ iter_occ = global_determinant_data(pos_iter_occ + part - 1, j) end function function get_iter_occ_tot_all(j) result(iter_occ) integer, intent(in) :: j real(dp) :: iter_occ(len_iter_occ_tot) iter_occ = global_determinant_data(pos_iter_occ: & pos_iter_occ + len_iter_occ_tot - 1, j) end function function get_spawn_rate(j) result(rate) integer, intent(in) :: j real(dp) :: rate #ifdef DEBUG_ character(*), parameter :: this_routine = 'get_spawn_rate' #endif ASSERT(tContTimeFCIMC .and. tContTimeFull) rate = global_determinant_data(pos_spawn_rate, j) end function subroutine set_spawn_rate(j, rate) integer, intent(in) :: j real(dp), intent(in) :: rate #ifdef DEBUG_ character(*), parameter :: this_routine = 'set_spawn_rate' #endif ASSERT(tContTimeFCIMC .and. tContTimeFull) global_determinant_data(pos_spawn_rate, j) = rate end subroutine !------------------------------------------------------------------------------------------! ! functions for storing information on the history of spawns onto a determinant !------------------------------------------------------------------------------------------! subroutine store_spawn(j, spawn_sgn) implicit none integer, intent(in) :: j real(dp), intent(in) :: spawn_sgn(lenof_sign) integer :: part do part = 1, lenof_sign if (spawn_sgn(part) > eps) then global_determinant_data(pos_pos_spawns + part - 1, j) = & global_determinant_data(pos_pos_spawns + part - 1, j) + abs(spawn_sgn(part)) else if (spawn_sgn(part) < -eps) then global_determinant_data(pos_neg_spawns + part - 1, j) = & global_determinant_data(pos_neg_spawns + part - 1, j) + abs(spawn_sgn(part)) end if end do end subroutine store_spawn !------------------------------------------------------------------------------------------! pure function get_pos_spawns(j) result(avSpawn) implicit none integer, intent(in) :: j real(dp) :: avSpawn(lenof_sign) avSpawn = global_determinant_data(pos_pos_spawns:(pos_pos_spawns + lenof_sign - 1), j) end function get_pos_spawns !------------------------------------------------------------------------------------------! pure function get_neg_spawns(j) result(avSpawn) implicit none integer, intent(in) :: j real(dp) :: avSpawn(lenof_sign) avSpawn = global_determinant_data(pos_neg_spawns:(pos_neg_spawns + lenof_sign - 1), j) end function get_neg_spawns !------------------------------------------------------------------------------------------! function get_max_ratio(j) result(maxSpawn) ! Get the maximum ratio Hij/pgen for the determinant j so far ! Input: j - index of the determinant ! Output: maxSpawn - maximum Hij/pgen of spawning attempts from Determinant j so far implicit none integer, intent(in) :: j real(dp) :: maxSpawn maxSpawn = global_determinant_data(pos_max_ratio, j) end function get_max_ratio !------------------------------------------------------------------------------------------! subroutine update_max_ratio(spawn, j) ! Update the maximum ratio Hij/pgen for the determinant j when spawning spawn walkers ! Input: j - index of the determinant ! spawn - walkers to spawn in this attempt implicit none real(dp), intent(in) :: spawn integer, intent(in) :: j if (abs(spawn) > get_max_ratio(j)) & call set_max_ratio(abs(spawn), j) end subroutine update_max_ratio !------------------------------------------------------------------------------------------! subroutine set_max_ratio(val, j) ! Set the maximum ratio Hij/pgen for the determinant j to val ! Input: j - index of the determinant ! val - new maximum Hij/pgen ratio implicit none real(dp), intent(in) :: val integer, intent(in) :: j global_determinant_data(pos_max_ratio, j) = val end subroutine set_max_ratio !------------------------------------------------------------------------------------------! subroutine write_max_ratio(ms_vals, ndets, initial) ! Write the values of the maximum ratios Hij/pgen for all determinants to ms_vals ! Input: ndets - number of determinants ! ms_vals - On return, contains the maximum Hij/pgen ratios for all determinants ! initial - optionally: the first determinant to consider implicit none integer, intent(in) :: ndets ! use a 2-d array for compatibility - the caller does not need to know that the first ! dimension is of size 1 real(dp), intent(out) :: ms_vals(:, :) integer, intent(in), optional :: initial integer :: j, start def_default(start, initial, 1) do j = 1, ndets ms_vals(1, j) = global_determinant_data(pos_max_ratio, j + start - 1) end do end subroutine write_max_ratio !------------------------------------------------------------------------------------------! subroutine set_all_max_ratios(ms_vals, ndets, initial) ! Set the maximum ratios stored to the values in ms_vals ! Input: ms_vals - Ratios to be stored. Has to be of size 1 x ndets ! ndets - number of values to be read in ! initial - index of the first entry to fill (everything before will be unchanged implicit none real(dp), intent(in) :: ms_vals(:, :) integer, intent(in) :: ndets integer, intent(in), optional :: initial integer :: j, start def_default(start, initial, 1) do j = 1, ndets call set_max_ratio(ms_vals(1, j), j + start - 1) end do end subroutine set_all_max_ratios !------------------------------------------------------------------------------------------! #ifdef USE_HDF_ subroutine set_max_ratio_hdf5Int(val, j) use hdf5, only: hsize_t ! Set the maximum ratio Hij/pgen for the determinant j to val ! Input: j - index of the determinant ! val - new maximum Hij/pgen ratio, bitwise re-interpreted as hsize_t int implicit none integer(hsize_t), intent(in) :: val(:) integer, intent(in) :: j ! dummy to specify the target type real(dp) :: real_val real_val = 0.0_dp if (size(val)>0) & global_determinant_data(pos_max_ratio, j) = transfer(val(1), real_val) end subroutine set_max_ratio_hdf5Int !------------------------------------------------------------------------------------------! subroutine write_max_ratio_as_int(ms_vals, pos) use hdf5, only: hsize_t use bit_rep_data, only: extract_sign use DetBitOps, only: FindBitExcitLevel ! Write the values of the maximum ratios Hij/pgen for all determinants to ms_vals ! Input: pos - position to get the data from ! ms_vals - On return, contains the maximum Hij/pgen ratios for all determinants implicit none integer, intent(in) :: pos ! use a 1-d array for compatibility - the caller does not need to know that the ! dimension is of size 1 integer(hsize_t), intent(out) :: ms_vals(:) ms_vals(1) = transfer(global_determinant_data(pos_max_ratio, pos), ms_vals(1)) end subroutine write_max_ratio_as_int #endif !------------------------------------------------------------------------------------------! ! Global storage for storing nI for each occupied determinant to save time for ! conversion from ilut to nI !------------------------------------------------------------------------------------------! subroutine store_decoding(j, nI) implicit none integer, intent(in) :: j, nI(nel) if (tStoredDets) then global_determinants(:, j) = nI end if end subroutine store_decoding function get_determinant(j) result(nI) implicit none integer, intent(in) :: j integer :: nI(nel) if (tStoredDets) then nI = global_determinants(:, j) else nI = 0 end if end function get_determinant end module