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_PeriodicTorsionForce_addTorsion; 48 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_PeriodicTorsionForce_create; 49 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_PeriodicTorsionForce_destroy; 50 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_PeriodicTorsionForce_getNumTorsions; 51 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_PeriodicTorsionForce_getTorsionParameters; 52 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_PeriodicTorsionForce_setTorsionParameters; 53 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_PeriodicTorsionForce_setUsesPeriodicBoundaryConditions; 54 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_PeriodicTorsionForce_updateParametersInContext; 55 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_PeriodicTorsionForce_usesPeriodicBoundaryConditions; 56 57 /** 58 * This class implements an interaction between groups of four particles that varies periodically with the torsion angle 59 * between them. To use it, create a PeriodicTorsionForce object then call addTorsion() once for each torsion. After 60 * a torsion has been added, you can modify its force field parameters by calling setTorsionParameters(). This will 61 * have no effect on Contexts that already exist unless you call updateParametersInContext(). 62 */ 63 public class PeriodicTorsionForce extends Force { 64 65 /** 66 * Create a new PeriodicTorsionForce. 67 */ 68 public PeriodicTorsionForce() { 69 super(OpenMM_PeriodicTorsionForce_create()); 70 } 71 72 /** 73 * Add a torsion to the PeriodicTorsionForce. 74 * 75 * @param particle1 Index of the first atom. 76 * @param particle2 Index of the second atom. 77 * @param particle3 Index of the third atom. 78 * @param particle4 Index of the fourth atom. 79 * @param periodicity The periodicity of the torsion. 80 * @param phase The phase of the torsion. 81 * @param k The force constant for the torsion. 82 * @return The index of the torsion that was added. 83 */ 84 public int addTorsion(int particle1, int particle2, int particle3, int particle4, int periodicity, double phase, double k) { 85 return OpenMM_PeriodicTorsionForce_addTorsion(pointer, particle1, particle2, particle3, particle4, periodicity, phase, k); 86 } 87 88 /** 89 * Destroy the force. 90 */ 91 @Override 92 public void destroy() { 93 if (pointer != null) { 94 OpenMM_PeriodicTorsionForce_destroy(pointer); 95 pointer = null; 96 } 97 } 98 99 /** 100 * Get the number of torsions in the force. 101 * 102 * @return The number of torsions. 103 */ 104 public int getNumTorsions() { 105 return OpenMM_PeriodicTorsionForce_getNumTorsions(pointer); 106 } 107 108 /** 109 * Get the parameters for a torsion. 110 * 111 * @param index The index of the torsion. 112 * @param particle1 The index of the first atom (output). 113 * @param particle2 The index of the second atom (output). 114 * @param particle3 The index of the third atom (output). 115 * @param particle4 The index of the fourth atom (output). 116 * @param periodicity The periodicity of the torsion (output). 117 * @param phase The phase of the torsion (output). 118 * @param k The force constant for the torsion (output). 119 */ 120 public void getTorsionParameters(int index, IntByReference particle1, IntByReference particle2, 121 IntByReference particle3, IntByReference particle4, 122 IntByReference periodicity, DoubleByReference phase, 123 DoubleByReference k) { 124 OpenMM_PeriodicTorsionForce_getTorsionParameters(pointer, index, particle1, particle2, 125 particle3, particle4, periodicity, phase, k); 126 } 127 128 /** 129 * Get the parameters for a torsion. 130 * 131 * @param index The index of the torsion. 132 * @param particle1 The index of the first atom (output). 133 * @param particle2 The index of the second atom (output). 134 * @param particle3 The index of the third atom (output). 135 * @param particle4 The index of the fourth atom (output). 136 * @param periodicity The periodicity of the torsion (output). 137 * @param phase The phase of the torsion (output). 138 * @param k The force constant for the torsion (output). 139 */ 140 public void getTorsionParameters(int index, IntBuffer particle1, IntBuffer particle2, 141 IntBuffer particle3, IntBuffer particle4, 142 IntBuffer periodicity, DoubleBuffer phase, 143 DoubleBuffer k) { 144 OpenMM_PeriodicTorsionForce_getTorsionParameters(pointer, index, particle1, particle2, 145 particle3, particle4, periodicity, phase, k); 146 } 147 148 /** 149 * Set the parameters for a torsion. 150 * 151 * @param index The index of the torsion for which to set parameters. 152 * @param particle1 The index of the first atom in the torsion. 153 * @param particle2 The index of the second atom in the torsion. 154 * @param particle3 The index of the third atom in the torsion. 155 * @param particle4 The index of the fourth atom in the torsion. 156 * @param periodicity The periodicity of the torsion. 157 * @param phase The phase of the torsion. 158 * @param k The force constant for the torsion. 159 */ 160 public void setTorsionParameters(int index, int particle1, int particle2, int particle3, 161 int particle4, int periodicity, double phase, double k) { 162 OpenMM_PeriodicTorsionForce_setTorsionParameters(pointer, index, particle1, particle2, 163 particle3, particle4, periodicity, phase, k); 164 } 165 166 /** 167 * Set whether this force should apply periodic boundary conditions when calculating displacements. 168 * 169 * @param periodic If true, periodic boundary conditions will be applied. 170 */ 171 public void setUsesPeriodicBoundaryConditions(boolean periodic) { 172 OpenMM_PeriodicTorsionForce_setUsesPeriodicBoundaryConditions(pointer, periodic ? 1 : 0); 173 } 174 175 /** 176 * Update the parameters in the OpenMM Context. 177 * 178 * @param context The OpenMM Context. 179 */ 180 public void updateParametersInContext(Context context) { 181 if (context.hasContextPointer()) { 182 OpenMM_PeriodicTorsionForce_updateParametersInContext(pointer, context.getPointer()); 183 } 184 } 185 186 /** 187 * Check if the force uses periodic boundary conditions. 188 * 189 * @return True if the force uses periodic boundary conditions. 190 */ 191 @Override 192 public boolean usesPeriodicBoundaryConditions() { 193 int pbc = OpenMM_PeriodicTorsionForce_usesPeriodicBoundaryConditions(pointer); 194 return pbc == OpenMM_True; 195 } 196 }