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.IntByReference; 41 import com.sun.jna.ptr.PointerByReference; 42 43 import java.nio.IntBuffer; 44 45 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Boolean.OpenMM_True; 46 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CMAPTorsionForce_addMap; 47 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CMAPTorsionForce_addTorsion; 48 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CMAPTorsionForce_create; 49 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CMAPTorsionForce_destroy; 50 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CMAPTorsionForce_getMapParameters; 51 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CMAPTorsionForce_getNumMaps; 52 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CMAPTorsionForce_getNumTorsions; 53 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CMAPTorsionForce_getTorsionParameters; 54 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CMAPTorsionForce_setMapParameters; 55 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CMAPTorsionForce_setTorsionParameters; 56 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CMAPTorsionForce_setUsesPeriodicBoundaryConditions; 57 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CMAPTorsionForce_updateParametersInContext; 58 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CMAPTorsionForce_usesPeriodicBoundaryConditions; 59 60 /** 61 * This class implements an interaction between pairs of dihedral angles. The interaction energy is 62 * defined by an "energy correction map" (CMAP), which is simply a set of tabulated energy values 63 * on a regular grid of (phi, psi) angles. Natural cubic spline interpolation is used to compute 64 * forces and energies at arbitrary values of the two angles. 65 * <p> 66 * To use this class, first create one or more energy correction maps by calling addMap(). For each 67 * one, you provide an array of energies at uniformly spaced values of the two angles. Next, 68 * add interactions by calling addTorsion(). For each one, you specify the sequence of particles used 69 * to calculate each of the two dihedral angles, and the index of the map used to calculate their 70 * interaction energy. 71 */ 72 public class CMAPTorsionForce extends Force { 73 74 /** 75 * Create a CMAPTorsionForce. 76 */ 77 public CMAPTorsionForce() { 78 super(OpenMM_CMAPTorsionForce_create()); 79 } 80 81 /** 82 * Create a new map that can be used for torsion pairs. 83 * 84 * @param size the size of the map along each dimension 85 * @param energy the energy values for the map. This must be of length size*size. 86 * The element energy[i+size*j] contains the energy when the first 87 * torsion angle equals i*2*PI/size and the second torsion angle 88 * equals j*2*PI/size. 89 * @return the index of the map that was added 90 */ 91 public int addMap(int size, PointerByReference energy) { 92 return OpenMM_CMAPTorsionForce_addMap(pointer, size, energy); 93 } 94 95 /** 96 * Add a CMAP torsion term to the force field. 97 * 98 * @param map the index of the map to use for this term 99 * @param a1 the index of the first particle forming the first torsion 100 * @param a2 the index of the second particle forming the first torsion 101 * @param a3 the index of the third particle forming the first torsion 102 * @param a4 the index of the fourth particle forming the first torsion 103 * @param b1 the index of the first particle forming the second torsion 104 * @param b2 the index of the second particle forming the second torsion 105 * @param b3 the index of the third particle forming the second torsion 106 * @param b4 the index of the fourth particle forming the second torsion 107 * @return the index of the torsion that was added 108 */ 109 public int addTorsion(int map, int a1, int a2, int a3, int a4, int b1, int b2, int b3, int b4) { 110 return OpenMM_CMAPTorsionForce_addTorsion(pointer, map, a1, a2, a3, a4, b1, b2, b3, b4); 111 } 112 113 /** 114 * Destroy the force. 115 */ 116 @Override 117 public void destroy() { 118 if (pointer != null) { 119 OpenMM_CMAPTorsionForce_destroy(pointer); 120 pointer = null; 121 } 122 } 123 124 /** 125 * Get the energy values of a map. 126 * 127 * @param index the index of the map for which to get energy values 128 * @param size the size of the map along each dimension 129 * @param energy the energy values for the map. This must be of length size*size. 130 * The element energy[i+size*j] contains the energy when the first 131 * torsion angle equals i*2*PI/size and the second torsion angle 132 * equals j*2*PI/size. 133 */ 134 public void getMapParameters(int index, IntByReference size, PointerByReference energy) { 135 OpenMM_CMAPTorsionForce_getMapParameters(pointer, index, size, energy); 136 } 137 138 /** 139 * Get the energy values of a map. 140 * 141 * @param index the index of the map for which to get energy values 142 * @param size the size of the map along each dimension 143 * @param energy the energy values for the map. This must be of length size*size. 144 * The element energy[i+size*j] contains the energy when the first 145 * torsion angle equals i*2*PI/size and the second torsion angle 146 * equals j*2*PI/size. 147 */ 148 public void getMapParameters(int index, IntBuffer size, PointerByReference energy) { 149 OpenMM_CMAPTorsionForce_getMapParameters(pointer, index, size, energy); 150 } 151 152 /** 153 * Get the number of maps that have been defined. 154 */ 155 public int getNumMaps() { 156 return OpenMM_CMAPTorsionForce_getNumMaps(pointer); 157 } 158 159 /** 160 * Get the number of CMAP torsion terms in the potential function 161 */ 162 public int getNumTorsions() { 163 return OpenMM_CMAPTorsionForce_getNumTorsions(pointer); 164 } 165 166 /** 167 * Get the force field parameters for a CMAP torsion term. 168 * 169 * @param index the index of the torsion for which to get parameters 170 * @param map the index of the map to use for this term 171 * @param a1 the index of the first particle forming the first torsion 172 * @param a2 the index of the second particle forming the first torsion 173 * @param a3 the index of the third particle forming the first torsion 174 * @param a4 the index of the fourth particle forming the first torsion 175 * @param b1 the index of the first particle forming the second torsion 176 * @param b2 the index of the second particle forming the second torsion 177 * @param b3 the index of the third particle forming the second torsion 178 * @param b4 the index of the fourth particle forming the second torsion 179 */ 180 public void getTorsionParameters(int index, IntByReference map, IntByReference a1, IntByReference a2, 181 IntByReference a3, IntByReference a4, IntByReference b1, 182 IntByReference b2, IntByReference b3, IntByReference b4) { 183 OpenMM_CMAPTorsionForce_getTorsionParameters(pointer, index, map, a1, a2, a3, a4, b1, b2, b3, b4); 184 } 185 186 /** 187 * Get the force field parameters for a CMAP torsion term. 188 * 189 * @param index the index of the torsion for which to get parameters 190 * @param map the index of the map to use for this term 191 * @param a1 the index of the first particle forming the first torsion 192 * @param a2 the index of the second particle forming the first torsion 193 * @param a3 the index of the third particle forming the first torsion 194 * @param a4 the index of the fourth particle forming the first torsion 195 * @param b1 the index of the first particle forming the second torsion 196 * @param b2 the index of the second particle forming the second torsion 197 * @param b3 the index of the third particle forming the second torsion 198 * @param b4 the index of the fourth particle forming the second torsion 199 */ 200 public void getTorsionParameters(int index, IntBuffer map, IntBuffer a1, IntBuffer a2, 201 IntBuffer a3, IntBuffer a4, IntBuffer b1, 202 IntBuffer b2, IntBuffer b3, IntBuffer b4) { 203 OpenMM_CMAPTorsionForce_getTorsionParameters(pointer, index, map, a1, a2, a3, a4, b1, b2, b3, b4); 204 } 205 206 /** 207 * Set the energy values of a map. 208 * 209 * @param index the index of the map for which to set energy values 210 * @param size the size of the map along each dimension 211 * @param energy the energy values for the map. This must be of length size*size. 212 * The element energy[i+size*j] contains the energy when the first 213 * torsion angle equals i*2*PI/size and the second torsion angle 214 * equals j*2*PI/size. 215 */ 216 public void setMapParameters(int index, int size, PointerByReference energy) { 217 OpenMM_CMAPTorsionForce_setMapParameters(pointer, index, size, energy); 218 } 219 220 /** 221 * Set the force field parameters for a CMAP torsion term. 222 * 223 * @param index the index of the torsion for which to set parameters 224 * @param map the index of the map to use for this term 225 * @param a1 the index of the first particle forming the first torsion 226 * @param a2 the index of the second particle forming the first torsion 227 * @param a3 the index of the third particle forming the first torsion 228 * @param a4 the index of the fourth particle forming the first torsion 229 * @param b1 the index of the first particle forming the second torsion 230 * @param b2 the index of the second particle forming the second torsion 231 * @param b3 the index of the third particle forming the second torsion 232 * @param b4 the index of the fourth particle forming the second torsion 233 */ 234 public void setTorsionParameters(int index, int map, int a1, int a2, int a3, int a4, 235 int b1, int b2, int b3, int b4) { 236 OpenMM_CMAPTorsionForce_setTorsionParameters(pointer, index, map, a1, a2, a3, a4, b1, b2, b3, b4); 237 } 238 239 /** 240 * Set whether this force should apply periodic boundary conditions when calculating displacements. 241 * Usually this is not appropriate for bonded forces, but there are situations when it can be useful. 242 */ 243 public void setUsesPeriodicBoundaryConditions(boolean periodic) { 244 OpenMM_CMAPTorsionForce_setUsesPeriodicBoundaryConditions(pointer, periodic ? 1 : 0); 245 } 246 247 /** 248 * Update the map and torsion parameters in a Context to match those stored in this Force object. This method provides 249 * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. 250 * Simply call setMapParameters() and setTorsionParameters() to modify this object's parameters, then call updateParametersInContext() 251 * to copy them over to the Context. 252 * <p> 253 * The only information that can be updated with this method is the energy values for a map, and the map index 254 * for a torsion. The size of a map and the set of particles involved in a torsion cannot be changed. Also, 255 * new bonds and torsions cannot be added. 256 */ 257 public void updateParametersInContext(Context context) { 258 if (context.hasContextPointer()) { 259 OpenMM_CMAPTorsionForce_updateParametersInContext(pointer, context.getPointer()); 260 } 261 } 262 263 /** 264 * Returns whether or not this force makes use of periodic boundary 265 * conditions. 266 * 267 * @return true if force uses PBC and false otherwise 268 */ 269 @Override 270 public boolean usesPeriodicBoundaryConditions() { 271 int pbc = OpenMM_CMAPTorsionForce_usesPeriodicBoundaryConditions(pointer); 272 return pbc == OpenMM_True; 273 } 274 }