kCalculateAmoebaCudaFixedFieldParticle.h 7.25 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

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
Mark Friedrichs's avatar
Mark Friedrichs committed
47
48
49
50
51

#ifdef INCLUDE_FIXED_FIELD_BUFFERS
    float tempBuffer[3];
    float tempBufferP[3];
#endif
Mark Friedrichs's avatar
Mark Friedrichs committed
52
53
};

54
__device__ static void loadFixedFieldShared( struct FixedFieldParticle* sA, unsigned int atomI 
Mark Friedrichs's avatar
Mark Friedrichs committed
55
56
57
58
59
60
61
#ifdef GK
    , float* bornR
#endif
)
{
    // coordinates & charge

62
63
64
65
    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
66
67
68

    // lab dipole

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

    // lab quadrupole

75
76
77
78
79
80
    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
81

82
83
    sA->damp                     = cAmoebaSim.pDampingFactorAndThole[atomI].x;
    sA->thole                    = cAmoebaSim.pDampingFactorAndThole[atomI].y;
Mark Friedrichs's avatar
Mark Friedrichs committed
84
85
86
87
88
89
90
91
#ifdef GK
    sA->bornR                    = bornR[atomI];
#endif

}

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

92
93
__device__ static void loadFixedFieldParticleData( struct FixedFieldParticle* sA, 
                                                   float4* jCoord, float* jDipole, float* jQuadrupole
Mark Friedrichs's avatar
Mark Friedrichs committed
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
125
126
127
128
129
#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

130
__device__ static void zeroFixedFieldParticleSharedField( struct FixedFieldParticle* sA )
Mark Friedrichs's avatar
Mark Friedrichs committed
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
{

    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
}

148

Mark Friedrichs's avatar
Mark Friedrichs committed
149
150
// body of fixed E-field calculation

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

 
    // ---------------------------------------------------------------------------------------
 
    // get deltaR and r between 2 atoms
 
    float deltaR[3];
165
166
167
    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
168
169
170
171
172
173
174
175
176
177
178

    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
    
179
    float damp          = atomI.damp*atomJ.damp;
Mark Friedrichs's avatar
Mark Friedrichs committed
180
    float dampExp;
181
    if( damp != 0.0f && r < cAmoebaSim.scalingDistanceCutoff ){
Mark Friedrichs's avatar
Mark Friedrichs committed
182
183
184
185

        // get scaling factors
      
        float ratio     = r/damp;
186
        float pGamma    = atomJ.thole > atomI.thole ? atomI.thole : atomJ.thole; 
Mark Friedrichs's avatar
Mark Friedrichs committed
187
188
189
190
191
192
193
194
195
196
197
198
199
        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];
200
201
202
    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
203
 
204
205
    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
206

207
208
209
210
211
    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
212
 
213
214
215
    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
216
 
217
    dotdd               = deltaR[0]*atomI.labFrameDipole_X    + deltaR[1]*atomI.labFrameDipole_Y    + deltaR[2]*atomI.labFrameDipole_Z;
Mark Friedrichs's avatar
Mark Friedrichs committed
218
    dotqd               = deltaR[0]*qDotDelta[0] + deltaR[1]*qDotDelta[1] + deltaR[2]*qDotDelta[2];
219
    factor              = rr3*atomI.q + rr5*dotdd + rr7*dotqd;
Mark Friedrichs's avatar
Mark Friedrichs committed
220
 
221
222
223
    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
224
225

}