NonbondedForce.h 16.4 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
         */
        Ewald = 3
95
    };
96
    /**
97
     * Create a NonbondedForce.
98
     */
99
    NonbondedForce();
100
    /**
101
     * Get the number of particles for which force field parameters have been defined.
102
     */
Peter Eastman's avatar
Peter Eastman committed
103
104
    int getNumParticles() const {
        return particles.size();
105
    }
106
    /**
107
     * Get the number of special interactions that should be calculated differently from other interactions.
108
     */
109
110
    int getNumExceptions() const {
        return exceptions.size();
111
    }
112
113
114
    /**
     * Get the method used for handling long range nonbonded interactions.
     */
115
    NonbondedMethod getNonbondedMethod() const;
116
117
118
119
120
121
122
123
    /**
     * 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
     * does not use cutoffs, this value will have no effect.
     */
124
    double getCutoffDistance() const;
125
126
127
128
129
130
    /**
     * Set the cutoff distance (in nm) being used for nonbonded interactions.  If the NonbondedMethod in use
     * does not use cutoffs, this value will have no effect.
     */
    void setCutoffDistance(double distance);
    /**
131
132
     * 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.
133
     *
134
135
136
137
138
139
     * 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
140
     */
141
    void getPeriodicBoxVectors(Vec3& a, Vec3& b, Vec3& c) const;
142
    /**
143
144
145
146
147
     * 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.
148
     *
149
150
151
     * @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
152
     */
153
    void setPeriodicBoxVectors(Vec3 a, Vec3 b, Vec3 c);
154
155
156
157
158
159
160
161
162
163
164
165
    /**
     * 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
     */
    void addParticle(double charge, double sigma, double epsilon);
166
    /**
Peter Eastman's avatar
Peter Eastman committed
167
     * Get the nonbonded force parameters for a particle.
168
     *
Peter Eastman's avatar
Peter Eastman committed
169
170
     * @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
171
172
     * @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
173
     */
174
    void getParticleParameters(int index, double& charge, double& sigma, double& epsilon) const;
175
    /**
176
177
178
179
     * 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
180
181
     * @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
182
183
     * @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
184
     */
185
    void setParticleParameters(int index, double charge, double sigma, double epsilon);
186
    /**
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
     * 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
     */
    void addException(int particle1, int particle2, double chargeProd, double sigma, double epsilon);
    /**
     * Get the force field parameters for an interaction that should be calculated differently from others.
202
     * 
203
204
205
206
     * @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
207
208
     * @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
209
     */
210
    void getExceptionParameters(int index, int& particle1, int& particle2, double& chargeProd, double& sigma, double& epsilon) const;
211
    /**
212
213
214
     * 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.
215
     * 
216
217
218
219
     * @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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
     * @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
235
     */
236
    void createExceptionsFromBonds(const std::vector<std::pair<int, int> >& bonds, double coulomb14Scale, double lj14Scale);
237
protected:
238
    ForceImpl* createImpl();
239
private:
Peter Eastman's avatar
Peter Eastman committed
240
    class ParticleInfo;
241
    class ExceptionInfo;
242
243
    NonbondedMethod nonbondedMethod;
    double cutoffDistance;
244
    Vec3 periodicBoxVectors[3];
245
246
    void addExclusionsToSet(const std::vector<std::set<int> >& bonded12, std::set<int>& exclusions, int baseParticle, int fromParticle, int currentLevel) const;

247

248
249
250
251
252
253
// 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)
254
#endif
Peter Eastman's avatar
Peter Eastman committed
255
    std::vector<ParticleInfo> particles;
256
    std::vector<ExceptionInfo> exceptions;
257
258
259
260
#if defined(_MSC_VER)
#pragma warning(pop)
#endif

261
262
};

Peter Eastman's avatar
Peter Eastman committed
263
class NonbondedForce::ParticleInfo {
264
public:
265
    double charge, sigma, epsilon;
Peter Eastman's avatar
Peter Eastman committed
266
    ParticleInfo() {
267
        charge = sigma = epsilon = 0.0;
268
    }
269
270
271
    ParticleInfo(double charge, double sigma, double epsilon) :
        charge(charge), sigma(sigma), epsilon(epsilon) {
    }
272
273
};

274
class NonbondedForce::ExceptionInfo {
275
public:
Peter Eastman's avatar
Peter Eastman committed
276
    int particle1, particle2;
277
    double chargeProd, sigma, epsilon;
278
    ExceptionInfo() {
Peter Eastman's avatar
Peter Eastman committed
279
        particle1 = particle2 = -1;
280
        chargeProd = sigma = epsilon = 0.0;
281
    }
282
283
284
    ExceptionInfo(int particle1, int particle2, double chargeProd, double sigma, double epsilon) :
        particle1(particle1), particle2(particle2), chargeProd(chargeProd), sigma(sigma), epsilon(epsilon) {
    }
285
286
};

287
288
} // namespace OpenMM

289
#endif /*OPENMM_NONBONDEDFORCE_H_*/