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_Boolean.OpenMM_True;
43 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_MonteCarloFlexibleBarostat_computeCurrentPressure;
44 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_MonteCarloFlexibleBarostat_create;
45 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_MonteCarloFlexibleBarostat_destroy;
46 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_MonteCarloFlexibleBarostat_getDefaultPressure;
47 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_MonteCarloFlexibleBarostat_getDefaultTemperature;
48 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_MonteCarloFlexibleBarostat_getFrequency;
49 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_MonteCarloFlexibleBarostat_getRandomNumberSeed;
50 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_MonteCarloFlexibleBarostat_getScaleMoleculesAsRigid;
51 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_MonteCarloFlexibleBarostat_setDefaultPressure;
52 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_MonteCarloFlexibleBarostat_setDefaultTemperature;
53 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_MonteCarloFlexibleBarostat_setFrequency;
54 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_MonteCarloFlexibleBarostat_setRandomNumberSeed;
55 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_MonteCarloFlexibleBarostat_setScaleMoleculesAsRigid;
56 import static edu.uiowa.jopenmm.OpenMMLibrary.OpenMM_MonteCarloFlexibleBarostat_usesPeriodicBoundaryConditions;
57
58 /**
59 * This class uses a Monte Carlo algorithm to adjust the size of the periodic box,
60 * simulating the effect of constant pressure. It assumes the simulation is running
61 * at constant temperature, and the box size is adjusted to maintain constant pressure.
62 * Unlike MonteCarloBarostat, this version allows flexible scaling of molecules,
63 * making it suitable for systems where molecular flexibility is important.
64 * <p>
65 * This class is most useful for simulating a system at constant pressure when
66 * flexible molecular scaling is desired, such as for systems with significant
67 * intramolecular flexibility or conformational changes.
68 */
69 public class MonteCarloFlexibleBarostat extends Force {
70
71 /**
72 * Create a MonteCarloFlexibleBarostat.
73 *
74 * @param defaultPressure The default pressure acting on the system (in bar).
75 * @param defaultTemperature The default temperature at which the system is being maintained (in Kelvin).
76 * @param frequency The frequency at which Monte Carlo pressure changes should be attempted (in time steps).
77 * @param scaleMoleculesAsRigid Whether to scale molecules as rigid bodies (1) or allow flexible scaling (0).
78 */
79 public MonteCarloFlexibleBarostat(double defaultPressure, double defaultTemperature,
80 int frequency, int scaleMoleculesAsRigid) {
81 super(OpenMM_MonteCarloFlexibleBarostat_create(defaultPressure, defaultTemperature, frequency, scaleMoleculesAsRigid));
82 }
83
84 /**
85 * Compute the current pressure in the system.
86 *
87 * @param context The context for which to compute the pressure.
88 * @param pressure The computed pressure (output).
89 */
90 public void computeCurrentPressure(Context context, PointerByReference pressure) {
91 OpenMM_MonteCarloFlexibleBarostat_computeCurrentPressure(pointer, context.getPointer(), pressure);
92 }
93
94 /**
95 * Destroy the force.
96 */
97 @Override
98 public void destroy() {
99 if (pointer != null) {
100 OpenMM_MonteCarloFlexibleBarostat_destroy(pointer);
101 pointer = null;
102 }
103 }
104
105 /**
106 * Get the default pressure (in bar).
107 *
108 * @return The default pressure acting on the system.
109 */
110 public double getDefaultPressure() {
111 return OpenMM_MonteCarloFlexibleBarostat_getDefaultPressure(pointer);
112 }
113
114 /**
115 * Get the default temperature at which the system is being maintained (in Kelvin).
116 *
117 * @return The default temperature.
118 */
119 public double getDefaultTemperature() {
120 return OpenMM_MonteCarloFlexibleBarostat_getDefaultTemperature(pointer);
121 }
122
123 /**
124 * Get the frequency (in time steps) at which Monte Carlo pressure changes should be attempted.
125 *
126 * @return The frequency of pressure change attempts.
127 */
128 public int getFrequency() {
129 return OpenMM_MonteCarloFlexibleBarostat_getFrequency(pointer);
130 }
131
132 /**
133 * Get the random number seed. See setRandomNumberSeed() for details.
134 *
135 * @return The random number seed.
136 */
137 public int getRandomNumberSeed() {
138 return OpenMM_MonteCarloFlexibleBarostat_getRandomNumberSeed(pointer);
139 }
140
141 /**
142 * Get whether molecules are scaled as rigid bodies.
143 *
144 * @return 1 if molecules are scaled as rigid bodies, 0 if flexible scaling is used.
145 */
146 public int getScaleMoleculesAsRigid() {
147 return OpenMM_MonteCarloFlexibleBarostat_getScaleMoleculesAsRigid(pointer);
148 }
149
150 /**
151 * Set the default pressure acting on the system (in bar).
152 *
153 * @param pressure The default pressure acting on the system.
154 */
155 public void setDefaultPressure(double pressure) {
156 OpenMM_MonteCarloFlexibleBarostat_setDefaultPressure(pointer, pressure);
157 }
158
159 /**
160 * Set the default temperature at which the system is being maintained (in Kelvin).
161 *
162 * @param temperature The default temperature.
163 */
164 public void setDefaultTemperature(double temperature) {
165 OpenMM_MonteCarloFlexibleBarostat_setDefaultTemperature(pointer, temperature);
166 }
167
168 /**
169 * Set the frequency (in time steps) at which Monte Carlo pressure changes should be attempted.
170 *
171 * @param frequency The frequency of pressure change attempts.
172 */
173 public void setFrequency(int frequency) {
174 OpenMM_MonteCarloFlexibleBarostat_setFrequency(pointer, frequency);
175 }
176
177 /**
178 * Set the random number seed. The precise meaning of this parameter is undefined, and is left up
179 * to each Platform to interpret in an appropriate way. It is guaranteed that if two simulations
180 * are run with different random number seeds, the sequence of random numbers will be different.
181 * On the other hand, no guarantees are made about the behavior of simulations that use the same seed.
182 * In particular, Platforms are permitted to use non-deterministic algorithms which produce different
183 * results on successive runs, even if those runs were initialized identically.
184 * <p>
185 * If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context
186 * is created from this Force. This is done to ensure that each Context receives unique random seeds
187 * without you needing to set them explicitly.
188 *
189 * @param seed The random number seed.
190 */
191 public void setRandomNumberSeed(int seed) {
192 OpenMM_MonteCarloFlexibleBarostat_setRandomNumberSeed(pointer, seed);
193 }
194
195 /**
196 * Set whether molecules should be scaled as rigid bodies.
197 *
198 * @param scaleMoleculesAsRigid 1 to scale molecules as rigid bodies, 0 for flexible scaling.
199 */
200 public void setScaleMoleculesAsRigid(int scaleMoleculesAsRigid) {
201 OpenMM_MonteCarloFlexibleBarostat_setScaleMoleculesAsRigid(pointer, scaleMoleculesAsRigid);
202 }
203
204 /**
205 * Returns whether this force makes use of periodic boundary conditions.
206 *
207 * @return True if the force uses periodic boundary conditions.
208 */
209 @Override
210 public boolean usesPeriodicBoundaryConditions() {
211 int pbc = OpenMM_MonteCarloFlexibleBarostat_usesPeriodicBoundaryConditions(pointer);
212 return pbc == OpenMM_True;
213 }
214 }