Esempio n. 1
0
    def trial(self, state: interfaces.IState,
              runner: interfaces.IRunner) -> Tuple[interfaces.IState, bool]:
        """
        Perform a Metropolis trial

        Args:
            starting_state: initial state of system
            runner: runner to evaluate energies

        Returns:
            the system state after Monte Carlo trials
        """
        starting_positions = state.positions.copy()
        starting_energy = state.energy

        trial_positions = starting_positions.copy()
        random_vector = np.random.normal(loc=0.0, scale=self.move_size, size=3)
        trial_positions[self.atom_indices, :] += random_vector
        state.positions = trial_positions
        trial_energy = runner.get_energy(state)

        accepted = _metropolis(starting_energy, trial_energy, bias=0.0)
        if accepted:
            state.energy = trial_energy
            state.positions = trial_positions
        else:
            state.energy = starting_energy
            state.positions = starting_positions

        return state, accepted
Esempio n. 2
0
    def trial(self, state: interfaces.IState,
              runner: interfaces.IRunner) -> Tuple[interfaces.IState, bool]:
        """
        Perform a Metropolis trial

        Args:
            starting_state: initial state of system
            runner: runner to evaluate energies

        Returns:
            the system state after Monte Carlo trials
        """
        starting_positions = state.positions.copy()
        starting_energy = state.energy

        angle = _generate_uniform_angle()
        trial_positions = starting_positions.copy()
        trial_positions[self.atom_indices, :] = _rotate_around_vector(
            starting_positions[self.index1, :],
            starting_positions[self.index2, :],
            angle,
            starting_positions[self.atom_indices, :],
        )
        state.positions = trial_positions
        trial_energy = runner.get_energy(state)

        accepted = _metropolis(starting_energy, trial_energy, 0.0)
        if accepted:
            state.energy = trial_energy
            state.positions = trial_positions
        else:
            state.energy = starting_energy
            state.positions = starting_positions

        return state, accepted
Esempio n. 3
0
 def _run_mc(self, state: interfaces.IState) -> interfaces.IState:
     if self._options.run_mc is not None:
         logger.info("Running MCMC.")
         logger.debug(f"Starting energy {self.get_energy(state):.3f}")
         state.energy = self.get_energy(state)
         state = self._options.run_mc.update(state, self)
         logger.debug(f"Ending energy {self.get_energy(state):.3f}")
     return state
Esempio n. 4
0
    def _run(self, state: interfaces.IState, minimize: bool) -> interfaces.IState:
        # update the transformers to account for sampled parameters
        # stored in the state
        self._transformers_update(state)

        assert abs(state.alpha - self._alpha) < 1e-6

        # Run Monte Carlo position updates
        if minimize:
            state = self._run_min_mc(state)
        else:
            state = self._run_mc(state)

        # Run MonteCarlo parameter updates
        state = self._run_param_mc(state)

        coordinates = u.Quantity(state.positions, u.nanometer)
        velocities = u.Quantity(state.velocities, u.nanometer / u.picosecond)
        box_vectors = u.Quantity(state.box_vector, u.nanometer)

        # set the positions
        self._simulation.context.setPositions(coordinates)

        # if explicit solvent, then set the box vectors
        if self._options.solvation == "explicit":
            self._simulation.context.setPeriodicBoxVectors(
                [box_vectors[0].value_in_unit(u.nanometer), 0.0, 0.0],
                [0.0, box_vectors[1].value_in_unit(u.nanometer), 0.0],
                [0.0, 0.0, box_vectors[2].value_in_unit(u.nanometer)],
            )

        # run energy minimization
        if minimize:
            self._simulation.minimizeEnergy(maxIterations=self._options.minimize_steps)

        # set the velocities
        self._simulation.context.setVelocities(velocities)

        # run timesteps
        self._simulation.step(self._options.timesteps)

        # extract coords, vels, energy and strip units
        if self._options.solvation == "implicit":
            snapshot = self._simulation.context.getState(
                getPositions=True, getVelocities=True, getEnergy=True
            )
        elif self._options.solvation == "explicit":
            snapshot = self._simulation.context.getState(
                getPositions=True,
                getVelocities=True,
                getEnergy=True,
                enforcePeriodicBox=True,
            )
        coordinates = snapshot.getPositions(asNumpy=True).value_in_unit(u.nanometer)
        velocities = snapshot.getVelocities(asNumpy=True).value_in_unit(
            u.nanometer / u.picosecond
        )
        _check_for_nan(coordinates, velocities, self._rank)

        # if explicit solvent, the recover the box vectors
        if self._options.solvation == "explicit":
            box_vector = snapshot.getPeriodicBoxVectors().value_in_unit(u.nanometer)
            box_vector = np.array(
                (box_vector[0][0], box_vector[1][1], box_vector[2][2])
            )
        # just store zeros for implicit solvent
        else:
            box_vector = np.zeros(3)

        # get the energy
        e_potential = (
            snapshot.getPotentialEnergy().value_in_unit(u.kilojoule / u.mole)
            / GAS_CONSTANT
            / self._temperature
        )

        # store in state
        state.positions = coordinates
        state.velocities = velocities
        state.energy = e_potential
        state.box_vector = box_vector

        return state