Unverified Commit 162b7c37 authored by Emilio Gallicchio's avatar Emilio Gallicchio Committed by GitHub
Browse files

Additional test case (#4408)

* Improve numerical stability for edge cases

* Undo checking of derivative factors

* Undo checking for NaNs
parent 6da98153
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "openmm/serialization/XmlSerializer.h" #include "openmm/serialization/XmlSerializer.h"
#include "sfmt/SFMT.h" #include "sfmt/SFMT.h"
#include <algorithm> #include <algorithm>
#include <random>
#include <iostream> #include <iostream>
#include <vector> #include <vector>
...@@ -240,47 +241,64 @@ void test2ParticlesSoftCore() { ...@@ -240,47 +241,64 @@ void test2ParticlesSoftCore() {
ASSERT_EQUAL_VEC(Vec3(-lmbd*df*displ[0], 0.0, 0.0), state.getForces()[1], 1e-6); ASSERT_EQUAL_VEC(Vec3(-lmbd*df*displ[0], 0.0, 0.0), state.getForces()[1], 1e-6);
} }
void test2ParticlesNonbonded() { void testNonbonded() {
System system; System system;
system.addParticle(1.0); double u0, u1, energy;
system.addParticle(1.0); double lambda = 0.5;
int numParticles = 216;
double width = 4.0;
system.setDefaultPeriodicBoxVectors(Vec3(width, 0, 0), Vec3(0, width, 0), Vec3(0, 0, width));
NonbondedForce* nbforce = new NonbondedForce(); NonbondedForce* nbforce = new NonbondedForce();
nbforce->addParticle( 1.0, 1.0, 1.0); nbforce->setNonbondedMethod(NonbondedForce::CutoffPeriodic);
nbforce->addParticle(-1.0, 1.0, 1.0); nbforce->setCutoffDistance(0.7);
ATMForce* atm = new ATMForce(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
double spacing = width/6.0;
double offset = spacing/5.0;
vector<Vec3> positions;
for (int i = 0; i < 6; i++)
for (int j = 0; j < 6; j++)
for (int k = 0; k < 6; k++) {
positions.push_back(Vec3(spacing*i+offset, spacing*j+offset, spacing*k+offset));
system.addParticle(10.0);
nbforce->addParticle(0, 0.3, 1.0);
atm->addParticle(Vec3());
}
auto rng = std::default_random_engine {};
std::shuffle(std::begin(positions), std::end(positions), rng);
atm->setParticleParameters(0, Vec3(0.5, 0, 0), Vec3(0.0, 0, 0));
//in this scenario the non-bonded force is added to the System, a copy is added to ATMForce and
//the System's copy is disabled by giving it a force group that is not evaluated.
//This should cause atom reordering in the main context
system.addForce(nbforce); system.addForce(nbforce);
ATMForce* atm = new ATMForce(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
Vec3 nodispl = Vec3(0., 0., 0.);
Vec3 displ = Vec3(1., 0., 0.);
atm->addParticle( nodispl );
atm->addParticle( displ );
atm->addForce(XmlSerializer::clone<Force>(*nbforce)); atm->addForce(XmlSerializer::clone<Force>(*nbforce));
system.removeForce(0); nbforce->setForceGroup(1);
system.addForce(atm); system.addForce(atm);
LangevinMiddleIntegrator integrator1(300, 1.0, 0.004);
vector<Vec3> positions; Context context1(system, integrator1, platform);
positions.push_back(Vec3(0., 0., 0.)); context1.setPositions(positions);
positions.push_back(Vec3(1., 0., 0.)); context1.setParameter(ATMForce::Lambda1(), lambda);
context1.setParameter(ATMForce::Lambda2(), lambda);
VerletIntegrator integrator(1.0); State state1 = context1.getState( State::Energy, false, 0 );
Context context(system, integrator, platform); double epot1 = state1.getPotentialEnergy();
context.setPositions(positions); atm->getPerturbationEnergy(context1, u1, u0, energy);
double epert1 = u1 - u0;
double lambda = 0.5;
context.setParameter(ATMForce::Lambda1(), lambda); //in this second scenario the non-bonded force is remove from the System
context.setParameter(ATMForce::Lambda2(), lambda); //and atom reordering is disabled.
State state = context.getState( State::Energy ); system.removeForce(0);
double epot = state.getPotentialEnergy(); LangevinMiddleIntegrator integrator2(300, 1.0, 0.004);
double u0, u1, energy; Context context2(system, integrator2, platform);
atm->getPerturbationEnergy(context, u1, u0, energy); context2.setPositions(positions);
double epert = u1 - u0; context2.setParameter(ATMForce::Lambda1(), lambda);
ASSERT_EQUAL_TOL(-104.2320, epot, 1e-3); context2.setParameter(ATMForce::Lambda2(), lambda);
ASSERT_EQUAL_TOL( 69.4062, epert, 1e-3); State state2 = context2.getState( State::Energy );
// std::cout << "Nonbonded: epot = " << epot << std::endl; double epot2 = state2.getPotentialEnergy();
// std::cout << "Nonbonded: epert = " << epert << std::endl; atm->getPerturbationEnergy(context2, u1, u0, energy);
double epert2 = u1 - u0;
ASSERT_EQUAL_TOL(epert1, epert2, 1e-3);
} }
...@@ -520,7 +538,7 @@ int main(int argc, char* argv[]) { ...@@ -520,7 +538,7 @@ int main(int argc, char* argv[]) {
test2Particles(); test2Particles();
test2Particles2Displacement0(); test2Particles2Displacement0();
test2ParticlesSoftCore(); test2ParticlesSoftCore();
test2ParticlesNonbonded(); testNonbonded();
testParticlesCustomExpressionLinear(); testParticlesCustomExpressionLinear();
testParticlesCustomExpressionSoftplus(); testParticlesCustomExpressionSoftplus();
testLargeSystem(); testLargeSystem();
......
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