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