NonbondedForce.h 18.9 KB
Newer Older
1
2
#ifndef OPENMM_NONBONDEDFORCE_H_
#define OPENMM_NONBONDEDFORCE_H_
3
4
5
6
7
8
9
10
11

/* -------------------------------------------------------------------------- *
 *                                   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-2010 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
35
36
 * 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.                                     *
 * -------------------------------------------------------------------------- */

#include "Force.h"
#include <map>
37
#include <set>
38
#include <utility>
39
#include <vector>
40
#include "internal/windowsExport.h"
41
42
43
44

namespace OpenMM {

/**
45
46
 * This class implements nonbonded interactions between particles, including a Coulomb force to represent
 * electrostatics and a Lennard-Jones force to represent van der Waals interactions.  It optionally supports
47
48
49
 * periodic boundary conditions and cutoffs for long range interactions.  Lennard-Jones interactions are
 * calculated with the Lorentz-Bertelot combining rule: it uses the arithmetic mean of the sigmas and the
 * geometric mean of the epsilons for the two interacting particles.
50
51
52
53
 *
 * To use this class, create a NonbondedForce object, then call addParticle() once for each particle in the
 * System to define its parameters.  The number of particles for which you define nonbonded parameters must
 * be exactly equal to the number of particles in the System, or else an exception will be thrown when you
54
 * try to create a Context.  After a particle has been added, you can modify its force field parameters
55
56
57
58
59
60
61
62
63
64
65
 * by calling setParticleParameters().
 *
 * NonbondedForce also lets you specify "exceptions", particular pairs of particles whose interactions should be
 * computed based on different parameters than those defined for the individual particles.  This can be used to
 * completely exclude certain interactions from the force calculation, or to alter how they interact with each other.
 *
 * Many molecular force fields omit Coulomb and Lennard-Jones interactions between particles separated by one
 * or two bonds, while using modified parameters for those separated by three bonds (known as "1-4 interactions").
 * This class provides a convenience method for this case called createExceptionsFromBonds().  You pass to it
 * a list of bonds and the scale factors to use for 1-4 interactions.  It identifies all pairs of particles which
 * are separated by 1, 2, or 3 bonds, then automatically creates exceptions for them.
66
67
 */

68
class OPENMM_EXPORT NonbondedForce : public Force {
69
public:
70
71
72
73
74
75
    /**
     * This is an enumeration of the different methods that may be used for handling long range nonbonded forces.
     */
    enum NonbondedMethod {
        /**
         * No cutoff is applied to nonbonded interactions.  The full set of N^2 interactions is computed exactly.
76
         * This necessarily means that periodic boundary conditions cannot be used.  This is the default.
77
78
79
80
         */
        NoCutoff = 0,
        /**
         * Interactions beyond the cutoff distance are ignored.  Coulomb interactions closer than the cutoff distance
81
         * are modified using the reaction field method.
82
83
84
         */
        CutoffNonPeriodic = 1,
        /**
Peter Eastman's avatar
Peter Eastman committed
85
86
         * Periodic boundary conditions are used, so that each particle interacts only with the nearest periodic copy of
         * each other particle.  Interactions beyond the cutoff distance are ignored.  Coulomb interactions closer than the
87
         * cutoff distance are modified using the reaction field method.
88
         */
89
90
        CutoffPeriodic = 2,
        /**
91
92
         * Periodic boundary conditions are used, and Ewald summation is used to compute the interaction of each particle
         * with all periodic copies of every other particle.
93
         */
94
95
96
97
98
99
        Ewald = 3,
        /**
         * Periodic boundary conditions are used, and Particle-Mesh Ewald (PME) summation is used to compute the interaction of each particle
         * with all periodic copies of every other particle.
         */
        PME = 4
100
    };
101
    /**
102
     * Create a NonbondedForce.
103
     */
104
    NonbondedForce();
105
    /**
106
     * Get the number of particles for which force field parameters have been defined.
107
     */
Peter Eastman's avatar
Peter Eastman committed
108
109
    int getNumParticles() const {
        return particles.size();
110
    }
111
    /**
112
     * Get the number of special interactions that should be calculated differently from other interactions.
113
     */
114
115
    int getNumExceptions() const {
        return exceptions.size();
116
    }
117
118
119
    /**
     * Get the method used for handling long range nonbonded interactions.
     */
120
    NonbondedMethod getNonbondedMethod() const;
121
122
123
124
125
126
    /**
     * Set the method used for handling long range nonbonded interactions.
     */
    void setNonbondedMethod(NonbondedMethod method);
    /**
     * Get the cutoff distance (in nm) being used for nonbonded interactions.  If the NonbondedMethod in use
127
     * is NoCutoff, this value will have no effect.
128
129
     *
     * @return the cutoff distance, measured in nm
130
     */
131
    double getCutoffDistance() const;
132
133
    /**
     * Set the cutoff distance (in nm) being used for nonbonded interactions.  If the NonbondedMethod in use
134
     * is NoCutoff, this value will have no effect.
135
136
     *
     * @param distance    the cutoff distance, measured in nm
137
138
     */
    void setCutoffDistance(double distance);
139
140
141
142
143
144
145
146
    /**
     * Get the dielectric constant to use for the solvent in the reaction field approximation.
     */
    double getReactionFieldDielectric() const;
    /**
     * Set the dielectric constant to use for the solvent in the reaction field approximation.
     */
    void setReactionFieldDielectric(double dielectric);
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    /**
     * Get the error tolerance for Ewald summation.  This corresponds to the fractional error in the forces
     * which is acceptable.  This value is used to select the reciprocal space cutoff and separation
     * parameter so that the average error level will be less than the tolerance.  There is not a
     * rigorous guarantee that all forces on all atoms will be less than the tolerance, however.
     */
    double getEwaldErrorTolerance() const;
    /**
     * Get the error tolerance for Ewald summation.  This corresponds to the fractional error in the forces
     * which is acceptable.  This value is used to select the reciprocal space cutoff and separation
     * parameter so that the average error level will be less than the tolerance.  There is not a
     * rigorous guarantee that all forces on all atoms will be less than the tolerance, however.
     */
    void setEwaldErrorTolerance(double tol);
161
162
163
164
165
166
167
168
169
170
    /**
     * Add the nonbonded force parameters for a particle.  This should be called once for each particle
     * in the System.  When it is called for the i'th time, it specifies the parameters for the i'th particle.
     * For calculating the Lennard-Jones interaction between two particles, the arithmetic mean of the sigmas
     * and the geometric mean of the epsilons for the two interacting particles is used (the Lorentz-Bertelot
     * combining rule).
     *
     * @param charge    the charge of the particle, measured in units of the proton charge
     * @param sigma     the sigma parameter of the Lennard-Jones potential (corresponding to the van der Waals radius of the particle), measured in nm
     * @param epsilon   the epsilon parameter of the Lennard-Jones potential (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
171
     * @return the index of the particle that was added
172
     */
173
    int addParticle(double charge, double sigma, double epsilon);
174
    /**
Peter Eastman's avatar
Peter Eastman committed
175
     * Get the nonbonded force parameters for a particle.
176
     *
Peter Eastman's avatar
Peter Eastman committed
177
178
     * @param index     the index of the particle for which to get parameters
     * @param charge    the charge of the particle, measured in units of the proton charge
179
180
     * @param sigma     the sigma parameter of the Lennard-Jones potential (corresponding to the van der Waals radius of the particle), measured in nm
     * @param epsilon   the epsilon parameter of the Lennard-Jones potential (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
181
     */
182
    void getParticleParameters(int index, double& charge, double& sigma, double& epsilon) const;
183
    /**
184
185
186
187
     * Set the nonbonded force parameters for a particle.  When calculating the Lennard-Jones interaction between two particles,
     * it uses the arithmetic mean of the sigmas and the geometric mean of the epsilons for the two interacting particles
     * (the Lorentz-Bertelot combining rule).
     *
Peter Eastman's avatar
Peter Eastman committed
188
189
     * @param index     the index of the particle for which to set parameters
     * @param charge    the charge of the particle, measured in units of the proton charge
190
191
     * @param sigma     the sigma parameter of the Lennard-Jones potential (corresponding to the van der Waals radius of the particle), measured in nm
     * @param epsilon   the epsilon parameter of the Lennard-Jones potential (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
192
     */
193
    void setParticleParameters(int index, double charge, double sigma, double epsilon);
194
    /**
195
196
197
198
199
200
201
202
203
204
205
     * Add an interaction to the list of exceptions that should be calculated differently from other interactions.
     * If chargeProd and epsilon are both equal to 0, this will cause the interaction to be completely omitted from
     * force and energy calculations.
     *
     * In many cases, you can use createExceptionsFromBonds() rather than adding each exception explicitly.
     *
     * @param particle1  the index of the first particle involved in the interaction
     * @param particle2  the index of the second particle involved in the interaction
     * @param chargeProd the scaled product of the atomic charges (i.e. the strength of the Coulomb interaction), measured in units of the proton charge squared
     * @param sigma      the sigma parameter of the Lennard-Jones potential (corresponding to the van der Waals radius of the particle), measured in nm
     * @param epsilon    the epsilon parameter of the Lennard-Jones potential (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
206
207
     * @param replace    determines the behavior if there is already an exception for the same two particles.  If true, the existing one is replaced.  If false,
     *                   an exception is thrown.
208
     * @return the index of the exception that was added
209
     */
210
    int addException(int particle1, int particle2, double chargeProd, double sigma, double epsilon, bool replace = false);
211
212
    /**
     * Get the force field parameters for an interaction that should be calculated differently from others.
213
     * 
214
215
216
217
     * @param index      the index of the interaction for which to get parameters
     * @param particle1  the index of the first particle involved in the interaction
     * @param particle2  the index of the second particle involved in the interaction
     * @param chargeProd the scaled product of the atomic charges (i.e. the strength of the Coulomb interaction), measured in units of the proton charge squared
218
219
     * @param sigma      the sigma parameter of the Lennard-Jones potential (corresponding to the van der Waals radius of the particle), measured in nm
     * @param epsilon    the epsilon parameter of the Lennard-Jones potential (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
220
     */
221
    void getExceptionParameters(int index, int& particle1, int& particle2, double& chargeProd, double& sigma, double& epsilon) const;
222
    /**
223
224
225
     * Set the force field parameters for an interaction that should be calculated differently from others.
     * If chargeProd and epsilon are both equal to 0, this will cause the interaction to be completely omitted from
     * force and energy calculations.
226
     * 
227
228
229
230
     * @param index      the index of the interaction for which to get parameters
     * @param particle1  the index of the first particle involved in the interaction
     * @param particle2  the index of the second particle involved in the interaction
     * @param chargeProd the scaled product of the atomic charges (i.e. the strength of the Coulomb interaction), measured in units of the proton charge squared
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
     * @param sigma      the sigma parameter of the Lennard-Jones potential (corresponding to the van der Waals radius of the particle), measured in nm
     * @param epsilon    the epsilon parameter of the Lennard-Jones potential (corresponding to the well depth of the van der Waals interaction), measured in kJ/mol
     */
    void setExceptionParameters(int index, int particle1, int particle2, double chargeProd, double sigma, double epsilon);
    /**
     * Identify exceptions based on the molecular topology.  Particles which are separated by one or two bonds are set
     * to not interact at all, while pairs of particles separated by three bonds (known as "1-4 interactions") have
     * their Coulomb and Lennard-Jones interactions reduced by a fixed factor.
     *
     * @param bonds           the set of bonds based on which to construct exceptions.  Each element specifies the indices of
     *                        two particles that are bonded to each other.
     * @param coulomb14Scale  pairs of particles separated by three bonds will have the strength of their Coulomb interaction
     *                        multiplied by this factor
     * @param lj14Scale       pairs of particles separated by three bonds will have the strength of their Lennard-Jones interaction
     *                        multiplied by this factor
246
     */
247
    void createExceptionsFromBonds(const std::vector<std::pair<int, int> >& bonds, double coulomb14Scale, double lj14Scale);
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
    /**
     * Get whether to add a contribution to the energy that approximately represents the effect of Lennard-Jones
     * interactions beyond the cutoff distance.  The energy depends on the volume of the periodic box, and is only
     * applicable when periodic boundary conditions are used.  When running simulations at constant pressure, adding
     * this contribution can improve the quality of results.
     */
    bool getUseDispersionCorrection() const {
        return useDispersionCorrection;
    }
    /**
     * Set whether to add a contribution to the energy that approximately represents the effect of Lennard-Jones
     * interactions beyond the cutoff distance.  The energy depends on the volume of the periodic box, and is only
     * applicable when periodic boundary conditions are used.  When running simulations at constant pressure, adding
     * this contribution can improve the quality of results.
     */
    void setUseDispersionCorrection(bool useCorrection) {
        useDispersionCorrection = useCorrection;
    }
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
    /**
     * Get the force group that reciprocal space interactions for Ewald or PME are included in.  This allows multiple
     * time step integrators to evaluate direct and reciprocal space interactions at different intervals: getForceGroup()
     * specifies the group for direct space, and getReciprocalSpaceForceGroup() specifies the group for reciprocal space.
     * The default value is 0.
     */
    int getReciprocalSpaceForceGroup() const;
    /**
     * Set the force group that reciprocal space interactions for Ewald or PME are included in.  This allows multiple
     * time step integrators to evaluate direct and reciprocal space interactions at different intervals: setForceGroup()
     * specifies the group for direct space, and setReciprocalSpaceForceGroup() specifies the group for reciprocal space.
     * The default value is 0.
     * 
     * @param group    the group index.  Legal values are between 0 and 31 (inclusive).
     */
    void setReciprocalSpaceForceGroup(int group);
282
protected:
283
    ForceImpl* createImpl();
284
private:
Peter Eastman's avatar
Peter Eastman committed
285
    class ParticleInfo;
286
    class ExceptionInfo;
287
    NonbondedMethod nonbondedMethod;
288
    double cutoffDistance, rfDielectric, ewaldErrorTol;
289
    bool useDispersionCorrection;
290
    int recipForceGroup;
291
    void addExclusionsToSet(const std::vector<std::set<int> >& bonded12, std::set<int>& exclusions, int baseParticle, int fromParticle, int currentLevel) const;
Peter Eastman's avatar
Peter Eastman committed
292
    std::vector<ParticleInfo> particles;
293
    std::vector<ExceptionInfo> exceptions;
294
    std::map<std::pair<int, int>, int> exceptionMap;
295
296
};

297
298
299
300
/**
 * This is an internal class used to record information about a particle.
 * @private
 */
Peter Eastman's avatar
Peter Eastman committed
301
class NonbondedForce::ParticleInfo {
302
public:
303
    double charge, sigma, epsilon;
Peter Eastman's avatar
Peter Eastman committed
304
    ParticleInfo() {
305
        charge = sigma = epsilon = 0.0;
306
    }
307
308
309
    ParticleInfo(double charge, double sigma, double epsilon) :
        charge(charge), sigma(sigma), epsilon(epsilon) {
    }
310
311
};

312
313
314
315
/**
 * This is an internal class used to record information about an exception.
 * @private
 */
316
class NonbondedForce::ExceptionInfo {
317
public:
Peter Eastman's avatar
Peter Eastman committed
318
    int particle1, particle2;
319
    double chargeProd, sigma, epsilon;
320
    ExceptionInfo() {
Peter Eastman's avatar
Peter Eastman committed
321
        particle1 = particle2 = -1;
322
        chargeProd = sigma = epsilon = 0.0;
323
    }
324
325
326
    ExceptionInfo(int particle1, int particle2, double chargeProd, double sigma, double epsilon) :
        particle1(particle1), particle2(particle2), chargeProd(chargeProd), sigma(sigma), epsilon(epsilon) {
    }
327
328
};

329
330
} // namespace OpenMM

331
#endif /*OPENMM_NONBONDEDFORCE_H_*/