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.numerics; 39 40 /** 41 * Defines a set of geometric constraints that must be applied self-consistently. 42 * 43 * @author Jacob M. Litman 44 * @author Michael J. Schnieders 45 * @since 1.0 46 */ 47 public interface Constraint { 48 49 /** 50 * Applies this Constraint in the context of a partially calculated MD time-step. All arrays are 51 * globally indexed (i.e. includes all system atoms, not just the constrained ones). 52 * 53 * <p>If there is no prior step (e.g. a newly loaded system that has not yet been rigidified), 54 * xPrior and xNew can be copies of each other when passed to the method. 55 * 56 * <p>xPrior corresponds to atomCoordinates in the OpenMM constraint code. Ours will be in 57 * Angstroms, not nm. xNew corresponds to atomCoordinatesP in the OpenMM constraint code. Ours will 58 * be in Angstroms, not nm. 59 * 60 * @param xPrior Atomic coordinates prior to the time-step to be constrained. 61 * @param xNew Atomic coordinates after the time-step; updated in-place to satisfy the 62 * constraint. 63 * @param masses Masses. 64 * @param tol Acceptable constraint tolerance for numerical methods, as a fraction of bond 65 * length. 66 */ 67 void applyConstraintToStep(final double[] xPrior, double[] xNew, final double[] masses, double tol); 68 69 /** 70 * Applies this Constraint to velocities, ensuring relative velocities are perpendicular to 71 * constrained bonds, etc., without affecting positions. All arrays are globally indexed (i.e. 72 * includes all system atoms, not just the constrained ones). 73 * 74 * <p>Our positions will be in Angstroms, and velocities in Angstroms/ps, compared to the OpenMM 75 * nm and nm/ps. 76 * 77 * @param x Atomic coordinates (unchanged). 78 * @param v Velocities (updated in-place to satisfy constraints). 79 * @param masses Masses. 80 * @param tol Acceptable constraint tolerance for numerical methods; likely in Angstroms/ps 81 */ 82 void applyConstraintToVelocities(final double[] x, double[] v, final double[] masses, double tol); 83 84 /** 85 * Returns the atomic XYZ indices of all Atoms constrained. Guaranteed to be unique. The primary 86 * assumption will be that variables are in sets of 3x Cartesian coordinates. 87 * 88 * @return All indices of constrained Atoms. 89 */ 90 int[] constrainedAtomIndices(); 91 92 /** 93 * Checks if this Constraint is satisfied. 94 * 95 * @param x Input coordinates to check. 96 * @param tol Numerical tolerance as a fraction of bond stretch. 97 * @return Whether this Constraint is satisfied. 98 */ 99 boolean constraintSatisfied(final double[] x, double tol); 100 101 /** 102 * Checks if this Constraint is satisfied. Also checks velocities; bond constraints, for example, 103 * require that relative velocity be orthogonal to the bond. If the velocities vector is null or 104 * the tolerance is zero, velocity checks are skipped. 105 * 106 * @param x Input coordinates to check. 107 * @param v Input velocities to check. If null, velocity check disabled. 108 * @param xTol Numerical tolerance for bond lengths. 109 * @param vTol Numerical tolerance for velocity checks (typically in degrees). If zero, 110 * velocity check disabled. 111 * @return Whether this Constraint is satisfied. 112 */ 113 boolean constraintSatisfied(final double[] x, final double[] v, double xTol, double vTol); 114 115 /** 116 * Returns the number of degrees of freedom this Constraint constrains. 117 * 118 * @return Number of frozen DoF. 119 */ 120 int getNumDegreesFrozen(); 121 }