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