TLDR; how is it that AMDForceGroupIntegrator scales forces rather than potential energy?
I hacked simulatedtempering.py to implement 'generalized REST' in serial. Details of gREST are here: https://aip.scitation.org/doi/10.1063/1.5016222
The short version is that instead of temperature, a subset of the potential energy term (for instance dihedral terms) is scaled by a constant factor based on relative temperatures. This can be done with force groups in OpenMM.
So I made a CustomIntegrator to scale a forcegroup, inspired by AMDForceGroupIntegrator and the LangevinIntegrator example given in the docs (see below). It seems to work.
So, the question is: the Hamelberg accelerated MD paper modifies potential energies, but the AMDForceGroupIntegrator modifies the force. Does the modification carry through and end up being the same thing?
Thanks for your time!
Lewis
A custom integrator to scale forces of a particular force group:
Code: Select all
from simtk.openmm import CustomIntegrator
class grestIntegrator(CustomIntegrator):
def __init__(self, temperature, friction, dt, group, scaleFactor):
CustomIntegrator.__init__(self, dt)
#added:
self.addGlobalVariable("scaleFactor", scaleFactor)
#normal langevin:
self.addGlobalVariable("temperature", temperature);
self.addGlobalVariable("friction", friction);
self.addGlobalVariable("vscale", 0);
self.addGlobalVariable("fscale", 0);
self.addGlobalVariable("noisescale", 0);
self.addPerDofVariable("x0", 0);
#added:
self.addPerDofVariable("fg", 0)
#normal langevin:
self.addUpdateContextState();
self.addComputeGlobal("vscale", "exp(-dt*friction)");
self.addComputeGlobal("fscale", "(1-vscale)/friction");
self.addComputeGlobal("noisescale", "sqrt(kT*(1-vscale*vscale)); kT=0.00831451*temperature");
self.addComputePerDof("x0", "x");
#added:
self.addComputePerDof("fg", "f"+str(group))
#original:
#self.addComputePerDof("v", "vscale*v + fscale*f/m + noisescale*gaussian/sqrt(m)");
#new (same as AMDForceGroupIntegrator code but with a globalvariable scaling factor)
self.addComputePerDof("v", "vscale*v + fscale*fprime/m + noisescale*gaussian/sqrt(m); fprime=fother+fg*scaleFactor; fother=f-fg");
#normal langevin
self.addComputePerDof("x", "x+dt*v");
self.addConstrainPositions();
self.addComputePerDof("v", "(x-x0)/dt");
def setScalingFactor(self, sf):
self.setGlobalVariable(0, sf)
def setTemperature(self, temp):
self.setGlobalVariable(1, temp)