Beispiel #1
0
    def bind(self,
             beads=None,
             atoms=None,
             pm=None,
             nm=None,
             prng=None,
             fixdof=None):
        """Binds the appropriate degrees of freedom to the thermostat.

        This takes an object with degrees of freedom, and makes their momentum
        and mass vectors members of the thermostat. It also then creates the
        objects that will hold the data needed in the thermostat algorithms
        and the dependency network.

        Args:
           beads: An optional beads object to take the mass and momentum vectors
              from.
           atoms: An optional atoms object to take the mass and momentum vectors
              from.
           pm: An optional tuple containing a single momentum value and its
              conjugate mass.
           prng: An optional pseudo random number generator object. Defaults to
              Random().
           fixdof: An optional integer which can specify the number of constraints
              applied to the system. Defaults to zero.

        Raises:
           TypeError: Raised if no appropriate degree of freedom or object
              containing a momentum vector is specified for
              the thermostat to couple to.
        """

        super(ThermoGLE, self).bind(beads=beads,
                                    atoms=atoms,
                                    pm=pm,
                                    prng=prng,
                                    fixdof=fixdof)
        dself = dd(self)

        # allocates, initializes or restarts an array of s's
        if self.s.shape != (self.ns + 1, len(dself.m)):
            if len(self.s) > 0:
                warning(
                    "Mismatch in GLE s array size on restart, will reinitialise to free particle.",
                    verbosity.low,
                )
            self.s = np.zeros((self.ns + 1, len(dself.m)))

            # Initializes the s vector in the free-particle limit
            info(
                " GLE additional DOFs initialised to the free-particle limit.",
                verbosity.low,
            )
            SC = stab_cholesky(self.C * Constants.kb)
            self.s[:] = np.dot(SC, self.prng.gvec(self.s.shape))
        else:
            info("GLE additional DOFs initialised from input.",
                 verbosity.medium)
Beispiel #2
0
    def bind(self, beads=None, atoms=None, pm=None, nm=None, prng=None, fixdof=None):
        """Binds the appropriate degrees of freedom to the thermostat.

        This takes an object with degrees of freedom, and makes their momentum
        and mass vectors members of the thermostat. It also then creates the
        objects that will hold the data needed in the thermostat algorithms
        and the dependency network.

        Args:
           beads: An optional beads object to take the mass and momentum vectors
              from.
           atoms: An optional atoms object to take the mass and momentum vectors
              from.
           pm: An optional tuple containing a single momentum value and its
              conjugate mass.
           prng: An optional pseudo random number generator object. Defaults to
              Random().
           fixdof: An optional integer which can specify the number of constraints
              applied to the system. Defaults to zero.

        Raises:
           TypeError: Raised if no appropriate degree of freedom or object
              containing a momentum vector is specified for
              the thermostat to couple to.
        """

        super(ThermoGLE, self).bind(beads=beads, atoms=atoms, pm=pm, prng=prng, fixdof=fixdof)
        dself = dd(self)

        # allocates, initializes or restarts an array of s's
        if self.s.shape != (self.ns + 1, len(dself.m)):
            if len(self.s) > 0:
                warning("Mismatch in GLE s array size on restart, will reinitialise to free particle.", verbosity.low)
            self.s = np.zeros((self.ns + 1, len(dself.m)))

            # Initializes the s vector in the free-particle limit
            info(" GLE additional DOFs initialised to the free-particle limit.", verbosity.low)
            SC = stab_cholesky(self.C * Constants.kb)
            self.s[:] = np.dot(SC, self.prng.gvec(self.s.shape))
        else:
            info("GLE additional DOFs initialised from input.", verbosity.medium)
Beispiel #3
0
    def bind(self,
             beads=None,
             atoms=None,
             pm=None,
             nm=None,
             prng=None,
             fixdof=None):
        """Binds the appropriate degrees of freedom to the thermostat.

        This takes an object with degrees of freedom, and makes their momentum
        and mass vectors members of the thermostat. It also then creates the
        objects that will hold the data needed in the thermostat algorithms
        and the dependency network. Actually, this specific thermostat requires
        being called on a beads object.

        Args:
           nm: An optional normal modes object to take the mass and momentum
              vectors from.
           prng: An optional pseudo random number generator object. Defaults to
              Random().
           fixdof: An optional integer which can specify the number of constraints
              applied to the system. Defaults to zero.

        Raises:
           TypeError: Raised if no beads object is specified for
              the thermostat to couple to.
        """

        dself = dd(self)
        if nm is None or not type(nm) is NormalModes:
            raise TypeError(
                "ThermoNMGLE.bind expects a NormalModes argument to bind to")

        if prng is None:
            self.prng = Random()
        else:
            self.prng = prng

        if nm.nbeads != self.nb:
            raise IndexError(
                "The parameters in nm_gle options correspond to a bead number "
                + str(self.nb) +
                " which does not match the number of beads in the path" +
                str(nm.nbeads))

        # allocates, initializes or restarts an array of s's
        if self.s.shape != (self.nb, self.ns + 1, nm.natoms * 3):
            if len(self.s) > 0:
                warning(
                    "Mismatch in GLE s array size on restart, will reinitialise to free particle.",
                    verbosity.low,
                )
            self.s = np.zeros((self.nb, self.ns + 1, nm.natoms * 3))

            # Initializes the s vector in the free-particle limit
            info(
                " GLE additional DOFs initialised to the free-particle limit.",
                verbosity.low,
            )
            for b in range(self.nb):
                SC = stab_cholesky(self.C[b] * Constants.kb)
                self.s[b] = np.dot(SC, self.prng.gvec(self.s[b].shape))
        else:
            info("GLE additional DOFs initialised from input.",
                 verbosity.medium)

        prev_ethermo = self.ethermo

        # creates a set of thermostats to be applied to individual normal modes
        self._thermos = [
            ThermoGLE(temp=1, dt=1, A=self.A[b], C=self.C[b])
            for b in range(self.nb)
        ]

        # must pipe all the dependencies in such a way that values for the nm
        # thermostats are automatically updated based on the "master" thermostat
        def make_Agetter(k):
            return lambda: self.A[k]

        def make_Cgetter(k):
            return lambda: self.C[k]

        it = 0
        for t in self._thermos:
            t.s = self.s[it]  # gets the s's as a slice of self.s
            t.bind(
                pm=(nm.pnm[it, :], nm.dynm3[it, :]),
                prng=self.prng)  # bind thermostat t to the it-th normal mode

            # pipes temp and dt
            dpipe(dself.temp, dd(t).temp)
            dpipe(dself.dt, dd(t).dt)

            # here we pipe the A and C of individual NM to the "master" arrays
            dd(t).A.add_dependency(dself.A)
            dd(t).A._func = make_Agetter(it)
            dd(t).C.add_dependency(dself.C)
            dd(t).C._func = make_Cgetter(it)
            dself.ethermo.add_dependency(dd(t).ethermo)
            it += 1

        # since the ethermo will be "delegated" to the normal modes thermostats,
        # one has to split
        # any previously-stored value between the sub-thermostats
        for t in self._thermos:
            t.ethermo = prev_ethermo / self.nb

        dself.ethermo._func = self.get_ethermo
Beispiel #4
0
   def bind(self, nm=None, prng=None, fixdof=None):
      """Binds the appropriate degrees of freedom to the thermostat.

      This takes an object with degrees of freedom, and makes their momentum
      and mass vectors members of the thermostat. It also then creates the
      objects that will hold the data needed in the thermostat algorithms
      and the dependency network. Actually, this specific thermostat requires
      being called on a beads object.

      Args:
         nm: An optional normal modes object to take the mass and momentum
            vectors from.
         prng: An optional pseudo random number generator object. Defaults to
            Random().
         fixdof: An optional integer which can specify the number of constraints
            applied to the system. Defaults to zero.

      Raises:
         TypeError: Raised if no beads object is specified for
            the thermostat to couple to.
      """

      if nm is None or not type(nm) is NormalModes:
         raise TypeError("ThermoNMGLE.bind expects a NormalModes argument to bind to")

      if prng is None:
         self.prng = Random()
      else:
         self.prng = prng

      if (nm.nbeads != self.nb):
         raise IndexError("The parameters in nm_gle options correspond to a bead number "+str(self.nb)+ " which does not match the number of beads in the path" + str(nm.nbeads) )

      # allocates, initializes or restarts an array of s's
      if self.s.shape != (self.nb, self.ns + 1, nm.natoms *3) :
         if len(self.s) > 0:
            warning("Mismatch in GLE s array size on restart, will reinitialise to free particle.", verbosity.low)
         self.s = np.zeros((self.nb, self.ns + 1, nm.natoms*3))

         # Initializes the s vector in the free-particle limit
         info(" GLE additional DOFs initialised to the free-particle limit.", verbosity.low)
         for b in range(self.nb):
            SC = stab_cholesky(self.C[b]*Constants.kb)
            self.s[b] = np.dot(SC, self.prng.gvec(self.s[b].shape))
      else:
         info("GLE additional DOFs initialised from input.", verbosity.medium)

      prev_ethermo = self.ethermo

      # creates a set of thermostats to be applied to individual normal modes
      self._thermos = [ThermoGLE(temp=1, dt=1, A=self.A[b], C=self.C[b]) for b in range(self.nb)]

      # must pipe all the dependencies in such a way that values for the nm
      # thermostats are automatically updated based on the "master" thermostat
      def make_Agetter(k):
         return lambda: self.A[k]
      def make_Cgetter(k):
         return lambda: self.C[k]

      it = 0
      for t in self._thermos:
         t.s = self.s[it]  # gets the s's as a slice of self.s
         t.bind(pm=(nm.pnm[it,:],nm.dynm3[it,:]), prng=self.prng) # bind thermostat t to the it-th normal mode

         # pipes temp and dt
         deppipe(self,"temp", t, "temp")
         deppipe(self,"dt", t, "dt")

         # here we pipe the A and C of individual NM to the "master" arrays
         dget(t,"A").add_dependency(dget(self,"A"))
         dget(t,"A")._func = make_Agetter(it)
         dget(t,"C").add_dependency(dget(self,"C"))
         dget(t,"C")._func = make_Cgetter(it)
         dget(self,"ethermo").add_dependency(dget(t,"ethermo"))
         it += 1

      # since the ethermo will be "delegated" to the normal modes thermostats,
      # one has to split
      # any previously-stored value between the sub-thermostats
      for t in self._thermos:
         t.ethermo = prev_ethermo/self.nb

      dget(self,"ethermo")._func = self.get_ethermo;