}
/* We always re-initialize the tables whether they are used or not */
- init_interaction_const_tables(nullptr, ic);
+ init_interaction_const_tables(nullptr, ic, ir.tabext);
Nbnxm::gpu_pme_loadbal_update_param(nbv, ic);
const RealType dz = iz - x[j3 + 2];
const RealType rsq = dx * dx + dy * dy + dz * dz;
RealType FscalC[NSTATES], FscalV[NSTATES];
+ /* Check if this pair on the exlusions list.*/
+ const bool bPairIncluded = nlist->excl_fep == nullptr || nlist->excl_fep[k];
- if (rsq >= rcutoff_max2)
+ if (rsq >= rcutoff_max2 && bPairIncluded)
{
/* We save significant time by skipping all code below.
* Note that with soft-core interactions, the actual cut-off
* check might be different. But since the soft-core distance
* is always larger than r, checking on r here is safe.
+ * Exclusions outside the cutoff can not be skipped as
+ * when using Ewald: the reciprocal-space
+ * Ewald component still needs to be subtracted.
*/
+
continue;
}
npair_within_cutoff++;
tj[STATE_A] = ntiA + 2 * typeA[jnr];
tj[STATE_B] = ntiB + 2 * typeB[jnr];
- if (nlist->excl_fep == nullptr || nlist->excl_fep[k])
+ if (bPairIncluded)
{
c6[STATE_A] = nbfp[tj[STATE_A]];
c6[STATE_B] = nbfp[tj[STATE_B]];
FscalC[i] *= rpinvC;
FscalV[i] *= rpinvV;
}
- }
+ } // end for (int i = 0; i < NSTATES; i++)
/* Assemble A and B states */
for (int i = 0; i < NSTATES; i++)
dvdl_vdw += Vvdw[i] * DLF[i];
}
}
- }
+ } // end if (bPairIncluded)
else if (icoul == GMX_NBKERNEL_ELEC_REACTIONFIELD)
{
/* For excluded pairs, which are only in this pair list when
}
}
- if (elecInteractionTypeIsEwald && r < rcoulomb)
+ if (elecInteractionTypeIsEwald && (r < rcoulomb || !bPairIncluded))
{
/* See comment in the preamble. When using Ewald interactions
* (unless we use a switch modifier) we subtract the reciprocal-space
#pragma omp atomic
f[j3 + 2] -= tz;
}
- }
+ } // end for (int k = nj0; k < nj1; k++)
/* The atomics below are expensive with many OpenMP threads.
* Here unperturbed i-particles will usually only have a few
Vv[ggid] += vvtot;
}
}
- }
+ } // end for (int n = 0; n < nri; n++)
#pragma omp atomic
dvdl[efptCOUL] += dvdl_coul;
* both accuracy requirements, when relevant.
*/
static void init_ewald_f_table(const interaction_const_t& ic,
+ const real tableExtensionLength,
EwaldCorrectionTables* coulombTables,
EwaldCorrectionTables* vdwTables)
{
*/
const real tableScale = ewald_spline3_table_scale(ic, useCoulombTable, useVdwTable);
- const int tableSize = static_cast<int>(ic.rcoulomb * tableScale) + 2;
+ real tableLen = ic.rcoulomb;
+ if (useCoulombTable && tableExtensionLength > 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.
+ * The alternative is to look through all the exclusions and check if they come from
+ * couple-intramol == no. Meanwhile, always having larger tables should only affect
+ * memory consumption, not speed (barring cache issues).
+ */
+ tableLen = ic.rcoulomb + tableExtensionLength;
+ }
+ const int tableSize = static_cast<int>(tableLen * tableScale) + 2;
if (useCoulombTable)
{
}
}
-void init_interaction_const_tables(FILE* fp, interaction_const_t* ic)
+void init_interaction_const_tables(FILE* fp, interaction_const_t* ic, const real tableExtensionLength)
{
if (EEL_PME_EWALD(ic->eeltype))
{
- init_ewald_f_table(*ic, ic->coulombEwaldTables.get(), nullptr);
+ init_ewald_f_table(*ic, tableExtensionLength, ic->coulombEwaldTables.get(), nullptr);
if (fp != nullptr)
{
fprintf(fp, "Initialized non-bonded Coulomb Ewald tables, spacing: %.2e size: %zu\n\n",
/* 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);
+ init_interaction_const_tables(fp, fr->ic, ir->tabext);
const interaction_const_t* ic = fr->ic;
/*! \brief Initiate table constants
*
* 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] fp File for debugging output
+ * \param[in] ic Structure holding the table constant
+ * \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);
+void init_interaction_const_tables(FILE* fp, interaction_const_t* ic, const 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);
+ init_interaction_const_tables(nullptr, &ic, 0);
}
return ic;