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)