196 lines
8.9 KiB
Python
196 lines
8.9 KiB
Python
"""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)
|