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.algorithms.dynamics.integrators;
39
40 import ffx.numerics.Constraint;
41 import ffx.numerics.Potential;
42 import ffx.potential.ForceFieldEnergy;
43 import ffx.potential.SystemState;
44
45 import java.util.ArrayList;
46 import java.util.List;
47 import java.util.logging.Logger;
48
49 /**
50 * The Integrator class is responsible for propagation of degrees of freedom through time.
51 * Implementations must define their behavior at pre-force and post-force evaluation time points.
52 *
53 * @author Michael J. Schnieders
54 * @since 1.0
55 */
56 public abstract class Integrator {
57
58 private static final Logger logger = Logger.getLogger(Integrator.class.getName());
59 /**
60 * Numerical tolerance (as a fraction of bond length) permitted for numerical solutions to
61 * constraints.
62 */
63 protected final double constraintTolerance = ForceFieldEnergy.DEFAULT_CONSTRAINT_TOLERANCE;
64
65 /**
66 * The MDState class contains the current state of the Molecular Dynamics simulation.
67 */
68 protected final SystemState state;
69 /** Time step (psec). */
70 protected double dt;
71 /** Any geometric constraints to apply during integration. */
72 protected List<Constraint> constraints = new ArrayList<>();
73 /** If there are constraints present. */
74 protected boolean useConstraints = false;
75 /** Half the time step (psec). */
76 double dt_2;
77
78 /**
79 * Constructor for Integrator.
80 *
81 * @param state The MD state to operate on.
82 */
83 public Integrator(SystemState state) {
84 this.state = state;
85 dt = 1.0e-3;
86 dt_2 = dt / 2.0;
87 }
88
89
90 /**
91 * Parse an integrator String into an instance of the IntegratorEnum enum.
92 *
93 * @param str Integrator string.
94 * @return Integrator enum.
95 */
96 public static IntegratorEnum parseIntegrator(String str) {
97 try {
98 String integrator = str.toUpperCase().replaceAll("\\s+", "");
99 integrator = integrator.replaceAll("-", "_");
100 return IntegratorEnum.valueOf(integrator);
101 } catch (Exception e) {
102 logger.info(String.format(" Could not parse %s as an integrator; defaulting to Verlet.", str));
103 return IntegratorEnum.VERLET;
104 }
105 }
106
107 /**
108 * Adds a set of Constraints that this Integrator must respect.
109 *
110 * @param addedConstraints Constraints to add.
111 */
112 public void addConstraints(List<Constraint> addedConstraints) {
113 constraints.addAll(addedConstraints);
114 useConstraints = true;
115 }
116
117 /** Copy acceleration to previous acceleration. */
118 public void copyAccelerationToPrevious() {
119 state.copyAccelerationsToPrevious();
120 }
121
122 /**
123 * Returns a copy of the list of Constraints.
124 *
125 * @return All Constraints this Integrator respects.
126 */
127 public List<Constraint> getConstraints() {
128 return new ArrayList<>(constraints);
129 }
130
131 /**
132 * Get the time step.
133 *
134 * @return the time step (psec).
135 */
136 public double getTimeStep() {
137 return dt;
138 }
139
140 /**
141 * Set the time step.
142 *
143 * @param dt the time step (psec).
144 */
145 public abstract void setTimeStep(double dt);
146
147 /**
148 * Integrator post-force evaluation operation.
149 *
150 * @param gradient the gradient for the post-force operation.
151 */
152 public abstract void postForce(double[] gradient);
153
154 /**
155 * Integrator pre-force evaluation operation.
156 *
157 * @param potential the Potential this integrator operates on.
158 */
159 public abstract void preForce(Potential potential);
160
161 }