def fetch(self): """Creates a motion calculator object. Returns: An ensemble object of the appropriate mode and with the appropriate objects given the attributes of the InputEnsemble object. """ super(InputMotionBase, self).fetch() if self.mode.fetch() == "replay": sc = Replay(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), intraj=self.file.fetch()) elif self.mode.fetch() == "minimize": sc = GeopMotion(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.optimizer.fetch()) elif self.mode.fetch() == "neb": sc = NEBMover(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.neb_optimizer.fetch()) elif self.mode.fetch() == "dynamics": sc = Dynamics(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.dynamics.fetch()) elif self.mode.fetch() == "vibrations": sc = DynMatrixMover(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.vibrations.fetch()) elif self.mode.fetch() == "alchemy": sc = AlchemyMC(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.alchemy.fetch()) elif self.mode.fetch() == "instanton": sc = InstantonMotion(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.instanton.fetch()) elif self.mode.fetch() == "t_ramp": sc = TemperatureRamp(**self.t_ramp.fetch()) elif self.mode.fetch() == "p_ramp": sc = PressureRamp(**self.p_ramp.fetch()) else: sc = Motion() # raise ValueError("'" + self.mode.fetch() + "' is not a supported motion calculation mode.") return sc
def fetch(self): """Creates a motion calculator object. Returns: An ensemble object of the appropriate mode and with the appropriate objects given the attributes of the InputEnsemble object. """ super(InputMotion, self).fetch() if self.mode.fetch() == "replay": sc = Replay(fixcom=False, fixatoms=None, intraj=self.file.fetch()) elif self.mode.fetch() == "minimize": sc = GeopMover(fixcom=False, fixatoms=None, **self.optimizer.fetch()) elif self.mode.fetch() == "neb": sc = NEBMover(fixcom=False, fixatoms=None, **self.neb_optimizer.fetch()) elif self.mode.fetch() == "dynamics": sc = Dynamics(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.dynamics.fetch()) else: sc = Motion() #raise ValueError("'" + self.mode.fetch() + "' is not a supported motion calculation mode.") return sc
def init_stage1(self, simul): """Initializes the simulation -- first stage. Takes a simulation object, and uses all the data in the initialization queue to fill up the beads and cell data needed to run the simulation. Args: simul: A simulation object to be initialized. Raises: ValueError: Raised if there is a problem with the initialization, if something that should have been has not been, or if the objects that have been specified are not compatible with each other. """ if simul.beads.nbeads == 0: fpos = fmom = fmass = flab = fcell = False # we don't have an explicitly defined beads object yet else: fpos = fmom = fmass = flab = fcell = True for (k, v) in self.queue: info(" # Initializer (stage 1) parsing " + str(k) + " object.", verbosity.high) if k == "cell": if v.mode == "manual": rh = v.value.reshape( (3, 3)) * unit_to_internal("length", v.units, 1.0) elif v.mode == "chk": rh = init_chk(v.value)[1].h elif init_file(v.mode, v.value)[1].h.trace() == -3: # In case the file do not contain any # + cell parameters, the diagonal elements of the cell will be # +set to -1 from the io_units and nothing is read here. continue else: rh = init_file(v.mode, v.value, cell_units=v.units)[1].h if fcell: warning("Overwriting previous cell parameters", verbosity.low) simul.cell.h = rh if simul.cell.V == 0.0: ValueError("Cell provided has zero volume") fcell = True elif k == "masses": if simul.beads.nbeads == 0: raise ValueError( "Cannot initialize the masses before the size of the system is known" ) if fmass: warning("Overwriting previous atomic masses", verbosity.medium) if v.mode == "manual": rm = v.value * unit_to_internal("mass", v.units, 1.0) else: rm = init_beads(v, self.nbeads).m if v.bead < 0: # we are initializing the path if (fmom and fmass): warning( "Rescaling momenta to make up for changed mass", verbosity.medium) simul.beads.p /= simul.beads.sm3 # go to mass-scaled momenta, that are mass-invariant if v.index < 0: simul.beads.m = rm else: # we are initializing a specific atom simul.beads.m[v.index:v.index + 1] = rm if (fmom and fmass): # finishes correcting the momenta simul.beads.p *= simul.beads.sm3 # back to normal momenta else: raise ValueError("Cannot change the mass of a single bead") fmass = True elif k == "labels": if simul.beads.nbeads == 0: raise ValueError( "Cannot initialize the labels before the size of the system is known" ) if flab: warning("Overwriting previous atomic labels", verbosity.medium) if v.mode == "manual": rn = v.value else: rn = init_beads(v, self.nbeads).names if v.bead < 0: # we are initializing the path if v.index < 0: simul.beads.names = rn else: # we are initializing a specific atom simul.beads.names[v.index:v.index + 1] = rn else: raise ValueError( "Cannot change the label of a single bead") flab = True elif k == "positions": if fpos: warning("Overwriting previous atomic positions", verbosity.medium) # read the atomic positions as a vector rq = init_vector(v, self.nbeads, dimension="length", units=v.units) nbeads, natoms = rq.shape natoms //= 3 # check if we must initialize the simulation beads if simul.beads.nbeads == 0: if v.index >= 0: raise ValueError( "Cannot initialize single atoms before the size of the system is known" ) simul.beads.resize(natoms, self.nbeads) set_vector(v, simul.beads.q, rq) fpos = True elif ( k == "velocities" or k == "momenta" ) and v.mode == "thermal": # intercept here thermal initialization, so we don't need to check further down if fmom: warning("Overwriting previous atomic momenta", verbosity.medium) if simul.beads.natoms == 0: raise ValueError( "Cannot initialize momenta before the size of the system is known." ) if not fmass: raise ValueError( "Trying to resample velocities before having masses.") rtemp = v.value * unit_to_internal("temperature", v.units, 1.0) if rtemp <= 0: warning( "Using the simulation temperature to resample velocities", verbosity.low) rtemp = simul.ensemble.temp else: info( " # Resampling velocities at temperature %s %s" % (v.value, v.units), verbosity.low) # pull together a mock initialization to get NM masses right # without too much code duplication if v.bead >= 0: raise ValueError("Cannot thermalize a single bead") if v.index >= 0: rnatoms = 1 else: rnatoms = simul.beads.natoms rbeads = Beads(rnatoms, simul.beads.nbeads) if v.index < 0: rbeads.m[:] = simul.beads.m else: rbeads.m[:] = simul.beads.m[v.index] rnm = NormalModes(mode=simul.nm.mode, transform_method=simul.nm.transform_method, freqs=simul.nm.nm_freqs) rens = Ensemble(temp=simul.ensemble.temp) rmv = Motion() rnm.bind(rens, rmv, rbeads) # then we exploit the sync magic to do a complicated initialization # in the NM representation # with (possibly) shifted-frequencies NM rnm.pnm = simul.prng.gvec( (rbeads.nbeads, 3 * rbeads.natoms)) * np.sqrt( rnm.dynm3) * np.sqrt( rbeads.nbeads * rtemp * Constants.kb) if v.index < 0: simul.beads.p = rbeads.p else: simul.beads.p[:, 3 * v.index:3 * (v.index + 1)] = rbeads.p fmom = True elif k == "momenta": if fmom: warning("Overwriting previous atomic momenta", verbosity.medium) # read the atomic momenta as a vector rp = init_vector(v, self.nbeads, momenta=True, dimension="momentum", units=v.units) nbeads, natoms = rp.shape natoms //= 3 # checks if we must initialize the simulation beads if simul.beads.nbeads == 0: if v.index >= 0: raise ValueError( "Cannot initialize single atoms before the size of the system is known" ) simul.beads.resize(natoms, self.nbeads) rp *= np.sqrt(self.nbeads / nbeads) set_vector(v, simul.beads.p, rp) fmom = True elif k == "velocities": if fmom: warning("Overwriting previous atomic momenta", verbosity.medium) # read the atomic velocities as a vector rv = init_vector(v, self.nbeads, dimension="velocity", units=v.units) nbeads, natoms = rv.shape natoms //= 3 # checks if we must initialize the simulation beads if simul.beads.nbeads == 0 or not fmass: ValueError( "Cannot initialize velocities before the masses of the atoms are known" ) simul.beads.resize(natoms, self.nbeads) warning( "Initializing from velocities uses the previously defined masses -- not the masses inferred from the file -- to build momenta", verbosity.low) if v.index >= 0: rv *= simul.beads.m[v.index] else: for ev in rv: ev *= simul.beads.m3[0] rv *= np.sqrt(self.nbeads / nbeads) set_vector(v, simul.beads.p, rv) fmom = True elif k == "gle": pass # thermostats must be initialised in a second stage if simul.beads.natoms == 0: raise ValueError( "Initializer could not initialize the atomic positions") if simul.cell.V == 0: raise ValueError("Initializer could not initialize the cell") for i in range(simul.beads.natoms): if simul.beads.m[i] <= 0: raise ValueError("Initializer could not initialize the masses") if simul.beads.names[i] == "": raise ValueError( "Initializer could not initialize the atom labels") if not fmom: warning( "Momenta not specified in initialize. Will start with zero velocity if they are not specified in beads.", verbosity.low)
def fetch(self): """Creates a motion calculator object. Returns: An ensemble object of the appropriate mode and with the appropriate objects given the attributes of the InputEnsemble object. """ super(InputMotionBase, self).fetch() if self.mode.fetch() == "replay": sc = Replay( fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), intraj=self.file.fetch(), ) elif self.mode.fetch() == "minimize": sc = GeopMotion(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.optimizer.fetch()) elif self.mode.fetch() == "neb": raise ValueError( "The nudged elastic band calculation has been temporarily disabled until further bug-fixes." ) # sc = NEBMover( # fixcom=self.fixcom.fetch(), # fixatoms=self.fixatoms.fetch(), # **self.neb_optimizer.fetch() # ) elif self.mode.fetch() == "dynamics": sc = Dynamics(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.dynamics.fetch()) elif self.mode.fetch() == "constrained_dynamics": sc = ConstrainedDynamics(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.constrained_dynamics.fetch()) elif self.mode.fetch() == "vibrations": sc = DynMatrixMover(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.vibrations.fetch()) elif self.mode.fetch() == "normalmodes": sc = NormalModeMover(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.normalmodes.fetch()) elif self.mode.fetch() == "scp": sc = SCPhononsMover(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.scp.fetch()) elif self.mode.fetch() == "alchemy": sc = AlchemyMC(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.alchemy.fetch()) elif self.mode.fetch() == "atomswap": sc = AtomSwap(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.atomswap.fetch()) elif self.mode.fetch() == "instanton": sc = InstantonMotion(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.instanton.fetch()) elif self.mode.fetch() == "planetary": sc = Planetary(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.planetary.fetch()) elif self.mode.fetch() == "t_ramp": sc = TemperatureRamp(**self.t_ramp.fetch()) elif self.mode.fetch() == "p_ramp": sc = PressureRamp(**self.p_ramp.fetch()) elif self.mode.fetch() == "al-kmc": sc = AlKMC(fixcom=self.fixcom.fetch(), fixatoms=self.fixatoms.fetch(), **self.al6xxx_kmc.fetch()) else: sc = Motion() # raise ValueError("'" + self.mode.fetch() + "' is not a supported motion calculation mode.") return sc