kCalculateAmoebaCudaKirkwoodEDiff.cu 49.6 KB
Newer Older
Mark Friedrichs's avatar
Mark Friedrichs committed
1
2
3
4
5
6
7
//-----------------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------------

#include "amoebaGpuTypes.h"
#include "amoebaCudaKernels.h"
#include "kCalculateAmoebaCudaUtilities.h"
8
9
//#include "kCalculateAmoebaCudaKirkwoodParticle.h"
#include "kCalculateAmoebaCudaKirkwoodEDiffParticle.h"
Mark Friedrichs's avatar
Mark Friedrichs committed
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

//#define AMOEBA_DEBUG

static __constant__ cudaGmxSimulation cSim;
static __constant__ cudaAmoebaGmxSimulation cAmoebaSim;

void SetCalculateAmoebaKirkwoodEDiffSim(amoebaGpuContext amoebaGpu)
{
    cudaError_t status;
    gpuContext gpu = amoebaGpu->gpuContext;
    status         = cudaMemcpyToSymbol(cSim, &gpu->sim, sizeof(cudaGmxSimulation));    
    RTERROR(status, "SetCalculateAmoebaKirkwoodEDiffSim: cudaMemcpyToSymbol: SetSim copy to cSim failed");
    status         = cudaMemcpyToSymbol(cAmoebaSim, &amoebaGpu->amoebaSim, sizeof(cudaAmoebaGmxSimulation));    
    RTERROR(status, "SetCalculateAmoebaKirkwoodEDiffSim: cudaMemcpyToSymbol: SetSim copy to cAmoebaSim failed");
}

void GetCalculateAmoebaKirkwoodEDiffSim(amoebaGpuContext amoebaGpu)
{
    cudaError_t status;
    gpuContext gpu = amoebaGpu->gpuContext;
    status = cudaMemcpyFromSymbol(&gpu->sim, cSim, sizeof(cudaGmxSimulation));    
    RTERROR(status, "GetCalculateAmoebaKirkwoodEDiffSim: cudaMemcpyFromSymbol: SetSim copy from cSim failed");
    status = cudaMemcpyFromSymbol(&amoebaGpu->amoebaSim, cAmoebaSim, sizeof(cudaAmoebaGmxSimulation));    
    RTERROR(status, "GetCalculateAmoebaKirkwoodEDiffSim: cudaMemcpyFromSymbol: SetSim copy from cAmoebaSim failed");
}

36
__device__ void loadKirkwoodEDiffShared( struct KirkwoodEDiffParticle* sA, unsigned int atomI )
Mark Friedrichs's avatar
Mark Friedrichs committed
37
38
39
{
    // coordinates & charge

40
41
42
43
    sA->x                        = cSim.pPosq[atomI].x;
    sA->y                        = cSim.pPosq[atomI].y;
    sA->z                        = cSim.pPosq[atomI].z;
    sA->q                        = cSim.pPosq[atomI].w;
Mark Friedrichs's avatar
Mark Friedrichs committed
44
45
46
47
48
49

    sA->damp                     = cAmoebaSim.pDampingFactorAndThole[atomI].x;
    sA->thole                    = cAmoebaSim.pDampingFactorAndThole[atomI].y;

    // lab dipole

50
51
52
    sA->labFrameDipole[0]        = cAmoebaSim.pLabFrameDipole[atomI*3];
    sA->labFrameDipole[1]        = cAmoebaSim.pLabFrameDipole[atomI*3+1];
    sA->labFrameDipole[2]        = cAmoebaSim.pLabFrameDipole[atomI*3+2];
Mark Friedrichs's avatar
Mark Friedrichs committed
53
54
55

    // lab quadrupole

56
57
58
59
60
61
    sA->labFrameQuadrupole_XX    = cAmoebaSim.pLabFrameQuadrupole[atomI*9];
    sA->labFrameQuadrupole_XY    = cAmoebaSim.pLabFrameQuadrupole[atomI*9+1];
    sA->labFrameQuadrupole_XZ    = cAmoebaSim.pLabFrameQuadrupole[atomI*9+2];
    sA->labFrameQuadrupole_YY    = cAmoebaSim.pLabFrameQuadrupole[atomI*9+4];
    sA->labFrameQuadrupole_YZ    = cAmoebaSim.pLabFrameQuadrupole[atomI*9+5];
    sA->labFrameQuadrupole_ZZ    = cAmoebaSim.pLabFrameQuadrupole[atomI*9+8];
Mark Friedrichs's avatar
Mark Friedrichs committed
62
63
64

    // induced dipole

65
66
67
    sA->inducedDipole[0]         = cAmoebaSim.pInducedDipole[atomI*3];
    sA->inducedDipole[1]         = cAmoebaSim.pInducedDipole[atomI*3+1];
    sA->inducedDipole[2]         = cAmoebaSim.pInducedDipole[atomI*3+2];
Mark Friedrichs's avatar
Mark Friedrichs committed
68
69
70

    // induced dipole polar

71
72
73
    sA->inducedDipoleP[0]        = cAmoebaSim.pInducedDipolePolar[atomI*3];
    sA->inducedDipoleP[1]        = cAmoebaSim.pInducedDipolePolar[atomI*3+1];
    sA->inducedDipoleP[2]        = cAmoebaSim.pInducedDipolePolar[atomI*3+2];
Mark Friedrichs's avatar
Mark Friedrichs committed
74
75
76

    // induced dipole

77
78
79
    sA->inducedDipoleS[0]        = cAmoebaSim.pInducedDipoleS[atomI*3];
    sA->inducedDipoleS[1]        = cAmoebaSim.pInducedDipoleS[atomI*3+1];
    sA->inducedDipoleS[2]        = cAmoebaSim.pInducedDipoleS[atomI*3+2];
Mark Friedrichs's avatar
Mark Friedrichs committed
80
81
82

    // induced dipole polar

83
84
85
    sA->inducedDipolePS[0]       = cAmoebaSim.pInducedDipolePolarS[atomI*3];
    sA->inducedDipolePS[1]       = cAmoebaSim.pInducedDipolePolarS[atomI*3+1];
    sA->inducedDipolePS[2]       = cAmoebaSim.pInducedDipolePolarS[atomI*3+2];
Mark Friedrichs's avatar
Mark Friedrichs committed
86
87
88
89
90
91
92
93
94
95
96

}

/*****************************************************************************

       ediff1 correct vacuum to SCRF derivatives

       calculates the energy and derivatives of polarizing
       the vacuum induced dipoles to their SCRF polarized values

******************************************************************************/
97
98
#ifdef INCLUDE_TORQUE
__device__ void calculateKirkwoodEDiffPairIxnOrig_kernel( KirkwoodEDiffParticle& atomI,  KirkwoodEDiffParticle& atomJ,
Mark Friedrichs's avatar
Mark Friedrichs committed
99
100
                                                      float pscale,                  float dscale,
                                                      float*  outputEnergy,          float*  outputForce,
101
                                                      float*  outputTorqueI,         float* outputTorqueJ){
Mark Friedrichs's avatar
Mark Friedrichs committed
102
103
104
105
106
107
108
109
110
111
112
113

    //float f;
    //float gfd;
    float scale3,scale5;
    float scale7;
    //float scale9;
    float psc3,psc5,psc7;
    //float psc9;
    float dsc3,dsc5,dsc7;
    //float dsc9;
    float scale3i,scale5i;
    //float scale7i;
114
    float r,rr1,rr3;
Mark Friedrichs's avatar
Mark Friedrichs committed
115
    float rr5,rr7,rr9;
116
117
    float pgamma;
    const float uscale = 1.0f;
Mark Friedrichs's avatar
Mark Friedrichs committed
118
119
120
121
122
123
124

    // set conversion factor, cutoff and scaling coefficients

    //f           = cAmoebaSim.electric / cAmoebaSim.dwater;

    // deltaR

125
126
127
    float xr          = atomJ.x - atomI.x;
    float yr          = atomJ.y - atomI.y;
    float zr          = atomJ.z - atomI.z;
Mark Friedrichs's avatar
Mark Friedrichs committed
128

129
    float r2          = xr*xr + yr*yr + zr*zr;
Mark Friedrichs's avatar
Mark Friedrichs committed
130
131
132
133
134
135
136
137
138
139
140
141
142

    r           = sqrtf(r2);
    rr1         = 1.0f / r;
    rr3         = rr1 / r2;
    rr5         = 3.0f * rr3 / r2;
    rr7         = 5.0f * rr5 / r2;
    rr9         = 7.0f * rr7 / r2;

    scale3      = 1.0f;
    scale5      = 1.0f;
    scale7      = 1.0f;
    //scale9      = 1.0f;

Peter Eastman's avatar
Peter Eastman committed
143
144
145
    float ddsc3_1    = 0.0f;
    float ddsc3_2    = 0.0f;
    float ddsc3_3    = 0.0f;
Mark Friedrichs's avatar
Mark Friedrichs committed
146

Peter Eastman's avatar
Peter Eastman committed
147
148
149
    float ddsc5_1    = 0.0f;
    float ddsc5_2    = 0.0f;
    float ddsc5_3    = 0.0f;
Mark Friedrichs's avatar
Mark Friedrichs committed
150

Peter Eastman's avatar
Peter Eastman committed
151
152
153
    float ddsc7_1    = 0.0f;
    float ddsc7_2    = 0.0f;
    float ddsc7_3    = 0.0f;
Mark Friedrichs's avatar
Mark Friedrichs committed
154
155
156

    // apply Thole polarization damping to scale factors
 
157
    float damp = atomI.damp * atomJ.damp;
Mark Friedrichs's avatar
Mark Friedrichs committed
158
    if( damp != 0.0f ){
159
        pgamma          = atomJ.thole > atomI.thole ? atomI.thole : atomJ.thole;
Mark Friedrichs's avatar
Mark Friedrichs committed
160
161
162
163
164
165
166
167
168
169
        float ratio     = (r/damp);
        damp            = -pgamma * ratio*ratio*ratio;
        if( damp > -50.0f){
            float dampE  = expf( damp );
            float damp2  = damp*damp;
            scale3       = 1.0f - dampE;
            scale5       = 1.0f - (1.0f - damp)*dampE;
            scale7       = 1.0f - (1.0f - damp + 0.6f*damp2)*dampE;
            //scale9       = 1.0f - (1.0f - damp + (18.0f*damp2 - (9.0f*damp*damp2))/35.0f)*dampE;

Peter Eastman's avatar
Peter Eastman committed
170
171
172
            ddsc3_1     = -3.0f*damp*exp(damp) * xr/r2;
            ddsc3_2     = -3.0f*damp*exp(damp) * yr/r2;
            ddsc3_3     = -3.0f*damp*exp(damp) * zr/r2;
Mark Friedrichs's avatar
Mark Friedrichs committed
173

Peter Eastman's avatar
Peter Eastman committed
174
175
176
            ddsc5_1     = -damp * ddsc3_1;
            ddsc5_2     = -damp * ddsc3_2;
            ddsc5_3     = -damp * ddsc3_3;
Mark Friedrichs's avatar
Mark Friedrichs committed
177

Peter Eastman's avatar
Peter Eastman committed
178
179
180
            ddsc7_1     = (-0.2f-0.6f*damp) * ddsc5_1;
            ddsc7_2     = (-0.2f-0.6f*damp) * ddsc5_2;
            ddsc7_3     = (-0.2f-0.6f*damp) * ddsc5_3;
Mark Friedrichs's avatar
Mark Friedrichs committed
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
        }
    }

    scale3i             = scale3 * uscale;
    scale5i             = scale5 * uscale;
    //scale7i             = scale7 * uscale;

    dsc3                = scale3 * dscale;
    dsc5                = scale5 * dscale;
    dsc7                = scale7 * dscale;
    //dsc9                = scale9 * dscale;

    psc3                = scale3 * pscale;
    psc5                = scale5 * pscale;
    psc7                = scale7 * pscale;
    //psc9                = scale9 * pscale;
 
    // construct auxiliary vectors for permanent terms
 
Peter Eastman's avatar
Peter Eastman committed
200
201
202
    float dixr1             = atomI.labFrameDipole[1]*zr - atomI.labFrameDipole[2]*yr;
    float dixr2             = atomI.labFrameDipole[2]*xr - atomI.labFrameDipole[0]*zr;
    float dixr3             = atomI.labFrameDipole[0]*yr - atomI.labFrameDipole[1]*xr;
Mark Friedrichs's avatar
Mark Friedrichs committed
203

Peter Eastman's avatar
Peter Eastman committed
204
205
206
    float dkxr1             = atomJ.labFrameDipole[1]*zr - atomJ.labFrameDipole[2]*yr;
    float dkxr2             = atomJ.labFrameDipole[2]*xr - atomJ.labFrameDipole[0]*zr;
    float dkxr3             = atomJ.labFrameDipole[0]*yr - atomJ.labFrameDipole[1]*xr;
Mark Friedrichs's avatar
Mark Friedrichs committed
207

Peter Eastman's avatar
Peter Eastman committed
208
209
210
    float qir1              = atomI.labFrameQuadrupole_XX*xr + atomI.labFrameQuadrupole_XY*yr + atomI.labFrameQuadrupole_XZ*zr;
    float qir2              = atomI.labFrameQuadrupole_XY*xr + atomI.labFrameQuadrupole_YY*yr + atomI.labFrameQuadrupole_YZ*zr;
    float qir3              = atomI.labFrameQuadrupole_XZ*xr + atomI.labFrameQuadrupole_YZ*yr + atomI.labFrameQuadrupole_ZZ*zr;
Mark Friedrichs's avatar
Mark Friedrichs committed
211

Peter Eastman's avatar
Peter Eastman committed
212
213
214
    float qkr1              = atomJ.labFrameQuadrupole_XX*xr + atomJ.labFrameQuadrupole_XY*yr + atomJ.labFrameQuadrupole_XZ*zr;
    float qkr2              = atomJ.labFrameQuadrupole_XY*xr + atomJ.labFrameQuadrupole_YY*yr + atomJ.labFrameQuadrupole_YZ*zr;
    float qkr3              = atomJ.labFrameQuadrupole_XZ*xr + atomJ.labFrameQuadrupole_YZ*yr + atomJ.labFrameQuadrupole_ZZ*zr;
Mark Friedrichs's avatar
Mark Friedrichs committed
215

Peter Eastman's avatar
Peter Eastman committed
216
217
218
    float rxqir1            = yr*qir3 - zr*qir2;
    float rxqir2            = zr*qir1 - xr*qir3;
    float rxqir3            = xr*qir2 - yr*qir1;
Mark Friedrichs's avatar
Mark Friedrichs committed
219

Peter Eastman's avatar
Peter Eastman committed
220
221
222
    float rxqkr1            = yr*qkr3 - zr*qkr2;
    float rxqkr2            = zr*qkr1 - xr*qkr3;
    float rxqkr3            = xr*qkr2 - yr*qkr1;
Mark Friedrichs's avatar
Mark Friedrichs committed
223
224
225

    // get intermediate variables for permanent energy terms
 
Peter Eastman's avatar
Peter Eastman committed
226
227
228
229
    float sc3               = atomI.labFrameDipole[0]*xr  + atomI.labFrameDipole[1]*yr  + atomI.labFrameDipole[2]*zr;
    float sc4               = atomJ.labFrameDipole[0]*xr  + atomJ.labFrameDipole[1]*yr  + atomJ.labFrameDipole[2]*zr;
    float sc5               = qir1*xr + qir2*yr + qir3*zr;
    float sc6               = qkr1*xr + qkr2*yr + qkr3*zr;
Mark Friedrichs's avatar
Mark Friedrichs committed
230
231
232
 
    // construct auxiliary vectors for induced terms
 
Peter Eastman's avatar
Peter Eastman committed
233
234
235
    float dixuk1            = atomI.labFrameDipole[1]*atomJ.inducedDipoleS[2] - atomI.labFrameDipole[2]*atomJ.inducedDipoleS[1];
    float dixuk2            = atomI.labFrameDipole[2]*atomJ.inducedDipoleS[0] - atomI.labFrameDipole[0]*atomJ.inducedDipoleS[2];
    float dixuk3            = atomI.labFrameDipole[0]*atomJ.inducedDipoleS[1] - atomI.labFrameDipole[1]*atomJ.inducedDipoleS[0];
Mark Friedrichs's avatar
Mark Friedrichs committed
236

Peter Eastman's avatar
Peter Eastman committed
237
238
239
    float dkxui1            = atomJ.labFrameDipole[1]*atomI.inducedDipoleS[2] - atomJ.labFrameDipole[2]*atomI.inducedDipoleS[1];
    float dkxui2            = atomJ.labFrameDipole[2]*atomI.inducedDipoleS[0] - atomJ.labFrameDipole[0]*atomI.inducedDipoleS[2];
    float dkxui3            = atomJ.labFrameDipole[0]*atomI.inducedDipoleS[1] - atomJ.labFrameDipole[1]*atomI.inducedDipoleS[0];
Mark Friedrichs's avatar
Mark Friedrichs committed
240

Peter Eastman's avatar
Peter Eastman committed
241
242
243
    float dixukp1           = atomI.labFrameDipole[1]*atomJ.inducedDipolePS[2] - atomI.labFrameDipole[2]*atomJ.inducedDipolePS[1];
    float dixukp2           = atomI.labFrameDipole[2]*atomJ.inducedDipolePS[0] - atomI.labFrameDipole[0]*atomJ.inducedDipolePS[2];
    float dixukp3           = atomI.labFrameDipole[0]*atomJ.inducedDipolePS[1] - atomI.labFrameDipole[1]*atomJ.inducedDipolePS[0];
Mark Friedrichs's avatar
Mark Friedrichs committed
244

Peter Eastman's avatar
Peter Eastman committed
245
246
247
    float dkxuip1           = atomJ.labFrameDipole[1]*atomI.inducedDipolePS[2] - atomJ.labFrameDipole[2]*atomI.inducedDipolePS[1];
    float dkxuip2           = atomJ.labFrameDipole[2]*atomI.inducedDipolePS[0] - atomJ.labFrameDipole[0]*atomI.inducedDipolePS[2];
    float dkxuip3           = atomJ.labFrameDipole[0]*atomI.inducedDipolePS[1] - atomJ.labFrameDipole[1]*atomI.inducedDipolePS[0];
Mark Friedrichs's avatar
Mark Friedrichs committed
248

Peter Eastman's avatar
Peter Eastman committed
249
250
251
    float qiuk1             = atomI.labFrameQuadrupole_XX*atomJ.inducedDipoleS[0] + atomI.labFrameQuadrupole_XY*atomJ.inducedDipoleS[1] + atomI.labFrameQuadrupole_XZ*atomJ.inducedDipoleS[2];
    float qiuk2             = atomI.labFrameQuadrupole_XY*atomJ.inducedDipoleS[0] + atomI.labFrameQuadrupole_YY*atomJ.inducedDipoleS[1] + atomI.labFrameQuadrupole_YZ*atomJ.inducedDipoleS[2];
    float qiuk3             = atomI.labFrameQuadrupole_XZ*atomJ.inducedDipoleS[0] + atomI.labFrameQuadrupole_YZ*atomJ.inducedDipoleS[1] + atomI.labFrameQuadrupole_ZZ*atomJ.inducedDipoleS[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
252

Peter Eastman's avatar
Peter Eastman committed
253
254
255
    float qkui1             = atomJ.labFrameQuadrupole_XX*atomI.inducedDipoleS[0] + atomJ.labFrameQuadrupole_XY*atomI.inducedDipoleS[1] + atomJ.labFrameQuadrupole_XZ*atomI.inducedDipoleS[2];
    float qkui2             = atomJ.labFrameQuadrupole_XY*atomI.inducedDipoleS[0] + atomJ.labFrameQuadrupole_YY*atomI.inducedDipoleS[1] + atomJ.labFrameQuadrupole_YZ*atomI.inducedDipoleS[2];
    float qkui3             = atomJ.labFrameQuadrupole_XZ*atomI.inducedDipoleS[0] + atomJ.labFrameQuadrupole_YZ*atomI.inducedDipoleS[1] + atomJ.labFrameQuadrupole_ZZ*atomI.inducedDipoleS[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
256

Peter Eastman's avatar
Peter Eastman committed
257
258
259
    float qiukp1            = atomI.labFrameQuadrupole_XX*atomJ.inducedDipolePS[0] + atomI.labFrameQuadrupole_XY*atomJ.inducedDipolePS[1] + atomI.labFrameQuadrupole_XZ*atomJ.inducedDipolePS[2];
    float qiukp2            = atomI.labFrameQuadrupole_XY*atomJ.inducedDipolePS[0] + atomI.labFrameQuadrupole_YY*atomJ.inducedDipolePS[1] + atomI.labFrameQuadrupole_YZ*atomJ.inducedDipolePS[2];
    float qiukp3            = atomI.labFrameQuadrupole_XZ*atomJ.inducedDipolePS[0] + atomI.labFrameQuadrupole_YZ*atomJ.inducedDipolePS[1] + atomI.labFrameQuadrupole_ZZ*atomJ.inducedDipolePS[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
260

Peter Eastman's avatar
Peter Eastman committed
261
262
263
    float qkuip1            = atomJ.labFrameQuadrupole_XX*atomI.inducedDipolePS[0] + atomJ.labFrameQuadrupole_XY*atomI.inducedDipolePS[1] + atomJ.labFrameQuadrupole_XZ*atomI.inducedDipolePS[2];
    float qkuip2            = atomJ.labFrameQuadrupole_XY*atomI.inducedDipolePS[0] + atomJ.labFrameQuadrupole_YY*atomI.inducedDipolePS[1] + atomJ.labFrameQuadrupole_YZ*atomI.inducedDipolePS[2];
    float qkuip3            = atomJ.labFrameQuadrupole_XZ*atomI.inducedDipolePS[0] + atomJ.labFrameQuadrupole_YZ*atomI.inducedDipolePS[1] + atomJ.labFrameQuadrupole_ZZ*atomI.inducedDipolePS[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
264

Peter Eastman's avatar
Peter Eastman committed
265
266
267
    float uixqkr1           = atomI.inducedDipoleS[1]*qkr3 - atomI.inducedDipoleS[2]*qkr2;
    float uixqkr2           = atomI.inducedDipoleS[2]*qkr1 - atomI.inducedDipoleS[0]*qkr3;
    float uixqkr3           = atomI.inducedDipoleS[0]*qkr2 - atomI.inducedDipoleS[1]*qkr1;
Mark Friedrichs's avatar
Mark Friedrichs committed
268

Peter Eastman's avatar
Peter Eastman committed
269
270
271
    float ukxqir1           = atomJ.inducedDipoleS[1]*qir3 - atomJ.inducedDipoleS[2]*qir2;
    float ukxqir2           = atomJ.inducedDipoleS[2]*qir1 - atomJ.inducedDipoleS[0]*qir3;
    float ukxqir3           = atomJ.inducedDipoleS[0]*qir2 - atomJ.inducedDipoleS[1]*qir1;
Mark Friedrichs's avatar
Mark Friedrichs committed
272

Peter Eastman's avatar
Peter Eastman committed
273
274
275
    float uixqkrp1          = atomI.inducedDipolePS[1]*qkr3 - atomI.inducedDipolePS[2]*qkr2;
    float uixqkrp2          = atomI.inducedDipolePS[2]*qkr1 - atomI.inducedDipolePS[0]*qkr3;
    float uixqkrp3          = atomI.inducedDipolePS[0]*qkr2 - atomI.inducedDipolePS[1]*qkr1;
Mark Friedrichs's avatar
Mark Friedrichs committed
276

Peter Eastman's avatar
Peter Eastman committed
277
278
279
    float ukxqirp1          = atomJ.inducedDipolePS[1]*qir3 - atomJ.inducedDipolePS[2]*qir2;
    float ukxqirp2          = atomJ.inducedDipolePS[2]*qir1 - atomJ.inducedDipolePS[0]*qir3;
    float ukxqirp3          = atomJ.inducedDipolePS[0]*qir2 - atomJ.inducedDipolePS[1]*qir1;
Mark Friedrichs's avatar
Mark Friedrichs committed
280

Peter Eastman's avatar
Peter Eastman committed
281
282
283
    float rxqiuk1           = yr*qiuk3 - zr*qiuk2;
    float rxqiuk2           = zr*qiuk1 - xr*qiuk3;
    float rxqiuk3           = xr*qiuk2 - yr*qiuk1;
Mark Friedrichs's avatar
Mark Friedrichs committed
284

Peter Eastman's avatar
Peter Eastman committed
285
286
287
    float rxqkui1           = yr*qkui3 - zr*qkui2;
    float rxqkui2           = zr*qkui1 - xr*qkui3;
    float rxqkui3           = xr*qkui2 - yr*qkui1;
Mark Friedrichs's avatar
Mark Friedrichs committed
288

Peter Eastman's avatar
Peter Eastman committed
289
290
291
    float rxqiukp1          = yr*qiukp3 - zr*qiukp2;
    float rxqiukp2          = zr*qiukp1 - xr*qiukp3;
    float rxqiukp3          = xr*qiukp2 - yr*qiukp1;
Mark Friedrichs's avatar
Mark Friedrichs committed
292

Peter Eastman's avatar
Peter Eastman committed
293
294
295
    float rxqkuip1          = yr*qkuip3 - zr*qkuip2;
    float rxqkuip2          = zr*qkuip1 - xr*qkuip3;
    float rxqkuip3          = xr*qkuip2 - yr*qkuip1;
Mark Friedrichs's avatar
Mark Friedrichs committed
296
297
298
 
    // get intermediate variables for induction energy terms

Peter Eastman's avatar
Peter Eastman committed
299
300
301
    float sci1              = atomI.inducedDipoleS[0]*atomJ.labFrameDipole[0] + atomI.inducedDipoleS[1]*atomJ.labFrameDipole[1] +
                              atomI.inducedDipoleS[2]*atomJ.labFrameDipole[2] + atomI.labFrameDipole[0]*atomJ.inducedDipoleS[0] +
                              atomI.labFrameDipole[1]*atomJ.inducedDipoleS[1] + atomI.labFrameDipole[2]*atomJ.inducedDipoleS[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
302

Peter Eastman's avatar
Peter Eastman committed
303
304
    float sci3              = atomI.inducedDipoleS[0]*xr + atomI.inducedDipoleS[1]*yr + atomI.inducedDipoleS[2]*zr;
    float sci4              = atomJ.inducedDipoleS[0]*xr + atomJ.inducedDipoleS[1]*yr + atomJ.inducedDipoleS[2]*zr;
Mark Friedrichs's avatar
Mark Friedrichs committed
305

Peter Eastman's avatar
Peter Eastman committed
306
307
    float sci7              = qir1*atomJ.inducedDipoleS[0] + qir2*atomJ.inducedDipoleS[1] + qir3*atomJ.inducedDipoleS[2];
    float sci8              = qkr1*atomI.inducedDipoleS[0] + qkr2*atomI.inducedDipoleS[1] + qkr3*atomI.inducedDipoleS[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
308

Peter Eastman's avatar
Peter Eastman committed
309
310
311
    float scip1             = atomI.inducedDipolePS[0]*atomJ.labFrameDipole[0] + atomI.inducedDipolePS[1]*atomJ.labFrameDipole[1] +
                              atomI.inducedDipolePS[2]*atomJ.labFrameDipole[2] + atomI.labFrameDipole[0]*atomJ.inducedDipolePS[0] +
                              atomI.labFrameDipole[1]*atomJ.inducedDipolePS[1] + atomI.labFrameDipole[2]*atomJ.inducedDipolePS[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
312

Peter Eastman's avatar
Peter Eastman committed
313
314
315
    float scip2             = atomI.inducedDipoleS[0]*atomJ.inducedDipolePS[0] + atomI.inducedDipoleS[1]*atomJ.inducedDipolePS[1] +
                              atomI.inducedDipoleS[2]*atomJ.inducedDipolePS[2] + atomI.inducedDipolePS[0]*atomJ.inducedDipoleS[0] +
                              atomI.inducedDipolePS[1]*atomJ.inducedDipoleS[1] + atomI.inducedDipolePS[2]*atomJ.inducedDipoleS[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
316

Peter Eastman's avatar
Peter Eastman committed
317
318
    float scip3             = atomI.inducedDipolePS[0]*xr + atomI.inducedDipolePS[1]*yr + atomI.inducedDipolePS[2]*zr;
    float scip4             = atomJ.inducedDipolePS[0]*xr + atomJ.inducedDipolePS[1]*yr + atomJ.inducedDipolePS[2]*zr;
Mark Friedrichs's avatar
Mark Friedrichs committed
319

Peter Eastman's avatar
Peter Eastman committed
320
321
    float scip7             = qir1*atomJ.inducedDipolePS[0] + qir2*atomJ.inducedDipolePS[1] + qir3*atomJ.inducedDipolePS[2];
    float scip8             = qkr1*atomI.inducedDipolePS[0] + qkr2*atomI.inducedDipolePS[1] + qkr3*atomI.inducedDipolePS[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
322
323
324

    // calculate the gl functions for potential energy

Peter Eastman's avatar
Peter Eastman committed
325
326
327
328
329
330
331
332
333
334
    float gli1              = atomJ.q*sci3 - atomI.q*sci4;
    float gli2              = -sc3*sci4 - sci3*sc4;
    float gli3              = sci3*sc6 - sci4*sc5;
    float gli6              = sci1;
    float gli7              = 2.0f * (sci7-sci8);
    float glip1             = atomJ.q*scip3 - atomI.q*scip4;
    float glip2             = -sc3*scip4 - scip3*sc4;
    float glip3             = scip3*sc6 - scip4*sc5;
    float glip6             = scip1;
    float glip7             = 2.0f * (scip7-scip8);
Mark Friedrichs's avatar
Mark Friedrichs committed
335
336
337

    // get the permanent multipole and induced energies;

338
    *outputEnergy           = 0.5f * (rr3*(gli1+gli6)*psc3 + rr5*(gli2+gli7)*psc5 + rr7*gli3*psc7);
Mark Friedrichs's avatar
Mark Friedrichs committed
339
340
341

    // intermediate variables for the induced-permanent terms

Peter Eastman's avatar
Peter Eastman committed
342
343
344
345
346
347
    float gfi1              = 0.5f*rr5*((gli1+gli6)*psc3 +
                                        (glip1+glip6)*dsc3+scip2*scale3i) +
                              0.5f*rr7*((gli7+gli2)*psc5 +
                                        (glip7+glip2)*dsc5 -
                              (sci3*scip4+scip3*sci4)*scale5i) +
                              0.5f*rr9*(gli3*psc7+glip3*dsc7);
Mark Friedrichs's avatar
Mark Friedrichs committed
348

Peter Eastman's avatar
Peter Eastman committed
349
350
351
    float gfi4              = 2.0f * rr5;
    float gfi5              = rr7 * (sci4*psc7+scip4*dsc7);
    float gfi6              = -rr7 * (sci3*psc7+scip3*dsc7);
Mark Friedrichs's avatar
Mark Friedrichs committed
352
353
354

    // get the induced force;
 
Peter Eastman's avatar
Peter Eastman committed
355
    float ftm2i1            = gfi1*xr + 0.5f*
356
                          (- rr3*atomJ.q*(atomI.inducedDipoleS[0]*psc3+atomI.inducedDipolePS[0]*dsc3)
Peter Eastman's avatar
Peter Eastman committed
357
358
                           + rr5*sc4*(atomI.inducedDipoleS[0]*psc5+atomI.inducedDipolePS[0]*dsc5)
                           - rr7*sc6*(atomI.inducedDipoleS[0]*psc7+atomI.inducedDipolePS[0]*dsc7))
359
                           +(rr3*atomI.q*(atomJ.inducedDipoleS[0]*psc3+atomJ.inducedDipolePS[0]*dsc3)
Peter Eastman's avatar
Peter Eastman committed
360
361
362
363
364
365
366
367
368
                           + rr5*sc3*(atomJ.inducedDipoleS[0]*psc5+atomJ.inducedDipolePS[0]*dsc5)
                           + rr7*sc5*(atomJ.inducedDipoleS[0]*psc7+atomJ.inducedDipolePS[0]*dsc7))*0.5f
                           + rr5*scale5i*(sci4*atomI.inducedDipolePS[0]+scip4*atomI.inducedDipoleS[0]
                           + sci3*atomJ.inducedDipolePS[0]+scip3*atomJ.inducedDipoleS[0])*0.5f
                           + 0.5f*(sci4*psc5+scip4*dsc5)*rr5*atomI.labFrameDipole[0]
                           + 0.5f*(sci3*psc5+scip3*dsc5)*rr5*atomJ.labFrameDipole[0]
                           + 0.5f*gfi4*((qkui1-qiuk1)*psc5
                           + (qkuip1-qiukp1)*dsc5)
                           + gfi5*qir1 + gfi6*qkr1;
Mark Friedrichs's avatar
Mark Friedrichs committed
369
 
Peter Eastman's avatar
Peter Eastman committed
370
    float ftm2i2            = gfi1*yr + 0.5f*
371
                          (- rr3*atomJ.q*(atomI.inducedDipoleS[1]*psc3+atomI.inducedDipolePS[1]*dsc3)
Peter Eastman's avatar
Peter Eastman committed
372
373
                           + rr5*sc4*(atomI.inducedDipoleS[1]*psc5+atomI.inducedDipolePS[1]*dsc5)
                           - rr7*sc6*(atomI.inducedDipoleS[1]*psc7+atomI.inducedDipolePS[1]*dsc7))
374
                           +(rr3*atomI.q*(atomJ.inducedDipoleS[1]*psc3+atomJ.inducedDipolePS[1]*dsc3)
Peter Eastman's avatar
Peter Eastman committed
375
376
377
378
379
380
381
382
383
384
385
                           + rr5*sc3*(atomJ.inducedDipoleS[1]*psc5+atomJ.inducedDipolePS[1]*dsc5)
                           + rr7*sc5*(atomJ.inducedDipoleS[1]*psc7+atomJ.inducedDipolePS[1]*dsc7))*0.5f
                           + rr5*scale5i*(sci4*atomI.inducedDipolePS[1]+scip4*atomI.inducedDipoleS[1]
                           + sci3*atomJ.inducedDipolePS[1]+scip3*atomJ.inducedDipoleS[1])*0.5f
                           + 0.5f*(sci4*psc5+scip4*dsc5)*rr5*atomI.labFrameDipole[1]
                           + 0.5f*(sci3*psc5+scip3*dsc5)*rr5*atomJ.labFrameDipole[1]
                           + 0.5f*gfi4*((qkui2-qiuk2)*psc5
                           + (qkuip2-qiukp2)*dsc5)
                           + gfi5*qir2 + gfi6*qkr2;

    float ftm2i3            = gfi1*zr  + 0.5f*
386
                          (- rr3*atomJ.q*(atomI.inducedDipoleS[2]*psc3+atomI.inducedDipolePS[2]*dsc3)
Peter Eastman's avatar
Peter Eastman committed
387
388
                           + rr5*sc4*(atomI.inducedDipoleS[2]*psc5+atomI.inducedDipolePS[2]*dsc5)
                           - rr7*sc6*(atomI.inducedDipoleS[2]*psc7+atomI.inducedDipolePS[2]*dsc7))
389
                           +(rr3*atomI.q*(atomJ.inducedDipoleS[2]*psc3+atomJ.inducedDipolePS[2]*dsc3)
Peter Eastman's avatar
Peter Eastman committed
390
391
392
393
394
395
396
397
398
                           + rr5*sc3*(atomJ.inducedDipoleS[2]*psc5+atomJ.inducedDipolePS[2]*dsc5)
                           + rr7*sc5*(atomJ.inducedDipoleS[2]*psc7+atomJ.inducedDipolePS[2]*dsc7))*0.5f
                           + rr5*scale5i*(sci4*atomI.inducedDipolePS[2]+scip4*atomI.inducedDipoleS[2]
                           + sci3*atomJ.inducedDipolePS[2]+scip3*atomJ.inducedDipoleS[2])*0.5f
                           + 0.5f*(sci4*psc5+scip4*dsc5)*rr5*atomI.labFrameDipole[2]
                           + 0.5f*(sci3*psc5+scip3*dsc5)*rr5*atomJ.labFrameDipole[2]
                           + 0.5f*gfi4*((qkui3-qiuk3)*psc5
                           + (qkuip3-qiukp3)*dsc5)
                           + gfi5*qir3 + gfi6*qkr3;
Mark Friedrichs's avatar
Mark Friedrichs committed
399
400
401
 
    // intermediate values needed for partially excluded interactions

Peter Eastman's avatar
Peter Eastman committed
402
403
404
405
406
    float fridmp1           = 0.5f * (rr3*((gli1+gli6)*pscale
                          +(glip1+glip6)*dscale)*ddsc3_1
                          + rr5*((gli2+gli7)*pscale
                          +(glip2+glip7)*dscale)*ddsc5_1
                          + rr7*(gli3*pscale+glip3*dscale)*ddsc7_1);
Mark Friedrichs's avatar
Mark Friedrichs committed
407

Peter Eastman's avatar
Peter Eastman committed
408
409
410
411
412
    float fridmp2           = 0.5f * (rr3*((gli1+gli6)*pscale
                          +(glip1+glip6)*dscale)*ddsc3_2
                          + rr5*((gli2+gli7)*pscale
                          +(glip2+glip7)*dscale)*ddsc5_2
                          + rr7*(gli3*pscale+glip3*dscale)*ddsc7_2);
Mark Friedrichs's avatar
Mark Friedrichs committed
413

Peter Eastman's avatar
Peter Eastman committed
414
415
416
417
418
    float fridmp3           = 0.5f * (rr3*((gli1+gli6)*pscale
                          +(glip1+glip6)*dscale)*ddsc3_3
                          + rr5*((gli2+gli7)*pscale
                          +(glip2+glip7)*dscale)*ddsc5_3
                          + rr7*(gli3*pscale+glip3*dscale)*ddsc7_3);
Mark Friedrichs's avatar
Mark Friedrichs committed
419
420
421

    // get the induced-induced derivative terms
 
Peter Eastman's avatar
Peter Eastman committed
422
423
    float findmp1           = 0.5f * uscale * (scip2*rr3*ddsc3_1
                          - rr5*ddsc5_1*(sci3*scip4+scip3*sci4));
Mark Friedrichs's avatar
Mark Friedrichs committed
424

Peter Eastman's avatar
Peter Eastman committed
425
426
    float findmp2           = 0.5f * uscale * (scip2*rr3*ddsc3_2
                          - rr5*ddsc5_2*(sci3*scip4+scip3*sci4));
Mark Friedrichs's avatar
Mark Friedrichs committed
427

Peter Eastman's avatar
Peter Eastman committed
428
429
    float findmp3           = 0.5f * uscale * (scip2*rr3*ddsc3_3
                          - rr5*ddsc5_3*(sci3*scip4+scip3*sci4));
Mark Friedrichs's avatar
Mark Friedrichs committed
430
431
432

    // handle of scaling for partially excluded interactions

Peter Eastman's avatar
Peter Eastman committed
433
434
435
    ftm2i1           -= fridmp1 + findmp1;
    ftm2i2           -= fridmp2 + findmp2;
    ftm2i3           -= fridmp3 + findmp3;
Mark Friedrichs's avatar
Mark Friedrichs committed
436
437
438

    // correction to convert mutual to direct polarization force

439
440
441
442
443
444
445
446
447
448
    if ( cAmoebaSim.polarizationType ){
        float gfd      = 0.5f * (rr5*scip2*scale3i - rr7*(scip3*sci4+sci3*scip4)*scale5i);
        float fdir1    = gfd*xr + 0.5f*rr5*scale5i* (sci4*atomI.inducedDipolePS[0]+scip4*atomI.inducedDipoleS[0] + sci3*atomJ.inducedDipolePS[0]+scip3*atomJ.inducedDipoleS[0]);
        float fdir2    = gfd*yr + 0.5f*rr5*scale5i* (sci4*atomI.inducedDipolePS[1]+scip4*atomI.inducedDipoleS[1] + sci3*atomJ.inducedDipolePS[1]+scip3*atomJ.inducedDipoleS[1]);
        float fdir3    = gfd*zr + 0.5f*rr5*scale5i* (sci4*atomI.inducedDipolePS[2]+scip4*atomI.inducedDipoleS[2] + sci3*atomJ.inducedDipolePS[2]+scip3*atomJ.inducedDipoleS[2]);
        ftm2i1        -= fdir1 - findmp1;
        ftm2i2        -= fdir2 - findmp2;
        ftm2i3        -= fdir3 - findmp3;
     
    }
Mark Friedrichs's avatar
Mark Friedrichs committed
449
450
451
452

    // now perform the torque calculation
    // intermediate terms for torque between multipoles i and k
 
Peter Eastman's avatar
Peter Eastman committed
453
454
455
456
457
    float gti2              = 0.5f * (sci4*psc5+scip4*dsc5) * rr5;
    float gti3              = 0.5f * (sci3*psc5+scip3*dsc5) * rr5;
    float gti4              = gfi4;
    float gti5              = gfi5;
    float gti6              = gfi6;
Mark Friedrichs's avatar
Mark Friedrichs committed
458
459
460

    // calculate the induced torque components

Peter Eastman's avatar
Peter Eastman committed
461
462
463
    float ttm2i1            = -rr3*(dixuk1*psc3+dixukp1*dsc3)*0.5f
                          + gti2*dixr1 + gti4*((ukxqir1+rxqiuk1)*psc5
                          +(ukxqirp1+rxqiukp1)*dsc5)*0.5f - gti5*rxqir1;
Mark Friedrichs's avatar
Mark Friedrichs committed
464

Peter Eastman's avatar
Peter Eastman committed
465
466
467
    float ttm2i2            = -rr3*(dixuk2*psc3+dixukp2*dsc3)*0.5f
                          + gti2*dixr2 + gti4*((ukxqir2+rxqiuk2)*psc5
                          +(ukxqirp2+rxqiukp2)*dsc5)*0.5f - gti5*rxqir2;
Mark Friedrichs's avatar
Mark Friedrichs committed
468

Peter Eastman's avatar
Peter Eastman committed
469
470
471
    float ttm2i3            = -rr3*(dixuk3*psc3+dixukp3*dsc3)*0.5f
                          + gti2*dixr3 + gti4*((ukxqir3+rxqiuk3)*psc5
                          +(ukxqirp3+rxqiukp3)*dsc5)*0.5f - gti5*rxqir3;
Mark Friedrichs's avatar
Mark Friedrichs committed
472

Peter Eastman's avatar
Peter Eastman committed
473
474
475
    float ttm3i1            = -rr3*(dkxui1*psc3+dkxuip1*dsc3)*0.5f
                          + gti3*dkxr1 - gti4*((uixqkr1+rxqkui1)*psc5
                          +(uixqkrp1+rxqkuip1)*dsc5)*0.5f - gti6*rxqkr1;
Mark Friedrichs's avatar
Mark Friedrichs committed
476

Peter Eastman's avatar
Peter Eastman committed
477
478
479
    float ttm3i2            = -rr3*(dkxui2*psc3+dkxuip2*dsc3)*0.5f
                          + gti3*dkxr2 - gti4*((uixqkr2+rxqkui2)*psc5
                          +(uixqkrp2+rxqkuip2)*dsc5)*0.5f - gti6*rxqkr2;
Mark Friedrichs's avatar
Mark Friedrichs committed
480

Peter Eastman's avatar
Peter Eastman committed
481
482
483
    float ttm3i3            = -rr3*(dkxui3*psc3+dkxuip3*dsc3)*0.5f
                          + gti3*dkxr3 - gti4*((uixqkr3+rxqkui3)*psc5
                          +(uixqkrp3+rxqkuip3)*dsc5)*0.5f - gti6*rxqkr3;
Mark Friedrichs's avatar
Mark Friedrichs committed
484
485
 
    // update force and torque on site k
486
    //
Peter Eastman's avatar
Peter Eastman committed
487
488
489
    outputForce[0]      = -ftm2i1;
    outputForce[1]      = -ftm2i2;
    outputForce[2]      = -ftm2i3;
Mark Friedrichs's avatar
Mark Friedrichs committed
490

Peter Eastman's avatar
Peter Eastman committed
491
492
493
    outputTorqueI[0]    = ttm2i1;
    outputTorqueI[1]    = ttm2i2;
    outputTorqueI[2]    = ttm2i3;
Mark Friedrichs's avatar
Mark Friedrichs committed
494

Peter Eastman's avatar
Peter Eastman committed
495
496
497
    outputTorqueJ[0]    = ttm3i1;
    outputTorqueJ[1]    = ttm3i2;
    outputTorqueJ[2]    = ttm3i3;
Mark Friedrichs's avatar
Mark Friedrichs committed
498
499
500

    // construct auxiliary vectors for induced terms

Peter Eastman's avatar
Peter Eastman committed
501
502
503
    dixuk1            = atomI.labFrameDipole[1]*atomJ.inducedDipole[2] - atomI.labFrameDipole[2]*atomJ.inducedDipole[1];
    dixuk2            = atomI.labFrameDipole[2]*atomJ.inducedDipole[0] - atomI.labFrameDipole[0]*atomJ.inducedDipole[2];
    dixuk3            = atomI.labFrameDipole[0]*atomJ.inducedDipole[1] - atomI.labFrameDipole[1]*atomJ.inducedDipole[0];
Mark Friedrichs's avatar
Mark Friedrichs committed
504

Peter Eastman's avatar
Peter Eastman committed
505
506
507
    dkxui1            = atomJ.labFrameDipole[1]*atomI.inducedDipole[2] - atomJ.labFrameDipole[2]*atomI.inducedDipole[1];
    dkxui2            = atomJ.labFrameDipole[2]*atomI.inducedDipole[0] - atomJ.labFrameDipole[0]*atomI.inducedDipole[2];
    dkxui3            = atomJ.labFrameDipole[0]*atomI.inducedDipole[1] - atomJ.labFrameDipole[1]*atomI.inducedDipole[0];
Mark Friedrichs's avatar
Mark Friedrichs committed
508

Peter Eastman's avatar
Peter Eastman committed
509
510
511
    dixukp1           = atomI.labFrameDipole[1]*atomJ.inducedDipoleP[2] - atomI.labFrameDipole[2]*atomJ.inducedDipoleP[1];
    dixukp2           = atomI.labFrameDipole[2]*atomJ.inducedDipoleP[0] - atomI.labFrameDipole[0]*atomJ.inducedDipoleP[2];
    dixukp3           = atomI.labFrameDipole[0]*atomJ.inducedDipoleP[1] - atomI.labFrameDipole[1]*atomJ.inducedDipoleP[0];
Mark Friedrichs's avatar
Mark Friedrichs committed
512

Peter Eastman's avatar
Peter Eastman committed
513
514
515
    dkxuip1           = atomJ.labFrameDipole[1]*atomI.inducedDipoleP[2] - atomJ.labFrameDipole[2]*atomI.inducedDipoleP[1];
    dkxuip2           = atomJ.labFrameDipole[2]*atomI.inducedDipoleP[0] - atomJ.labFrameDipole[0]*atomI.inducedDipoleP[2];
    dkxuip3           = atomJ.labFrameDipole[0]*atomI.inducedDipoleP[1] - atomJ.labFrameDipole[1]*atomI.inducedDipoleP[0];
Mark Friedrichs's avatar
Mark Friedrichs committed
516

Peter Eastman's avatar
Peter Eastman committed
517
518
519
    qiuk1             = atomI.labFrameQuadrupole_XX*atomJ.inducedDipole[0] + atomI.labFrameQuadrupole_XY*atomJ.inducedDipole[1] + atomI.labFrameQuadrupole_XZ*atomJ.inducedDipole[2];
    qiuk2             = atomI.labFrameQuadrupole_XY*atomJ.inducedDipole[0] + atomI.labFrameQuadrupole_YY*atomJ.inducedDipole[1] + atomI.labFrameQuadrupole_YZ*atomJ.inducedDipole[2];
    qiuk3             = atomI.labFrameQuadrupole_XZ*atomJ.inducedDipole[0] + atomI.labFrameQuadrupole_YZ*atomJ.inducedDipole[1] + atomI.labFrameQuadrupole_ZZ*atomJ.inducedDipole[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
520

Peter Eastman's avatar
Peter Eastman committed
521
522
523
    qkui1             = atomJ.labFrameQuadrupole_XX*atomI.inducedDipole[0] + atomJ.labFrameQuadrupole_XY*atomI.inducedDipole[1] + atomJ.labFrameQuadrupole_XZ*atomI.inducedDipole[2];
    qkui2             = atomJ.labFrameQuadrupole_XY*atomI.inducedDipole[0] + atomJ.labFrameQuadrupole_YY*atomI.inducedDipole[1] + atomJ.labFrameQuadrupole_YZ*atomI.inducedDipole[2];
    qkui3             = atomJ.labFrameQuadrupole_XZ*atomI.inducedDipole[0] + atomJ.labFrameQuadrupole_YZ*atomI.inducedDipole[1] + atomJ.labFrameQuadrupole_ZZ*atomI.inducedDipole[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
524

Peter Eastman's avatar
Peter Eastman committed
525
526
527
    qiukp1            = atomI.labFrameQuadrupole_XX*atomJ.inducedDipoleP[0] + atomI.labFrameQuadrupole_XY*atomJ.inducedDipoleP[1] + atomI.labFrameQuadrupole_XZ*atomJ.inducedDipoleP[2];
    qiukp2            = atomI.labFrameQuadrupole_XY*atomJ.inducedDipoleP[0] + atomI.labFrameQuadrupole_YY*atomJ.inducedDipoleP[1] + atomI.labFrameQuadrupole_YZ*atomJ.inducedDipoleP[2];
    qiukp3            = atomI.labFrameQuadrupole_XZ*atomJ.inducedDipoleP[0] + atomI.labFrameQuadrupole_YZ*atomJ.inducedDipoleP[1] + atomI.labFrameQuadrupole_ZZ*atomJ.inducedDipoleP[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
528

Peter Eastman's avatar
Peter Eastman committed
529
530
531
    qkuip1            = atomJ.labFrameQuadrupole_XX*atomI.inducedDipoleP[0] + atomJ.labFrameQuadrupole_XY*atomI.inducedDipoleP[1] + atomJ.labFrameQuadrupole_XZ*atomI.inducedDipoleP[2];
    qkuip2            = atomJ.labFrameQuadrupole_XY*atomI.inducedDipoleP[0] + atomJ.labFrameQuadrupole_YY*atomI.inducedDipoleP[1] + atomJ.labFrameQuadrupole_YZ*atomI.inducedDipoleP[2];
    qkuip3            = atomJ.labFrameQuadrupole_XZ*atomI.inducedDipoleP[0] + atomJ.labFrameQuadrupole_YZ*atomI.inducedDipoleP[1] + atomJ.labFrameQuadrupole_ZZ*atomI.inducedDipoleP[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
532

Peter Eastman's avatar
Peter Eastman committed
533
534
535
    uixqkr1           = atomI.inducedDipole[1]*qkr3 - atomI.inducedDipole[2]*qkr2;
    uixqkr2           = atomI.inducedDipole[2]*qkr1 - atomI.inducedDipole[0]*qkr3;
    uixqkr3           = atomI.inducedDipole[0]*qkr2 - atomI.inducedDipole[1]*qkr1;
Mark Friedrichs's avatar
Mark Friedrichs committed
536

Peter Eastman's avatar
Peter Eastman committed
537
538
539
    ukxqir1           = atomJ.inducedDipole[1]*qir3 - atomJ.inducedDipole[2]*qir2;
    ukxqir2           = atomJ.inducedDipole[2]*qir1 - atomJ.inducedDipole[0]*qir3;
    ukxqir3           = atomJ.inducedDipole[0]*qir2 - atomJ.inducedDipole[1]*qir1;
Mark Friedrichs's avatar
Mark Friedrichs committed
540

Peter Eastman's avatar
Peter Eastman committed
541
542
543
    uixqkrp1          = atomI.inducedDipoleP[1]*qkr3 - atomI.inducedDipoleP[2]*qkr2;
    uixqkrp2          = atomI.inducedDipoleP[2]*qkr1 - atomI.inducedDipoleP[0]*qkr3;
    uixqkrp3          = atomI.inducedDipoleP[0]*qkr2 - atomI.inducedDipoleP[1]*qkr1;
Mark Friedrichs's avatar
Mark Friedrichs committed
544

Peter Eastman's avatar
Peter Eastman committed
545
546
547
    ukxqirp1          = atomJ.inducedDipoleP[1]*qir3 - atomJ.inducedDipoleP[2]*qir2;
    ukxqirp2          = atomJ.inducedDipoleP[2]*qir1 - atomJ.inducedDipoleP[0]*qir3;
    ukxqirp3          = atomJ.inducedDipoleP[0]*qir2 - atomJ.inducedDipoleP[1]*qir1;
Mark Friedrichs's avatar
Mark Friedrichs committed
548

Peter Eastman's avatar
Peter Eastman committed
549
550
551
    rxqiuk1           = yr*qiuk3 - zr*qiuk2;
    rxqiuk2           = zr*qiuk1 - xr*qiuk3;
    rxqiuk3           = xr*qiuk2 - yr*qiuk1;
Mark Friedrichs's avatar
Mark Friedrichs committed
552

Peter Eastman's avatar
Peter Eastman committed
553
554
555
    rxqkui1           = yr*qkui3 - zr*qkui2;
    rxqkui2           = zr*qkui1 - xr*qkui3;
    rxqkui3           = xr*qkui2 - yr*qkui1;
Mark Friedrichs's avatar
Mark Friedrichs committed
556

Peter Eastman's avatar
Peter Eastman committed
557
558
559
    rxqiukp1          = yr*qiukp3 - zr*qiukp2;
    rxqiukp2          = zr*qiukp1 - xr*qiukp3;
    rxqiukp3          = xr*qiukp2 - yr*qiukp1;
Mark Friedrichs's avatar
Mark Friedrichs committed
560

Peter Eastman's avatar
Peter Eastman committed
561
562
563
    rxqkuip1          = yr*qkuip3 - zr*qkuip2;
    rxqkuip2          = zr*qkuip1 - xr*qkuip3;
    rxqkuip3          = xr*qkuip2 - yr*qkuip1;
Mark Friedrichs's avatar
Mark Friedrichs committed
564
565
566

    // get intermediate variables for induction energy terms

Peter Eastman's avatar
Peter Eastman committed
567
    sci1              = atomI.inducedDipole[0]*atomJ.labFrameDipole[0] + atomI.inducedDipole[1]*atomJ.labFrameDipole[1]
568
569
                          + atomI.inducedDipole[2]*atomJ.labFrameDipole[2] + atomI.labFrameDipole[0]*atomJ.inducedDipole[0]
                          + atomI.labFrameDipole[1]*atomJ.inducedDipole[1] + atomI.labFrameDipole[2]*atomJ.inducedDipole[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
570

Peter Eastman's avatar
Peter Eastman committed
571
572
    sci3              = atomI.inducedDipole[0]*xr + atomI.inducedDipole[1]*yr + atomI.inducedDipole[2]*zr;
    sci4              = atomJ.inducedDipole[0]*xr + atomJ.inducedDipole[1]*yr + atomJ.inducedDipole[2]*zr;
Mark Friedrichs's avatar
Mark Friedrichs committed
573

Peter Eastman's avatar
Peter Eastman committed
574
575
    sci7              = qir1*atomJ.inducedDipole[0] + qir2*atomJ.inducedDipole[1] + qir3*atomJ.inducedDipole[2];
    sci8              = qkr1*atomI.inducedDipole[0] + qkr2*atomI.inducedDipole[1] + qkr3*atomI.inducedDipole[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
576

Peter Eastman's avatar
Peter Eastman committed
577
578
    scip1             = atomI.inducedDipoleP[0]*atomJ.labFrameDipole[0] + atomI.inducedDipoleP[1]*atomJ.labFrameDipole[1] + atomI.inducedDipoleP[2]*atomJ.labFrameDipole[2] + atomI.labFrameDipole[0]*atomJ.inducedDipoleP[0] + atomI.labFrameDipole[1]*atomJ.inducedDipoleP[1] + atomI.labFrameDipole[2]*atomJ.inducedDipoleP[2];
    scip2             = atomI.inducedDipole[0]*atomJ.inducedDipoleP[0]+atomI.inducedDipole[1]*atomJ.inducedDipoleP[1] + atomI.inducedDipole[2]*atomJ.inducedDipoleP[2]+atomI.inducedDipoleP[0]*atomJ.inducedDipole[0] + atomI.inducedDipoleP[1]*atomJ.inducedDipole[1]+atomI.inducedDipoleP[2]*atomJ.inducedDipole[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
579

Peter Eastman's avatar
Peter Eastman committed
580
581
    scip3             = atomI.inducedDipoleP[0]*xr + atomI.inducedDipoleP[1]*yr + atomI.inducedDipoleP[2]*zr;
    scip4             = atomJ.inducedDipoleP[0]*xr + atomJ.inducedDipoleP[1]*yr + atomJ.inducedDipoleP[2]*zr;
Mark Friedrichs's avatar
Mark Friedrichs committed
582

Peter Eastman's avatar
Peter Eastman committed
583
584
    scip7             = qir1*atomJ.inducedDipoleP[0] + qir2*atomJ.inducedDipoleP[1] + qir3*atomJ.inducedDipoleP[2];
    scip8             = qkr1*atomI.inducedDipoleP[0] + qkr2*atomI.inducedDipoleP[1] + qkr3*atomI.inducedDipoleP[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
585
586
587

    // calculate the gl functions for potential energy

Peter Eastman's avatar
Peter Eastman committed
588
589
590
591
592
    gli1              = atomJ.q*sci3 - atomI.q*sci4;
    gli2              = -sc3*sci4 - sci3*sc4;
    gli3              = sci3*sc6 - sci4*sc5;
    gli6              = sci1;
    gli7              = 2.0f * (sci7-sci8);
Mark Friedrichs's avatar
Mark Friedrichs committed
593

Peter Eastman's avatar
Peter Eastman committed
594
595
596
597
598
    glip1             = atomJ.q*scip3 - atomI.q*scip4;
    glip2             = -sc3*scip4 - scip3*sc4;
    glip3             = scip3*sc6 - scip4*sc5;
    glip6             = scip1;
    glip7             = 2.0f * (scip7-scip8);
Mark Friedrichs's avatar
Mark Friedrichs committed
599
600
601

    // get the permanent multipole and induced energies

Peter Eastman's avatar
Peter Eastman committed
602
    *outputEnergy      += -0.5f * (rr3*(gli1+gli6)*psc3 + rr5*(gli2+gli7)*psc5 + rr7*gli3*psc7);
Mark Friedrichs's avatar
Mark Friedrichs committed
603
604
605

    // intermediate variables for the induced-permanent terms;

Peter Eastman's avatar
Peter Eastman committed
606
607
608
609
    gfi1             = 0.5f*rr5*((gli1+gli6)*psc3 + (glip1+glip6)*dsc3+scip2*scale3i)
                         + 0.5f*rr7*((gli7+gli2)*psc5 +(glip7+glip2)*dsc5
                         -(sci3*scip4+scip3*sci4)*scale5i)
                         + 0.5f*rr9*(gli3*psc7+glip3*dsc7);
Mark Friedrichs's avatar
Mark Friedrichs committed
610

Peter Eastman's avatar
Peter Eastman committed
611
612
613
    gfi4             = 2.0f * rr5;
    gfi5             = rr7 * (sci4*psc7+scip4*dsc7);
    gfi6             = -rr7 * (sci3*psc7+scip3*dsc7);
Mark Friedrichs's avatar
Mark Friedrichs committed
614
615
616

    // get the induced force

Peter Eastman's avatar
Peter Eastman committed
617
    ftm2i1           = gfi1*xr + 0.5f*
618
                        (- rr3*atomJ.q*(atomI.inducedDipole[0]*psc3+atomI.inducedDipoleP[0]*dsc3)
Peter Eastman's avatar
Peter Eastman committed
619
620
                         + rr5*sc4*(atomI.inducedDipole[0]*psc5+atomI.inducedDipoleP[0]*dsc5)
                         - rr7*sc6*(atomI.inducedDipole[0]*psc7+atomI.inducedDipoleP[0]*dsc7))
621
                         +(rr3*atomI.q*(atomJ.inducedDipole[0]*psc3+atomJ.inducedDipoleP[0]*dsc3)
Peter Eastman's avatar
Peter Eastman committed
622
623
624
625
626
627
628
629
630
631
632
                         + rr5*sc3*(atomJ.inducedDipole[0]*psc5+atomJ.inducedDipoleP[0]*dsc5)
                         + rr7*sc5*(atomJ.inducedDipole[0]*psc7+atomJ.inducedDipoleP[0]*dsc7))*0.5f
                         + rr5*scale5i*(sci4*atomI.inducedDipoleP[0]+scip4*atomI.inducedDipole[0]
                         + sci3*atomJ.inducedDipoleP[0]+scip3*atomJ.inducedDipole[0])*0.5f
                         + 0.5f*(sci4*psc5+scip4*dsc5)*rr5*atomI.labFrameDipole[0]
                         + 0.5f*(sci3*psc5+scip3*dsc5)*rr5*atomJ.labFrameDipole[0]
                         + 0.5f*gfi4*((qkui1-qiuk1)*psc5
                         + (qkuip1-qiukp1)*dsc5)
                         + gfi5*qir1 + gfi6*qkr1;

    ftm2i2           = gfi1*yr + 0.5f*
633
                        (- rr3*atomJ.q*(atomI.inducedDipole[1]*psc3+atomI.inducedDipoleP[1]*dsc3)
Peter Eastman's avatar
Peter Eastman committed
634
635
                         + rr5*sc4*(atomI.inducedDipole[1]*psc5+atomI.inducedDipoleP[1]*dsc5)
                         - rr7*sc6*(atomI.inducedDipole[1]*psc7+atomI.inducedDipoleP[1]*dsc7))
636
                         +(rr3*atomI.q*(atomJ.inducedDipole[1]*psc3+atomJ.inducedDipoleP[1]*dsc3)
Peter Eastman's avatar
Peter Eastman committed
637
638
639
640
641
642
643
644
645
646
647
                         + rr5*sc3*(atomJ.inducedDipole[1]*psc5+atomJ.inducedDipoleP[1]*dsc5)
                         + rr7*sc5*(atomJ.inducedDipole[1]*psc7+atomJ.inducedDipoleP[1]*dsc7))*0.5f
                         + rr5*scale5i*(sci4*atomI.inducedDipoleP[1]+scip4*atomI.inducedDipole[1]
                         + sci3*atomJ.inducedDipoleP[1]+scip3*atomJ.inducedDipole[1])*0.5f
                         + 0.5f*(sci4*psc5+scip4*dsc5)*rr5*atomI.labFrameDipole[1]
                         + 0.5f*(sci3*psc5+scip3*dsc5)*rr5*atomJ.labFrameDipole[1]
                         + 0.5f*gfi4*((qkui2-qiuk2)*psc5
                         + (qkuip2-qiukp2)*dsc5)
                         + gfi5*qir2 + gfi6*qkr2;

    ftm2i3           = gfi1*zr  + 0.5f*
648
                         (- rr3*atomJ.q*(atomI.inducedDipole[2]*psc3+atomI.inducedDipoleP[2]*dsc3)
Peter Eastman's avatar
Peter Eastman committed
649
650
                         + rr5*sc4*(atomI.inducedDipole[2]*psc5+atomI.inducedDipoleP[2]*dsc5)
                         - rr7*sc6*(atomI.inducedDipole[2]*psc7+atomI.inducedDipoleP[2]*dsc7))
651
                         +(rr3*atomI.q*(atomJ.inducedDipole[2]*psc3+atomJ.inducedDipoleP[2]*dsc3)
Peter Eastman's avatar
Peter Eastman committed
652
653
654
655
656
657
658
659
660
                         + rr5*sc3*(atomJ.inducedDipole[2]*psc5+atomJ.inducedDipoleP[2]*dsc5)
                         + rr7*sc5*(atomJ.inducedDipole[2]*psc7+atomJ.inducedDipoleP[2]*dsc7))*0.5f
                         + rr5*scale5i*(sci4*atomI.inducedDipoleP[2]+scip4*atomI.inducedDipole[2]
                         + sci3*atomJ.inducedDipoleP[2]+scip3*atomJ.inducedDipole[2])*0.5f
                         + 0.5f*(sci4*psc5+scip4*dsc5)*rr5*atomI.labFrameDipole[2]
                         + 0.5f*(sci3*psc5+scip3*dsc5)*rr5*atomJ.labFrameDipole[2]
                         + 0.5f*gfi4*((qkui3-qiuk3)*psc5
                         + (qkuip3-qiukp3)*dsc5)
                         + gfi5*qir3 + gfi6*qkr3;
Mark Friedrichs's avatar
Mark Friedrichs committed
661
662
663

    // intermediate values needed for partially excluded interactions

Peter Eastman's avatar
Peter Eastman committed
664
665
666
667
668
    fridmp1          = 0.5f * (rr3*((gli1+gli6)*pscale
                         +(glip1+glip6)*dscale)*ddsc3_1
                         + rr5*((gli2+gli7)*pscale
                         +(glip2+glip7)*dscale)*ddsc5_1
                         + rr7*(gli3*pscale+glip3*dscale)*ddsc7_1);
Mark Friedrichs's avatar
Mark Friedrichs committed
669

Peter Eastman's avatar
Peter Eastman committed
670
671
672
673
674
    fridmp2          = 0.5f * (rr3*((gli1+gli6)*pscale
                         +(glip1+glip6)*dscale)*ddsc3_2
                         + rr5*((gli2+gli7)*pscale
                         +(glip2+glip7)*dscale)*ddsc5_2
                         + rr7*(gli3*pscale+glip3*dscale)*ddsc7_2);
Mark Friedrichs's avatar
Mark Friedrichs committed
675

Peter Eastman's avatar
Peter Eastman committed
676
677
678
679
680
    fridmp3          = 0.5f * (rr3*((gli1+gli6)*pscale
                         +(glip1+glip6)*dscale)*ddsc3_3
                         + rr5*((gli2+gli7)*pscale
                         +(glip2+glip7)*dscale)*ddsc5_3
                         + rr7*(gli3*pscale+glip3*dscale)*ddsc7_3);
Mark Friedrichs's avatar
Mark Friedrichs committed
681
682
683

    // get the induced-induced derivative terms;

Peter Eastman's avatar
Peter Eastman committed
684
685
    findmp1          = 0.5f * uscale * (scip2*rr3*ddsc3_1
                         - rr5*ddsc5_1*(sci3*scip4+scip3*sci4));
Mark Friedrichs's avatar
Mark Friedrichs committed
686

Peter Eastman's avatar
Peter Eastman committed
687
688
    findmp2          = 0.5f * uscale * (scip2*rr3*ddsc3_2
                         - rr5*ddsc5_2*(sci3*scip4+scip3*sci4));
Mark Friedrichs's avatar
Mark Friedrichs committed
689

Peter Eastman's avatar
Peter Eastman committed
690
691
    findmp3          = 0.5f * uscale * (scip2*rr3*ddsc3_3
                         - rr5*ddsc5_3*(sci3*scip4+scip3*sci4));
Mark Friedrichs's avatar
Mark Friedrichs committed
692
693
694

    // handle of scaling for partially excluded interactions;

Peter Eastman's avatar
Peter Eastman committed
695
696
697
    ftm2i1           = ftm2i1 - fridmp1 - findmp1;
    ftm2i2           = ftm2i2 - fridmp2 - findmp2;
    ftm2i3           = ftm2i3 - fridmp3 - findmp3;
Mark Friedrichs's avatar
Mark Friedrichs committed
698
699
700

    // correction to convert mutual to direct polarization force;

701
702
703
704
705
706
707
708
709
710
    if ( cAmoebaSim.polarizationType ){

        float gfd    = 0.5f * (rr5*scip2*scale3i- rr7*(scip3*sci4+sci3*scip4)*scale5i);
        float fdir1  = gfd*xr + 0.5f*rr5*scale5i* (sci4*atomI.inducedDipoleP[0]+scip4*atomI.inducedDipole[0] + sci3*atomJ.inducedDipoleP[0]+scip3*atomJ.inducedDipole[0]);
        float fdir2  = gfd*yr + 0.5f*rr5*scale5i* (sci4*atomI.inducedDipoleP[1]+scip4*atomI.inducedDipole[1] + sci3*atomJ.inducedDipoleP[1]+scip3*atomJ.inducedDipole[1]);
        float fdir3  = gfd*zr + 0.5f*rr5*scale5i* (sci4*atomI.inducedDipoleP[2]+scip4*atomI.inducedDipole[2] + sci3*atomJ.inducedDipoleP[2]+scip3*atomJ.inducedDipole[2]);
        ftm2i1      -= fdir1 - findmp1;
        ftm2i2      -= fdir2 - findmp2;
        ftm2i3      -= fdir3 - findmp3;
    }
Mark Friedrichs's avatar
Mark Friedrichs committed
711
712
713
714

    // now perform the torque calculation
    // intermediate terms for torque between multipoles i and k

Peter Eastman's avatar
Peter Eastman committed
715
716
717
718
719
    gti2             = 0.5f * (sci4*psc5+scip4*dsc5) * rr5;
    gti3             = 0.5f * (sci3*psc5+scip3*dsc5) * rr5;
    gti4             = gfi4;
    gti5             = gfi5;
    gti6             = gfi6;
Mark Friedrichs's avatar
Mark Friedrichs committed
720
721
722

    // calculate the induced torque components

Peter Eastman's avatar
Peter Eastman committed
723
724
725
    ttm2i1           = -rr3*(dixuk1*psc3+dixukp1*dsc3)*0.5f
                         + gti2*dixr1 + gti4*((ukxqir1+rxqiuk1)*psc5
                         +(ukxqirp1+rxqiukp1)*dsc5)*0.5f - gti5*rxqir1;
Mark Friedrichs's avatar
Mark Friedrichs committed
726

Peter Eastman's avatar
Peter Eastman committed
727
728
729
    ttm2i2           = -rr3*(dixuk2*psc3+dixukp2*dsc3)*0.5f
                         + gti2*dixr2 + gti4*((ukxqir2+rxqiuk2)*psc5
                         +(ukxqirp2+rxqiukp2)*dsc5)*0.5f - gti5*rxqir2;
Mark Friedrichs's avatar
Mark Friedrichs committed
730

Peter Eastman's avatar
Peter Eastman committed
731
732
733
    ttm2i3           = -rr3*(dixuk3*psc3+dixukp3*dsc3)*0.5f
                         + gti2*dixr3 + gti4*((ukxqir3+rxqiuk3)*psc5
                         +(ukxqirp3+rxqiukp3)*dsc5)*0.5f - gti5*rxqir3;
Mark Friedrichs's avatar
Mark Friedrichs committed
734

Peter Eastman's avatar
Peter Eastman committed
735
736
737
    ttm3i1           = -rr3*(dkxui1*psc3+dkxuip1*dsc3)*0.5f
                         + gti3*dkxr1 - gti4*((uixqkr1+rxqkui1)*psc5
                         +(uixqkrp1+rxqkuip1)*dsc5)*0.5f - gti6*rxqkr1;
Mark Friedrichs's avatar
Mark Friedrichs committed
738

Peter Eastman's avatar
Peter Eastman committed
739
740
741
    ttm3i2           = -rr3*(dkxui2*psc3+dkxuip2*dsc3)*0.5f
                         + gti3*dkxr2 - gti4*((uixqkr2+rxqkui2)*psc5
                         +(uixqkrp2+rxqkuip2)*dsc5)*0.5f - gti6*rxqkr2;
Mark Friedrichs's avatar
Mark Friedrichs committed
742

Peter Eastman's avatar
Peter Eastman committed
743
744
745
    ttm3i3           = -rr3*(dkxui3*psc3+dkxuip3*dsc3)*0.5f
                         + gti3*dkxr3 - gti4*((uixqkr3+rxqkui3)*psc5
                         +(uixqkrp3+rxqkuip3)*dsc5)*0.5f - gti6*rxqkr3;
Mark Friedrichs's avatar
Mark Friedrichs committed
746
747
748

    // update force and torque on site k;

Peter Eastman's avatar
Peter Eastman committed
749
750
751
    outputForce[0]     += ftm2i1;
    outputForce[1]     += ftm2i2;
    outputForce[2]     += ftm2i3;
Mark Friedrichs's avatar
Mark Friedrichs committed
752

Peter Eastman's avatar
Peter Eastman committed
753
754
755
    outputTorqueI[0]   -= ttm2i1;
    outputTorqueI[1]   -= ttm2i2;
    outputTorqueI[2]   -= ttm2i3;
Mark Friedrichs's avatar
Mark Friedrichs committed
756

Peter Eastman's avatar
Peter Eastman committed
757
758
759
    outputTorqueJ[0]   -= ttm3i1;
    outputTorqueJ[1]   -= ttm3i2;
    outputTorqueJ[2]   -= ttm3i3;
Mark Friedrichs's avatar
Mark Friedrichs committed
760
761

}
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
#endif

#undef SUB_METHOD_NAME
#undef F1
#define SUB_METHOD_NAME(a, b) a##F1##b
#define F1
#include "kCalculateAmoebaCudaKirkwoodEDiff_b.h"
#undef F1
#undef SUB_METHOD_NAME

#undef SUB_METHOD_NAME
#undef T1
#define SUB_METHOD_NAME(a, b) a##T1##b
#define T1
#include "kCalculateAmoebaCudaKirkwoodEDiff_b.h"
#undef T1
#undef SUB_METHOD_NAME

#undef SUB_METHOD_NAME
#undef T3
#define SUB_METHOD_NAME(a, b) a##T3##b
#define T3
#include "kCalculateAmoebaCudaKirkwoodEDiff_b.h"
#undef T3
#undef SUB_METHOD_NAME

#define APPLY_SCALE
#undef SUB_METHOD_NAME
#undef F1
#define SUB_METHOD_NAME(a, b) a##F1Scale##b
#define F1
#include "kCalculateAmoebaCudaKirkwoodEDiff_b.h"
#undef F1
#undef SUB_METHOD_NAME

#undef SUB_METHOD_NAME
#undef T1
#define SUB_METHOD_NAME(a, b) a##T1Scale##b
#define T1
#include "kCalculateAmoebaCudaKirkwoodEDiff_b.h"
#undef T1
#undef SUB_METHOD_NAME

#undef SUB_METHOD_NAME
#undef T3
#define SUB_METHOD_NAME(a, b) a##T3Scale##b
#define T3
#include "kCalculateAmoebaCudaKirkwoodEDiff_b.h"
#undef T3
#undef SUB_METHOD_NAME
#undef APPLY_SCALE

#ifdef INCLUDE_TORQUE

/*****************************************************************************
 *
 *        ediff1 correct vacuum to SCRF derivatives
 *
 *               calculates the energy and derivatives of polarizing
 *                      the vacuum induced dipoles to their SCRF polarized values
 *
*******************************************************************************/

__device__ void calculateKirkwoodEDiffPairIxn_kernel( KirkwoodEDiffParticle& atomI,  KirkwoodEDiffParticle& atomJ,
                                                      float pscale,                  float dscale,
                                                      float*  outputEnergy, float forceFactor ){

#ifdef Orig
    return calculateKirkwoodEDiffPairIxnOrig_kernel( atomI,  atomJ, pscale, dscale, outputEnergy,outputForce,
                                                     outputTorqueI, outputTorqueJ );
#else

    float force[3];
    float energy;
    calculateKirkwoodEDiffPairIxnF1_kernel( atomI,  atomJ, pscale, dscale, &energy, force);
    atomI.force[0] += force[0];
    atomI.force[1] += force[1];
    atomI.force[2] += force[2];
    if( forceFactor == 1.0f ){
        atomJ.force[0] -= force[0];
        atomJ.force[1] -= force[1];
        atomJ.force[2] -= force[2];
        energy *= 0.5f;
    } else {
        energy *= 0.25f;
    }
    *outputEnergy += energy;

    calculateKirkwoodEDiffPairIxnT1_kernel( atomI,  atomJ, pscale, dscale, outputEnergy, force);
    atomI.torque[0] += force[0];
    atomI.torque[1] += force[1];
    atomI.torque[2] += force[2];
    //calculateKirkwoodEDiffPairIxnT1_kernel( atomJ,  atomI, pscale, dscale, outputEnergy, force );
    calculateKirkwoodEDiffPairIxnT3_kernel( atomI,  atomJ, pscale, dscale, outputEnergy, force );
    atomJ.torque[0] += force[0];
    atomJ.torque[1] += force[1];
    atomJ.torque[2] += force[2];

    return;

#endif

}

#endif
Mark Friedrichs's avatar
Mark Friedrichs committed
867

868
#ifdef AMOEBA_DEBUG
869
__device__ static int debugAccumulate( unsigned int index, float4* debugArray, float* field, unsigned int addMask, float idLabel )
Mark Friedrichs's avatar
Mark Friedrichs committed
870
{
871
    index                             += cSim.paddedNumberOfAtoms;
Mark Friedrichs's avatar
Mark Friedrichs committed
872
873
874
875
876
877
878
    debugArray[index].x                = addMask ? field[0] : 0.0f;
    debugArray[index].y                = addMask ? field[1] : 0.0f;
    debugArray[index].z                = addMask ? field[2] : 0.0f;
    debugArray[index].w                = idLabel;

    return index;
}
879
#endif
Mark Friedrichs's avatar
Mark Friedrichs committed
880
881
882
883
884
885
886
887
888

__device__ void zeroKirkwoodEDiffParticleSharedField( struct KirkwoodEDiffParticle* sA )
{
    // zero shared fields

    sA->force[0]              = 0.0f;
    sA->force[1]              = 0.0f;
    sA->force[2]              = 0.0f;

889
#ifdef INCLUDE_TORQUE
Mark Friedrichs's avatar
Mark Friedrichs committed
890
891
892
    sA->torque[0]             = 0.0f;
    sA->torque[1]             = 0.0f;
    sA->torque[2]             = 0.0f;
893
#endif
Mark Friedrichs's avatar
Mark Friedrichs committed
894
895
896
897
898
899
900
901
902
903
904
905
906

}

// Include versions of the kernels for N^2 calculations.

#undef USE_OUTPUT_BUFFER_PER_WARP
#define METHOD_NAME(a, b) a##N2##b
#include "kCalculateAmoebaCudaKirkwoodEDiff.h"
#define USE_OUTPUT_BUFFER_PER_WARP
#undef METHOD_NAME
#define METHOD_NAME(a, b) a##N2ByWarp##b
#include "kCalculateAmoebaCudaKirkwoodEDiff.h"

907
// reduce psWorkArray_3_1 -> torque
Mark Friedrichs's avatar
Mark Friedrichs committed
908

909
static void kReduceTorque( amoebaGpuContext amoebaGpu )
Mark Friedrichs's avatar
Mark Friedrichs committed
910
911
{

912
913
914
    gpuContext gpu = amoebaGpu->gpuContext;
    kReduceFields_kernel<<<gpu->sim.nonbond_blocks, gpu->sim.bsf_reduce_threads_per_block>>>(
                           gpu->sim.paddedNumberOfAtoms*3, gpu->sim.outputBuffers,
915
                           amoebaGpu->psWorkArray_3_1->_pDevData, amoebaGpu->psTorque->_pDevData, 0 );
Mark Friedrichs's avatar
Mark Friedrichs committed
916

917
    LAUNCHERROR("kReduceForceTorqueKirkwoodEDiff");
Mark Friedrichs's avatar
Mark Friedrichs committed
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
}

/**---------------------------------------------------------------------------------------

   Compute Amoeba electrostatic force & torque

   @param amoebaGpu        amoebaGpu context
   @param gpu              OpenMM gpu Cuda context

   --------------------------------------------------------------------------------------- */

void kCalculateAmoebaKirkwoodEDiff( amoebaGpuContext amoebaGpu )
{
  
   // ---------------------------------------------------------------------------------------

Mark Friedrichs's avatar
Update  
Mark Friedrichs committed
934
935
    static int timestep                 = 0;
    timestep++;
Mark Friedrichs's avatar
Mark Friedrichs committed
936
#ifdef AMOEBA_DEBUG
937
    static const char* methodName       = "kCalculateAmoebaKirkwoodEDiff";
Mark Friedrichs's avatar
Mark Friedrichs committed
938
939
940
941
942
943
944
945
946
947
948
    std::vector<int> fileId;
    fileId.resize( 2 );
    fileId[0] = timestep;
    fileId[1] = 1;
#endif

    // ---------------------------------------------------------------------------------------

    gpuContext gpu = amoebaGpu->gpuContext;

    // apparently debug array can take up nontrivial no. registers
949
    //
950
    static unsigned int threadsPerBlock = 0;
Mark Friedrichs's avatar
Mark Friedrichs committed
951
    if( threadsPerBlock == 0 ){
952
953
        unsigned int maxThreads;
        if (gpu->sm_version >= SM_20)
954
955
            //maxThreads = 384;
            maxThreads = 512;
956
957
958
959
        else if (gpu->sm_version >= SM_12)
            maxThreads = 96;
        else
            maxThreads = 32;
Mark Friedrichs's avatar
Mark Friedrichs committed
960
        threadsPerBlock = std::min(getThreadsPerBlock( amoebaGpu, sizeof(KirkwoodEDiffParticle), gpu->sharedMemoryPerBlock ), maxThreads);
Mark Friedrichs's avatar
Mark Friedrichs committed
961
962
    }   
    
963
#ifdef AMOEBA_DEBUG
964
    if( amoebaGpu->log ){
965
        (void) fprintf( amoebaGpu->log, "kCalculateAmoebaCudaKirkwoodEDiffN2Forces: blocks=%u threads=%u bffr/Warp=%u atm=%lu shrd=%lu"
966
                                        " ixnCt=%lu workUnits=%u sm=%d device=%d sharedMemoryPerBlock=%u step=%d\n",
967
                        gpu->sim.nonbond_blocks, threadsPerBlock, gpu->bOutputBufferPerWarp,
Mark Friedrichs's avatar
Update  
Mark Friedrichs committed
968
                        sizeof(KirkwoodEDiffParticle), sizeof(KirkwoodEDiffParticle)*threadsPerBlock,
969
                        (*gpu->psInteractionCount)[0], gpu->sim.workUnits, gpu->sm_version, gpu->device, gpu->sharedMemoryPerBlock, timestep );
Mark Friedrichs's avatar
Update  
Mark Friedrichs committed
970
971
        (void) fflush( amoebaGpu->log );
    }   
972
#endif
Mark Friedrichs's avatar
Update  
Mark Friedrichs committed
973

Mark Friedrichs's avatar
Mark Friedrichs committed
974
    if (gpu->bOutputBufferPerWarp){
975
        kCalculateAmoebaCudaKirkwoodEDiffN2ByWarpForces_kernel<<<gpu->sim.nonbond_blocks, threadsPerBlock, sizeof(KirkwoodEDiffParticle)*threadsPerBlock>>>(
976
                                                                           gpu->psWorkUnit->_pDevData, amoebaGpu->psWorkArray_3_1->_pDevData );
Mark Friedrichs's avatar
Mark Friedrichs committed
977
978
979

    } else {

980
        kCalculateAmoebaCudaKirkwoodEDiffN2Forces_kernel<<<gpu->sim.nonbond_blocks, threadsPerBlock, sizeof(KirkwoodEDiffParticle)*threadsPerBlock>>>(
981
                                                                           gpu->psWorkUnit->_pDevData, amoebaGpu->psWorkArray_3_1->_pDevData );
Mark Friedrichs's avatar
Mark Friedrichs committed
982
983
984
    }
    LAUNCHERROR("kCalculateAmoebaCudaKirkwoodEDiffN2Forces");

985
    // reduce and map torques to forces
Mark Friedrichs's avatar
Mark Friedrichs committed
986

987
    kReduceTorque( amoebaGpu );
988
    cudaComputeAmoebaMapTorqueAndAddToForce( amoebaGpu, amoebaGpu->psTorque );
Mark Friedrichs's avatar
Mark Friedrichs committed
989
990
991

   // ---------------------------------------------------------------------------------------
}