#include "gmxpre.h"
#include "gromacs/gmxlib/nrnb.h"
-#include "gromacs/gmxlib/nonbonded/nb_free_energy.h"
-#include "gromacs/gmxlib/nonbonded/nonbonded.h"
#include "gromacs/math/vectypes.h"
#include "gromacs/mdlib/enerdata_utils.h"
#include "gromacs/mdlib/force.h"
accountFlops(nrnb, pairlistSet, *this, ic, stepWork);
}
-
-void nonbonded_verlet_t::dispatchFreeEnergyKernel(gmx::InteractionLocality iLocality,
- gmx::ArrayRef<const gmx::RVec> coords,
- gmx::ForceWithShiftForces* forceWithShiftForces,
- bool useSimd,
- int ntype,
- real rlist,
- const interaction_const_t& ic,
- gmx::ArrayRef<const gmx::RVec> shiftvec,
- gmx::ArrayRef<const real> nbfp,
- gmx::ArrayRef<const real> nbfp_grid,
- gmx::ArrayRef<const real> chargeA,
- gmx::ArrayRef<const real> chargeB,
- gmx::ArrayRef<const int> typeA,
- gmx::ArrayRef<const int> typeB,
- t_lambda* fepvals,
- gmx::ArrayRef<const real> lambda,
- gmx_enerdata_t* enerd,
- const gmx::StepWorkload& stepWork,
- t_nrnb* nrnb)
-{
- const auto nbl_fep = pairlistSets().pairlistSet(iLocality).fepLists();
-
- /* When the first list is empty, all are empty and there is nothing to do */
- if (!pairlistSets().params().haveFep || nbl_fep[0]->nrj == 0)
- {
- return;
- }
-
- int donb_flags = 0;
- /* Add short-range interactions */
- donb_flags |= GMX_NONBONDED_DO_SR;
-
- if (stepWork.computeForces)
- {
- donb_flags |= GMX_NONBONDED_DO_FORCE;
- }
- if (stepWork.computeVirial)
- {
- donb_flags |= GMX_NONBONDED_DO_SHIFTFORCE;
- }
- if (stepWork.computeEnergy)
- {
- donb_flags |= GMX_NONBONDED_DO_POTENTIAL;
- }
-
- gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> dvdl_nb = { 0 };
- int kernelFlags = donb_flags;
- gmx::ArrayRef<const real> kernelLambda = lambda;
- gmx::ArrayRef<real> kernelDvdl = dvdl_nb;
-
- gmx::ArrayRef<real> energygrp_elec = enerd->grpp.energyGroupPairTerms[NonBondedEnergyTerms::CoulombSR];
- gmx::ArrayRef<real> energygrp_vdw = enerd->grpp.energyGroupPairTerms[NonBondedEnergyTerms::LJSR];
-
- GMX_ASSERT(gmx_omp_nthreads_get(ModuleMultiThread::Nonbonded) == nbl_fep.ssize(),
- "Number of lists should be same as number of NB threads");
-
- wallcycle_sub_start(wcycle_, WallCycleSubCounter::NonbondedFep);
-#pragma omp parallel for schedule(static) num_threads(nbl_fep.ssize())
- for (gmx::index th = 0; th < nbl_fep.ssize(); th++)
- {
- try
- {
- gmx_nb_free_energy_kernel(*nbl_fep[th],
- coords,
- forceWithShiftForces,
- useSimd,
- ntype,
- rlist,
- ic,
- shiftvec,
- nbfp,
- nbfp_grid,
- chargeA,
- chargeB,
- typeA,
- typeB,
- kernelFlags,
- kernelLambda,
- kernelDvdl,
- energygrp_elec,
- energygrp_vdw,
- nrnb);
- }
- GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
- }
-
- if (fepvals->sc_alpha != 0)
- {
- enerd->dvdl_nonlin[FreeEnergyPerturbationCouplingType::Vdw] +=
- dvdl_nb[FreeEnergyPerturbationCouplingType::Vdw];
- enerd->dvdl_nonlin[FreeEnergyPerturbationCouplingType::Coul] +=
- dvdl_nb[FreeEnergyPerturbationCouplingType::Coul];
- }
- else
- {
- enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Vdw] +=
- dvdl_nb[FreeEnergyPerturbationCouplingType::Vdw];
- enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Coul] +=
- dvdl_nb[FreeEnergyPerturbationCouplingType::Coul];
- }
-
- /* If we do foreign lambda and we have soft-core interactions
- * we have to recalculate the (non-linear) energies contributions.
- */
- if (fepvals->n_lambda > 0 && stepWork.computeDhdl && fepvals->sc_alpha != 0)
- {
- gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> lam_i;
- kernelFlags = (donb_flags & ~(GMX_NONBONDED_DO_FORCE | GMX_NONBONDED_DO_SHIFTFORCE))
- | GMX_NONBONDED_DO_FOREIGNLAMBDA;
- kernelLambda = lam_i;
- kernelDvdl = dvdl_nb;
- gmx::ArrayRef<real> energygrp_elec =
- foreignEnergyGroups_->energyGroupPairTerms[NonBondedEnergyTerms::CoulombSR];
- gmx::ArrayRef<real> energygrp_vdw =
- foreignEnergyGroups_->energyGroupPairTerms[NonBondedEnergyTerms::LJSR];
-
- for (gmx::index i = 0; i < 1 + enerd->foreignLambdaTerms.numLambdas(); i++)
- {
- std::fill(std::begin(dvdl_nb), std::end(dvdl_nb), 0);
- for (int j = 0; j < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); j++)
- {
- lam_i[j] = (i == 0 ? lambda[j] : fepvals->all_lambda[j][i - 1]);
- }
- foreignEnergyGroups_->clear();
-#pragma omp parallel for schedule(static) num_threads(nbl_fep.ssize())
- for (gmx::index th = 0; th < nbl_fep.ssize(); th++)
- {
- try
- {
- gmx_nb_free_energy_kernel(*nbl_fep[th],
- coords,
- forceWithShiftForces,
- useSimd,
- ntype,
- rlist,
- ic,
- shiftvec,
- nbfp,
- nbfp_grid,
- chargeA,
- chargeB,
- typeA,
- typeB,
- kernelFlags,
- kernelLambda,
- kernelDvdl,
- energygrp_elec,
- energygrp_vdw,
- nrnb);
- }
- GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
- }
- std::array<real, F_NRE> foreign_term = { 0 };
- sum_epot(*foreignEnergyGroups_, foreign_term.data());
- enerd->foreignLambdaTerms.accumulate(
- i,
- foreign_term[F_EPOT],
- dvdl_nb[FreeEnergyPerturbationCouplingType::Vdw]
- + dvdl_nb[FreeEnergyPerturbationCouplingType::Coul]);
- }
- }
- wallcycle_sub_stop(wcycle_, WallCycleSubCounter::NonbondedFep);
-}