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 }