kCalculateAmoebaCudaFixedFieldParticle.h 7.16 KB
Newer Older
Mark Friedrichs's avatar
Mark Friedrichs committed
1
2
3
4
5
6
7
8
9
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
36
37
38
39
40
41
42
43
44
45
46
47
48

struct FixedFieldParticle {

    // coordinates charge

    float x;
    float y;
    float z;
    float q;

    // lab frame dipole

    float labFrameDipole_X;
    float labFrameDipole_Y;
    float labFrameDipole_Z;

    // lab frame quadrupole

    float labFrameQuadrupole_XX;
    float labFrameQuadrupole_XY;
    float labFrameQuadrupole_XZ;
    float labFrameQuadrupole_YY;
    float labFrameQuadrupole_YZ;
    float labFrameQuadrupole_ZZ;

    // scaling factor

    float thole;
    float damp;

    // field accumulators

    float eField[3];
    float eFieldP[3];

#ifdef GK

    // Born radius

    float bornR;

    // GK field

    float gkField[3];

#endif
};

49
__device__ static void loadFixedFieldShared( struct FixedFieldParticle* sA, unsigned int atomI 
Mark Friedrichs's avatar
Mark Friedrichs committed
50
51
52
53
54
55
56
#ifdef GK
    , float* bornR
#endif
)
{
    // coordinates & charge

57
58
59
60
    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
61
62
63

    // lab dipole

64
65
66
    sA->labFrameDipole_X         = cAmoebaSim.pLabFrameDipole[atomI*3];
    sA->labFrameDipole_Y         = cAmoebaSim.pLabFrameDipole[atomI*3+1];
    sA->labFrameDipole_Z         = cAmoebaSim.pLabFrameDipole[atomI*3+2];
Mark Friedrichs's avatar
Mark Friedrichs committed
67
68
69

    // lab quadrupole

70
71
72
73
74
75
    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
76

77
78
    sA->damp                     = cAmoebaSim.pDampingFactorAndThole[atomI].x;
    sA->thole                    = cAmoebaSim.pDampingFactorAndThole[atomI].y;
Mark Friedrichs's avatar
Mark Friedrichs committed
79
80
81
82
83
84
85
86
#ifdef GK
    sA->bornR                    = bornR[atomI];
#endif

}

// load struct and arrays w/ shared data in sA

87
88
__device__ static void loadFixedFieldParticleData( struct FixedFieldParticle* sA, 
                                                   float4* jCoord, float* jDipole, float* jQuadrupole
Mark Friedrichs's avatar
Mark Friedrichs committed
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#ifdef GK
, float* bornR
#endif
)
{

    // load coords, charge, ...

    jCoord->x               = sA->x;
    jCoord->y               = sA->y;
    jCoord->z               = sA->z;
    jCoord->w               = sA->q;

    jDipole[0]              = sA->labFrameDipole_X;
    jDipole[1]              = sA->labFrameDipole_Y;
    jDipole[2]              = sA->labFrameDipole_Z;

    jQuadrupole[0]          = sA->labFrameQuadrupole_XX;
    jQuadrupole[1]          = sA->labFrameQuadrupole_XY;
    jQuadrupole[2]          = sA->labFrameQuadrupole_XZ;

    jQuadrupole[3]          = sA->labFrameQuadrupole_XY;
    jQuadrupole[4]          = sA->labFrameQuadrupole_YY;
    jQuadrupole[5]          = sA->labFrameQuadrupole_YZ;

    jQuadrupole[6]          = sA->labFrameQuadrupole_XZ;
    jQuadrupole[7]          = sA->labFrameQuadrupole_YZ;
    jQuadrupole[8]          = sA->labFrameQuadrupole_ZZ;
 
#ifdef GK
    *bornR                  = sA->bornR;
#endif
}

// zero fields

125
__device__ static void zeroFixedFieldParticleSharedField( struct FixedFieldParticle* sA )
Mark Friedrichs's avatar
Mark Friedrichs committed
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
{

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

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

#ifdef GK
    sA->gkField[0]   = 0.0f;
    sA->gkField[1]   = 0.0f;
    sA->gkField[2]   = 0.0f;
#endif
}

143

Mark Friedrichs's avatar
Mark Friedrichs committed
144
145
// body of fixed E-field calculation

146
147
__device__ static void calculateFixedEFieldPairIxn_kernel( FixedFieldParticle& atomI, FixedFieldParticle& atomJ,
                                                           float field[2][3]
Mark Friedrichs's avatar
Mark Friedrichs committed
148
149
150
151
152
153
154
155
156
157
158
159
#ifdef AMOEBA_DEBUG
                                                    , float4 debugArray[12]
#endif
)
{

 
    // ---------------------------------------------------------------------------------------
 
    // get deltaR and r between 2 atoms
 
    float deltaR[3];
160
161
162
    deltaR[0]           = atomJ.x - atomI.x;
    deltaR[1]           = atomJ.y - atomI.y;
    deltaR[2]           = atomJ.z - atomI.z;
Mark Friedrichs's avatar
Mark Friedrichs committed
163
164
165
166
167
168
169
170
171
172
173

    float r             =  SQRT( deltaR[0]*deltaR[0] + deltaR[1]*deltaR[1] + deltaR[2]*deltaR[2] );
    float rI            =  1.0f/r;
    float r2I           =  rI*rI;

    float rr3           =  rI*r2I;
    float rr5           =  3.0f*rr3*r2I;
    float rr7           =  5.0f*rr5*r2I;
 
    // get scaling factors, if needed
    
174
    float damp          = atomI.damp*atomJ.damp;
Mark Friedrichs's avatar
Mark Friedrichs committed
175
    float dampExp;
176
    if( damp != 0.0f && r < cAmoebaSim.scalingDistanceCutoff ){
Mark Friedrichs's avatar
Mark Friedrichs committed
177
178
179
180

        // get scaling factors
      
        float ratio     = r/damp;
181
        float pGamma    = atomJ.thole > atomI.thole ? atomI.thole : atomJ.thole; 
Mark Friedrichs's avatar
Mark Friedrichs committed
182
183
184
185
186
187
188
189
190
191
192
193
194
        damp            = ratio*ratio*ratio*pGamma;
        dampExp         = EXP( -damp );
    } else {
        dampExp         = 0.0f;
    }
      
    rr3                *= 1.0f - dampExp;
    rr5                *= 1.0f - ( 1.0f + damp )*dampExp;
    rr7                *= 1.0f - ( 1.0f + damp + (0.6f*damp*damp))*dampExp;
      
    float rr5_2         = rr5*2.0f;
 
    float  qDotDelta[3];
195
196
197
    qDotDelta[0]        = deltaR[0]*atomJ.labFrameQuadrupole_XX + deltaR[1]*atomJ.labFrameQuadrupole_XY + deltaR[2]*atomJ.labFrameQuadrupole_XZ;
    qDotDelta[1]        = deltaR[0]*atomJ.labFrameQuadrupole_XY + deltaR[1]*atomJ.labFrameQuadrupole_YY + deltaR[2]*atomJ.labFrameQuadrupole_YZ;
    qDotDelta[2]        = deltaR[0]*atomJ.labFrameQuadrupole_XZ + deltaR[1]*atomJ.labFrameQuadrupole_YZ + deltaR[2]*atomJ.labFrameQuadrupole_ZZ;
Mark Friedrichs's avatar
Mark Friedrichs committed
198
 
199
200
    float dotdd         = deltaR[0]*atomJ.labFrameDipole_X      + deltaR[1]*atomJ.labFrameDipole_Y      + deltaR[2]*atomJ.labFrameDipole_Z;
    float dotqd         = deltaR[0]*qDotDelta[0]                + deltaR[1]*qDotDelta[1]                + deltaR[2]*qDotDelta[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
201

202
203
204
205
206
    float factor        = -rr3*atomJ.q + rr5*dotdd - rr7*dotqd;
 
    field[0][0]         = deltaR[0]*factor - rr3*atomJ.labFrameDipole_X + rr5_2*qDotDelta[0];
    field[0][1]         = deltaR[1]*factor - rr3*atomJ.labFrameDipole_Y + rr5_2*qDotDelta[1];
    field[0][2]         = deltaR[2]*factor - rr3*atomJ.labFrameDipole_Z + rr5_2*qDotDelta[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
207
 
208
209
210
    qDotDelta[0]        = deltaR[0]*atomI.labFrameQuadrupole_XX + deltaR[1]*atomI.labFrameQuadrupole_XY + deltaR[2]*atomI.labFrameQuadrupole_XZ;
    qDotDelta[1]        = deltaR[0]*atomI.labFrameQuadrupole_XY + deltaR[1]*atomI.labFrameQuadrupole_YY + deltaR[2]*atomI.labFrameQuadrupole_YZ;
    qDotDelta[2]        = deltaR[0]*atomI.labFrameQuadrupole_XZ + deltaR[1]*atomI.labFrameQuadrupole_YZ + deltaR[2]*atomI.labFrameQuadrupole_ZZ;
Mark Friedrichs's avatar
Mark Friedrichs committed
211
 
212
    dotdd               = deltaR[0]*atomI.labFrameDipole_X    + deltaR[1]*atomI.labFrameDipole_Y    + deltaR[2]*atomI.labFrameDipole_Z;
Mark Friedrichs's avatar
Mark Friedrichs committed
213
    dotqd               = deltaR[0]*qDotDelta[0] + deltaR[1]*qDotDelta[1] + deltaR[2]*qDotDelta[2];
214
    factor              = rr3*atomI.q + rr5*dotdd + rr7*dotqd;
Mark Friedrichs's avatar
Mark Friedrichs committed
215
 
216
217
218
    field[1][0]         = deltaR[0]*factor - rr3*atomI.labFrameDipole_X - rr5_2*qDotDelta[0];
    field[1][1]         = deltaR[1]*factor - rr3*atomI.labFrameDipole_Y - rr5_2*qDotDelta[1];
    field[1][2]         = deltaR[2]*factor - rr3*atomI.labFrameDipole_Z - rr5_2*qDotDelta[2];
Mark Friedrichs's avatar
Mark Friedrichs committed
219
220

}