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!");
44 energySlow = energyNonbond = 0.0;
45 for(
int i = 0; i < 3; ++i) {
46 for(
int j = 0; j < 3; ++j) {
47 virialNonbonded[i][j] = 0.0;
48 virialSlow[i][j] = 0.0;
57 this->computeNonbonded<true, true>(alphaLJ, cutoff,
58 lattice, virialNonbonded, virialSlow, energyNonbond, energySlow);
63 this->computeNonbonded<true, false>(alphaLJ, cutoff,
64 lattice, virialNonbonded, virialSlow, energyNonbond, energySlow);
69 ljForceSlow, energySlow, virialSlow, doEnergy);
72 this->computeNonbonded<false, true>(alphaLJ, cutoff,
73 lattice, virialNonbonded, virialSlow, energyNonbond, energySlow);
75 this->computeNonbonded<false, false>(alphaLJ, cutoff,
76 lattice, virialNonbonded, virialSlow, energyNonbond, energySlow);
81 template <
bool doSlow,
bool doEnergy>
83 const double &cutoff,
const Lattice &lattice,
84 double virialNonbonded[][3],
double virialSlow[][3],
85 double &energyNonbond,
double &energySlow) {
87 double dispersion = 0.0;
double repulsion = 0.0;
88 double nonBondEnergy = 0.0;
89 double slowEnergy = 0.0;
91 double rcut2 = cutoff * cutoff;
92 double rcut2inv = 1.0 / rcut2;
93 double rcut6inv = rcut2inv * rcut2inv * rcut2inv;
94 double rcut12inv = rcut6inv * rcut6inv;
95 double aRc = alphaLJ * cutoff;
96 double aRc2 = aRc * aRc;
99 double screen_rc = (1.0 - (1 + aRc2 + 0.5*aRc2*aRc2)*exp(-aRc2));
100 Vector iCoord, jCoord, distance;
101 for(
int i = 0; i < numAtoms; ++i) {
102 for(
int j = i+1; j < numAtoms; ++j) {
104 iCoord =
Vector(ljPmeCoord[4*i], ljPmeCoord[4*i+1], ljPmeCoord[4*i+2]);
105 jCoord =
Vector(ljPmeCoord[4*j], ljPmeCoord[4*j+1], ljPmeCoord[4*j+2]);
107 distance = lattice.
delta(iCoord, jCoord);
114 #ifdef MEM_OPT_VERSION 116 exclusion = molecule->checkExclByIdx(i, i, j);
125 double r2inv = 1.0/r2;
126 double r6inv = r2inv * r2inv * r2inv;
127 double r12inv = r6inv * r6inv;
128 double aR2 = r2 * alphaLJ * alphaLJ;
129 double aR4 = aR2 * aR2;
131 double c6 = ljPmeCoord[4*i+3] * ljPmeCoord[4*j+3];
133 double screen_dr = (1.0 - (1.0 + aR2 + 0.5*aR4 + aR4*aR2/6.0)*exp(-aR2));
136 double slowForce = 6.0 * c6 * screen_dr * r6inv * r2inv;
140 double screen_r = (1.0 - (1.0 + aR2 + 0.5*aR4)*exp(-aR2));
143 energy1 += c6 * screen_r * r6inv;
144 slowEnergy += energy1;
148 Vector force_r = slowForce * distance;
149 ljForceSlow[3*i] += force_r.
x;
150 ljForceSlow[3*i+1] += force_r.
y;
151 ljForceSlow[3*i+2] += force_r.
z;
152 ljForceSlow[3*j] -= force_r.
x;
153 ljForceSlow[3*j+1] -= force_r.
y;
154 ljForceSlow[3*j+2] -= force_r.
z;
156 virialSlow[0][0] += force_r.
x * distance.x;
157 virialSlow[0][1] += force_r.
x * distance.y;
158 virialSlow[0][2] += force_r.
x * distance.z;
159 virialSlow[1][0] += force_r.
y * distance.x;
160 virialSlow[1][1] += force_r.
y * distance.y;
161 virialSlow[1][2] += force_r.
y * distance.z;
162 virialSlow[2][0] += force_r.
z * distance.x;
163 virialSlow[2][1] += force_r.
z * distance.y;
164 virialSlow[2][2] += force_r.
z * distance.z;
168 int iType = atomType[i];
169 int jType = atomType[j];
170 int typeIndex = 2*(iType * tableDim + jType);
171 double r2inv = 1.0/r2;
172 double r6inv = r2inv * r2inv * r2inv;
173 double r12inv = r6inv * r6inv;
174 if (exclusion == 2) {
175 repulsion = ljParameter14[typeIndex];
176 dispersion = ljParameter14[typeIndex + 1];
178 repulsion = ljParameter[typeIndex];
179 dispersion = ljParameter[typeIndex + 1];
184 energy1 += (repulsion*r12inv - dispersion*r6inv);
185 nonBondEnergy += energy1;
188 double nonBondForce = (12.0*repulsion*r12inv - 6.0*dispersion*r6inv)*r2inv;
192 double aR2 = r2 * alphaLJ * alphaLJ;
193 double aR4 = aR2 * aR2;
195 double c6 = ljPmeCoord[4*i+3] * ljPmeCoord[4*j+3];
197 double screen_dr = (1.0 - (1.0 + aR2 + 0.5*aR4 + aR4*aR2/6.0)*exp(-aR2));
199 nonBondForce += 6.0 * c6 * screen_dr * r6inv * r2inv;
203 double screen_r = (1.0 - (1.0 + aR2 + 0.5*aR4)*exp(-aR2));
205 double energySlow1 = c6 * screen_r * r6inv;
208 double potentialShift = (repulsion*rcut12inv - dispersion*rcut6inv);
210 potentialShift += c6 * screen_rc * rcut6inv;
212 energySlow1 -= potentialShift;
213 energy1 += energySlow1;
214 nonBondEnergy += energySlow1;
219 Vector force_r = nonBondForce * distance;
220 ljForceNonbond[3*i] += force_r.
x;
221 ljForceNonbond[3*i+1] += force_r.
y;
222 ljForceNonbond[3*i+2] += force_r.
z;
223 ljForceNonbond[3*j] -= force_r.
x;
224 ljForceNonbond[3*j+1] -= force_r.
y;
225 ljForceNonbond[3*j+2] -= force_r.
z;
228 virialNonbonded[0][0] += force_r.
x * distance.x;
229 virialNonbonded[0][1] += force_r.
x * distance.y;
230 virialNonbonded[0][2] += force_r.
x * distance.z;
231 virialNonbonded[1][0] += force_r.
y * distance.x;
232 virialNonbonded[1][1] += force_r.
y * distance.y;
233 virialNonbonded[1][2] += force_r.
y * distance.z;
234 virialNonbonded[2][0] += force_r.
z * distance.x;
235 virialNonbonded[2][1] += force_r.
z * distance.y;
236 virialNonbonded[2][2] += force_r.
z * distance.z;
242 energyNonbond += nonBondEnergy;
243 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