OpenMM

Here I collect some tricks I found on the web and some that I've come up with to use advanced features of OpenMM.

Using the group-wide openmm installation

Currently, we have two parallel versions of OpenMM available the OpenMM-5.1 release and a regularly updated build from the github repository. Both installations are in our local software installation directories:

  • /group/ag_cmb/software on the local machines, cuda01, and allegro
  • /import/ag_cmb/software on cuda02, cuda03, and allegro

To use one of these versions, please load the corresponding module:

module load compiler/4.6.3 openmm/5.1

or

module load compiler/4.6.3 openmm/git

Please not that the compiler/4.6.3 module is mandatory since CUDA requires a gcc compiler version <= 4.6.x!

Parallel MD on many graphics cards

Since OpenMM version 5.0, you can create multiple simulations in one Python script where each simulation runs on a different GPU. When you combine this with Python's multi-threading capability, you can very easily implement parallel algorithms like TREMD or HREMD.

The general idea is to tie one simulation object to one GPU and wrap calls to simulation.step in separate threads.

Switching off the Barostat after box equilibration

state = simulation.context.getState(getPositions=True, getVelocities=True)
n_forces = len(system.getForces()) # assume that the Barostat was last force that I added
system.removeForce(n_forces-1)
simulation.context.reinitialize()
simulation.context.setState(state)

Using the xtc writer from MDAnalysis

OpenMM comes without an xtc writer. Here I show you the writer of MDAnalysis can be persuaded to work with OpenMM.

At first you need to import MDAnalysis. Conversion from OpenMM to MDAnalysis will involve stripping of OpenMM's units. So we import this package too.

import MDAnalysis
from simtk.unit import *

Next you have to subclass the Timestep class of MDAnalysis. This class will act as a hinge between MDAnalysis and OpenMM. Each instance of Timestep must provide the properties numatoms, frame, _unitcell and _pos. For every frame that we want to save, a new instance of Timestep will be generated (see below) so we can just pass in all the data via init.

class MyTimestep(MDAnalysis.coordinates.base.Timestep):
  def __init__(self,numatoms,frame_number,positions,boxvectors):
    self.numatoms = numatoms
    self.frame = frame_number
    boxvectors /= angstroms
    self._unitcell = (boxvectors[0,0],90.0,boxvectors[1,1],90.0,90.0,boxvectors[2,2])
    positions /= angstroms
    self._pos = positions.astype(numpy.float32)

The actual writing is done by the MDAnalysis.Writer class. Before we can write any frames, we need to make an instance of it. The only parameter is the output file name.
writer = MDAnalysis.Writer('trajectory.xtc')

When you have set your OpenMM simulation, you can read the current frame with the getState method. Then it is easy to write this frame to the xtc file. Just extract all the data from OpenMM's state object, make an instance of MyTimestep thats holds the data and instruct the writer class to write this frame to disk.
state = simulation.context.getState(getPositions=True,enforcePeriodicBox=True)
x = state.getPositions(asNumpy=True)
box = state.getPeriodicBoxVectors(asNumpy=True)
natoms = x.shape[0]
step = MyTimestep(natoms,simulation.currentStep,x,box)
writer.write(step)

Comments

 
Topic revision: r3 - 24 Jun 2016, FabianPaul
 
  • Printable version of this topic (p) Printable version of this topic (p)