Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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

        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

        dset(self, "step", depend_value(name="step", value=step))
        self.tsteps = tsteps
        self.ttime = ttime
        self.paratemp = paratemp

        self.chk = None
        self.rollback = True
Exemplo n.º 4
0
    def __init__(self,
                 timestep,
                 mode="nve",
                 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.
        """

        super(Dynamics, self).__init__(fixcom=fixcom, fixatoms=fixatoms)

        dset(self, "dt", depend_value(name='dt', value=timestep))
        if thermostat is None:
            self.thermostat = Thermostat()
        else:
            self.thermostat = thermostat

        if barostat is None:
            self.barostat = Barostat()
        else:
            self.barostat = barostat

        if nmts is None:
            self.nmts = np.asarray([1], int)
        else:
            self.nmts = np.asarray(nmts)

        self.enstype = mode
        if self.enstype == "nve":
            self.integrator = NVEIntegrator()
        elif self.enstype == "nvt":
            self.integrator = NVTIntegrator()
        elif self.enstype == "npt":
            self.integrator = NPTIntegrator()
        elif self.enstype == "nst":
            self.integrator = NSTIntegrator()
        elif self.enstype == "mts":
            self.integrator = MTSIntegrator()
        else:
            self.integrator = DummyIntegrator()

        self.fixcom = fixcom
        if fixatoms is None:
            self.fixatoms = np.zeros(0, int)
        else:
            self.fixatoms = fixatoms
Exemplo n.º 5
0
    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.
        """

        dset(self, "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
Exemplo n.º 6
0
    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
Exemplo n.º 7
0
Arquivo: motion.py Projeto: i-pi/i-pi
    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
Exemplo n.º 8
0
Arquivo: multi.py Projeto: i-pi/i-pi
    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
Exemplo n.º 9
0
    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
Exemplo n.º 10
0
    def bind(self, ens, beads, nm, cell, bforce, prng):
        """Binds ensemble beads, cell, bforce, and prng to the dynamics.

        This takes a beads object, a cell object, a forcefield object and a
        random number generator object and makes them members of the ensemble.
        It also then creates the objects that will hold the data needed in the
        ensemble algorithms and the dependency network. Note that the conserved
        quantity is defined in the init, but as each ensemble has a different
        conserved quantity the dependencies are defined in bind.

        Args:
            beads: The beads object from whcih the bead positions are taken.
            nm: A normal modes object used to do the normal modes transformation.
            cell: The cell object from which the system box is taken.
            bforce: The forcefield object from which the force and virial are
                taken.
            prng: The random number generator object which controls random number
                generation.
        """

        super(Dynamics, self).bind(ens, beads, nm, cell, bforce, prng)

        # Binds integrators
        self.integrator.bind(self)

        # n times the temperature (for path integral partition function)
        dset(
            self, "ntemp",
            depend_value(name='ntemp',
                         func=self.get_ntemp,
                         dependencies=[dget(self.ensemble, "temp")]))
        self.integrator.pconstraints()

        fixdof = len(self.fixatoms) * 3 * self.beads.nbeads
        if self.fixcom:
            fixdof += 3

        # first makes sure that the thermostat has the correct temperature, then proceed with binding it.
        deppipe(self, "ntemp", self.thermostat, "temp")
        deppipe(self, "dt", self.thermostat, "dt")

        # the free ring polymer propagator is called in the inner loop, so propagation time should be redefined accordingly.
        if self.enstype == "mts":
            self.inmts = 1
            for mk in self.nmts:
                self.inmts *= mk
            dset(
                self, "deltat",
                depend_value(name="deltat",
                             func=(lambda: self.dt / self.inmts),
                             dependencies=[dget(self, "dt")]))
            deppipe(self, "deltat", self.nm, "dt")

        # depending on the kind, the thermostat might work in the normal mode or the bead representation.
        self.thermostat.bind(beads=self.beads,
                             nm=self.nm,
                             prng=prng,
                             fixdof=fixdof)

        deppipe(self, "ntemp", self.barostat, "temp")
        deppipe(self, "dt", self.barostat, "dt")
        deppipe(self.ensemble, "pext", self.barostat, "pext")
        deppipe(self.ensemble, "stressext", self.barostat, "stressext")

        self.barostat.bind(beads, nm, cell, bforce, prng=prng, fixdof=fixdof)

        self.ensemble.add_econs(dget(self.thermostat, "ethermo"))
        self.ensemble.add_econs(dget(self.barostat, "ebaro"))

        #!TODO THOROUGH CLEAN-UP AND CHECK
        #if self.enstype in ["nvt", "npt", "nst"]:
        if self.enstype == "nvt" or self.enstype == "npt" or self.enstype == "nst":
            if self.ensemble.temp < 0:
                raise ValueError(
                    "Negative or unspecified temperature for a constant-T integrator"
                )
            if self.enstype == "npt":
                if type(self.barostat) is Barostat:
                    raise ValueError(
                        "The barostat and its mode have to be specified for constant-p integrators"
                    )
                if self.ensemble.pext < 0:
                    raise ValueError(
                        "Negative or unspecified pressure for a constant-p integrator"
                    )
            elif self.enstype == "nst":
                print "STRESS:", np.trace(self.ensemble.stressext)
                if np.trace(self.ensemble.stressext) < 0:
                    raise ValueError(
                        "Negative or unspecified stress for a constant-s integrator"
                    )