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
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
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
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