}
gmxForceCalculator_->interactionConst_->coulombEwaldTables =
std::make_unique<EwaldCorrectionTables>();
- init_interaction_const_tables(nullptr, gmxForceCalculator_->interactionConst_.get(), 0);
+ init_interaction_const_tables(nullptr, gmxForceCalculator_->interactionConst_.get(), 0, 0);
}
}
:issue:`3469`
+Correct excluded perturbed interactions beyond the non-bonded cut-off distance
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+With free-energy calculations without coupling of intermolecular interactions,
+non-bonded pair interactions at distance longer than the cut-off distance can
+be excluded. These interactions would still have PME long-range contributions.
+The contributions are now removed. In addition, mdrun will stop with a fatal
+error when interactions beyond the pair-list cut-off are present.
+
+:issue:`3403`
+:issue:`3808`
+
Corrected AWH initial histogram size
""""""""""""""""""""""""""""""""""""
}
/* We always re-initialize the tables whether they are used or not */
- init_interaction_const_tables(nullptr, ic, ir.tabext);
+ init_interaction_const_tables(nullptr, ic, set->rlistOuter, ir.tabext);
Nbnxm::gpu_pme_loadbal_update_param(nbv, ic);
real* gmx_restrict f = &(forceWithShiftForces->force()[0][0]);
real* gmx_restrict fshift = &(forceWithShiftForces->shiftForces()[0][0]);
+ const real rlistSquared = gmx::square(fr->rlist);
+
+ int numExcludedPairsBeyondRlist = 0;
+
for (int n = 0; n < nri; n++)
{
int npair_within_cutoff = 0;
}
npair_within_cutoff++;
+ if (rsq > rlistSquared)
+ {
+ numExcludedPairsBeyondRlist++;
+ }
+
if (rsq > 0)
{
/* Note that unlike in the nbnxn kernels, we do not need
}
}
- if (vdwInteractionTypeIsEwald && r < rvdw)
+ if (vdwInteractionTypeIsEwald && (r < rvdw || !bPairIncluded))
{
/* See comment in the preamble. When using LJ-Ewald interactions
* (unless we use a switch modifier) we subtract the reciprocal-space
*/
#pragma omp atomic
inc_nrnb(nrnb, eNR_NBKERNEL_FREE_ENERGY, nlist->nri * 12 + nlist->jindex[nri] * 150);
+
+ if (numExcludedPairsBeyondRlist > 0)
+ {
+ gmx_fatal(FARGS,
+ "There are %d perturbed non-bonded pair interactions beyond the pair-list cutoff "
+ "of %g nm, which is not supported. This can happen because the system is "
+ "unstable or because intra-molecular interactions at long distances are "
+ "excluded. If the "
+ "latter is the case, you can try to increase nstlist or rlist to avoid this."
+ "The error is likely triggered by the use of couple-intramol=no "
+ "and the maximal distance in the decoupled molecule exceeding rlist.",
+ numExcludedPairsBeyondRlist, fr->rlist);
+ }
}
typedef void (*KernelFunction)(const t_nblist* gmx_restrict nlist,
* both accuracy requirements, when relevant.
*/
static void init_ewald_f_table(const interaction_const_t& ic,
- const real tableExtensionLength,
+ const real rlist,
+ const real tabext,
EwaldCorrectionTables* coulombTables,
EwaldCorrectionTables* vdwTables)
{
const bool havePerturbedNonbondeds = (ic.softCoreParameters != nullptr);
real tableLen = ic.rcoulomb;
- if (useCoulombTable && havePerturbedNonbondeds && tableExtensionLength > 0.0)
+ if ((useCoulombTable || useVdwTable) && havePerturbedNonbondeds && rlist + tabext > 0.0)
{
/* TODO: Ideally this should also check if couple-intramol == no, but that isn't
* stored in ir. Grompp puts that info into an opts structure that doesn't make it into the tpr.
* couple-intramol == no. Meanwhile, always having larger tables should only affect
* memory consumption, not speed (barring cache issues).
*/
- tableLen = ic.rcoulomb + tableExtensionLength;
+ tableLen = rlist + tabext;
}
const int tableSize = static_cast<int>(tableLen * tableScale) + 2;
}
}
-void init_interaction_const_tables(FILE* fp, interaction_const_t* ic, const real tableExtensionLength)
+void init_interaction_const_tables(FILE* fp, interaction_const_t* ic, const real rlist, const real tableExtensionLength)
{
if (EEL_PME_EWALD(ic->eeltype) || EVDW_PME(ic->vdwtype))
{
- init_ewald_f_table(*ic, tableExtensionLength, ic->coulombEwaldTables.get(),
+ init_ewald_f_table(*ic, rlist, tableExtensionLength, ic->coulombEwaldTables.get(),
ic->vdwEwaldTables.get());
if (fp != nullptr)
{
/* fr->ic is used both by verlet and group kernels (to some extent) now */
init_interaction_const(fp, &fr->ic, ir, mtop, systemHasNetCharge);
- init_interaction_const_tables(fp, fr->ic, ir->tabext);
+ init_interaction_const_tables(fp, fr->ic, fr->rlist, ir->tabext);
const interaction_const_t* ic = fr->ic;
* Initializes the tables in the interaction constant data structure.
* \param[in] fp File for debugging output
* \param[in] ic Structure holding the table constant
+ * \param[in] rlist Length of the neighbour list
* \param[in] tableExtensionLength Length by which to extend the tables. Taken from the input record.
*/
-void init_interaction_const_tables(FILE* fp, interaction_const_t* ic, real tableExtensionLength);
+void init_interaction_const_tables(FILE* fp, interaction_const_t* ic, real rlist, real tableExtensionLength);
/*! \brief Initialize forcerec structure.
*
GMX_RELEASE_ASSERT(options.ewaldcoeff_q > 0, "Ewald coefficient should be > 0");
ic.ewaldcoeff_q = options.ewaldcoeff_q;
ic.coulombEwaldTables = std::make_unique<EwaldCorrectionTables>();
- init_interaction_const_tables(nullptr, &ic, 0);
+ init_interaction_const_tables(nullptr, &ic, 0, 0);
}
return ic;