14 const double *parameter14,
const int *type,
15 double *forceNonbond,
double *forceSlow,
16 const int &ljTableDim,
const int &nAtoms) {
18 ljPmeCoord = pmeCoord;
19 ljParameter = parameter;
20 ljParameter14 = parameter14;
22 ljForceNonbond = forceNonbond;
23 ljForceSlow = forceSlow;
24 tableDim = ljTableDim;
30 NAMD_die(
"LjPmeCompute has already been initialized!");
35 const double &cutoff,
const Lattice &lattice,
36 double virialNonbonded[][3],
double virialSlow[][3],
37 double &energyNonbond,
double &energySlow,
38 bool doEnergy,
bool doSlow) {
40 NAMD_die(
"LjPmeCompute has been called without initialization!");
43 energySlow = energyNonbond = 0.0;
44 for(
int i = 0; i < 3; ++i) {
45 for(
int j = 0; j < 3; ++j) {
46 virialNonbonded[i][j] = 0.0;
47 virialSlow[i][j] = 0.0;
55 this->computeNonbonded<true, true>(alphaLJ, cutoff,
56 lattice, virialNonbonded, virialSlow, energyNonbond, energySlow);
59 this->computeNonbonded<true, false>(alphaLJ, cutoff,
60 lattice, virialNonbonded, virialSlow, energyNonbond, energySlow);
64 ljForceSlow, energySlow, virialSlow, doEnergy);
67 this->computeNonbonded<false, true>(alphaLJ, cutoff,
68 lattice, virialNonbonded, virialSlow, energyNonbond, energySlow);
70 this->computeNonbonded<false, false>(alphaLJ, cutoff,
71 lattice, virialNonbonded, virialSlow, energyNonbond, energySlow);
76 template <
bool doSlow,
bool doEnergy>
78 const double &cutoff,
const Lattice &lattice,
79 double virialNonbonded[][3],
double virialSlow[][3],
80 double &energyNonbond,
double &energySlow) {
82 double dispersion = 0.0;
double repulsion = 0.0;
83 double nonBondEnergy = 0.0;
84 double slowEnergy = 0.0;
86 double rcut2 = cutoff * cutoff;
87 double rcut2inv = 1.0 / rcut2;
88 double rcut6inv = rcut2inv * rcut2inv * rcut2inv;
89 double rcut12inv = rcut6inv * rcut6inv;
90 double aRc = alphaLJ * cutoff;
91 double aRc2 = aRc * aRc;
94 double screen_rc = (1.0 - (1 + aRc2 + 0.5*aRc2*aRc2)*exp(-aRc2));
95 Vector iCoord, jCoord, distance;
96 for(
int i = 0; i < numAtoms; ++i) {
97 for(
int j = i+1; j < numAtoms; ++j) {
98 iCoord =
Vector(ljPmeCoord[4*i], ljPmeCoord[4*i+1], ljPmeCoord[4*i+2]);
99 jCoord =
Vector(ljPmeCoord[4*j], ljPmeCoord[4*j+1], ljPmeCoord[4*j+2]);
101 distance = lattice.
delta(iCoord, jCoord);
108 #ifdef MEM_OPT_VERSION 110 exclusion = molecule->checkExclByIdx(i, i, j);
119 double r2inv = 1.0/r2;
120 double r6inv = r2inv * r2inv * r2inv;
121 double r12inv = r6inv * r6inv;
122 double aR2 = r2 * alphaLJ * alphaLJ;
123 double aR4 = aR2 * aR2;
125 double c6 = ljPmeCoord[4*i+3] * ljPmeCoord[4*j+3];
127 double screen_dr = (1.0 - (1.0 + aR2 + 0.5*aR4 + aR4*aR2/6.0)*exp(-aR2));
130 double slowForce = 6.0 * c6 * screen_dr * r6inv * r2inv;
134 double screen_r = (1.0 - (1.0 + aR2 + 0.5*aR4)*exp(-aR2));
137 slowEnergy += c6 * screen_r * r6inv;
141 Vector force_r = slowForce * distance;
142 ljForceSlow[3*i] += force_r.
x;
143 ljForceSlow[3*i+1] += force_r.
y;
144 ljForceSlow[3*i+2] += force_r.
z;
145 ljForceSlow[3*j] -= force_r.
x;
146 ljForceSlow[3*j+1] -= force_r.
y;
147 ljForceSlow[3*j+2] -= force_r.
z;
149 virialSlow[0][0] += force_r.
x * distance.x;
150 virialSlow[0][1] += force_r.
x * distance.y;
151 virialSlow[0][2] += force_r.
x * distance.z;
152 virialSlow[1][0] += force_r.
y * distance.x;
153 virialSlow[1][1] += force_r.
y * distance.y;
154 virialSlow[1][2] += force_r.
y * distance.z;
155 virialSlow[2][0] += force_r.
z * distance.x;
156 virialSlow[2][1] += force_r.
z * distance.y;
157 virialSlow[2][2] += force_r.
z * distance.z;
161 int iType = atomType[i];
162 int jType = atomType[j];
163 int typeIndex = 2*(iType * tableDim + jType);
164 double r2inv = 1.0/r2;
165 double r6inv = r2inv * r2inv * r2inv;
166 double r12inv = r6inv * r6inv;
167 if (exclusion == 2) {
168 repulsion = ljParameter14[typeIndex];
169 dispersion = ljParameter14[typeIndex + 1];
171 repulsion = ljParameter[typeIndex];
172 dispersion = ljParameter[typeIndex + 1];
177 nonBondEnergy += (repulsion*r12inv - dispersion*r6inv);
180 double nonBondForce = (12.0*repulsion*r12inv - 6.0*dispersion*r6inv)*r2inv;
184 double aR2 = r2 * alphaLJ * alphaLJ;
185 double aR4 = aR2 * aR2;
187 double c6 = ljPmeCoord[4*i+3] * ljPmeCoord[4*j+3];
189 double screen_dr = (1.0 - (1.0 + aR2 + 0.5*aR4 + aR4*aR2/6.0)*exp(-aR2));
191 nonBondForce += 6.0 * c6 * screen_dr * r6inv * r2inv;
195 double screen_r = (1.0 - (1.0 + aR2 + 0.5*aR4)*exp(-aR2));
197 nonBondEnergy += c6 * screen_r * r6inv;
200 double potentialShift = (repulsion*rcut12inv - dispersion*rcut6inv);
202 potentialShift += c6 * screen_rc * rcut6inv;
204 nonBondEnergy -= potentialShift;
209 Vector force_r = nonBondForce * distance;
210 ljForceNonbond[3*i] += force_r.
x;
211 ljForceNonbond[3*i+1] += force_r.
y;
212 ljForceNonbond[3*i+2] += force_r.
z;
213 ljForceNonbond[3*j] -= force_r.
x;
214 ljForceNonbond[3*j+1] -= force_r.
y;
215 ljForceNonbond[3*j+2] -= force_r.
z;
218 virialNonbonded[0][0] += force_r.
x * distance.x;
219 virialNonbonded[0][1] += force_r.
x * distance.y;
220 virialNonbonded[0][2] += force_r.
x * distance.z;
221 virialNonbonded[1][0] += force_r.
y * distance.x;
222 virialNonbonded[1][1] += force_r.
y * distance.y;
223 virialNonbonded[1][2] += force_r.
y * distance.z;
224 virialNonbonded[2][0] += force_r.
z * distance.x;
225 virialNonbonded[2][1] += force_r.
z * distance.y;
226 virialNonbonded[2][2] += force_r.
z * distance.z;
232 energyNonbond += nonBondEnergy;
233 energySlow += slowEnergy;
void computeLongRange(const double *ljPmeCoord, const Lattice &lattice, const double &alphaLJ, double *force, double &energy, double virial[][3], bool doEnergy)
void computeLJpotential(const double &alphaLJ, const double &cutoff, const Lattice &lattice, double virialNonbonded[][3], double virialSlow[][3], double &energyNonbond, double &energySlow, bool doEnergy, bool doSlow)
int checkexcl(int atom1, int atom2) const
void computeNonbonded(const double &alphaLJ, const double &cutoff, const Lattice &lattice, double virialNonbonded[][3], double virialSlow[][3], double &energyNonbond, double &energySlow)
SimParameters * simParameters
void initialize(const SimParameters *simParams, const int nAtoms)
Molecule stores the structural information for the system.
NAMD_HOST_DEVICE BigReal length2(void) const
void NAMD_die(const char *err_msg)
void initialize(const double *pmeCoord, const double *parameter, const double *parameter14, const int *type, double *forceNonbond, double *forceSlow, const int &ljTableDim, const int &nAtoms)
NAMD_HOST_DEVICE Vector delta(const Position &pos1, const Position &pos2) const