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.PointerByReference;
41  
42  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_Boolean.OpenMM_True;
43  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_RMSDForce_create;
44  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_RMSDForce_destroy;
45  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_RMSDForce_getParticles;
46  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_RMSDForce_getReferencePositions;
47  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_RMSDForce_setParticles;
48  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_RMSDForce_setReferencePositions;
49  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_RMSDForce_updateParametersInContext;
50  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_RMSDForce_usesPeriodicBoundaryConditions;
51  
52  /**
53   * This is a force whose energy equals the root mean squared deviation (RMSD)
54   * between the current coordinates and a reference structure. It is intended for
55   * use with CustomCVForce. You will not normally want a force that exactly equals
56   * the RMSD, but there are many situations where it is useful to have a restraining
57   * or biasing force that depends on the RMSD in some way.
58   * <p>
59   * The force is computed by first aligning the particle positions to the reference
60   * structure, then computing the RMSD between the aligned positions and the reference.
61   * The computation can optionally be done based on only a subset of the particles
62   * in the system.
63   */
64  public class RMSDForce extends Force {
65  
66    /**
67     * Create an RMSDForce.
68     *
69     * @param referencePositions the reference positions to compute the deviation
70     *                           from. The length of this vector must equal the
71     *                           number of particles in the system, even if not
72     *                           all particles are used in computing the RMSD.
73     * @param particles          the indices of the particles to use when computing
74     *                           the RMSD. If this is empty (the default), all
75     *                           particles in the system will be used.
76     */
77    public RMSDForce(PointerByReference particles, PointerByReference referencePositions) {
78      super(OpenMM_RMSDForce_create(particles, referencePositions));
79    }
80  
81    /**
82     * Destroy the force.
83     */
84    @Override
85    public void destroy() {
86      if (pointer != null) {
87        OpenMM_RMSDForce_destroy(pointer);
88        pointer = null;
89      }
90    }
91  
92    /**
93     * Get the indices of the particles to use when computing the RMSD. If this
94     * is empty, all particles in the system will be used.
95     *
96     * @return the indices of the particles to use when computing the RMSD.
97     */
98    public PointerByReference getParticles() {
99      return OpenMM_RMSDForce_getParticles(pointer);
100   }
101 
102   /**
103    * Get the reference positions to compute the deviation from.
104    *
105    * @return the reference positions to compute the deviation from.
106    */
107   public PointerByReference getReferencePositions() {
108     return OpenMM_RMSDForce_getReferencePositions(pointer);
109   }
110 
111   /**
112    * Set the indices of the particles to use when computing the RMSD. If this
113    * is empty, all particles in the system will be used.
114    *
115    * @param particles the indices of the particles to use when computing the RMSD.
116    */
117   public void setParticles(PointerByReference particles) {
118     OpenMM_RMSDForce_setParticles(pointer, particles);
119   }
120 
121   /**
122    * Set the reference positions to compute the deviation from.
123    *
124    * @param referencePositions the reference positions to compute the deviation from.
125    */
126   public void setReferencePositions(PointerByReference referencePositions) {
127     OpenMM_RMSDForce_setReferencePositions(pointer, referencePositions);
128   }
129 
130   /**
131    * Update the reference positions and particle indices in a Context to match those stored
132    * in this Force object. This method provides an efficient method to update certain parameters
133    * in an existing Context without needing to reinitialize it. Simply call setReferencePositions()
134    * and setParticles() to modify this object's parameters, then call updateParametersInContext()
135    * to copy them over to the Context.
136    *
137    * @param context the Context in which to update the parameters.
138    */
139   public void updateParametersInContext(Context context) {
140     if (context.hasContextPointer()) {
141       OpenMM_RMSDForce_updateParametersInContext(pointer, context.getPointer());
142     }
143   }
144 
145   /**
146    * Returns whether or not this force makes use of periodic boundary
147    * conditions.
148    *
149    * @return true if force uses PBC and false otherwise.
150    */
151   @Override
152   public boolean usesPeriodicBoundaryConditions() {
153     int pbc = OpenMM_RMSDForce_usesPeriodicBoundaryConditions(pointer);
154     return pbc == OpenMM_True;
155   }
156 }