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  
42  import java.nio.DoubleBuffer;
43  
44  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Boolean.OpenMM_True;
45  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_addParticle;
46  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_create;
47  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_destroy;
48  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_getCutoffDistance;
49  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_getNonbondedMethod;
50  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_getNumParticles;
51  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_getParticleParameters;
52  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_getSoluteDielectric;
53  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_getSolventDielectric;
54  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_getSurfaceAreaEnergy;
55  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_setCutoffDistance;
56  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_setNonbondedMethod;
57  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_setParticleParameters;
58  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_setSoluteDielectric;
59  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_setSolventDielectric;
60  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_setSurfaceAreaEnergy;
61  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_updateParametersInContext;
62  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_GBSAOBCForce_usesPeriodicBoundaryConditions;
63  
64  /**
65   * This class implements an implicit solvation force using the GBSA-OBC model.
66   * <p>
67   * To use this class, create a GBSAOBCForce object, then call addParticle() once for each particle in the
68   * System to define its parameters.  The number of particles for which you define GBSA parameters must
69   * be exactly equal to the number of particles in the System, or else an exception will be thrown when you
70   * try to create a Context.  After a particle has been added, you can modify its force field parameters
71   * by calling setParticleParameters().  This will have no effect on Contexts that already exist unless you
72   * call updateParametersInContext().
73   * <p>
74   * When using this Force, the System should also include a NonbondedForce, and both objects must specify
75   * identical charges for all particles.  Otherwise, the results will not be correct.  Furthermore, if the
76   * nonbonded method is set to CutoffNonPeriodic or CutoffPeriodic, you should call setReactionFieldDielectric(1.0)
77   * on the NonbondedForce to turn off the reaction field approximation, which does not produce correct results
78   * when combined with GBSA.
79   */
80  public class GBSAOBCForce extends Force {
81  
82    /**
83     * Create a new GBSAOBCForce.
84     */
85    public GBSAOBCForce() {
86      super(OpenMM_GBSAOBCForce_create());
87    }
88  
89    /**
90     * Add a particle to the force field.
91     *
92     * @param charge The charge of the particle, measured in units of the proton charge.
93     * @param radius The GBSA radius of the particle, measured in nm.
94     * @param scale  The OBC scaling parameter for the particle.
95     * @return The index of the particle that was added.
96     */
97    public int addParticle(double charge, double radius, double scale) {
98      return OpenMM_GBSAOBCForce_addParticle(pointer, charge, radius, scale);
99    }
100 
101   /**
102    * Destroy the force.
103    */
104   @Override
105   public void destroy() {
106     if (pointer != null) {
107       OpenMM_GBSAOBCForce_destroy(pointer);
108       pointer = null;
109     }
110   }
111 
112   /**
113    * Get the cutoff distance (in nm) being used for nonbonded interactions.
114    *
115    * @return The cutoff distance, measured in nm.
116    */
117   public double getCutoffDistance() {
118     return OpenMM_GBSAOBCForce_getCutoffDistance(pointer);
119   }
120 
121   /**
122    * Get the method used for handling long range nonbonded interactions.
123    *
124    * @return The nonbonded method.
125    */
126   public int getNonbondedMethod() {
127     return OpenMM_GBSAOBCForce_getNonbondedMethod(pointer);
128   }
129 
130   /**
131    * Get the number of particles in the force field.
132    *
133    * @return The number of particles.
134    */
135   public int getNumParticles() {
136     return OpenMM_GBSAOBCForce_getNumParticles(pointer);
137   }
138 
139   /**
140    * Get the force field parameters for a particle.
141    *
142    * @param index  The index of the particle for which to get parameters.
143    * @param charge The charge of the particle, measured in units of the proton charge (output).
144    * @param radius The GBSA radius of the particle, measured in nm (output).
145    * @param scale  The OBC scaling parameter for the particle (output).
146    */
147   public void getParticleParameters(int index, DoubleByReference charge, DoubleByReference radius, DoubleByReference scale) {
148     OpenMM_GBSAOBCForce_getParticleParameters(pointer, index, charge, radius, scale);
149   }
150 
151   /**
152    * Get the force field parameters for a particle.
153    *
154    * @param index  The index of the particle for which to get parameters.
155    * @param charge The charge of the particle, measured in units of the proton charge (output).
156    * @param radius The GBSA radius of the particle, measured in nm (output).
157    * @param scale  The OBC scaling parameter for the particle (output).
158    */
159   public void getParticleParameters(int index, DoubleBuffer charge, DoubleBuffer radius, DoubleBuffer scale) {
160     OpenMM_GBSAOBCForce_getParticleParameters(pointer, index, charge, radius, scale);
161   }
162 
163   /**
164    * Get the dielectric constant for the solute.
165    *
166    * @return The solute dielectric constant.
167    */
168   public double getSoluteDielectric() {
169     return OpenMM_GBSAOBCForce_getSoluteDielectric(pointer);
170   }
171 
172   /**
173    * Get the dielectric constant for the solvent.
174    *
175    * @return The solvent dielectric constant.
176    */
177   public double getSolventDielectric() {
178     return OpenMM_GBSAOBCForce_getSolventDielectric(pointer);
179   }
180 
181   /**
182    * Get the energy scale for the surface area term, measured in kJ/mol/nm&circ;2.
183    *
184    * @return The surface area energy scale.
185    */
186   public double getSurfaceAreaEnergy() {
187     return OpenMM_GBSAOBCForce_getSurfaceAreaEnergy(pointer);
188   }
189 
190   /**
191    * Set the cutoff distance (in nm) being used for nonbonded interactions.
192    *
193    * @param distance The cutoff distance, measured in nm.
194    */
195   public void setCutoffDistance(double distance) {
196     OpenMM_GBSAOBCForce_setCutoffDistance(pointer, distance);
197   }
198 
199   /**
200    * Set the method used for handling long range nonbonded interactions.
201    *
202    * @param method The nonbonded method.
203    */
204   public void setNonbondedMethod(int method) {
205     OpenMM_GBSAOBCForce_setNonbondedMethod(pointer, method);
206   }
207 
208   /**
209    * Set the force field parameters for a particle.
210    *
211    * @param index  The index of the particle for which to set parameters.
212    * @param charge The charge of the particle, measured in units of the proton charge.
213    * @param radius The GBSA radius of the particle, measured in nm.
214    * @param scale  The OBC scaling parameter for the particle.
215    */
216   public void setParticleParameters(int index, double charge, double radius, double scale) {
217     OpenMM_GBSAOBCForce_setParticleParameters(pointer, index, charge, radius, scale);
218   }
219 
220   /**
221    * Set the dielectric constant for the solute.
222    *
223    * @param dielectric The solute dielectric constant.
224    */
225   public void setSoluteDielectric(double dielectric) {
226     OpenMM_GBSAOBCForce_setSoluteDielectric(pointer, dielectric);
227   }
228 
229   /**
230    * Set the dielectric constant for the solvent.
231    *
232    * @param dielectric The solvent dielectric constant.
233    */
234   public void setSolventDielectric(double dielectric) {
235     OpenMM_GBSAOBCForce_setSolventDielectric(pointer, dielectric);
236   }
237 
238   /**
239    * Set the energy scale for the surface area term, measured in kJ/mol/nm&circ;2.
240    *
241    * @param energy The surface area energy scale.
242    */
243   public void setSurfaceAreaEnergy(double energy) {
244     OpenMM_GBSAOBCForce_setSurfaceAreaEnergy(pointer, energy);
245   }
246 
247   /**
248    * Update the particle parameters in a Context to match those stored in this Force object.
249    *
250    * @param context The Context in which to update the parameters.
251    */
252   public void updateParametersInContext(Context context) {
253     if (context.hasContextPointer()) {
254       OpenMM_GBSAOBCForce_updateParametersInContext(pointer, context.getPointer());
255     }
256   }
257 
258   /**
259    * Check if the force uses periodic boundary conditions.
260    *
261    * @return True if the force uses periodic boundary conditions.
262    */
263   @Override
264   public boolean usesPeriodicBoundaryConditions() {
265     int pbc = OpenMM_GBSAOBCForce_usesPeriodicBoundaryConditions(pointer);
266     return pbc == OpenMM_True;
267   }
268 }