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 }