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.potential;
39  
40  import java.util.Arrays;
41  
42  import static ffx.utilities.Constants.KCAL_TO_GRAM_ANG2_PER_PS2;
43  import static java.lang.System.arraycopy;
44  
45  /**
46   * The current state of the molecular dynamics simulation.
47   */
48  public class SystemState {
49  
50    /**
51     * Number of dynamics variables. The length of x, v, a, aPrevious, gradient, and mass.
52     */
53    protected final int numberOfVariables;
54    /**
55     * Coordinates.
56     */
57    protected final double[] x;
58    /**
59     * Velocities.
60     */
61    protected final double[] v;
62    /**
63     * Accelerations.
64     */
65    protected final double[] a;
66    /**
67     * Previous accelerations.
68     */
69    protected final double[] aPrevious;
70    /**
71     * The gradient.
72     */
73    protected final double[] gradient;
74    /**
75     * Mass for each degree of freedom.
76     */
77    protected final double[] mass;
78    /**
79     * Current temperature.
80     */
81    double temperature;
82    /**
83     * Current kinetic energy.
84     */
85    double kineticEnergy;
86    /**
87     * Current potential energy.
88     */
89    double potentialEnergy;
90  
91    /**
92     * Constructor for MDState.
93     *
94     * @param numberOfVariables The number of variables.
95     */
96    public SystemState(int numberOfVariables) {
97      this.numberOfVariables = numberOfVariables;
98      x = new double[numberOfVariables];
99      v = new double[numberOfVariables];
100     a = new double[numberOfVariables];
101     aPrevious = new double[numberOfVariables];
102     gradient = new double[numberOfVariables];
103     mass = new double[numberOfVariables];
104   }
105 
106   /**
107    * Get an unmodifiable view of the current state.
108    */
109   public UnmodifiableState getUnmodifiableState() {
110     return new UnmodifiableState(x, v, a, aPrevious, mass, gradient, kineticEnergy,
111         potentialEnergy, temperature);
112   }
113 
114   /**
115    * Get the number of variables.
116    *
117    * @return The number of variables.
118    */
119   public int getNumberOfVariables() {
120     return numberOfVariables;
121   }
122 
123   /**
124    * Revert the current state to the passed UnmodifiableState.
125    *
126    * @param state The state to revert to.
127    */
128   public void revertState(UnmodifiableState state) {
129     assert (state.x().length == numberOfVariables);
130     arraycopy(state.x(), 0, x, 0, numberOfVariables);
131     arraycopy(state.v(), 0, v, 0, numberOfVariables);
132     arraycopy(state.a(), 0, a, 0, numberOfVariables);
133     arraycopy(state.aPrevious(), 0, aPrevious, 0, numberOfVariables);
134     arraycopy(state.mass(), 0, mass, 0, numberOfVariables);
135     arraycopy(state.gradient(), 0, gradient, 0, numberOfVariables);
136     kineticEnergy = state.kineticEnergy();
137     potentialEnergy = state.potentialEnergy();
138     temperature = state.temperature();
139   }
140 
141   /**
142    * Set the mass of each degree of freedom.
143    *
144    * @param mass The mass of each degree of freedom.
145    */
146   public void setMass(double[] mass) {
147     assert (mass.length == numberOfVariables);
148     arraycopy(mass, 0, this.mass, 0, numberOfVariables);
149   }
150 
151   /**
152    * Set the coordinates via a copy of the passed array into the internal array.
153    *
154    * @param x The coordinates.
155    */
156   public void setCoordinates(double[] x) {
157     assert (x.length == numberOfVariables);
158     arraycopy(x, 0, this.x, 0, numberOfVariables);
159   }
160 
161   /**
162    * Set the velocities via a copy of the passed array into the internal array.
163    *
164    * @param v The velocities.
165    */
166   public void setVelocities(double[] v) {
167     assert (v.length == numberOfVariables);
168     arraycopy(v, 0, this.v, 0, numberOfVariables);
169   }
170 
171   /**
172    * Set the accelerations via a copy of the passed array into the internal array.
173    *
174    * @param a The accelerations.
175    */
176   public void setAccelerations(double[] a) {
177     assert (a.length == numberOfVariables);
178     arraycopy(a, 0, this.a, 0, numberOfVariables);
179   }
180 
181   /**
182    * Set the previous accelerations via a copy of the passed array into the internal array.
183    *
184    * @param aPrevious The previous accelerations.
185    */
186   public void setPreviousAccelerations(double[] aPrevious) {
187     assert (aPrevious.length == numberOfVariables);
188     arraycopy(aPrevious, 0, this.aPrevious, 0, numberOfVariables);
189   }
190 
191   /**
192    * Get a reference to the internal coordinates array.
193    *
194    * @return The coordinates.
195    */
196   public double[] x() {
197     return x;
198   }
199 
200   /**
201    * Get a reference to the internal velocities array.
202    *
203    * @return The velocities.
204    */
205   public double[] v() {
206     return v;
207   }
208 
209   /**
210    * Get a reference to the internal accelerations array.
211    *
212    * @return The accelerations.
213    */
214   public double[] a() {
215     return a;
216   }
217 
218   /**
219    * Get a reference to the internal previous accelerations array.
220    *
221    * @return The previous accelerations.
222    */
223   public double[] aPrevious() {
224     return aPrevious;
225   }
226 
227   /**
228    * Get a reference to the internal mass array.
229    *
230    * @return The mass.
231    */
232   public double[] getMass() {
233     return mass;
234   }
235 
236   /**
237    * Get a reference to the internal gradient array.
238    *
239    * @return The gradient.
240    */
241   public double[] gradient() {
242     return gradient;
243   }
244 
245   /**
246    * Get a copy of the internal coordinate array.
247    *
248    * @return The coordinates.
249    */
250   public double[] getCoordinatesCopy() {
251     return Arrays.copyOf(x, numberOfVariables);
252   }
253 
254   /**
255    * Copy the current accelerations to the previous accelerations.
256    */
257   public void copyAccelerationsToPrevious() {
258     arraycopy(a, 0, aPrevious, 0, numberOfVariables);
259   }
260 
261   /**
262    * Set the temperature.
263    *
264    * @param temperature The temperature.
265    */
266   public void setTemperature(double temperature) {
267     this.temperature = temperature;
268   }
269 
270   /**
271    * Set the kinetic energy.
272    *
273    * @param kineticEnergy The kinetic energy.
274    */
275   public void setKineticEnergy(double kineticEnergy) {
276     this.kineticEnergy = kineticEnergy;
277   }
278 
279   /**
280    * Set the potential energy.
281    *
282    * @param potentialEnergy The potential energy.
283    */
284   public void setPotentialEnergy(double potentialEnergy) {
285     this.potentialEnergy = potentialEnergy;
286   }
287 
288   /**
289    * Get the temperature.
290    */
291   public double getTemperature() {
292     return temperature;
293   }
294 
295   /**
296    * Get the kinetic energy.
297    */
298   public double getKineticEnergy() {
299     return kineticEnergy;
300   }
301 
302   /**
303    * Get the potential energy.
304    */
305   public double getPotentialEnergy() {
306     return potentialEnergy;
307   }
308 
309   /**
310    * Get the total energy as the sum of the kinetic and potential energies.
311    */
312   public double getTotalEnergy() {
313     return kineticEnergy + potentialEnergy;
314   }
315 
316   /**
317    * Compute the kinetic energy from the current velocities and masses.
318    *
319    * @return The kinetic energy.
320    */
321   public double getKineticEnergyFromVelocities() {
322     double e = 0.0;
323     for (int i = 0; i < numberOfVariables; i++) {
324       double m = mass[i];
325       if (m > 0.0) {
326         double velocity = v[i];
327         double v2 = velocity * velocity;
328         e += m * v2;
329       }
330     }
331     e *= 0.5 / KCAL_TO_GRAM_ANG2_PER_PS2;
332     return e;
333   }
334 
335 }