Page 1 of 1

Scaling force vs scaling PE in AMDForceGroupIntegrator

Posted: Sun Nov 10, 2019 7:43 pm
by lewiso1
Hi all,

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)

Re: Scaling force vs scaling PE in AMDForceGroupIntegrator

Posted: Mon Nov 11, 2019 9:15 am
by peastman
Yes, it's the same thing. Force is the gradient of the energy, so if you scale the energy by a constant that just scales the force by the same constant.

Re: Scaling force vs scaling PE in AMDForceGroupIntegrator

Posted: Thu Nov 14, 2019 5:59 pm
by lewiso1
Thanks!


If anyone's interested in the serial gREST code Ill have a demo up on github in a week or so

Re: Scaling force vs scaling PE in AMDForceGroupIntegrator

Posted: Mon Nov 25, 2019 8:31 am
by pwintrode
We've been getting good results with simulated tempering, but we'd be very interested in trying out your serial gREST code when it's ready.

PLW