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-2024.
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 }