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 }