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.drude; 39 40 import com.sun.jna.ptr.DoubleByReference; 41 import com.sun.jna.ptr.IntByReference; 42 import ffx.openmm.Context; 43 import ffx.openmm.Force; 44 45 import java.nio.DoubleBuffer; 46 import java.nio.IntBuffer; 47 48 import static edu.uiowa.jopenmm.OpenMMDrudeLibrary.OpenMM_DrudeForce_addParticle; 49 import static edu.uiowa.jopenmm.OpenMMDrudeLibrary.OpenMM_DrudeForce_addScreenedPair; 50 import static edu.uiowa.jopenmm.OpenMMDrudeLibrary.OpenMM_DrudeForce_create; 51 import static edu.uiowa.jopenmm.OpenMMDrudeLibrary.OpenMM_DrudeForce_destroy; 52 import static edu.uiowa.jopenmm.OpenMMDrudeLibrary.OpenMM_DrudeForce_getNumParticles; 53 import static edu.uiowa.jopenmm.OpenMMDrudeLibrary.OpenMM_DrudeForce_getNumScreenedPairs; 54 import static edu.uiowa.jopenmm.OpenMMDrudeLibrary.OpenMM_DrudeForce_getParticleParameters; 55 import static edu.uiowa.jopenmm.OpenMMDrudeLibrary.OpenMM_DrudeForce_getScreenedPairParameters; 56 import static edu.uiowa.jopenmm.OpenMMDrudeLibrary.OpenMM_DrudeForce_setParticleParameters; 57 import static edu.uiowa.jopenmm.OpenMMDrudeLibrary.OpenMM_DrudeForce_setScreenedPairParameters; 58 import static edu.uiowa.jopenmm.OpenMMDrudeLibrary.OpenMM_DrudeForce_setUsesPeriodicBoundaryConditions; 59 import static edu.uiowa.jopenmm.OpenMMDrudeLibrary.OpenMM_DrudeForce_updateParametersInContext; 60 import static edu.uiowa.jopenmm.OpenMMDrudeLibrary.OpenMM_DrudeForce_usesPeriodicBoundaryConditions; 61 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Boolean.OpenMM_True; 62 63 /** 64 * This class implements forces that are specific to Drude oscillators. There are two distinct forces 65 * it applies: an anisotropic harmonic force connecting each Drude particle to its parent particle; and 66 * a screened Coulomb interaction between specific pairs of dipoles. The latter is typically used between 67 * closely bonded particles whose Coulomb interaction would otherwise be fully excluded. 68 * <p> 69 * To use this class, create a DrudeForce object, then call addParticle() once for each Drude particle in the 70 * System to define its parameters. After a particle has been added, you can modify its force field parameters 71 * by calling setParticleParameters(). This will have no effect on Contexts that already exist unless you 72 * call updateParametersInContext(). Likewise, call addScreenedPair() for each pair of dipoles (each dipole 73 * consisting of a Drude particle and its parent) that should be computed. 74 */ 75 public class DrudeForce extends Force { 76 77 /** 78 * Create a DrudeForce. 79 */ 80 public DrudeForce() { 81 super(OpenMM_DrudeForce_create()); 82 } 83 84 /** 85 * Add a Drude particle to which forces should be applied. 86 * 87 * @param particle the index within the System of the Drude particle 88 * @param particle1 the index within the System of the particle to which the Drude particle is attached 89 * @param particle2 the index within the System of the second particle used for defining anisotropic polarizability. 90 * This may be set to -1, in which case aniso12 will be ignored. 91 * @param particle3 the index within the System of the third particle used for defining anisotropic polarizability. 92 * This may be set to -1, in which case aniso34 will be ignored. 93 * @param particle4 the index within the System of the fourth particle used for defining anisotropic polarizability. 94 * This may be set to -1, in which case aniso34 will be ignored. 95 * @param charge The charge on the Drude particle 96 * @param polarizability The isotropic polarizability 97 * @param aniso12 The scale factor for the polarizability along the direction defined by particle1 and particle2 98 * @param aniso34 The scale factor for the polarizability along the direction defined by particle3 and particle4 99 * @return the index of the particle that was added 100 */ 101 public int addParticle(int particle, int particle1, int particle2, int particle3, int particle4, 102 double charge, double polarizability, double aniso12, double aniso34) { 103 return OpenMM_DrudeForce_addParticle(pointer, particle, particle1, particle2, particle3, particle4, 104 charge, polarizability, aniso12, aniso34); 105 } 106 107 /** 108 * Add an interaction to the list of screened pairs. 109 * 110 * @param particle1 the index within this Force of the first particle involved in the interaction 111 * @param particle2 the index within this Force of the second particle involved in the interaction 112 * @param thole the Thole screening factor 113 * @return the index of the screenedPair that was added 114 */ 115 public int addScreenedPair(int particle1, int particle2, double thole) { 116 return OpenMM_DrudeForce_addScreenedPair(pointer, particle1, particle2, thole); 117 } 118 119 /** 120 * Destroy the force. 121 * <p> 122 * This method releases the memory associated with the DrudeForce object. 123 * After calling this method, the force should not be used. 124 */ 125 @Override 126 public void destroy() { 127 if (pointer != null) { 128 OpenMM_DrudeForce_destroy(pointer); 129 pointer = null; 130 } 131 } 132 133 /** 134 * Get the number of particles for which force field parameters have been defined. 135 */ 136 public int getNumParticles() { 137 return OpenMM_DrudeForce_getNumParticles(pointer); 138 } 139 140 /** 141 * Get the number of special interactions that should be calculated differently from other interactions. 142 */ 143 public int getNumScreenedPairs() { 144 return OpenMM_DrudeForce_getNumScreenedPairs(pointer); 145 } 146 147 /** 148 * Get the parameters for a Drude particle. 149 * 150 * @param index the index of the Drude particle for which to get parameters 151 * @param particle the index within the System of the Drude particle 152 * @param particle1 the index within the System of the particle to which the Drude particle is attached 153 * @param particle2 the index within the System of the second particle used for defining anisotropic polarizability. 154 * This may be set to -1, in which case aniso12 will be ignored. 155 * @param particle3 the index within the System of the third particle used for defining anisotropic polarizability. 156 * This may be set to -1, in which case aniso34 will be ignored. 157 * @param particle4 the index within the System of the fourth particle used for defining anisotropic polarizability. 158 * This may be set to -1, in which case aniso34 will be ignored. 159 * @param charge The charge on the Drude particle 160 * @param polarizability The isotropic polarizability 161 * @param aniso12 The scale factor for the polarizability along the direction defined by particle1 and particle2 162 * @param aniso34 The scale factor for the polarizability along the direction defined by particle3 and particle4 163 */ 164 public void getParticleParameters(int index, IntByReference particle, IntByReference particle1, 165 IntByReference particle2, IntByReference particle3, IntByReference particle4, 166 DoubleByReference charge, DoubleByReference polarizability, 167 DoubleByReference aniso12, DoubleByReference aniso34) { 168 OpenMM_DrudeForce_getParticleParameters(pointer, index, particle, particle1, particle2, 169 particle3, particle4, charge, polarizability, aniso12, aniso34); 170 } 171 172 /** 173 * Get the force field parameters for a screened pair. 174 * 175 * @param index the index of the pair for which to get parameters 176 * @param particle1 the index within this Force of the first particle involved in the interaction 177 * @param particle2 the index within this Force of the second particle involved in the interaction 178 * @param thole the Thole screening factor 179 */ 180 public void getScreenedPairParameters(int index, IntByReference particle1, IntByReference particle2, 181 DoubleByReference thole) { 182 OpenMM_DrudeForce_getScreenedPairParameters(pointer, index, particle1, particle2, thole); 183 } 184 185 /** 186 * Get the force field parameters for a screened pair. 187 * 188 * @param index the index of the pair for which to get parameters 189 * @param particle1 the index within this Force of the first particle involved in the interaction 190 * @param particle2 the index within this Force of the second particle involved in the interaction 191 * @param thole the Thole screening factor 192 */ 193 public void getScreenedPairParameters(int index, IntBuffer particle1, IntBuffer particle2, 194 DoubleBuffer thole) { 195 OpenMM_DrudeForce_getScreenedPairParameters(pointer, index, particle1, particle2, thole); 196 } 197 198 /** 199 * Set the parameters for a Drude particle. 200 * 201 * @param index the index of the Drude particle for which to set parameters 202 * @param particle the index within the System of the Drude particle 203 * @param particle1 the index within the System of the particle to which the Drude particle is attached 204 * @param particle2 the index within the System of the second particle used for defining anisotropic polarizability. 205 * This may be set to -1, in which case aniso12 will be ignored. 206 * @param particle3 the index within the System of the third particle used for defining anisotropic polarizability. 207 * This may be set to -1, in which case aniso34 will be ignored. 208 * @param particle4 the index within the System of the fourth particle used for defining anisotropic polarizability. 209 * This may be set to -1, in which case aniso34 will be ignored. 210 * @param charge The charge on the Drude particle 211 * @param polarizability The isotropic polarizability 212 * @param aniso12 The scale factor for the polarizability along the direction defined by particle1 and particle2 213 * @param aniso34 The scale factor for the polarizability along the direction defined by particle3 and particle4 214 */ 215 public void setParticleParameters(int index, int particle, int particle1, int particle2, 216 int particle3, int particle4, double charge, double polarizability, 217 double aniso12, double aniso34) { 218 OpenMM_DrudeForce_setParticleParameters(pointer, index, particle, particle1, particle2, 219 particle3, particle4, charge, polarizability, aniso12, aniso34); 220 } 221 222 /** 223 * Set the force field parameters for a screened pair. 224 * 225 * @param index the index of the pair for which to get parameters 226 * @param particle1 the index within this Force of the first particle involved in the interaction 227 * @param particle2 the index within this Force of the second particle involved in the interaction 228 * @param thole the Thole screening factor 229 */ 230 public void setScreenedPairParameters(int index, int particle1, int particle2, double thole) { 231 OpenMM_DrudeForce_setScreenedPairParameters(pointer, index, particle1, particle2, thole); 232 } 233 234 /** 235 * Set whether this force should apply periodic boundary conditions when calculating displacements. 236 * Usually this is not appropriate for bonded forces, but there are situations when it can be useful. 237 * <p> 238 * Periodic boundary conditions are only applied to screened pairs. They are never used for the 239 * force between a Drude particle and its parent particle, regardless of this setting. 240 */ 241 public void setUsesPeriodicBoundaryConditions(boolean periodic) { 242 OpenMM_DrudeForce_setUsesPeriodicBoundaryConditions(pointer, periodic ? 1 : 0); 243 } 244 245 /** 246 * Update the particle and screened pair parameters in a Context to match those stored in this Force object. This method 247 * provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. 248 * Simply call setParticleParameters() and setScreenedPairParameters() to modify this object's parameters, then call 249 * updateParametersInContext() to copy them over to the Context. 250 * <p> 251 * This method has several limitations. It can be used to modify the numeric parameters associated with a particle or 252 * screened pair (polarizability, thole, etc.), but not the identities of the particles they involve. It also cannot 253 * be used to add new particles or screenedPairs, only to change the parameters of existing ones. 254 */ 255 public void updateParametersInContext(Context context) { 256 if (context.hasContextPointer()) { 257 OpenMM_DrudeForce_updateParametersInContext(pointer, context.getPointer()); 258 } 259 } 260 261 /** 262 * Returns whether or not this force makes use of periodic boundary 263 * conditions. 264 */ 265 @Override 266 public boolean usesPeriodicBoundaryConditions() { 267 int pbc = OpenMM_DrudeForce_usesPeriodicBoundaryConditions(pointer); 268 return pbc == OpenMM_True; 269 } 270 }