AmoebaCudaKernels.h 25.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
#ifndef AMOEBA_OPENMM_CUDAKERNELS_H_
#define AMOEBA_OPENMM_CUDAKERNELS_H_

/* -------------------------------------------------------------------------- *
 *                              OpenMMAmoeba                                  *
 * -------------------------------------------------------------------------- *
 * This is part of the OpenMM molecular simulation toolkit originating from   *
 * Simbios, the NIH National Center for Physics-Based Simulation of           *
 * Biological Structures at Stanford, funded under the NIH Roadmap for        *
 * Medical Research, grant U54 GM072970. See https://simtk.org.               *
 *                                                                            *
12
 * Portions copyright (c) 2008-2015 Stanford University and the Authors.      *
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * Authors: Mark Friedrichs, Peter Eastman                                    *
 * Contributors:                                                              *
 *                                                                            *
 * This program is free software: you can redistribute it and/or modify       *
 * it under the terms of the GNU Lesser General Public License as published   *
 * by the Free Software Foundation, either version 3 of the License, or       *
 * (at your option) any later version.                                        *
 *                                                                            *
 * This program is distributed in the hope that it will be useful,            *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
 * GNU Lesser General Public License for more details.                        *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.      *
 * -------------------------------------------------------------------------- */

#include "openmm/amoebaKernels.h"
#include "openmm/kernels.h"
#include "openmm/System.h"
#include "CudaArray.h"
34
35
36
#include "CudaContext.h"
#include "CudaSort.h"
#include <cufft.h>
37
38
39

namespace OpenMM {

40
41
class CudaCalcAmoebaGeneralizedKirkwoodForceKernel;

42
/**
43
 * This kernel is invoked by AmoebaBondForce to calculate the forces acting on the system and the energy of the system.
44
 */
45
class CudaCalcAmoebaBondForceKernel : public CalcAmoebaBondForceKernel {
46
public:
47
    CudaCalcAmoebaBondForceKernel(std::string name, 
48
49
                                          const Platform& platform,
                                          CudaContext& cu,
50
                                          const System& system);
51
    ~CudaCalcAmoebaBondForceKernel();
52
53
54
55
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
56
     * @param force      the AmoebaBondForce this kernel will be used for
57
     */
58
    void initialize(const System& system, const AmoebaBondForce& force);
59
60
61
62
63
64
65
66
67
    /**
     * Execute the kernel to calculate the forces and/or energy.
     *
     * @param context        the context in which to execute this kernel
     * @param includeForces  true if forces should be calculated
     * @param includeEnergy  true if the energy should be calculated
     * @return the potential energy due to the force
     */
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
68
69
70
71
72
73
74
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the AmoebaBondForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const AmoebaBondForce& force);
75
76
77
78
private:
    class ForceInfo;
    int numBonds;
    CudaContext& cu;
79
    const System& system;
80
81
82
83
    CudaArray* params;
};

/**
84
 * This kernel is invoked by AmoebaAngleForce to calculate the forces acting on the system and the energy of the system.
85
 */
86
class CudaCalcAmoebaAngleForceKernel : public CalcAmoebaAngleForceKernel {
87
public:
88
    CudaCalcAmoebaAngleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
89
    ~CudaCalcAmoebaAngleForceKernel();
90
91
92
93
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
94
     * @param force      the AmoebaAngleForce this kernel will be used for
95
     */
96
    void initialize(const System& system, const AmoebaAngleForce& force);
97
98
99
100
101
102
103
104
105
    /**
     * Execute the kernel to calculate the forces and/or energy.
     *
     * @param context        the context in which to execute this kernel
     * @param includeForces  true if forces should be calculated
     * @param includeEnergy  true if the energy should be calculated
     * @return the potential energy due to the force
     */
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
106
107
108
109
110
111
112
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the AmoebaAngleForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const AmoebaAngleForce& force);
113
114
115
116
private:
    class ForceInfo;
    int numAngles;
    CudaContext& cu;
117
    const System& system;
118
119
120
121
    CudaArray* params;
};

/**
122
 * This kernel is invoked by AmoebaInPlaneAngleForce to calculate the forces acting on the system and the energy of the system.
123
 */
124
class CudaCalcAmoebaInPlaneAngleForceKernel : public CalcAmoebaInPlaneAngleForceKernel {
125
public:
126
    CudaCalcAmoebaInPlaneAngleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
127
    ~CudaCalcAmoebaInPlaneAngleForceKernel();
128
129
130
131
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
132
     * @param force      the AmoebaInPlaneAngleForce this kernel will be used for
133
     */
134
    void initialize(const System& system, const AmoebaInPlaneAngleForce& force);
135
136
137
138
139
140
141
142
143
    /**
     * Execute the kernel to calculate the forces and/or energy.
     *
     * @param context        the context in which to execute this kernel
     * @param includeForces  true if forces should be calculated
     * @param includeEnergy  true if the energy should be calculated
     * @return the potential energy due to the force
     */
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
144
145
146
147
148
149
150
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the AmoebaInPlaneAngleForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const AmoebaInPlaneAngleForce& force);
151
152
153
154
private:
    class ForceInfo;
    int numAngles;
    CudaContext& cu;
155
    const System& system;
156
157
158
159
160
161
162
163
    CudaArray* params;
};

/**
 * This kernel is invoked by AmoebaPiTorsionForce to calculate the forces acting on the system and the energy of the system.
 */
class CudaCalcAmoebaPiTorsionForceKernel : public CalcAmoebaPiTorsionForceKernel {
public:
164
    CudaCalcAmoebaPiTorsionForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
    ~CudaCalcAmoebaPiTorsionForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the AmoebaPiTorsionForce this kernel will be used for
     */
    void initialize(const System& system, const AmoebaPiTorsionForce& force);
    /**
     * Execute the kernel to calculate the forces and/or energy.
     *
     * @param context        the context in which to execute this kernel
     * @param includeForces  true if forces should be calculated
     * @param includeEnergy  true if the energy should be calculated
     * @return the potential energy due to the force
     */
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
182
183
184
185
186
187
188
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the AmoebaPiTorsionForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const AmoebaPiTorsionForce& force);
189
190
191
192
private:
    class ForceInfo;
    int numPiTorsions;
    CudaContext& cu;
193
    const System& system;
194
195
196
197
198
199
200
201
    CudaArray* params;
};

/**
 * This kernel is invoked by AmoebaStretchBendForce to calculate the forces acting on the system and the energy of the system.
 */
class CudaCalcAmoebaStretchBendForceKernel : public CalcAmoebaStretchBendForceKernel {
public:
202
    CudaCalcAmoebaStretchBendForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
    ~CudaCalcAmoebaStretchBendForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the AmoebaStretchBendForce this kernel will be used for
     */
    void initialize(const System& system, const AmoebaStretchBendForce& force);
    /**
     * Execute the kernel to calculate the forces and/or energy.
     *
     * @param context        the context in which to execute this kernel
     * @param includeForces  true if forces should be calculated
     * @param includeEnergy  true if the energy should be calculated
     * @return the potential energy due to the force
     */
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
220
221
222
223
224
225
226
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the AmoebaStretchBendForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const AmoebaStretchBendForce& force);
227
228
229
230
private:
    class ForceInfo;
    int numStretchBends;
    CudaContext& cu;
231
    const System& system;
232
233
    CudaArray* params1; // Equilibrium values
    CudaArray* params2; // force constants
234
235
236
237
238
239
240
};

/**
 * This kernel is invoked by AmoebaOutOfPlaneBendForce to calculate the forces acting on the system and the energy of the system.
 */
class CudaCalcAmoebaOutOfPlaneBendForceKernel : public CalcAmoebaOutOfPlaneBendForceKernel {
public:
241
    CudaCalcAmoebaOutOfPlaneBendForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
    ~CudaCalcAmoebaOutOfPlaneBendForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the AmoebaOutOfPlaneBendForce this kernel will be used for
     */
    void initialize(const System& system, const AmoebaOutOfPlaneBendForce& force);
    /**
     * Execute the kernel to calculate the forces and/or energy.
     *
     * @param context        the context in which to execute this kernel
     * @param includeForces  true if forces should be calculated
     * @param includeEnergy  true if the energy should be calculated
     * @return the potential energy due to the force
     */
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
259
260
261
262
263
264
265
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the AmoebaOutOfPlaneBendForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const AmoebaOutOfPlaneBendForce& force);
266
267
268
269
private:
    class ForceInfo;
    int numOutOfPlaneBends;
    CudaContext& cu;
270
    const System& system;
271
    CudaArray* params;
272
273
274
275
276
277
278
};

/**
 * This kernel is invoked by AmoebaTorsionTorsionForce to calculate the forces acting on the system and the energy of the system.
 */
class CudaCalcAmoebaTorsionTorsionForceKernel : public CalcAmoebaTorsionTorsionForceKernel {
public:
279
    CudaCalcAmoebaTorsionTorsionForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
    ~CudaCalcAmoebaTorsionTorsionForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the AmoebaTorsionTorsionForce this kernel will be used for
     */
    void initialize(const System& system, const AmoebaTorsionTorsionForce& force);
    /**
     * Execute the kernel to calculate the forces and/or energy.
     *
     * @param context        the context in which to execute this kernel
     * @param includeForces  true if forces should be calculated
     * @param includeEnergy  true if the energy should be calculated
     * @return the potential energy due to the force
     */
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
private:
    class ForceInfo;
    int numTorsionTorsions;
    int numTorsionTorsionGrids;
    CudaContext& cu;
302
    const System& system;
303
304
305
    CudaArray* gridValues;
    CudaArray* gridParams;
    CudaArray* torsionParams;
306
307
308
309
310
311
312
};

/**
 * This kernel is invoked by AmoebaMultipoleForce to calculate the forces acting on the system and the energy of the system.
 */
class CudaCalcAmoebaMultipoleForceKernel : public CalcAmoebaMultipoleForceKernel {
public:
313
    CudaCalcAmoebaMultipoleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
    ~CudaCalcAmoebaMultipoleForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the AmoebaMultipoleForce this kernel will be used for
     */
    void initialize(const System& system, const AmoebaMultipoleForce& force);
    /**
     * Execute the kernel to calculate the forces and/or energy.
     *
     * @param context        the context in which to execute this kernel
     * @param includeForces  true if forces should be calculated
     * @param includeEnergy  true if the energy should be calculated
     * @return the potential energy due to the force
     */
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
331
332
333
334
335
336
     /**
     * Get the LabFrame dipole moments of all particles.
     * 
     * @param context    the Context for which to get the induced dipoles
     * @param dipoles    the induced dipole moment of particle i is stored into the i'th element
     */
337
    void getLabFramePermanentDipoles(ContextImpl& context, std::vector<Vec3>& dipoles);
338
339
340
341
342
343
344
    /**
     * Get the induced dipole moments of all particles.
     * 
     * @param context    the Context for which to get the induced dipoles
     * @param dipoles    the induced dipole moment of particle i is stored into the i'th element
     */
    void getInducedDipoles(ContextImpl& context, std::vector<Vec3>& dipoles);
345
346
347
348
349
350
351
352
    /**
     * Execute the kernel to calculate the electrostatic potential
     *
     * @param context        the context in which to execute this kernel
     * @param inputGrid      input grid coordinates
     * @param outputElectrostaticPotential output potential 
     */
    void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid,
353
                                   std::vector< double >& outputElectrostaticPotential);
354
355
356
357
358

   /** 
     * Get the system multipole moments
     *
     * @param context      context
359
360
361
362
     * @param outputMultipoleMoments (charge,
     *                                dipole_x, dipole_y, dipole_z,
     *                                quadrupole_xx, quadrupole_xy, quadrupole_xz,
     *                                quadrupole_yx, quadrupole_yy, quadrupole_yz,
363
     *                                quadrupole_zx, quadrupole_zy, quadrupole_zz)
364
     */
Lee-Ping Wang's avatar
Lee-Ping Wang committed
365
    void getSystemMultipoleMoments(ContextImpl& context, std::vector<double>& outputMultipoleMoments);
366
367
368
369
370
371
372
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the AmoebaMultipoleForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const AmoebaMultipoleForce& force);
373
374
375
376
377
378
379
380
381
    /**
     * Get the parameters being used for PME.
     * 
     * @param alpha   the separation parameter
     * @param nx      the number of grid points along the X axis
     * @param ny      the number of grid points along the Y axis
     * @param nz      the number of grid points along the Z axis
     */
    void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const;
382
383
private:
    class ForceInfo;
384
385
386
387
388
    class SortTrait : public CudaSort::SortTrait {
        int getDataSize() const {return 8;}
        int getKeySize() const {return 4;}
        const char* getDataType() const {return "int2";}
        const char* getKeyType() const {return "int";}
Robert McGibbon's avatar
Robert McGibbon committed
389
390
391
        const char* getMinKey() const {return "(-2147483647 - 1)";}
        const char* getMaxKey() const {return "2147483647";}
        const char* getMaxValue() const {return "make_int2(2147483647, 2147483647)";}
392
393
        const char* getSortKey() const {return "value.y";}
    };
394
    void initializeScaleFactors();
peastman's avatar
peastman committed
395
    bool iterateDipolesByDIIS(int iteration);
396
    void ensureMultipolesValid(ContextImpl& context);
Lee-Ping Wang's avatar
Lee-Ping Wang committed
397
    template <class T, class T4, class M4> void computeSystemMultipoleMoments(ContextImpl& context, std::vector<double>& outputMultipoleMoments);
398
    int numMultipoles, maxInducedIterations;
399
    int fixedFieldThreads, inducedFieldThreads, electrostaticsThreads;
400
401
402
    int gridSizeX, gridSizeY, gridSizeZ;
    double alpha, inducedEpsilon;
    bool usePME, hasQuadrupoles, hasInitializedScaleFactors, hasInitializedFFT, multipolesAreValid;
403
    CudaContext& cu;
404
    const System& system;
405
406
407
408
409
410
411
    std::vector<int3> covalentFlagValues;
    std::vector<int2> polarizationFlagValues;
    CudaArray* multipoleParticles;
    CudaArray* molecularDipoles;
    CudaArray* molecularQuadrupoles;
    CudaArray* labFrameDipoles;
    CudaArray* labFrameQuadrupoles;
412
413
    CudaArray* sphericalDipoles;
    CudaArray* sphericalQuadrupoles;
414
415
    CudaArray* fracDipoles;
    CudaArray* fracQuadrupoles;
416
417
    CudaArray* field;
    CudaArray* fieldPolar;
418
419
    CudaArray* inducedField;
    CudaArray* inducedFieldPolar;
420
    CudaArray* torque;
421
422
423
    CudaArray* dampingAndThole;
    CudaArray* inducedDipole;
    CudaArray* inducedDipolePolar;
424
    CudaArray* inducedDipoleErrors;
peastman's avatar
peastman committed
425
426
427
428
429
430
431
    CudaArray* prevDipoles;
    CudaArray* prevDipolesPolar;
    CudaArray* prevDipolesGk;
    CudaArray* prevDipolesGkPolar;
    CudaArray* prevErrors;
    CudaArray* diisMatrix;
    CudaArray* diisCoefficients;
432
433
434
435
436
437
438
439
440
441
442
443
    CudaArray* polarizability;
    CudaArray* covalentFlags;
    CudaArray* polarizationGroupFlags;
    CudaArray* pmeGrid;
    CudaArray* pmeBsplineModuliX;
    CudaArray* pmeBsplineModuliY;
    CudaArray* pmeBsplineModuliZ;
    CudaArray* pmeIgrid;
    CudaArray* pmePhi;
    CudaArray* pmePhid;
    CudaArray* pmePhip;
    CudaArray* pmePhidp;
444
    CudaArray* pmeCphi;
445
446
    CudaArray* pmeAtomRange;
    CudaArray* pmeAtomGridIndex;
447
    CudaArray* lastPositions;
448
449
    CudaSort* sort;
    cufftHandle fft;
450
    CUfunction computeMomentsKernel, recordInducedDipolesKernel, computeFixedFieldKernel, computeInducedFieldKernel, updateInducedFieldKernel, electrostaticsKernel, mapTorqueKernel;
451
452
    CUfunction pmeGridIndexKernel, pmeSpreadFixedMultipolesKernel, pmeSpreadInducedDipolesKernel, pmeFinishSpreadChargeKernel, pmeConvolutionKernel;
    CUfunction pmeFixedPotentialKernel, pmeInducedPotentialKernel, pmeFixedForceKernel, pmeInducedForceKernel, pmeRecordInducedFieldDipolesKernel, computePotentialKernel;
peastman's avatar
peastman committed
453
    CUfunction recordDIISDipolesKernel, buildMatrixKernel;
454
    CUfunction pmeTransformMultipolesKernel, pmeTransformPotentialKernel;
455
    CudaCalcAmoebaGeneralizedKirkwoodForceKernel* gkKernel;
456
    static const int PmeOrder = 5;
peastman's avatar
peastman committed
457
    static const int MaxPrevDIISDipoles = 20;
458
459
460
461
462
463
464
};

/**
 * This kernel is invoked by AmoebaMultipoleForce to calculate the forces acting on the system and the energy of the system.
 */
class CudaCalcAmoebaGeneralizedKirkwoodForceKernel : public CalcAmoebaGeneralizedKirkwoodForceKernel {
public:
465
    CudaCalcAmoebaGeneralizedKirkwoodForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
    ~CudaCalcAmoebaGeneralizedKirkwoodForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the AmoebaMultipoleForce this kernel will be used for
     */
    void initialize(const System& system, const AmoebaGeneralizedKirkwoodForce& force);
    /**
     * Execute the kernel to calculate the forces and/or energy.
     *
     * @param context        the context in which to execute this kernel
     * @param includeForces  true if forces should be calculated
     * @param includeEnergy  true if the energy should be calculated
     * @return the potential energy due to the force
     */
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
483
484
485
486
487
488
489
490
491
492
493
494
495
496
    /**
     * Perform the computation of Born radii.
     */
    void computeBornRadii();
    /**
     * Perform the final parts of the force/energy computation.
     */
    void finishComputation(CudaArray& torque, CudaArray& labFrameDipoles, CudaArray& labFrameQuadrupoles, CudaArray& inducedDipole, CudaArray& inducedDipolePolar, CudaArray& dampingAndThole, CudaArray& covalentFlags, CudaArray& polarizationGroupFlags);
    CudaArray* getBornRadii() {
        return bornRadii;
    }
    CudaArray* getField() {
        return field;
    }
497
498
499
500
501
502
    CudaArray* getInducedField() {
        return inducedField;
    }
    CudaArray* getInducedFieldPolar() {
        return inducedFieldPolar;
    }
503
504
505
506
507
508
    CudaArray* getInducedDipoles() {
        return inducedDipoleS;
    }
    CudaArray* getInducedDipolesPolar() {
        return inducedDipolePolarS;
    }
509
510
511
512
513
514
515
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the AmoebaGeneralizedKirkwoodForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const AmoebaGeneralizedKirkwoodForce& force);
516
517
518
private:
    class ForceInfo;
    CudaContext& cu;
519
    const System& system;
520
    bool includeSurfaceArea, hasInitializedKernels;
521
    int computeBornSumThreads, gkForceThreads, chainRuleThreads, ediffThreads;
522
    std::map<std::string, std::string> defines;
523
524
525
526
527
    CudaArray* params;
    CudaArray* bornSum;
    CudaArray* bornRadii;
    CudaArray* bornForce;
    CudaArray* field;
528
529
    CudaArray* inducedField;
    CudaArray* inducedFieldPolar;
530
531
    CudaArray* inducedDipoleS;
    CudaArray* inducedDipolePolarS;
532
    CUfunction computeBornSumKernel, reduceBornSumKernel, surfaceAreaKernel, gkForceKernel, chainRuleKernel, ediffKernel;
533
534
535
536
537
538
539
};

/**
 * This kernel is invoked to calculate the vdw forces acting on the system and the energy of the system.
 */
class CudaCalcAmoebaVdwForceKernel : public CalcAmoebaVdwForceKernel {
public:
540
    CudaCalcAmoebaVdwForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
    ~CudaCalcAmoebaVdwForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the AmoebaMultipoleForce this kernel will be used for
     */
    void initialize(const System& system, const AmoebaVdwForce& force);
    /**
     * Execute the kernel to calculate the forces and/or energy.
     *
     * @param context        the context in which to execute this kernel
     * @param includeForces  true if forces should be calculated
     * @param includeEnergy  true if the energy should be calculated
     * @return the potential energy due to the force
     */
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
558
559
560
561
562
563
564
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the AmoebaVdwForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const AmoebaVdwForce& force);
565
566
567
private:
    class ForceInfo;
    CudaContext& cu;
568
    const System& system;
569
    bool hasInitializedNonbonded;
570
    double dispersionCoefficient;
571
572
573
574
575
576
577
    CudaArray* sigmaEpsilon;
    CudaArray* bondReductionAtoms;
    CudaArray* bondReductionFactors;
    CudaArray* tempPosq;
    CudaArray* tempForces;
    CudaNonbondedUtilities* nonbonded;
    CUfunction prepareKernel, spreadKernel;
578
579
580
581
582
583
584
};

/**
 * This kernel is invoked to calculate the WCA dispersion forces acting on the system and the energy of the system.
 */
class CudaCalcAmoebaWcaDispersionForceKernel : public CalcAmoebaWcaDispersionForceKernel {
public:
585
    CudaCalcAmoebaWcaDispersionForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
    ~CudaCalcAmoebaWcaDispersionForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the AmoebaMultipoleForce this kernel will be used for
     */
    void initialize(const System& system, const AmoebaWcaDispersionForce& force);
    /**
     * Execute the kernel to calculate the forces and/or energy.
     *
     * @param context        the context in which to execute this kernel
     * @param includeForces  true if forces should be calculated
     * @param includeEnergy  true if the energy should be calculated
     * @return the potential energy due to the force
     */
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
603
604
605
606
607
608
609
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the AmoebaWcaDispersionForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const AmoebaWcaDispersionForce& force);
610
611
612
private:
    class ForceInfo;
    CudaContext& cu;
613
    const System& system;
614
615
616
    double totalMaximumDispersionEnergy;
    CudaArray* radiusEpsilon;
    CUfunction forceKernel;
617
618
619
620
621
};

} // namespace OpenMM

#endif /*AMOEBA_OPENMM_CUDAKERNELS_H*/