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.IntByReference;
42  import com.sun.jna.ptr.PointerByReference;
43  
44  import java.nio.IntBuffer;
45  
46  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Boolean.OpenMM_True;
47  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_addExclusion;
48  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_addGlobalParameter;
49  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_addParticle;
50  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_addPerParticleParameter;
51  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_addTabulatedFunction;
52  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_create;
53  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_createExclusionsFromBonds;
54  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_destroy;
55  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getCutoffDistance;
56  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getEnergyFunction;
57  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getExclusionParticles;
58  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getGlobalParameterDefaultValue;
59  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getGlobalParameterName;
60  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getNonbondedMethod;
61  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getNumExclusions;
62  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getNumGlobalParameters;
63  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getNumParticles;
64  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getNumParticlesPerSet;
65  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getNumPerParticleParameters;
66  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getNumTabulatedFunctions;
67  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getParticleParameters;
68  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getPerParticleParameterName;
69  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getPermutationMode;
70  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getTabulatedFunction;
71  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getTabulatedFunctionName;
72  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_getTypeFilter;
73  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_setCutoffDistance;
74  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_setEnergyFunction;
75  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_setExclusionParticles;
76  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_setGlobalParameterDefaultValue;
77  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_setGlobalParameterName;
78  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_setNonbondedMethod;
79  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_setParticleParameters;
80  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_setPerParticleParameterName;
81  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_setPermutationMode;
82  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_setTypeFilter;
83  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_updateParametersInContext;
84  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_CustomManyParticleForce_usesPeriodicBoundaryConditions;
85  
86  /**
87   * This class supports a wide variety of nonbonded N-particle interactions, where N is user specified.  The
88   * interaction energy is determined by an arbitrary, user specified algebraic expression that is evaluated for
89   * every possible set of N particles in the system.  It may depend on the positions of the individual particles,
90   * the distances between pairs of particles, the angles formed by sets of three particles, and the dihedral
91   * angles formed by sets of four particles.
92   *
93   * <p>Be aware that the cost of evaluating an N-particle interaction increases very rapidly with N.  Values larger
94   * than N=3 are rarely used.
95   *
96   * <p>We refer to a set of particles for which the energy is being evaluated  as p1, p2, p3, etc.  The energy expression
97   * may depend on the following variables and functions:
98   *
99   * <ul>
100  * <li>x1, y1, z1, x2, y2, z2, etc.: The x, y, and z coordinates of the particle positions.  For example, x1
101  * is the x coordinate of particle p1, and y3 is the y coordinate of particle p3.</li>
102  * <li>distance(p1, p2): the distance between particles p1 and p2 (where "p1" and "p2" may be replaced by the names
103  * of whichever particles you want to calculate the distance between).</li>
104  * <li>angle(p1, p2, p3): the angle formed by the three specified particles.</li>
105  * <li>dihedral(p1, p2, p3, p4): the dihedral angle formed by the four specified particles.</li>
106  * <li>arbitrary global and per-particle parameters that you define.</li>
107  * </ul>
108  *
109  * <p>To use this class, create a CustomManyParticleForce object, passing an algebraic expression to the constructor
110  * that defines the interaction energy of each set of particles.  Then call addPerParticleParameter() to define per-particle
111  * parameters, and addGlobalParameter() to define global parameters.  The values of per-particle parameters are specified as
112  * part of the system definition, while values of global parameters may be modified during a simulation by calling Context::setParameter().
113  *
114  * <p>Next, call addParticle() once for each particle in the System to set the values of its per-particle parameters.
115  * The number of particles for which you set parameters must be exactly equal to the number of particles in the
116  * System, or else an exception will be thrown when you try to create a Context.  After a particle has been added,
117  * you can modify its parameters by calling setParticleParameters().  This will have no effect on Contexts that already exist
118  * unless you call updateParametersInContext().
119  *
120  * <p>Multi-particle interactions can be very expensive to evaluate, so they are usually used with a cutoff distance.  The exact
121  * interpretation of the cutoff depends on the permutation mode, as discussed below.
122  *
123  * <p>CustomManyParticleForce also lets you specify "exclusions", particular pairs of particles whose interactions should be
124  * omitted from force and energy calculations.  This is most often used for particles that are bonded to each other.
125  * If you specify a pair of particles as an exclusion, <i>all</i> sets that include those two particles will be omitted.
126  *
127  * <p>As an example, the following code creates a CustomManyParticleForce that implements an Axilrod-Teller potential.  This
128  * is an interaction between three particles that depends on all three distances and angles formed by the particles.
129  *
130  * <pre>{@code
131  * CustomManyParticleForce force = new CustomManyParticleForce(3,
132  *     "C*(1+3*cos(theta1)*cos(theta2)*cos(theta3))/(r12*r13*r23)^3;" +
133  *     "theta1=angle(p1,p2,p3); theta2=angle(p2,p3,p1); theta3=angle(p3,p1,p2);" +
134  *     "r12=distance(p1,p2); r13=distance(p1,p3); r23=distance(p2,p3)");
135  * force.setPermutationMode(CustomManyParticleForce.SinglePermutation);
136  * }</pre>
137  *
138  * <p>This force depends on one parameter, C.  The following code defines it as a global parameter:
139  *
140  * <pre>{@code
141  * force.addGlobalParameter("C", 1.0);
142  * }</pre>
143  *
144  * <p>Notice that the expression is symmetric with respect to the particles.  It only depends on the products
145  * cos(theta1)*cos(theta2)*cos(theta3) and r12*r13*r23, both of which are unchanged if the labels p1, p2, and p3 are permuted.
146  * This is required because we specified SinglePermutation as the permutation mode.  (This is the default, so we did not
147  * really need to set it, but doing so makes the example clearer.)  In this mode, the expression is only evaluated once for
148  * each set of particles.  No guarantee is made about which particle will be identified as p1, p2, etc.  Therefore, the
149  * energy <i>must</i> be symmetric with respect to exchange of particles.  Otherwise, the results would be undefined because
150  * permuting the labels would change the energy.
151  */
152 public class CustomManyParticleForce extends Force {
153 
154   /**
155    * Create a CustomManyParticleForce.
156    *
157    * @param particlesPerSet The number of particles involved in each interaction.
158    * @param energy          The algebraic expression that gives the interaction energy for each set of particles.
159    */
160   public CustomManyParticleForce(int particlesPerSet, String energy) {
161     super(OpenMM_CustomManyParticleForce_create(particlesPerSet, energy));
162   }
163 
164   /**
165    * Add an exclusion for a pair of particles.
166    *
167    * @param particle1 The index of the first particle.
168    * @param particle2 The index of the second particle.
169    * @return The index of the exclusion that was added.
170    */
171   public int addExclusion(int particle1, int particle2) {
172     return OpenMM_CustomManyParticleForce_addExclusion(pointer, particle1, particle2);
173   }
174 
175   /**
176    * Add a new global parameter that the interaction may depend on.
177    *
178    * @param name         The name of the parameter.
179    * @param defaultValue The default value of the parameter.
180    * @return The index of the parameter that was added.
181    */
182   public int addGlobalParameter(String name, double defaultValue) {
183     return OpenMM_CustomManyParticleForce_addGlobalParameter(pointer, name, defaultValue);
184   }
185 
186   /**
187    * Add a new global parameter that the interaction may depend on.
188    *
189    * @param name         The name of the parameter.
190    * @param defaultValue The default value of the parameter.
191    * @return The index of the parameter that was added.
192    */
193   public int addGlobalParameter(Pointer name, double defaultValue) {
194     return OpenMM_CustomManyParticleForce_addGlobalParameter(pointer, name, defaultValue);
195   }
196 
197   /**
198    * Add a particle to the Force.
199    *
200    * @param parameters The list of parameters for the new particle.
201    * @param type       The particle type.
202    * @return The index of the particle that was added.
203    */
204   public int addParticle(PointerByReference parameters, int type) {
205     return OpenMM_CustomManyParticleForce_addParticle(pointer, parameters, type);
206   }
207 
208   /**
209    * Add a new per-particle parameter that the interaction may depend on.
210    *
211    * @param name The name of the parameter.
212    * @return The index of the parameter that was added.
213    */
214   public int addPerParticleParameter(String name) {
215     return OpenMM_CustomManyParticleForce_addPerParticleParameter(pointer, name);
216   }
217 
218   /**
219    * Add a new per-particle parameter that the interaction may depend on.
220    *
221    * @param name The name of the parameter.
222    * @return The index of the parameter that was added.
223    */
224   public int addPerParticleParameter(Pointer name) {
225     return OpenMM_CustomManyParticleForce_addPerParticleParameter(pointer, name);
226   }
227 
228   /**
229    * Add a tabulated function that may appear in the energy expression.
230    *
231    * @param name     The name of the function as it appears in expressions.
232    * @param function A TabulatedFunction object defining the function.
233    * @return The index of the function that was added.
234    */
235   public int addTabulatedFunction(String name, PointerByReference function) {
236     return OpenMM_CustomManyParticleForce_addTabulatedFunction(pointer, name, function);
237   }
238 
239   /**
240    * Add a tabulated function that may appear in the energy expression.
241    *
242    * @param name     The name of the function as it appears in expressions.
243    * @param function A TabulatedFunction object defining the function.
244    * @return The index of the function that was added.
245    */
246   public int addTabulatedFunction(Pointer name, PointerByReference function) {
247     return OpenMM_CustomManyParticleForce_addTabulatedFunction(pointer, name, function);
248   }
249 
250   /**
251    * Identify exclusions based on the molecular topology.
252    *
253    * @param bonds      The set of bonds based on which to construct exclusions.
254    * @param bondCutoff Pairs of particles that are separated by this many bonds or fewer are added as exclusions.
255    */
256   public void createExclusionsFromBonds(PointerByReference bonds, int bondCutoff) {
257     OpenMM_CustomManyParticleForce_createExclusionsFromBonds(pointer, bonds, bondCutoff);
258   }
259 
260   /**
261    * Destroy the force.
262    */
263   @Override
264   public void destroy() {
265     if (pointer != null) {
266       OpenMM_CustomManyParticleForce_destroy(pointer);
267       pointer = null;
268     }
269   }
270 
271   /**
272    * Get the cutoff distance (in nm) being used for interactions.
273    *
274    * @return The cutoff distance, measured in nm.
275    */
276   public double getCutoffDistance() {
277     return OpenMM_CustomManyParticleForce_getCutoffDistance(pointer);
278   }
279 
280   /**
281    * Get the algebraic expression that gives the interaction energy for each set of particles.
282    *
283    * @return The energy expression.
284    */
285   public String getEnergyFunction() {
286     Pointer p = OpenMM_CustomManyParticleForce_getEnergyFunction(pointer);
287     if (p == null) {
288       return null;
289     }
290     return p.getString(0);
291   }
292 
293   /**
294    * Get the particles in an exclusion.
295    *
296    * @param index     The index of the exclusion for which to get particles.
297    * @param particle1 The index of the first particle in the exclusion (output).
298    * @param particle2 The index of the second particle in the exclusion (output).
299    */
300   public void getExclusionParticles(int index, IntByReference particle1, IntByReference particle2) {
301     OpenMM_CustomManyParticleForce_getExclusionParticles(pointer, index, particle1, particle2);
302   }
303 
304   /**
305    * Get the particles in an exclusion.
306    *
307    * @param index     The index of the exclusion for which to get particles.
308    * @param particle1 The index of the first particle in the exclusion (output).
309    * @param particle2 The index of the second particle in the exclusion (output).
310    */
311   public void getExclusionParticles(int index, IntBuffer particle1, IntBuffer particle2) {
312     OpenMM_CustomManyParticleForce_getExclusionParticles(pointer, index, particle1, particle2);
313   }
314 
315   /**
316    * Get the default value of a global parameter.
317    *
318    * @param index The index of the parameter for which to get the default value.
319    * @return The parameter default value.
320    */
321   public double getGlobalParameterDefaultValue(int index) {
322     return OpenMM_CustomManyParticleForce_getGlobalParameterDefaultValue(pointer, index);
323   }
324 
325   /**
326    * Get the name of a global parameter.
327    *
328    * @param index The index of the parameter for which to get the name.
329    * @return The parameter name.
330    */
331   public String getGlobalParameterName(int index) {
332     Pointer p = OpenMM_CustomManyParticleForce_getGlobalParameterName(pointer, index);
333     if (p == null) {
334       return null;
335     }
336     return p.getString(0);
337   }
338 
339   /**
340    * Get the method used for handling long range nonbonded interactions.
341    *
342    * @return The nonbonded method.
343    */
344   public int getNonbondedMethod() {
345     return OpenMM_CustomManyParticleForce_getNonbondedMethod(pointer);
346   }
347 
348   /**
349    * Get the number of exclusions.
350    *
351    * @return The number of exclusions.
352    */
353   public int getNumExclusions() {
354     return OpenMM_CustomManyParticleForce_getNumExclusions(pointer);
355   }
356 
357   /**
358    * Get the number of global parameters that the interaction depends on.
359    *
360    * @return The number of parameters.
361    */
362   public int getNumGlobalParameters() {
363     return OpenMM_CustomManyParticleForce_getNumGlobalParameters(pointer);
364   }
365 
366   /**
367    * Get the number of particles for which force field parameters have been defined.
368    *
369    * @return The number of particles.
370    */
371   public int getNumParticles() {
372     return OpenMM_CustomManyParticleForce_getNumParticles(pointer);
373   }
374 
375   /**
376    * Get the number of particles involved in each interaction.
377    *
378    * @return The number of particles per set.
379    */
380   public int getNumParticlesPerSet() {
381     return OpenMM_CustomManyParticleForce_getNumParticlesPerSet(pointer);
382   }
383 
384   /**
385    * Get the number of per-particle parameters that the interaction depends on.
386    *
387    * @return The number of parameters.
388    */
389   public int getNumPerParticleParameters() {
390     return OpenMM_CustomManyParticleForce_getNumPerParticleParameters(pointer);
391   }
392 
393   /**
394    * Get the number of tabulated functions that have been defined.
395    *
396    * @return The number of functions.
397    */
398   public int getNumTabulatedFunctions() {
399     return OpenMM_CustomManyParticleForce_getNumTabulatedFunctions(pointer);
400   }
401 
402   /**
403    * Get the parameters for a particle.
404    *
405    * @param index      The index of the particle for which to get parameters.
406    * @param parameters The list of parameters (output).
407    * @param type       The particle type (output).
408    */
409   public void getParticleParameters(int index, PointerByReference parameters, IntByReference type) {
410     OpenMM_CustomManyParticleForce_getParticleParameters(pointer, index, parameters, type);
411   }
412 
413   /**
414    * Get the parameters for a particle.
415    *
416    * @param index      The index of the particle for which to get parameters.
417    * @param parameters The list of parameters (output).
418    * @param type       The particle type (output).
419    */
420   public void getParticleParameters(int index, PointerByReference parameters, IntBuffer type) {
421     OpenMM_CustomManyParticleForce_getParticleParameters(pointer, index, parameters, type);
422   }
423 
424   /**
425    * Get the name of a per-particle parameter.
426    *
427    * @param index The index of the parameter for which to get the name.
428    * @return The parameter name.
429    */
430   public String getPerParticleParameterName(int index) {
431     Pointer p = OpenMM_CustomManyParticleForce_getPerParticleParameterName(pointer, index);
432     if (p == null) {
433       return null;
434     }
435     return p.getString(0);
436   }
437 
438   /**
439    * Get the permutation mode.
440    *
441    * @return The permutation mode.
442    */
443   public int getPermutationMode() {
444     return OpenMM_CustomManyParticleForce_getPermutationMode(pointer);
445   }
446 
447   /**
448    * Get a reference to a tabulated function that may appear in the energy expression.
449    *
450    * @param index The index of the function to get.
451    * @return The TabulatedFunction object defining the function.
452    */
453   public PointerByReference getTabulatedFunction(int index) {
454     return OpenMM_CustomManyParticleForce_getTabulatedFunction(pointer, index);
455   }
456 
457   /**
458    * Get the name of a tabulated function that may appear in the energy expression.
459    *
460    * @param index The index of the function to get.
461    * @return The name of the function as it appears in expressions.
462    */
463   public String getTabulatedFunctionName(int index) {
464     Pointer p = OpenMM_CustomManyParticleForce_getTabulatedFunctionName(pointer, index);
465     if (p == null) {
466       return null;
467     }
468     return p.getString(0);
469   }
470 
471   /**
472    * Get the type filter for the specified type.
473    *
474    * @param index The particle type index.
475    * @param types The allowed types for interactions (output).
476    */
477   public void getTypeFilter(int index, PointerByReference types) {
478     OpenMM_CustomManyParticleForce_getTypeFilter(pointer, index, types);
479   }
480 
481   /**
482    * Set the cutoff distance (in nm) being used for interactions.
483    *
484    * @param distance The cutoff distance, measured in nm.
485    */
486   public void setCutoffDistance(double distance) {
487     OpenMM_CustomManyParticleForce_setCutoffDistance(pointer, distance);
488   }
489 
490   /**
491    * Set the algebraic expression that gives the interaction energy for each set of particles.
492    *
493    * @param energy The energy expression.
494    */
495   public void setEnergyFunction(String energy) {
496     OpenMM_CustomManyParticleForce_setEnergyFunction(pointer, energy);
497   }
498 
499   /**
500    * Set the algebraic expression that gives the interaction energy for each set of particles.
501    *
502    * @param energy The energy expression.
503    */
504   public void setEnergyFunction(Pointer energy) {
505     OpenMM_CustomManyParticleForce_setEnergyFunction(pointer, energy);
506   }
507 
508   /**
509    * Set the particles in an exclusion.
510    *
511    * @param index     The index of the exclusion for which to set particles.
512    * @param particle1 The index of the first particle in the exclusion.
513    * @param particle2 The index of the second particle in the exclusion.
514    */
515   public void setExclusionParticles(int index, int particle1, int particle2) {
516     OpenMM_CustomManyParticleForce_setExclusionParticles(pointer, index, particle1, particle2);
517   }
518 
519   /**
520    * Set the default value of a global parameter.
521    *
522    * @param index        The index of the parameter for which to set the default value.
523    * @param defaultValue The default value of the parameter.
524    */
525   public void setGlobalParameterDefaultValue(int index, double defaultValue) {
526     OpenMM_CustomManyParticleForce_setGlobalParameterDefaultValue(pointer, index, defaultValue);
527   }
528 
529   /**
530    * Set the name of a global parameter.
531    *
532    * @param index The index of the parameter for which to set the name.
533    * @param name  The name of the parameter.
534    */
535   public void setGlobalParameterName(int index, String name) {
536     OpenMM_CustomManyParticleForce_setGlobalParameterName(pointer, index, name);
537   }
538 
539   /**
540    * Set the name of a global parameter.
541    *
542    * @param index The index of the parameter for which to set the name.
543    * @param name  The name of the parameter.
544    */
545   public void setGlobalParameterName(int index, Pointer name) {
546     OpenMM_CustomManyParticleForce_setGlobalParameterName(pointer, index, name);
547   }
548 
549   /**
550    * Set the method used for handling long range nonbonded interactions.
551    *
552    * @param method The nonbonded method.
553    */
554   public void setNonbondedMethod(int method) {
555     OpenMM_CustomManyParticleForce_setNonbondedMethod(pointer, method);
556   }
557 
558   /**
559    * Set the parameters for a particle.
560    *
561    * @param index      The index of the particle for which to set parameters.
562    * @param parameters The list of parameters for the particle.
563    * @param type       The particle type.
564    */
565   public void setParticleParameters(int index, PointerByReference parameters, int type) {
566     OpenMM_CustomManyParticleForce_setParticleParameters(pointer, index, parameters, type);
567   }
568 
569   /**
570    * Set the name of a per-particle parameter.
571    *
572    * @param index The index of the parameter for which to set the name.
573    * @param name  The name of the parameter.
574    */
575   public void setPerParticleParameterName(int index, String name) {
576     OpenMM_CustomManyParticleForce_setPerParticleParameterName(pointer, index, name);
577   }
578 
579   /**
580    * Set the name of a per-particle parameter.
581    *
582    * @param index The index of the parameter for which to set the name.
583    * @param name  The name of the parameter.
584    */
585   public void setPerParticleParameterName(int index, Pointer name) {
586     OpenMM_CustomManyParticleForce_setPerParticleParameterName(pointer, index, name);
587   }
588 
589   /**
590    * Set the permutation mode.
591    *
592    * @param mode The permutation mode.
593    */
594   public void setPermutationMode(int mode) {
595     OpenMM_CustomManyParticleForce_setPermutationMode(pointer, mode);
596   }
597 
598   /**
599    * Set the type filter for the specified type.
600    *
601    * @param index The particle type index.
602    * @param types The allowed types for interactions.
603    */
604   public void setTypeFilter(int index, PointerByReference types) {
605     OpenMM_CustomManyParticleForce_setTypeFilter(pointer, index, types);
606   }
607 
608   /**
609    * Update the per-particle parameters and tabulated functions in a Context to match those stored in this Force object.
610    *
611    * @param context The Context in which to update the parameters.
612    */
613   public void updateParametersInContext(Context context) {
614     if (context.hasContextPointer()) {
615       OpenMM_CustomManyParticleForce_updateParametersInContext(pointer, context.getPointer());
616     }
617   }
618 
619   /**
620    * Check if the force uses periodic boundary conditions.
621    *
622    * @return True if the force uses periodic boundary conditions.
623    */
624   @Override
625   public boolean usesPeriodicBoundaryConditions() {
626     int pbc = OpenMM_CustomManyParticleForce_usesPeriodicBoundaryConditions(pointer);
627     return pbc == OpenMM_True;
628   }
629 }