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 }