Page MenuHomec4science

thermostats.py
No OneTemporary

File Metadata

Created
Fri, Aug 9, 12:04

thermostats.py

"""Deals with creating the thermostats class.
Copyright (C) 2013, Joshua More and Michele Ceriotti
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http.//www.gnu.org/licenses/>.
Chooses between the different possible thermostat options and creates the
appropriate thermostat object, with suitable parameters.
Classes:
InputThermo: Deals with creating the thermostat object from a file, and
writing the checkpoints.
"""
__all__ = ['InputThermo']
import numpy as np
from ipi.utils.depend import *
from ipi.utils.inputvalue import *
from ipi.engine.thermostats import *
class InputThermo(Input):
"""Thermostat input class.
Handles generating the appropriate thermostat class from the xml input file,
and generating the xml checkpoiunt tags and data from an instance of the
object.
Attributes:
mode: An optional string giving the type of the thermostat used. Defaults
to 'langevin'.
Fields:
ethermo: An optional float giving the amount of heat energy transferred
to the bath. Defaults to 0.0.
tau: An optional float giving the damping time scale. Defaults to 1.0.
pile_scale: Scaling for the PILE damping relative to the critical damping.
A: An optional array of floats giving the drift matrix. Defaults to 0.0.
C: An optional array of floats giving the static covariance matrix.
Defaults to 0.0.
s: An optional array of floats giving the additional momentum-scaled
momenta in GLE. Defaults to 0.0.
"""
attribs = { "mode": (InputAttribute, { "dtype" : str,
"options" : [ "", "langevin", "svr", "pile_l", "pile_g", "gle", "nm_gle", "nm_gle_g" ],
"help" : "The style of thermostatting. 'langevin' specifies a white noise langevin equation to be attached to the cartesian representation of the momenta. 'svr' attaches a velocity rescaling thermostat to the cartesian representation of the momenta. Both 'pile_l' and 'pile_g' attaches a white noise langevin thermostat to the normal mode representation, with 'pile_l' attaching a local langevin thermostat to the centroid mode and 'pile_g' instead attaching a global velocity rescaling thermostat. 'gle' attaches a coloured noise langevin thermostat to the cartesian representation of the momenta, 'nm_gle' attaches a coloured noise langevin thermostat to the normal mode representation of the momenta and a langevin thermostat to the centroid and 'nm_gle_g' attaches a gle thermostat to the normal modes and a svr thermostat to the centroid."
}) }
fields = { "ethermo" : (InputValue, { "dtype" : float,
"default" : 0.0,
"help" : "The initial value of the thermostat energy. Used when the simulation is restarted to guarantee continuity of the conserved quantity.",
"dimension" : "energy" }),
"tau" : (InputValue, { "dtype" : float,
"default" : 0.0,
"help" : "The friction coefficient for white noise thermostats.",
"dimension" : "time" }),
"pile_scale" : (InputValue, { "dtype" : float,
"default" : 1.0,
"help" : "Scaling for the PILE damping relative to the critical damping."} ),
"A" : (InputArray, { "dtype" : float,
"default" : input_default(factory=np.zeros, args = (0,)),
"help" : "The friction matrix for GLE thermostats.",
"dimension" : "frequency" }),
"C" : (InputArray, { "dtype" : float,
"default" : input_default(factory=np.zeros, args = (0,)),
"help" : "The covariance matrix for GLE thermostats.",
"dimension" : "temperature" }),
"s" : (InputArray, { "dtype" : float,
"default" : input_default(factory=np.zeros, args = (0,)),
"help" : "Input values for the additional momenta in GLE.",
"dimension" : "ms-momentum" })
}
default_help = "Simulates an external heat bath to keep the velocity distribution at the correct temperature."
default_label = "THERMOSTATS"
def store(self, thermo):
"""Takes a thermostat instance and stores a minimal representation of it.
Args:
thermo: A thermostat object.
Raises:
TypeError: Raised if the thermostat is not a recognized type.
"""
super(InputThermo,self).store(thermo)
if type(thermo) is ThermoLangevin:
self.mode.store("langevin")
self.tau.store(thermo.tau)
elif type(thermo) is ThermoSVR:
self.mode.store("svr")
self.tau.store(thermo.tau)
elif type(thermo) is ThermoPILE_L:
self.mode.store("pile_l")
self.tau.store(thermo.tau)
self.pile_scale.store(thermo.pilescale)
elif type(thermo) is ThermoPILE_G:
self.mode.store("pile_g")
self.tau.store(thermo.tau)
self.pile_scale.store(thermo.pilescale)
elif type(thermo) is ThermoGLE:
self.mode.store("gle")
self.A.store(thermo.A)
if dget(thermo,"C")._func is None:
self.C.store(thermo.C)
self.s.store(thermo.s)
elif type(thermo) is ThermoNMGLE:
self.mode.store("nm_gle")
self.A.store(thermo.A)
if dget(thermo,"C")._func is None:
self.C.store(thermo.C)
self.s.store(thermo.s)
elif type(thermo) is ThermoNMGLEG:
self.mode.store("nm_gle_g")
self.A.store(thermo.A)
self.tau.store(thermo.tau)
if dget(thermo,"C")._func is None:
self.C.store(thermo.C)
self.s.store(thermo.s)
elif type(thermo) is Thermostat:
self.mode.store("")
else:
raise TypeError("Unknown thermostat mode " + type(thermo).__name__)
self.ethermo.store(thermo.ethermo)
def fetch(self):
"""Creates a thermostat object.
Returns:
A thermostat object of the appropriate type and with the appropriate
parameters given the attributes of the InputThermo object.
Raises:
TypeError: Raised if the thermostat type is not a recognized option.
"""
super(InputThermo,self).fetch()
if self.mode.fetch() == "langevin":
thermo = ThermoLangevin(tau=self.tau.fetch())
elif self.mode.fetch() == "svr":
thermo = ThermoSVR(tau=self.tau.fetch())
elif self.mode.fetch() == "pile_l":
thermo = ThermoPILE_L(tau=self.tau.fetch(), scale=self.pile_scale.fetch())
elif self.mode.fetch() == "pile_g":
thermo = ThermoPILE_G(tau=self.tau.fetch(), scale=self.pile_scale.fetch())
elif self.mode.fetch() == "gle":
rC = self.C.fetch()
if len(rC) == 0:
rC = None
thermo = ThermoGLE(A=self.A.fetch(),C=rC)
thermo.s = self.s.fetch()
elif self.mode.fetch() == "nm_gle":
rC = self.C.fetch()
if len(rC) == 0:
rC = None
thermo = ThermoNMGLE(A=self.A.fetch(),C=rC)
thermo.s = self.s.fetch()
elif self.mode.fetch() == "nm_gle_g":
rC = self.C.fetch()
if len(rC) == 0:
rC = None
thermo = ThermoNMGLEG(A=self.A.fetch(),C=rC, tau=self.tau.fetch())
thermo.s = self.s.fetch()
elif self.mode.fetch() == "" :
thermo=Thermostat()
else:
raise TypeError("Invalid thermostat mode " + self.mode.fetch())
thermo.ethermo = self.ethermo.fetch()
return thermo
def check(self):
"""Checks that the parameter arrays represents a valid thermostat."""
super(InputThermo,self).check()
if self.mode.fetch() in ["langevin", "svr", "pile_l", "pile_g", "nm_gle_g"]:
if self.tau.fetch() <= 0:
raise ValueError("The thermostat friction coefficient must be set to a positive value")
if self.mode.fetch() in ["gle", "nm_gle", "nm_gle_g"]:
pass # PERHAPS DO CHECKS THAT MATRICES SATISFY REASONABLE CONDITIONS (POSITIVE-DEFINITENESS, ETC)

Event Timeline