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  
42  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Boolean.OpenMM_True;
43  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomVolumeForce_addGlobalParameter;
44  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomVolumeForce_create;
45  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomVolumeForce_destroy;
46  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomVolumeForce_getEnergyFunction;
47  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomVolumeForce_getGlobalParameterDefaultValue;
48  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomVolumeForce_getGlobalParameterName;
49  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomVolumeForce_getNumGlobalParameters;
50  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomVolumeForce_setEnergyFunction;
51  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomVolumeForce_setGlobalParameterDefaultValue;
52  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomVolumeForce_setGlobalParameterName;
53  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomVolumeForce_usesPeriodicBoundaryConditions;
54  
55  /**
56   * This class computes an energy that depends only on the volume of the periodic box, or more generally
57   * on the box shape as specified by the elements of the box vectors.  Because the energy does not
58   * depend on particle positions, it does not apply any forces to particles.  It is primarily useful
59   * for constant pressure simulations, where the volume-dependent energy can influence the behavior
60   * of the barostat.  Energy terms of this sort are often used for pressure matching in coarse grained
61   * force fields.
62   *
63   * <p>To use this class, create a CustomVolumeForce object, passing an algebraic expression to the constructor
64   * that defines the energy.  The expression may depend on the following variables.
65   *
66   * <ul>
67   * <li>v: The volume of the periodic box in nm^3.</li>
68   * <li>ax: The x component of the first box vector in nm.  (The y and z components are always zero.)</li>
69   * <li>bx, by: The x and y components of the second box vector in nm.  (The z component is always zero.)</li>
70   * <li>cx, cy, cz: The x, y and z components of the third box vector in nm.</li>
71   * <li>Global parameters that you define by calling addGlobalParameter().</li>
72   * </ul>
73   *
74   * <p>The initial value of a global parameter is specified in the call to addGlobalParameter().  Their values
75   * can be modified during a simulation by calling Context::setParameter().
76   *
77   * <p>Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following
78   * 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
79   * are defined in radians, and log is the natural logarithm.  step(x) = 0 if x &lt; 0, 1 otherwise.  delta(x) = 1 if x = 0, 0 otherwise.
80   * select(x,y,z) = z if x = 0, y otherwise.
81   */
82  public class CustomVolumeForce extends Force {
83  
84    /**
85     * Create a CustomVolumeForce.
86     *
87     * @param energy an algebraic expression giving the energy as a function of the box shape
88     */
89    public CustomVolumeForce(String energy) {
90      super(OpenMM_CustomVolumeForce_create(energy));
91    }
92  
93    /**
94     * Add a new global parameter that the interaction may depend on.  The default value provided to
95     * this method is the initial value of the parameter in newly created Contexts.  You can change
96     * the value at any time by calling setParameter() on the Context.
97     *
98     * @param name         the name of the parameter
99     * @param defaultValue the default value of the parameter
100    * @return the index of the parameter that was added
101    */
102   public int addGlobalParameter(String name, double defaultValue) {
103     return OpenMM_CustomVolumeForce_addGlobalParameter(pointer, name, defaultValue);
104   }
105 
106   /**
107    * Add a new global parameter that the energy may depend on.
108    *
109    * @param name         The name of the parameter.
110    * @param defaultValue The default value of the parameter.
111    * @return The index of the parameter that was added.
112    */
113   public int addGlobalParameter(Pointer name, double defaultValue) {
114     return OpenMM_CustomVolumeForce_addGlobalParameter(pointer, name, defaultValue);
115   }
116 
117   /**
118    * Destroy the force.
119    */
120   @Override
121   public void destroy() {
122     if (pointer != null) {
123       OpenMM_CustomVolumeForce_destroy(pointer);
124       pointer = null;
125     }
126   }
127 
128   /**
129    * Get the algebraic expression that defines the energy.
130    *
131    * @return the energy expression
132    */
133   public String getEnergyFunction() {
134     Pointer p = OpenMM_CustomVolumeForce_getEnergyFunction(pointer);
135     if (p == null) {
136       return null;
137     }
138     return p.getString(0);
139   }
140 
141   /**
142    * Get the default value of a global parameter.
143    *
144    * @param index the index of the parameter for which to get the default value
145    * @return the parameter default value
146    */
147   public double getGlobalParameterDefaultValue(int index) {
148     return OpenMM_CustomVolumeForce_getGlobalParameterDefaultValue(pointer, index);
149   }
150 
151   /**
152    * Get the name of a global parameter.
153    *
154    * @param index the index of the parameter for which to get the name
155    * @return the parameter name
156    */
157   public String getGlobalParameterName(int index) {
158     Pointer p = OpenMM_CustomVolumeForce_getGlobalParameterName(pointer, index);
159     if (p == null) {
160       return null;
161     }
162     return p.getString(0);
163   }
164 
165   /**
166    * Get the number of global parameters that the energy depends on.
167    *
168    * @return The number of parameters.
169    */
170   public int getNumGlobalParameters() {
171     return OpenMM_CustomVolumeForce_getNumGlobalParameters(pointer);
172   }
173 
174   /**
175    * Set the algebraic expression that defines the energy.
176    *
177    * @param energy the energy expression
178    */
179   public void setEnergyFunction(String energy) {
180     OpenMM_CustomVolumeForce_setEnergyFunction(pointer, energy);
181   }
182 
183   /**
184    * Set the algebraic expression that defines the energy.
185    *
186    * @param energy the energy expression
187    */
188   public void setEnergyFunction(Pointer energy) {
189     OpenMM_CustomVolumeForce_setEnergyFunction(pointer, energy);
190   }
191 
192   /**
193    * Set the default value of a global parameter.
194    *
195    * @param index        the index of the parameter for which to set the default value
196    * @param defaultValue the default value of the parameter
197    */
198   public void setGlobalParameterDefaultValue(int index, double defaultValue) {
199     OpenMM_CustomVolumeForce_setGlobalParameterDefaultValue(pointer, index, defaultValue);
200   }
201 
202   /**
203    * Set the name of a global parameter.
204    *
205    * @param index the index of the parameter for which to set the name
206    * @param name  the name of the parameter
207    */
208   public void setGlobalParameterName(int index, String name) {
209     OpenMM_CustomVolumeForce_setGlobalParameterName(pointer, index, name);
210   }
211 
212   /**
213    * Set the name of a global parameter.
214    *
215    * @param index the index of the parameter for which to set the name
216    * @param name  the name of the parameter
217    */
218   public void setGlobalParameterName(int index, Pointer name) {
219     OpenMM_CustomVolumeForce_setGlobalParameterName(pointer, index, name);
220   }
221 
222   /**
223    * Returns whether or not this force makes use of periodic boundary conditions.  Because this
224    * class is only applicable to periodic systems, this always returns true.
225    *
226    * @return true if the force uses periodic boundary conditions
227    */
228   @Override
229   public boolean usesPeriodicBoundaryConditions() {
230     int pbc = OpenMM_CustomVolumeForce_usesPeriodicBoundaryConditions(pointer);
231     return pbc == OpenMM_True;
232   }
233 }