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 < 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 }