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.thermostats; 39 40 import ffx.numerics.Constraint; 41 import ffx.numerics.Potential.VARIABLE_TYPE; 42 import ffx.potential.SystemState; 43 44 import java.util.Collections; 45 import java.util.List; 46 47 import static java.lang.String.format; 48 import static org.apache.commons.math3.util.FastMath.sqrt; 49 50 /** 51 * Thermostat a molecular dynamics trajectory to an external bath using the Berendsen weak-coupling 52 * thermostat. 53 * 54 * @author Michael J. Schnieders 55 * @see <a href="http://link.aip.org/link/?JCP/81/3684">H. J. C. Berendsen, J. P. M. Postma, W. F. 56 * van Gunsteren, A. DiNola and J. R. Hauk, "Molecular Dynamics with Coupling to an External 57 * Bath", Journal of Chemical Physics, 81, 3684-3690 (1984)</a> 58 */ 59 public class Berendsen extends Thermostat { 60 61 /** Berendsen time constant (psec). */ 62 private double tau; 63 64 /** 65 * Constructor for Berendsen. 66 * 67 * @param type The VARIABLE_TYPE of each variable. 68 * @param targetTemperature The target temperatures. 69 * @param tau Berendsen thermostat time constant (psec). 70 */ 71 public Berendsen(SystemState state, VARIABLE_TYPE[] type, double targetTemperature, double tau) { 72 this(state, type, targetTemperature, tau, Collections.emptyList()); 73 } 74 75 public Berendsen(SystemState state, VARIABLE_TYPE[] type, double targetTemperature, double tau, 76 List<Constraint> constraints) { 77 super(state, type, targetTemperature, constraints); 78 this.name = ThermostatEnum.BERENDSEN; 79 this.tau = tau; 80 } 81 82 /** 83 * Constructor for Berendsen. 84 * 85 * @param state The MDState to operate on. 86 * @param type The VARIABLE_TYPE of each variable. 87 * @param targetTemperature The target temperatures. 88 */ 89 public Berendsen(SystemState state, VARIABLE_TYPE[] type, double targetTemperature) { 90 this(state, type, targetTemperature, 0.2e0); 91 } 92 93 /** 94 * {@inheritDoc} 95 * 96 * <p>Full step velocity modification. 97 */ 98 @Override 99 public void fullStep(double dt) { 100 double ratio = targetTemperature / state.getTemperature(); 101 double scale = sqrt(1.0 + (dt / tau) * (ratio - 1.0)); 102 double[] v = state.v(); 103 double[] mass = state.getMass(); 104 for (int i = 0; i < state.getNumberOfVariables(); i++) { 105 if (mass[i] > 0.0) { 106 v[i] *= scale; 107 } 108 } 109 } 110 111 /** 112 * Getter for the field <code>tau</code>. 113 * 114 * @return a double. 115 */ 116 public double getTau() { 117 return tau; 118 } 119 120 /** 121 * Setter for the field <code>tau</code>. 122 * 123 * @param tau a double. 124 */ 125 public void setTau(double tau) { 126 this.tau = tau; 127 } 128 129 /** 130 * {@inheritDoc} 131 * 132 * <p>No velocity modifications are made by the Berendsen method at the half-step. 133 */ 134 @Override 135 public void halfStep(double dt) { 136 } 137 138 /** 139 * Add Thermostat details to the kinetic energy and temperature details. 140 * 141 * @return Description of the thermostat, kinetic energy and temperature. 142 */ 143 public String toThermostatString() { 144 return format("\n Berendsen Thermostat (tau = %8.3f psec)\n %s", tau, super.toString()); 145 } 146 147 /** {@inheritDoc} */ 148 @Override 149 public String toString() { 150 return "Berendsen"; 151 } 152 }