Commit aefe9a9f authored by Peter Eastman's avatar Peter Eastman
Browse files

Improved test cases: use symmetric difference to approximate force instead of one sided difference

parent fb13fc68
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2012 Stanford University and the Authors. * * Portions copyright (c) 2008-2013 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -242,15 +242,19 @@ void testMembrane() { ...@@ -242,15 +242,19 @@ void testMembrane() {
norm += forces[i].dot(forces[i]); norm += forces[i].dot(forces[i]);
norm = std::sqrt(norm); norm = std::sqrt(norm);
const double stepSize = 1e-3; const double stepSize = 1e-3;
double step = stepSize/norm; double step = 0.5*stepSize/norm;
vector<Vec3> positions2(numParticles), positions3(numParticles);
for (int i = 0; i < (int) positions.size(); ++i) { for (int i = 0; i < (int) positions.size(); ++i) {
Vec3 p = positions[i]; Vec3 p = positions[i];
Vec3 f = forces[i]; Vec3 f = forces[i];
positions[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step); positions2[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step);
positions3[i] = Vec3(p[0]+f[0]*step, p[1]+f[1]*step, p[2]+f[2]*step);
} }
context.setPositions(positions); context.setPositions(positions2);
State state2 = context.getState(State::Energy); State state2 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state.getPotentialEnergy())/stepSize, 1e-2); context.setPositions(positions3);
State state3 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state3.getPotentialEnergy())/stepSize, 1e-3);
} }
void testTabulatedFunction() { void testTabulatedFunction() {
...@@ -367,15 +371,19 @@ void testPositionDependence() { ...@@ -367,15 +371,19 @@ void testPositionDependence() {
norm += forces[i].dot(forces[i]); norm += forces[i].dot(forces[i]);
norm = std::sqrt(norm); norm = std::sqrt(norm);
const double stepSize = 1e-3; const double stepSize = 1e-3;
double step = stepSize/norm; double step = 0.5*stepSize/norm;
vector<Vec3> positions2(2), positions3(2);
for (int i = 0; i < (int) positions.size(); ++i) { for (int i = 0; i < (int) positions.size(); ++i) {
Vec3 p = positions[i]; Vec3 p = positions[i];
Vec3 f = forces[i]; Vec3 f = forces[i];
positions[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step); positions2[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step);
positions3[i] = Vec3(p[0]+f[0]*step, p[1]+f[1]*step, p[2]+f[2]*step);
} }
context.setPositions(positions); context.setPositions(positions2);
State state2 = context.getState(State::Energy); State state2 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state.getPotentialEnergy())/stepSize, 1e-3*abs(state.getPotentialEnergy())); context.setPositions(positions3);
State state3 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state3.getPotentialEnergy())/stepSize, 1e-3);
} }
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2012 Stanford University and the Authors. * * Portions copyright (c) 2008-2013 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -202,24 +202,25 @@ void testForce(int numParticles, NonbondedForce::NonbondedMethod method, GBSAOBC ...@@ -202,24 +202,25 @@ void testForce(int numParticles, NonbondedForce::NonbondedMethod method, GBSAOBC
ASSERT_EQUAL_TOL(0.0, diff, 0.001*norm); ASSERT_EQUAL_TOL(0.0, diff, 0.001*norm);
ASSERT_EQUAL_TOL(state.getPotentialEnergy(), refState.getPotentialEnergy(), 1e-3); ASSERT_EQUAL_TOL(state.getPotentialEnergy(), refState.getPotentialEnergy(), 1e-3);
// Take a small step in the direction of the energy gradient. (This doesn't work with cutoffs, since the energy // Take a small step in the direction of the energy gradient and see whether the potential energy changes by the expected amount.
// changes discontinuously at the cutoff distance.) // (This doesn't work with cutoffs, since the energy changes discontinuously at the cutoff distance.)
if (method == NonbondedForce::NoCutoff) if (method == NonbondedForce::NoCutoff)
{ {
const double delta = 1e-2; const double delta = 1e-2;
double step = delta/norm; double step = 0.5*delta/norm;
vector<Vec3> positions2(numParticles), positions3(numParticles);
for (int i = 0; i < numParticles; ++i) { for (int i = 0; i < numParticles; ++i) {
Vec3 p = positions[i]; Vec3 p = positions[i];
Vec3 f = state.getForces()[i]; Vec3 f = state.getForces()[i];
positions[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step); positions2[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step);
positions3[i] = Vec3(p[0]+f[0]*step, p[1]+f[1]*step, p[2]+f[2]*step);
} }
context.setPositions(positions); context.setPositions(positions2);
// See whether the potential energy changed by the expected amount.
State state2 = context.getState(State::Energy); State state2 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state.getPotentialEnergy())/delta, 1e-3*abs(state.getPotentialEnergy())); context.setPositions(positions3);
State state3 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state3.getPotentialEnergy())/delta, 1e-3)
} }
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2012 Stanford University and the Authors. * * Portions copyright (c) 2008-2013 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -242,15 +242,19 @@ void testMembrane() { ...@@ -242,15 +242,19 @@ void testMembrane() {
norm += forces[i].dot(forces[i]); norm += forces[i].dot(forces[i]);
norm = std::sqrt(norm); norm = std::sqrt(norm);
const double stepSize = 1e-3; const double stepSize = 1e-3;
double step = stepSize/norm; double step = 0.5*stepSize/norm;
vector<Vec3> positions2(numParticles), positions3(numParticles);
for (int i = 0; i < (int) positions.size(); ++i) { for (int i = 0; i < (int) positions.size(); ++i) {
Vec3 p = positions[i]; Vec3 p = positions[i];
Vec3 f = forces[i]; Vec3 f = forces[i];
positions[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step); positions2[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step);
positions3[i] = Vec3(p[0]+f[0]*step, p[1]+f[1]*step, p[2]+f[2]*step);
} }
context.setPositions(positions); context.setPositions(positions2);
State state2 = context.getState(State::Energy); State state2 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state.getPotentialEnergy())/stepSize, 1e-2); context.setPositions(positions3);
State state3 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state3.getPotentialEnergy())/stepSize, 1e-3);
} }
void testTabulatedFunction() { void testTabulatedFunction() {
...@@ -367,15 +371,19 @@ void testPositionDependence() { ...@@ -367,15 +371,19 @@ void testPositionDependence() {
norm += forces[i].dot(forces[i]); norm += forces[i].dot(forces[i]);
norm = std::sqrt(norm); norm = std::sqrt(norm);
const double stepSize = 1e-3; const double stepSize = 1e-3;
double step = stepSize/norm; double step = 0.5*stepSize/norm;
vector<Vec3> positions2(2), positions3(2);
for (int i = 0; i < (int) positions.size(); ++i) { for (int i = 0; i < (int) positions.size(); ++i) {
Vec3 p = positions[i]; Vec3 p = positions[i];
Vec3 f = forces[i]; Vec3 f = forces[i];
positions[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step); positions2[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step);
positions3[i] = Vec3(p[0]+f[0]*step, p[1]+f[1]*step, p[2]+f[2]*step);
} }
context.setPositions(positions); context.setPositions(positions2);
State state2 = context.getState(State::Energy); State state2 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state.getPotentialEnergy())/stepSize, 1e-3*abs(state.getPotentialEnergy())); context.setPositions(positions3);
State state3 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state3.getPotentialEnergy())/stepSize, 1e-3);
} }
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2009 Stanford University and the Authors. * * Portions copyright (c) 2008-2013 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -202,24 +202,25 @@ void testForce(int numParticles, NonbondedForce::NonbondedMethod method, GBSAOBC ...@@ -202,24 +202,25 @@ void testForce(int numParticles, NonbondedForce::NonbondedMethod method, GBSAOBC
ASSERT_EQUAL_TOL(0.0, diff, 0.001*norm); ASSERT_EQUAL_TOL(0.0, diff, 0.001*norm);
ASSERT_EQUAL_TOL(state.getPotentialEnergy(), refState.getPotentialEnergy(), 1e-3); ASSERT_EQUAL_TOL(state.getPotentialEnergy(), refState.getPotentialEnergy(), 1e-3);
// Take a small step in the direction of the energy gradient. (This doesn't work with cutoffs, since the energy // Take a small step in the direction of the energy gradient and see whether the potential energy changes by the expected amount.
// changes discontinuously at the cutoff distance.) // (This doesn't work with cutoffs, since the energy changes discontinuously at the cutoff distance.)
if (method == NonbondedForce::NoCutoff) if (method == NonbondedForce::NoCutoff)
{ {
const double delta = 1e-2; const double delta = 1e-2;
double step = delta/norm; double step = 0.5*delta/norm;
vector<Vec3> positions2(numParticles), positions3(numParticles);
for (int i = 0; i < numParticles; ++i) { for (int i = 0; i < numParticles; ++i) {
Vec3 p = positions[i]; Vec3 p = positions[i];
Vec3 f = state.getForces()[i]; Vec3 f = state.getForces()[i];
positions[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step); positions2[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step);
positions3[i] = Vec3(p[0]+f[0]*step, p[1]+f[1]*step, p[2]+f[2]*step);
} }
context.setPositions(positions); context.setPositions(positions2);
// See whether the potential energy changed by the expected amount.
State state2 = context.getState(State::Energy); State state2 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state.getPotentialEnergy())/delta, 1e-3*abs(state.getPotentialEnergy())); context.setPositions(positions3);
State state3 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state3.getPotentialEnergy())/delta, 1e-3)
} }
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2012 Stanford University and the Authors. * * Portions copyright (c) 2008-2013 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -245,15 +245,19 @@ void testMembrane() { ...@@ -245,15 +245,19 @@ void testMembrane() {
norm += forces[i].dot(forces[i]); norm += forces[i].dot(forces[i]);
norm = std::sqrt(norm); norm = std::sqrt(norm);
const double stepSize = 1e-3; const double stepSize = 1e-3;
double step = stepSize/norm; double step = 0.5*stepSize/norm;
vector<Vec3> positions2(numParticles), positions3(numParticles);
for (int i = 0; i < (int) positions.size(); ++i) { for (int i = 0; i < (int) positions.size(); ++i) {
Vec3 p = positions[i]; Vec3 p = positions[i];
Vec3 f = forces[i]; Vec3 f = forces[i];
positions[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step); positions2[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step);
positions3[i] = Vec3(p[0]+f[0]*step, p[1]+f[1]*step, p[2]+f[2]*step);
} }
context.setPositions(positions); context.setPositions(positions2);
State state2 = context.getState(State::Energy); State state2 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state.getPotentialEnergy())/stepSize, 1e-2); context.setPositions(positions3);
State state3 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state3.getPotentialEnergy())/stepSize, 1e-3);
} }
void testTabulatedFunction() { void testTabulatedFunction() {
...@@ -365,15 +369,19 @@ void testPositionDependence() { ...@@ -365,15 +369,19 @@ void testPositionDependence() {
norm += forces[i].dot(forces[i]); norm += forces[i].dot(forces[i]);
norm = std::sqrt(norm); norm = std::sqrt(norm);
const double stepSize = 1e-3; const double stepSize = 1e-3;
double step = stepSize/norm; double step = 0.5*stepSize/norm;
vector<Vec3> positions2(2), positions3(2);
for (int i = 0; i < (int) positions.size(); ++i) { for (int i = 0; i < (int) positions.size(); ++i) {
Vec3 p = positions[i]; Vec3 p = positions[i];
Vec3 f = forces[i]; Vec3 f = forces[i];
positions[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step); positions2[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step);
positions3[i] = Vec3(p[0]+f[0]*step, p[1]+f[1]*step, p[2]+f[2]*step);
} }
context.setPositions(positions); context.setPositions(positions2);
State state2 = context.getState(State::Energy); State state2 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state.getPotentialEnergy())/stepSize, 1e-3*abs(state.getPotentialEnergy())); context.setPositions(positions3);
State state3 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state3.getPotentialEnergy())/stepSize, 1e-3);
} }
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2009 Stanford University and the Authors. * * Portions copyright (c) 2008-2013 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -163,7 +163,7 @@ void testForce() { ...@@ -163,7 +163,7 @@ void testForce() {
context.setPositions(positions); context.setPositions(positions);
State state = context.getState(State::Forces | State::Energy); State state = context.getState(State::Forces | State::Energy);
// Take a small step in the direction of the energy gradient. // Take a small step in the direction of the energy gradient and see whether the potential energy changes by the expected amount.
double norm = 0.0; double norm = 0.0;
for (int i = 0; i < numParticles; ++i) { for (int i = 0; i < numParticles; ++i) {
...@@ -172,18 +172,19 @@ void testForce() { ...@@ -172,18 +172,19 @@ void testForce() {
} }
norm = std::sqrt(norm); norm = std::sqrt(norm);
const double delta = 1e-3; const double delta = 1e-3;
double step = delta/norm; double step = 0.5*delta/norm;
vector<Vec3> positions2(numParticles), positions3(numParticles);
for (int i = 0; i < numParticles; ++i) { for (int i = 0; i < numParticles; ++i) {
Vec3 p = positions[i]; Vec3 p = positions[i];
Vec3 f = state.getForces()[i]; Vec3 f = state.getForces()[i];
positions[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step); positions2[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step);
positions3[i] = Vec3(p[0]+f[0]*step, p[1]+f[1]*step, p[2]+f[2]*step);
} }
context.setPositions(positions); context.setPositions(positions2);
// See whether the potential energy changed by the expected amount.
State state2 = context.getState(State::Energy); State state2 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state.getPotentialEnergy())/delta, 0.01) context.setPositions(positions3);
State state3 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state3.getPotentialEnergy())/delta, 1e-3)
} }
int main() { int main() {
......
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