View Javadoc
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 }