示例#1
0
    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 fcell:
                    warning("Overwriting previous cell parameters",
                            verbosity.medium)
                if v.mode == "pdb":
                    rh = init_pdb(v.value)[1].h
                elif v.mode == "chk":
                    rh = init_chk(v.value)[1].h
                else:
                    rh = v.value.reshape((3, 3))
                rh *= unit_to_internal("length", v.units, 1.0)

                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
                else:
                    rm = init_beads(v, self.nbeads).m
                rm *= unit_to_internal("mass", v.units, 1.0)

                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)
                rq *= unit_to_internal("length", v.units, 1.0)
                (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(dt=simul.ensemble.dt, temp=simul.ensemble.temp)
                rnm.bind(rbeads, rens)
                # 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)
                rp *= unit_to_internal("momentum", v.units, 1.0)
                (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)
                rv *= unit_to_internal("velocity", v.units, 1.0)
                (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]
                elif v.bead >= 0:
                    rv *= simul.beads.m3[0]
                else:
                    rv *= simul.beads.m3
                rv *= np.sqrt(self.nbeads / nbeads)
                set_vector(v, simul.beads.p, rv)
                fmom = True
            elif k == "thermostat":
                pass  # thermostats must be initialized 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)
示例#2
0
    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)