NonbondedForce.h 17.7 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-2009 Stanford University and the Authors.      *
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 * 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"
36
#include "Vec3.h"
37
#include <map>
38
#include <set>
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
54
55
56
57
58
59
60
61
62
63
64
65
 *
 * 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
 * try to create an OpenMMContext.  After a particle has been added, you can modify its force field parameters
 * 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
    double getCutoffDistance() const;
130
131
    /**
     * Set the cutoff distance (in nm) being used for nonbonded interactions.  If the NonbondedMethod in use
132
     * is NoCutoff, this value will have no effect.
133
134
     */
    void setCutoffDistance(double distance);
135
136
137
138
139
140
141
142
143
144
145
146
147
148
    /**
     * 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);
149
    /**
150
151
     * Get the vectors which define the axes of the periodic box (measured in nm).  If the NonbondedMethod
     * in use does not use periodic boundary conditions, these values will have no effect.
152
     *
153
154
155
156
157
158
     * Currently, only rectangular boxes are supported.  This means that a, b, and c must be aligned with the
     * x, y, and z axes respectively.  Future releases may support arbitrary triclinic boxes.
     *
     * @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
159
     */
160
    void getPeriodicBoxVectors(Vec3& a, Vec3& b, Vec3& c) const;
161
    /**
162
163
164
165
166
     * Set the vectors which define the axes of the periodic box (measured in nm).  If the NonbondedMethod
     * in use does not use periodic boundary conditions, these values will have no effect.
     *
     * Currently, only rectangular boxes are supported.  This means that a, b, and c must be aligned with the
     * x, y, and z axes respectively.  Future releases may support arbitrary triclinic boxes.
167
     *
168
169
170
     * @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
171
     */
172
    void setPeriodicBoxVectors(Vec3 a, Vec3 b, Vec3 c);
173
174
175
176
177
178
179
180
181
182
    /**
     * 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
183
     * @return the index of the particle that was added
184
     */
185
    int addParticle(double charge, double sigma, double epsilon);
186
    /**
Peter Eastman's avatar
Peter Eastman committed
187
     * Get the nonbonded force parameters for a particle.
188
     *
Peter Eastman's avatar
Peter Eastman committed
189
190
     * @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
191
192
     * @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
193
     */
194
    void getParticleParameters(int index, double& charge, double& sigma, double& epsilon) const;
195
    /**
196
197
198
199
     * 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
200
201
     * @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
202
203
     * @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
204
     */
205
    void setParticleParameters(int index, double charge, double sigma, double epsilon);
206
    /**
207
208
209
210
211
212
213
214
215
216
217
     * 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
218
     * @return the index of the exception that was added
219
     */
220
    int addException(int particle1, int particle2, double chargeProd, double sigma, double epsilon);
221
222
    /**
     * Get the force field parameters for an interaction that should be calculated differently from others.
223
     * 
224
225
226
227
     * @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
228
229
     * @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
230
     */
231
    void getExceptionParameters(int index, int& particle1, int& particle2, double& chargeProd, double& sigma, double& epsilon) const;
232
    /**
233
234
235
     * 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.
236
     * 
237
238
239
240
     * @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
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
     * @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
256
     */
257
    void createExceptionsFromBonds(const std::vector<std::pair<int, int> >& bonds, double coulomb14Scale, double lj14Scale);
258
protected:
259
    ForceImpl* createImpl();
260
private:
Peter Eastman's avatar
Peter Eastman committed
261
    class ParticleInfo;
262
    class ExceptionInfo;
263
    NonbondedMethod nonbondedMethod;
264
    double cutoffDistance, ewaldErrorTol;
265
    Vec3 periodicBoxVectors[3];
266
267
    void addExclusionsToSet(const std::vector<std::set<int> >& bonded12, std::set<int>& exclusions, int baseParticle, int fromParticle, int currentLevel) const;

268

269
270
271
272
273
274
// Retarded visual studio compiler complains about being unable to 
// export private stl class members.
// This stanza explains that it should temporarily shut up.
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4251)
275
#endif
Peter Eastman's avatar
Peter Eastman committed
276
    std::vector<ParticleInfo> particles;
277
    std::vector<ExceptionInfo> exceptions;
278
279
280
281
#if defined(_MSC_VER)
#pragma warning(pop)
#endif

282
283
};

Peter Eastman's avatar
Peter Eastman committed
284
class NonbondedForce::ParticleInfo {
285
public:
286
    double charge, sigma, epsilon;
Peter Eastman's avatar
Peter Eastman committed
287
    ParticleInfo() {
288
        charge = sigma = epsilon = 0.0;
289
    }
290
291
292
    ParticleInfo(double charge, double sigma, double epsilon) :
        charge(charge), sigma(sigma), epsilon(epsilon) {
    }
293
294
};

295
class NonbondedForce::ExceptionInfo {
296
public:
Peter Eastman's avatar
Peter Eastman committed
297
    int particle1, particle2;
298
    double chargeProd, sigma, epsilon;
299
    ExceptionInfo() {
Peter Eastman's avatar
Peter Eastman committed
300
        particle1 = particle2 = -1;
301
        chargeProd = sigma = epsilon = 0.0;
302
    }
303
304
305
    ExceptionInfo(int particle1, int particle2, double chargeProd, double sigma, double epsilon) :
        particle1(particle1), particle2(particle2), chargeProd(chargeProd), sigma(sigma), epsilon(epsilon) {
    }
306
307
};

308
309
} // namespace OpenMM

310
#endif /*OPENMM_NONBONDEDFORCE_H_*/