def _add_times(self, ptfile): """Make ptfile time series data an observable""" data = numpy.array(ptfile.time_steps()) label = Label("t", "DLM steps", "time steps") tobs = Observable(data, label) self.add_observable(tobs, independent_variable=True)
def k_boltzmann(dlstr): """Return value of Boltzmann constant in current DL units Args: dlstr (string): "ev" | 'kJ" | "kcal" | "k" | "internal" Returns: Boltzmann constant in the relevant units """ key = dlstr.lower() label = Label("k_b", "Boltzmann Constant", None) if key == "ev": label.units = "eV per Kelvin" parameter = Parameter((1.0/QE_SI)*KB_SI, label) elif key == "kcal": label.units = "kCal per mole per Kelvin" parameter = Parameter((1.0/4184.0)*KB_SI*NA_SI, label) elif key == "kj": label.units = "kJoules per mole per Kelvin" parameter = Parameter((1.0/1000.0)*KB_SI*NA_SI, label) elif key == "k": label.units = "10 Joules per mole per Kelvin" parameter = Parameter((1.0/10.0)*KB_SI*NA_SI, label) elif key == "internal": label.units = "10 Joules per mole per Kelvin" parameter = Parameter((1.0/10.0)*KB_SI*NA_SI, label) else: raise ValueError("units not recognised {}".format(dlstr)) return parameter
def _add_mols_yaml(self, ptfile): """Make observable""" nmoltypes, moldata = ptfile.nmol() for mol in range(nmoltypes): data = numpy.array(moldata[mol]) lmol = self.field.moltypes[mol].name label = Label("nmol" + lmol, "No. molecules " + lmol, None) self.add_observable(Observable(data, label))
def _add_energies(self, ptfile): """Look at energy data and move to obsevable""" energies = dict(dlptfile.ENERGY) eunits = self.field.units for key in energies: data = numpy.array(ptfile.time_series(key)) if numpy.any(data): label = Label(key, dlptfile.KEYS[key], eunits) eobs = Observable(data, label) self.add_observable(eobs)
def _add_ensemble_parameters(self): """Check we have parameters for the Ensemble Temperature: always from control file Volume: if constant, should be set from data Pressure: if required, is from control file N: number of particles """ try: systemp = self.control.main_block.statements["temperature"] syspres = self.control.main_block.statements["pressure"] except KeyError: pass nlabel = Label("N", "No. atoms", None) tlabel = Label("systemp", "Temperature", "K") if isinstance(self.ensemble, htk.ensemble.EnsembleNVT): self.add_parameter(self.config.natom, nlabel) self.add_parameter(systemp, tlabel) elif isinstance(self.ensemble, htk.ensemble.EnsembleNPT): # Add pressure, temperature plabel = Label("syspres", "Pressure", "kAtmos.") self.add_parameter(self.config.natom, nlabel) self.add_parameter(syspres, plabel) self.add_parameter(systemp, tlabel) elif isinstance(self.ensemble, htk.ensemble.EnsembleMuVT): self.add_parameter(systemp, tlabel) # Activities # NEED TO CHECK MOVE TYPE for mover in self.control.main_block.moves[0].movers: activity = mover["molpot"] label = Label("z" + mover["id"], "Activity", "Volume^-1") self.add_parameter(activity, label) else: # No microcanonical examples available assert 0
def _add_atoms(self, ptfile): """Make observable from number of atoms""" # Units are really "None" natomtypes, atomdata = ptfile.natom() for natom in range(natomtypes): data = numpy.array(atomdata[natom]) _, nau1 = numpy.unique(data, return_counts=True) if nau1.size > 1: latom = self.field.atomtypes[natom].name label = Label("natom" + latom, "No. atoms " + latom, None) self.add_observable(Observable(data, label))
def _add_lattice(self, ptfile): """If lattice vectors fixed, ignore. Or treat together""" data1 = numpy.array(ptfile.time_series("L1")) _, nlv1 = numpy.unique(data1, return_counts=True) data2 = numpy.array(ptfile.time_series("L2")) _, nlv2 = numpy.unique(data2, return_counts=True) data3 = numpy.array(ptfile.time_series("L3")) _, nlv3 = numpy.unique(data3, return_counts=True) if nlv1.size > 1 or nlv2.size > 1 or nlv3.size > 1: label = Label("la", "Lat. vector 1", "Angstrom") self.add_observable(Observable(data1, label)) label = Label("lb", "Lat. vector 2", "Angstrom") self.add_observable(Observable(data2, label)) label = Label("lc", "Lat. vector 3", "Angstrom") self.add_observable(Observable(data3, label)) data1 = numpy.array(ptfile.time_series("Lcos1")) _, nlcos1 = numpy.unique(data1, return_counts=True) data2 = numpy.array(ptfile.time_series("Lcos2")) _, nlcos2 = numpy.unique(data2, return_counts=True) data3 = numpy.array(ptfile.time_series("Lcos3")) _, nlcos3 = numpy.unique(data3, return_counts=True) if nlcos1.size > 1 or nlcos2.size > 1 or nlcos3.size > 1: label = Label("lcos1", "Angle 1", "TBC") self.add_observable(Observable(data1, label)) label = Label("lcos2", "Angle 2", "TBC") self.add_observable(Observable(data2, label)) label = Label("lcos3", "Angle 3", "TBC") self.add_observable(Observable(data3, label))
def load(self, filename=None): """Load data from file""" # Parameters f = open(filename, "r") with f: line = f.readline() line = f.readline() match = re.search(r" (\d+)$", line) n = int(match.group(0)) v = 1.0 * n * n line = f.readline() match = re.search(r" (\w+.\w+)$", line) j = float(match.group(0)) line = f.readline() match = re.search(r" (\w+.\w+)$", line) h = float(match.group(0)) line = f.readline() match = re.search(r" (\w+.\w+)$", line) kT = float(match.group(0)) # Load the parameters self.add_parameter(n * n, Label("N", "Number of spins", None)) self.add_parameter(kT, Label("kT", "Temperature", "k_bT")) self.add_parameter(v, Label("V", "Volume", "sites")) self.add_parameter(j, Label("J", "Coupling constant", "k_bT")) self.add_parameter(h, Label("H", "External field", "k_bT")) self.data_source = filename self.data_type = "Ising Model (2d) " + str(n) + "x" + str(n) # Load the observable data data = numpy.loadtxt(filename, skiprows=9) tdata = data[:, 0] sdata = data[:, 1] mdata = data[:, 2] # Form the total energy (per site) edata = sdata.copy() edata[:] = -j * sdata[:] - h * mdata[:] tobs = Observable(tdata, Label("t", "Time", "MC Sweeps")) sobs = Observable(sdata, Label("S", "Interaction Energy", "k_bT/site")) mobs = Observable(mdata, Label("M", "Magnetisation", "k_bT/site")) eobs = Observable(edata, Label("E", "Total Energy", "k_bT/site")) self.add_observable(tobs, independent_variable=True) self.add_observable(sobs) self.add_observable(mobs) self.add_observable(eobs) # Reweighters # Reweighting always takes place via the total energy # (system, not per site), so introduce a factor of the # volume vparam = self.parameter("v") tparam = self.parameter("kt") hparam = self.parameter("h") beta = Parameter(1.0 / kT, Label("beta", "Inverse Energy", "1/k_bT")) rbeta = BetaReweighter("beta", beta, vparam, eobs) rkt = KTReweighter("kt", tparam, vparam, eobs) # To reweight wrt external field, a factor of v/kT is # required as we have magnetistation per site alpha = Parameter(v / kT, Label("a", "Volume/k_bT", "sites/k_bT")) rh = Reweighter("h", hparam, alpha, mobs) self.add_reweighter(rbeta) self.add_reweighter(rkt) self.add_reweighter(rh)
def _add_energy_parameter(self): """Add energy as a parameter""" label = Label("energy", "Energy", "kT") self.add_parameter(energy, label)
def _add_energy_observable(self, data): """Add energy as observable time series""" label = Label("energy", "Energy", self.field.units) self.add_observable(Observable(data, label))
def _add_volume_parameter(self): """Add volume as a parameter""" label = Label("volume", "Volume", "Angstrom^3") volume = self.config.volume() self.add_parameter(volume, label)
def _add_volume_observable(self, vdata): """Add volume as observable time series""" label = Label("volume", "Volume", "Angstrom^3") self.add_observable(Observable(vdata, label))
Values here are to be consistent with those used in DL-MONTE constants.f90 DL_MONTE Units for input/output Temperature Kelvin Length Angstrom Energy Defined by user in FIELD file Charge Electronic charge (?) Pressure kilo Atmospheres """ from inputs.parameter import Parameter from inputs.util import Label LABEL_NA = Label("N_A", "Avogadro's Number", "per mole") LABEL_KB = Label("k_b", "Boltzmann Constant", "Joules per Kelvin") LABEL_QE = Label("q", "Electronic charge", "Coulomb") NA_SI = Parameter(6.022140e+23, LABEL_NA) KB_SI = Parameter(1.3806488e-23, LABEL_KB) QE_SI = Parameter(1.602176e-19, LABEL_QE) def k_boltzmann(dlstr): """Return value of Boltzmann constant in current DL units Args: dlstr (string): "ev" | 'kJ" | "kcal" | "k" | "internal"