def __init__(self, motionlist=None): """Initialises MultiMotion. Args: fixcom: An optional boolean which decides whether the centre of mass motion will be constrained or not. Defaults to False. """ dself = dd(self) dself.dt = depend_value(name="dt", func=self.get_totdt) self.mlist = motionlist for m in self.mlist: dd(m).dt.add_dependant(dself.dt) a = ( # noqa self.dt ) # DON'T ASK WHY BUT IF YOU DON'T DO THAT WEAKREFS TO SELF.DT WILL BE INVALIDATED self.fixatoms = set(self.mlist[0].fixatoms) for m in self.mlist: self.fixatoms = self.fixatoms.intersection(m.fixatoms) self.fixatoms = list(self.fixatoms) self.fixcom = True # fixcom is true only if all movers are fixed for m in self.mlist: self.fixcom = self.fixcom and m.fixcom
def __init__( self, mode, syslist, fflist, outputs, prng, smotion=None, step=0, tsteps=1000, ttime=0, threads=False, ): """Initialises Simulation class. Args: mode: What kind of simulation is this syslist: A list of system objects fflist: A list of forcefield objects prng: A random number object. smotion: A "super-motion" class specifying what to do with different system replicas outputs: A list of output objects. step: An optional integer giving the current simulation time step. Defaults to 0. tsteps: An optional integer giving the total number of steps. Defaults to 1000. ttime: The simulation running time. Used on restart, to keep a cumulative total. """ info(" # Initializing simulation object ", verbosity.low) self.prng = prng self.mode = mode self.threading = threads dself = dd(self) self.syslist = syslist for s in syslist: s.prng = self.prng # bind the system's prng to self prng s.init.init_stage1(s) # TODO - does this have any meaning now that we introduce the smotion class? if self.mode == "md" and len(syslist) > 1: warning("Multiple systems will evolve independently in a '" + self.mode + "' simulation.") self.fflist = {} for f in fflist: self.fflist[f.name] = f self.outtemplate = outputs dself.step = depend_value(name="step", value=step) self.tsteps = tsteps self.ttime = ttime self.smotion = smotion self.chk = None self.rollback = True
def __init__(self, motionlist=None): """Initialises MultiMotion. Args: fixcom: An optional boolean which decides whether the centre of mass motion will be constrained or not. Defaults to False. """ dself = dd(self) dself.dt = depend_value(name="dt", func=self.get_totdt) self.mlist = motionlist for m in self.mlist: dd(m).dt.add_dependant(dself.dt) print dd(m).dt._dependants a = self.dt # DON'T ASK WHY BUT IF YOU DON'T DO THAT WEAKREFS TO SELF.DT WILL BE INVALIDATED self.fixatoms = set(self.mlist[0].fixatoms) for m in self.mlist: self.fixatoms = self.fixatoms.intersection(m.fixatoms) self.fixatoms = list(self.fixatoms) self.fixcom = True # fixcom is true only if all movers are fixed for m in self.mlist: self.fixcom = self.fixcom and m.fixcom
def __init__(self, mode, syslist, fflist, outputs, prng, smotion=None, step=0, tsteps=1000, ttime=0, threads=False): """Initialises Simulation class. Args: mode: What kind of simulation is this syslist: A list of system objects fflist: A list of forcefield objects prng: A random number object. smotion: A "super-motion" class specifying what to do with different system replicas outputs: A list of output objects. step: An optional integer giving the current simulation time step. Defaults to 0. tsteps: An optional integer giving the total number of steps. Defaults to 1000. ttime: The simulation running time. Used on restart, to keep a cumulative total. """ info(" # Initializing simulation object ", verbosity.low) self.prng = prng self.mode = mode self.threading = threads dself = dd(self) self.syslist = syslist for s in syslist: s.prng = self.prng # bind the system's prng to self prng s.init.init_stage1(s) #! TODO - does this have any meaning now that we introduce the smotion class? if self.mode == "md" and len(syslist) > 1: warning("Multiple systems will evolve independently in a '" + self.mode + "' simulation.") self.fflist = {} for f in fflist: self.fflist[f.name] = f self.outtemplate = outputs dself.step = depend_value(name="step", value=step) self.tsteps = tsteps self.ttime = ttime self.smotion = smotion self.chk = None self.rollback = True
def __init__(self, mode, syslist, fflist, outputs, prng, paratemp, step=0, tsteps=1000, ttime=0): """Initialises Simulation class. Args: mode: What kind of simulation is this syslist: A list of system objects fflist: A list of forcefield objects prng: A random number object. paratemp: A parallel tempering helper class. outputs: A list of output objects. step: An optional integer giving the current simulation time step. Defaults to 0. tsteps: An optional integer giving the total number of steps. Defaults to 1000. ttime: The simulation running time. Used on restart, to keep a cumulative total. """ info(" # Initializing simulation object ", verbosity.low) self.prng = prng self.mode = mode dself = dd(self) self.syslist = syslist for s in syslist: s.prng = self.prng # bind the system's prng to self prng s.init.init_stage1(s) if self.mode == "md" and len(syslist) > 1: warning("Multiple systems will evolve independently in a '" + self.mode + "' simulation.") self.fflist = {} for f in fflist: self.fflist[f.name] = f self.outtemplate = outputs dself.step = depend_value(name="step", value=step) self.tsteps = tsteps self.ttime = ttime self.paratemp = paratemp self.chk = None self.rollback = True
def __init__(self, fixcom=False, fixatoms=None): """Initialises Motion object. Args: fixcom: An optional boolean which decides whether the centre of mass motion will be constrained or not. Defaults to False. fixatoms: A list of atoms that should be held fixed to their initial positions. """ dself = dd(self) dself.dt = depend_value(name="dt", value=0.0) self.fixcom = fixcom if fixatoms is None: self.fixatoms = np.zeros(0, int) else: self.fixatoms = fixatoms self.beads = self.cell = self.forces = self.prng = self.nm = None
def __init__(self, mode, geop, nstep, a0, ncell, nvac, nsi, nmg, neval, diffusion_barrier_al, diffusion_prefactor_al, diffusion_barrier_mg, diffusion_prefactor_mg, diffusion_barrier_si, diffusion_prefactor_si, idx=[], tottime=0, ecache_file="", qcache_file="", thermostat=None, barostat=None, fixcom=False, fixatoms=None, nmts=None): """Initialises a "dynamics" motion object. Args: dt: The timestep of the simulation algorithms. fixcom: An optional boolean which decides whether the centre of mass motion will be constrained or not. Defaults to False. """ # This will generate a lattice model based on a primitive FCC cell. the lattice is represented in three ways: # 1. as a string in which each lattice site is identified by a letter # 2. by a list of the lattice sites in 3D space, in 1-1 mapping with the letters # 3. by a list of the atoms, whose lattice position is indicated by an integer self.nstep = nstep self.ncell = ncell self.nvac = nvac self.nsi = nsi self.nmg = nmg self.nsites = self.ncell**3 self.natoms = self.nsites - self.nvac self.neval = neval self.diffusion_barrier_al = diffusion_barrier_al self.diffusion_prefactor_al = diffusion_prefactor_al if diffusion_barrier_mg > 0: self.diffusion_barrier_mg = diffusion_barrier_mg else: self.diffusion_barrier_mg = diffusion_barrier_al if diffusion_barrier_si > 0: self.diffusion_barrier_si = diffusion_barrier_si else: self.diffusion_barrier_si = diffusion_barrier_al if diffusion_prefactor_mg > 0: self.diffusion_prefactor_mg = diffusion_prefactor_mg else: self.diffusion_prefactor_mg = diffusion_prefactor_al if diffusion_prefactor_si > 0: self.diffusion_prefactor_si = diffusion_prefactor_si else: self.diffusion_prefactor_si = diffusion_prefactor_al self.barriers = { "A": self.diffusion_barrier_al, "M": self.diffusion_barrier_mg, "S": self.diffusion_barrier_si } self.prefactors = { "A": self.diffusion_prefactor_al, "M": self.diffusion_prefactor_mg, "S": self.diffusion_prefactor_si } self.a0 = a0 cell = np.zeros((3, 3)) cell[0] = [ 0.7071067811865475, 0.35355339059327373, 0.35355339059327373 ] cell[1] = [0., 0.6123724356957945, 0.20412414523193154] cell[2] = [0., 0., 0.5773502691896258] self.scell = self.a0 * cell self.dcell = Cell() self.dcell.h = self.scell * self.ncell print "LATTICE PARAM ", self.a0 # this is the list of lattice sites, in 3D coordinates ix, iy, iz = np.meshgrid(range(self.ncell), range(self.ncell), range(self.ncell), indexing='ij') self.sites = np.dot( np.asarray([ix.flatten(), iy.flatten(), iz.flatten()]).T, self.scell.T) print len(self.sites), self.nsites, "###" # now we build list of nearest neighbors (fcc-lattice hardcoded!) self.neigh = np.zeros((self.nsites, 12), int) nneigh = np.zeros(self.nsites, int) # could be done in a more analytic way but whatever, I'm too lazy a02 = 1.01 * 0.5 * self.a0**2 # perhaps 1.01 it is not enough, must check! for i in xrange( self.nsites): # determines the connectivity of the lattice rij = self.sites.copy().flatten() for j in xrange(self.nsites): rij[3 * j:3 * j + 3] -= self.sites[i] self.dcell.array_pbc(rij) rij.shape = (self.nsites, 3) for j in xrange(i): if np.dot(rij[j], rij[j]) < a02: # found nearest neighbor self.neigh[i, nneigh[i]] = j self.neigh[j, nneigh[j]] = i nneigh[i] += 1 nneigh[j] += 1 self.idx = idx # the KMC step is variable and so it cannot be stored as proper timing dd(self).dt = depend_value(name="dt", value=0.0) self.fixatoms = np.asarray([]) self.fixcom = True self.geop = [None] * self.neval # geop should not trigger exit if there is early convergence, but just carry on. # we hard-code this option to avoid early-termination that would be hard to debug for a user geop["exit_on_convergence"] = False for i in xrange(self.neval): # geometry optimizer should not have *any* hystory dependence self.geop[i] = GeopMotion( fixcom=fixcom, fixatoms=fixatoms, **geop ) #mode="cg", ls_options={"tolerance": 1, "iter": 20, "step": 1e-3, "adaptive": 0.0}, tolerances={"energy": 1e-7, "force": 1e-2, "position": 1e-4}, ) #!TODO: set the geop parameters properly # dictionary of previous energy evaluations - kind of tricky to use this with the omaker thingie self.ecache_file = ecache_file self.qcache_file = qcache_file try: ff = open(self.ecache_file, "rb") self.ecache = pickle.load(ff) ff.close() ff = open(self.qcache_file, "rb") self.qcache = pickle.load(ff) ff.close() print "Loaded %d cached energies" % (len(self.ecache)) except: print "Couldn't load cache files " + self.ecache_file + "," + self.qcache_file + " - resetting" self.ecache = {} self.qcache = {} self.ncache = len(self.ecache) self.ncache_stored = self.ncache # no TS evaluation implemented yet self.tscache = {} self.tottime = tottime
def bind(self, read_only=False): """Calls the bind routines for all the objects in the simulation.""" if self.tsteps <= self.step: raise ValueError( "Simulation has already run for total_steps, will not even start. " "Modify total_steps or step counter to continue.") # initializes the output maker so it can be passed around to systems f_start = self.step == 0 # special operations if we're starting from scratch if f_start: mode = "w" else: mode = "a" self.output_maker = eoutputs.OutputMaker(self.outtemplate.prefix, f_start) for s in self.syslist: # binds important computation engines s.bind(self) if read_only: # returns before we open the sockets return # start forcefields here so we avoid having a shitload of files printed # out only to find the socket is busy or whatever prevented starting the threads for k, f in self.fflist.items(): f.start() # Checks for repeated filenames. filename_list = [x.filename for x in self.outtemplate] if len(filename_list) > len(set(filename_list)): raise ValueError( "Output filenames are not unique. Modify filename attributes.") self.outputs = [] for o in self.outtemplate: dco = deepcopy(o) # avoids overwriting the actual filename if self.outtemplate.prefix != "": dco.filename = self.outtemplate.prefix + "." + o.filename if (type(dco) is eoutputs.CheckpointOutput ): # checkpoints are output per simulation dco.bind(self) dpipe( dd(dco).step, dd(o).step ) # makes sure that the checkpoint step is updated also in the template self.outputs.append(dco) else: # properties and trajectories are output per system isys = 0 for s in self.syslist: # create multiple copies no = deepcopy(dco) if s.prefix != "": no.filename = s.prefix + "_" + no.filename no.bind(s, mode) self.outputs.append(no) if f_start: # starting of simulation, print headers (if any) no.print_header() isys += 1 self.chk = eoutputs.CheckpointOutput("RESTART", 1, True, 0) self.chk.bind(self) if self.smotion is not None: self.smotion.bind(self.syslist, self.prng, self.output_maker)