checkinput Subroutine

public subroutine checkinput()

Arguments

None

Contents

Source Code


Source Code

    subroutine checkinput()

        ! Check that the specified runtime options are consistent and valid

        use SystemData, only: nel, tUseBrillouin, beta, tFixLz, &
                              tFindCINatOrbs, tNoRenormRandExcits, LMS, STOT, &
                              tSpn, tUHF, tGenHelWeighted, tHPHF, &
                              tGen_4ind_weighted, tGen_4ind_reverse, &
                              tMultiReplicas, tGen_4ind_part_exact, &
                              tGUGA, tgen_guga_weighted, &
                              tGen_4ind_lin_exact, tGen_4ind_2, tGAS, &
                              tComplexOrbs_RealInts, tLatticeGens
        use CalcData, only: I_VMAX, NPATHS, G_VMC_EXCITWEIGHT, &
                            G_VMC_EXCITWEIGHTS, EXCITFUNCS, TMCDIRECTSUM, &
                            TDIAGNODES, TSTARSTARS, TBiasing, TMoveDets, &
                            TNoSameExcit, TInitStar, tMP2Standalone, &
                            MemoryFacPart, &
                            tSemiStochastic, semistoch_shift_iter, ss_space_in, &
                            tSpatialOnlyHash, InitWalkers, tUniqueHFNode, &
                            tCheckHighestPop, &
                            tKP_FCIQMC, tReplicaEstimates, &
                            tRealCoeffByExcitLevel, &
                            tAllRealCoeff, tUseRealCoeffs, tChangeProjEDet, &
                            tOrthogonaliseReplicas, tReadPops, tStartMP1, &
                            tStartCAS, tUniqueHFNode, tContTimeFCIMC, &
                            tContTimeFull, tFCIMC, tPreCond, tOrthogonaliseReplicas, &
                            tMultipleInitialStates, pgen_unit_test_spec, &
                            user_input_seed, tTargetShiftdamp, tFixedN0, t_core_inits, &
                            tWalkContGrow
        use real_time_data, only: tInfInit
        use Calc, only : RDMsamplingiters_in_inp
        Use Determinants, only: SpecDet, tagSpecDet, tDefinedet, DefDet
        use IntegralsData, only: nFrozen, tDiscoNodes, tQuadValMax, &
                                 tQuadVecMax, tCalcExcitStar, tJustQuads, &
                                 tNoDoubs
        use IntegralsData, only: tDiagStarStars, tExcitStarsRootChange, &
                                 tRmRootExcitStarsRootChange, tLinRootChange
        use LoggingData, only: iLogging, tCalcFCIMCPsi, tRDMOnFly, &
                               tCalcInstantS2, tDiagAllSpaceEver, &
                               tCalcVariationalEnergy, tCalcInstantS2Init, &
                               tPopsFile, tRDMOnFly, tExplicitAllRDM, &
                               tHDF5PopsRead, tHDF5PopsWrite, tCalcFcimcPsi, &
                               tHistEnergies, tPrintOrbOcc, tUserKnowsBiasedRDMS
        use Logging, only: calcrdmonfly_in_inp, RDMlinspace_in_inp
        use real_time_data, only: t_real_time_fciqmc
        use DetCalc, only: tEnergy, tCalcHMat, tFindDets, tCompressDets
        use load_balance_calcnodes, only: tLoadBalanceBlocks
        use constants
        use global_utilities
        use FciMCData, only: nWalkerHashes, HashLengthFrac, InputDiagSft, t_global_core_space
        use hist_data, only: tHistSpawn
        use Parallel_neci, only: nNodes, nProcessors
        use UMatCache, only: tDeferred_Umat2d
        use gasci, only: GAS_specification, GAS_exc_gen, possible_GAS_exc_gen, user_input_GAS_exc_gen

        use guga_init, only: checkInputGUGA
        implicit none

        integer :: vv, kk, cc, ierr
        real(dp) :: InputDiagSftSingle
        logical :: check
        character(*), parameter :: t_r = 'checkinput', this_routine = t_r

        if (tDiagAllSpaceEver .and. .not. tHistSpawn) then
            call stop_all(t_r, "DIAGALLSPACEEVER requires HISTSPAWN option")
        end if
        if (tCalcVariationalEnergy .and. .not. tHistSpawn) then
            call stop_all(t_r, "CALCVARIATIONALENERGY requires HISTSPAWN option")
        end if
        if (tCalcVariationalEnergy .and. .not. tEnergy) then
            call stop_all(t_r, "CALCVARIATIONALENERGY requires initial FCI calculation")
        end if

        nWalkerHashes = nint(HashLengthFrac * InitWalkers)

        ! ================ GUGA implementation ===============================
        ! design convention to store as many guga related functionality in
        ! guga_*.F90 files and just call the routines in the main level modules
        ! checkInputGUGA() is found in guga_init.F90
        if (tGUGA) call checkInputGUGA()

        ! Turn on histogramming of fcimc wavefunction in order to find density
        ! matrix, or the orbital occupations
        if (tFindCINatOrbs) tCalcFCIMCPsi = .true.

        ! Used in the FCIMC. We find dets and compress them for later use
        if (tCalcFCIMCPsi .or. tHistSpawn) then
            tFindDets = .true.
            tCompressDets = .true.
        end if

        ! We need to have found the dets before calculating the H mat.
        if (tCalcHMat) tFindDets = .true.

        ! If we are using TNoSameExcit, then we have to start with the star -
        ! the other random graph algorithm cannot remove same excitation
        ! links yet.
        if (tNoSameExcit .and. .not. tInitStar) then
            call stop_all(this_routine, "If we are using TNoSameExcit, then we have to start&
                         & with the star. The other random graph algorithm &
                         &cannot remove same excitation links yet.")
        end if

        ! The MoveDets and Biasing algorithms cannot both be used in the
        ! GraphMorph Algorithm.
        if (tBiasing .and. tMoveDets) then
            call stop_all(this_routine, "Biasing algorithm and MoveDets algorithm cannot both&
                        & be used")
        end if

        ! ..RmRootExcitStarsRootChange must be used with DiagStarStars, and not
        ! with ExcitStarsRootChange
        if (tRmRootExcitStarsRootChange .and. .not. tDiagStarStars) then
            call stop_all(this_routine, "RmRootExcitStarsRootChange can only with used with &
                        &DiagStarStars currently")
        end if

        if (TRmRootExcitStarsRootChange .and. TExcitStarsRootChange) then
            call stop_all(this_routine, "RmRootExcitStarsRootChange and ExcitStarsRootChange &
                        &cannot both be used as they are both different &
                        &options with diagstarstars")
        end if

        !..ExcitStarsRootChange must be used with TDiagStarStars
        if (tExcitStarsRootChange .and. .not. tDiagStarStars) then
            call stop_all(this_routine, "ExcitStarsRootChange can only with used with &
                        &DiagStarStars currently")
        end if

        ! ..TDiagStarStars must be used with TStarStars, and cannot be used
        ! with TCalcExcitStar
        if (tDiagStarStars .and. .not. tStarStars) then
            call stop_all(this_routine, "DiagStarStars must be used with StarStars")
        end if
        if (tDiagStarStars .and. tCalcExcitStar) then
            call stop_all(this_routine, "DiagStarStars is incompatable with CalcExcitStar")
        end if
        if (tDiagStarStars .and. (tNoDoubs .or. tJustQuads)) then
            call stop_all(this_routine, "NoDoubs/JustQuads cannot be used with DiagStarStars &
                        &- try CalcExcitStar")
        end if

        ! ..TNoDoubs is only an option which applied to TCalcExcitStar, and
        ! cannot occurs with TJustQuads.
        if (tNoDoubs .and. .not. tCalcExcitStar) then
            call stop_all(this_routine, "STARNODOUBS is only an option which applied to &
                        &TCalcExcitStar")
        end if

        if (tNoDoubs .and. tJustQuads) then
            call stop_all(this_routine, "STARNODOUBS and STARQUADEXCITS cannot be applied &
                        &together!")
        end if

        ! .. TJustQuads is only an option which applies to TCalcExcitStar
        if (tJustQuads .and. .not. tCalcExcitStar) then
            call stop_all(this_routine, "STARQUADEXCITS is only an option which applies to &
                        &tCalcExcitStar")
        end if

        !.. tCalcExcitStar can only be used with tStarStars
        if (tCalcExcitStar .and. .not. tStarStars) then
            call stop_all(this_routine, "CalcExcitStar can only be used with StarStars set")
        end if

        !.. Brillouin Theorem must be applied when using TStarStars
        if (tStarStars .and. .not. tUseBrillouin) then
            call stop_all(this_routine, "Brillouin Theorem must be used when using &
                        &CalcExcitStar")
        end if

        !.. TQuadValMax and TQuadVecMax can only be used if TLINESTARSTARS set
        if ((tQuadValMax .or. tQuadVecMax) .and. .not. tStarStars) then
            call stop_all(this_routine, "TQuadValMax or TQuadVecMax can only be specified if &
                        &STARSTARS specified in method line")
        end if

        !.. TQuadValMax and TQuadVecMax cannot both be set
        if (tQuadValMax .and. tQuadVecMax) then
            call stop_all(this_routine, "TQuadValMax and TQuadVecMax cannot both be set")
        end if

        !.. TDISCONODES can only be set if NODAL is set in the star methods
        ! section
        if (tDiscoNodes .and. .not. tDiagNodes) then
            call stop_all(this_routine, "DISCONNECTED NODES ONLY POSSIBLE IF NODAL SET IN &
                        &METHOD")
        end if

        if (tMultipleInitialStates .or. tOrthogonaliseReplicas .or. &
            tPreCond) then
            if (tHistSpawn .or. &
                (tCalcFCIMCPsi .and. tFCIMC) .or. tHistEnergies .or. tPrintOrbOcc) then
                call stop_all(this_routine, "HistSpawn and PrintOrbOcc not yet supported for multi-replica with different references")
            end if
        end if

        if (.not. t_global_core_space) then
            if (t_real_time_fciqmc) call stop_all(this_routine, "Real-time FCIQMC requires a global core space")
            if (tKP_FCIQMC) call stop_all(this_routine, "KP-FCIQMC requires a global core space")
            if (tReplicaEstimates) call stop_all(this_routine, "Replica estimates require a global core space")
        end if

        !.. We still need a specdet space even if we don't have a specdet.
        if (.not. associated(SPECDET)) then
            allocate(SPECDET(nel - nFrozen), stat=ierr)
            call LogMemAlloc('SPECDET', nel - nFrozen, 4, t_r, tagSPECDET, ierr)
        end if

        !..   Testing ILOGGING
        !     ILOGGING = 0771
        if (I_VMAX == 0 .and. nPaths /= 0 .and. (.not. tKP_FCIQMC)) then
            call stop_all(this_routine, 'NPATHS!=0 and I_VMAX=0.  VERTEX SUM max level not &
                         &set')
        end if

        !Ensure beta is set.
        if (beta < 1.0e-6_dp .and. .not. tMP2Standalone) then
            call stop_all(this_routine, "No beta value provided.")
        end if

        do vv = 2, I_VMAX
            g_VMC_ExcitWeights(:, vv) = g_VMC_ExcitWeights(:, 1)
            G_VMC_EXCITWEIGHT(vv) = G_VMC_EXCITWEIGHT(1)
        end do

        !IF THERE IS NO WEIGHTING FUNCTION, ExcitFuncs(10)=.true.
        do vv = 1, 9
            IF (EXCITFUNCS(vv)) EXCITFUNCS(10) = .false.
        end do

        if (tNoRenormRandExcits .and. (.not. ExcitFuncs(10))) then
            write(stdout, *) "Random excitations WILL have to be renormalised, &
                       &since an excitation weighting has been detected."
        end if

        ! if the LMS value specified is not reachable with the number of electrons,
        ! fix this
        if (mod(abs(lms), 2) /= mod(nel, 2)) then
            call stop_all(t_r, "LMS Value is not reachable with the given number of electrons.")
        end if

        if (tCalcInstantS2 .or. tCalcInstantS2Init) then
            if (tUHF) then
                call stop_all(t_r, 'Cannot calculate instantaneous values of&
                              & S^2 with UF enabled.')
            end if
            write(stdout, *) 'Enabling calculation of instantaneous S^2 each &
                       &iteration.'
        end if

        if (tUniqueHFNode .and. nProcessors < 2) then
            write(stdout, *) "nNodes: ", nNodes
            write(stdout, *) 'nProcessors: ', nProcessors
            call stop_all(t_r, 'At least two nodes required to designate &
                          &a node uniquely to the HF determinant')
        end if

        if (tGenHelWeighted) then
            write(stdout, *)
            write(stdout, *) '*** WARNING ***'
            write(stdout, *) 'Slow HElement biased excitation generators in use.'
            write(stdout, *) 'NOT FOR PRODUCTION RUNS'
            write(stdout, *) '***************'
            write(stdout, *)
        end if

        if (tGen_4ind_weighted .or. tGen_4ind_reverse .or. tGen_4ind_2 &
            .or. tgen_guga_weighted) then

            ! We want to use UMAT2D...
            tDeferred_Umat2d = .true.

        end if

        if (tHPHF .and. tUHF) then
            call stop_all(t_r, 'HPHF functions cannot work with UHF')
        end if

#if PROG_NUMRUNS_
        if (tKP_FCIQMC .and. .not. tMultiReplicas) then

            write(stdout, *) 'Using KPFCIQMC without explicitly specifying the &
                       &number of replica simulations'
            write(stdout, *) 'Defaulting to using 2 replicas'
            tMultiReplicas = .true.
#ifdef CMPLX_
            lenof_sign = 4
#else
            lenof_sign = 2
#endif
            inum_runs = 2

            ! Correct the size of InputDiagSft:
            InputDiagSftSingle = InputDiagSft(1)
            deallocate(InputDiagSft)
            allocate(InputDiagSft(inum_runs))
            InputDiagSft = InputDiagSftSingle
        end if
#endif

#if PROG_NUMRUNS_
        if (tRDMonFly) then
            write(stdout, *) 'RDM on fly'

            if (.not. tMultiReplicas) then
                write(stdout, *) 'unspecified'
                write(stdout, *) 'Filling RDMs without explicitly specifying the &
                           &number of replica simplations'
                write(stdout, *) 'Defaulting to using 2 replicas'
                tMultiReplicas = .true.
                lenof_sign = 2
                inum_runs = 2

                ! Correct the size of InputDiagSft:
                InputDiagSftSingle = InputDiagSft(1)
                deallocate(InputDiagSft)
                allocate(InputDiagSft(inum_runs))
                InputDiagSft = InputDiagSftSingle
            end if
        end if
#endif


#if ! (defined(PROG_NUMRUNS_) || defined(DOUBLERUN_))
        if (tRDMonFly .and. .not. tUserKnowsBiasedRDMS) then
            write(stdout, *) 'RDM sampling is specified, but this version of neci'
            write(stdout, *) 'is not compiled with the replica trick.'
            write(stdout, *) 'You probably want to use dneci or mneci &
                    &(or their complex counterparts).'
            write(stdout, *)
            write(stdout, *) 'If you know what you do and really want to sample biased RDMS'
            write(stdout, *) 'you can also add `BIASED-RDMS` to the Logging block.'
            call stop_all(t_r, "Compiled version does not support RDM sampling.")
        end if
#endif

        if (tRDMOnFly .and. .not. tCheckHighestPop) then
            write(stdout, *) 'Highest population checking required for calculating &
                       &RDMs on the fly'
            write(stdout, *) 'If you are seeing this, it is an input parsing error'
            call stop_all(t_r, 'RDMs without CheckHighestPop')
        end if

        if (tSemiStochastic .and. .not. (tAllRealCoeff .and. tUseRealCoeffs)) then
            write(stdout, *) 'Semi-stochastic simulations only supported when using &
                       &ALLREALCOEFF option'
            call stop_all(t_r, 'Semistochastic without ALLREALCOEFF')
        end if

        if (ss_space_in%tPopsProportion &
                .and. .not. tSemiStochastic &
                .and. semistoch_shift_iter < 1) then
            call stop_all(t_r, 'POPS-CORE-PROPORTION requires SEMI-STOCHASTIC option')
        end if

        if (ss_space_in%tPopsCore .and. ss_space_in%tPopsProportion) then
            call stop_all(t_r, 'POPS-CORE and POPS-CORE-PROPORTION cannot be used&
                               & at the same time')
        end if

        if (tAllRealCoeff .and. tRealCoeffByExcitLevel) then
            call stop_all(t_r, 'Options ALLREALCOEFF and REALCOEFFBYEXCITLEVEL&
                               & are incompatibile')
        end if

        if (RDMlinspace_in_inp .and. (RDMsamplingiters_in_inp .or. calcrdmonfly_in_inp)) then
            call stop_all(t_r, 'RDMlinspace and (RDMsamplingiters + calcrdmonfly) &
                               &are mutually exclusive')
        end if

        if (tOrthogonaliseReplicas) then
            if (.not. tMultiReplicas) then
                call stop_all(t_r, 'Replica orthogonalisation requires &
                                   &SYSTEM-REPLICAS to determine the number &
                                   &of simulations')
            end if

            if (tStartMP1 .or. tStartCAS) then
                call stop_all(t_r, "MP1 or CAS starting not implemented for &
                                   &orthogonalised calculations")
            end if
        end if

        if (tLoadBalanceBlocks) then
            if (tUniqueHFNode) then
                call stop_all(t_r, "UNIQUE-HF-NODE requires disabling &
                                   &LOAD-BALANCE-BLOCKS")
            end if

            ! If there is only one node, then load balancing doesn't make
            ! a great deal of sense, and only slows things down...
            if (nNodes == 1) then
                write(stdout, *) 'Disabling load balancing for single node calculation'
                tLoadBalanceBlocks = .false.
            end if

            if (tContTimeFCIMC .and. tContTimeFull) then
                call stop_all(t_r, 'Load balancing not yet usable for &
                             &calculations requiring accumulated determinant &
                             &specific global data')
            end if
        end if

#ifndef USE_HDF_
        if (tHDF5PopsRead .or. tHDF5PopsWrite) then
            call stop_all(t_r, 'Support for HDF5 files disabled at compile time')
        end if
#endif

        if (tFixLz .and. tComplexOrbs_RealInts) then
            write(stdout, *) 'Options LZTOT and COMPLEXORBS_REALINTS incompatible'
            write(stdout, *)
            write(stdout, *) '1. Using multiple options that filter integrals at runtime is unsupported.'
            write(stdout, *) '   Only one integral filter may be used at once.'
            write(stdout, *)
            write(stdout, *) '2. This is almost certainly not what you intended to do.  LZTOT works using'
            write(stdout, *) '   abelian symmetries combined with momentum information. COMPLEXORBS_REALINTS'
            write(stdout, *) '   provides support for non-abelian symmetries in FCIDUMP files produced'
            write(stdout, *) '   using VASP'
            write(stdout, *)
            call stop_all(t_r, 'Options incompatible')
        end if

        if (tLatticeGens) then
            if (tGen_4ind_2 .or. tGen_4ind_weighted .or. tGen_4ind_reverse) then
                call stop_all(t_r, "Invalid excitation options")
            end if
        end if

        if (tGAS .neqv. allocated(user_input_GAS_exc_gen)) then
            call stop_all(this_routine, 'GAS-CI and GAS-SPEC required.')
        end if

        if (tGAS) then
            if (.not. tDefineDet) then
                call stop_all(t_r, "Running GAS requires a user-defined reference via definedet.")
            endif
            if (.not. GAS_specification%contains_conf(DefDet)) then
                call stop_all(t_r, "Reference determinant has to be contained in GAS space.")
            endif
            if (.not. GAS_specification%is_valid()) then
                call stop_all(t_r, "GAS specification not valid.")
            end if
            if (.not. GAS_specification%recoupling() .and. all(GAS_exc_gen /= [possible_GAS_exc_gen%DISCONNECTED, possible_GAS_exc_gen%PCHB])) then
                call stop_all(t_r, "Running GAS without spin-recoupling requires {DISCONNECTED, GENERAL_PCHB} implementations.")
            end if
            if (GAS_exc_gen == possible_GAS_exc_gen%DISCONNECTED .and.  GAS_specification%is_connected()) then
                call stop_all(t_r, "Running GAS-CI = DISCONNECTED requires disconnected spaces.")
            end if
        end if

        if (tDefineDet .and. allocated(user_input_m_s)) then
            if (sum(merge(1, -1, mod(DefDet, 2) == 0)) /= user_input_m_s) then
                call stop_all(t_r, "Spin of Definedet and Spin-restrict is not consistent.")
            end if
        end if

        if (allocated(pgen_unit_test_spec) .and. .not. tReadPops) then
            call stop_all(t_r, "UNIT-TEST-PGEN requires READPOPS.")
        end if

        if (tTargetShiftdamp .and. tFixedN0) then
            call stop_all(t_r, "TARGET-SHIFTDAMP and FIXED-N0 not compatible.")
        end if

        if (tTargetShiftdamp .and. tWalkContGrow) then
            call stop_all(t_r, "TARGET-SHIFTDAMP and WALKCONTGROW not compatible.")
        end if

        if (.not. (tInfInit .implies. t_core_inits)) then
            call stop_all(t_r, 'INFINITE-INIT requires CORE-INITS OFF.')
        end if

        block
            use load_balance_calcnodes, only: &
                tLoadBalanceBlocks, loadBalanceInterval
            logical :: deterministic
            if (allocated(user_input_seed)) then
                deterministic = loadBalanceInterval /= 0
                if (tLoadBalanceBlocks .and. .not. deterministic) then
        write(stdout, *) 'Seed was specified in input.'
        write(stdout, *) 'Please note that because of load-balancing the calculation is not fully deterministic (CPU load).'
        write(stdout, *) 'If a fully deterministic calculation is required use the `load-balance-interval` keyword.'
                end if
            end if
        end block


        time_step: block
            if (.not. allocated(tau_start_val)) then
                call stop_all(t_r, 'Start value for tau is required.')
            end if

            if (tau_start_val == possible_tau_start%from_popsfile .neqv. tReadPops) then
                if (tau_start_val == possible_tau_start%from_popsfile) then
                    call stop_all(t_r, 'Starting tau from popsfile requires readpops.')
                else if (.not. readpops_but_tau_not_from_popsfile) then
                    write(stdout, *) 'Using readpops while not reading tau from popsfile is &
                        &very likely an input error.'
                    write(stdout, *) 'If you think that your input is correct and you know what you do &
                        &add `readpops-but-tau-not-from-popsfile` to the tau-values keywords'
                    call stop_all(t_r, 'Readpops requires `tau-values start from-popsfile`.')
                end if
            end if

            if (tau_start_val == possible_tau_start%tau_factor &
                    .and. t_trans_corr_2body .and. t_k_space_hubbard) then
                call stop_all(this_routine, &
                              "finding the number of excits from HF breaks for too large lattice.")
            end if

            if (tau_start_val == possible_tau_start%refdet_connections .and. tGUGA) then
                call stop_all(this_routine, &
                              "tau-values start refdet-connections is not compatible with GUGA calculations!")
            end if

            if (tau_search_method /= possible_tau_search_methods%off) then
                if (tTruncInitiator .and. MaxWalkerBloom > InitiatorWalkNo) then
                    call stop_all(this_routine, &
                                  "MaxWalkerBloom has to be smaller equal than InitiatorWalkNo.")
                end if
                if (tScaleBlooms .and. MaxWalkerBloom > max_allowed_spawn) then
                    call stop_all(this_routine, &
                                  "MaxWalkerBloom has to be smaller equal than max_allowed_spawn.")
                end if
            end if
        end block time_step

    end subroutine checkinput