if (dd->reverse_top->bExclRequired)
{
dd->nbonded_local += nexcl;
-
- forcerec_set_excl_load(fr, ltop);
}
ltop->atomtypes = mtop->atomtypes;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/mdtypes/forcerec.h"
#include "gromacs/mdtypes/md_enums.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/gmxassert.h"
/* There's nothing special to do here if just masses are perturbed,
* but if either charge or type is perturbed then the implementation
* perturbations. The parameter vectors for LJ-PME are likewise
* undefined when LJ-PME is not active. This works because
* bHaveChargeOrTypePerturbed handles the control flow. */
-void ewald_LRcorrection(int start, int end,
- t_commrec *cr, int thread, t_forcerec *fr,
+void ewald_LRcorrection(int numAtomsLocal,
+ t_commrec *cr,
+ int numThreads, int thread,
+ t_forcerec *fr,
real *chargeA, real *chargeB,
real *C6A, real *C6B,
real *sigmaA, real *sigmaB,
real lambda_q, real lambda_lj,
real *dvdlambda_q, real *dvdlambda_lj)
{
+ int numAtomsToBeCorrected;
+ if (calc_excl_corr)
+ {
+ /* We need to correct all exclusion pairs (cutoff-scheme = group) */
+ numAtomsToBeCorrected = excl->nr;
+
+ GMX_RELEASE_ASSERT(numAtomsToBeCorrected >= numAtomsLocal, "We might need to do self-corrections");
+ }
+ else
+ {
+ /* We need to correct only self interactions */
+ numAtomsToBeCorrected = numAtomsLocal;
+ }
+ int start = (numAtomsToBeCorrected* thread )/numThreads;
+ int end = (numAtomsToBeCorrected*(thread + 1))/numThreads;
+
int i, i1, i2, j, k, m, iv, jv, q;
int *AA;
double Vexcl_q, dvdl_excl_q, dvdl_excl_lj; /* Necessary for precision */
}
}
/* Dipole correction on force */
- if (dipole_coeff != 0)
+ if (dipole_coeff != 0 && i < numAtomsLocal)
{
for (j = 0; (j < DIM); j++)
{
}
}
/* Dipole correction on force */
- if (dipole_coeff != 0)
+ if (dipole_coeff != 0 && i < numAtomsLocal)
{
for (j = 0; (j < DIM); j++)
{
if (debug)
{
fprintf(debug, "Long Range corrections for Ewald interactions:\n");
- fprintf(debug, "start=%d,natoms=%d\n", start, end-start);
fprintf(debug, "q2sum = %g, Vself_q=%g c6sum = %g, Vself_lj=%g\n",
L1_q*fr->q2sum[0]+lambda_q*fr->q2sum[1], L1_q*Vself_q[0]+lambda_q*Vself_q[1], L1_lj*fr->c6sum[0]+lambda_lj*fr->c6sum[1], L1_lj*Vself_lj[0]+lambda_lj*Vself_lj[1]);
fprintf(debug, "Electrostatic Long Range correction: Vexcl=%g\n", Vexcl_q);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* For both cutoff schemes, but only for Coulomb interactions,
* calculates correction for surface dipole terms. */
void
-ewald_LRcorrection(int start, int end,
- t_commrec *cr, int thread, t_forcerec *fr,
+ewald_LRcorrection(int numAtomsLocal,
+ t_commrec *cr,
+ int numThreads, int thread,
+ t_forcerec *fr,
real *chargeA, real *chargeB,
real *C6A, real *C6B,
real *sigmaA, real *sigmaB,
* exclusion forces) are calculated, so we can store
* the forces in the normal, single fr->f_novirsum array.
*/
- ewald_LRcorrection(fr->excl_load[t], fr->excl_load[t+1],
- cr, t, fr,
+ ewald_LRcorrection(md->homenr, cr, nthreads, t, fr,
md->chargeA, md->chargeB,
md->sqrt_c6A, md->sqrt_c6B,
md->sigmaA, md->sigmaB,
fr->nthread_ewc = gmx_omp_nthreads_get(emntBonded);
snew(fr->ewc_t, fr->nthread_ewc);
- snew(fr->excl_load, fr->nthread_ewc + 1);
/* fr->ic is used both by verlet and group kernels (to some extent) now */
init_interaction_const(fp, &fr->ic, fr);
fflush(fp);
}
-void forcerec_set_excl_load(t_forcerec *fr,
- const gmx_localtop_t *top)
-{
- const int *ind, *a;
- int t, i, j, ntot, n, ntarget;
-
- ind = top->excls.index;
- a = top->excls.a;
-
- ntot = 0;
- for (i = 0; i < top->excls.nr; i++)
- {
- for (j = ind[i]; j < ind[i+1]; j++)
- {
- if (a[j] > i)
- {
- ntot++;
- }
- }
- }
-
- fr->excl_load[0] = 0;
- n = 0;
- i = 0;
- for (t = 1; t <= fr->nthread_ewc; t++)
- {
- ntarget = (ntot*t)/fr->nthread_ewc;
- while (i < top->excls.nr && n < ntarget)
- {
- for (j = ind[i]; j < ind[i+1]; j++)
- {
- if (a[j] > i)
- {
- n++;
- }
- }
- i++;
- }
- fr->excl_load[t] = i;
- }
-}
-
/* Frees GPU memory and destroys the GPU context.
*
* Note that this function needs to be called even if GPUs are not used
*top = gmx_mtop_generate_local_top(top_global, ir->efep != efepNO);
- forcerec_set_excl_load(fr, *top);
-
setup_bonded_threading(fr, &(*top)->idef);
if (ir->ePBC != epbcNONE && !fr->bMolPBC)
};
-static void do_update_md(int start, int nrend, double dt,
+static void do_update_md(int start, int nrend,
+ double dt, int nstpcouple,
t_grp_tcstat *tcstat,
double nh_vxi[],
gmx_bool bNEMD, t_grp_acc *gstat, rvec accel[],
if ((ptype[n] != eptVSite) && (ptype[n] != eptShell) && !nFreeze[gf][d])
{
vnrel = (lg*vrel[d] + dt*(imass*f[n][d] - 0.5*vxi*vrel[d]
- - iprod(M[d], vrel)))/(1 + 0.5*vxi*dt);
+ - nstpcouple*iprod(M[d], vrel)))/(1 + 0.5*vxi*dt);
/* do not scale the mean velocities u */
vn = gstat[ga].u[d] + accel[ga][d]*dt + vnrel;
v[n][d] = vn;
}
} /* do_update_vv_pos */
-static void do_update_visc(int start, int nrend, double dt,
+static void do_update_visc(int start, int nrend,
+ double dt, int nstpcouple,
t_grp_tcstat *tcstat,
double nh_vxi[],
real invmass[],
if ((ptype[n] != eptVSite) && (ptype[n] != eptShell))
{
vn = (lg*vrel[d] + dt*(imass*f[n][d] - 0.5*vxi*vrel[d]
- - iprod(M[d], vrel)))/(1 + 0.5*vxi*dt);
+ - nstpcouple*iprod(M[d], vrel)))/(1 + 0.5*vxi*dt);
if (d == XX)
{
vn += vc + dt*cosz*cos_accel;
case (eiMD):
if (ekind->cosacc.cos_accel == 0)
{
- do_update_md(start_th, end_th, dt,
+ do_update_md(start_th, end_th,
+ dt, inputrec->nstpcouple,
ekind->tcstat, state->nosehoover_vxi,
ekind->bNEMD, ekind->grpstat, inputrec->opts.acc,
inputrec->opts.nFreeze,
}
else
{
- do_update_visc(start_th, end_th, dt,
+ do_update_visc(start_th, end_th,
+ dt, inputrec->nstpcouple,
ekind->tcstat, state->nosehoover_vxi,
md->invmass, md->ptype,
md->cTC, state->x, upd->xp, state->v, f, M,
/* Ewald correction thread local virial and energy data */
int nthread_ewc;
ewald_corr_thread_t *ewc_t;
- /* Ewald charge correction load distribution over the threads */
- int *excl_load;
} t_forcerec;
/* Important: Starting with Gromacs-4.6, the values of c6 and c12 in the nbfp array have
{
top = gmx_mtop_generate_local_top(top_global, ir->efep != efepNO);
- forcerec_set_excl_load(fr, top);
-
state = serial_init_local_state(state_global);
atoms2md(top_global, ir, 0, NULL, top_global->natoms, mdatoms);