ReferenceKernels.h 39.4 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
#ifndef OPENMM_REFERENCEKERNELS_H_
#define OPENMM_REFERENCEKERNELS_H_

/* -------------------------------------------------------------------------- *
 *                                   OpenMM                                   *
 * -------------------------------------------------------------------------- *
 * 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-2009 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
34
 * Authors: Peter Eastman                                                     *
 * Contributors:                                                              *
 *                                                                            *
 * Permission is hereby granted, free of charge, to any person obtaining a    *
 * copy of this software and associated documentation files (the "Software"), *
 * to deal in the Software without restriction, including without limitation  *
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
 * and/or sell copies of the Software, and to permit persons to whom the      *
 * Software is furnished to do so, subject to the following conditions:       *
 *                                                                            *
 * The above copyright notice and this permission notice shall be included in *
 * all copies or substantial portions of the Software.                        *
 *                                                                            *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
 * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
 * -------------------------------------------------------------------------- */

35
#include "ReferencePlatform.h"
36
#include "openmm/kernels.h"
37
#include "SimTKUtilities/SimTKOpenMMRealType.h"
38
#include "SimTKReference/ReferenceNeighborList.h"
39
#include "lepton/ExpressionProgram.h"
40

41
class CpuObc;
Mark Friedrichs's avatar
Mark Friedrichs committed
42
class CpuGBVI;
43
class ReferenceAndersenThermostat;
44
class ReferenceCustomHbondIxn;
45
class ReferenceBrownianDynamics;
46
class ReferenceStochasticDynamics;
47
class ReferenceConstraintAlgorithm;
48
class ReferenceMonteCarloBarostat;
49
class ReferenceVariableStochasticDynamics;
50
class ReferenceVariableVerletDynamics;
51
class ReferenceVerletDynamics;
52

53
54
namespace OpenMM {

55
/**
56
57
58
 * This kernel is invoked at the beginning and end of force and energy computations.  It gives the
 * Platform a chance to clear buffers and do other initialization at the beginning, and to do any
 * necessary work at the end to determine the final results.
59
 */
60
class ReferenceCalcForcesAndEnergyKernel : public CalcForcesAndEnergyKernel {
61
public:
62
    ReferenceCalcForcesAndEnergyKernel(std::string name, const Platform& platform) : CalcForcesAndEnergyKernel(name, platform) {
63
64
65
66
67
68
69
70
    }
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     */
    void initialize(const System& system);
    /**
71
     * This is called at the beginning of each force/energy computation, before calcForcesAndEnergy() has been called on
72
73
     * any ForceImpl.
     *
74
75
76
     * @param context       the context in which to execute this kernel
     * @param includeForce  true if forces should be computed
     * @param includeEnergy true if potential energy should be computed
77
     */
78
    void beginComputation(ContextImpl& context, bool includeForce, bool includeEnergy);
79
    /**
80
     * This is called at the end of each force/energy computation, after calcForcesAndEnergy() has been called on
81
82
     * every ForceImpl.
     *
83
84
85
     * @param context       the context in which to execute this kernel
     * @param includeForce  true if forces should be computed
     * @param includeEnergy true if potential energy should be computed
86
     * @return the potential energy of the system.  This value is added to all values returned by ForceImpls'
87
     * calcForcesAndEnergy() methods.  That is, each force kernel may <i>either</i> return its contribution to the
88
     * energy directly, <i>or</i> add it to an internal buffer so that it will be included here.
89
     */
90
    double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy);
91
92
};

93
/**
94
95
 * This kernel provides methods for setting and retrieving various state data: time, positions,
 * velocities, and forces.
96
 */
97
class ReferenceUpdateStateDataKernel : public UpdateStateDataKernel {
98
public:
99
    ReferenceUpdateStateDataKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : UpdateStateDataKernel(name, platform), data(data) {
100
101
102
103
104
105
106
107
108
109
110
111
    }
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     */
    void initialize(const System& system);
    /**
     * Get the current time (in picoseconds).
     *
     * @param context    the context in which to execute this kernel
     */
112
    double getTime(const ContextImpl& context) const;
113
114
115
116
117
    /**
     * Set the current time (in picoseconds).
     *
     * @param context    the context in which to execute this kernel
     */
118
    void setTime(ContextImpl& context, double time);
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
    /**
     * Get the positions of all particles.
     *
     * @param positions  on exit, this contains the particle positions
     */
    void getPositions(ContextImpl& context, std::vector<Vec3>& positions);
    /**
     * Set the positions of all particles.
     *
     * @param positions  a vector containg the particle positions
     */
    void setPositions(ContextImpl& context, const std::vector<Vec3>& positions);
    /**
     * Get the velocities of all particles.
     *
     * @param velocities  on exit, this contains the particle velocities
     */
    void getVelocities(ContextImpl& context, std::vector<Vec3>& velocities);
    /**
     * Set the velocities of all particles.
     *
     * @param velocities  a vector containg the particle velocities
     */
    void setVelocities(ContextImpl& context, const std::vector<Vec3>& velocities);
    /**
     * Get the current forces on all particles.
     *
     * @param forces  on exit, this contains the forces
     */
    void getForces(ContextImpl& context, std::vector<Vec3>& forces);
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
    /**
     * Get the current periodic box vectors.
     *
     * @param a      on exit, this contains the vector defining the first edge of the periodic box
     * @param b      on exit, this contains the vector defining the second edge of the periodic box
     * @param c      on exit, this contains the vector defining the third edge of the periodic box
     */
    void getPeriodicBoxVectors(ContextImpl& context, Vec3& a, Vec3& b, Vec3& c) const;
    /**
     * Set the current periodic box vectors.
     *
     * @param a      the vector defining the first edge of the periodic box
     * @param b      the vector defining the second edge of the periodic box
     * @param c      the vector defining the third edge of the periodic box
     */
    void setPeriodicBoxVectors(ContextImpl& context, const Vec3& a, const Vec3& b, const Vec3& c) const;
165
166
167
168
private:
    ReferencePlatform::PlatformData& data;
};

169
170
171
172
173
174
/**
 * This kernel modifies the positions of particles to enforce distance constraints.
 */
class ReferenceApplyConstraintsKernel : public ApplyConstraintsKernel {
public:
    ReferenceApplyConstraintsKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) :
175
            ApplyConstraintsKernel(name, platform), data(data), constraints(0), constraintDistances(0), constraintIndices(0) {
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
    }
    ~ReferenceApplyConstraintsKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     */
    void initialize(const System& system);
    /**
     * Update particle positions to enforce constraints.
     *
     * @param context    the context in which to execute this kernel
     * @param tol        the distance tolerance within which constraints must be satisfied.
     */
    void apply(ContextImpl& context, double tol);
private:
    ReferencePlatform::PlatformData& data;
    ReferenceConstraintAlgorithm* constraints;
194
195
    std::vector<RealOpenMM> masses;
    std::vector<RealOpenMM> inverseMasses;
196
197
198
199
200
    RealOpenMM* constraintDistances;
    int** constraintIndices;
    int numConstraints;
};

201
/**
202
 * This kernel is invoked by HarmonicBondForce to calculate the forces acting on the system and the energy of the system.
203
 */
204
class ReferenceCalcHarmonicBondForceKernel : public CalcHarmonicBondForceKernel {
205
public:
206
    ReferenceCalcHarmonicBondForceKernel(std::string name, const Platform& platform) : CalcHarmonicBondForceKernel(name, platform) {
207
    }
208
    ~ReferenceCalcHarmonicBondForceKernel();
209
    /**
210
     * Initialize the kernel.
211
     * 
212
     * @param system     the System this kernel will be applied to
213
214
215
216
     * @param force      the HarmonicBondForce this kernel will be used for
     */
    void initialize(const System& system, const HarmonicBondForce& force);
    /**
217
218
219
220
221
222
     * 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
223
     */
224
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
225
226
227
228
229
230
private:
    int numBonds;
    int **bondIndexArray;
    RealOpenMM **bondParamArray;
};

231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/**
 * This kernel is invoked by CustomBondForce to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcCustomBondForceKernel : public CalcCustomBondForceKernel {
public:
    ReferenceCalcCustomBondForceKernel(std::string name, const Platform& platform) : CalcCustomBondForceKernel(name, platform) {
    }
    ~ReferenceCalcCustomBondForceKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the CustomBondForce this kernel will be used for
     */
    void initialize(const System& system, const CustomBondForce& force);
    /**
247
     * Execute the kernel to calculate the forces and/or energy.
248
     *
249
250
251
252
     * @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
253
     */
254
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
255
256
257
258
259
260
261
262
private:
    int numBonds;
    int **bondIndexArray;
    RealOpenMM **bondParamArray;
    Lepton::ExpressionProgram energyExpression, forceExpression;
    std::vector<std::string> parameterNames, globalParameterNames;
};

263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
/**
 * This kernel is invoked by HarmonicAngleForce to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcHarmonicAngleForceKernel : public CalcHarmonicAngleForceKernel {
public:
    ReferenceCalcHarmonicAngleForceKernel(std::string name, const Platform& platform) : CalcHarmonicAngleForceKernel(name, platform) {
    }
    ~ReferenceCalcHarmonicAngleForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the HarmonicAngleForce this kernel will be used for
     */
    void initialize(const System& system, const HarmonicAngleForce& force);
    /**
279
280
281
282
283
284
     * 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
285
     */
286
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
287
288
289
290
291
292
private:
    int numAngles;
    int **angleIndexArray;
    RealOpenMM **angleParamArray;
};

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
/**
 * This kernel is invoked by CustomAngleForce to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcCustomAngleForceKernel : public CalcCustomAngleForceKernel {
public:
    ReferenceCalcCustomAngleForceKernel(std::string name, const Platform& platform) : CalcCustomAngleForceKernel(name, platform) {
    }
    ~ReferenceCalcCustomAngleForceKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the CustomAngleForce this kernel will be used for
     */
    void initialize(const System& system, const CustomAngleForce& force);
    /**
309
     * Execute the kernel to calculate the forces and/or energy.
310
     *
311
312
313
314
     * @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
315
     */
316
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
317
318
319
320
321
322
323
324
private:
    int numAngles;
    int **angleIndexArray;
    RealOpenMM **angleParamArray;
    Lepton::ExpressionProgram energyExpression, forceExpression;
    std::vector<std::string> parameterNames, globalParameterNames;
};

325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
/**
 * This kernel is invoked by PeriodicTorsionForce to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcPeriodicTorsionForceKernel : public CalcPeriodicTorsionForceKernel {
public:
    ReferenceCalcPeriodicTorsionForceKernel(std::string name, const Platform& platform) : CalcPeriodicTorsionForceKernel(name, platform) {
    }
    ~ReferenceCalcPeriodicTorsionForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the PeriodicTorsionForce this kernel will be used for
     */
    void initialize(const System& system, const PeriodicTorsionForce& force);
    /**
341
342
343
344
345
346
     * 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
347
     */
348
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
private:
    int numTorsions;
    int **torsionIndexArray;
    RealOpenMM **torsionParamArray;
};

/**
 * This kernel is invoked by RBTorsionForce to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcRBTorsionForceKernel : public CalcRBTorsionForceKernel {
public:
    ReferenceCalcRBTorsionForceKernel(std::string name, const Platform& platform) : CalcRBTorsionForceKernel(name, platform) {
    }
    ~ReferenceCalcRBTorsionForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the RBTorsionForce this kernel will be used for
     */
    void initialize(const System& system, const RBTorsionForce& force);
    /**
371
372
373
374
375
376
     * 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
377
     */
378
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
379
380
381
382
383
384
private:
    int numTorsions;
    int **torsionIndexArray;
    RealOpenMM **torsionParamArray;
};

385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
/**
 * This kernel is invoked by CMAPTorsionForce to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcCMAPTorsionForceKernel : public CalcCMAPTorsionForceKernel {
public:
    ReferenceCalcCMAPTorsionForceKernel(std::string name, const Platform& platform) : CalcCMAPTorsionForceKernel(name, platform) {
    }
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the CMAPTorsionForce this kernel will be used for
     */
    void initialize(const System& system, const CMAPTorsionForce& force);
    /**
400
     * Execute the kernel to calculate the forces and/or energy.
401
     *
402
403
404
405
     * @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
406
     */
407
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
408
409
410
411
412
413
private:
    std::vector<std::vector<std::vector<RealOpenMM> > > coeff;
    std::vector<int> torsionMaps;
    std::vector<std::vector<int> > torsionIndices;
};

414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
/**
 * This kernel is invoked by CustomTorsionForce to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcCustomTorsionForceKernel : public CalcCustomTorsionForceKernel {
public:
    ReferenceCalcCustomTorsionForceKernel(std::string name, const Platform& platform) : CalcCustomTorsionForceKernel(name, platform) {
    }
    ~ReferenceCalcCustomTorsionForceKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the CustomTorsionForce this kernel will be used for
     */
    void initialize(const System& system, const CustomTorsionForce& force);
    /**
430
     * Execute the kernel to calculate the forces and/or energy.
431
     *
432
433
434
435
     * @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
436
     */
437
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
438
439
440
441
442
443
444
445
private:
    int numTorsions;
    int **torsionIndexArray;
    RealOpenMM **torsionParamArray;
    Lepton::ExpressionProgram energyExpression, forceExpression;
    std::vector<std::string> parameterNames, globalParameterNames;
};

446
447
448
449
450
451
452
453
454
455
456
457
458
/**
 * This kernel is invoked by NonbondedForce to calculate the forces acting on the system.
 */
class ReferenceCalcNonbondedForceKernel : public CalcNonbondedForceKernel {
public:
    ReferenceCalcNonbondedForceKernel(std::string name, const Platform& platform) : CalcNonbondedForceKernel(name, platform) {
    }
    ~ReferenceCalcNonbondedForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the NonbondedForce this kernel will be used for
459
     */
460
    void initialize(const System& system, const NonbondedForce& force);
461
    /**
462
463
464
465
466
467
     * 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
468
     */
469
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
470
private:
Peter Eastman's avatar
Peter Eastman committed
471
    int numParticles, num14;
472
    int **exclusionArray, **bonded14IndexArray;
Peter Eastman's avatar
Peter Eastman committed
473
    RealOpenMM **particleParamArray, **bonded14ParamArray;
474
    RealOpenMM nonbondedCutoff, rfDielectric, ewaldAlpha, dispersionCoefficient;
475
    int kmax[3], gridSize[3];
476
477
478
    std::vector<std::set<int> > exclusions;
    NonbondedMethod nonbondedMethod;
    NeighborList* neighborList;
479
480
};

481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
/**
 * This kernel is invoked by CustomNonbondedForce to calculate the forces acting on the system.
 */
class ReferenceCalcCustomNonbondedForceKernel : public CalcCustomNonbondedForceKernel {
public:
    ReferenceCalcCustomNonbondedForceKernel(std::string name, const Platform& platform) : CalcCustomNonbondedForceKernel(name, platform) {
    }
    ~ReferenceCalcCustomNonbondedForceKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the CustomNonbondedForce this kernel will be used for
     */
    void initialize(const System& system, const CustomNonbondedForce& force);
    /**
497
     * Execute the kernel to calculate the forces and/or energy.
498
     *
499
500
501
502
     * @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
503
     */
504
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
505
private:
506
507
508
    int numParticles;
    int **exclusionArray;
    RealOpenMM **particleParamArray;
509
510
511
    RealOpenMM nonbondedCutoff, periodicBoxSize[3];
    std::vector<std::set<int> > exclusions;
    Lepton::ExpressionProgram energyExpression, forceExpression;
512
    std::vector<std::string> parameterNames, globalParameterNames;
513
514
515
516
    NonbondedMethod nonbondedMethod;
    NeighborList* neighborList;
};

517
/**
518
 * This kernel is invoked by GBSAOBCForce to calculate the forces acting on the system.
519
 */
520
class ReferenceCalcGBSAOBCForceKernel : public CalcGBSAOBCForceKernel {
521
public:
522
    ReferenceCalcGBSAOBCForceKernel(std::string name, const Platform& platform) : CalcGBSAOBCForceKernel(name, platform) {
523
    }
524
    ~ReferenceCalcGBSAOBCForceKernel();
525
    /**
526
     * Initialize the kernel.
527
     * 
528
     * @param system     the System this kernel will be applied to
529
     * @param force      the GBSAOBCForce this kernel will be used for
530
     */
531
    void initialize(const System& system, const GBSAOBCForce& force);
532
    /**
533
534
535
536
537
538
     * 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
539
     */
540
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
541
542
543
private:
    CpuObc* obc;
    std::vector<RealOpenMM> charges;
544
    bool isPeriodic;
545
546
};

Mark Friedrichs's avatar
Mark Friedrichs committed
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
/**
 * This kernel is invoked by GBVIForce to calculate the forces acting on the system.
 */
class ReferenceCalcGBVIForceKernel : public CalcGBVIForceKernel {
public:
    ReferenceCalcGBVIForceKernel(std::string name, const Platform& platform) : CalcGBVIForceKernel(name, platform) {
    }
    ~ReferenceCalcGBVIForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system       the System this kernel will be applied to
     * @param force        the GBVIForce this kernel will be used for
     * @param scaled radii the scaled radii (Eq. 5 of Labute paper)
     */
    void initialize(const System& system, const GBVIForce& force, const std::vector<double> & scaledRadii);
    /**
564
565
566
567
568
569
     * 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
Mark Friedrichs's avatar
Mark Friedrichs committed
570
     */
571
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
Mark Friedrichs's avatar
Mark Friedrichs committed
572
573
574
private:
    CpuGBVI * gbvi;
    std::vector<RealOpenMM> charges;
575
    bool isPeriodic;
Mark Friedrichs's avatar
Mark Friedrichs committed
576
577
};

578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
/**
 * This kernel is invoked by CustomGBForce to calculate the forces acting on the system.
 */
class ReferenceCalcCustomGBForceKernel : public CalcCustomGBForceKernel {
public:
    ReferenceCalcCustomGBForceKernel(std::string name, const Platform& platform) : CalcCustomGBForceKernel(name, platform) {
    }
    ~ReferenceCalcCustomGBForceKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the CustomGBForce this kernel will be used for
     */
    void initialize(const System& system, const CustomGBForce& force);
    /**
594
     * Execute the kernel to calculate the forces and/or energy.
595
     *
596
597
598
599
     * @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
600
     */
601
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
602
603
private:
    int numParticles;
604
    bool isPeriodic;
605
    RealOpenMM **particleParamArray;
606
    RealOpenMM nonbondedCutoff;
607
608
609
    std::vector<std::set<int> > exclusions;
    std::vector<std::string> particleParameterNames, globalParameterNames, valueNames;
    std::vector<Lepton::ExpressionProgram> valueExpressions;
610
    std::vector<std::vector<Lepton::ExpressionProgram> > valueDerivExpressions;
611
    std::vector<std::vector<Lepton::ExpressionProgram> > valueGradientExpressions;
612
613
614
    std::vector<OpenMM::CustomGBForce::ComputationType> valueTypes;
    std::vector<Lepton::ExpressionProgram> energyExpressions;
    std::vector<std::vector<Lepton::ExpressionProgram> > energyDerivExpressions;
615
    std::vector<std::vector<Lepton::ExpressionProgram> > energyGradientExpressions;
616
617
618
619
620
    std::vector<OpenMM::CustomGBForce::ComputationType> energyTypes;
    NonbondedMethod nonbondedMethod;
    NeighborList* neighborList;
};

621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
/**
 * This kernel is invoked by CustomExternalForce to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcCustomExternalForceKernel : public CalcCustomExternalForceKernel {
public:
    ReferenceCalcCustomExternalForceKernel(std::string name, const Platform& platform) : CalcCustomExternalForceKernel(name, platform) {
    }
    ~ReferenceCalcCustomExternalForceKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the CustomExternalForce this kernel will be used for
     */
    void initialize(const System& system, const CustomExternalForce& force);
    /**
637
     * Execute the kernel to calculate the forces and/or energy.
638
     *
639
640
641
642
     * @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
643
     */
644
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
645
646
647
648
649
650
651
652
private:
    int numParticles;
    std::vector<int> particles;
    RealOpenMM **particleParamArray;
    Lepton::ExpressionProgram energyExpression, forceExpressionX, forceExpressionY, forceExpressionZ;
    std::vector<std::string> parameterNames, globalParameterNames;
};

653
654
655
656
657
/**
 * This kernel is invoked by CustomHbondForce to calculate the forces acting on the system.
 */
class ReferenceCalcCustomHbondForceKernel : public CalcCustomHbondForceKernel {
public:
658
    ReferenceCalcCustomHbondForceKernel(std::string name, const Platform& platform) : CalcCustomHbondForceKernel(name, platform), ixn(NULL) {
659
660
661
662
663
664
665
666
667
668
    }
    ~ReferenceCalcCustomHbondForceKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the CustomHbondForce this kernel will be used for
     */
    void initialize(const System& system, const CustomHbondForce& force);
    /**
669
     * Execute the kernel to calculate the forces and/or energy.
670
     *
671
672
673
674
     * @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
675
     */
676
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
677
678
private:
    int numDonors, numAcceptors, numParticles;
679
    bool isPeriodic;
680
681
    int **exclusionArray;
    RealOpenMM **donorParamArray, **acceptorParamArray;
682
    RealOpenMM nonbondedCutoff;
683
    ReferenceCustomHbondIxn* ixn;
684
    std::vector<std::set<int> > exclusions;
685
    std::vector<std::string> globalParameterNames;
686
687
};

688
689
690
691
692
/**
 * This kernel is invoked by VerletIntegrator to take one time step.
 */
class ReferenceIntegrateVerletStepKernel : public IntegrateVerletStepKernel {
public:
693
    ReferenceIntegrateVerletStepKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : IntegrateVerletStepKernel(name, platform),
694
        data(data), dynamics(0), constraints(0), constraintDistances(0), constraintIndices(0) {
695
    }
696
    ~ReferenceIntegrateVerletStepKernel();
697
    /**
698
     * Initialize the kernel.
699
     * 
700
701
     * @param system     the System this kernel will be applied to
     * @param integrator the VerletIntegrator this kernel will be used for
702
     */
703
    void initialize(const System& system, const VerletIntegrator& integrator);
704
705
706
    /**
     * Execute the kernel.
     * 
707
708
     * @param context    the context in which to execute this kernel
     * @param integrator the VerletIntegrator this kernel is being used for
709
     */
710
    void execute(ContextImpl& context, const VerletIntegrator& integrator);
711
private:
712
    ReferencePlatform::PlatformData& data;
713
    ReferenceVerletDynamics* dynamics;
714
    ReferenceConstraintAlgorithm* constraints;
715
    std::vector<RealOpenMM> masses;
716
    RealOpenMM* constraintDistances;
717
718
719
    int** constraintIndices;
    int numConstraints;
    double prevStepSize;
720
721
722
723
724
725
726
};

/**
 * This kernel is invoked by LangevinIntegrator to take one time step.
 */
class ReferenceIntegrateLangevinStepKernel : public IntegrateLangevinStepKernel {
public:
727
    ReferenceIntegrateLangevinStepKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : IntegrateLangevinStepKernel(name, platform),
728
        data(data), dynamics(0), constraints(0), constraintDistances(0), constraintIndices(0) {
729
    }
730
    ~ReferenceIntegrateLangevinStepKernel();
731
    /**
Peter Eastman's avatar
Peter Eastman committed
732
     * Initialize the kernel, setting up the particle masses.
733
     * 
734
735
     * @param system     the System this kernel will be applied to
     * @param integrator the LangevinIntegrator this kernel will be used for
736
     */
737
    void initialize(const System& system, const LangevinIntegrator& integrator);
738
739
740
    /**
     * Execute the kernel.
     * 
741
742
     * @param context    the context in which to execute this kernel
     * @param integrator the LangevinIntegrator this kernel is being used for
743
     */
744
    void execute(ContextImpl& context, const LangevinIntegrator& integrator);
745
private:
746
    ReferencePlatform::PlatformData& data;
747
    ReferenceStochasticDynamics* dynamics;
748
    ReferenceConstraintAlgorithm* constraints;
749
    std::vector<RealOpenMM> masses;
750
    RealOpenMM* constraintDistances;
751
752
753
    int** constraintIndices;
    int numConstraints;
    double prevTemp, prevFriction, prevStepSize;
754
755
756
757
758
759
760
};

/**
 * This kernel is invoked by BrownianIntegrator to take one time step.
 */
class ReferenceIntegrateBrownianStepKernel : public IntegrateBrownianStepKernel {
public:
761
    ReferenceIntegrateBrownianStepKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : IntegrateBrownianStepKernel(name, platform),
762
        data(data), dynamics(0), constraints(0), constraintDistances(0), constraintIndices(0) {
763
    }
764
    ~ReferenceIntegrateBrownianStepKernel();
765
    /**
766
     * Initialize the kernel.
767
     * 
768
769
     * @param system     the System this kernel will be applied to
     * @param integrator the BrownianIntegrator this kernel will be used for
770
     */
771
    void initialize(const System& system, const BrownianIntegrator& integrator);
772
773
774
    /**
     * Execute the kernel.
     * 
775
776
     * @param context    the context in which to execute this kernel
     * @param integrator the BrownianIntegrator this kernel is being used for
777
     */
778
    void execute(ContextImpl& context, const BrownianIntegrator& integrator);
779
private:
780
    ReferencePlatform::PlatformData& data;
781
    ReferenceBrownianDynamics* dynamics;
782
    ReferenceConstraintAlgorithm* constraints;
783
    std::vector<RealOpenMM> masses;
784
    RealOpenMM* constraintDistances;
785
786
787
    int** constraintIndices;
    int numConstraints;
    double prevTemp, prevFriction, prevStepSize;
788
789
};

790
791
792
793
794
795
/**
 * This kernel is invoked by VariableLangevinIntegrator to take one time step.
 */
class ReferenceIntegrateVariableLangevinStepKernel : public IntegrateVariableLangevinStepKernel {
public:
    ReferenceIntegrateVariableLangevinStepKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : IntegrateVariableLangevinStepKernel(name, platform),
796
        data(data), dynamics(0), constraints(0), constraintDistances(0), constraintIndices(0) {
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
    }
    ~ReferenceIntegrateVariableLangevinStepKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param integrator the LangevinIntegrator this kernel will be used for
     */
    void initialize(const System& system, const VariableLangevinIntegrator& integrator);
    /**
     * Execute the kernel.
     *
     * @param context    the context in which to execute this kernel
     * @param integrator the LangevinIntegrator this kernel is being used for
     * @param maxTime    the maximum time beyond which the simulation should not be advanced
     */
813
    void execute(ContextImpl& context, const VariableLangevinIntegrator& integrator, double maxTime);
814
815
816
817
private:
    ReferencePlatform::PlatformData& data;
    ReferenceVariableStochasticDynamics* dynamics;
    ReferenceConstraintAlgorithm* constraints;
818
    std::vector<RealOpenMM> masses;
819
820
821
822
823
824
    RealOpenMM* constraintDistances;
    int** constraintIndices;
    int numConstraints;
    double prevTemp, prevFriction, prevErrorTol;
};

825
826
827
828
829
830
/**
 * This kernel is invoked by VariableVerletIntegrator to take one time step.
 */
class ReferenceIntegrateVariableVerletStepKernel : public IntegrateVariableVerletStepKernel {
public:
    ReferenceIntegrateVariableVerletStepKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : IntegrateVariableVerletStepKernel(name, platform),
831
        data(data), dynamics(0), constraints(0), constraintDistances(0), constraintIndices(0) {
832
833
834
835
836
837
838
839
840
841
842
843
844
845
    }
    ~ReferenceIntegrateVariableVerletStepKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param integrator the VerletIntegrator this kernel will be used for
     */
    void initialize(const System& system, const VariableVerletIntegrator& integrator);
    /**
     * Execute the kernel.
     *
     * @param context    the context in which to execute this kernel
     * @param integrator the VerletIntegrator this kernel is being used for
846
     * @param maxTime    the maximum time beyond which the simulation should not be advanced
847
     */
848
    void execute(ContextImpl& context, const VariableVerletIntegrator& integrator, double maxTime);
849
850
851
852
private:
    ReferencePlatform::PlatformData& data;
    ReferenceVariableVerletDynamics* dynamics;
    ReferenceConstraintAlgorithm* constraints;
853
    std::vector<RealOpenMM> masses;
854
855
856
    RealOpenMM* constraintDistances;
    int** constraintIndices;
    int numConstraints;
857
    double prevErrorTol;
858
859
};

860
/**
Peter Eastman's avatar
Peter Eastman committed
861
 * This kernel is invoked by AndersenThermostat at the start of each time step to adjust the particle velocities.
862
863
864
 */
class ReferenceApplyAndersenThermostatKernel : public ApplyAndersenThermostatKernel {
public:
865
    ReferenceApplyAndersenThermostatKernel(std::string name, const Platform& platform) : ApplyAndersenThermostatKernel(name, platform), thermostat(0) {
866
    }
867
    ~ReferenceApplyAndersenThermostatKernel();
868
    /**
869
     * Initialize the kernel.
870
     * 
871
872
     * @param system     the System this kernel will be applied to
     * @param thermostat the AndersenThermostat this kernel will be used for
873
     */
874
    void initialize(const System& system, const AndersenThermostat& thermostat);
875
876
877
    /**
     * Execute the kernel.
     * 
878
     * @param context    the context in which to execute this kernel
879
     */
880
    void execute(ContextImpl& context);
881
882
private:
    ReferenceAndersenThermostat* thermostat;
883
    std::vector<std::vector<int> > particleGroups;
884
    std::vector<RealOpenMM> masses;
885
886
};

887
888
889
890
891
/**
 * This kernel is invoked by MonteCarloBarostat to adjust the periodic box volume
 */
class ReferenceApplyMonteCarloBarostatKernel : public ApplyMonteCarloBarostatKernel {
public:
892
    ReferenceApplyMonteCarloBarostatKernel(std::string name, const Platform& platform) : ApplyMonteCarloBarostatKernel(name, platform), barostat(NULL) {
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
    }
    ~ReferenceApplyMonteCarloBarostatKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param barostat   the MonteCarloBarostat this kernel will be used for
     */
    void initialize(const System& system, const MonteCarloBarostat& barostat);
    /**
     * Attempt a Monte Carlo step, scaling particle positions (or cluster centers) by a specified value.
     * This is called BEFORE the periodic box size is modified.  It should begin by translating each particle
     * or cluster into the first periodic box, so that coordinates will still be correct after the box size
     * is changed.
     *
     * @param context    the context in which to execute this kernel
     * @param scale      the scale factor by which to multiply particle positions
     */
    void scaleCoordinates(ContextImpl& context, double scale);
    /**
     * Reject the most recent Monte Carlo step, restoring the particle positions to where they were before
     * scaleCoordinates() was last called.
     *
     * @param context    the context in which to execute this kernel
     */
    void restoreCoordinates(ContextImpl& context);
private:
    ReferenceMonteCarloBarostat* barostat;
};

923
924
925
926
927
/**
 * This kernel is invoked to calculate the kinetic energy of the system.
 */
class ReferenceCalcKineticEnergyKernel : public CalcKineticEnergyKernel {
public:
928
    ReferenceCalcKineticEnergyKernel(std::string name, const Platform& platform) : CalcKineticEnergyKernel(name, platform) {
929
930
    }
    /**
931
     * Initialize the kernel.
932
     * 
933
     * @param system     the System this kernel will be applied to
934
     */
935
    void initialize(const System& system);
936
937
938
    /**
     * Execute the kernel.
     * 
939
     * @param context    the context in which to execute this kernel
940
     */
941
    double execute(ContextImpl& context);
942
943
private:
    std::vector<double> masses;
944
945
};

946
947
948
949
950
/**
 * This kernel is invoked to remove center of mass motion from the system.
 */
class ReferenceRemoveCMMotionKernel : public RemoveCMMotionKernel {
public:
951
    ReferenceRemoveCMMotionKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : RemoveCMMotionKernel(name, platform), data(data) {
952
953
    }
    /**
Peter Eastman's avatar
Peter Eastman committed
954
     * Initialize the kernel, setting up the particle masses.
955
     * 
956
957
     * @param system     the System this kernel will be applied to
     * @param force      the CMMotionRemover this kernel will be used for
958
     */
959
    void initialize(const System& system, const CMMotionRemover& force);
960
961
962
    /**
     * Execute the kernel.
     * 
963
     * @param context    the context in which to execute this kernel
964
     */
965
    void execute(ContextImpl& context);
966
private:
967
    ReferencePlatform::PlatformData& data;
968
    std::vector<double> masses;
969
    int frequency;
970
971
};

972
973
974
} // namespace OpenMM

#endif /*OPENMM_REFERENCEKERNELS_H_*/