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.amoeba;
39  
40  import com.sun.jna.ptr.DoubleByReference;
41  import ffx.openmm.Context;
42  import ffx.openmm.Force;
43  
44  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_addParticle;
45  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_addParticle_1;
46  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_create;
47  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_destroy;
48  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_getDescreenOffset;
49  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_getDielectricOffset;
50  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_getIncludeCavityTerm;
51  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_getNumParticles;
52  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_getParticleParameters;
53  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_getProbeRadius;
54  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_getSoluteDielectric;
55  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_getSolventDielectric;
56  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_getSurfaceAreaFactor;
57  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_getTanhParameters;
58  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_getTanhRescaling;
59  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_setDescreenOffset;
60  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_setDielectricOffset;
61  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_setIncludeCavityTerm;
62  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_setParticleParameters;
63  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_setProbeRadius;
64  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_setSoluteDielectric;
65  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_setSolventDielectric;
66  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_setSurfaceAreaFactor;
67  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_setTanhParameters;
68  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_setTanhRescaling;
69  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_updateParametersInContext;
70  import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_AmoebaGeneralizedKirkwoodForce_usesPeriodicBoundaryConditions;
71  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Boolean.OpenMM_True;
72  
73  /**
74   * This class implements an implicit solvation force using the Amoeba Generalized Kirkwood model.
75   * <p>
76   * To use this class, create a GeneralizedKirkwoodForce object, then call addParticle() once for each
77   * particle in the System to define its parameters. The number of particles for which you define
78   * parameters must be equal to the number of particles in the System, or else an exception will be
79   * thrown when you try to create a Context. After a particle has been added, you can modify its
80   * force field parameters by calling setParticleParameters(). This will have no effect on Contexts
81   * that already exist unless you call updateParametersInContext().
82   * <p>
83   * The force supports both 3-parameter and 5-parameter particle definitions, where the extended
84   * form includes additional descreening and neck correction parameters for enhanced accuracy in
85   * specific molecular environments.
86   */
87  public class GeneralizedKirkwoodForce extends Force {
88  
89    public GeneralizedKirkwoodForce() {
90      super(OpenMM_AmoebaGeneralizedKirkwoodForce_create());
91    }
92  
93    /**
94     * Add the parameters for a particle. This should be called once for each particle
95     * in the System. When it is called for the i'th time, it specifies the parameters for the i'th particle.
96     * <p>
97     * This method is provided for backwards compatibility. Compared to the alternative five parameter addParticle
98     * method, the descreenRadius parameter is set to base radius value and the neckFactor is set to zero
99     * (no neck descreening).
100    *
101    * @param charge        the charge of the particle, measured in units of the proton charge
102    * @param radius        the atomic radius of the particle, measured in nm
103    * @param scalingFactor the scaling factor for the particle
104    * @return the index of the particle that was added
105    */
106   public int addParticle(double charge, double radius, double scalingFactor) {
107     return OpenMM_AmoebaGeneralizedKirkwoodForce_addParticle(pointer, charge, radius, scalingFactor);
108   }
109 
110   /**
111    * Add the parameters for a particle. This should be called once for each particle
112    * in the System. When it is called for the i'th time, it specifies the parameters for the i'th particle.
113    * <p>
114    * For generalized Born / generalized Kirkwood methods, the radius of each atom has two roles. The first
115    * is to define the base radius of the atom when computing its effective radius. This base radius is usually
116    * parameterized against solvation free energy differences. The second role is to describe how much continuum
117    * water is displaced when the atom descreens water for the calculation of the Born radii of other atoms.
118    * Separation of the two roles into the "radius" and "descreenRadius" parameters gives model developers more
119    * control over these separate roles.
120    * <p>
121    * For example, the fitting of base "radius" values will usually result in deviation from the force field's
122    * van der Waals definition of Rmin (or sigma). The descreenRadius can be defined separately using force field
123    * van der Waals Rmin values, which maintains consistency of atomic sizes during the HCT pairwise
124    * descreening integral. The "scalingFactor" is applied to the descreenRadius during the HCT pairwise
125    * descreening integral, while the neckFactor (if greater than zero) includes neck contributions to descreening.
126    *
127    * @param charge         the charge of the particle, measured in units of the proton charge
128    * @param radius         the atomic radius of the particle, measured in nm
129    * @param scalingFactor  the scaling factor for the particle (unitless)
130    * @param descreenRadius the atomic radius of the particle for descreening, measure in nm
131    * @param neckFactor     the scaling factor for interstitial neck descreening (unitless)
132    * @return the index of the particle that was added
133    */
134   public int addParticle(double charge, double radius, double scalingFactor, double descreenRadius, double neckFactor) {
135     return OpenMM_AmoebaGeneralizedKirkwoodForce_addParticle_1(pointer, charge, radius, scalingFactor, descreenRadius, neckFactor);
136   }
137 
138   /**
139    * Destroy the force.
140    */
141   @Override
142   public void destroy() {
143     if (pointer != null) {
144       OpenMM_AmoebaGeneralizedKirkwoodForce_destroy(pointer);
145       pointer = null;
146     }
147   }
148 
149   /**
150    * Get the descreen offset.
151    *
152    * @return The descreen offset.
153    */
154   public double getDescreenOffset() {
155     return OpenMM_AmoebaGeneralizedKirkwoodForce_getDescreenOffset(pointer);
156   }
157 
158   /**
159    * Get the dielectric offset.
160    *
161    * @return The dielectric offset.
162    */
163   public double getDielectricOffset() {
164     return OpenMM_AmoebaGeneralizedKirkwoodForce_getDielectricOffset(pointer);
165   }
166 
167   /**
168    * Get the include cavity term.
169    *
170    * @return The include cavity term.
171    */
172   public int getIncludeCavityTerm() {
173     return OpenMM_AmoebaGeneralizedKirkwoodForce_getIncludeCavityTerm(pointer);
174   }
175 
176   /**
177    * Get the number of particles in the force.
178    *
179    * @return The number of particles.
180    */
181   public int getNumParticles() {
182     return OpenMM_AmoebaGeneralizedKirkwoodForce_getNumParticles(pointer);
183   }
184 
185   /**
186    * Get the force field parameters for a particle.
187    *
188    * @param index          the index of the particle for which to get parameters
189    * @param charge         the charge of the particle, measured in units of the proton charge (output)
190    * @param radius         the atomic radius of the particle, measured in nm (output)
191    * @param scalingFactor  the scaling factor for the particle (output)
192    * @param descreenRadius the atomic radius of the particle for descreening, measure in nm (output)
193    * @param neckFactor     the scaling factor for interstitial neck descreening (unitless) (output)
194    */
195   public void getParticleParameters(int index, DoubleByReference charge, DoubleByReference radius,
196                                     DoubleByReference scalingFactor, DoubleByReference descreenRadius,
197                                     DoubleByReference neckFactor) {
198     OpenMM_AmoebaGeneralizedKirkwoodForce_getParticleParameters(pointer, index, charge, radius,
199         scalingFactor, descreenRadius, neckFactor);
200   }
201 
202   /**
203    * Get the probe radius.
204    *
205    * @return The probe radius.
206    */
207   public double getProbeRadius() {
208     return OpenMM_AmoebaGeneralizedKirkwoodForce_getProbeRadius(pointer);
209   }
210 
211   /**
212    * Get the solute dielectric constant.
213    *
214    * @return The solute dielectric constant.
215    */
216   public double getSoluteDielectric() {
217     return OpenMM_AmoebaGeneralizedKirkwoodForce_getSoluteDielectric(pointer);
218   }
219 
220   /**
221    * Get the solvent dielectric constant.
222    *
223    * @return The solvent dielectric constant.
224    */
225   public double getSolventDielectric() {
226     return OpenMM_AmoebaGeneralizedKirkwoodForce_getSolventDielectric(pointer);
227   }
228 
229   /**
230    * Get the surface area factor.
231    *
232    * @return The surface area factor.
233    */
234   public double getSurfaceAreaFactor() {
235     return OpenMM_AmoebaGeneralizedKirkwoodForce_getSurfaceAreaFactor(pointer);
236   }
237 
238   /**
239    * Get Tanh function parameters b0, b1 and b2.
240    *
241    * @param b0 The first tanh parameter (output).
242    * @param b1 The second tanh parameter (output).
243    * @param b2 The third tanh parameter (output).
244    */
245   public void getTanhParameters(DoubleByReference b0, DoubleByReference b1, DoubleByReference b2) {
246     OpenMM_AmoebaGeneralizedKirkwoodForce_getTanhParameters(pointer, b0, b1, b2);
247   }
248 
249   /**
250    * Get the tanh rescaling.
251    *
252    * @return The tanh rescaling.
253    */
254   public int getTanhRescaling() {
255     return OpenMM_AmoebaGeneralizedKirkwoodForce_getTanhRescaling(pointer);
256   }
257 
258   /**
259    * Set the descreen offset.
260    *
261    * @param offset The descreen offset.
262    */
263   public void setDescreenOffset(double offset) {
264     OpenMM_AmoebaGeneralizedKirkwoodForce_setDescreenOffset(pointer, offset);
265   }
266 
267   /**
268    * Set the dielectric offset.
269    *
270    * @param offset The dielectric offset.
271    */
272   public void setDielectricOffset(double offset) {
273     OpenMM_AmoebaGeneralizedKirkwoodForce_setDielectricOffset(pointer, offset);
274   }
275 
276   /**
277    * Set the include cavity term.
278    *
279    * @param includeCavityTerm The include cavity term.
280    */
281   public void setIncludeCavityTerm(int includeCavityTerm) {
282     OpenMM_AmoebaGeneralizedKirkwoodForce_setIncludeCavityTerm(pointer, includeCavityTerm);
283   }
284 
285   /**
286    * Set the force field parameters for a particle.
287    *
288    * @param index          the index of the particle for which to set parameters
289    * @param charge         the charge of the particle, measured in units of the proton charge
290    * @param radius         the atomic radius of the particle, measured in nm
291    * @param scalingFactor  the scaling factor for the particle
292    * @param descreenRadius the atomic radius of the particle for descreening, measure in nm
293    * @param neckFactor     the scaling factor for interstitial neck descreening (unitless)
294    */
295   public void setParticleParameters(int index, double charge, double radius, double scalingFactor, double descreenRadius, double neckFactor) {
296     OpenMM_AmoebaGeneralizedKirkwoodForce_setParticleParameters(pointer, index, charge, radius, scalingFactor, descreenRadius, neckFactor);
297   }
298 
299   /**
300    * Set the probe radius.
301    *
302    * @param radius The probe radius.
303    */
304   public void setProbeRadius(double radius) {
305     OpenMM_AmoebaGeneralizedKirkwoodForce_setProbeRadius(pointer, radius);
306   }
307 
308   /**
309    * Set the solute dielectric constant.
310    *
311    * @param dielectric The solute dielectric constant.
312    */
313   public void setSoluteDielectric(double dielectric) {
314     OpenMM_AmoebaGeneralizedKirkwoodForce_setSoluteDielectric(pointer, dielectric);
315   }
316 
317   /**
318    * Set the solvent dielectric constant.
319    *
320    * @param dielectric The solvent dielectric constant.
321    */
322   public void setSolventDielectric(double dielectric) {
323     OpenMM_AmoebaGeneralizedKirkwoodForce_setSolventDielectric(pointer, dielectric);
324   }
325 
326   /**
327    * Set the surface area factor.
328    *
329    * @param surfaceAreaFactor The surface area factor.
330    */
331   public void setSurfaceAreaFactor(double surfaceAreaFactor) {
332     OpenMM_AmoebaGeneralizedKirkwoodForce_setSurfaceAreaFactor(pointer, surfaceAreaFactor);
333   }
334 
335   /**
336    * Set the tanh parameters.
337    *
338    * @param beta0 The tanh parameter beta0.
339    * @param beta1 The tanh parameter beta1.
340    * @param beta2 The tanh parameter beta2.
341    */
342   public void setTanhParameters(double beta0, double beta1, double beta2) {
343     OpenMM_AmoebaGeneralizedKirkwoodForce_setTanhParameters(pointer, beta0, beta1, beta2);
344   }
345 
346   /**
347    * Set the tanh rescaling.
348    *
349    * @param tanhRescale The tanh rescaling.
350    */
351   public void setTanhRescaling(int tanhRescale) {
352     OpenMM_AmoebaGeneralizedKirkwoodForce_setTanhRescaling(pointer, tanhRescale);
353   }
354 
355   /**
356    * Update the parameters in the context.
357    *
358    * @param context The OpenMM context.
359    */
360   public void updateParametersInContext(Context context) {
361     if (context.hasContextPointer()) {
362       OpenMM_AmoebaGeneralizedKirkwoodForce_updateParametersInContext(pointer, context.getPointer());
363     }
364   }
365 
366   /**
367    * Check if the force uses periodic boundary conditions.
368    *
369    * @return True if the force uses periodic boundary conditions.
370    */
371   @Override
372   public boolean usesPeriodicBoundaryConditions() {
373     int pbc = OpenMM_AmoebaGeneralizedKirkwoodForce_usesPeriodicBoundaryConditions(pointer);
374     return pbc == OpenMM_True;
375   }
376 
377 }