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.openmm;
39  
40  import com.sun.jna.ptr.PointerByReference;
41  
42  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_addSubsystemThermostat;
43  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_addThermostat;
44  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_computeHeatBathEnergy;
45  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_create;
46  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_create_2;
47  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_destroy;
48  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_getCollisionFrequency;
49  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_getMaximumPairDistance;
50  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_getNumThermostats;
51  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_getRelativeCollisionFrequency;
52  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_getRelativeTemperature;
53  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_getTemperature;
54  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_getThermostat;
55  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_hasSubsystemThermostats;
56  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_setCollisionFrequency;
57  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_setMaximumPairDistance;
58  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_setRelativeCollisionFrequency;
59  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_setRelativeTemperature;
60  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_setTemperature;
61  import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_NoseHooverIntegrator_step;
62  
63  /**
64   * This is an Integrator which simulates a System using one or more Nose Hoover chain
65   * thermostats, using the "middle" leapfrog propagation algorithm described in
66   * J. Phys. Chem. A 2019, 123, 6056-6079.
67   */
68  public class NoseHooverIntegrator extends Integrator {
69  
70    /**
71     * Create a NoseHooverIntegrator with a single thermostat.
72     *
73     * @param pointer A pointer to the native OpenMM NoseHooverIntegrator object.
74     */
75    public NoseHooverIntegrator(PointerByReference pointer) {
76      super(pointer);
77    }
78  
79    /**
80     * Create a NoseHooverIntegrator with a single thermostat.
81     *
82     * @param stepSize The step size with which to integrate the system (in ps).
83     */
84    public NoseHooverIntegrator(double stepSize) {
85      super(OpenMM_NoseHooverIntegrator_create(stepSize));
86    }
87  
88    /**
89     * Create a NoseHooverIntegrator with detailed thermostat parameters.
90     *
91     * @param stepSize           The step size with which to integrate the system (in ps).
92     * @param temperature        The temperature of the heat bath (in Kelvin).
93     * @param collisionFrequency The collision frequency (in 1/ps).
94     * @param numMTS             The number of multiple time step levels.
95     * @param numYoshidaSuzuki   The number of Yoshida-Suzuki steps.
96     * @param numNoseHoover      The number of Nosé-Hoover chain thermostats.
97     */
98    public NoseHooverIntegrator(double stepSize, double temperature, double collisionFrequency,
99                                int numMTS, int numYoshidaSuzuki, int numNoseHoover) {
100     super(OpenMM_NoseHooverIntegrator_create_2(stepSize, temperature, collisionFrequency,
101         numMTS, numYoshidaSuzuki, numNoseHoover));
102   }
103 
104   /**
105    * Add a subsystem thermostat to the integrator.
106    *
107    * @param particles                  The particles to be controlled by this thermostat.
108    * @param chainWeights               The weights for the thermostat chain.
109    * @param temperature                The temperature for this thermostat (in Kelvin).
110    * @param collisionFrequency         The collision frequency for this thermostat (in 1/ps).
111    * @param relativeTemperature        The relative temperature scaling factor.
112    * @param relativeCollisionFrequency The relative collision frequency scaling factor.
113    * @param numMTS                     The number of multiple time step levels.
114    * @param numYoshidaSuzuki           The number of Yoshida-Suzuki steps.
115    * @param numNoseHoover              The number of Nosé-Hoover chain thermostats.
116    * @return The index of the thermostat that was added.
117    */
118   public int addSubsystemThermostat(PointerByReference particles, PointerByReference chainWeights,
119                                     double temperature, double collisionFrequency,
120                                     double relativeTemperature, double relativeCollisionFrequency,
121                                     int numMTS, int numYoshidaSuzuki, int numNoseHoover) {
122     return OpenMM_NoseHooverIntegrator_addSubsystemThermostat(pointer, particles, chainWeights,
123         temperature, collisionFrequency,
124         relativeTemperature, relativeCollisionFrequency,
125         numMTS, numYoshidaSuzuki, numNoseHoover);
126   }
127 
128   /**
129    * Add a thermostat to the integrator.
130    *
131    * @param temperature        The temperature for this thermostat (in Kelvin).
132    * @param collisionFrequency The collision frequency for this thermostat (in 1/ps).
133    * @param numMTS             The number of multiple time step levels.
134    * @param numYoshidaSuzuki   The number of Yoshida-Suzuki steps.
135    * @param numNoseHoover      The number of Nosé-Hoover chain thermostats.
136    * @return The index of the thermostat that was added.
137    */
138   public int addThermostat(double temperature, double collisionFrequency,
139                            int numMTS, int numYoshidaSuzuki, int numNoseHoover) {
140     return OpenMM_NoseHooverIntegrator_addThermostat(pointer, temperature, collisionFrequency,
141         numMTS, numYoshidaSuzuki, numNoseHoover);
142   }
143 
144   /**
145    * Compute the total energy of all heat baths.
146    *
147    * @return The total heat bath energy.
148    */
149   public double computeHeatBathEnergy() {
150     return OpenMM_NoseHooverIntegrator_computeHeatBathEnergy(pointer);
151   }
152 
153   /**
154    * Destroy the integrator.
155    */
156   @Override
157   public void destroy() {
158     if (pointer != null) {
159       OpenMM_NoseHooverIntegrator_destroy(pointer);
160       pointer = null;
161     }
162   }
163 
164   /**
165    * Get the collision frequency for a thermostat.
166    *
167    * @param thermostat The index of the thermostat.
168    * @return The collision frequency (in 1/ps).
169    */
170   public double getCollisionFrequency(int thermostat) {
171     return OpenMM_NoseHooverIntegrator_getCollisionFrequency(pointer, thermostat);
172   }
173 
174   /**
175    * Get the maximum pair distance for neighbor list updates.
176    *
177    * @return The maximum pair distance (in nm).
178    */
179   public double getMaximumPairDistance() {
180     return OpenMM_NoseHooverIntegrator_getMaximumPairDistance(pointer);
181   }
182 
183   /**
184    * Get the number of thermostats.
185    *
186    * @return The number of thermostats.
187    */
188   public int getNumThermostats() {
189     return OpenMM_NoseHooverIntegrator_getNumThermostats(pointer);
190   }
191 
192   /**
193    * Get the relative collision frequency for a thermostat.
194    *
195    * @param thermostat The index of the thermostat.
196    * @return The relative collision frequency scaling factor.
197    */
198   public double getRelativeCollisionFrequency(int thermostat) {
199     return OpenMM_NoseHooverIntegrator_getRelativeCollisionFrequency(pointer, thermostat);
200   }
201 
202   /**
203    * Get the relative temperature for a thermostat.
204    *
205    * @param thermostat The index of the thermostat.
206    * @return The relative temperature scaling factor.
207    */
208   public double getRelativeTemperature(int thermostat) {
209     return OpenMM_NoseHooverIntegrator_getRelativeTemperature(pointer, thermostat);
210   }
211 
212   /**
213    * Get the temperature for a thermostat.
214    *
215    * @param thermostat The index of the thermostat.
216    * @return The temperature (in Kelvin).
217    */
218   public double getTemperature(int thermostat) {
219     return OpenMM_NoseHooverIntegrator_getTemperature(pointer, thermostat);
220   }
221 
222   /**
223    * Get a reference to a thermostat.
224    *
225    * @param thermostat The index of the thermostat.
226    * @return A reference to the thermostat object.
227    */
228   public PointerByReference getThermostat(int thermostat) {
229     return OpenMM_NoseHooverIntegrator_getThermostat(pointer, thermostat);
230   }
231 
232   /**
233    * Check if the integrator has subsystem thermostats.
234    *
235    * @return 1 if subsystem thermostats are present, 0 otherwise.
236    */
237   public int hasSubsystemThermostats() {
238     return OpenMM_NoseHooverIntegrator_hasSubsystemThermostats(pointer);
239   }
240 
241   /**
242    * Set the collision frequency for a thermostat.
243    *
244    * @param collisionFrequency The collision frequency (in 1/ps).
245    * @param thermostat         The index of the thermostat.
246    */
247   public void setCollisionFrequency(double collisionFrequency, int thermostat) {
248     OpenMM_NoseHooverIntegrator_setCollisionFrequency(pointer, collisionFrequency, thermostat);
249   }
250 
251   /**
252    * Set the maximum pair distance for neighbor list updates.
253    *
254    * @param distance The maximum pair distance (in nm).
255    */
256   public void setMaximumPairDistance(double distance) {
257     OpenMM_NoseHooverIntegrator_setMaximumPairDistance(pointer, distance);
258   }
259 
260   /**
261    * Set the relative collision frequency for a thermostat.
262    *
263    * @param relativeCollisionFrequency The relative collision frequency scaling factor.
264    * @param thermostat                 The index of the thermostat.
265    */
266   public void setRelativeCollisionFrequency(double relativeCollisionFrequency, int thermostat) {
267     OpenMM_NoseHooverIntegrator_setRelativeCollisionFrequency(pointer, relativeCollisionFrequency, thermostat);
268   }
269 
270   /**
271    * Set the relative temperature for a thermostat.
272    *
273    * @param relativeTemperature The relative temperature scaling factor.
274    * @param thermostat          The index of the thermostat.
275    */
276   public void setRelativeTemperature(double relativeTemperature, int thermostat) {
277     OpenMM_NoseHooverIntegrator_setRelativeTemperature(pointer, relativeTemperature, thermostat);
278   }
279 
280   /**
281    * Set the temperature for a thermostat.
282    *
283    * @param temperature The temperature (in Kelvin).
284    * @param thermostat  The index of the thermostat.
285    */
286   public void setTemperature(double temperature, int thermostat) {
287     OpenMM_NoseHooverIntegrator_setTemperature(pointer, temperature, thermostat);
288   }
289 
290   /**
291    * Advance a simulation through time by taking a series of time steps.
292    *
293    * @param steps The number of time steps to take.
294    */
295   public void step(int steps) {
296     OpenMM_NoseHooverIntegrator_step(pointer, steps);
297   }
298 }