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.Pointer;
41  import com.sun.jna.ptr.PointerByReference;
42  
43  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Boolean.OpenMM_True;
44  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_addCollectiveVariable;
45  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_addEnergyParameterDerivative;
46  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_addGlobalParameter;
47  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_addTabulatedFunction;
48  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_create;
49  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_destroy;
50  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_getCollectiveVariable;
51  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_getCollectiveVariableName;
52  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_getCollectiveVariableValues;
53  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_getEnergyFunction;
54  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_getEnergyParameterDerivativeName;
55  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_getGlobalParameterDefaultValue;
56  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_getGlobalParameterName;
57  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_getInnerContext;
58  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_getNumCollectiveVariables;
59  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_getNumEnergyParameterDerivatives;
60  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_getNumGlobalParameters;
61  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_getNumTabulatedFunctions;
62  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_getTabulatedFunction;
63  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_getTabulatedFunctionName;
64  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_setEnergyFunction;
65  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_setGlobalParameterDefaultValue;
66  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_setGlobalParameterName;
67  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_updateParametersInContext;
68  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomCVForce_usesPeriodicBoundaryConditions;
69  
70  /**
71   * This class supports energy functions that depend on collective variables. To use it,
72   * you define a set of collective variables (scalar valued functions that depend on the
73   * particle positions), and an algebraic expression for the energy as a function of the
74   * collective variables. The expression also may involve tabulated functions, and may
75   * depend on arbitrary global parameters.
76   * <p>
77   * Each collective variable is defined by a Force object. The Force's potential energy
78   * is computed, and that becomes the value of the variable. This provides enormous
79   * flexibility in defining collective variables, especially by using custom forces.
80   * Anything that can be computed as a potential function can also be used as a collective
81   * variable.
82   * <p>
83   * To use this class, create a CustomCVForce object, passing an algebraic expression to the
84   * constructor that defines the potential energy. Then call addCollectiveVariable() to define
85   * collective variables and addGlobalParameter() to define global parameters. The values
86   * of global parameters may be modified during a simulation by calling Context::setParameter().
87   * <p>
88   * This class also has the ability to compute derivatives of the potential energy with respect to global parameters.
89   * Call addEnergyParameterDerivative() to request that the derivative with respect to a particular parameter be
90   * computed. You can then query its value in a Context by calling getState() on it.
91   * <p>
92   * Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following
93   * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, atan2, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions
94   * are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise.
95   * select(x,y,z) = z if x = 0, y otherwise.
96   * <p>
97   * In addition, you can call addTabulatedFunction() to define a new function based on tabulated values. You specify the function by
98   * creating a TabulatedFunction object. That function can then appear in the expression.
99   */
100 public class CustomCVForce extends Force {
101 
102   /**
103    * Create a new CustomCVForce.
104    *
105    * @param energy The energy function as an algebraic expression.
106    */
107   public CustomCVForce(String energy) {
108     super(OpenMM_CustomCVForce_create(energy));
109   }
110 
111   /**
112    * Add a collective variable to the force.
113    *
114    * @param name  The name of the collective variable.
115    * @param force The Force object that defines the collective variable.
116    * @return The index of the collective variable that was added.
117    */
118   public int addCollectiveVariable(String name, PointerByReference force) {
119     return OpenMM_CustomCVForce_addCollectiveVariable(pointer, name, force);
120   }
121 
122   /**
123    * Add a collective variable to the force.
124    *
125    * @param name  The name of the collective variable.
126    * @param force The Force object that defines the collective variable.
127    * @return The index of the collective variable that was added.
128    */
129   public int addCollectiveVariable(Pointer name, PointerByReference force) {
130     return OpenMM_CustomCVForce_addCollectiveVariable(pointer, name, force);
131   }
132 
133   /**
134    * Add an energy parameter derivative to the force.
135    *
136    * @param name The name of the parameter to compute the derivative with respect to.
137    */
138   public void addEnergyParameterDerivative(String name) {
139     OpenMM_CustomCVForce_addEnergyParameterDerivative(pointer, name);
140   }
141 
142   /**
143    * Add an energy parameter derivative to the force.
144    *
145    * @param name The name of the parameter to compute the derivative with respect to.
146    */
147   public void addEnergyParameterDerivative(Pointer name) {
148     OpenMM_CustomCVForce_addEnergyParameterDerivative(pointer, name);
149   }
150 
151   /**
152    * Add a global parameter to the force.
153    *
154    * @param name         The name of the parameter.
155    * @param defaultValue The default value of the parameter.
156    * @return The index of the parameter that was added.
157    */
158   public int addGlobalParameter(String name, double defaultValue) {
159     return OpenMM_CustomCVForce_addGlobalParameter(pointer, name, defaultValue);
160   }
161 
162   /**
163    * Add a global parameter to the force.
164    *
165    * @param name         The name of the parameter.
166    * @param defaultValue The default value of the parameter.
167    * @return The index of the parameter that was added.
168    */
169   public int addGlobalParameter(Pointer name, double defaultValue) {
170     return OpenMM_CustomCVForce_addGlobalParameter(pointer, name, defaultValue);
171   }
172 
173   /**
174    * Add a tabulated function to the force.
175    *
176    * @param name     The name of the function as it appears in expressions.
177    * @param function A TabulatedFunction object defining the function.
178    * @return The index of the function that was added.
179    */
180   public int addTabulatedFunction(String name, TabulatedFunction function) {
181     return OpenMM_CustomCVForce_addTabulatedFunction(pointer, name, function.getPointer());
182   }
183 
184   /**
185    * Add a tabulated function to the force.
186    *
187    * @param name     The name of the function as it appears in expressions.
188    * @param function A TabulatedFunction object defining the function.
189    * @return The index of the function that was added.
190    */
191   public int addTabulatedFunction(Pointer name, TabulatedFunction function) {
192     return OpenMM_CustomCVForce_addTabulatedFunction(pointer, name, function.getPointer());
193   }
194 
195   /**
196    * Destroy the force.
197    */
198   @Override
199   public void destroy() {
200     if (pointer != null) {
201       OpenMM_CustomCVForce_destroy(pointer);
202       pointer = null;
203     }
204   }
205 
206   /**
207    * Get a collective variable by index.
208    *
209    * @param index The index of the collective variable.
210    * @return The Force object that defines the collective variable.
211    */
212   public PointerByReference getCollectiveVariable(int index) {
213     return OpenMM_CustomCVForce_getCollectiveVariable(pointer, index);
214   }
215 
216   /**
217    * Get the name of a collective variable.
218    *
219    * @param index The index of the collective variable.
220    * @return The name of the collective variable.
221    */
222   public String getCollectiveVariableName(int index) {
223     Pointer p = OpenMM_CustomCVForce_getCollectiveVariableName(pointer, index);
224     if (p == null) {
225       return null;
226     }
227     return p.getString(0);
228   }
229 
230   /**
231    * Get the values of all collective variables in a given context.
232    *
233    * @param context The context for which to get the values.
234    * @param values  The values of the collective variables (output).
235    */
236   public void getCollectiveVariableValues(Context context, PointerByReference values) {
237     OpenMM_CustomCVForce_getCollectiveVariableValues(pointer, context.getPointer(), values);
238   }
239 
240   /**
241    * Get the energy function.
242    *
243    * @return The energy function as an algebraic expression.
244    */
245   public String getEnergyFunction() {
246     Pointer p = OpenMM_CustomCVForce_getEnergyFunction(pointer);
247     if (p == null) {
248       return null;
249     }
250     return p.getString(0);
251   }
252 
253   /**
254    * Get the name of an energy parameter derivative.
255    *
256    * @param index The index of the parameter derivative.
257    * @return The name of the parameter derivative.
258    */
259   public String getEnergyParameterDerivativeName(int index) {
260     Pointer p = OpenMM_CustomCVForce_getEnergyParameterDerivativeName(pointer, index);
261     if (p == null) {
262       return null;
263     }
264     return p.getString(0);
265   }
266 
267   /**
268    * Get the default value of a global parameter.
269    *
270    * @param index The index of the parameter.
271    * @return The default value of the parameter.
272    */
273   public double getGlobalParameterDefaultValue(int index) {
274     return OpenMM_CustomCVForce_getGlobalParameterDefaultValue(pointer, index);
275   }
276 
277   /**
278    * Get the name of a global parameter.
279    *
280    * @param index The index of the parameter.
281    * @return The name of the parameter.
282    */
283   public String getGlobalParameterName(int index) {
284     Pointer p = OpenMM_CustomCVForce_getGlobalParameterName(pointer, index);
285     if (p == null) {
286       return null;
287     }
288     return p.getString(0);
289   }
290 
291   /**
292    * Get the inner context used for evaluating collective variables.
293    *
294    * @param context The main context.
295    * @return The inner context.
296    */
297   public PointerByReference getInnerContext(Context context) {
298     return OpenMM_CustomCVForce_getInnerContext(pointer, context.getPointer());
299   }
300 
301   /**
302    * Get the number of collective variables.
303    *
304    * @return The number of collective variables.
305    */
306   public int getNumCollectiveVariables() {
307     return OpenMM_CustomCVForce_getNumCollectiveVariables(pointer);
308   }
309 
310   /**
311    * Get the number of energy parameter derivatives.
312    *
313    * @return The number of energy parameter derivatives.
314    */
315   public int getNumEnergyParameterDerivatives() {
316     return OpenMM_CustomCVForce_getNumEnergyParameterDerivatives(pointer);
317   }
318 
319   /**
320    * Get the number of global parameters.
321    *
322    * @return The number of global parameters.
323    */
324   public int getNumGlobalParameters() {
325     return OpenMM_CustomCVForce_getNumGlobalParameters(pointer);
326   }
327 
328   /**
329    * Get the number of tabulated functions.
330    *
331    * @return The number of tabulated functions.
332    */
333   public int getNumTabulatedFunctions() {
334     return OpenMM_CustomCVForce_getNumTabulatedFunctions(pointer);
335   }
336 
337   /**
338    * Get a tabulated function by index.
339    *
340    * @param index The index of the function.
341    * @return The TabulatedFunction object.
342    */
343   public PointerByReference getTabulatedFunction(int index) {
344     return OpenMM_CustomCVForce_getTabulatedFunction(pointer, index);
345   }
346 
347   /**
348    * Get the name of a tabulated function.
349    *
350    * @param index The index of the function.
351    * @return The name of the function as it appears in expressions.
352    */
353   public String getTabulatedFunctionName(int index) {
354     Pointer p = OpenMM_CustomCVForce_getTabulatedFunctionName(pointer, index);
355     if (p == null) {
356       return null;
357     }
358     return p.getString(0);
359   }
360 
361   /**
362    * Set the energy function.
363    *
364    * @param energy The energy function as an algebraic expression.
365    */
366   public void setEnergyFunction(String energy) {
367     OpenMM_CustomCVForce_setEnergyFunction(pointer, energy);
368   }
369 
370   /**
371    * Set the energy function.
372    *
373    * @param energy The energy function as an algebraic expression.
374    */
375   public void setEnergyFunction(Pointer energy) {
376     OpenMM_CustomCVForce_setEnergyFunction(pointer, energy);
377   }
378 
379   /**
380    * Set the default value of a global parameter.
381    *
382    * @param index        The index of the parameter.
383    * @param defaultValue The default value of the parameter.
384    */
385   public void setGlobalParameterDefaultValue(int index, double defaultValue) {
386     OpenMM_CustomCVForce_setGlobalParameterDefaultValue(pointer, index, defaultValue);
387   }
388 
389   /**
390    * Set the name of a global parameter.
391    *
392    * @param index The index of the parameter.
393    * @param name  The name of the parameter.
394    */
395   public void setGlobalParameterName(int index, String name) {
396     OpenMM_CustomCVForce_setGlobalParameterName(pointer, index, name);
397   }
398 
399   /**
400    * Set the name of a global parameter.
401    *
402    * @param index The index of the parameter.
403    * @param name  The name of the parameter.
404    */
405   public void setGlobalParameterName(int index, Pointer name) {
406     OpenMM_CustomCVForce_setGlobalParameterName(pointer, index, name);
407   }
408 
409   /**
410    * Update the parameters in a Context to match those stored in this Force object.
411    *
412    * @param context The Context in which to update the parameters.
413    */
414   public void updateParametersInContext(Context context) {
415     if (context.hasContextPointer()) {
416       OpenMM_CustomCVForce_updateParametersInContext(pointer, context.getPointer());
417     }
418   }
419 
420   /**
421    * Check if the force uses periodic boundary conditions.
422    *
423    * @return True if the force uses periodic boundary conditions.
424    */
425   @Override
426   public boolean usesPeriodicBoundaryConditions() {
427     int pbc = OpenMM_CustomCVForce_usesPeriodicBoundaryConditions(pointer);
428     return pbc == OpenMM_True;
429   }
430 }