View Javadoc
1   // ******************************************************************************
2   //
3   // Title:       Force Field X.
4   // Description: Force Field X - Software for Molecular Biophysics.
5   // Copyright:   Copyright (c) Michael J. Schnieders 2001-2025.
6   //
7   // This file is part of Force Field X.
8   //
9   // Force Field X is free software; you can redistribute it and/or modify it
10  // under the terms of the GNU General Public License version 3 as published by
11  // the Free Software Foundation.
12  //
13  // Force Field X is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16  // details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA 02111-1307 USA
21  //
22  // Linking this library statically or dynamically with other modules is making a
23  // combined work based on this library. Thus, the terms and conditions of the
24  // GNU General Public License cover the whole combination.
25  //
26  // As a special exception, the copyright holders of this library give you
27  // permission to link this library with independent modules to produce an
28  // executable, regardless of the license terms of these independent modules, and
29  // to copy and distribute the resulting executable under terms of your choice,
30  // provided that you also meet, for each linked independent module, the terms
31  // and conditions of the license of that module. An independent module is a
32  // module which is not derived from or based on this library. If you modify this
33  // library, you may extend this exception to your version of the library, but
34  // you are not obligated to do so. If you do not wish to do so, delete this
35  // exception statement from your version.
36  //
37  // ******************************************************************************
38  package ffx.openmm;
39  
40  import com.sun.jna.ptr.DoubleByReference;
41  import com.sun.jna.ptr.IntByReference;
42  
43  import java.nio.DoubleBuffer;
44  import java.nio.IntBuffer;
45  
46  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Boolean.OpenMM_True;
47  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_addException;
48  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_addParticle;
49  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_create;
50  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_destroy;
51  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_getCutoffDistance;
52  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_getExceptionParameters;
53  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_getNonbondedMethod;
54  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_getNumExceptions;
55  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_getNumParticles;
56  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_getParticleParameters;
57  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_getSwitchingDistance;
58  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_getUseSwitchingFunction;
59  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_setCutoffDistance;
60  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_setExceptionParameters;
61  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_setNonbondedMethod;
62  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_setParticleParameters;
63  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_setSwitchingDistance;
64  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_setUseSwitchingFunction;
65  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_updateParametersInContext;
66  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GayBerneForce_usesPeriodicBoundaryConditions;
67  
68  /**
69   * This class implements the Gay-Berne anisotropic potential.  This is similar to a Lennard-Jones potential,
70   * but it represents the particles as ellipsoids rather than point particles.  In addition to the standard
71   * sigma and epsilon parameters, each particle has three widths sx, sy, and sz that give the diameter of the
72   * ellipsoid along each axis.  It also has three scale factors ex, ey, and ez that scale the strength
73   * of the interaction along each axis.  You can think of this force as a Lennard-Jones interaction computed
74   * based on the distance between the nearest points on two ellipsoids.  The scale factors act as multipliers
75   * for epsilon along each axis, so the strength of the interaction along the ellipsoid's x axis is multiplied by
76   * ex, and likewise for the other axes.  If two particles each have all their widths set to sigma and all their
77   * scale factors set to 1, the interaction simplifies to a standard Lennard-Jones force between point particles.
78   * <p>
79   * The orientation of a particle's ellipsoid is determined based on the positions of two other particles.
80   * The vector to the first particle sets the direction of the x axis.  The vector to the second particle
81   * (after subtracting out any x component) sets the direction of the y axis.  If the ellipsoid is axially
82   * symmetric (sy=sz and ey=ez), you can omit the second particle and define only an x axis direction.
83   * If the ellipsoid is a sphere (all three widths and all three scale factors are equal), both particles
84   * can be omitted.
85   * <p>
86   * To determine the values of sigma and epsilon for an interaction, this class uses Lorentz-Berthelot
87   * combining rules: it takes the arithmetic mean of the sigmas and the geometric mean of the epsilons for
88   * the two interacting particles.  You also can specify "exceptions", particular pairs of particles for
89   * which different values should be used.
90   * <p>
91   * To use this class, create a GayBerneForce object, then call addParticle() once for each particle in the
92   * System to define its parameters.  The number of particles for which you define parameters must be exactly
93   * equal to the number of particles in the System, or else an exception will be thrown when you try to
94   * create a Context.  After a particle has been added, you can modify its force field parameters by calling
95   * setParticleParameters().  This will have no effect on Contexts that already exist unless you call
96   * updateParametersInContext().
97   * <p>
98   * When using a cutoff, by default interactions are sharply truncated at the cutoff distance.  Optionally
99   * you can instead use a switching function to make the interaction smoothly go to zero over a finite
100  * distance range.  To enable this, call setUseSwitchingFunction().  You must also call setSwitchingDistance()
101  * to specify the distance at which the interaction should begin to decrease.  The switching distance must be
102  * less than the cutoff distance.
103  */
104 public class GayBerneForce extends Force {
105 
106   /**
107    * Create a new GayBerneForce.
108    */
109   public GayBerneForce() {
110     super(OpenMM_GayBerneForce_create());
111   }
112 
113   /**
114    * Add an exception to the force.
115    *
116    * @param particle1 The index of the first particle.
117    * @param particle2 The index of the second particle.
118    * @param sigma     The sigma parameter for the exception.
119    * @param epsilon   The epsilon parameter for the exception.
120    * @param replace   Whether to replace an existing exception.
121    * @return The index of the exception that was added.
122    */
123   public int addException(int particle1, int particle2, double sigma, double epsilon, int replace) {
124     return OpenMM_GayBerneForce_addException(pointer, particle1, particle2, sigma, epsilon, replace);
125   }
126 
127   /**
128    * Add a particle to the force.
129    *
130    * @param sigma     The sigma parameter.
131    * @param epsilon   The epsilon parameter.
132    * @param xparticle The x-axis particle type.
133    * @param yparticle The y-axis particle type.
134    * @param ex        The x-axis shape parameter.
135    * @param ey        The y-axis shape parameter.
136    * @param ez        The z-axis shape parameter.
137    * @param sx        The x-axis strength parameter.
138    * @param sy        The y-axis strength parameter.
139    * @param sz        The z-axis strength parameter.
140    * @return The index of the particle that was added.
141    */
142   public int addParticle(double sigma, double epsilon, int xparticle, int yparticle,
143                          double ex, double ey, double ez, double sx, double sy, double sz) {
144     return OpenMM_GayBerneForce_addParticle(pointer, sigma, epsilon, xparticle, yparticle,
145         ex, ey, ez, sx, sy, sz);
146   }
147 
148   /**
149    * Destroy the force.
150    */
151   @Override
152   public void destroy() {
153     if (pointer != null) {
154       OpenMM_GayBerneForce_destroy(pointer);
155       pointer = null;
156     }
157   }
158 
159   /**
160    * Get the cutoff distance.
161    *
162    * @return The cutoff distance, measured in nm.
163    */
164   public double getCutoffDistance() {
165     return OpenMM_GayBerneForce_getCutoffDistance(pointer);
166   }
167 
168   /**
169    * Get the parameters for an exception.
170    *
171    * @param index     The index of the exception.
172    * @param particle1 The index of the first particle (output).
173    * @param particle2 The index of the second particle (output).
174    * @param sigma     The sigma parameter for the exception (output).
175    * @param epsilon   The epsilon parameter for the exception (output).
176    */
177   public void getExceptionParameters(int index, IntByReference particle1, IntByReference particle2,
178                                      DoubleByReference sigma, DoubleByReference epsilon) {
179     OpenMM_GayBerneForce_getExceptionParameters(pointer, index, particle1, particle2, sigma, epsilon);
180   }
181 
182   /**
183    * Get the parameters for an exception.
184    *
185    * @param index     The index of the exception.
186    * @param particle1 The index of the first particle (output).
187    * @param particle2 The index of the second particle (output).
188    * @param sigma     The sigma parameter for the exception (output).
189    * @param epsilon   The epsilon parameter for the exception (output).
190    */
191   public void getExceptionParameters(int index, IntBuffer particle1, IntBuffer particle2,
192                                      DoubleBuffer sigma, DoubleBuffer epsilon) {
193     OpenMM_GayBerneForce_getExceptionParameters(pointer, index, particle1, particle2, sigma, epsilon);
194   }
195 
196   /**
197    * Get the nonbonded method.
198    *
199    * @return The nonbonded method.
200    */
201   public int getNonbondedMethod() {
202     return OpenMM_GayBerneForce_getNonbondedMethod(pointer);
203   }
204 
205   /**
206    * Get the number of exceptions.
207    *
208    * @return The number of exceptions.
209    */
210   public int getNumExceptions() {
211     return OpenMM_GayBerneForce_getNumExceptions(pointer);
212   }
213 
214   /**
215    * Get the number of particles.
216    *
217    * @return The number of particles.
218    */
219   public int getNumParticles() {
220     return OpenMM_GayBerneForce_getNumParticles(pointer);
221   }
222 
223   /**
224    * Get the parameters for a particle.
225    *
226    * @param index     The index of the particle.
227    * @param sigma     The sigma parameter (output).
228    * @param epsilon   The epsilon parameter (output).
229    * @param xparticle The x-axis particle type (output).
230    * @param yparticle The y-axis particle type (output).
231    * @param ex        The x-axis shape parameter (output).
232    * @param ey        The y-axis shape parameter (output).
233    * @param ez        The z-axis shape parameter (output).
234    * @param sx        The x-axis strength parameter (output).
235    * @param sy        The y-axis strength parameter (output).
236    * @param sz        The z-axis strength parameter (output).
237    */
238   public void getParticleParameters(int index, DoubleByReference sigma, DoubleByReference epsilon,
239                                     IntByReference xparticle, IntByReference yparticle,
240                                     DoubleByReference ex, DoubleByReference ey, DoubleByReference ez,
241                                     DoubleByReference sx, DoubleByReference sy, DoubleByReference sz) {
242     OpenMM_GayBerneForce_getParticleParameters(pointer, index, sigma, epsilon, xparticle, yparticle,
243         ex, ey, ez, sx, sy, sz);
244   }
245 
246   /**
247    * Get the parameters for a particle.
248    *
249    * @param index     The index of the particle.
250    * @param sigma     The sigma parameter (output).
251    * @param epsilon   The epsilon parameter (output).
252    * @param xparticle The x-axis particle type (output).
253    * @param yparticle The y-axis particle type (output).
254    * @param ex        The x-axis shape parameter (output).
255    * @param ey        The y-axis shape parameter (output).
256    * @param ez        The z-axis shape parameter (output).
257    * @param sx        The x-axis strength parameter (output).
258    * @param sy        The y-axis strength parameter (output).
259    * @param sz        The z-axis strength parameter (output).
260    */
261   public void getParticleParameters(int index, DoubleBuffer sigma, DoubleBuffer epsilon,
262                                     IntBuffer xparticle, IntBuffer yparticle,
263                                     DoubleBuffer ex, DoubleBuffer ey, DoubleBuffer ez,
264                                     DoubleBuffer sx, DoubleBuffer sy, DoubleBuffer sz) {
265     OpenMM_GayBerneForce_getParticleParameters(pointer, index, sigma, epsilon, xparticle, yparticle,
266         ex, ey, ez, sx, sy, sz);
267   }
268 
269   /**
270    * Get the switching distance.
271    *
272    * @return The switching distance, measured in nm.
273    */
274   public double getSwitchingDistance() {
275     return OpenMM_GayBerneForce_getSwitchingDistance(pointer);
276   }
277 
278   /**
279    * Get whether a switching function is used.
280    *
281    * @return 1 if a switching function is used, 0 otherwise.
282    */
283   public int getUseSwitchingFunction() {
284     return OpenMM_GayBerneForce_getUseSwitchingFunction(pointer);
285   }
286 
287   /**
288    * Set the cutoff distance.
289    *
290    * @param distance The cutoff distance, measured in nm.
291    */
292   public void setCutoffDistance(double distance) {
293     OpenMM_GayBerneForce_setCutoffDistance(pointer, distance);
294   }
295 
296   /**
297    * Set the parameters for an exception.
298    *
299    * @param index     The index of the exception.
300    * @param particle1 The index of the first particle.
301    * @param particle2 The index of the second particle.
302    * @param sigma     The sigma parameter for the exception.
303    * @param epsilon   The epsilon parameter for the exception.
304    */
305   public void setExceptionParameters(int index, int particle1, int particle2, double sigma, double epsilon) {
306     OpenMM_GayBerneForce_setExceptionParameters(pointer, index, particle1, particle2, sigma, epsilon);
307   }
308 
309   /**
310    * Set the nonbonded method.
311    *
312    * @param method The nonbonded method.
313    */
314   public void setNonbondedMethod(int method) {
315     OpenMM_GayBerneForce_setNonbondedMethod(pointer, method);
316   }
317 
318   /**
319    * Set the parameters for a particle.
320    *
321    * @param index     The index of the particle.
322    * @param sigma     The sigma parameter.
323    * @param epsilon   The epsilon parameter.
324    * @param xparticle The x-axis particle type.
325    * @param yparticle The y-axis particle type.
326    * @param ex        The x-axis shape parameter.
327    * @param ey        The y-axis shape parameter.
328    * @param ez        The z-axis shape parameter.
329    * @param sx        The x-axis strength parameter.
330    * @param sy        The y-axis strength parameter.
331    * @param sz        The z-axis strength parameter.
332    */
333   public void setParticleParameters(int index, double sigma, double epsilon, int xparticle, int yparticle,
334                                     double ex, double ey, double ez, double sx, double sy, double sz) {
335     OpenMM_GayBerneForce_setParticleParameters(pointer, index, sigma, epsilon, xparticle, yparticle,
336         ex, ey, ez, sx, sy, sz);
337   }
338 
339   /**
340    * Set the switching distance.
341    *
342    * @param distance The switching distance, measured in nm.
343    */
344   public void setSwitchingDistance(double distance) {
345     OpenMM_GayBerneForce_setSwitchingDistance(pointer, distance);
346   }
347 
348   /**
349    * Set whether to use a switching function.
350    *
351    * @param use 1 to use a switching function, 0 otherwise.
352    */
353   public void setUseSwitchingFunction(int use) {
354     OpenMM_GayBerneForce_setUseSwitchingFunction(pointer, use);
355   }
356 
357   /**
358    * Update the parameters in a Context to match those stored in this Force object.
359    *
360    * @param context The Context in which to update the parameters.
361    */
362   public void updateParametersInContext(Context context) {
363     if (context.hasContextPointer()) {
364       OpenMM_GayBerneForce_updateParametersInContext(pointer, context.getPointer());
365     }
366   }
367 
368   /**
369    * Check if the force uses periodic boundary conditions.
370    *
371    * @return True if the force uses periodic boundary conditions.
372    */
373   @Override
374   public boolean usesPeriodicBoundaryConditions() {
375     int pbc = OpenMM_GayBerneForce_usesPeriodicBoundaryConditions(pointer);
376     return pbc == OpenMM_True;
377   }
378 }