Commit 85636c52 authored by Peter Eastman's avatar Peter Eastman
Browse files

Reduced unnecessary force evaluations with multiple time step integrators

parent 8ecf9e35
...@@ -186,6 +186,10 @@ public: ...@@ -186,6 +186,10 @@ public:
* @return the potential energy of the system, or 0 if includeEnergy is false * @return the potential energy of the system, or 0 if includeEnergy is false
*/ */
double calcForcesAndEnergy(bool includeForces, bool includeEnergy, int groups=0xFFFFFFFF); double calcForcesAndEnergy(bool includeForces, bool includeEnergy, int groups=0xFFFFFFFF);
/**
* Get the set of force group flags that were passed to the most recent call to calcForcesAndEnergy().
*/
int getLastForceGroups() const;
/** /**
* Calculate the kinetic energy of the system (in kJ/mol). * Calculate the kinetic energy of the system (in kJ/mol).
*/ */
...@@ -226,6 +230,7 @@ private: ...@@ -226,6 +230,7 @@ private:
std::map<std::string, double> parameters; std::map<std::string, double> parameters;
mutable std::vector<std::vector<int> > molecules; mutable std::vector<std::vector<int> > molecules;
bool hasInitializedForces; bool hasInitializedForces;
int lastForceGroups;
Platform* platform; Platform* platform;
Kernel initializeForcesKernel, kineticEnergyKernel, updateStateDataKernel, applyConstraintsKernel, virtualSitesKernel; Kernel initializeForcesKernel, kineticEnergyKernel, updateStateDataKernel, applyConstraintsKernel, virtualSitesKernel;
void* platformData; void* platformData;
......
...@@ -49,7 +49,7 @@ using std::vector; ...@@ -49,7 +49,7 @@ using std::vector;
using std::string; using std::string;
ContextImpl::ContextImpl(Context& owner, System& system, Integrator& integrator, Platform* platform, const map<string, string>& properties) : ContextImpl::ContextImpl(Context& owner, System& system, Integrator& integrator, Platform* platform, const map<string, string>& properties) :
owner(owner), system(system), integrator(integrator), hasInitializedForces(false), platform(platform), platformData(NULL) { owner(owner), system(system), integrator(integrator), hasInitializedForces(false), lastForceGroups(-1), platform(platform), platformData(NULL) {
if (system.getNumParticles() == 0) if (system.getNumParticles() == 0)
throw OpenMMException("Cannot create a Context for a System with no particles"); throw OpenMMException("Cannot create a Context for a System with no particles");
...@@ -192,6 +192,7 @@ void ContextImpl::computeVirtualSites() { ...@@ -192,6 +192,7 @@ void ContextImpl::computeVirtualSites() {
} }
double ContextImpl::calcForcesAndEnergy(bool includeForces, bool includeEnergy, int groups) { double ContextImpl::calcForcesAndEnergy(bool includeForces, bool includeEnergy, int groups) {
lastForceGroups = groups;
CalcForcesAndEnergyKernel& kernel = dynamic_cast<CalcForcesAndEnergyKernel&>(initializeForcesKernel.getImpl()); CalcForcesAndEnergyKernel& kernel = dynamic_cast<CalcForcesAndEnergyKernel&>(initializeForcesKernel.getImpl());
double energy = 0.0; double energy = 0.0;
kernel.beginComputation(*this, includeForces, includeEnergy, groups); kernel.beginComputation(*this, includeForces, includeEnergy, groups);
...@@ -201,6 +202,10 @@ double ContextImpl::calcForcesAndEnergy(bool includeForces, bool includeEnergy, ...@@ -201,6 +202,10 @@ double ContextImpl::calcForcesAndEnergy(bool includeForces, bool includeEnergy,
return energy; return energy;
} }
int ContextImpl::getLastForceGroups() const {
return lastForceGroups;
}
double ContextImpl::calcKineticEnergy() { double ContextImpl::calcKineticEnergy() {
return dynamic_cast<CalcKineticEnergyKernel&>(kineticEnergyKernel.getImpl()).execute(*this); return dynamic_cast<CalcKineticEnergyKernel&>(kineticEnergyKernel.getImpl()).execute(*this);
} }
......
...@@ -91,7 +91,6 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve ...@@ -91,7 +91,6 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
vector<RealVec>& velocities, vector<RealVec>& forces, vector<RealOpenMM>& masses, vector<RealVec>& velocities, vector<RealVec>& forces, vector<RealOpenMM>& masses,
map<string, RealOpenMM>& globals, vector<vector<RealVec> >& perDof, bool& forcesAreValid){ map<string, RealOpenMM>& globals, vector<vector<RealVec> >& perDof, bool& forcesAreValid){
int numSteps = stepType.size(); int numSteps = stepType.size();
int currentForceGroup = -1;
globals.insert(context.getParameters().begin(), context.getParameters().end()); globals.insert(context.getParameters().begin(), context.getParameters().end());
if (invalidatesForces.size() == 0) { if (invalidatesForces.size() == 0) {
// The first time this is called, work out when to recompute forces and energy. First build a // The first time this is called, work out when to recompute forces and energy. First build a
...@@ -167,7 +166,7 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve ...@@ -167,7 +166,7 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
// Loop over steps and execute them. // Loop over steps and execute them.
for (int i = 0; i < numSteps; i++) { for (int i = 0; i < numSteps; i++) {
if ((needsForces[i] || needsEnergy[i]) && (!forcesAreValid || currentForceGroup != forceGroup[i])) { if ((needsForces[i] || needsEnergy[i]) && (!forcesAreValid || context.getLastForceGroups() != forceGroup[i])) {
// Recompute forces and or energy. Figure out what is actually needed // Recompute forces and or energy. Figure out what is actually needed
// between now and the next time they get invalidated again. // between now and the next time they get invalidated again.
...@@ -189,7 +188,6 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve ...@@ -189,7 +188,6 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
if (computeEnergy) if (computeEnergy)
energy = e; energy = e;
forcesAreValid = true; forcesAreValid = true;
currentForceGroup = forceGroup[i];
} }
globals["energy"] = energy; globals["energy"] = energy;
...@@ -248,8 +246,6 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve ...@@ -248,8 +246,6 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
ReferenceVirtualSites::computePositions(context.getSystem(), atomCoordinates); ReferenceVirtualSites::computePositions(context.getSystem(), atomCoordinates);
incrementTimeStep(); incrementTimeStep();
recordChangedParameters(context, globals); recordChangedParameters(context, globals);
if (currentForceGroup != -1)
forcesAreValid = false;
} }
void ReferenceCustomDynamics::computePerDof(int numberOfAtoms, vector<RealVec>& results, const vector<RealVec>& atomCoordinates, void ReferenceCustomDynamics::computePerDof(int numberOfAtoms, vector<RealVec>& results, const vector<RealVec>& atomCoordinates,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment