"openmmapi/include/Integrator.h" did not exist on "0e879806cdd38e58b04481ecf7fcd93c44c7dc27"
ReferenceKernels.h 80.9 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-2025 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 "openmm/internal/CustomCPPForceImpl.h"
38
#include "openmm/internal/CustomNonbondedForceImpl.h"
39
#include "openmm/internal/windowsExport.h"
40
41
#include "SimTKOpenMMRealType.h"
#include "ReferenceNeighborList.h"
42
#include "lepton/CompiledExpression.h"
43
#include "lepton/CustomFunction.h"
44
45
#include <array>
#include <utility>
46

47
48
namespace OpenMM {

49
class ReferenceObc;
50
class ReferenceAndersenThermostat;
51
class ReferenceLangevinMiddleDynamics;
52
53
54
55
class ReferenceCustomBondIxn;
class ReferenceCustomAngleIxn;
class ReferenceCustomTorsionIxn;
class ReferenceCustomExternalIxn;
56
class ReferenceCustomCentroidBondIxn;
57
class ReferenceCustomCompoundBondIxn;
58
class ReferenceCustomCVForce;
59
class ReferenceCustomHbondIxn;
60
class ReferenceCustomManyParticleIxn;
61
class ReferenceGayBerneForce;
62
class ReferenceBrownianDynamics;
63
class ReferenceConstraintAlgorithm;
64
class ReferenceNoseHooverChain;
65
class ReferenceMonteCarloBarostat;
66
class ReferenceNoseHooverDynamics;
67
class ReferenceVariableStochasticDynamics;
68
class ReferenceVariableVerletDynamics;
69
class ReferenceVerletDynamics;
70
class ReferenceCustomDynamics;
Peter Eastman's avatar
Peter Eastman committed
71
class ReferenceDPDDynamics;
72
class ReferenceQTBDynamics;
73

74
/**
75
76
77
 * 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.
78
 */
79
class ReferenceCalcForcesAndEnergyKernel : public CalcForcesAndEnergyKernel {
80
public:
81
    ReferenceCalcForcesAndEnergyKernel(std::string name, const Platform& platform) : CalcForcesAndEnergyKernel(name, platform) {
82
83
84
85
86
87
88
89
    }
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     */
    void initialize(const System& system);
    /**
90
     * This is called at the beginning of each force/energy computation, before calcForcesAndEnergy() has been called on
91
92
     * any ForceImpl.
     *
93
94
95
     * @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
96
     * @param groups        a set of bit flags for which force groups to include
97
     */
98
    void beginComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups);
99
    /**
100
     * This is called at the end of each force/energy computation, after calcForcesAndEnergy() has been called on
101
102
     * every ForceImpl.
     *
103
104
105
     * @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
106
     * @param groups        a set of bit flags for which force groups to include
107
108
     * @param valid         the method may set this to false to indicate the results are invalid and the force/energy
     *                      calculation should be repeated
109
     * @return the potential energy of the system.  This value is added to all values returned by ForceImpls'
110
     * calcForcesAndEnergy() methods.  That is, each force kernel may <i>either</i> return its contribution to the
111
     * energy directly, <i>or</i> add it to an internal buffer so that it will be included here.
112
     */
113
    double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups, bool& valid);
114
private:
peastman's avatar
peastman committed
115
    std::vector<Vec3> savedForces;
116
117
};

118
/**
119
120
 * This kernel provides methods for setting and retrieving various state data: time, positions,
 * velocities, and forces.
121
 */
122
class OPENMM_EXPORT ReferenceUpdateStateDataKernel : public UpdateStateDataKernel {
123
public:
124
    ReferenceUpdateStateDataKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : UpdateStateDataKernel(name, platform), data(data) {
125
126
127
128
129
130
131
132
133
134
135
136
    }
    /**
     * 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
     */
137
    double getTime(const ContextImpl& context) const;
138
139
140
141
142
    /**
     * Set the current time (in picoseconds).
     *
     * @param context    the context in which to execute this kernel
     */
143
    void setTime(ContextImpl& context, double time);
144
145
146
147
148
149
150
151
152
153
154
155
    /**
     * Get the current step count
     *
     * @param context    the context in which to execute this kernel
     */
    long long getStepCount(const ContextImpl& context) const;
    /**
     * Set the current step count
     *
     * @param context    the context in which to execute this kernel
     */
    void setStepCount(const ContextImpl& context, long long count);
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
    /**
     * 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);
180
181
182
183
184
185
186
187
188
    /**
     * Compute velocities, shifted in time to account for a leapfrog integrator.  The shift
     * is based on the most recently computed forces.
     * 
     * @param context     the context in which to execute this kernel
     * @param timeShift   the amount by which to shift the velocities in time
     * @param velocities  the shifted velocities are returned in this
     */
    void computeShiftedVelocities(ContextImpl& context, double timeShift, std::vector<Vec3>& velocities);
189
190
191
192
193
194
    /**
     * Get the current forces on all particles.
     *
     * @param forces  on exit, this contains the forces
     */
    void getForces(ContextImpl& context, std::vector<Vec3>& forces);
195
196
197
198
199
200
    /**
     * Get the current derivatives of the energy with respect to context parameters.
     *
     * @param derivs  on exit, this contains the derivatives
     */
    void getEnergyParameterDerivatives(ContextImpl& context, std::map<std::string, double>& derivs);
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
    /**
     * 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
     */
216
    void setPeriodicBoxVectors(ContextImpl& context, const Vec3& a, const Vec3& b, const Vec3& c);
Peter Eastman's avatar
Peter Eastman committed
217
218
219
220
221
222
223
224
225
226
227
228
    /**
     * Create a checkpoint recording the current state of the Context.
     * 
     * @param stream    an output stream the checkpoint data should be written to
     */
    void createCheckpoint(ContextImpl& context, std::ostream& stream);
    /**
     * Load a checkpoint that was written by createCheckpoint().
     * 
     * @param stream    an input stream the checkpoint data should be read from
     */
    void loadCheckpoint(ContextImpl& context, std::istream& stream);
229
230
private:
    ReferencePlatform::PlatformData& data;
231
    std::vector<double> masses;
232
233
};

234
235
236
237
238
239
/**
 * 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) :
240
            ApplyConstraintsKernel(name, platform), data(data) {
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
    }
    ~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);
256
257
258
259
260
261
262
    /**
     * Update particle velocities to enforce constraints.
     *
     * @param context    the context in which to execute this kernel
     * @param tol        the velocity tolerance within which constraints must be satisfied.
     */
    void applyToVelocities(ContextImpl& context, double tol);
263
264
private:
    ReferencePlatform::PlatformData& data;
peastman's avatar
peastman committed
265
266
    std::vector<double> masses;
    std::vector<double> inverseMasses;
267
268
};

269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
/**
 * This kernel recomputes the positions of virtual sites.
 */
class ReferenceVirtualSitesKernel : public VirtualSitesKernel {
public:
    ReferenceVirtualSitesKernel(std::string name, const Platform& platform) : VirtualSitesKernel(name, platform) {
    }
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     */
    void initialize(const System& system);
    /**
     * Compute the virtual site locations.
     *
     * @param context    the context in which to execute this kernel
     */
    void computePositions(ContextImpl& context);
};

290
/**
291
 * This kernel is invoked by HarmonicBondForce to calculate the forces acting on the system and the energy of the system.
292
 */
293
class ReferenceCalcHarmonicBondForceKernel : public CalcHarmonicBondForceKernel {
294
public:
295
    ReferenceCalcHarmonicBondForceKernel(std::string name, const Platform& platform) : CalcHarmonicBondForceKernel(name, platform) {
296
297
    }
    /**
298
     * Initialize the kernel.
299
     * 
300
     * @param system     the System this kernel will be applied to
301
302
303
304
     * @param force      the HarmonicBondForce this kernel will be used for
     */
    void initialize(const System& system, const HarmonicBondForce& force);
    /**
305
306
307
308
309
310
     * 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
311
     */
312
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
313
314
315
316
317
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the HarmonicBondForce to copy the parameters from
318
319
     * @param firstBond  the index of the first bond whose parameters might have changed
     * @param lastBond   the index of the last bond whose parameters might have changed
320
     */
321
    void copyParametersToContext(ContextImpl& context, const HarmonicBondForce& force, int firstBond, int lastBond);
322
323
private:
    int numBonds;
324
325
    std::vector<std::vector<int> >bondIndexArray;
    std::vector<std::vector<double> >bondParamArray;
326
    bool usePeriodic;
327
328
};

329
330
331
332
333
/**
 * 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:
334
    ReferenceCalcCustomBondForceKernel(std::string name, const Platform& platform) : CalcCustomBondForceKernel(name, platform), ixn(NULL) {
335
    }
336
    ~ReferenceCalcCustomBondForceKernel();
337
338
339
340
341
342
343
344
    /**
     * 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);
    /**
345
     * Execute the kernel to calculate the forces and/or energy.
346
     *
347
348
349
350
     * @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
351
     */
352
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
353
354
355
    /**
     * Copy changed parameters over to a context.
     *
356
357
     * @param firstBond  the index of the first bond whose parameters might have changed
     * @param lastBond   the index of the last bond whose parameters might have changed
358
     */
359
    void copyParametersToContext(ContextImpl& context, const CustomBondForce& force, int firstBond, int lastBond);
360
361
private:
    int numBonds;
362
    ReferenceCustomBondIxn* ixn;
363
364
    std::vector<std::vector<int> >bondIndexArray;
    std::vector<std::vector<double> >bondParamArray;
365
    Lepton::CompiledExpression energyExpression, forceExpression;
366
367
    std::vector<Lepton::CompiledExpression> energyParamDerivExpressions;
    std::vector<std::string> parameterNames, globalParameterNames, energyParamDerivNames;
368
    bool usePeriodic;
369
370
};

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
/**
 * 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) {
    }
    /**
     * 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);
    /**
386
387
388
389
390
391
     * 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
392
     */
393
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
394
395
396
    /**
     * Copy changed parameters over to a context.
     *
397
398
     * @param firstAngle the index of the first bond whose parameters might have changed
     * @param lastAngle  the index of the last bond whose parameters might have changed
399
     */
400
    void copyParametersToContext(ContextImpl& context, const HarmonicAngleForce& force, int firstAngle, int lastAngle);
401
402
private:
    int numAngles;
403
404
    std::vector<std::vector<int> >angleIndexArray;
    std::vector<std::vector<double> >angleParamArray;
405
    bool usePeriodic;
406
407
};

408
409
410
411
412
/**
 * 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:
413
    ReferenceCalcCustomAngleForceKernel(std::string name, const Platform& platform) : CalcCustomAngleForceKernel(name, platform), ixn(NULL) {
414
    }
415
    ~ReferenceCalcCustomAngleForceKernel();
416
417
418
419
420
421
422
423
    /**
     * 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);
    /**
424
     * Execute the kernel to calculate the forces and/or energy.
425
     *
426
427
428
429
     * @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
430
     */
431
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
432
433
434
    /**
     * Copy changed parameters over to a context.
     *
435
436
     * @param firstAngle the index of the first bond whose parameters might have changed
     * @param lastAngle  the index of the last bond whose parameters might have changed
437
     */
438
    void copyParametersToContext(ContextImpl& context, const CustomAngleForce& force, int firstAngle, int lastAngle);
439
440
private:
    int numAngles;
441
    ReferenceCustomAngleIxn* ixn;
442
443
    std::vector<std::vector<int> >angleIndexArray;
    std::vector<std::vector<double> >angleParamArray;
444
    Lepton::CompiledExpression energyExpression, forceExpression;
445
446
    std::vector<Lepton::CompiledExpression> energyParamDerivExpressions;
    std::vector<std::string> parameterNames, globalParameterNames, energyParamDerivNames;
447
    bool usePeriodic;
448
449
};

450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
/**
 * 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) {
    }
    /**
     * 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);
    /**
465
466
467
468
469
470
     * 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
471
     */
472
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
473
474
475
    /**
     * Copy changed parameters over to a context.
     *
476
477
478
479
     * @param context      the context to copy parameters to
     * @param force        the PeriodicTorsionForce to copy the parameters from
     * @param firstTorsion the index of the first torsion whose parameters might have changed
     * @param lastTorsion  the index of the last torsion whose parameters might have changed
480
     */
481
    void copyParametersToContext(ContextImpl& context, const PeriodicTorsionForce& force, int firstTorsion, int lastTorsion);
482
483
private:
    int numTorsions;
484
485
    std::vector<std::vector<int> >torsionIndexArray;
    std::vector<std::vector<double> >torsionParamArray;
486
    bool usePeriodic;
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
};

/**
 * 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) {
    }
    /**
     * 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);
    /**
504
505
506
507
508
509
     * 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
510
     */
511
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
512
513
514
515
516
517
518
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the RBTorsionForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const RBTorsionForce& force);
519
520
private:
    int numTorsions;
521
522
    std::vector<std::vector<int> >torsionIndexArray;
    std::vector<std::vector<double> >torsionParamArray;
523
    bool usePeriodic;
524
525
};

526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
/**
 * 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);
    /**
541
     * Execute the kernel to calculate the forces and/or energy.
542
     *
543
544
545
546
     * @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
547
     */
548
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
549
550
551
552
553
554
555
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the CMAPTorsionForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const CMAPTorsionForce& force);
556
private:
peastman's avatar
peastman committed
557
    std::vector<std::vector<std::vector<double> > > coeff;
558
559
    std::vector<int> torsionMaps;
    std::vector<std::vector<int> > torsionIndices;
560
    bool usePeriodic;
561
562
};

563
564
565
566
567
/**
 * 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:
568
    ReferenceCalcCustomTorsionForceKernel(std::string name, const Platform& platform) : CalcCustomTorsionForceKernel(name, platform), ixn(NULL) {
569
    }
570
    ~ReferenceCalcCustomTorsionForceKernel();
571
572
573
574
575
576
577
578
    /**
     * 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);
    /**
579
     * Execute the kernel to calculate the forces and/or energy.
580
     *
581
582
583
584
     * @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
585
     */
586
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
587
588
589
    /**
     * Copy changed parameters over to a context.
     *
590
591
592
593
     * @param context      the context to copy parameters to
     * @param force        the CustomTorsionForce to copy the parameters from
     * @param firstTorsion the index of the first torsion whose parameters might have changed
     * @param lastTorsion  the index of the last torsion whose parameters might have changed
594
     */
595
    void copyParametersToContext(ContextImpl& context, const CustomTorsionForce& force, int firstTorsion, int lastTorsion);
596
597
private:
    int numTorsions;
598
    ReferenceCustomTorsionIxn* ixn;
599
600
    std::vector<std::vector<int> >torsionIndexArray;
    std::vector<std::vector<double> >torsionParamArray;
601
    Lepton::CompiledExpression energyExpression, forceExpression;
602
603
    std::vector<Lepton::CompiledExpression> energyParamDerivExpressions;
    std::vector<std::string> parameterNames, globalParameterNames, energyParamDerivNames;
604
    bool usePeriodic;
605
606
};

607
608
609
610
611
612
613
614
615
616
617
618
619
/**
 * 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
620
     */
621
    void initialize(const System& system, const NonbondedForce& force);
622
    /**
623
624
625
626
627
     * 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
628
     * @param includeReciprocal  true if reciprocal space interactions should be included
629
     * @return the potential energy due to the force
630
     */
631
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy, bool includeDirect, bool includeReciprocal);
632
633
634
    /**
     * Copy changed parameters over to a context.
     *
635
636
637
638
639
640
     * @param context        the context to copy parameters to
     * @param force          the NonbondedForce to copy the parameters from
     * @param firstParticle  the index of the first particle whose parameters might have changed
     * @param lastParticle   the index of the last particle whose parameters might have changed
     * @param firstException the index of the first exception whose parameters might have changed
     * @param lastException  the index of the last exception whose parameters might have changed
641
     */
642
    void copyParametersToContext(ContextImpl& context, const NonbondedForce& force, int firstParticle, int lastParticle, int firstException, int lastException);
643
644
645
646
647
648
649
650
651
    /**
     * 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;
652
653
654
    /**
     * Get the dispersion parameters being used for the dispersion term in LJPME.
     *
655
656
657
658
     * @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
659
     */
660
    void getLJPMEParameters(double& alpha, int& nx, int& ny, int& nz) const;
661
private:
662
    void computeParameters(ContextImpl& context);
Peter Eastman's avatar
Peter Eastman committed
663
    int numParticles, num14;
664
665
    std::vector<std::vector<int> >bonded14IndexArray;
    std::vector<std::vector<double> > particleParamArray, bonded14ParamArray;
666
667
    std::vector<std::array<double, 3> > baseParticleParams, baseExceptionParams;
    std::map<std::pair<std::string, int>, std::array<double, 3> > particleParamOffsets, exceptionParamOffsets;
668
    std::map<int, int> nb14Index;
peastman's avatar
peastman committed
669
    double nonbondedCutoff, switchingDistance, rfDielectric, ewaldAlpha, ewaldDispersionAlpha, dispersionCoefficient;
670
    int kmax[3], gridSize[3], dispersionGridSize[3];
671
    bool useSwitchingFunction, exceptionsArePeriodic;
672
673
674
    std::vector<std::set<int> > exclusions;
    NonbondedMethod nonbondedMethod;
    NeighborList* neighborList;
675
676
};

677
678
679
680
681
/**
 * This kernel is invoked by CustomNonbondedForce to calculate the forces acting on the system.
 */
class ReferenceCalcCustomNonbondedForceKernel : public CalcCustomNonbondedForceKernel {
public:
682
    ReferenceCalcCustomNonbondedForceKernel(std::string name, const Platform& platform) : CalcCustomNonbondedForceKernel(name, platform), forceCopy(NULL) {
683
684
685
686
687
688
689
690
691
692
    }
    ~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);
    /**
693
     * Execute the kernel to calculate the forces and/or energy.
694
     *
695
696
697
698
     * @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
699
     */
700
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
701
702
703
704
705
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the CustomNonbondedForce to copy the parameters from
706
707
     * @param firstParticle  the index of the first particle whose parameters might have changed
     * @param lastParticle   the index of the last particle whose parameters might have changed
708
     */
709
    void copyParametersToContext(ContextImpl& context, const CustomNonbondedForce& force, int firstParticle, int lastParticle);
710
private:
711
    void createExpressions(const CustomNonbondedForce& force);
712
    int numParticles;
713
    std::vector<std::vector<double> > particleParamArray;
peastman's avatar
peastman committed
714
    double nonbondedCutoff, switchingDistance, periodicBoxSize[3], longRangeCoefficient;
715
    bool useSwitchingFunction, hasInitializedLongRangeCorrection;
716
    CustomNonbondedForce* forceCopy;
717
    CustomNonbondedForceImpl::LongRangeCorrectionData longRangeCorrectionData;
718
    std::map<std::string, double> globalParamValues;
719
    std::vector<std::set<int> > exclusions;
720
    Lepton::CompiledExpression energyExpression, forceExpression;
721
722
    std::vector<Lepton::CompiledExpression> computedValueExpressions, energyParamDerivExpressions;
    std::vector<std::string> parameterNames, globalParameterNames, computedValueNames, energyParamDerivNames;
723
    std::vector<std::pair<std::set<int>, std::set<int> > > interactionGroups;
724
    std::vector<double> longRangeCoefficientDerivs;
725
    std::map<std::string, int> tabulatedFunctionUpdateCount;
726
727
728
729
    NonbondedMethod nonbondedMethod;
    NeighborList* neighborList;
};

730
/**
731
 * This kernel is invoked by GBSAOBCForce to calculate the forces acting on the system.
732
 */
733
class ReferenceCalcGBSAOBCForceKernel : public CalcGBSAOBCForceKernel {
734
public:
735
    ReferenceCalcGBSAOBCForceKernel(std::string name, const Platform& platform) : CalcGBSAOBCForceKernel(name, platform) {
736
    }
737
    ~ReferenceCalcGBSAOBCForceKernel();
738
    /**
739
     * Initialize the kernel.
740
     * 
741
     * @param system     the System this kernel will be applied to
742
     * @param force      the GBSAOBCForce this kernel will be used for
743
     */
744
    void initialize(const System& system, const GBSAOBCForce& force);
745
    /**
746
747
748
749
750
751
     * 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
752
     */
753
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
754
755
756
757
758
759
760
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the GBSAOBCForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const GBSAOBCForce& force);
761
private:
762
    ReferenceObc* obc;
peastman's avatar
peastman committed
763
    std::vector<double> charges;
764
    bool isPeriodic;
765
766
};

767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
/**
 * 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);
    /**
783
     * Execute the kernel to calculate the forces and/or energy.
784
     *
785
786
787
788
     * @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
789
     */
790
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
791
792
793
794
795
796
797
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the CustomGBForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const CustomGBForce& force);
798
private:
799
    void createExpressions(const CustomGBForce& force);
800
    int numParticles;
801
    bool isPeriodic;
802
    std::vector<std::vector<double> > particleParamArray;
peastman's avatar
peastman committed
803
    double nonbondedCutoff;
804
    std::vector<std::set<int> > exclusions;
805
    std::vector<std::string> particleParameterNames, globalParameterNames, energyParamDerivNames, valueNames;
806
807
808
    std::vector<Lepton::CompiledExpression> valueExpressions;
    std::vector<std::vector<Lepton::CompiledExpression> > valueDerivExpressions;
    std::vector<std::vector<Lepton::CompiledExpression> > valueGradientExpressions;
809
    std::vector<std::vector<Lepton::CompiledExpression> > valueParamDerivExpressions;
810
    std::vector<OpenMM::CustomGBForce::ComputationType> valueTypes;
811
812
813
    std::vector<Lepton::CompiledExpression> energyExpressions;
    std::vector<std::vector<Lepton::CompiledExpression> > energyDerivExpressions;
    std::vector<std::vector<Lepton::CompiledExpression> > energyGradientExpressions;
814
    std::vector<std::vector<Lepton::CompiledExpression> > energyParamDerivExpressions;
815
    std::vector<OpenMM::CustomGBForce::ComputationType> energyTypes;
816
    std::map<std::string, int> tabulatedFunctionUpdateCount;
817
818
819
820
    NonbondedMethod nonbondedMethod;
    NeighborList* neighborList;
};

821
822
823
824
825
/**
 * 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:
826
    ReferenceCalcCustomExternalForceKernel(std::string name, const Platform& platform) : CalcCustomExternalForceKernel(name, platform), ixn(NULL) {
827
    }
828
    ~ReferenceCalcCustomExternalForceKernel();
829
830
831
832
833
834
835
836
    /**
     * 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);
    /**
837
     * Execute the kernel to calculate the forces and/or energy.
838
     *
839
840
841
842
     * @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
843
     */
844
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
845
846
847
    /**
     * Copy changed parameters over to a context.
     *
848
849
850
851
     * @param context        the context to copy parameters to
     * @param force          the CustomExternalForce to copy the parameters from
     * @param firstParticle  the index of the first particle whose parameters might have changed
     * @param lastParticle   the index of the last particle whose parameters might have changed
852
     */
853
    void copyParametersToContext(ContextImpl& context, const CustomExternalForce& force, int firstParticle, int lastParticle);
854
855
private:
    int numParticles;
856
    ReferenceCustomExternalIxn* ixn;
857
    std::vector<int> particles;
858
    std::vector<std::vector<double> > particleParamArray;
859
    Lepton::CompiledExpression energyExpression, forceExpressionX, forceExpressionY, forceExpressionZ;
860
    std::vector<std::string> parameterNames, globalParameterNames;
peastman's avatar
peastman committed
861
    Vec3* boxVectors;
862
863
};

864
865
866
867
868
/**
 * This kernel is invoked by CustomHbondForce to calculate the forces acting on the system.
 */
class ReferenceCalcCustomHbondForceKernel : public CalcCustomHbondForceKernel {
public:
869
    ReferenceCalcCustomHbondForceKernel(std::string name, const Platform& platform) : CalcCustomHbondForceKernel(name, platform), ixn(NULL) {
870
871
872
873
874
875
876
877
878
879
    }
    ~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);
    /**
880
     * Execute the kernel to calculate the forces and/or energy.
881
     *
882
883
884
885
     * @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
886
     */
887
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
888
889
890
891
892
893
894
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the CustomHbondForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const CustomHbondForce& force);
895
private:
896
    void createInteraction(const CustomHbondForce& force);
897
    int numDonors, numAcceptors, numParticles;
898
    bool isPeriodic;
899
    std::vector<std::vector<int> > donorParticles, acceptorParticles;
900
    std::vector<std::vector<double> > donorParamArray, acceptorParamArray;
peastman's avatar
peastman committed
901
    double nonbondedCutoff;
902
    ReferenceCustomHbondIxn* ixn;
903
    std::vector<std::set<int> > exclusions;
904
    std::vector<std::string> globalParameterNames;
905
    std::map<std::string, int> tabulatedFunctionUpdateCount;
906
907
};

908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
/**
 * This kernel is invoked by CustomCentroidBondForce to calculate the forces acting on the system.
 */
class ReferenceCalcCustomCentroidBondForceKernel : public CalcCustomCentroidBondForceKernel {
public:
    ReferenceCalcCustomCentroidBondForceKernel(std::string name, const Platform& platform) : CalcCustomCentroidBondForceKernel(name, platform), ixn(NULL) {
    }
    ~ReferenceCalcCustomCentroidBondForceKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the CustomCentroidBondForce this kernel will be used for
     */
    void initialize(const System& system, const CustomCentroidBondForce& 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);
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the CustomCentroidBondForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const CustomCentroidBondForce& force);
private:
940
    void createInteraction(const CustomCentroidBondForce& force);
941
    int numBonds, numParticles;
942
943
944
    std::vector<std::vector<int> > bondGroups;
    std::vector<std::vector<int> > groupAtoms;
    std::vector<std::vector<double> > normalizedWeights;
945
    std::vector<std::vector<double> > bondParamArray;
946
    ReferenceCustomCentroidBondIxn* ixn;
947
    std::vector<std::string> globalParameterNames, energyParamDerivNames;
948
    std::map<std::string, int> tabulatedFunctionUpdateCount;
949
    bool usePeriodic;
950
    Vec3* boxVectors;
951
952
};

953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
/**
 * This kernel is invoked by CustomCompoundBondForce to calculate the forces acting on the system.
 */
class ReferenceCalcCustomCompoundBondForceKernel : public CalcCustomCompoundBondForceKernel {
public:
    ReferenceCalcCustomCompoundBondForceKernel(std::string name, const Platform& platform) : CalcCustomCompoundBondForceKernel(name, platform), ixn(NULL) {
    }
    ~ReferenceCalcCustomCompoundBondForceKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the CustomCompoundBondForce this kernel will be used for
     */
    void initialize(const System& system, const CustomCompoundBondForce& 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);
977
978
979
980
981
982
983
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the CustomCompoundBondForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const CustomCompoundBondForce& force);
984
private:
985
    void createInteraction(const CustomCompoundBondForce& force);
986
    int numBonds;
987
    std::vector<std::vector<int> > bondParticles;
988
    std::vector<std::vector<double> > bondParamArray;
989
    ReferenceCustomCompoundBondIxn* ixn;
990
    std::vector<std::string> globalParameterNames, energyParamDerivNames;
991
    std::map<std::string, int> tabulatedFunctionUpdateCount;
992
    bool usePeriodic;
993
    Vec3* boxVectors;
994
995
};

996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
/**
 * This kernel is invoked by CustomManyParticleForce to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcCustomManyParticleForceKernel : public CalcCustomManyParticleForceKernel {
public:
    ReferenceCalcCustomManyParticleForceKernel(std::string name, const Platform& platform) : CalcCustomManyParticleForceKernel(name, platform), ixn(NULL) {
    }
    ~ReferenceCalcCustomManyParticleForceKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the CustomManyParticleForce this kernel will be used for
     */
    void initialize(const System& system, const CustomManyParticleForce& 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);
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the CustomManyParticleForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const CustomManyParticleForce& force);
private:
    int numParticles;
peastman's avatar
peastman committed
1029
    double cutoffDistance;
1030
    std::vector<std::vector<double> > particleParamArray;
1031
1032
    ReferenceCustomManyParticleIxn* ixn;
    std::vector<std::string> globalParameterNames;
1033
    std::map<std::string, int> tabulatedFunctionUpdateCount;
1034
1035
1036
    NonbondedMethod nonbondedMethod;
};

1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
/**
 * This kernel is invoked by GayBerneForce to calculate the forces acting on the system.
 */
class ReferenceCalcGayBerneForceKernel : public CalcGayBerneForceKernel {
public:
    ReferenceCalcGayBerneForceKernel(std::string name, const Platform& platform) : CalcGayBerneForceKernel(name, platform), ixn(NULL) {
    }
    ~ReferenceCalcGayBerneForceKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the GayBerneForce this kernel will be used for
     */
    void initialize(const System& system, const GayBerneForce& 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
     * @return the potential energy due to the force
     */
    double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the GayBerneForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const GayBerneForce& force);
private:
    ReferenceGayBerneForce* ixn;
};

1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
/**
 * This kernel is invoked by CustomCVForce to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcCustomCVForceKernel : public CalcCustomCVForceKernel {
public:
    ReferenceCalcCustomCVForceKernel(std::string name, const Platform& platform) : CalcCustomCVForceKernel(name, platform), ixn(NULL) {
    }
    ~ReferenceCalcCustomCVForceKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the CustomCVForce this kernel will be used for
1084
     * @param innerContext   the context created by the CustomCVForce for computing collective variables
1085
     */
1086
    void initialize(const System& system, const CustomCVForce& force, ContextImpl& innerContext);
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
    /**
     * Execute the kernel to calculate the forces and/or energy.
     *
     * @param context        the context in which to execute this kernel
     * @param innerContext   the context created by the CustomCVForce for computing collective variables
     * @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, ContextImpl& innerContext, bool includeForces, bool includeEnergy);
    /**
     * Copy state information to the inner context.
     *
     * @param context        the context in which to execute this kernel
     * @param innerContext   the context created by the CustomCVForce for computing collective variables
     */
    void copyState(ContextImpl& context, ContextImpl& innerContext);
1104
1105
1106
1107
1108
1109
1110
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the CustomCVForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const CustomCVForce& force);
1111
1112
1113
1114
1115
private:
    ReferenceCustomCVForce* ixn;
    std::vector<std::string> globalParameterNames, energyParamDerivNames;
};

1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
/**
 * This kernel is invoked by RMSDForce to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcRMSDForceKernel : public CalcRMSDForceKernel {
public:
    ReferenceCalcRMSDForceKernel(std::string name, const Platform& platform) : CalcRMSDForceKernel(name, platform) {
    }
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the RMSDForce this kernel will be used for
     */
    void initialize(const System& system, const RMSDForce& 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);
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the RMSDForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const RMSDForce& force);
private:
    std::vector<Vec3> referencePos;
    std::vector<int> particles;
};

1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
/**
 * This kernel is invoked by RGForce to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcRGForceKernel : public CalcRGForceKernel {
public:
    ReferenceCalcRGForceKernel(std::string name, const Platform& platform) : CalcRGForceKernel(name, platform) {
    }
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the RGForce this kernel will be used for
     */
    void initialize(const System& system, const RGForce& 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:
    std::vector<int> particles;
};

1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
/**
 * This kernel is invoked by OrientationRestraintForce to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcOrientationRestraintForceKernel : public CalcOrientationRestraintForceKernel {
public:
    ReferenceCalcOrientationRestraintForceKernel(std::string name, const Platform& platform) : CalcOrientationRestraintForceKernel(name, platform) {
    }
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the OrientationRestraintForce this kernel will be used for
     */
    void initialize(const System& system, const OrientationRestraintForce& 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);
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the OrientationRestraintForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const OrientationRestraintForce& force);
private:
    double k;
    std::vector<Vec3> referencePos;
    std::vector<int> particles;
};

1214
1215
1216
1217
1218
/**
 * This kernel is invoked by VerletIntegrator to take one time step.
 */
class ReferenceIntegrateVerletStepKernel : public IntegrateVerletStepKernel {
public:
1219
    ReferenceIntegrateVerletStepKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : IntegrateVerletStepKernel(name, platform),
1220
        data(data), dynamics(0) {
1221
    }
1222
    ~ReferenceIntegrateVerletStepKernel();
1223
    /**
1224
     * Initialize the kernel.
1225
     * 
1226
1227
     * @param system     the System this kernel will be applied to
     * @param integrator the VerletIntegrator this kernel will be used for
1228
     */
1229
    void initialize(const System& system, const VerletIntegrator& integrator);
1230
1231
1232
    /**
     * Execute the kernel.
     * 
1233
1234
     * @param context    the context in which to execute this kernel
     * @param integrator the VerletIntegrator this kernel is being used for
1235
     */
1236
    void execute(ContextImpl& context, const VerletIntegrator& integrator);
1237
1238
1239
1240
1241
1242
1243
    /**
     * Compute the kinetic energy.
     * 
     * @param context    the context in which to execute this kernel
     * @param integrator the VerletIntegrator this kernel is being used for
     */
    double computeKineticEnergy(ContextImpl& context, const VerletIntegrator& integrator);
1244
private:
1245
    ReferencePlatform::PlatformData& data;
1246
    ReferenceVerletDynamics* dynamics;
peastman's avatar
peastman committed
1247
    std::vector<double> masses;
1248
    double prevStepSize;
1249
1250
1251
}
;
/**
1252
 * This kernel is invoked by NoseHooverIntegrator to take one time step.
1253
 */
1254
class ReferenceIntegrateNoseHooverStepKernel : public IntegrateNoseHooverStepKernel {
1255
public:
1256
    ReferenceIntegrateNoseHooverStepKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : IntegrateNoseHooverStepKernel(name, platform),
1257
1258
        data(data), dynamics(0) {
    }
1259
    ~ReferenceIntegrateNoseHooverStepKernel();
1260
1261
1262
1263
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
1264
     * @param integrator the NoseHooverIntegrator this kernel will be used for
1265
     */
1266
    void initialize(const System& system, const NoseHooverIntegrator& integrator);
1267
1268
1269
1270
1271
1272
    /**
     * Execute the kernel.
     * 
     * @param context    the context in which to execute this kernel
     * @param integrator the VerletIntegrator this kernel is being used for
     */
1273
    void execute(ContextImpl& context, const NoseHooverIntegrator& integrator);
1274
1275
1276
1277
    /**
     * Compute the kinetic energy.
     * 
     * @param context    the context in which to execute this kernel
1278
     * @param integrator the NoseHooverIntegrator this kernel is being used for
1279
     */
1280
    double computeKineticEnergy(ContextImpl& context, const NoseHooverIntegrator& integrator);
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
    /**
     * Execute the kernel that propagates the Nose Hoover chain and determines the velocity scale factor.
     * 
     * @param context  the context in which to execute this kernel
     * @param noseHooverChain the object describing the chain to be propagated.
     * @param kineticEnergy the {center of mass, relative} kineticEnergies of the particles being thermostated by this chain.
     * @param timeStep the time step used by the integrator.
     * @return the velocity scale factor to apply to the particles associated with this heat bath.
     */
    std::pair<double, double> propagateChain(ContextImpl& context, const NoseHooverChain &noseHooverChain, std::pair<double, double> kineticEnergy, double timeStep);
    /**
     * Execute the kernal that computes the total (kinetic + potential) heat bath energy.
     *
     * @param context the context in which to execute this kernel
     * @param noseHooverChain the chain whose energy is to be determined.
     * @return the total heat bath energy.
     */
    double computeHeatBathEnergy(ContextImpl& context, const NoseHooverChain &noseHooverChain);
    /**
     * Execute the kernel that computes the kinetic energy for a subset of atoms,
     * or the relative kinetic energy of Drude particles with respect to their parent atoms
     *
     * @param context the context in which to execute this kernel
     * @param noseHooverChain the chain whose energy is to be determined.
     * @param downloadValue whether the computed value should be downloaded and returned.
     */
    std::pair<double, double> computeMaskedKineticEnergy(ContextImpl& context, const NoseHooverChain &noseHooverChain, bool downloadValue);
    /**
     * Execute the kernel that scales the velocities of particles associated with a nose hoover chain
     *
     * @param context the context in which to execute this kernel
     * @param noseHooverChain the chain whose energy is to be determined.
     * @param scaleFactor the multiplicative factor by which {absolute, relative} velocities are scaled.
     */
    void scaleVelocities(ContextImpl& context, const NoseHooverChain &noseHooverChain, std::pair<double, double> scaleFactor);
1316
1317
1318
1319
1320
1321
1322
1323
    /**
     * Write the chain states to a checkpoint.
     */
    void createCheckpoint(ContextImpl& context, std::ostream& stream) const;
    /**
     * Load the chain states from a checkpoint.
     */
    void loadCheckpoint(ContextImpl& context, std::istream& stream);
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
    /**
     * Get the internal states of all chains.
     * 
     * @param context       the context for which to get the states
     * @param positions     element [i][j] contains the position of bead j for chain i
     * @param velocities    element [i][j] contains the velocity of bead j for chain i
     */
    void getChainStates(ContextImpl& context, std::vector<std::vector<double> >& positions, std::vector<std::vector<double> >& velocities) const;
    /**
     * Set the internal states of all chains.
     * 
     * @param context       the context for which to get the states
     * @param positions     element [i][j] contains the position of bead j for chain i
     * @param velocities    element [i][j] contains the velocity of bead j for chain i
     */
    void setChainStates(ContextImpl& context, const std::vector<std::vector<double> >& positions, const std::vector<std::vector<double> >& velocities);
1340
1341
private:
    ReferencePlatform::PlatformData& data;
1342
1343
    ReferenceNoseHooverChain* chainPropagator;
    ReferenceNoseHooverDynamics* dynamics;
1344
    std::vector<double> masses;
1345
1346
    std::vector<std::vector<double> > chainPositions;
    std::vector<std::vector<double> > chainVelocities;
1347
    double prevStepSize;
1348
1349
};

1350
/**
1351
 * This kernel is invoked by LangevinMiddleIntegrator to take one time step.
1352
 */
1353
class ReferenceIntegrateLangevinMiddleStepKernel : public IntegrateLangevinMiddleStepKernel {
1354
public:
1355
    ReferenceIntegrateLangevinMiddleStepKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : IntegrateLangevinMiddleStepKernel(name, platform),
1356
1357
        data(data), dynamics(0) {
    }
1358
    ~ReferenceIntegrateLangevinMiddleStepKernel();
1359
1360
1361
1362
    /**
     * Initialize the kernel, setting up the particle masses.
     * 
     * @param system     the System this kernel will be applied to
1363
     * @param integrator the LangevinMiddleIntegrator this kernel will be used for
1364
     */
1365
    void initialize(const System& system, const LangevinMiddleIntegrator& integrator);
1366
1367
1368
1369
    /**
     * Execute the kernel.
     * 
     * @param context    the context in which to execute this kernel
1370
     * @param integrator the LangevinMiddleIntegrator this kernel is being used for
1371
     */
1372
    void execute(ContextImpl& context, const LangevinMiddleIntegrator& integrator);
1373
1374
1375
1376
    /**
     * Compute the kinetic energy.
     * 
     * @param context    the context in which to execute this kernel
1377
     * @param integrator the LangevinMiddleIntegrator this kernel is being used for
1378
     */
1379
    double computeKineticEnergy(ContextImpl& context, const LangevinMiddleIntegrator& integrator);
1380
1381
private:
    ReferencePlatform::PlatformData& data;
1382
    ReferenceLangevinMiddleDynamics* dynamics;
1383
1384
1385
1386
    std::vector<double> masses;
    double prevTemp, prevFriction, prevStepSize;
};

1387
1388
1389
1390
1391
/**
 * This kernel is invoked by BrownianIntegrator to take one time step.
 */
class ReferenceIntegrateBrownianStepKernel : public IntegrateBrownianStepKernel {
public:
1392
    ReferenceIntegrateBrownianStepKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : IntegrateBrownianStepKernel(name, platform),
1393
        data(data), dynamics(0) {
1394
    }
1395
    ~ReferenceIntegrateBrownianStepKernel();
1396
    /**
1397
     * Initialize the kernel.
1398
     * 
1399
1400
     * @param system     the System this kernel will be applied to
     * @param integrator the BrownianIntegrator this kernel will be used for
1401
     */
1402
    void initialize(const System& system, const BrownianIntegrator& integrator);
1403
1404
1405
    /**
     * Execute the kernel.
     * 
1406
1407
     * @param context    the context in which to execute this kernel
     * @param integrator the BrownianIntegrator this kernel is being used for
1408
     */
1409
    void execute(ContextImpl& context, const BrownianIntegrator& integrator);
1410
1411
1412
1413
1414
1415
1416
    /**
     * Compute the kinetic energy.
     * 
     * @param context    the context in which to execute this kernel
     * @param integrator the BrownianIntegrator this kernel is being used for
     */
    double computeKineticEnergy(ContextImpl& context, const BrownianIntegrator& integrator);
1417
private:
1418
    ReferencePlatform::PlatformData& data;
1419
    ReferenceBrownianDynamics* dynamics;
peastman's avatar
peastman committed
1420
    std::vector<double> masses;
1421
    double prevTemp, prevFriction, prevStepSize;
1422
1423
};

1424
1425
1426
1427
1428
1429
/**
 * 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),
1430
        data(data), dynamics(0) {
1431
1432
1433
1434
1435
1436
    }
    ~ReferenceIntegrateVariableLangevinStepKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
1437
     * @param integrator the VariableLangevinIntegrator this kernel will be used for
1438
1439
1440
1441
1442
1443
     */
    void initialize(const System& system, const VariableLangevinIntegrator& integrator);
    /**
     * Execute the kernel.
     *
     * @param context    the context in which to execute this kernel
1444
     * @param integrator the VariableLangevinIntegrator this kernel is being used for
1445
     * @param maxTime    the maximum time beyond which the simulation should not be advanced
1446
     * @return the size of the step that was taken
1447
     */
1448
    double execute(ContextImpl& context, const VariableLangevinIntegrator& integrator, double maxTime);
1449
1450
1451
1452
1453
1454
1455
    /**
     * Compute the kinetic energy.
     * 
     * @param context    the context in which to execute this kernel
     * @param integrator the VariableLangevinIntegrator this kernel is being used for
     */
    double computeKineticEnergy(ContextImpl& context, const VariableLangevinIntegrator& integrator);
1456
1457
1458
private:
    ReferencePlatform::PlatformData& data;
    ReferenceVariableStochasticDynamics* dynamics;
peastman's avatar
peastman committed
1459
    std::vector<double> masses;
1460
1461
1462
    double prevTemp, prevFriction, prevErrorTol;
};

1463
1464
1465
1466
1467
1468
/**
 * 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),
1469
        data(data), dynamics(0) {
1470
1471
1472
1473
1474
1475
    }
    ~ReferenceIntegrateVariableVerletStepKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
1476
     * @param integrator the VariableVerletIntegrator this kernel will be used for
1477
1478
1479
1480
1481
1482
     */
    void initialize(const System& system, const VariableVerletIntegrator& integrator);
    /**
     * Execute the kernel.
     *
     * @param context    the context in which to execute this kernel
1483
     * @param integrator the VariableVerletIntegrator this kernel is being used for
1484
     * @param maxTime    the maximum time beyond which the simulation should not be advanced
1485
     * @return the size of the step that was taken
1486
     */
1487
    double execute(ContextImpl& context, const VariableVerletIntegrator& integrator, double maxTime);
1488
1489
1490
1491
1492
1493
1494
    /**
     * Compute the kinetic energy.
     * 
     * @param context    the context in which to execute this kernel
     * @param integrator the VariableVerletIntegrator this kernel is being used for
     */
    double computeKineticEnergy(ContextImpl& context, const VariableVerletIntegrator& integrator);
1495
1496
1497
private:
    ReferencePlatform::PlatformData& data;
    ReferenceVariableVerletDynamics* dynamics;
peastman's avatar
peastman committed
1498
    std::vector<double> masses;
1499
    double prevErrorTol;
1500
1501
};

1502
1503
1504
1505
1506
1507
/**
 * This kernel is invoked by CustomIntegrator to take one time step.
 */
class ReferenceIntegrateCustomStepKernel : public IntegrateCustomStepKernel {
public:
    ReferenceIntegrateCustomStepKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : IntegrateCustomStepKernel(name, platform),
1508
        data(data), dynamics(0) {
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
    }
    ~ReferenceIntegrateCustomStepKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param integrator the CustomIntegrator this kernel will be used for
     */
    void initialize(const System& system, const CustomIntegrator& integrator);
    /**
     * Execute the kernel.
     * 
     * @param context    the context in which to execute this kernel
     * @param integrator the CustomIntegrator this kernel is being used for
     * @param forcesAreValid if the context has been modified since the last time step, this will be
     *                       false to show that cached forces are invalid and must be recalculated.
     *                       On exit, this should specify whether the cached forces are valid at the
     *                       end of the step.
     */
    void execute(ContextImpl& context, CustomIntegrator& integrator, bool& forcesAreValid);
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
    /**
     * Compute the kinetic energy.
     * 
     * @param context    the context in which to execute this kernel
     * @param integrator the CustomIntegrator this kernel is being used for
     * @param forcesAreValid if the context has been modified since the last time step, this will be
     *                       false to show that cached forces are invalid and must be recalculated.
     *                       On exit, this should specify whether the cached forces are valid at the
     *                       end of the step.
     */
    double computeKineticEnergy(ContextImpl& context, CustomIntegrator& integrator, bool& forcesAreValid);
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
    /**
     * Get the values of all global variables.
     *
     * @param context   the context in which to execute this kernel
     * @param values    on exit, this contains the values
     */
    void getGlobalVariables(ContextImpl& context, std::vector<double>& values) const;
    /**
     * Set the values of all global variables.
     *
     * @param context   the context in which to execute this kernel
     * @param values    a vector containing the values
     */
    void setGlobalVariables(ContextImpl& context, const std::vector<double>& values);
    /**
     * Get the values of a per-DOF variable.
     *
     * @param context   the context in which to execute this kernel
     * @param variable  the index of the variable to get
     * @param values    on exit, this contains the values
     */
    void getPerDofVariable(ContextImpl& context, int variable, std::vector<Vec3>& values) const;
    /**
     * Set the values of a per-DOF variable.
     *
     * @param context   the context in which to execute this kernel
     * @param variable  the index of the variable to get
     * @param values    a vector containing the values
     */
    void setPerDofVariable(ContextImpl& context, int variable, const std::vector<Vec3>& values);
private:
    ReferencePlatform::PlatformData& data;
    ReferenceCustomDynamics* dynamics;
peastman's avatar
peastman committed
1573
1574
    std::vector<double> masses, globalValues;
    std::vector<std::vector<OpenMM::Vec3> > perDofValues; 
1575
1576
};

Peter Eastman's avatar
Peter Eastman committed
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
/**
 * This kernel is invoked by DPDIntegrator to take one time step.
 */
class ReferenceIntegrateDPDStepKernel : public IntegrateDPDStepKernel {
public:
    ReferenceIntegrateDPDStepKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : IntegrateDPDStepKernel(name, platform),
        data(data), dynamics(NULL) {
    }
    ~ReferenceIntegrateDPDStepKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param integrator the DPDIntegrator this kernel will be used for
     */
    void initialize(const System& system, const DPDIntegrator& integrator);
    /**
     * Execute the kernel.
     * 
     * @param context    the context in which to execute this kernel
     * @param integrator the DPDIntegrator this kernel is being used for
     */
    void execute(ContextImpl& context, const DPDIntegrator& integrator);
    /**
     * Compute the kinetic energy.
     * 
     * @param context    the context in which to execute this kernel
     * @param integrator the DPDIntegrator this kernel is being used for
     */
    double computeKineticEnergy(ContextImpl& context, const DPDIntegrator& integrator);
private:
    ReferencePlatform::PlatformData& data;
    ReferenceDPDDynamics* dynamics;
    std::vector<double> masses;
};

1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
/**
 * This kernel is invoked by QTBIntegrator to take one time step.
 */
class ReferenceIntegrateQTBStepKernel : public IntegrateQTBStepKernel {
public:
    ReferenceIntegrateQTBStepKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : IntegrateQTBStepKernel(name, platform),
        data(data), dynamics(NULL), hasInitialized(false) {
    }
    ~ReferenceIntegrateQTBStepKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param integrator the QTBIntegrator this kernel will be used for
     */
    void initialize(const System& system, const QTBIntegrator& integrator);
    /**
     * Execute the kernel.
     * 
     * @param context    the context in which to execute this kernel
     * @param integrator the QTBIntegrator this kernel is being used for
     */
    void execute(ContextImpl& context, const QTBIntegrator& integrator);
    /**
     * Compute the kinetic energy.
     * 
     * @param context    the context in which to execute this kernel
     * @param integrator the QTBIntegrator this kernel is being used for
     */
    double computeKineticEnergy(ContextImpl& context, const QTBIntegrator& integrator);
    /**
     * Get the adapted friction coefficients for a particle.
     * 
     * @param context    the context in which to execute this kernel
     * @param particle   the index of the particle for which to get the friction
     * @param friction   the adapted friction coefficients used in generating the
     *                   random force
     */
    void getAdaptedFriction(ContextImpl& context, int particle, std::vector<double>& friction) const;
    /**
     * Set the adapted friction coefficients for a particle.  This affects the
     * specified particle, and all others that have the same type.
     * 
     * @param context    the context in which to execute this kernel
     * @param particle   the index of the particle for which to get the friction
     * @param friction   the adapted friction coefficients used in generating the
     *                   random force
     */
    void setAdaptedFriction(ContextImpl& context, int particle, const std::vector<double>& friction);
    /**
     * Write the adapted friction to a checkpoint.
     * 
     * @param context    the context in which to execute this kernel
     * @param stream     the stream to write the checkpoint to
     */
    void createCheckpoint(ContextImpl& context, std::ostream& stream) const;
    /**
     * Load the adapted friction from a checkpoint.
     * 
     * @param context    the context in which to execute this kernel
     * @param stream     the stream to read the checkpoint from
     */
    void loadCheckpoint(ContextImpl& context, std::istream& stream);
private:
    ReferencePlatform::PlatformData& data;
    ReferenceQTBDynamics* dynamics;
    std::vector<double> masses;
    bool hasInitialized;
};

1683
/**
Peter Eastman's avatar
Peter Eastman committed
1684
 * This kernel is invoked by AndersenThermostat at the start of each time step to adjust the particle velocities.
1685
1686
1687
 */
class ReferenceApplyAndersenThermostatKernel : public ApplyAndersenThermostatKernel {
public:
1688
    ReferenceApplyAndersenThermostatKernel(std::string name, const Platform& platform) : ApplyAndersenThermostatKernel(name, platform), thermostat(0) {
1689
    }
1690
    ~ReferenceApplyAndersenThermostatKernel();
1691
    /**
1692
     * Initialize the kernel.
1693
     * 
1694
1695
     * @param system     the System this kernel will be applied to
     * @param thermostat the AndersenThermostat this kernel will be used for
1696
     */
1697
    void initialize(const System& system, const AndersenThermostat& thermostat);
1698
1699
1700
    /**
     * Execute the kernel.
     * 
1701
     * @param context    the context in which to execute this kernel
1702
     */
1703
    void execute(ContextImpl& context);
1704
1705
private:
    ReferenceAndersenThermostat* thermostat;
1706
    std::vector<std::vector<int> > particleGroups;
peastman's avatar
peastman committed
1707
    std::vector<double> masses;
1708
1709
};

1710
1711
1712
1713
1714
/**
 * This kernel is invoked by MonteCarloBarostat to adjust the periodic box volume
 */
class ReferenceApplyMonteCarloBarostatKernel : public ApplyMonteCarloBarostatKernel {
public:
1715
    ReferenceApplyMonteCarloBarostatKernel(std::string name, const Platform& platform) : ApplyMonteCarloBarostatKernel(name, platform), barostat(NULL) {
1716
1717
1718
1719
1720
    }
    ~ReferenceApplyMonteCarloBarostatKernel();
    /**
     * Initialize the kernel.
     *
1721
1722
     * @param system          the System this kernel will be applied to
     * @param barostat        the MonteCarloBarostat this kernel will be used for
1723
     * @param rigidMolecules  whether molecules should be kept rigid while scaling coordinates
1724
1725
     * @param components      the number of box components the barostat operates one (1 for isotropic scaling,
     *                        3 for anisotropic, 6 for both lengths and angles)
1726
     */
1727
    void initialize(const System& system, const Force& barostat, int components, bool rigidMolecules=true);
1728
1729
1730
1731
1732
1733
1734
    /**
     * Save the coordinates before attempting a Monte Carlo step.  This allows us to restore them
     * if the step is rejected.
     *
     * @param context    the context in which to execute this kernel
     */
    void saveCoordinates(ContextImpl& context);
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
    /**
     * Attempt a Monte Carlo step, scaling particle positions (or cluster centers) by a specified value.
     * This version scales the x, y, and z positions independently.
     * 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 scaleX     the scale factor by which to multiply particle x-coordinate
     * @param scaleY     the scale factor by which to multiply particle y-coordinate
     * @param scaleZ     the scale factor by which to multiply particle z-coordinate
     */
1747
    void scaleCoordinates(ContextImpl& context, double scaleX, double scaleY, double scaleZ);
1748
    /**
1749
1750
     * Reject the most recent Monte Carlo step, restoring the particle positions to where they were when
     * saveCoordinates() was last called.
1751
1752
1753
1754
     *
     * @param context    the context in which to execute this kernel
     */
    void restoreCoordinates(ContextImpl& context);
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
    /**
     * Compute the kinetic energy of the system.  If initialize() was called with rigidMolecules=true, this
     * should include only the translational center of mass motion of molecules.  Otherwise it should include
     * the total kinetic energy of all particles.  This is used when computing instantaneous pressure.
     * 
     * @param context    the context in which to execute this kernel
     * @param ke         a vector to store the kinetic energy components into.  On output, its length will
     *                   equal the number of components passed to initialize().
     */
    void computeKineticEnergy(ContextImpl& context, std::vector<double>& ke);
1765
private:
1766
    bool rigidMolecules;
1767
    int components;
1768
1769
1770
    ReferenceMonteCarloBarostat* barostat;
};

1771
1772
1773
1774
1775
/**
 * This kernel is invoked to remove center of mass motion from the system.
 */
class ReferenceRemoveCMMotionKernel : public RemoveCMMotionKernel {
public:
1776
    ReferenceRemoveCMMotionKernel(std::string name, const Platform& platform, ReferencePlatform::PlatformData& data) : RemoveCMMotionKernel(name, platform), data(data) {
1777
1778
    }
    /**
Peter Eastman's avatar
Peter Eastman committed
1779
     * Initialize the kernel, setting up the particle masses.
1780
     * 
1781
1782
     * @param system     the System this kernel will be applied to
     * @param force      the CMMotionRemover this kernel will be used for
1783
     */
1784
    void initialize(const System& system, const CMMotionRemover& force);
1785
1786
1787
    /**
     * Execute the kernel.
     * 
1788
     * @param context    the context in which to execute this kernel
1789
     */
1790
    void execute(ContextImpl& context);
1791
private:
1792
    ReferencePlatform::PlatformData& data;
1793
    std::vector<double> masses;
1794
    int frequency;
1795
1796
};

1797
1798
1799
1800
1801
1802
1803
1804
1805
/**
 * This kernel is invoked by ATMForce to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcATMForceKernel : public CalcATMForceKernel {
public:
    ReferenceCalcATMForceKernel(std::string name, const Platform& platform) : CalcATMForceKernel(name, platform) {
    }
    /**
     * Initialize the kernel.
1806
     *
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
     * @param system     the System this kernel will be applied to
     * @param force      the ATMForce this kernel will be used for
     */
    void initialize(const System& system, const ATMForce& force);
    /**
     * Scale the forces from the inner contexts and apply them to the main context.
     *
     * @param context        the context in which to execute this kernel
     * @param innerContext1  the first inner context
     * @param innerContext2  the second inner context
     * @param dEdu0          the derivative of the final energy with respect to the first inner context's energy
     * @param dEdu1          the derivative of the final energy with respect to the second inner context's energy
     * @param energyParamDerivs  derivatives of the final energy with respect to global parameters
     */
    void applyForces(ContextImpl& context, ContextImpl& innerContext0, ContextImpl& innerContext1,
                     double dEdu0, double dEdu1, const std::map<std::string, double>& energyParamDerivs);
    /**
     * Copy changed parameters over to a context.
     *
     * @param context    the context to copy parameters to
     * @param force      the ATMForce to copy the parameters from
     */
    void copyParametersToContext(ContextImpl& context, const ATMForce& force);
    /**
     * Copy state information to the inner contexts.
     *
     * @param context        the context in which to execute this kernel
     * @param innerContext1  the first context created by the ATMForce for computing displaced energy
     * @param innerContext2  the second context created by the ATMForce for computing displaced energy
     */
    void copyState(ContextImpl& context, ContextImpl& innerContext0, ContextImpl& innerContext1);
private:
    int numParticles;
1840
1841
1842
1843
1844
1845
    std::vector<Vec3> displ1, displ0;
    std::vector<Vec3> displacement1, displacement0;
    std::vector<int> pj1, pi1, pj0, pi0;
    void setDisplacements(std::vector<Vec3>& pos);
    void displForces(std::vector<Vec3>& force0, std::vector<Vec3>& force1);
    void loadParams(int numParticles, const ATMForce& force);
1846
1847
};

1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
/**
 * This kernel is invoked by CustomCPPForceImpl to calculate the forces acting on the system and the energy of the system.
 */
class ReferenceCalcCustomCPPForceKernel : public CalcCustomCPPForceKernel {
public:
    ReferenceCalcCustomCPPForceKernel(std::string name, const Platform& platform) : CalcCustomCPPForceKernel(name, platform), force(NULL) {
    }
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the CustomCPPForceImpl this kernel will be used for
     */
    void initialize(const System& system, CustomCPPForceImpl& 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:
    CustomCPPForceImpl* force;
    std::vector<Vec3> forces;
};

1876
1877
1878
} // namespace OpenMM

#endif /*OPENMM_REFERENCEKERNELS_H_*/