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 }