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.Pointer;
41  import com.sun.jna.ptr.PointerByReference;
42  
43  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Boolean.OpenMM_True;
44  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Force_getForceGroup;
45  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Force_getName;
46  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Force_setForceGroup;
47  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Force_setName;
48  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Force_usesPeriodicBoundaryConditions;
49  
50  /**
51   * Force objects apply forces to the particles in a System, or alter their behavior in other
52   * ways. This is an abstract class. Subclasses define particular forces.
53   * <p>
54   * More specifically, a Force object can do any or all of the following:
55   *
56   * <ul>
57   * <li>Add a contribution to the force on each particle</li>
58   * <li>Add a contribution to the potential energy of the System</li>
59   * <li>Modify the positions and velocities of particles at the start of each time step</li>
60   * <li>Define parameters which are stored in the Context and can be modified by the user</li>
61   * <li>Change the values of parameters defined by other Force objects at the start of each time step</li>
62   * </ul>
63   * <p>
64   * Forces may be organized into "force groups". This is used for multiple time step integration,
65   * and allows subsets of the Forces in a System to be evaluated at different times. By default,
66   * all Forces are in group 0. Call setForceGroup() to change this. Some Force subclasses may
67   * provide additional methods to further split their computations into multiple groups.  Be aware
68   * that particular Platforms may place restrictions on the use of force groups, such as requiring
69   * all nonbonded forces to be in the same group.
70   */
71  public abstract class Force {
72  
73    /**
74     * The forcePointer is allocated and deallocated by classes that extend OpenMMForce.
75     */
76    protected PointerByReference pointer = null;
77  
78    /**
79     * The forceIndex is returned by OpenMMSystem.addForce and is used to remove the force.
80     */
81    private int forceIndex = -1;
82  
83    /**
84     * Create a new Force object with the specified pointer.
85     *
86     * @param pointer A pointer to the native OpenMM Force object.
87     */
88    public Force(PointerByReference pointer) {
89      if (pointer == null || pointer.getValue() == null) {
90        throw new IllegalArgumentException("Pointer cannot be null.");
91      }
92      this.pointer = pointer;
93    }
94  
95    /**
96     * Destroy the force.
97     */
98    public abstract void destroy();
99  
100   /**
101    * Get the pointer to the OpenMM Force.
102    *
103    * @return The pointer to the OpenMM Force.
104    */
105   public PointerByReference getPointer() {
106     return pointer;
107   }
108 
109   /**
110    * Set the force group.
111    *
112    * @param forceGroup The force group.
113    */
114   public void setForceGroup(int forceGroup) {
115     OpenMM_Force_setForceGroup(pointer, forceGroup);
116   }
117 
118   /**
119    * Get the force group.
120    *
121    * @return The force group.
122    */
123   public int getForceGroup() {
124     return OpenMM_Force_getForceGroup(pointer);
125   }
126 
127   /**
128    * Set the name of the force.
129    *
130    * @param name The name of the force.
131    */
132   public void setName(String name) {
133     OpenMM_Force_setName(pointer, name);
134   }
135 
136   /**
137    * Get the name of the force.
138    *
139    * @return The name of the force.
140    */
141   public String getName() {
142     Pointer pointer = OpenMM_Force_getName(this.pointer);
143     if (pointer == null) {
144       return null;
145     }
146     return pointer.getString(0);
147   }
148 
149   /**
150    * Set the force index.
151    *
152    * @param forceIndex The force index.
153    */
154   public void setForceIndex(int forceIndex) {
155     this.forceIndex = forceIndex;
156   }
157 
158   /**
159    * Get the force index.
160    *
161    * @return The force index.
162    */
163   public int getForceIndex() {
164     return forceIndex;
165   }
166 
167   /**
168    * Check if the force use periodic boundary conditions. This is a virtual method
169    * that must be implemented by classes that extend OpenMMForce.
170    *
171    * @return True if the force uses periodic boundary conditions.
172    */
173   public boolean usesPeriodicBoundaryConditions() {
174     int pbc = OpenMM_Force_usesPeriodicBoundaryConditions(pointer);
175     return pbc == OpenMM_True;
176   }
177 
178 }