Commit 047934e2 authored by Rafal P. Wiewiora's avatar Rafal P. Wiewiora
Browse files

Merge remote-tracking branch 'upstream/master'

parents ce3a5dc0 d12c9bd1
...@@ -37,19 +37,19 @@ ...@@ -37,19 +37,19 @@
using namespace OpenMM; using namespace OpenMM;
using namespace std; using namespace std;
static vector<RealVec>& extractPositions(ContextImpl& context) { static vector<Vec3>& extractPositions(ContextImpl& context) {
ReferencePlatform::PlatformData* data = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData()); ReferencePlatform::PlatformData* data = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData());
return *((vector<RealVec>*) data->positions); return *((vector<Vec3>*) data->positions);
} }
static vector<RealVec>& extractVelocities(ContextImpl& context) { static vector<Vec3>& extractVelocities(ContextImpl& context) {
ReferencePlatform::PlatformData* data = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData()); ReferencePlatform::PlatformData* data = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData());
return *((vector<RealVec>*) data->velocities); return *((vector<Vec3>*) data->velocities);
} }
static vector<RealVec>& extractForces(ContextImpl& context) { static vector<Vec3>& extractForces(ContextImpl& context) {
ReferencePlatform::PlatformData* data = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData()); ReferencePlatform::PlatformData* data = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData());
return *((vector<RealVec>*) data->forces); return *((vector<Vec3>*) data->forces);
} }
ReferenceIntegrateRPMDStepKernel::~ReferenceIntegrateRPMDStepKernel() { ReferenceIntegrateRPMDStepKernel::~ReferenceIntegrateRPMDStepKernel() {
...@@ -113,12 +113,12 @@ void ReferenceIntegrateRPMDStepKernel::initialize(const System& system, const RP ...@@ -113,12 +113,12 @@ void ReferenceIntegrateRPMDStepKernel::initialize(const System& system, const RP
void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDIntegrator& integrator, bool forcesAreValid) { void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDIntegrator& integrator, bool forcesAreValid) {
const int numCopies = positions.size(); const int numCopies = positions.size();
const int numParticles = positions[0].size(); const int numParticles = positions[0].size();
const RealOpenMM dt = integrator.getStepSize(); const double dt = integrator.getStepSize();
const RealOpenMM halfdt = 0.5*dt; const double halfdt = 0.5*dt;
const System& system = context.getSystem(); const System& system = context.getSystem();
vector<RealVec>& pos = extractPositions(context); vector<Vec3>& pos = extractPositions(context);
vector<RealVec>& vel = extractVelocities(context); vector<Vec3>& vel = extractVelocities(context);
vector<RealVec>& f = extractForces(context); vector<Vec3>& f = extractForces(context);
// Loop over copies and compute the force on each one. // Loop over copies and compute the force on each one.
...@@ -129,17 +129,17 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI ...@@ -129,17 +129,17 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI
vector<t_complex> v(numCopies); vector<t_complex> v(numCopies);
vector<t_complex> q(numCopies); vector<t_complex> q(numCopies);
const RealOpenMM hbar = 1.054571628e-34*AVOGADRO/(1000*1e-12); const double hbar = 1.054571628e-34*AVOGADRO/(1000*1e-12);
const RealOpenMM scale = 1.0/sqrt((RealOpenMM) numCopies); const double scale = 1.0/sqrt((double) numCopies);
const RealOpenMM nkT = numCopies*BOLTZ*integrator.getTemperature(); const double nkT = numCopies*BOLTZ*integrator.getTemperature();
const RealOpenMM twown = 2.0*nkT/hbar; const double twown = 2.0*nkT/hbar;
const RealOpenMM c1_0 = exp(-halfdt*integrator.getFriction()); const double c1_0 = exp(-halfdt*integrator.getFriction());
const RealOpenMM c2_0 = sqrt(1.0-c1_0*c1_0); const double c2_0 = sqrt(1.0-c1_0*c1_0);
if (integrator.getApplyThermostat()) { if (integrator.getApplyThermostat()) {
for (int particle = 0; particle < numParticles; particle++) { for (int particle = 0; particle < numParticles; particle++) {
if (system.getParticleMass(particle) == 0.0) if (system.getParticleMass(particle) == 0.0)
continue; continue;
const RealOpenMM c3_0 = c2_0*sqrt(nkT/system.getParticleMass(particle)); const double c3_0 = c2_0*sqrt(nkT/system.getParticleMass(particle));
for (int component = 0; component < 3; component++) { for (int component = 0; component < 3; component++) {
for (int k = 0; k < numCopies; k++) for (int k = 0; k < numCopies; k++)
v[k] = t_complex(scale*velocities[k][particle][component], 0.0); v[k] = t_complex(scale*velocities[k][particle][component], 0.0);
...@@ -153,12 +153,12 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI ...@@ -153,12 +153,12 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI
for (int k = 1; k <= numCopies/2; k++) { for (int k = 1; k <= numCopies/2; k++) {
const bool isCenter = (numCopies%2 == 0 && k == numCopies/2); const bool isCenter = (numCopies%2 == 0 && k == numCopies/2);
const RealOpenMM wk = twown*sin(k*M_PI/numCopies); const double wk = twown*sin(k*M_PI/numCopies);
const RealOpenMM c1 = exp(-2.0*wk*halfdt); const double c1 = exp(-2.0*wk*halfdt);
const RealOpenMM c2 = sqrt((1.0-c1*c1)/2) * (isCenter ? sqrt(2.0) : 1.0); const double c2 = sqrt((1.0-c1*c1)/2) * (isCenter ? sqrt(2.0) : 1.0);
const RealOpenMM c3 = c2*sqrt(nkT/system.getParticleMass(particle)); const double c3 = c2*sqrt(nkT/system.getParticleMass(particle));
RealOpenMM rand1 = c3*SimTKOpenMMUtilities::getNormallyDistributedRandomNumber(); double rand1 = c3*SimTKOpenMMUtilities::getNormallyDistributedRandomNumber();
RealOpenMM rand2 = (isCenter ? 0.0 : c3*SimTKOpenMMUtilities::getNormallyDistributedRandomNumber()); double rand2 = (isCenter ? 0.0 : c3*SimTKOpenMMUtilities::getNormallyDistributedRandomNumber());
v[k] = v[k]*c1 + t_complex(rand1, rand2); v[k] = v[k]*c1 + t_complex(rand1, rand2);
if (k < numCopies-k) if (k < numCopies-k)
v[numCopies-k] = v[numCopies-k]*c1 + t_complex(rand1, -rand2); v[numCopies-k] = v[numCopies-k]*c1 + t_complex(rand1, -rand2);
...@@ -191,11 +191,11 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI ...@@ -191,11 +191,11 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI
fftpack_exec_1d(fft, FFTPACK_FORWARD, &v[0], &v[0]); fftpack_exec_1d(fft, FFTPACK_FORWARD, &v[0], &v[0]);
q[0] += v[0]*dt; q[0] += v[0]*dt;
for (int k = 1; k < numCopies; k++) { for (int k = 1; k < numCopies; k++) {
const RealOpenMM wk = twown*sin(k*M_PI/numCopies); const double wk = twown*sin(k*M_PI/numCopies);
const RealOpenMM wt = wk*dt; const double wt = wk*dt;
const RealOpenMM coswt = cos(wt); const double coswt = cos(wt);
const RealOpenMM sinwt = sin(wt); const double sinwt = sin(wt);
const RealOpenMM wm = wk*system.getParticleMass(particle); const double wm = wk*system.getParticleMass(particle);
const t_complex vprime = v[k]*coswt - q[k]*(wk*sinwt); // Advance velocity from t to t+dt const t_complex vprime = v[k]*coswt - q[k]*(wk*sinwt); // Advance velocity from t to t+dt
q[k] = v[k]*(sinwt/wk) + q[k]*coswt; // Advance position from t to t+dt q[k] = v[k]*(sinwt/wk) + q[k]*coswt; // Advance position from t to t+dt
v[k] = vprime; v[k] = vprime;
...@@ -226,7 +226,7 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI ...@@ -226,7 +226,7 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI
for (int particle = 0; particle < numParticles; particle++) { for (int particle = 0; particle < numParticles; particle++) {
if (system.getParticleMass(particle) == 0.0) if (system.getParticleMass(particle) == 0.0)
continue; continue;
const RealOpenMM c3_0 = c2_0*sqrt(nkT/system.getParticleMass(particle)); const double c3_0 = c2_0*sqrt(nkT/system.getParticleMass(particle));
for (int component = 0; component < 3; component++) { for (int component = 0; component < 3; component++) {
for (int k = 0; k < numCopies; k++) for (int k = 0; k < numCopies; k++)
v[k] = t_complex(scale*velocities[k][particle][component], 0.0); v[k] = t_complex(scale*velocities[k][particle][component], 0.0);
...@@ -240,12 +240,12 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI ...@@ -240,12 +240,12 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI
for (int k = 1; k <= numCopies/2; k++) { for (int k = 1; k <= numCopies/2; k++) {
const bool isCenter = (numCopies%2 == 0 && k == numCopies/2); const bool isCenter = (numCopies%2 == 0 && k == numCopies/2);
const RealOpenMM wk = twown*sin(k*M_PI/numCopies); const double wk = twown*sin(k*M_PI/numCopies);
const RealOpenMM c1 = exp(-2.0*wk*halfdt); const double c1 = exp(-2.0*wk*halfdt);
const RealOpenMM c2 = sqrt((1.0-c1*c1)/2) * (isCenter ? sqrt(2.0) : 1.0); const double c2 = sqrt((1.0-c1*c1)/2) * (isCenter ? sqrt(2.0) : 1.0);
const RealOpenMM c3 = c2*sqrt(nkT/system.getParticleMass(particle)); const double c3 = c2*sqrt(nkT/system.getParticleMass(particle));
RealOpenMM rand1 = c3*SimTKOpenMMUtilities::getNormallyDistributedRandomNumber(); double rand1 = c3*SimTKOpenMMUtilities::getNormallyDistributedRandomNumber();
RealOpenMM rand2 = (isCenter ? 0.0 : c3*SimTKOpenMMUtilities::getNormallyDistributedRandomNumber()); double rand2 = (isCenter ? 0.0 : c3*SimTKOpenMMUtilities::getNormallyDistributedRandomNumber());
v[k] = v[k]*c1 + t_complex(rand1, rand2); v[k] = v[k]*c1 + t_complex(rand1, rand2);
if (k < numCopies-k) if (k < numCopies-k)
v[numCopies-k] = v[numCopies-k]*c1 + t_complex(rand1, -rand2); v[numCopies-k] = v[numCopies-k]*c1 + t_complex(rand1, -rand2);
...@@ -265,9 +265,9 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI ...@@ -265,9 +265,9 @@ void ReferenceIntegrateRPMDStepKernel::execute(ContextImpl& context, const RPMDI
void ReferenceIntegrateRPMDStepKernel::computeForces(ContextImpl& context, const RPMDIntegrator& integrator) { void ReferenceIntegrateRPMDStepKernel::computeForces(ContextImpl& context, const RPMDIntegrator& integrator) {
const int totalCopies = positions.size(); const int totalCopies = positions.size();
const int numParticles = positions[0].size(); const int numParticles = positions[0].size();
vector<RealVec>& pos = extractPositions(context); vector<Vec3>& pos = extractPositions(context);
vector<RealVec>& vel = extractVelocities(context); vector<Vec3>& vel = extractVelocities(context);
vector<RealVec>& f = extractForces(context); vector<Vec3>& f = extractForces(context);
// Compute forces from all groups that didn't have a specified contraction. // Compute forces from all groups that didn't have a specified contraction.
...@@ -298,7 +298,7 @@ void ReferenceIntegrateRPMDStepKernel::computeForces(ContextImpl& context, const ...@@ -298,7 +298,7 @@ void ReferenceIntegrateRPMDStepKernel::computeForces(ContextImpl& context, const
// Find the contracted positions. // Find the contracted positions.
vector<t_complex> q(totalCopies); vector<t_complex> q(totalCopies);
const RealOpenMM scale1 = 1.0/totalCopies; const double scale1 = 1.0/totalCopies;
for (int particle = 0; particle < numParticles; particle++) { for (int particle = 0; particle < numParticles; particle++) {
for (int component = 0; component < 3; component++) { for (int component = 0; component < 3; component++) {
// Transform to the frequency domain, set high frequency components to zero, and transform back. // Transform to the frequency domain, set high frequency components to zero, and transform back.
...@@ -329,7 +329,7 @@ void ReferenceIntegrateRPMDStepKernel::computeForces(ContextImpl& context, const ...@@ -329,7 +329,7 @@ void ReferenceIntegrateRPMDStepKernel::computeForces(ContextImpl& context, const
// Apply the forces to the original copies. // Apply the forces to the original copies.
const RealOpenMM scale2 = 1.0/copies; const double scale2 = 1.0/copies;
for (int particle = 0; particle < numParticles; particle++) { for (int particle = 0; particle < numParticles; particle++) {
for (int component = 0; component < 3; component++) { for (int component = 0; component < 3; component++) {
// Transform to the frequency domain, pad with zeros, and transform back. // Transform to the frequency domain, pad with zeros, and transform back.
...@@ -355,12 +355,12 @@ void ReferenceIntegrateRPMDStepKernel::computeForces(ContextImpl& context, const ...@@ -355,12 +355,12 @@ void ReferenceIntegrateRPMDStepKernel::computeForces(ContextImpl& context, const
double ReferenceIntegrateRPMDStepKernel::computeKineticEnergy(ContextImpl& context, const RPMDIntegrator& integrator) { double ReferenceIntegrateRPMDStepKernel::computeKineticEnergy(ContextImpl& context, const RPMDIntegrator& integrator) {
const System& system = context.getSystem(); const System& system = context.getSystem();
int numParticles = system.getNumParticles(); int numParticles = system.getNumParticles();
vector<RealVec>& velData = extractVelocities(context); vector<Vec3>& velData = extractVelocities(context);
double energy = 0.0; double energy = 0.0;
for (int i = 0; i < numParticles; ++i) { for (int i = 0; i < numParticles; ++i) {
double mass = system.getParticleMass(i); double mass = system.getParticleMass(i);
if (mass > 0) { if (mass > 0) {
RealVec v = velData[i]; Vec3 v = velData[i];
energy += mass*(v.dot(v)); energy += mass*(v.dot(v));
} }
} }
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include "ReferencePlatform.h" #include "ReferencePlatform.h"
#include "openmm/RpmdKernels.h" #include "openmm/RpmdKernels.h"
#include "RealVec.h" #include "openmm/Vec3.h"
#include "fftpack.h" #include "fftpack.h"
namespace OpenMM { namespace OpenMM {
...@@ -86,11 +86,11 @@ public: ...@@ -86,11 +86,11 @@ public:
void copyToContext(int copy, ContextImpl& context); void copyToContext(int copy, ContextImpl& context);
private: private:
void computeForces(ContextImpl& context, const RPMDIntegrator& integrator); void computeForces(ContextImpl& context, const RPMDIntegrator& integrator);
std::vector<std::vector<RealVec> > positions; std::vector<std::vector<Vec3> > positions;
std::vector<std::vector<RealVec> > velocities; std::vector<std::vector<Vec3> > velocities;
std::vector<std::vector<RealVec> > forces; std::vector<std::vector<Vec3> > forces;
std::vector<std::vector<RealVec> > contractedPositions; std::vector<std::vector<Vec3> > contractedPositions;
std::vector<std::vector<RealVec> > contractedForces; std::vector<std::vector<Vec3> > contractedForces;
std::map<int, int> groupsByCopies; std::map<int, int> groupsByCopies;
int groupsNotContracted; int groupsNotContracted;
fftpack* fft; fftpack* fft;
......
...@@ -77,7 +77,7 @@ void testFreeParticles() { ...@@ -77,7 +77,7 @@ void testFreeParticles() {
integ.step(1000); integ.step(1000);
vector<double> ke(numCopies, 0.0); vector<double> ke(numCopies, 0.0);
vector<double> rg(numParticles, 0.0); vector<double> rg(numParticles, 0.0);
const RealOpenMM hbar = 1.054571628e-34*AVOGADRO/(1000*1e-12); const double hbar = 1.054571628e-34*AVOGADRO/(1000*1e-12);
for (int i = 0; i < numSteps; i++) { for (int i = 0; i < numSteps; i++) {
integ.step(1); integ.step(1);
vector<State> state(numCopies); vector<State> state(numCopies);
......
...@@ -107,6 +107,12 @@ void* CustomIntegratorProxy::deserialize(const SerializationNode& node) const { ...@@ -107,6 +107,12 @@ void* CustomIntegratorProxy::deserialize(const SerializationNode& node) const {
integrator->addConstrainVelocities(); integrator->addConstrainVelocities();
} else if(computationType == CustomIntegrator::UpdateContextState) { } else if(computationType == CustomIntegrator::UpdateContextState) {
integrator->addUpdateContextState(); integrator->addUpdateContextState();
} else if(computationType == CustomIntegrator::IfBlockStart) {
integrator->beginIfBlock(cit->getStringProperty("computationExpression"));
} else if(computationType == CustomIntegrator::WhileBlockStart) {
integrator->beginWhileBlock(cit->getStringProperty("computationExpression"));
} else if(computationType == CustomIntegrator::BlockEnd) {
integrator->endBlock();
} else { } else {
throw(OpenMMException("Custom Integrator Deserialization: Unknown computation type")); throw(OpenMMException("Custom Integrator Deserialization: Unknown computation type"));
} }
...@@ -115,4 +121,4 @@ void* CustomIntegratorProxy::deserialize(const SerializationNode& node) const { ...@@ -115,4 +121,4 @@ void* CustomIntegratorProxy::deserialize(const SerializationNode& node) const {
integrator->setRandomNumberSeed(node.getIntProperty("randomSeed")); integrator->setRandomNumberSeed(node.getIntProperty("randomSeed"));
integrator->setConstraintTolerance(node.getDoubleProperty("constraintTolerance")); integrator->setConstraintTolerance(node.getDoubleProperty("constraintTolerance"));
return integrator; return integrator;
} }
\ No newline at end of file
...@@ -42,7 +42,7 @@ NonbondedForceProxy::NonbondedForceProxy() : SerializationProxy("NonbondedForce" ...@@ -42,7 +42,7 @@ NonbondedForceProxy::NonbondedForceProxy() : SerializationProxy("NonbondedForce"
} }
void NonbondedForceProxy::serialize(const void* object, SerializationNode& node) const { void NonbondedForceProxy::serialize(const void* object, SerializationNode& node) const {
node.setIntProperty("version", 1); node.setIntProperty("version", 2);
const NonbondedForce& force = *reinterpret_cast<const NonbondedForce*>(object); const NonbondedForce& force = *reinterpret_cast<const NonbondedForce*>(object);
node.setIntProperty("forceGroup", force.getForceGroup()); node.setIntProperty("forceGroup", force.getForceGroup());
node.setIntProperty("method", (int) force.getNonbondedMethod()); node.setIntProperty("method", (int) force.getNonbondedMethod());
...@@ -59,6 +59,11 @@ void NonbondedForceProxy::serialize(const void* object, SerializationNode& node) ...@@ -59,6 +59,11 @@ void NonbondedForceProxy::serialize(const void* object, SerializationNode& node)
node.setIntProperty("nx", nx); node.setIntProperty("nx", nx);
node.setIntProperty("ny", ny); node.setIntProperty("ny", ny);
node.setIntProperty("nz", nz); node.setIntProperty("nz", nz);
force.getLJPMEParameters(alpha, nx, ny, nz);
node.setDoubleProperty("ljAlpha", alpha);
node.setIntProperty("ljnx", nx);
node.setIntProperty("ljny", ny);
node.setIntProperty("ljnz", nz);
node.setIntProperty("recipForceGroup", force.getReciprocalSpaceForceGroup()); node.setIntProperty("recipForceGroup", force.getReciprocalSpaceForceGroup());
SerializationNode& particles = node.createChildNode("Particles"); SerializationNode& particles = node.createChildNode("Particles");
for (int i = 0; i < force.getNumParticles(); i++) { for (int i = 0; i < force.getNumParticles(); i++) {
...@@ -76,7 +81,8 @@ void NonbondedForceProxy::serialize(const void* object, SerializationNode& node) ...@@ -76,7 +81,8 @@ void NonbondedForceProxy::serialize(const void* object, SerializationNode& node)
} }
void* NonbondedForceProxy::deserialize(const SerializationNode& node) const { void* NonbondedForceProxy::deserialize(const SerializationNode& node) const {
if (node.getIntProperty("version") != 1) int version = node.getIntProperty("version");
if (version < 1 || version > 2)
throw OpenMMException("Unsupported version number"); throw OpenMMException("Unsupported version number");
NonbondedForce* force = new NonbondedForce(); NonbondedForce* force = new NonbondedForce();
try { try {
...@@ -93,6 +99,13 @@ void* NonbondedForceProxy::deserialize(const SerializationNode& node) const { ...@@ -93,6 +99,13 @@ void* NonbondedForceProxy::deserialize(const SerializationNode& node) const {
int ny = node.getIntProperty("ny", 0); int ny = node.getIntProperty("ny", 0);
int nz = node.getIntProperty("nz", 0); int nz = node.getIntProperty("nz", 0);
force->setPMEParameters(alpha, nx, ny, nz); force->setPMEParameters(alpha, nx, ny, nz);
if (version >= 2) {
alpha = node.getDoubleProperty("ljAlpha", 0.0);
nx = node.getIntProperty("ljnx", 0);
ny = node.getIntProperty("ljny", 0);
nz = node.getIntProperty("ljnz", 0);
force->setLJPMEParameters(alpha, nx, ny, nz);
}
force->setReciprocalSpaceForceGroup(node.getIntProperty("recipForceGroup", -1)); force->setReciprocalSpaceForceGroup(node.getIntProperty("recipForceGroup", -1));
const SerializationNode& particles = node.getChildNode("Particles"); const SerializationNode& particles = node.getChildNode("Particles");
for (int i = 0; i < (int) particles.getChildren().size(); i++) { for (int i = 0; i < (int) particles.getChildren().size(); i++) {
......
...@@ -137,12 +137,20 @@ void testSerializeCustomIntegrator() { ...@@ -137,12 +137,20 @@ void testSerializeCustomIntegrator() {
intg->addGlobalVariable("oute", 0); intg->addGlobalVariable("oute", 0);
intg->addGlobalVariable("oute1", 0); intg->addGlobalVariable("oute1", 0);
intg->addGlobalVariable("oute2", 0); intg->addGlobalVariable("oute2", 0);
intg->addGlobalVariable("oute3_conditional_v1", 0);// HACK: need addGlobals to be alphabetical to work around bug
intg->addGlobalVariable("oute3_conditional_v2", 0);
intg->addComputePerDof("outf", "f"); intg->addComputePerDof("outf", "f");
intg->addComputePerDof("outf1", "f1"); intg->addComputePerDof("outf1", "f1");
intg->addComputePerDof("outf2", "f2"); intg->addComputePerDof("outf2", "f2");
intg->addComputeGlobal("oute", "energy"); intg->addComputeGlobal("oute", "energy");
intg->addComputeGlobal("oute1", "energy1"); intg->addComputeGlobal("oute1", "energy1");
intg->addComputeGlobal("oute2", "energy2"); intg->addComputeGlobal("oute2", "energy2");
intg->beginIfBlock("1 > 0");
intg->addComputeGlobal("oute3_conditional_v1", "energy");
intg->endBlock();
intg->beginWhileBlock("0 > 1");
intg->addComputeGlobal("oute3_conditional_v2", "energy");
intg->endBlock();
intg->addUpdateContextState(); intg->addUpdateContextState();
intg->addConstrainVelocities(); intg->addConstrainVelocities();
intg->addComputeSum("summand2", "v*v+f*f"); intg->addComputeSum("summand2", "v*v+f*f");
...@@ -216,13 +224,13 @@ int main() { ...@@ -216,13 +224,13 @@ int main() {
testSerializeVerletIntegrator(); testSerializeVerletIntegrator();
testSerializeVariableLangevinIntegrator(); testSerializeVariableLangevinIntegrator();
testSerializeVariableVerletIntegrator(); testSerializeVariableVerletIntegrator();
testSerializeLangevinIntegrator(); testSerializeLangevinIntegrator();
testSerializeCompoundIntegrator(); testSerializeCompoundIntegrator();
} }
catch(const exception& e) { catch(const exception& e) {
return 1; cout << "exception: " << e.what() << endl;
return 1;
} }
cout << "Done" << endl;
return 0; return 0;
} }
...@@ -53,6 +53,9 @@ void testSerialization() { ...@@ -53,6 +53,9 @@ void testSerialization() {
double alpha = 0.5; double alpha = 0.5;
int nx = 3, ny = 5, nz = 7; int nx = 3, ny = 5, nz = 7;
force.setPMEParameters(alpha, nx, ny, nz); force.setPMEParameters(alpha, nx, ny, nz);
double dalpha = 0.8;
int dnx = 4, dny = 6, dnz = 7;
force.setLJPMEParameters(dalpha, dnx, dny, dnz);
force.addParticle(1, 0.1, 0.01); force.addParticle(1, 0.1, 0.01);
force.addParticle(0.5, 0.2, 0.02); force.addParticle(0.5, 0.2, 0.02);
force.addParticle(-0.5, 0.3, 0.03); force.addParticle(-0.5, 0.3, 0.03);
...@@ -84,6 +87,13 @@ void testSerialization() { ...@@ -84,6 +87,13 @@ void testSerialization() {
ASSERT_EQUAL(nx, nx2); ASSERT_EQUAL(nx, nx2);
ASSERT_EQUAL(ny, ny2); ASSERT_EQUAL(ny, ny2);
ASSERT_EQUAL(nz, nz2); ASSERT_EQUAL(nz, nz2);
double dalpha2;
int dnx2, dny2, dnz2;
force2.getLJPMEParameters(dalpha2, dnx2, dny2, dnz2);
ASSERT_EQUAL(dalpha, dalpha2);
ASSERT_EQUAL(dnx, dnx2);
ASSERT_EQUAL(dny, dny2);
ASSERT_EQUAL(dnz, dnz2);
for (int i = 0; i < force.getNumParticles(); i++) { for (int i = 0; i < force.getNumParticles(); i++) {
double charge1, sigma1, epsilon1; double charge1, sigma1, epsilon1;
double charge2, sigma2, epsilon2; double charge2, sigma2, epsilon2;
......
...@@ -858,6 +858,43 @@ void testEnergyParameterDerivatives() { ...@@ -858,6 +858,43 @@ void testEnergyParameterDerivatives() {
ASSERT_EQUAL_TOL(dEdtheta0, values[2][1], 1e-5); ASSERT_EQUAL_TOL(dEdtheta0, values[2][1], 1e-5);
} }
/**
* Test an integrator that modifies the step size.
*/
void testChangeDT() {
System system;
system.addParticle(1.0);
CustomIntegrator integrator(0.5);
integrator.addGlobalVariable("dt_global", 0.0);
integrator.addPerDofVariable("dt_dof", 0.0);
integrator.addComputeGlobal("dt", "dt+1");
integrator.addComputePerDof("dt_dof", "dt");
integrator.addComputeGlobal("dt_global", "dt");
Context context(system, integrator, platform);
vector<Vec3> positions(1);
positions[0] = Vec3(0, 0, 0);
context.setPositions(positions);
for (int i = 0; i < 5; i++) {
integrator.step(1);
double dt = 1.5+i;
ASSERT_EQUAL_TOL(dt, integrator.getStepSize(), 1e-5);
ASSERT_EQUAL_TOL(dt, integrator.getGlobalVariable(0), 1e-5);
vector<Vec3> values;
integrator.getPerDofVariable(0, values);
ASSERT_EQUAL_VEC(Vec3(dt, dt, dt), values[0], 1e-5);
}
integrator.setStepSize(1.0);
for (int i = 0; i < 5; i++) {
integrator.step(1);
double dt = 2.0+i;
ASSERT_EQUAL_TOL(dt, integrator.getStepSize(), 1e-5);
ASSERT_EQUAL_TOL(dt, integrator.getGlobalVariable(0), 1e-5);
vector<Vec3> values;
integrator.getPerDofVariable(0, values);
ASSERT_EQUAL_VEC(Vec3(dt, dt, dt), values[0], 1e-5);
}
}
void runPlatformTests(); void runPlatformTests();
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
...@@ -879,6 +916,7 @@ int main(int argc, char* argv[]) { ...@@ -879,6 +916,7 @@ int main(int argc, char* argv[]) {
testWhileBlock(); testWhileBlock();
testChangingGlobal(); testChangingGlobal();
testEnergyParameterDerivatives(); testEnergyParameterDerivatives();
testChangeDT();
runPlatformTests(); runPlatformTests();
} }
catch(const exception& e) { catch(const exception& e) {
......
...@@ -878,6 +878,16 @@ void testLargeInteractionGroup() { ...@@ -878,6 +878,16 @@ void testLargeInteractionGroup() {
State state3 = context.getState(State::Forces); State state3 = context.getState(State::Forces);
for (int i = 0; i < numParticles; i++) for (int i = 0; i < numParticles; i++)
ASSERT_EQUAL_VEC(state1.getForces()[i], state3.getForces()[i], 1e-4); ASSERT_EQUAL_VEC(state1.getForces()[i], state3.getForces()[i], 1e-4);
// Now make the interaction group empty. The energy should then be zero.
set1.clear();
set2.clear();
nonbonded->setInteractionGroupParameters(0, set1, set2);
context.reinitialize();
context.setPositions(positions);
State state4 = context.getState(State::Energy);
ASSERT_EQUAL(0.0, state4.getPotentialEnergy());
} }
void testInteractionGroupLongRangeCorrection() { void testInteractionGroupLongRangeCorrection() {
...@@ -1024,6 +1034,65 @@ void testMultipleCutoffs() { ...@@ -1024,6 +1034,65 @@ void testMultipleCutoffs() {
} }
} }
void testMultipleSwitches() {
System system;
system.addParticle(1.0);
system.addParticle(1.0);
VerletIntegrator integrator(0.01);
// Add multiple CustomNonbondedForces, one with a switching function and one without.
CustomNonbondedForce* nonbonded1 = new CustomNonbondedForce("2*r");
nonbonded1->addParticle(vector<double>());
nonbonded1->addParticle(vector<double>());
nonbonded1->setNonbondedMethod(CustomNonbondedForce::CutoffNonPeriodic);
nonbonded1->setCutoffDistance(1.0);
system.addForce(nonbonded1);
CustomNonbondedForce* nonbonded2 = new CustomNonbondedForce("3*r");
nonbonded2->addParticle(vector<double>());
nonbonded2->addParticle(vector<double>());
nonbonded2->setNonbondedMethod(CustomNonbondedForce::CutoffNonPeriodic);
nonbonded2->setCutoffDistance(1.0);
nonbonded2->setSwitchingDistance(0.5);
nonbonded2->setUseSwitchingFunction(true);
nonbonded2->setForceGroup(1);
system.addForce(nonbonded2);
Context context(system, integrator, platform);
double r = 0.8;
vector<Vec3> positions(2);
positions[0] = Vec3(0, 0, 0);
positions[1] = Vec3(0, r, 0);
context.setPositions(positions);
double t = (r-0.5)/(1.0-0.5);
double switchValue = 1+t*t*t*(-10+t*(15-t*6));
double switchDeriv = t*t*(-30+t*(60-t*30))/(1.0-0.5);
double e1 = 2.0*r;
double e2 = 3.0*r*switchValue;
double f1 = 2.0;
double f2 = 3.0*switchValue + 3.0*switchDeriv*r;
// Check the first force.
State state = context.getState(State::Forces | State::Energy, false, 1);
ASSERT_EQUAL_VEC(Vec3(0, f1, 0), state.getForces()[0], TOL);
ASSERT_EQUAL_VEC(Vec3(0, -f1, 0), state.getForces()[1], TOL);
ASSERT_EQUAL_TOL(e1, state.getPotentialEnergy(), TOL);
// Check the second force.
state = context.getState(State::Forces | State::Energy, false, 2);
ASSERT_EQUAL_VEC(Vec3(0, f2, 0), state.getForces()[0], TOL);
ASSERT_EQUAL_VEC(Vec3(0, -f2, 0), state.getForces()[1], TOL);
ASSERT_EQUAL_TOL(e2, state.getPotentialEnergy(), TOL);
// Check the sum of both forces.
state = context.getState(State::Forces | State::Energy);
ASSERT_EQUAL_VEC(Vec3(0, f1+f2, 0), state.getForces()[0], TOL);
ASSERT_EQUAL_VEC(Vec3(0, -f1-f2, 0), state.getForces()[1], TOL);
ASSERT_EQUAL_TOL(e1+e2, state.getPotentialEnergy(), TOL);
}
void testIllegalVariable() { void testIllegalVariable() {
System system; System system;
system.addParticle(1.0); system.addParticle(1.0);
...@@ -1144,6 +1213,7 @@ int main(int argc, char* argv[]) { ...@@ -1144,6 +1213,7 @@ int main(int argc, char* argv[]) {
testInteractionGroupLongRangeCorrection(); testInteractionGroupLongRangeCorrection();
testInteractionGroupTabulatedFunction(); testInteractionGroupTabulatedFunction();
testMultipleCutoffs(); testMultipleCutoffs();
testMultipleSwitches();
testIllegalVariable(); testIllegalVariable();
testEnergyParameterDerivatives(); testEnergyParameterDerivatives();
testEnergyParameterDerivatives2(); testEnergyParameterDerivatives2();
......
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2017 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#ifdef _MSC_VER
// Prevent Windows from defining macros that interfere with other code.
#define NOMINMAX
#endif
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/Context.h"
#include "openmm/NonbondedForce.h"
#include "openmm/System.h"
#include "openmm/Units.h"
#include "openmm/VerletIntegrator.h"
#include "openmm/internal/NonbondedForceImpl.h"
#include "sfmt/SFMT.h"
#include <iostream>
#include <vector>
#include <algorithm>
using namespace OpenMM;
using namespace std;
void testConvergence() {
// Create a cloud of random particles.
const int numParticles = 1000;
const double boxWidth = 6.0;
System system;
system.setDefaultPeriodicBoxVectors(Vec3(boxWidth, 0, 0), Vec3(0, boxWidth, 0), Vec3(0, 0, boxWidth));
NonbondedForce* force = new NonbondedForce();
system.addForce(force);
vector<Vec3> positions(numParticles);
OpenMM_SFMT::SFMT sfmt;
init_gen_rand(0, sfmt);
for (int i = 0; i < numParticles; i++) {
system.addParticle(1.0);
force->addParticle(0.0, 0.1+0.3*genrand_real2(sfmt), genrand_real2(sfmt));
while (true) {
Vec3 pos = Vec3(boxWidth*genrand_real2(sfmt), boxWidth*genrand_real2(sfmt), boxWidth*genrand_real2(sfmt));
double minDist = boxWidth;
for (int j = 0; j < i; j++) {
Vec3 delta = pos-positions[j];
minDist = std::min(minDist, sqrt(delta.dot(delta)));
}
if (minDist > 0.15) {
positions[i] = pos;
break;
}
}
}
// Compute the energy with short and long cutoffs, and compare them to LJPME.
// The long cutoff should match the LJPME result better than the short cutoff.
force->setNonbondedMethod(NonbondedForce::LJPME);
force->setCutoffDistance(1.0);
force->setEwaldErrorTolerance(1e-5);
force->setUseDispersionCorrection(false);
VerletIntegrator integrator(0.01);
Context context(system, integrator, platform);
context.setPositions(positions);
double pmeEnergy = context.getState(State::Energy, false, 1).getPotentialEnergy();
force->setNonbondedMethod(NonbondedForce::CutoffPeriodic);
context.reinitialize();
context.setPositions(positions);
double shortEnergy = context.getState(State::Energy, false, 1).getPotentialEnergy();
force->setCutoffDistance(3.0);
context.reinitialize();
context.setPositions(positions);
double longEnergy = context.getState(State::Energy, false, 1).getPotentialEnergy();
ASSERT(fabs(longEnergy-pmeEnergy) < fabs(shortEnergy-pmeEnergy))
}
void testErrorTolerance() {
// Create a cloud of random particles.
const int numParticles = 200;
const double boxWidth = 5.0;
System system;
system.setDefaultPeriodicBoxVectors(Vec3(boxWidth, 0, 0), Vec3(0, boxWidth, 0), Vec3(0, 0, boxWidth));
NonbondedForce* force = new NonbondedForce();
system.addForce(force);
vector<Vec3> positions(numParticles);
OpenMM_SFMT::SFMT sfmt;
init_gen_rand(0, sfmt);
for (int i = 0; i < numParticles; i++) {
system.addParticle(1.0);
force->addParticle(0.0, 0.1+0.2*genrand_real2(sfmt), genrand_real2(sfmt));
while (true) {
Vec3 pos = Vec3(boxWidth*genrand_real2(sfmt), boxWidth*genrand_real2(sfmt), boxWidth*genrand_real2(sfmt));
double minDist = boxWidth;
for (int j = 0; j < i; j++) {
Vec3 delta = pos-positions[j];
minDist = std::min(minDist, sqrt(delta.dot(delta)));
}
if (minDist > 0.1) {
positions[i] = pos;
break;
}
}
}
force->setNonbondedMethod(NonbondedForce::LJPME);
// For various values of the cutoff and error tolerance, see if the actual error is reasonable.
for (double cutoff = 0.8; cutoff < boxWidth/2; cutoff *= 1.3) {
force->setCutoffDistance(cutoff);
vector<Vec3> refForces;
double norm = 0.0;
for (double tol = 5e-5; tol < 1e-3; tol *= 2.0) {
force->setEwaldErrorTolerance(tol);
VerletIntegrator integrator(0.01);
Context context(system, integrator, platform);
context.setPositions(positions);
State state = context.getState(State::Forces);
if (refForces.size() == 0) {
refForces = state.getForces();
for (int i = 0; i < numParticles; i++)
norm += refForces[i].dot(refForces[i]);
norm = sqrt(norm);
}
else {
double diff = 0.0;
for (int i = 0; i < numParticles; i++) {
Vec3 delta = refForces[i]-state.getForces()[i];
diff += delta.dot(delta);
}
diff = sqrt(diff)/norm;
ASSERT(diff < 2*tol);
}
// See if the PME parameters were calculated correctly.
double expectedAlpha, actualAlpha;
int expectedSize[3], actualSize[3];
NonbondedForceImpl::calcPMEParameters(system, *force, expectedAlpha, expectedSize[0], expectedSize[1], expectedSize[2], true);
force->getLJPMEParametersInContext(context, actualAlpha, actualSize[0], actualSize[1], actualSize[2]);
ASSERT_EQUAL_TOL(expectedAlpha, actualAlpha, 1e-5);
for (int i = 0; i < 3; i++) {
ASSERT(actualSize[i] >= expectedSize[i]);
ASSERT(actualSize[i] < expectedSize[i]+10);
}
}
}
}
void testPMEParameters() {
// Create a cloud of random particles.
const int numParticles = 51;
const double boxWidth = 4.7;
System system;
system.setDefaultPeriodicBoxVectors(Vec3(boxWidth, 0, 0), Vec3(0, boxWidth, 0), Vec3(0, 0, boxWidth));
NonbondedForce* force = new NonbondedForce();
system.addForce(force);
vector<Vec3> positions(numParticles);
OpenMM_SFMT::SFMT sfmt;
init_gen_rand(0, sfmt);
for (int i = 0; i < numParticles; i++) {
system.addParticle(1.0);
force->addParticle(0.0, 0.1+0.2*genrand_real2(sfmt), genrand_real2(sfmt));
positions[i] = Vec3(boxWidth*genrand_real2(sfmt), boxWidth*genrand_real2(sfmt), boxWidth*genrand_real2(sfmt));
}
force->setNonbondedMethod(NonbondedForce::LJPME);
force->setCutoffDistance(0.5);
// Compute the energy with an error tolerance of 0.1.
force->setEwaldErrorTolerance(0.1);
VerletIntegrator integrator1(0.01);
Context context1(system, integrator1, platform);
context1.setPositions(positions);
double energy1 = context1.getState(State::Energy).getPotentialEnergy();
double alpha;
int gridx, gridy, gridz;
force->getLJPMEParametersInContext(context1, alpha, gridx, gridy, gridz);
// Try again with an error tolerance of 1e-4.
force->setEwaldErrorTolerance(1e-4);
VerletIntegrator integrator2(0.01);
Context context2(system, integrator2, platform);
context2.setPositions(positions);
double energy2 = context2.getState(State::Energy).getPotentialEnergy();
// Now explicitly set the parameters. These should match the values that were
// used for tolerance 0.1.
force->setLJPMEParameters(alpha, gridx, gridy, gridz);
VerletIntegrator integrator3(0.01);
Context context3(system, integrator3, platform);
context3.setPositions(positions);
double energy3 = context3.getState(State::Energy).getPotentialEnergy();
ASSERT_EQUAL_TOL(energy1, energy3, 1e-5);
ASSERT(fabs((energy1-energy2)/energy1) > 1e-5);
force->getLJPMEParametersInContext(context2, alpha, gridx, gridy, gridz);
}
void testCoulombAndLJ() {
// Create a cloud of random particles.
const int numParticles = 200;
const double boxWidth = 5.0;
System system;
system.setDefaultPeriodicBoxVectors(Vec3(boxWidth, 0, 0), Vec3(0, boxWidth, 0), Vec3(0, 0, boxWidth));
NonbondedForce* force = new NonbondedForce();
system.addForce(force);
vector<Vec3> positions(numParticles);
OpenMM_SFMT::SFMT sfmt;
init_gen_rand(0, sfmt);
vector<double> charge(numParticles), sigma(numParticles), epsilon(numParticles);
for (int i = 0; i < numParticles; i++) {
system.addParticle(1.0);
charge[i] = -1.0+i*2.0/(numParticles-1);
sigma[i] = 0.1+0.2*genrand_real2(sfmt);
epsilon[i] = genrand_real2(sfmt);
force->addParticle(charge[i], 1.0, 0.0);
while (true) {
Vec3 pos = Vec3(boxWidth*genrand_real2(sfmt), boxWidth*genrand_real2(sfmt), boxWidth*genrand_real2(sfmt));
double minDist = boxWidth;
for (int j = 0; j < i; j++) {
Vec3 delta = pos-positions[j];
minDist = std::min(minDist, sqrt(delta.dot(delta)));
}
if (minDist > 0.1) {
positions[i] = pos;
break;
}
}
}
force->setNonbondedMethod(NonbondedForce::LJPME);
// Compute forces and energy with only Coulomb interactions.
VerletIntegrator integrator(0.01);
Context context(system, integrator, platform);
context.setPositions(positions);
State state1 = context.getState(State::Forces | State::Energy);
// Now repeat with only LJ interactions.
for (int i = 0; i < numParticles; i++)
force->setParticleParameters(i, 0.0, sigma[i], epsilon[i]);
context.reinitialize();
context.setPositions(positions);
State state2 = context.getState(State::Forces | State::Energy);
// Finally compute with both Coulomb and LJ.
for (int i = 0; i < numParticles; i++)
force->setParticleParameters(i, charge[i], sigma[i], epsilon[i]);
context.reinitialize();
context.setPositions(positions);
State state3 = context.getState(State::Forces | State::Energy);
// Make sure the results agree.
ASSERT_EQUAL_TOL(state1.getPotentialEnergy()+state2.getPotentialEnergy(), state3.getPotentialEnergy(), 1e-5);
for (int i = 0; i < numParticles; i++)
ASSERT_EQUAL_VEC(state1.getForces()[i]+state2.getForces()[i], state3.getForces()[i], 1e-5);
}
void make_dmfbox(int natoms, double boxEdgeLength, NonbondedForce *forceField, vector<Vec3> &positions, vector<double>& eps, vector<double>& sig,
vector<pair<int, int> >& bonds, System &system, bool do_electrostatics) {
const int RESSIZE = 12;
const double charges[RESSIZE] = {
0.08, 0.43, -0.54, -0.33, -0.09, 0.09,
0.09, 0.09, -0.09, 0.09, 0.09, 0.09
};
const double masses[RESSIZE] = {
1.008, 12.011, 15.9994, 14.007, 12.011, 1.008,
1.008, 1.008, 12.011, 1.008, 1.008, 1.008
};
const double sigmas[RESSIZE] = {
0.160361769265, 0.356359487256, 0.302905564168, 0.329632525712, 0.365268474438, 0.238760856462,
0.238760856462, 0.238760856462, 0.365268474438, 0.238760856462, 0.238760856462, 0.238760856462
};
const double epsilons[RESSIZE] = {
0.19246, 0.46024, 0.50208, 0.83680, 0.32635, 0.10042,
0.10042, 0.10042, 0.32635, 0.10042, 0.10042, 0.10042
};
positions.clear();
if (natoms == 12) {
const double coords[12][3] = {
{ 0.620, 0.945, 0.128 },
{ 0.560, 0.905, 0.045 },
{ 0.502, 0.987, -0.026 },
{ 0.556, 0.770, 0.028 },
{ 0.643, 0.685, 0.106 },
{ 0.680, 0.741, 0.193 },
{ 0.729, 0.653, 0.045 },
{ 0.587, 0.597, 0.140 },
{ 0.477, 0.708, -0.072 },
{ 0.377, 0.688, -0.032 },
{ 0.524, 0.614, -0.102 },
{ 0.468, 0.775, -0.158 }
};
for (int atom = 0; atom < natoms; ++atom)
positions.push_back(Vec3(coords[atom][0], coords[atom][1], coords[atom][2]));
}
else
throw exception();
system.setDefaultPeriodicBoxVectors(Vec3(boxEdgeLength, 0, 0),
Vec3(0, boxEdgeLength, 0),
Vec3(0, 0, boxEdgeLength));
sig.clear();
eps.clear();
bonds.clear();
for (int atom = 0; atom < natoms; ++atom) {
system.addParticle(masses[atom%RESSIZE]);
double sigma = sigmas[atom%RESSIZE];
double epsilon = epsilons[atom%RESSIZE];
sig.push_back(sigma);
eps.push_back(epsilon);
if (atom%RESSIZE == 0) {
int offset = atom-1;
bonds.push_back(pair<int, int>(offset+1, offset+ 2));
bonds.push_back(pair<int, int>(offset+2, offset+ 3));
bonds.push_back(pair<int, int>(offset+2, offset+ 4));
bonds.push_back(pair<int, int>(offset+4, offset+ 5));
bonds.push_back(pair<int, int>(offset+4, offset+ 9));
bonds.push_back(pair<int, int>(offset+5, offset+ 6));
bonds.push_back(pair<int, int>(offset+5, offset+ 7));
bonds.push_back(pair<int, int>(offset+5, offset+ 8));
bonds.push_back(pair<int, int>(offset+9, offset+10));
bonds.push_back(pair<int, int>(offset+9, offset+11));
bonds.push_back(pair<int, int>(offset+9, offset+12));
}
double charge = do_electrostatics ? charges[atom] : 0;
forceField->addParticle(charge, sigma, epsilon);
}
// Make exceptions and replacement 1-4 parameters
forceField->createExceptionsFromBonds(bonds, 1.0, 1.0);
int nres = natoms / RESSIZE;
double newqq = do_electrostatics ? charges[8]*charges[8] : 0.0;
double newsig = 0.293996576986;
double neweps = 0.144938011577;
for(int i = 0; i < forceField->getNumExceptions(); ++i){
for(int res = 0; res < nres; ++res){
int particle1, particle2;
double chargeProd, sigma, epsilon;
forceField->getExceptionParameters(i, particle1, particle2, chargeProd, sigma, epsilon);
if((particle1 == res+2 && particle2 == res+8) ||
(particle1 == res+8 && particle2 == res+2) ||
(particle1 == res+2 && particle2 == res+4) ||
(particle1 == res+4 && particle2 == res+2))
forceField->setExceptionParameters(i, particle1, particle2, newqq, newsig, neweps);
}
}
}
void make_waterbox(int natoms, double boxEdgeLength, NonbondedForce *forceField, vector<Vec3> &positions, vector<double>& eps, vector<double>& sig,
vector<pair<int, int> >& bonds, System &system, bool do_electrostatics) {
const int RESSIZE = 3;
const double masses[RESSIZE] = { 8.0, 1.0, 1.0 };
const double charges[RESSIZE] = { -0.834, 0.417, 0.417 };
// Values from the CHARMM force field, in AKMA units
const double epsilons[RESSIZE] = { -0.1521, -0.046, -0.046 };
const double halfrmins[RESSIZE] = { 1.7682, 0.2245, 0.2245 };
positions.clear();
if (natoms == 6) {
const double coords[6][3] = {
{ 2.000000, 2.000000, 2.000000},
{ 2.500000, 2.000000, 3.000000},
{ 1.500000, 2.000000, 3.000000},
{ 0.000000, 0.000000, 0.000000},
{ 0.500000, 0.000000, 1.000000},
{ -0.500000, 0.000000, 1.000000}
};
for (int atom = 0; atom < natoms; ++atom)
positions.push_back(Vec3(coords[atom][0], coords[atom][1], coords[atom][2])*OpenMM::NmPerAngstrom);
}
else if (natoms == 375) {
const double coords[375][3] = {
{ -6.22, -6.25, -6.24 },
{ -5.32, -6.03, -6.00 },
{ -6.75, -5.56, -5.84 },
{ -3.04, -6.23, -6.19 },
{ -3.52, -5.55, -5.71 },
{ -3.59, -6.43, -6.94 },
{ 0.02, -6.23, -6.14 },
{ -0.87, -5.97, -6.37 },
{ 0.53, -6.03, -6.93 },
{ 3.10, -6.20, -6.27 },
{ 3.87, -6.35, -5.72 },
{ 2.37, -6.11, -5.64 },
{ 6.18, -6.14, -6.20 },
{ 6.46, -6.66, -5.44 },
{ 6.26, -6.74, -6.94 },
{ -6.21, -3.15, -6.24 },
{ -6.23, -3.07, -5.28 },
{ -6.02, -2.26, -6.55 },
{ -3.14, -3.07, -6.16 },
{ -3.38, -3.63, -6.90 },
{ -2.18, -3.05, -6.17 },
{ -0.00, -3.16, -6.23 },
{ -0.03, -2.30, -6.67 },
{ 0.05, -2.95, -5.29 },
{ 3.08, -3.11, -6.14 },
{ 2.65, -2.55, -6.79 },
{ 3.80, -3.53, -6.62 },
{ 6.16, -3.14, -6.16 },
{ 7.04, -3.32, -6.51 },
{ 5.95, -2.27, -6.51 },
{ -6.20, -0.04, -6.15 },
{ -5.43, 0.32, -6.59 },
{ -6.95, 0.33, -6.62 },
{ -3.10, -0.06, -6.19 },
{ -3.75, 0.42, -6.69 },
{ -2.46, 0.60, -5.93 },
{ 0.05, -0.01, -6.17 },
{ -0.10, 0.02, -7.12 },
{ -0.79, 0.16, -5.77 },
{ 3.03, 0.00, -6.19 },
{ 3.54, 0.08, -7.01 },
{ 3.69, -0.22, -5.53 },
{ 6.17, 0.05, -6.19 },
{ 5.78, -0.73, -6.57 },
{ 7.09, -0.17, -6.04 },
{ -6.20, 3.15, -6.25 },
{ -6.59, 3.18, -5.37 },
{ -5.87, 2.25, -6.33 },
{ -3.09, 3.04, -6.17 },
{ -3.88, 3.58, -6.26 },
{ -2.41, 3.54, -6.63 },
{ 0.00, 3.06, -6.26 },
{ -0.71, 3.64, -6.00 },
{ 0.65, 3.15, -5.55 },
{ 3.14, 3.06, -6.23 },
{ 3.11, 3.31, -5.30 },
{ 2.38, 3.49, -6.63 },
{ 6.19, 3.14, -6.25 },
{ 6.82, 3.25, -5.54 },
{ 5.76, 2.30, -6.07 },
{ -6.22, 6.26, -6.19 },
{ -6.22, 5.74, -7.00 },
{ -5.89, 5.67, -5.52 },
{ -3.04, 6.24, -6.20 },
{ -3.08, 5.28, -6.17 },
{ -3.96, 6.52, -6.25 },
{ -0.05, 6.21, -6.16 },
{ 0.82, 6.58, -6.06 },
{ 0.01, 5.64, -6.93 },
{ 3.10, 6.25, -6.15 },
{ 3.64, 5.47, -6.31 },
{ 2.46, 6.24, -6.87 },
{ 6.22, 6.20, -6.27 },
{ 5.37, 6.42, -5.88 },
{ 6.80, 6.07, -5.51 },
{ -6.19, -6.15, -3.13 },
{ -6.37, -7.01, -3.51 },
{ -6.25, -6.29, -2.18 },
{ -3.10, -6.27, -3.11 },
{ -2.29, -5.77, -2.99 },
{ -3.80, -5.62, -2.98 },
{ -0.03, -6.18, -3.15 },
{ -0.07, -7.05, -2.75 },
{ 0.68, -5.74, -2.70 },
{ 3.10, -6.14, -3.07 },
{ 2.35, -6.72, -3.23 },
{ 3.86, -6.65, -3.37 },
{ 6.22, -6.20, -3.16 },
{ 6.82, -6.36, -2.43 },
{ 5.35, -6.13, -2.75 },
{ -6.26, -3.13, -3.12 },
{ -6.16, -2.27, -2.70 },
{ -5.36, -3.47, -3.18 },
{ -3.11, -3.05, -3.14 },
{ -3.31, -3.96, -3.34 },
{ -2.77, -3.06, -2.24 },
{ 0.00, -3.13, -3.16 },
{ 0.48, -2.37, -2.81 },
{ -0.57, -3.40, -2.44 },
{ 3.09, -3.09, -3.16 },
{ 2.41, -3.19, -2.49 },
{ 3.91, -3.07, -2.67 },
{ 6.19, -3.04, -3.08 },
{ 5.64, -3.61, -3.61 },
{ 6.93, -3.58, -2.82 },
{ -6.18, -0.00, -3.04 },
{ -6.00, -0.59, -3.78 },
{ -6.79, 0.64, -3.39 },
{ -3.05, -0.03, -3.07 },
{ -2.95, 0.80, -3.52 },
{ -4.00, -0.20, -3.07 },
{ -0.03, 0.03, -3.06 },
{ -0.33, -0.37, -3.87 },
{ 0.89, -0.21, -2.99 },
{ 3.13, -0.05, -3.10 },
{ 3.44, 0.81, -3.34 },
{ 2.21, 0.07, -2.86 },
{ 6.20, -0.05, -3.13 },
{ 6.89, 0.60, -3.20 },
{ 5.58, 0.30, -2.49 },
{ -6.23, 3.09, -3.16 },
{ -5.62, 3.79, -2.94 },
{ -6.33, 2.60, -2.33 },
{ -3.10, 3.08, -3.04 },
{ -3.84, 3.47, -3.51 },
{ -2.40, 3.01, -3.69 },
{ 0.01, 3.04, -3.11 },
{ -0.56, 3.59, -3.64 },
{ 0.28, 3.60, -2.38 },
{ 3.04, 3.11, -3.09 },
{ 3.49, 2.30, -2.87 },
{ 3.70, 3.66, -3.51 },
{ 6.15, 3.14, -3.11 },
{ 6.52, 2.52, -3.74 },
{ 6.72, 3.06, -2.34 },
{ -6.22, 6.15, -3.13 },
{ -5.49, 6.21, -2.51 },
{ -6.56, 7.04, -3.18 },
{ -3.11, 6.24, -3.05 },
{ -3.76, 5.83, -3.62 },
{ -2.26, 5.92, -3.37 },
{ 0.03, 6.25, -3.07 },
{ 0.34, 5.63, -3.73 },
{ -0.87, 6.00, -2.91 },
{ 3.07, 6.15, -3.08 },
{ 3.29, 6.92, -2.56 },
{ 3.39, 6.35, -3.96 },
{ 6.22, 6.14, -3.12 },
{ 5.79, 6.38, -2.29 },
{ 6.25, 6.96, -3.62 },
{ -6.21, -6.20, -0.06 },
{ -5.79, -6.87, 0.48 },
{ -6.43, -5.50, 0.54 },
{ -3.16, -6.21, -0.02 },
{ -2.50, -6.87, 0.20 },
{ -2.77, -5.37, 0.23 },
{ -0.00, -6.14, -0.00 },
{ 0.68, -6.72, -0.33 },
{ -0.64, -6.73, 0.38 },
{ 3.03, -6.20, -0.01 },
{ 3.77, -6.56, -0.51 },
{ 3.43, -5.85, 0.78 },
{ 6.25, -6.16, -0.00 },
{ 5.36, -6.09, -0.36 },
{ 6.24, -6.97, 0.49 },
{ -6.24, -3.05, -0.01 },
{ -6.35, -3.64, 0.73 },
{ -5.42, -3.33, -0.42 },
{ -3.09, -3.06, 0.05 },
{ -2.44, -3.62, -0.38 },
{ -3.90, -3.21, -0.43 },
{ 0.05, -3.10, 0.02 },
{ -0.31, -2.35, -0.43 },
{ -0.63, -3.77, 0.01 },
{ 3.05, -3.09, -0.04 },
{ 3.28, -3.90, 0.41 },
{ 3.65, -2.43, 0.30 },
{ 6.20, -3.04, -0.03 },
{ 5.66, -3.31, 0.71 },
{ 6.78, -3.79, -0.19 },
{ -6.18, 0.04, -0.04 },
{ -6.73, -0.73, -0.15 },
{ -5.98, 0.06, 0.89 },
{ -3.11, -0.04, -0.04 },
{ -3.36, -0.08, 0.87 },
{ -2.70, 0.81, -0.14 },
{ -0.02, -0.02, -0.05 },
{ -0.45, 0.28, 0.75 },
{ 0.90, 0.15, 0.07 },
{ 3.04, 0.02, -0.01 },
{ 3.26, -0.82, 0.38 },
{ 3.89, 0.45, -0.13 },
{ 6.19, 0.05, -0.03 },
{ 5.52, -0.56, 0.25 },
{ 7.01, -0.29, 0.32 },
{ -6.14, 3.08, 0.00 },
{ -6.83, 2.82, 0.61 },
{ -6.59, 3.64, -0.64 },
{ -3.05, 3.09, -0.04 },
{ -3.79, 2.50, 0.09 },
{ -3.18, 3.80, 0.59 },
{ 0.02, 3.14, 0.04 },
{ -0.89, 3.04, -0.19 },
{ 0.49, 2.57, -0.57 },
{ 3.14, 3.15, 0.00 },
{ 3.28, 2.28, 0.37 },
{ 2.30, 3.08, -0.45 },
{ 6.27, 3.08, -0.00 },
{ 5.55, 2.54, -0.33 },
{ 5.83, 3.87, 0.34 },
{ -6.18, 6.15, -0.03 },
{ -6.45, 6.21, 0.88 },
{ -6.26, 7.05, -0.36 },
{ -3.06, 6.19, -0.05 },
{ -2.84, 6.64, 0.76 },
{ -3.99, 5.96, 0.03 },
{ -0.00, 6.20, 0.06 },
{ -0.67, 5.99, -0.59 },
{ 0.76, 6.46, -0.44 },
{ 3.10, 6.26, -0.03 },
{ 3.57, 6.09, 0.78 },
{ 2.57, 5.47, -0.18 },
{ 6.26, 6.18, 0.02 },
{ 5.53, 5.64, -0.29 },
{ 5.95, 7.08, -0.06 },
{ -6.26, -6.21, 3.07 },
{ -5.98, -6.38, 3.97 },
{ -5.46, -5.94, 2.62 },
{ -3.10, -6.24, 3.04 },
{ -2.69, -6.51, 3.87 },
{ -3.43, -5.35, 3.21 },
{ -0.03, -6.16, 3.06 },
{ 0.83, -6.00, 3.42 },
{ -0.30, -6.99, 3.45 },
{ 3.15, -6.25, 3.11 },
{ 2.77, -5.60, 3.72 },
{ 2.68, -6.10, 2.28 },
{ 6.20, -6.21, 3.16 },
{ 5.75, -6.73, 2.50 },
{ 6.69, -5.56, 2.66 },
{ -6.17, -3.10, 3.04 },
{ -6.82, -2.44, 3.28 },
{ -6.12, -3.69, 3.80 },
{ -3.08, -3.04, 3.11 },
{ -3.59, -3.56, 3.72 },
{ -2.97, -3.61, 2.34 },
{ 0.01, -3.04, 3.11 },
{ -0.86, -3.41, 3.20 },
{ 0.56, -3.78, 2.86 },
{ 3.07, -3.07, 3.15 },
{ 3.81, -3.68, 3.13 },
{ 2.80, -2.98, 2.23 },
{ 6.20, -3.04, 3.13 },
{ 5.48, -3.64, 2.92 },
{ 6.98, -3.49, 2.81 },
{ -6.18, -0.05, 3.12 },
{ -6.41, 0.66, 3.69 },
{ -6.33, 0.28, 2.23 },
{ -3.05, 0.03, 3.10 },
{ -3.46, -0.42, 3.83 },
{ -3.57, -0.19, 2.33 },
{ 0.03, -0.02, 3.15 },
{ 0.23, -0.08, 2.21 },
{ -0.81, 0.41, 3.18 },
{ 3.09, 0.00, 3.03 },
{ 2.48, -0.29, 3.71 },
{ 3.91, 0.16, 3.51 },
{ 6.19, -0.06, 3.11 },
{ 6.05, 0.47, 2.33 },
{ 6.59, 0.52, 3.74 },
{ -6.20, 3.05, 3.05 },
{ -6.87, 3.73, 3.17 },
{ -5.55, 3.24, 3.73 },
{ -3.11, 3.06, 3.15 },
{ -3.64, 3.74, 2.71 },
{ -2.32, 3.00, 2.62 },
{ 0.02, 3.05, 3.06 },
{ -0.87, 3.14, 3.38 },
{ 0.48, 3.82, 3.42 },
{ 3.07, 3.10, 3.16 },
{ 3.95, 3.44, 2.97 },
{ 2.76, 2.73, 2.32 },
{ 6.19, 3.07, 3.16 },
{ 7.02, 3.30, 2.72 },
{ 5.52, 3.27, 2.51 },
{ -6.19, 6.24, 3.15 },
{ -5.56, 5.88, 2.52 },
{ -7.05, 5.96, 2.83 },
{ -3.10, 6.14, 3.08 },
{ -2.34, 6.69, 3.27 },
{ -3.86, 6.69, 3.29 },
{ -0.04, 6.24, 3.13 },
{ 0.63, 6.54, 2.53 },
{ 0.08, 5.29, 3.18 },
{ 3.12, 6.24, 3.14 },
{ 3.57, 5.82, 2.40 },
{ 2.23, 5.90, 3.12 },
{ 6.25, 6.19, 3.06 },
{ 5.55, 5.59, 3.32 },
{ 6.08, 6.99, 3.55 },
{ -6.20, -6.16, 6.15 },
{ -6.29, -5.99, 7.09 },
{ -6.09, -7.11, 6.09 },
{ -3.09, -6.19, 6.27 },
{ -2.56, -5.90, 5.52 },
{ -3.80, -6.69, 5.87 },
{ 0.02, -6.25, 6.24 },
{ -0.70, -5.70, 6.51 },
{ 0.25, -5.93, 5.36 },
{ 3.11, -6.18, 6.14 },
{ 3.76, -6.54, 6.74 },
{ 2.29, -6.20, 6.64 },
{ 6.22, -6.17, 6.15 },
{ 6.61, -6.98, 6.47 },
{ 5.56, -5.94, 6.81 },
{ -6.21, -3.10, 6.14 },
{ -6.76, -2.66, 6.78 },
{ -5.51, -3.50, 6.65 },
{ -3.13, -3.05, 6.18 },
{ -2.19, -3.14, 6.34 },
{ -3.50, -3.89, 6.43 },
{ 0.01, -3.06, 6.15 },
{ -0.06, -2.81, 7.07 },
{ -0.25, -3.98, 6.13 },
{ 3.04, -3.09, 6.17 },
{ 3.84, -3.51, 5.84 },
{ 3.25, -2.85, 7.08 },
{ 6.26, -3.13, 6.19 },
{ 6.01, -2.20, 6.09 },
{ 5.47, -3.55, 6.54 },
{ -6.20, 0.01, 6.27 },
{ -5.79, -0.70, 5.78 },
{ -6.67, 0.51, 5.60 },
{ -3.13, 0.01, 6.14 },
{ -3.53, -0.35, 6.94 },
{ -2.21, 0.17, 6.39 },
{ -0.04, -0.04, 6.20 },
{ 0.26, 0.47, 5.46 },
{ 0.51, 0.22, 6.93 },
{ 3.10, -0.05, 6.23 },
{ 2.33, 0.44, 5.95 },
{ 3.85, 0.45, 5.92 },
{ 6.19, -0.01, 6.26 },
{ 7.05, 0.16, 5.88 },
{ 5.58, 0.02, 5.52 },
{ -6.22, 3.04, 6.17 },
{ -5.45, 3.57, 5.95 },
{ -6.62, 3.50, 6.92 },
{ -3.09, 3.16, 6.21 },
{ -3.71, 2.75, 5.61 },
{ -2.60, 2.43, 6.59 },
{ -0.02, 3.10, 6.26 },
{ 0.89, 3.27, 6.05 },
{ -0.44, 2.94, 5.41 },
{ 3.12, 3.04, 6.23 },
{ 2.31, 3.53, 6.43 },
{ 3.59, 3.60, 5.60 },
{ 6.23, 3.05, 6.24 },
{ 5.92, 3.91, 6.54 },
{ 6.02, 3.03, 5.30 },
{ -6.15, 6.21, 6.24 },
{ -6.27, 6.46, 5.32 },
{ -7.00, 5.85, 6.51 },
{ -3.07, 6.15, 6.22 },
{ -3.98, 6.27, 5.94 },
{ -2.66, 7.01, 6.10 },
{ 0.04, 6.20, 6.25 },
{ -0.38, 5.50, 5.75 },
{ -0.36, 7.00, 5.93 },
{ 3.12, 6.15, 6.24 },
{ 3.66, 6.88, 5.93 },
{ 2.25, 6.33, 5.86 },
{ 6.20, 6.27, 6.19 },
{ 5.46, 5.65, 6.19 },
{ 6.97, 5.73, 6.39 }
};
for (int atom = 0; atom < natoms; ++atom)
positions.push_back(Vec3(coords[atom][0], coords[atom][1], coords[atom][2])*OpenMM::NmPerAngstrom);
}
else
throw exception();
system.setDefaultPeriodicBoxVectors(Vec3(boxEdgeLength, 0, 0),
Vec3(0, boxEdgeLength, 0),
Vec3(0, 0, boxEdgeLength));
sig.clear();
eps.clear();
bonds.clear();
for (int atom = 0; atom < natoms; ++atom) {
system.addParticle(masses[atom%RESSIZE]);
double sigma = 2.0*pow(2.0, -1.0/6.0)*halfrmins[atom%RESSIZE]*OpenMM::NmPerAngstrom;
double epsilon = fabs(epsilons[atom%RESSIZE])*OpenMM::KJPerKcal;
sig.push_back(0.5*sigma);
eps.push_back(2.0*sqrt(epsilon));
if (atom%RESSIZE == 0) {
bonds.push_back(pair<int, int>(atom, atom+1));
bonds.push_back(pair<int, int>(atom, atom+2));
}
double charge = do_electrostatics ? charges[atom] : 0;
forceField->addParticle(charge, sigma, epsilon);
}
}
void testWater2DpmeEnergiesForcesNoExclusions() {
const double cutoff = 7.0*OpenMM::NmPerAngstrom;
const double alpha = 4.0124063605;
const double dalpha = 4.0124063605;
const int grid = 32;
NonbondedForce* forceField = new NonbondedForce();
vector<Vec3> positions;
vector<double> epsvals;
vector<double> sigvals;
vector<pair<int, int> > bonds;
System system;
const int numAtoms = 6;
double boxEdgeLength = 25*OpenMM::NmPerAngstrom;
make_waterbox(numAtoms, boxEdgeLength, forceField, positions, epsvals, sigvals, bonds, system, false);
forceField->setNonbondedMethod(OpenMM::NonbondedForce::LJPME);
forceField->setPMEParameters(alpha, grid, grid, grid);
forceField->setLJPMEParameters(dalpha, grid, grid, grid);
forceField->setCutoffDistance(cutoff);
forceField->setReactionFieldDielectric(1.0);
system.addForce(forceField);
VerletIntegrator integrator(0.01);
Context context(system, integrator, platform);
context.setPositions(positions);
//Gromacs reference values from the following inputs
//
//------------------------------------------------
// water2.gro
//------------------------------------------------
//MD of 2 waters, t= 0.0
// 6
// 1SOL OW1 1 0.200 0.200 0.200
// 1SOL HW1 2 0.250 0.200 0.300
// 1SOL HW2 3 0.150 0.200 0.300
// 2SOL OW1 4 0.000 0.000 0.000
// 2SOL HW1 5 0.050 0.000 0.100
// 2SOL HW2 6 -0.050 0.000 0.100
// 2.50000 2.50000 2.50000
//------------------------------------------------
//
//------------------------------------------------
// water2.gro
//------------------------------------------------
//[ defaults ]
//; nbfunc comb-rule gen-pairs fudgeLJ fudgeQQ
// 1 2 no 1.0 1.0
//
//[ atomtypes ]
//; full atom descriptions are available in ffoplsaa.atp
//; name bond_type mass charge ptype sigma epsilon
//OW OW 8 15.99940 -0.834 A 3.15057e-01 6.36386e-01
//HW HW 1 1.00800 0.417 A 4.00014e-02 1.92464e-01
//
//
//#ifdef NOEXCLUDE
//
//[ moleculetype ]
//; molname nrexcl
//SOL 0
//
//#else
//
//[ moleculetype ]
//; molname nrexcl
//SOL 3
//
//#endif
//
//#ifdef NOCHARGE
//[ atoms ]
//; id at type res nr residu name at name cg nr charge
//1 OW 1 SOL OW1 1 0.000
//2 HW 1 SOL HW1 1 0.000
//3 HW 1 SOL HW2 1 0.000
//#else
//[ atoms ]
//; id at type res nr residu name at name cg nr charge
//1 OW 1 SOL OW1 1 -0.834
//2 HW 1 SOL HW1 1 0.417
//3 HW 1 SOL HW2 1 0.417
//#endif
//
//[ settles ]
//; i j funct length
//1 1 0.09572 0.15139
//
//#ifndef NOEXCLUDE
//[ exclusions ]
//1 2 3
//2 1 3
//3 1 2
//#endif
//------------------------------------------------
//
//------------------------------------------------
// water2.top
//------------------------------------------------
//#include "tip3p.tpi"
//
//[ system ]
//Water dimer
//
//[ molecules ]
//SOL 2
//------------------------------------------------
//
//------------------------------------------------
// water2.mdp
//------------------------------------------------
//define = -DNOCHARGE -DNOEXCLUDE
//;define = -DNOCHARGE
//rvdw = 0.7
//vdw-modifier = Potential-Shift
//;vdw-modifier = None
//rlist = 0.9
//rcoulomb = 0.7
//nstfout = 1
//fourierspacing = 0.08
//pme-order = 5
//ewald-rtol = 1.5E-2
//ewald-rtol-lj = 1.5E-2
//vdwtype = PME
//lj-pme-comb-rule = geometric
//continuation = yes
//------------------------------------------------
//
//run commands:-
// gmx grompp -c water2.gro -p water2.top -f water2.mdp -o run.tpr
// gmx mdrun -s run.tpr -o traj.trr -pforce 1E-16
// gmx dump -f traj.trr
double refenergy = 1.34804e+03;
vector<Vec3> refforces(6);
refforces[0] = Vec3( 3.15301e-01, -3.91114e-03, -6.68965e+04);
refforces[1] = Vec3( 1.67241e+04, -3.79846e-02, 3.34487e+04);
refforces[2] = Vec3(-1.67243e+04, -9.55931e-02, 3.34486e+04);
refforces[3] = Vec3(-1.71643e+00, -1.76696e+00, -6.68993e+04);
refforces[4] = Vec3( 1.67254e+04, 1.59080e+00, 3.34495e+04);
refforces[5] = Vec3(-1.67239e+04, 3.13897e-01, 3.34491e+04);
State state = context.getState(State::Forces | State::Energy);
double energy = state.getPotentialEnergy();
const vector<Vec3>& forces = state.getForces();
ASSERT_EQUAL_TOL(refenergy, energy, 1E-4);
for (int n = 0; n < numAtoms; ++n)
ASSERT_EQUAL_VEC(refforces[n], forces[n], 1E-4);
}
void testDMFDpmeEnergiesForcesWithExclusions() {
const double cutoff = 7.0*OpenMM::NmPerAngstrom;
const double alpha = 4.0124063605;
const double dalpha = 4.0124063605;
const int grid = 32;
NonbondedForce* forceField = new NonbondedForce();
vector<Vec3> positions;
vector<double> epsvals;
vector<double> sigvals;
vector<pair<int, int> > bonds;
System system;
const int numAtoms = 12;
double boxEdgeLength = 20*OpenMM::NmPerAngstrom;
make_dmfbox(numAtoms, boxEdgeLength, forceField, positions, epsvals, sigvals, bonds, system, false);
forceField->setNonbondedMethod(OpenMM::NonbondedForce::LJPME);
forceField->setPMEParameters(alpha, grid, grid, grid);
forceField->setLJPMEParameters(dalpha, grid, grid, grid);
forceField->setCutoffDistance(cutoff);
forceField->setUseSwitchingFunction(false);
forceField->setUseDispersionCorrection(false);
forceField->setReactionFieldDielectric(1.0);
system.addForce(forceField);
VerletIntegrator integrator(0.01);
Context context(system, integrator, platform);
context.setPositions(positions);
double refenergy = 1.29545e+01;
vector<Vec3> refforces(12);
//Gromacs reference values from the following inputs
//------------------------------------------------
// dmf.mdp
//------------------------------------------------
//rvdw = 0.7
//vdw-modifier = Potential-Shift
//rlist = 0.9
//rcoulomb = 0.7
//nstfout = 1
//fourierspacing = 0.0625
//pme-order = 5
//ewald-rtol = 1.5E-2
//ewald-rtol-lj = 1.5E-2
//vdwtype = PME
//lj-pme-comb-rule = geometric
//continuation = yes
//------------------------------------------------
// dmf.gro
//------------------------------------------------
//Guyana Rwanda Oman Macau Angola Cameroon Senegal
// 12
// 101DMF HA 1 0.620 0.945 0.128
// 101DMF C 2 0.560 0.905 0.045
// 101DMF O 3 0.502 0.987 -0.026
// 101DMF N 4 0.556 0.770 0.028
// 101DMF CC 5 0.643 0.685 0.106
// 101DMF HC1 6 0.680 0.741 0.193
// 101DMF HC2 7 0.729 0.653 0.045
// 101DMF HC3 8 0.587 0.597 0.140
// 101DMF CT 9 0.477 0.708 -0.072
// 101DMF HT1 10 0.377 0.688 -0.032
// 101DMF HT2 11 0.524 0.614 -0.102
// 101DMF HT3 12 0.468 0.775 -0.158
// 2.00000 2.00000 2.00000
//------------------------------------------------
// dmf.top
//------------------------------------------------
//[ defaults ]
//; nbfunc comb-rule gen-pairs fudgeLJ fudgeQQ
//1 2 yes 1.0 1.0
//
//[ atomtypes ]
//HGR52 1 1.008000 0.000 A 0.160361769265 0.19246
//CG2O1 6 12.011000 0.000 A 0.356359487256 0.46024
//OG2D1 8 15.999400 0.000 A 0.302905564168 0.50208
//NG2S0 7 14.007000 0.000 A 0.329632525712 0.83680
//CG331 6 12.011000 0.000 A 0.365268474438 0.32635
// HGA3 1 1.008000 0.000 A 0.238760856462 0.10042
//
//[ pairtypes ]
//OG2D1 CG331 1 0.293996576986 0.144938011577
//
//[ bondtypes ]
//; i j func b0 kb
// CG2O1 HGR52 1 0.11000000 0.0000000000
// CG2O1 OG2D1 1 0.12300000 0.0000000000
// CG2O1 NG2S0 1 0.13500000 0.0000000000
// CG331 NG2S0 1 0.14340000 0.0000000000
// CG331 HGA3 1 0.11110000 0.0000000000
//
//[ angletypes ]
//; i j k func theta0 ktheta ub0 kub
// HGA3 CG331 HGA3 5 108.400000 0.0000000000000 0.18020000 0.0000000
// NG2S0 CG331 HGA3 5 105.000000 0.0000000000000 0.00000000 0.0000000
// CG331 NG2S0 CG331 5 121.000000 0.0000000000000 0.00000000 0.0000000
// CG2O1 NG2S0 CG331 5 119.500000 0.0000000000000 0.00000000 0.0000000
// NG2S0 CG2O1 OG2D1 5 124.000000 0.0000000000000 0.00000000 0.0000000
// NG2S0 CG2O1 HGR52 5 115.000000 0.0000000000000 0.00000000 0.0000000
// OG2D1 CG2O1 HGR52 5 122.000000 0.0000000000000 0.00000000 0.0000000
//
//[ dihedraltypes ]
//; i j k l func phi0 kphi mult
// OG2D1 CG2O1 NG2S0 CG331 9 180.000000 0.00000000 2
// HGR52 CG2O1 NG2S0 CG331 9 180.000000 0.00000000 2
// HGA3 CG331 NG2S0 CG331 9 0.000000 0.00000000 3
// HGA3 CG331 NG2S0 CG2O1 9 0.000000 0.00000000 3
//
//[ dihedraltypes ]
//; 'improper' dihedrals
//; i j k l func phi0 kphi
// CG2O1 NG2S0 OG2D1 HGR52 2 0.000000 0.0000000
//
//[ moleculetype ]
//; Name nrexcl
//DMF 3
//
//[ atoms ]
//; nr type resnr residue atom cgnr charge mass typeB chargeB massB
//; residue 101 DMF rtp DMF q 0.0
// 1 HGR52 101 DMF HA 1 0.00 1.008 ; qtot 0.00
// 2 CG2O1 101 DMF C 2 0.00 12.011 ; qtot 0.00
// 3 OG2D1 101 DMF O 3 0.00 15.9994 ; qtot 0.00
// 4 NG2S0 101 DMF N 4 0.00 14.007 ; qtot 0.00
// 5 CG331 101 DMF CC 5 0.00 12.011 ; qtot 0.00
// 6 HGA3 101 DMF HC1 6 0.00 1.008 ; qtot 0.00
// 7 HGA3 101 DMF HC2 7 0.00 1.008 ; qtot 0.00
// 8 HGA3 101 DMF HC3 8 0.00 1.008 ; qtot 0.00
// 9 CG331 101 DMF CT 9 0.00 12.011 ; qtot 0.00
// 10 HGA3 101 DMF HT1 10 0.00 1.008 ; qtot 0.00
// 11 HGA3 101 DMF HT2 11 0.00 1.008 ; qtot 0.00
// 12 HGA3 101 DMF HT3 12 0.00 1.008 ; qtot 0
//
//[ bonds ]
//; ai aj funct c0 c1 c2 c3
// 1 2 1
// 2 3 1
// 2 4 1
// 4 5 1
// 4 9 1
// 5 6 1
// 5 7 1
// 5 8 1
// 9 10 1
// 9 11 1
// 9 12 1
//
//[ pairs ]
//; ai aj funct c0 c1 c2 c3
// 1 5 1
// 1 9 1
// 2 6 1
// 2 7 1
// 2 8 1
// 2 10 1
// 2 11 1
// 2 12 1
// 3 5 1
// 3 9 1
// 5 10 1
// 5 11 1
// 5 12 1
// 6 9 1
// 7 9 1
// 8 9 1
//
//[ angles ]
//; ai aj ak funct c0 c1 c2 c3
// 1 2 3 5
// 1 2 4 5
// 3 2 4 5
// 2 4 5 5
// 2 4 9 5
// 5 4 9 5
// 4 5 6 5
// 4 5 7 5
// 4 5 8 5
// 6 5 7 5
// 6 5 8 5
// 7 5 8 5
// 4 9 10 5
// 4 9 11 5
// 4 9 12 5
// 10 9 11 5
// 10 9 12 5
// 11 9 12 5
//
//[ dihedrals ]
//; ai aj ak al funct c0 c1 c2 c3 c4 c5
// 1 2 4 5 9
// 1 2 4 9 9
// 3 2 4 5 9
// 3 2 4 9 9
// 2 4 5 6 9
// 2 4 5 7 9
// 2 4 5 8 9
// 9 4 5 6 9
// 9 4 5 7 9
// 9 4 5 8 9
// 2 4 9 10 9
// 2 4 9 11 9
// 2 4 9 12 9
// 5 4 9 10 9
// 5 4 9 11 9
// 5 4 9 12 9
//
//[ dihedrals ]
//; ai aj ak al funct c0 c1 c2 c3
// 1 3 4 2 2
//
//[ system ]
//; Name
//DMF Monomer
//
//[ molecules ]
//; Compound #mols
//DMF 1
//
//
//run commands:-
//gmx_d grompp -c dmf.gro -p dmf.top -f dmf.mdp -o run.tpr
//gmx_d mdrun -s run.tpr -o traj.trr -pforce 1E-16 -debug
//gmx_d dump -f traj.trr
// Gromacs reference values. See inputs above.
refforces[ 0] = Vec3(-3.19942e+00, 2.19766e+01, 2.72861e-01);
refforces[ 1] = Vec3(-5.22879e+01, 2.82006e+02, -6.86534e+00);
refforces[ 2] = Vec3( 1.23583e+01, 7.31235e+01, 4.08375e+01);
refforces[ 3] = Vec3(-1.28656e-03, 1.14097e-03, 4.07527e-04);
refforces[ 4] = Vec3( 1.51942e+02, 5.65684e+01, 2.41818e+02);
refforces[ 5] = Vec3( 1.20290e+02, -1.65176e+02, 1.48309e+02);
refforces[ 6] = Vec3( 4.57022e+01, -1.65198e+01, 1.88824e+01);
refforces[ 7] = Vec3( 5.57228e+01, -5.68770e+01, 1.09979e+02);
refforces[ 8] = Vec3(-9.58422e+01, 4.41982e+01, -1.27887e+02);
refforces[ 9] = Vec3(-2.59754e+01, -1.42402e+01, -1.23475e+01);
refforces[10] = Vec3(-1.37259e+02, -7.97690e+01, -2.39814e+02);
refforces[11] = Vec3(-7.14520e+01, -1.45287e+02, -1.73189e+02);
State state = context.getState(State::Forces | State::Energy);
double energy = state.getPotentialEnergy();
const vector<Vec3>& forces = state.getForces();
ASSERT_EQUAL_TOL(refenergy, energy, 1E-4);
for (int n = 0; n < numAtoms; ++n)
// The forces on atom 3 are much smaller in magnitude to the others,
// which causes problems for testing in single precision
if(n != 3)
ASSERT_EQUAL_VEC(refforces[n], forces[n], 5E-4);
}
void testWater2DpmeEnergiesForcesWithExclusions() {
const double cutoff = 7.0*OpenMM::NmPerAngstrom;
const double alpha = 4.0124063605;
const double dalpha = 4.0124063605;
const int grid = 32;
NonbondedForce* forceField = new NonbondedForce();
vector<Vec3> positions;
vector<double> epsvals;
vector<double> sigvals;
vector<pair<int, int> > bonds;
System system;
const int numAtoms = 6;
double boxEdgeLength = 25*OpenMM::NmPerAngstrom;
make_waterbox(numAtoms, boxEdgeLength, forceField, positions, epsvals, sigvals, bonds, system, false);
forceField->setNonbondedMethod(OpenMM::NonbondedForce::LJPME);
forceField->createExceptionsFromBonds(bonds, 1.0, 1.0);
forceField->setPMEParameters(alpha, grid, grid, grid);
forceField->setLJPMEParameters(dalpha, grid, grid, grid);
forceField->setCutoffDistance(cutoff);
forceField->setUseSwitchingFunction(false);
forceField->setUseDispersionCorrection(false);
forceField->setReactionFieldDielectric(1.0);
system.addForce(forceField);
VerletIntegrator integrator(0.01);
Context context(system, integrator, platform);
context.setPositions(positions);
double refenergy = -7.78060e-01;
vector<Vec3> refforces(6);
// Gromacs reference values. See comments in testWater2DpmeEnergiesForcesNoExclusions() for details.
refforces[0] = Vec3( 3.15301e-01, -3.91114e-03, 9.48373e-01);
refforces[1] = Vec3(-4.74745e-02, -3.79846e-02, -5.69616e-02);
refforces[2] = Vec3(-7.16866e-02, -9.55931e-02, -1.43348e-01);
refforces[3] = Vec3(-1.78136e+00, -1.76696e+00, -1.70022e+00);
refforces[4] = Vec3( 1.19309e+00, 1.59080e+00, 7.95443e-01);
refforces[5] = Vec3( 3.92366e-01, 3.13897e-01, 1.56962e-01);
State state = context.getState(State::Forces | State::Energy);
double energy = state.getPotentialEnergy();
const vector<Vec3>& forces = state.getForces();
ASSERT_EQUAL_TOL(refenergy, energy, 1E-4);
for (int n = 0; n < numAtoms; ++n)
ASSERT_EQUAL_VEC(refforces[n], forces[n], 5E-4);
}
void testWater125DpmeVsLongCutoffNoExclusions() {
const double cutoff = 8.5*OpenMM::NmPerAngstrom;
const double alpha = 0.45*OpenMM::AngstromsPerNm;
const double dalpha = 0.45*OpenMM::AngstromsPerNm;
const int grid = 32;
NonbondedForce* forceField = new NonbondedForce();
vector<Vec3> positions;
vector<double> epsvals;
vector<double> sigvals;
vector<pair<int, int> > bonds;
System system;
const int numAtoms = 375;
double boxEdgeLength = 17.01*OpenMM::NmPerAngstrom;
make_waterbox(numAtoms, boxEdgeLength, forceField, positions, epsvals, sigvals, bonds, system, false);
forceField->setNonbondedMethod(OpenMM::NonbondedForce::LJPME);
forceField->setPMEParameters(alpha, grid, grid, grid);
forceField->setLJPMEParameters(dalpha, grid, grid, grid);
forceField->setCutoffDistance(cutoff);
forceField->setReactionFieldDielectric(1.0);
system.addForce(forceField);
VerletIntegrator integrator(0.01);
Context context(system, integrator, platform);
context.setPositions(positions);
State state = context.getState(State::Forces | State::Energy);
double energy = state.getPotentialEnergy();
//Gromacs reference values. See comments in testWater2DpmeEnergiesForcesNoExclusions() for details.
//Coordinates are from make_waterbox, and the .gro file looks like
//
//;define = -DNOCHARGE -DNOEXCLUDE
//define = -DNOCHARGE
//vdw-modifier = Potential-Shift
//rvdw = 1.15
//rlist = 1.15
//rcoulomb = 1.15
//fourierspacing = 0.04
//nstfout = 1
//pme-order = 5
//ewald-rtol = 1E-8
//ewald-rtol-lj = 1E-8
//vdwtype = PME
//lj-pme-comb-rule = geometric
//continuation = yes
double gromacs_energy = 5.63157e+05;
const vector<Vec3>& forces = state.getForces();
vector<Vec3> refforces(numAtoms);
refforces[ 0] = Vec3(-1.12446e+05, -2.71952e+05, -1.91471e+05);
refforces[ 1] = Vec3( 2.70479e+05, 6.61172e+04, 7.21277e+04);
refforces[ 2] = Vec3(-1.58058e+05, 2.05779e+05, 1.19292e+05);
refforces[ 3] = Vec3( 3.16438e+05, -1.27994e+05, 1.08811e+05);
refforces[ 4] = Vec3(-1.36520e+05, 1.93405e+05, 1.36521e+05);
refforces[ 5] = Vec3(-1.79957e+05, -6.54374e+04, -2.45393e+05);
refforces[ 6] = Vec3( 1.30626e+05, -1.36728e+05, 2.93833e+05);
refforces[ 7] = Vec3(-2.74564e+05, 8.02095e+04, -7.09524e+04);
refforces[ 8] = Vec3( 1.43952e+05, 5.64523e+04, -2.22980e+05);
refforces[ 9] = Vec3(-4.22852e+04, 2.14660e+04, -3.23254e+05);
refforces[ 10] = Vec3( 2.28059e+05, -4.44251e+04, 1.62898e+05);
refforces[ 11] = Vec3(-1.85776e+05, 2.29044e+04, 1.60326e+05);
refforces[ 12] = Vec3(-1.02075e+05, 3.27346e+05, 1.47993e+04);
refforces[ 13] = Vec3( 7.77195e+04, -1.44336e+05, 2.10959e+05);
refforces[ 14] = Vec3( 2.44142e+04, -1.83111e+05, -2.25837e+05);
refforces[ 15] = Vec3(-4.81843e+04, -2.72889e+05, -1.75068e+05);
refforces[ 16] = Vec3(-5.46666e+03, 2.18711e+04, 2.62456e+05);
refforces[ 17] = Vec3( 5.35890e+04, 2.51021e+05, -8.74311e+04);
refforces[ 18] = Vec3(-2.04721e+05, 1.58918e+05, 2.20448e+05);
refforces[ 19] = Vec3(-7.05932e+04, -1.64717e+05, -2.17659e+05);
refforces[ 20] = Vec3( 2.75339e+05, 5.73611e+03, -2.86718e+03);
refforces[ 21] = Vec3(-5.65480e+03, -2.81809e+05, -1.38358e+05);
refforces[ 22] = Vec3(-7.85576e+03, 2.25204e+05, -1.15217e+05);
refforces[ 23] = Vec3( 1.34846e+04, 5.66345e+04, 2.53512e+05);
refforces[ 24] = Vec3(-7.73167e+04, -4.43114e+04, 3.22354e+05);
refforces[ 25] = Vec3(-1.24372e+05, 1.61973e+05, -1.88001e+05);
refforces[ 26] = Vec3( 2.01689e+05, -1.17651e+05, -1.34455e+05);
refforces[ 27] = Vec3(-1.79300e+05, -1.97922e+05, 1.94294e+05);
refforces[ 28] = Vec3( 2.38945e+05, -4.88761e+04, -9.50350e+04);
refforces[ 29] = Vec3(-5.95911e+04, 2.46878e+05, -9.93159e+04);
refforces[ 30] = Vec3(-1.31892e+04, -2.15675e+05, 2.68757e+05);
refforces[ 31] = Vec3( 2.31232e+05, 1.08107e+05, -1.32129e+05);
refforces[ 32] = Vec3(-2.18089e+05, 1.07592e+05, -1.36669e+05);
refforces[ 33] = Vec3( 1.90632e+04, -3.62889e+05, 8.61608e+04);
refforces[ 34] = Vec3(-2.16178e+05, 1.59639e+05, -1.66288e+05);
refforces[ 35] = Vec3( 1.97134e+05, 2.03295e+05, 8.00862e+04);
refforces[ 36] = Vec3( 3.40071e+05, -6.87734e+04, 1.22584e+05);
refforces[ 37] = Vec3(-4.17943e+04, 8.35901e+03, -2.64693e+05);
refforces[ 38] = Vec3(-2.98358e+05, 6.03813e+04, 1.42075e+05);
refforces[ 39] = Vec3(-3.21693e+05, 4.40885e+04, 1.41154e+04);
refforces[ 40] = Vec3( 1.28817e+05, 2.02067e+04, -2.07114e+05);
refforces[ 41] = Vec3( 1.92948e+05, -6.43160e+04, 1.92949e+05);
refforces[ 42] = Vec3(-1.46001e+05, 3.20840e+05, 7.97305e+04);
refforces[ 43] = Vec3(-1.27705e+05, -2.55411e+05, -1.24428e+05);
refforces[ 44] = Vec3( 2.73737e+05, -6.54594e+04, 4.46323e+04);
refforces[ 45] = Vec3( 1.50212e+04, 2.43629e+05, -2.20084e+05);
refforces[ 46] = Vec3(-1.07432e+05, 8.26408e+03, 2.42419e+05);
refforces[ 47] = Vec3( 9.23685e+04, -2.51915e+05, -2.23909e+04);
refforces[ 48] = Vec3( 3.14327e+04, -2.94199e+05, 1.55484e+05);
refforces[ 49] = Vec3(-2.23665e+05, 1.52883e+05, -2.54793e+04);
refforces[ 50] = Vec3( 1.92227e+05, 1.41342e+05, -1.30033e+05);
refforces[ 51] = Vec3( 5.73542e+04, -2.08689e+05, -2.68170e+05);
refforces[ 52] = Vec3(-2.26784e+05, 1.85259e+05, 8.30474e+04);
refforces[ 53] = Vec3( 1.69446e+05, 2.34613e+04, 1.85087e+05);
refforces[ 54] = Vec3( 2.25490e+05, -1.91311e+05, -1.40103e+05);
refforces[ 55] = Vec3(-8.20802e+03, 6.83988e+04, 2.54448e+05);
refforces[ 56] = Vec3(-2.17315e+05, 1.22953e+05, -1.14373e+05);
refforces[ 57] = Vec3(-7.09510e+04, 2.05639e+05, -2.69540e+05);
refforces[ 58] = Vec3( 1.93603e+05, 3.38041e+04, 2.18192e+05);
refforces[ 59] = Vec3(-1.22579e+05, -2.39458e+05, 5.13124e+04);
refforces[ 60] = Vec3(-1.07250e+05, 3.35982e+05, 6.89600e+03);
refforces[ 61] = Vec3( 6.90672e-01, -1.44228e+05, -2.24659e+05);
refforces[ 62] = Vec3( 1.07222e+05, -1.91701e+05, 2.17695e+05);
refforces[ 63] = Vec3( 2.64846e+05, 1.94002e+05, 5.27262e+03);
refforces[ 64] = Vec3(-1.12985e+04, -2.71176e+05, 8.47510e+03);
refforces[ 65] = Vec3(-2.53630e+05, 7.71894e+04, -1.37831e+04);
refforces[ 66] = Vec3(-3.04551e+05, 4.21918e+04, 1.88948e+05);
refforces[ 67] = Vec3( 2.87326e+05, 1.22193e+05, 3.30263e+04);
refforces[ 68] = Vec3( 1.73006e+04, -1.64358e+05, -2.22023e+05);
refforces[ 69] = Vec3( 2.45556e+04, 2.20596e+05, 2.41913e+05);
refforces[ 70] = Vec3( 1.50804e+05, -2.17829e+05, -4.46813e+04);
refforces[ 71] = Vec3(-1.75369e+05, -2.74087e+03, -1.97287e+05);
refforces[ 72] = Vec3( 8.65787e+04, -2.77188e+04, -3.15014e+05);
refforces[ 73] = Vec3(-2.42127e+05, 6.26659e+04, 1.11092e+05);
refforces[ 74] = Vec3( 1.55591e+05, -3.48752e+04, 2.03883e+05);
refforces[ 75] = Vec3( 7.06224e+04, 2.96642e+05, -1.51267e+05);
refforces[ 76] = Vec3(-5.39280e+04, -2.57657e+05, -1.13850e+05);
refforces[ 77] = Vec3(-1.67422e+04, -3.90659e+04, 2.65102e+05);
refforces[ 78] = Vec3(-4.52577e+04, -3.21552e+05, -7.01075e+04);
refforces[ 79] = Vec3( 2.35182e+05, 1.45173e+05, 3.48411e+04);
refforces[ 80] = Vec3(-1.89931e+05, 1.76363e+05, 3.52722e+04);
refforces[ 81] = Vec3(-2.29347e+05, 1.06977e+05, -2.70703e+05);
refforces[ 82] = Vec3(-1.17929e+04, -2.56493e+05, 1.17929e+05);
refforces[ 83] = Vec3( 2.41161e+05, 1.49452e+05, 1.52847e+05);
refforces[ 84] = Vec3( 2.32633e+03, 3.03443e+05, 1.27473e+05);
refforces[ 85] = Vec3(-2.11215e+05, -1.63335e+05, -4.50583e+04);
refforces[ 86] = Vec3( 2.08887e+05, -1.40170e+05, -8.24544e+04);
refforces[ 87] = Vec3( 5.83172e+04, 2.82133e+04, -3.26001e+05);
refforces[ 88] = Vec3( 1.76890e+05, -4.71698e+04, 2.15220e+05);
refforces[ 89] = Vec3(-2.35168e+05, 1.89225e+04, 1.10825e+05);
refforces[ 90] = Vec3(-2.72444e+05, -1.46998e+05, -1.00637e+05);
refforces[ 91] = Vec3( 2.78426e+04, 2.39442e+05, 1.16936e+05);
refforces[ 92] = Vec3( 2.44570e+05, -9.23920e+04, -1.63042e+04);
refforces[ 93] = Vec3(-3.10100e+04, 2.93390e+05, -1.87196e+05);
refforces[ 94] = Vec3(-6.38830e+04, -2.90671e+05, -6.38833e+04);
refforces[ 95] = Vec3( 9.48775e+04, -2.79002e+03, 2.51149e+05);
refforces[ 96] = Vec3( 4.18753e+04, -1.23438e+05, -3.10188e+05);
refforces[ 97] = Vec3( 1.29157e+05, 2.04500e+05, 9.41770e+04);
refforces[ 98] = Vec3(-1.71038e+05, -8.10180e+04, 2.16049e+05);
refforces[ 99] = Vec3(-5.61490e+04, 2.26993e+04, -3.44090e+05);
refforces[100] = Vec3(-1.96230e+05, -2.88572e+04, 1.93344e+05);
refforces[101] = Vec3( 2.52383e+05, 6.15570e+03, 1.50813e+05);
refforces[102] = Vec3(-6.33126e+04, 3.55941e+05, 8.51300e+04);
refforces[103] = Vec3(-1.75405e+05, -1.81783e+05, -1.69027e+05);
refforces[104] = Vec3( 2.38759e+05, -1.74232e+05, 8.38891e+04);
refforces[105] = Vec3( 1.51480e+05, -4.90606e+04, 3.17956e+05);
refforces[106] = Vec3( 4.93229e+04, -1.61668e+05, -2.02771e+05);
refforces[107] = Vec3(-2.00831e+05, 2.10712e+05, -1.15233e+05);
refforces[108] = Vec3( 2.20204e+05, -2.33820e+05, 1.51386e+05);
refforces[109] = Vec3( 3.36498e+04, 2.79296e+05, -1.51424e+05);
refforces[110] = Vec3(-2.53896e+05, -4.54334e+04, 2.10242e-01);
refforces[111] = Vec3(-1.94665e+05, 2.05890e+05, 2.40510e+05);
refforces[112] = Vec3(-9.73233e+04, -1.29764e+05, -2.62775e+05);
refforces[113] = Vec3( 2.92049e+05, -7.61856e+04, 2.22208e+04);
refforces[114] = Vec3( 1.60261e+05, -3.43716e+05, 1.52456e+04);
refforces[115] = Vec3( 1.11151e+05, 3.08358e+05, -8.60527e+04);
refforces[116] = Vec3(-2.71443e+05, 3.54056e+04, 7.08103e+04);
refforces[117] = Vec3(-4.27331e+04, -3.19871e+05, -1.68415e+05);
refforces[118] = Vec3( 2.28408e+05, 2.15171e+05, -2.31720e+04);
refforces[119] = Vec3(-1.85616e+05, 1.04782e+05, 1.91602e+05);
refforces[120] = Vec3(-1.66057e+05, -9.58191e+04, -2.78448e+05);
refforces[121] = Vec3( 1.91258e+05, 2.19476e+05, 6.89779e+04);
refforces[122] = Vec3(-2.52379e+04, -1.23674e+05, 2.09489e+05);
refforces[123] = Vec3( 6.55172e+03, -9.23173e+04, 3.29554e+05);
refforces[124] = Vec3(-2.14685e+05, 1.13143e+05, -1.36353e+05);
refforces[125] = Vec3( 2.08124e+05, -2.08124e+04, -1.93257e+05);
refforces[126] = Vec3( 1.02696e+05, -3.39299e+05, -4.47114e+04);
refforces[127] = Vec3(-1.81786e+05, 1.75407e+05, -1.69029e+05);
refforces[128] = Vec3( 7.90534e+04, 1.63962e+05, 2.13738e+05);
refforces[129] = Vec3(-3.45588e+05, 9.36838e+04, 5.67939e+04);
refforces[130] = Vec3( 1.44967e+05, -2.60943e+05, 7.08730e+04);
refforces[131] = Vec3( 2.00649e+05, 1.67207e+05, -1.27685e+05);
refforces[132] = Vec3(-2.70181e+05, 2.05707e+05, -3.11852e+04);
refforces[133] = Vec3( 1.09331e+05, -1.83207e+05, -1.86162e+05);
refforces[134] = Vec3( 1.60883e+05, -2.25804e+04, 2.17340e+05);
refforces[135] = Vec3(-1.04496e+05, -2.97000e+05, -1.63733e+05);
refforces[136] = Vec3( 2.11303e+05, 1.73661e+04, 1.79462e+05);
refforces[137] = Vec3(-1.06849e+05, 2.79694e+05, -1.57134e+04);
refforces[138] = Vec3(-3.82271e+04, 2.11942e+05, 2.60118e+05);
refforces[139] = Vec3(-1.96098e+05, -1.23692e+05, -1.71962e+05);
refforces[140] = Vec3( 2.34334e+05, -8.82195e+04, -8.82188e+04);
refforces[141] = Vec3( 2.17634e+05, 2.72527e+05, 1.42967e+05);
refforces[142] = Vec3( 9.30924e+04, -1.86185e+05, -1.98197e+05);
refforces[143] = Vec3(-3.10770e+05, -8.63246e+04, 5.52480e+04);
refforces[144] = Vec3(-1.63880e+05, -2.98869e+05, 1.01299e+05);
refforces[145] = Vec3( 6.83424e+04, 2.39196e+05, 1.61538e+05);
refforces[146] = Vec3( 9.55787e+04, 5.97354e+04, -2.62846e+05);
refforces[147] = Vec3( 1.06430e+05, -2.97083e+05, -7.97261e+04);
refforces[148] = Vec3(-1.14920e+05, 6.41394e+04, 2.21823e+05);
refforces[149] = Vec3( 8.52531e+03, 2.33043e+05, -1.42101e+05);
refforces[150] = Vec3(-4.96390e+04, -4.12076e+04, -3.67834e+05);
refforces[151] = Vec3( 1.25352e+05, -1.99962e+05, 1.61166e+05);
refforces[152] = Vec3(-7.57841e+04, 2.41138e+05, 2.06689e+05);
refforces[153] = Vec3(-3.06397e+05, -5.15222e+04, -1.37080e+05);
refforces[154] = Vec3( 1.92949e+05, -1.92945e+05, 6.43163e+04);
refforces[155] = Vec3( 1.13490e+05, 2.44443e+05, 7.27504e+04);
refforces[156] = Vec3(-3.74471e+03, 3.83223e+05, -2.14754e+04);
refforces[157] = Vec3( 2.17881e+05, -1.85835e+05, -1.05735e+05);
refforces[158] = Vec3(-2.14191e+05, -1.97454e+05, 1.27176e+05);
refforces[159] = Vec3(-3.33357e+05, -1.38307e+04, -1.17320e+05);
refforces[160] = Vec3( 2.04157e+05, -9.93173e+04, -1.37945e+05);
refforces[161] = Vec3( 1.29262e+05, 1.13105e+05, 2.55294e+05);
refforces[162] = Vec3( 2.50185e+05, 2.64217e+05, -7.18219e+04);
refforces[163] = Vec3(-2.46668e+05, 1.94013e+04, -9.97745e+04);
refforces[164] = Vec3(-3.50266e+03, -2.83658e+05, 1.71598e+05);
refforces[165] = Vec3(-2.05824e+05, 2.71177e+05, -1.16442e+05);
refforces[166] = Vec3(-3.52163e+04, -1.88897e+05, 2.36923e+05);
refforces[167] = Vec3( 2.41012e+05, -8.22954e+04, -1.20505e+05);
refforces[168] = Vec3( 6.89329e+04, 2.09489e+05, 2.76583e+05);
refforces[169] = Vec3( 1.87999e+05, -1.61968e+05, -1.24368e+05);
refforces[170] = Vec3(-2.56932e+05, -4.75793e+04, -1.52255e+05);
refforces[171] = Vec3( 3.39431e+05, -5.75509e+04, 1.62795e+05);
refforces[172] = Vec3(-1.27767e+05, 2.66184e+05, -1.59709e+05);
refforces[173] = Vec3(-2.11726e+05, -2.08613e+05, -3.11349e+03);
refforces[174] = Vec3(-2.58601e+05, 4.61975e+04, -2.46016e+05);
refforces[175] = Vec3( 7.15587e+04, -2.52015e+05, 1.40007e+05);
refforces[176] = Vec3( 1.87109e+05, 2.05820e+05, 1.06028e+05);
refforces[177] = Vec3( 3.92176e+03, 2.94819e+05, -1.84065e+05);
refforces[178] = Vec3(-1.67230e+05, -8.36141e+04, 2.29167e+05);
refforces[179] = Vec3( 1.63334e+05, -2.11213e+05, -4.50586e+04);
refforces[180] = Vec3( 1.11151e+05, 2.40551e+05, -2.68210e+05);
refforces[181] = Vec3(-1.76495e+05, -2.47099e+05, -3.53002e+04);
refforces[182] = Vec3( 6.52872e+04, 6.52855e+03, 3.03586e+05);
refforces[183] = Vec3(-4.84049e+04, -2.73305e+05, -2.95224e+05);
refforces[184] = Vec3(-9.04206e+04, -1.44672e+04, 3.29135e+05);
refforces[185] = Vec3( 1.38830e+05, 2.87820e+05, -3.38610e+04);
refforces[186] = Vec3(-2.09072e+05, -1.53610e+05, -2.86654e+05);
refforces[187] = Vec3(-1.30322e+05, 9.09223e+04, 2.42461e+05);
refforces[188] = Vec3( 3.39380e+05, 6.27113e+04, 4.42669e+04);
refforces[189] = Vec3(-3.15692e+05, 1.48900e+05, -9.20420e+04);
refforces[190] = Vec3( 7.13687e+04, -2.72503e+05, 1.26518e+05);
refforces[191] = Vec3( 2.44351e+05, 1.23612e+05, -3.44964e+04);
refforces[192] = Vec3(-2.80727e+04, 3.15077e+05, -2.05427e+05);
refforces[193] = Vec3(-2.29004e+05, -2.08496e+05, 9.57028e+04);
refforces[194] = Vec3( 2.57096e+05, -1.06603e+05, 1.09738e+05);
refforces[195] = Vec3( 3.33213e+05, -7.80040e+04, -5.04749e+03);
refforces[196] = Vec3(-2.07680e+05, -7.82574e+04, 1.83605e+05);
refforces[197] = Vec3(-1.25574e+05, 1.56274e+05, -1.78599e+05);
refforces[198] = Vec3( 2.66795e+05, -2.82879e+04, -2.26620e+05);
refforces[199] = Vec3(-2.28291e+05, -1.82015e+05, 4.01046e+04);
refforces[200] = Vec3(-3.85027e+04, 2.10288e+05, 1.86592e+05);
refforces[201] = Vec3( 1.93076e+05, 2.05300e+05, 2.64591e+05);
refforces[202] = Vec3(-3.32259e+05, -3.65117e+04, -8.39768e+04);
refforces[203] = Vec3( 1.39204e+05, -1.68822e+05, -1.80669e+05);
refforces[204] = Vec3( 2.15422e+05, 2.88264e+05, 2.49786e+04);
refforces[205] = Vec3( 4.29235e+04, -2.66744e+05, 1.13441e+05);
refforces[206] = Vec3(-2.58339e+05, -2.15280e+04, -1.38395e+05);
refforces[207] = Vec3( 3.27580e+05, -4.93781e+04, 7.43625e+03);
refforces[208] = Vec3(-2.11622e+05, -1.58716e+05, -9.69925e+04);
refforces[209] = Vec3(-1.15917e+05, 2.08125e+05, 8.95715e+04);
refforces[210] = Vec3( 1.10967e+05, -2.71544e+05, -2.06279e+05);
refforces[211] = Vec3(-8.86155e+04, 1.96918e+04, 2.98676e+05);
refforces[212] = Vec3(-2.23913e+04, 2.51912e+05, -9.23690e+04);
refforces[213] = Vec3( 1.91611e+05, -7.99998e+04, -2.83463e+05);
refforces[214] = Vec3( 7.08725e+04, 1.44963e+05, 2.60941e+05);
refforces[215] = Vec3(-2.62503e+05, -6.49202e+04, 2.25808e+04);
refforces[216] = Vec3(-6.63168e+04, -2.84265e+04, 3.72700e+05);
refforces[217] = Vec3(-2.02131e+05, -6.33547e+04, -1.96097e+05);
refforces[218] = Vec3( 2.68466e+05, 9.18414e+04, -1.76621e+05);
refforces[219] = Vec3(-6.80052e+03, 2.72744e+05, -2.21849e+05);
refforces[220] = Vec3( 1.52709e+05, -5.52356e+04, 2.63181e+05);
refforces[221] = Vec3(-1.45890e+05, -2.17461e+05, -4.12893e+04);
refforces[222] = Vec3( 3.07522e+05, -1.21146e+05, 1.14593e+05);
refforces[223] = Vec3(-2.11787e+05, -1.56664e+05, -8.99363e+04);
refforces[224] = Vec3(-9.57076e+04, 2.77857e+05, -2.46987e+04);
refforces[225] = Vec3(-3.24882e+05, -3.09840e+04, -1.31947e+05);
refforces[226] = Vec3( 8.33124e+04, -5.05809e+04, 2.67793e+05);
refforces[227] = Vec3( 2.41536e+05, 8.15185e+04, -1.35863e+05);
refforces[228] = Vec3(-2.16561e+04, -1.67607e+05, -2.70252e+05);
refforces[229] = Vec3( 1.10825e+05, -7.29802e+04, 2.24354e+05);
refforces[230] = Vec3(-8.91995e+04, 2.40572e+05, 4.59512e+04);
refforces[231] = Vec3(-2.22246e+05, 1.96766e+05, -2.46638e+05);
refforces[232] = Vec3( 3.04748e+05, 5.66971e+04, 1.27568e+05);
refforces[233] = Vec3(-8.24632e+04, -2.53495e+05, 1.19113e+05);
refforces[234] = Vec3( 2.20621e+05, -2.03896e+05, 6.63128e+04);
refforces[235] = Vec3(-9.59082e+04, 1.64055e+05, 1.53960e+05);
refforces[236] = Vec3(-1.24758e+05, 3.98170e+04, -2.20320e+05);
refforces[237] = Vec3(-7.79583e+03, -3.49688e+04, 3.64330e+05);
refforces[238] = Vec3(-1.43293e+05, -1.65580e+05, -2.10163e+05);
refforces[239] = Vec3( 1.51159e+05, 2.00522e+05, -1.54247e+05);
refforces[240] = Vec3( 1.82058e+05, -3.72909e+04, -2.80373e+05);
refforces[241] = Vec3(-1.95792e+05, 1.98809e+05, 7.22936e+04);
refforces[242] = Vec3( 1.36910e+04, -1.61546e+05, 2.08094e+05);
refforces[243] = Vec3( 1.40288e+05, 3.27379e+05, 4.78569e+03);
refforces[244] = Vec3(-1.70016e+05, -1.73349e+05, 2.03353e+05);
refforces[245] = Vec3( 2.97331e+04, -1.54072e+05, -2.08134e+05);
refforces[246] = Vec3( 1.21932e+05, 3.52267e+05, 4.69291e+04);
refforces[247] = Vec3(-2.91621e+05, -1.24021e+05, 3.01674e+04);
refforces[248] = Vec3( 1.69673e+05, -2.28288e+05, -7.71238e+04);
refforces[249] = Vec3(-1.41105e+05, 1.52818e+05, 2.59197e+05);
refforces[250] = Vec3( 2.15511e+05, -1.77650e+05, -5.82442e+03);
refforces[251] = Vec3(-7.43779e+04, 2.47926e+04, -2.53438e+05);
refforces[252] = Vec3(-3.34214e+04, 3.09554e+05, 1.58194e+05);
refforces[253] = Vec3(-2.05877e+05, -1.71563e+05, -6.00467e+04);
refforces[254] = Vec3( 2.39329e+05, -1.38076e+05, -9.81875e+04);
refforces[255] = Vec3( 1.32793e+05, -3.72271e+05, 2.88491e+04);
refforces[256] = Vec3(-9.02633e+04, 2.78646e+05, 2.23700e+05);
refforces[257] = Vec3(-4.25632e+04, 9.36427e+04, -2.52553e+05);
refforces[258] = Vec3( 2.97252e+05, 2.17294e+05, -2.50945e+03);
refforces[259] = Vec3(-1.35724e+05, -1.48966e+05, 2.41658e+05);
refforces[260] = Vec3(-1.61536e+05, -6.83423e+04, -2.39199e+05);
refforces[261] = Vec3( 2.50550e+05, -1.39926e+05, 2.48375e+05);
refforces[262] = Vec3( 5.51783e+04, -1.65530e+04, -2.59341e+05);
refforces[263] = Vec3(-3.05734e+05, 1.56505e+05, 1.09189e+04);
refforces[264] = Vec3(-4.44616e+04, 4.17040e+04, -3.31507e+05);
refforces[265] = Vec3(-1.79702e+05, -8.54319e+04, 2.00323e+05);
refforces[266] = Vec3( 2.24182e+05, 4.37421e+04, 1.31227e+05);
refforces[267] = Vec3(-9.89367e+04, -3.76136e+05, 2.17157e+04);
refforces[268] = Vec3(-4.44424e+04, 1.68244e+05, -2.47606e+05);
refforces[269] = Vec3( 1.43421e+05, 2.07965e+05, 2.25893e+05);
refforces[270] = Vec3(-1.09030e+03, -2.44686e+05, -2.30145e+05);
refforces[271] = Vec3(-1.86963e+05, 1.89757e+05, 3.34863e+04);
refforces[272] = Vec3( 1.88003e+05, 5.49541e+04, 1.96680e+05);
refforces[273] = Vec3(-1.15452e+05, -1.55243e+05, 2.81412e+05);
refforces[274] = Vec3(-1.35893e+05, 1.74355e+05, -1.12817e+05);
refforces[275] = Vec3( 2.51361e+05, -1.90905e+04, -1.68633e+05);
refforces[276] = Vec3( 1.76202e+05, -2.31601e+05, -2.00886e+05);
refforces[277] = Vec3(-2.96697e+05, 3.00025e+04, 1.06676e+05);
refforces[278] = Vec3( 1.20457e+05, 2.01635e+05, 9.42700e+04);
refforces[279] = Vec3(-1.66320e+05, -9.08355e+02, 2.65478e+05);
refforces[280] = Vec3( 2.44823e+05, 9.45895e+04, -5.28589e+04);
refforces[281] = Vec3(-7.84765e+04, -9.36654e+04, -2.12648e+05);
refforces[282] = Vec3(-6.58002e+03, -1.21918e+05, 3.16459e+05);
refforces[283] = Vec3( 2.15225e+05, 5.96416e+04, -1.14097e+05);
refforces[284] = Vec3(-2.08615e+05, 6.22725e+04, -2.02387e+05);
refforces[285] = Vec3( 7.09186e+04, 1.83619e+05, 2.71862e+05);
refforces[286] = Vec3( 1.78911e+05, -1.02234e+05, -1.78910e+05);
refforces[287] = Vec3(-2.49882e+05, -8.13582e+04, -9.29803e+04);
refforces[288] = Vec3(-1.35529e+04, -3.20226e+05, -1.16293e+05);
refforces[289] = Vec3( 2.28053e+05, 1.65034e+05, 5.70125e+04);
refforces[290] = Vec3(-2.14515e+05, 1.55237e+05, 5.92732e+04);
refforces[291] = Vec3(-2.65006e+05, 1.75233e+05, 1.91268e+05);
refforces[292] = Vec3( 2.29905e+05, 1.02940e+05, -2.05886e+05);
refforces[293] = Vec3( 3.51345e+04, -2.78156e+05, 1.46393e+04);
refforces[294] = Vec3( 1.59458e+05, 2.25128e+05, 2.11611e+05);
refforces[295] = Vec3( 1.24813e+05, -1.16492e+05, -2.05249e+05);
refforces[296] = Vec3(-2.84281e+05, -1.08601e+05, -6.38824e+03);
refforces[297] = Vec3( 2.61767e+05, -7.55993e+04, -2.32576e+05);
refforces[298] = Vec3(-2.07803e+05, -1.78116e+05, 7.71831e+04);
refforces[299] = Vec3(-5.39242e+04, 2.53755e+05, 1.55427e+05);
refforces[300] = Vec3(-6.44117e+03, 2.31328e+05, -2.54922e+05);
refforces[301] = Vec3(-2.61097e+04, 4.93208e+04, 2.72709e+05);
refforces[302] = Vec3( 3.25053e+04, -2.80718e+05, -1.77304e+04);
refforces[303] = Vec3( 7.06280e+04, 7.26140e+04, 3.28446e+05);
refforces[304] = Vec3( 1.45890e+05, 7.98271e+04, -2.06449e+05);
refforces[305] = Vec3(-2.16516e+05, -1.52473e+05, -1.21980e+05);
refforces[306] = Vec3( 1.94879e+05, -2.83084e+05, 1.41824e+05);
refforces[307] = Vec3(-2.57149e+05, 1.96432e+05, 9.64284e+04);
refforces[308] = Vec3( 6.22633e+04, 8.66280e+04, -2.38228e+05);
refforces[309] = Vec3( 3.26456e+04, 1.17141e+05, -3.28374e+05);
refforces[310] = Vec3( 2.01298e+05, -1.11486e+05, 1.85810e+05);
refforces[311] = Vec3(-2.33937e+05, -5.70482e+03, 1.42641e+05);
refforces[312] = Vec3( 6.42964e+04, 1.88719e+05, -2.86572e+05);
refforces[313] = Vec3( 1.22184e+05, -2.53768e+05, 1.00254e+05);
refforces[314] = Vec3(-1.86433e+05, 6.49694e+04, 1.86429e+05);
refforces[315] = Vec3(-4.12317e+04, -1.73607e+04, -3.68620e+05);
refforces[316] = Vec3(-1.78981e+05, 1.43186e+05, 2.08269e+05);
refforces[317] = Vec3( 2.20155e+05, -1.25802e+05, 1.60395e+05);
refforces[318] = Vec3(-1.58613e+05, 3.01594e+05, -1.29345e+05);
refforces[319] = Vec3( 2.79698e+05, -2.67790e+04, 4.76063e+04);
refforces[320] = Vec3(-1.21063e+05, -2.74847e+05, 8.17976e+04);
refforces[321] = Vec3( 1.00451e+05, 2.03427e+05, -2.75044e+05);
refforces[322] = Vec3(-2.13956e+04, 7.64144e+04, 2.81199e+05);
refforces[323] = Vec3(-7.91039e+04, -2.79910e+05, -6.08590e+03);
refforces[324] = Vec3(-2.80664e+05, 5.26142e+04, -1.53706e+05);
refforces[325] = Vec3( 2.23923e+05, -1.17559e+05, -9.23685e+04);
refforces[326] = Vec3( 5.68062e+04, 6.49218e+04, 2.46158e+05);
refforces[327] = Vec3( 2.88911e+05, -1.17893e+05, -7.40828e+04);
refforces[328] = Vec3(-6.38612e+04, 2.37565e+05, -2.55450e+04);
refforces[329] = Vec3(-2.25033e+05, -1.19637e+05, 9.96952e+04);
refforces[330] = Vec3( 1.03510e+04, 7.35559e+04, 3.47129e+05);
refforces[331] = Vec3( 1.26778e+05, -2.19542e+05, -1.51515e+05);
refforces[332] = Vec3(-1.37190e+05, 1.45950e+05, -1.95573e+05);
refforces[333] = Vec3(-1.31816e+05, 5.57951e+04, -2.81935e+05);
refforces[334] = Vec3(-1.08367e+05, -9.75306e+04, 2.16731e+05);
refforces[335] = Vec3( 2.40191e+05, 4.17715e+04, 6.52667e+04);
refforces[336] = Vec3(-2.86680e+05, -2.63007e+05, 1.37964e+04);
refforces[337] = Vec3( 1.03914e+05, 1.76653e+05, -2.56324e+05);
refforces[338] = Vec3( 1.82779e+05, 8.64040e+04, 2.42594e+05);
refforces[339] = Vec3( 1.09800e+03, -3.11636e+05, 1.85833e+05);
refforces[340] = Vec3(-2.39750e+05, 1.52568e+05, -8.71817e+04);
refforces[341] = Vec3( 2.38635e+05, 1.59089e+05, -9.86351e+04);
refforces[342] = Vec3(-8.76706e+04, -6.10520e+04, 3.31680e+05);
refforces[343] = Vec3( 2.64692e+05, 5.23233e+04, -1.16959e+05);
refforces[344] = Vec3(-1.76973e+05, 8.70353e+03, -2.14689e+05);
refforces[345] = Vec3(-1.15976e+05, -2.72303e+05, -1.33307e+05);
refforces[346] = Vec3( 2.20682e+05, 1.51896e+05, -6.30516e+04);
refforces[347] = Vec3(-1.04744e+05, 1.20457e+05, 1.96395e+05);
refforces[348] = Vec3( 4.57064e+04, 3.43550e+05, 7.23245e+04);
refforces[349] = Vec3(-1.91414e+05, -1.26580e+05, -1.85241e+05);
refforces[350] = Vec3( 1.45684e+05, -2.17040e+05, 1.12977e+05);
refforces[351] = Vec3(-1.88623e+05, -1.22936e+04, 3.10223e+05);
refforces[352] = Vec3( 3.06931e+05, 5.73380e+04, -7.08300e+04);
refforces[353] = Vec3(-1.18279e+05, -4.50586e+04, -2.39376e+05);
refforces[354] = Vec3( 8.31603e+04, -2.75958e+05, 1.16877e+05);
refforces[355] = Vec3(-2.08784e+05, 1.26300e+05, 5.15494e+04);
refforces[356] = Vec3( 1.25608e+05, 1.49661e+05, -1.68370e+05);
refforces[357] = Vec3( 1.44100e+05, -2.34453e+05, 1.73916e+05);
refforces[358] = Vec3(-8.65072e+04, 2.39988e+05, 8.37141e+04);
refforces[359] = Vec3(-5.75432e+04, -5.48037e+03, -2.57574e+05);
refforces[360] = Vec3( 2.72504e+05, 2.99781e+04, 1.85778e+05);
refforces[361] = Vec3(-3.41026e+04, 7.10483e+04, -2.61466e+05);
refforces[362] = Vec3(-2.38458e+05, -1.00996e+05, 7.57451e+04);
refforces[363] = Vec3( 1.45826e+05, -2.81284e+05, 1.15502e+05);
refforces[364] = Vec3(-2.63407e+05, 3.47332e+04, -8.10477e+04);
refforces[365] = Vec3( 1.17594e+05, 2.46657e+05, -3.44181e+04);
refforces[366] = Vec3( 2.59381e+05, -5.73297e+04, 2.56690e+05);
refforces[367] = Vec3(-1.25834e+05, -2.09725e+05, -1.49803e+05);
refforces[368] = Vec3(-1.33554e+05, 2.67105e+05, -1.06844e+05);
refforces[369] = Vec3( 7.18473e+04, -2.59021e+05, 1.89797e+05);
refforces[370] = Vec3( 1.56664e+05, 2.11783e+05, -8.99369e+04);
refforces[371] = Vec3(-2.28511e+05, 4.72761e+04, -9.98083e+04);
refforces[372] = Vec3(-1.99083e+04, 3.17042e+05, -5.62792e+04);
refforces[373] = Vec3(-1.96875e+05, -1.64948e+05, -7.96758e-01);
refforces[374] = Vec3( 2.16840e+05, -1.52072e+05, 5.63215e+04);
const double longcutoff = 30.0*OpenMM::NmPerAngstrom;
const double longcutoff2 = longcutoff*longcutoff;
const double cutoff2 = cutoff*cutoff;
const double cutoff6inv = 1.0 / (cutoff2*cutoff2*cutoff2);
const int nboxes = ceil(longcutoff/boxEdgeLength);
double refenergy = 0.0;
// Loop over home box first...
for (int i = 0; i < numAtoms; ++ i) {
for (int j = i+1; j < numAtoms; ++j) {
Vec3 dR = positions[i] - positions[j];
double R2 = dR[0]*dR[0] + dR[1]*dR[1] + dR[2]*dR[2];
double sig2 = (sigvals[i] + sigvals[j])*(sigvals[i] + sigvals[j]) / R2;
double sig6 = sig2*sig2*sig2;
double eps = epsvals[i]*epsvals[j];
refenergy += 2.0*eps*(sig6-1.0)*sig6;
if (R2 < cutoff2) {
// Add a shift term for direct space parts withing t
refenergy += 2.0*eps*(pow(sigvals[i]+sigvals[j], 6) - 64.0*pow(sigvals[i]*sigvals[j], 3))*cutoff6inv;
}
}
}
// ... and now add in the image box terms
for (int bx = -nboxes; bx <= nboxes; ++bx) {
for (int by = -nboxes; by <= nboxes; ++by) {
for (int bz = -nboxes; bz <= nboxes; ++bz) {
if (bx==0 && by==0 && bz==0) continue;
Vec3 offset(bx*boxEdgeLength, by*boxEdgeLength, bz*boxEdgeLength);
for (int i = 0; i < numAtoms; ++ i) {
for (int j = 0; j < numAtoms; ++j) {
Vec3 dR = positions[i] - positions[j] + offset;
double R2 = dR[0]*dR[0] + dR[1]*dR[1] + dR[2]*dR[2];
if (R2 > longcutoff2) continue;
double sig2 = (sigvals[i] + sigvals[j])*(sigvals[i] + sigvals[j]) / R2;
double sig6 = sig2*sig2*sig2;
double eps = epsvals[i]*epsvals[j];
refenergy += eps*(sig6-1.0)*sig6;
if (R2 < cutoff2) {
// Add a shift term for direct space parts withing teh
refenergy += eps*(pow(sigvals[i]+sigvals[j], 6) - 64.0*pow(sigvals[i]*sigvals[j], 3))*cutoff6inv;
}
}
}
}
}
}
refenergy *= 0.5;
// For this test the reference energy is 545636 kJ/mol, while the difference between DPME and 30A cutoffs
// is just 1.062 kJ/mol. The difference is due to the fact that arithmetic mean combination rules are used
// up to the cutoff, while the reciprocal space uses the geometric mean. See DOI: 10.1021/acs.jctc.5b00726
ASSERT_EQUAL_TOL(refenergy, energy, 5E-5);
ASSERT_EQUAL_TOL(gromacs_energy, energy, 5E-4);
for (int n = 0; n < numAtoms; ++n)
ASSERT_EQUAL_VEC(refforces[n], forces[n], 5E-4);
}
void testWater125DpmeVsLongCutoffWithExclusions() {
const double cutoff = 11.5*OpenMM::NmPerAngstrom;
const double alpha = 0.45*OpenMM::AngstromsPerNm;
const double dalpha = 4.2760443169;
const int grid = 60;
NonbondedForce* forceField = new NonbondedForce();
vector<Vec3> positions;
vector<double> epsvals;
vector<double> sigvals;
vector<pair<int, int> > bonds;
System system;
const int numAtoms = 375;
double boxEdgeLength = 23.01*OpenMM::NmPerAngstrom;
make_waterbox(numAtoms, boxEdgeLength, forceField, positions, epsvals, sigvals, bonds, system, false);
forceField->setNonbondedMethod(OpenMM::NonbondedForce::LJPME);
forceField->createExceptionsFromBonds(bonds, 1.0, 1.0);
forceField->setPMEParameters(alpha, grid, grid, grid);
forceField->setLJPMEParameters(dalpha, grid, grid, grid);
forceField->setCutoffDistance(cutoff);
forceField->setReactionFieldDielectric(1.0);
system.addForce(forceField);
VerletIntegrator integrator(0.01);
Context context(system, integrator, platform);
context.setPositions(positions);
State state = context.getState(State::Forces | State::Energy);
double energy = state.getPotentialEnergy();
const vector<Vec3>& forces = state.getForces();
// Gromacs reference values. See comments in testWater2DpmeEnergiesForcesNoExclusions() for details.
double gromacs_energy = -2.17481e+02;
vector<Vec3> refforces(numAtoms);
refforces[ 0] = Vec3(-3.10130e+01, -6.01219e+01, -5.31302e+01);
refforces[ 1] = Vec3( 4.21376e+00, 9.13811e-01, 9.61319e-01);
refforces[ 2] = Vec3( 1.42363e+00, 2.97219e+00, 1.27185e+00);
refforces[ 3] = Vec3(-3.70172e+01, -2.95228e+01, -6.27987e+01);
refforces[ 4] = Vec3(-6.57386e-01, 2.39279e+00, 1.53243e+00);
refforces[ 5] = Vec3(-1.61426e+00, 7.11728e-01, 9.99752e-01);
refforces[ 6] = Vec3( 1.60813e+01, -6.77979e+01, -1.01302e+02);
refforces[ 7] = Vec3(-4.23118e+00, 9.25550e-01, 1.28003e+00);
refforces[ 8] = Vec3( 1.81589e+00, 1.10083e+00, 1.28615e+00);
refforces[ 9] = Vec3(-2.24427e+00, -5.71071e+01, -3.18064e+01);
refforces[ 10] = Vec3( 3.41715e+00, 1.32918e+00, 1.27908e+00);
refforces[ 11] = Vec3(-3.09930e+00, 9.91868e-01, 1.69245e+00);
refforces[ 12] = Vec3( 6.08033e+01, -1.02990e+02, -8.26733e+01);
refforces[ 13] = Vec3(-1.01346e+00, 1.35475e+00, 4.13725e+00);
refforces[ 14] = Vec3(-6.71645e-01, 4.69536e-01, 4.64774e-01);
refforces[ 15] = Vec3(-6.39056e+01, -9.85756e-01, -4.97837e+01);
refforces[ 16] = Vec3( 9.97113e-01, 1.13195e-01, 4.49387e+00);
refforces[ 17] = Vec3( 9.48864e-01, 4.22217e+00, 1.56364e+00);
refforces[ 18] = Vec3( 2.18124e+01, -6.14078e+01, -8.10129e+01);
refforces[ 19] = Vec3(-5.59701e-01, -1.47528e+00, 1.40157e+00);
refforces[ 20] = Vec3( 4.29539e+00, 4.27738e-02, 1.03009e+00);
refforces[ 21] = Vec3(-2.62377e+01, 2.55532e+01, -6.89576e+01);
refforces[ 22] = Vec3( 1.17222e-01, 3.81618e+00, 1.74502e+00);
refforces[ 23] = Vec3( 1.46448e-01, 1.06214e-01, 4.27946e+00);
refforces[ 24] = Vec3(-1.90819e+00, 9.86513e+00, -1.05364e+02);
refforces[ 25] = Vec3(-1.18537e+00, 1.75021e+00, 1.54448e+00);
refforces[ 26] = Vec3( 2.96182e+00, -9.48323e-01, 1.61299e+00);
refforces[ 27] = Vec3( 5.61257e+01, 7.69427e+01, -5.84534e+01);
refforces[ 28] = Vec3(-8.11821e-01, -7.15455e-01, 6.60049e-01);
refforces[ 29] = Vec3(-9.20901e-01, 3.76217e+00, 1.35685e+00);
refforces[ 30] = Vec3(-5.03791e+01, 2.24324e+01, -4.31606e+01);
refforces[ 31] = Vec3( 3.72530e+00, 3.48275e-01, 1.40060e+00);
refforces[ 32] = Vec3( 7.61265e-01, 8.56416e-01, 6.23359e-01);
refforces[ 33] = Vec3( 1.95683e+01, 4.16950e+01, -4.33266e+01);
refforces[ 34] = Vec3(-2.19677e+00, 1.06287e+00, 1.58260e+00);
refforces[ 35] = Vec3( 1.70923e+00, 2.09511e+00, 9.84492e-01);
refforces[ 36] = Vec3(-7.84273e+01, -3.34396e+01, -3.66486e+01);
refforces[ 37] = Vec3(-1.53567e-01, 1.74934e-01, 1.15266e+00);
refforces[ 38] = Vec3(-3.45548e+00, 1.68633e-01, 1.15923e+00);
refforces[ 39] = Vec3( 6.90725e+01, -2.09426e+01, -5.31532e+01);
refforces[ 40] = Vec3( 1.33274e+00, 3.09504e-01, 1.40065e+00);
refforces[ 41] = Vec3( 1.65828e+00, -1.96378e-01, 2.68350e+00);
refforces[ 42] = Vec3( 3.39954e+01, -2.65418e+01, -6.81184e+01);
refforces[ 43] = Vec3(-1.17491e+00, -2.88793e+00, 1.40541e+00);
refforces[ 44] = Vec3(-9.63132e-01, -3.78178e-01, 1.06756e+00);
refforces[ 45] = Vec3(-4.44610e+01, -1.81736e+01, -6.19409e+01);
refforces[ 46] = Vec3( 1.48529e+00, 8.95548e-06, 4.60732e+00);
refforces[ 47] = Vec3( 1.00451e+00, -3.88830e+00, 1.27726e+00);
refforces[ 48] = Vec3(-4.23022e+00, 2.52963e+01, -3.04756e+01);
refforces[ 49] = Vec3(-3.45228e+00, 7.61191e-01, 9.40731e-01);
refforces[ 50] = Vec3( 2.78622e+00, 8.32081e-01, 1.37588e+00);
refforces[ 51] = Vec3( 1.63360e+01, 3.02230e+01, -3.91446e+01);
refforces[ 52] = Vec3(-2.64761e+00, 1.18509e+00, 9.81393e-01);
refforces[ 53] = Vec3( 1.74883e+00, -1.51958e-01, 2.56504e+00);
refforces[ 54] = Vec3(-3.01111e+01, 4.08021e+01, -3.45058e+01);
refforces[ 55] = Vec3(-1.17129e-01, 9.74282e-02, 4.56402e+00);
refforces[ 56] = Vec3(-3.03696e+00, 4.44012e-01, 1.44269e+00);
refforces[ 57] = Vec3( 7.57956e+01, -1.12043e+01, -3.92084e+01);
refforces[ 58] = Vec3(-1.55617e+00, 2.26444e-01, 2.88234e+00);
refforces[ 59] = Vec3(-1.37287e+00, -3.79045e+00, 8.55326e-01);
refforces[ 60] = Vec3(-2.88831e+01, 5.72484e+01, -7.17030e+01);
refforces[ 61] = Vec3( 6.88458e-01, -2.06343e+00, 1.03552e+00);
refforces[ 62] = Vec3( 6.94194e-01, -1.83673e+00, 2.90979e+00);
refforces[ 63] = Vec3(-7.87489e+01, 2.17729e+01, -3.72371e+01);
refforces[ 64] = Vec3( 1.39267e-01, -4.55150e+00, 9.53893e-01);
refforces[ 65] = Vec3(-4.27928e+00, -1.14139e+00, 9.25405e-01);
refforces[ 66] = Vec3( 7.13947e+01, 3.02722e+01, -5.16551e+01);
refforces[ 67] = Vec3( 4.07933e+00, -1.28199e+00, 9.34707e-01);
refforces[ 68] = Vec3(-7.53668e-02, -2.14888e+00, 1.27713e+00);
refforces[ 69] = Vec3(-9.36762e+00, 2.98321e+01, -5.70761e+01);
refforces[ 70] = Vec3( 1.35989e+00, -3.09988e+00, 9.89945e-01);
refforces[ 71] = Vec3(-2.20314e+00, -7.81892e-01, 1.21781e+00);
refforces[ 72] = Vec3( 4.89194e+01, 7.40749e+01, -4.22017e+01);
refforces[ 73] = Vec3(-4.25696e+00, -1.18954e+00, 1.04383e+00);
refforces[ 74] = Vec3(-1.40510e+00, -9.87719e-01, 3.30559e+00);
refforces[ 75] = Vec3(-4.95912e+01, -8.24838e+01, -1.82510e+01);
refforces[ 76] = Vec3( 7.39933e-01, 9.29483e-01, -1.09883e+00);
refforces[ 77] = Vec3( 9.70359e-01, 1.03012e+00, 4.01759e+00);
refforces[ 78] = Vec3(-7.87499e+00, -1.87981e+01, 5.77017e+00);
refforces[ 79] = Vec3( 3.82847e+00, 1.01191e+00, -7.30715e-02);
refforces[ 80] = Vec3(-2.64831e+00, 1.68402e+00, 1.06474e-01);
refforces[ 81] = Vec3( 1.81335e+01, -6.72766e+01, 7.21397e+01);
refforces[ 82] = Vec3(-1.89188e-01, 1.27803e+00, 8.45103e-01);
refforces[ 83] = Vec3( 2.47584e+00, 1.54044e+00, 6.55440e-01);
refforces[ 84] = Vec3(-1.05824e+00, -6.50833e+01, -3.88413e+01);
refforces[ 85] = Vec3(-3.21762e+00, 1.58809e+00, -1.32879e-01);
refforces[ 86] = Vec3( 3.30285e+00, 1.52154e+00, -3.56471e-01);
refforces[ 87] = Vec3( 4.41972e+01, -3.58815e+01, 4.01227e+01);
refforces[ 88] = Vec3(-1.22923e+00, 8.91826e-01, 2.84505e+00);
refforces[ 89] = Vec3(-4.31649e+00, 1.00895e+00, 4.43366e-01);
refforces[ 90] = Vec3(-3.65176e+01, 4.86616e+01, -6.44163e+00);
refforces[ 91] = Vec3( 1.03989e+00, 3.91910e+00, 7.93373e-01);
refforces[ 92] = Vec3( 4.11089e+00, -4.60733e-01, -7.78461e-02);
refforces[ 93] = Vec3(-1.58332e+01, -6.82045e+01, 6.62934e+01);
refforces[ 94] = Vec3(-7.75645e-02, -3.66897e+00, -3.55044e-01);
refforces[ 95] = Vec3( 4.08399e-01, 2.84950e-01, 3.80641e+00);
refforces[ 96] = Vec3(-5.05975e+00, 4.20346e+01, 3.49518e+01);
refforces[ 97] = Vec3( 9.82673e-01, 2.64451e+00, 4.02971e-01);
refforces[ 98] = Vec3(-1.24992e+00, -3.34479e-01, 1.95012e+00);
refforces[ 99] = Vec3( 2.31815e+00, -2.30056e+00, 6.49918e+01);
refforces[100] = Vec3(-2.16986e+00, -1.05184e-01, 1.89395e+00);
refforces[101] = Vec3( 3.51302e+00, 1.83706e-01, 7.08534e-01);
refforces[102] = Vec3( 4.46929e+01, -7.11604e+01, -6.62201e+00);
refforces[103] = Vec3(-1.87730e+00, -1.10206e+00, -1.47504e+00);
refforces[104] = Vec3(-1.41639e+00, -1.36347e+00, 6.10811e-01);
refforces[105] = Vec3(-3.12256e+01, -1.73923e+01, -4.47428e+01);
refforces[106] = Vec3( 7.92004e-01, -1.39066e+00, -2.68309e+00);
refforces[107] = Vec3( 1.54891e+00, 2.50018e+00, -6.21395e-01);
refforces[108] = Vec3(-3.83585e+01, 3.90231e+01, -3.68876e+01);
refforces[109] = Vec3( 1.86446e-01, 3.49120e+00, -4.00101e-01);
refforces[110] = Vec3(-4.05592e+00, -2.21609e-01, 2.13257e-01);
refforces[111] = Vec3( 5.70991e+01, -5.95502e+01, -4.08285e+01);
refforces[112] = Vec3(-4.25039e-01, -3.96206e-01, -3.23550e+00);
refforces[113] = Vec3( 4.14811e+00, -1.47859e-01, 1.11071e-01);
refforces[114] = Vec3(-2.74979e+01, 4.40260e+01, 3.06766e+00);
refforces[115] = Vec3( 2.22804e-01, 3.48934e+00, -1.96162e-01);
refforces[116] = Vec3(-4.21754e+00, 1.18655e-01, 3.36974e-01);
refforces[117] = Vec3( 6.32783e+01, 8.02719e+01, 1.38219e+01);
refforces[118] = Vec3(-1.49058e+00, 1.87045e+00, -1.32164e-01);
refforces[119] = Vec3(-2.30776e+00, 1.73240e-01, 1.92445e+00);
refforces[120] = Vec3(-4.04272e+01, -1.77143e+01, 1.57461e+01);
refforces[121] = Vec3( 1.82378e+00, 2.60376e+00, 2.33866e-01);
refforces[122] = Vec3( 1.33379e+00, -1.16675e+00, 3.34265e+00);
refforces[123] = Vec3(-8.78170e+00, 1.35313e+01, -5.40700e+01);
refforces[124] = Vec3(-2.72817e+00, 3.27413e-01, -6.95012e-01);
refforces[125] = Vec3( 2.41935e+00, -2.66049e-01, -1.62940e+00);
refforces[126] = Vec3(-3.63273e+01, 6.91610e+01, -3.72663e+00);
refforces[127] = Vec3(-1.40546e+00, 7.48503e-01, -9.73230e-01);
refforces[128] = Vec3( 5.39530e-01, 8.56302e-01, 2.57617e+00);
refforces[129] = Vec3( 2.54426e+01, -5.04169e+01, -1.76229e+01);
refforces[130] = Vec3( 6.82595e-01, -3.17362e+00, 2.20610e-01);
refforces[131] = Vec3( 1.94539e+00, 1.53325e+00, -4.24624e-01);
refforces[132] = Vec3( 3.61678e+01, -7.89030e+01, -9.61808e+00);
refforces[133] = Vec3(-1.29295e+00, -1.55223e+00, -1.88241e+00);
refforces[134] = Vec3(-1.51438e+00, 3.14594e-02, 3.60043e+00);
refforces[135] = Vec3(-4.60860e+01, 6.18971e+01, 1.38188e+01);
refforces[136] = Vec3( 3.07506e+00, -9.60659e-01, 1.81485e+00);
refforces[137] = Vec3( 6.46515e-01, -7.30203e-01, -2.17471e-01);
refforces[138] = Vec3( 7.76539e+00, 3.18751e+01, -6.18739e+01);
refforces[139] = Vec3(-2.12790e+00, -1.06577e+00, -1.03098e+00);
refforces[140] = Vec3( 3.70469e+00, -7.70591e-01, -2.00619e-01);
refforces[141] = Vec3(-4.02748e+01, 1.93804e+01, 1.92911e+01);
refforces[142] = Vec3( 5.74429e-01, -1.58840e+00, -2.07083e+00);
refforces[143] = Vec3(-4.21689e+00, -7.25280e-01, 1.61839e-01);
refforces[144] = Vec3( 4.10890e+01, 6.50772e+01, -6.64661e+00);
refforces[145] = Vec3( 2.02022e-01, -1.46124e+00, 1.99785e+00);
refforces[146] = Vec3( 1.91733e-01, -1.14906e+00, -4.18291e+00);
refforces[147] = Vec3( 3.77785e+01, 1.01191e+02, -6.07436e+00);
refforces[148] = Vec3(-1.03030e+00, -1.26650e+00, 3.57188e+00);
refforces[149] = Vec3(-7.42295e-01, -1.05437e+00, -1.47491e+00);
refforces[150] = Vec3(-7.40150e+01, -3.53477e+01, 1.81946e+01);
refforces[151] = Vec3( 1.65267e+00, 1.39873e+00, 1.46780e+00);
refforces[152] = Vec3( 1.18632e+00, 2.66165e+00, 1.61236e+00);
refforces[153] = Vec3( 3.89536e+01, -2.96071e+01, -1.38610e+01);
refforces[154] = Vec3( 2.05061e+00, 1.54050e+00, 5.35476e-01);
refforces[155] = Vec3( 4.98336e-01, 3.85036e+00, 4.21301e-01);
refforces[156] = Vec3(-5.53456e+01, -6.87157e+01, -3.55693e+01);
refforces[157] = Vec3( 3.17070e+00, 1.65800e+00, -3.99476e-01);
refforces[158] = Vec3(-2.02395e+00, 1.48143e+00, 1.00879e+00);
refforces[159] = Vec3( 5.94087e+01, -4.57694e+01, 2.77585e+01);
refforces[160] = Vec3( 2.05570e+00, 1.46552e+00, -1.41447e+00);
refforces[161] = Vec3( 2.97741e-01, 9.12876e-01, 3.27902e+00);
refforces[162] = Vec3( 1.93442e+01, -4.16391e+01, 3.34803e-01);
refforces[163] = Vec3(-3.93865e+00, 8.46322e-01, -4.47285e-01);
refforces[164] = Vec3(-7.34898e-01, 9.82679e-01, 1.44017e+00);
refforces[165] = Vec3(-3.34824e+01, -1.38834e+01, -2.62952e+01);
refforces[166] = Vec3( 1.26693e+00, -1.10171e+00, 3.22806e+00);
refforces[167] = Vec3( 3.49758e+00, -1.84534e-01, -4.62412e-01);
refforces[168] = Vec3( 1.82122e+00, -5.69776e+01, -3.86605e+01);
refforces[169] = Vec3( 1.92404e+00, -1.05303e+00, -4.52186e-01);
refforces[170] = Vec3(-3.25172e+00, 9.44050e-02, -5.87318e-01);
refforces[171] = Vec3(-5.98475e+01, 1.85708e+01, -2.67060e+01);
refforces[172] = Vec3(-3.77230e-01, 3.29609e+00, -4.81590e-01);
refforces[173] = Vec3(-1.66002e+00, -2.41098e+00, 1.03425e-01);
refforces[174] = Vec3( 6.47852e+01, 4.38661e+00, 1.77482e+01);
refforces[175] = Vec3(-1.29162e-01, -3.40031e+00, 3.91521e-01);
refforces[176] = Vec3( 1.28253e+00, 2.14633e+00, 2.64792e-01);
refforces[177] = Vec3( 2.95010e+01, -5.60376e+00, 4.16733e+01);
refforces[178] = Vec3(-1.43378e+00, -1.96178e-01, 2.40594e+00);
refforces[179] = Vec3(-1.56255e+00, -3.08967e+00, -3.14335e-01);
refforces[180] = Vec3(-6.02384e+01, -1.59585e+01, 7.16798e+01);
refforces[181] = Vec3( 1.68669e+00, -3.54228e+00, -2.98122e-01);
refforces[182] = Vec3( 9.46412e-01, -8.03852e-02, 4.17305e+00);
refforces[183] = Vec3( 3.87313e+00, 4.46632e+01, 4.59130e+01);
refforces[184] = Vec3(-9.83299e-02, -8.11669e-02, 4.04515e+00);
refforces[185] = Vec3( 6.64172e-01, 3.66814e+00, -2.58278e-01);
refforces[186] = Vec3(-1.65450e+01, 2.35336e+01, 7.09485e+01);
refforces[187] = Vec3(-6.98821e-01, 2.45516e-01, 2.69560e+00);
refforces[188] = Vec3( 4.04145e+00, 5.46258e-02, -1.82210e-02);
refforces[189] = Vec3( 2.39311e+01, 1.22785e+01, -2.13260e+01);
refforces[190] = Vec3(-3.33802e-02, -3.60205e+00, 6.21747e-01);
refforces[191] = Vec3( 3.50616e+00, 6.09623e-01, -7.40284e-02);
refforces[192] = Vec3( 2.32693e+01, -1.88836e+01, 1.24193e+01);
refforces[193] = Vec3(-2.25948e+00, -1.74718e+00, 2.65705e-01);
refforces[194] = Vec3(-1.32949e+00, -8.67446e-01, 7.75386e-01);
refforces[195] = Vec3(-4.40626e+01, 1.17032e+01, -4.18284e+01);
refforces[196] = Vec3( 1.61723e+00, -6.18309e-01, 2.45312e+00);
refforces[197] = Vec3( 1.42535e+00, 1.71801e+00, -1.86477e+00);
refforces[198] = Vec3( 3.37157e+00, -1.65818e+01, 7.59773e+01);
refforces[199] = Vec3(-2.81989e+00, -1.37877e+00, -9.60015e-02);
refforces[200] = Vec3(-8.77602e-02, 2.44299e+00, 1.17362e+00);
refforces[201] = Vec3( 2.44644e+01, -3.26831e+01, -5.34506e+01);
refforces[202] = Vec3(-4.14853e+00, -9.48873e-02, -2.18126e-01);
refforces[203] = Vec3( 8.13810e-01, -1.30429e+00, -1.62539e+00);
refforces[204] = Vec3( 1.03414e+01, -4.14898e+00, 2.56841e+01);
refforces[205] = Vec3(-1.50990e-01, -3.90514e+00, 2.98649e-01);
refforces[206] = Vec3(-3.60035e+00, -7.83546e-02, -7.95300e-01);
refforces[207] = Vec3( 4.49059e+01, 2.88959e+01, 1.53626e+01);
refforces[208] = Vec3(-2.55855e+00, -1.55231e+00, -3.96734e-01);
refforces[209] = Vec3(-1.14072e+00, 3.25255e+00, 2.39860e-01);
refforces[210] = Vec3(-4.12850e+01, 6.11654e+01, 2.43179e+01);
refforces[211] = Vec3( 1.20781e+00, -8.28196e-01, 4.26212e+00);
refforces[212] = Vec3( 7.30387e-01, -9.26965e-01, -9.32605e-01);
refforces[213] = Vec3(-1.64972e+01, 4.58667e+01, 5.58154e+01);
refforces[214] = Vec3( 4.43484e-01, -1.67205e+00, 3.42164e+00);
refforces[215] = Vec3(-4.14170e+00, -9.68400e-01, -9.21231e-02);
refforces[216] = Vec3( 1.79252e+01, 6.24205e+01, -1.47777e+01);
refforces[217] = Vec3(-2.53437e+00, -9.16373e-01, -1.63636e+00);
refforces[218] = Vec3( 3.32247e+00, -1.29776e+00, -1.07427e+00);
refforces[219] = Vec3( 1.79752e+01, 5.16430e+01, 3.90249e+01);
refforces[220] = Vec3( 7.14180e-01, -1.00018e+00, 3.14118e+00);
refforces[221] = Vec3(-1.07965e+00, -3.41285e+00, -2.24161e-01);
refforces[222] = Vec3( 3.16317e+01, 4.98025e+01, -4.17518e+01);
refforces[223] = Vec3(-2.55899e+00, -1.63433e+00, -3.76149e-01);
refforces[224] = Vec3(-1.19443e+00, -1.02227e+00, -5.37349e-02);
refforces[225] = Vec3(-3.77249e+01, -4.85845e+01, -2.11073e+01);
refforces[226] = Vec3( 7.98995e-01, 1.26056e+00, 4.28442e+00);
refforces[227] = Vec3( 3.35648e+00, 9.11653e-01, -8.07025e-01);
refforces[228] = Vec3(-3.16004e+01, -2.04156e+01, 5.01542e+01);
refforces[229] = Vec3( 8.97766e-01, 1.34997e+00, 2.86585e+00);
refforces[230] = Vec3(-2.09603e-01, 4.05651e+00, -1.91043e-02);
refforces[231] = Vec3( 3.61582e+01, -3.35593e+01, 4.19940e+01);
refforces[232] = Vec3( 3.66075e+00, 7.71021e-01, 3.45598e-01);
refforces[233] = Vec3(-7.50361e-01, 1.22549e+00, 7.98677e-01);
refforces[234] = Vec3(-4.42511e+01, -2.71049e+01, -4.56576e+01);
refforces[235] = Vec3(-3.30181e-01, 1.98824e+00, 2.21005e+00);
refforces[236] = Vec3(-7.68719e-01, 9.09063e-01, -3.77633e+00);
refforces[237] = Vec3( 7.33817e+01, -3.03886e+01, -7.59758e+01);
refforces[238] = Vec3(-1.71701e+00, 1.41048e+00, -1.84182e+00);
refforces[239] = Vec3(-1.35491e+00, 2.27816e+00, -1.08799e+00);
refforces[240] = Vec3(-4.58218e+01, -2.91931e+01, 1.12369e+01);
refforces[241] = Vec3( 1.68546e+00, 2.81258e+00, 3.93755e-01);
refforces[242] = Vec3( 8.28917e-01, -1.32237e+00, 2.91182e+00);
refforces[243] = Vec3( 5.44446e+00, -3.99466e+01, 6.77923e+00);
refforces[244] = Vec3(-1.09231e+00, -5.21927e-01, 1.83581e+00);
refforces[245] = Vec3( 5.24849e-02, -7.21832e-01, -3.35896e+00);
refforces[246] = Vec3(-1.29863e+01, -3.94851e+01, -2.70347e+01);
refforces[247] = Vec3(-3.94725e+00, -2.01688e-01, 5.93703e-02);
refforces[248] = Vec3( 1.30447e+00, -2.35362e+00, -2.94278e-01);
refforces[249] = Vec3( 2.56542e+01, -3.79434e+01, -6.19782e+01);
refforces[250] = Vec3( 2.48025e+00, -1.19994e+00, 1.41640e-01);
refforces[251] = Vec3(-5.01379e-01, 2.48607e-01, -3.97535e+00);
refforces[252] = Vec3( 3.46461e+01, -8.37214e+01, -3.92225e+01);
refforces[253] = Vec3(-2.80216e+00, -1.13524e+00, 1.85582e-02);
refforces[254] = Vec3(-1.28421e+00, -9.50174e-01, -5.56828e-01);
refforces[255] = Vec3(-3.56755e+01, 1.44176e+01, -7.63345e-01);
refforces[256] = Vec3( 1.25547e+00, 2.64846e+00, 1.29226e+00);
refforces[257] = Vec3( 1.22691e+00, 5.72301e-01, -4.09853e+00);
refforces[258] = Vec3(-6.02997e+00, -1.31579e+01, -5.03304e+01);
refforces[259] = Vec3(-4.59947e-01, -8.09031e-01, 3.08383e+00);
refforces[260] = Vec3(-8.93872e-01, -3.70797e-01, -2.89773e+00);
refforces[261] = Vec3(-1.92458e+00, 2.50787e+01, -4.30937e+01);
refforces[262] = Vec3( 2.10381e-01, -1.24125e-01, -4.01554e+00);
refforces[263] = Vec3(-3.85853e+00, 6.72311e-01, 4.06873e-02);
refforces[264] = Vec3( 1.66952e+01, 1.47383e+01, 4.13458e+01);
refforces[265] = Vec3(-2.12261e+00, -5.40916e-01, 1.54532e+00);
refforces[266] = Vec3( 3.54041e+00, -4.73740e-02, 4.73489e-01);
refforces[267] = Vec3( 4.43789e+01, 6.96271e+01, 4.06335e+00);
refforces[268] = Vec3(-9.59563e-01, 9.94730e-01, -3.12464e+00);
refforces[269] = Vec3(-1.42363e+00, 1.62107e+00, 1.87365e+00);
refforces[270] = Vec3(-5.38380e+01, 2.27365e+01, 1.95666e+01);
refforces[271] = Vec3( 1.47405e+00, 2.11523e+00, 1.97777e-01);
refforces[272] = Vec3( 2.54377e+00, -4.04439e-02, 1.97927e+00);
refforces[273] = Vec3( 1.33568e+01, 1.88750e+01, -3.59233e+01);
refforces[274] = Vec3(-1.09293e+00, 2.25841e+00, -4.61222e-01);
refforces[275] = Vec3( 3.27762e+00, -1.71208e-01, -8.67824e-01);
refforces[276] = Vec3(-3.41864e+01, 3.38579e+01, 5.95219e+01);
refforces[277] = Vec3(-4.18249e+00, -8.81154e-02, 1.97498e-01);
refforces[278] = Vec3( 1.06177e+00, 2.34089e+00, 2.42037e-01);
refforces[279] = Vec3( 2.35073e+01, 1.61625e+01, -2.58858e+01);
refforces[280] = Vec3( 3.87903e+00, 1.67313e-01, -4.03473e-02);
refforces[281] = Vec3(-5.12341e-01, -5.62857e-01, -3.19237e+00);
refforces[282] = Vec3( 3.39154e+01, -5.09470e+00, -2.29146e+01);
refforces[283] = Vec3(-1.24992e+00, 5.24960e-01, -1.16022e+00);
refforces[284] = Vec3(-2.39537e+00, 1.82818e-01, -1.53421e+00);
refforces[285] = Vec3(-5.56195e+01, 2.89266e+01, -2.61137e+01);
refforces[286] = Vec3( 2.49596e+00, -1.03213e+00, -1.51258e+00);
refforces[287] = Vec3( 1.02471e+00, -1.05342e+00, -6.79809e-01);
refforces[288] = Vec3(-1.52895e+01, 4.83734e+01, -7.33233e+00);
refforces[289] = Vec3( 3.77837e+00, -1.59224e+00, 2.02675e-01);
refforces[290] = Vec3(-3.51854e+00, -1.54234e+00, 2.89348e-01);
refforces[291] = Vec3( 3.22262e+01, 2.32542e+01, 2.37269e+01);
refforces[292] = Vec3( 1.88520e+00, -1.38396e+00, -1.98750e+00);
refforces[293] = Vec3( 4.99036e-02, -4.53129e+00, -2.13859e-01);
refforces[294] = Vec3(-7.48274e+00, 3.71318e+01, -2.35667e+01);
refforces[295] = Vec3( 7.81671e-01, -1.07371e+00, -2.37009e+00);
refforces[296] = Vec3(-3.98896e+00, -9.36146e-01, 2.62843e-02);
refforces[297] = Vec3( 4.33081e+01, 4.24806e+01, 3.21190e+01);
refforces[298] = Vec3(-2.52531e+00, -1.90285e+00, 2.72091e-01);
refforces[299] = Vec3(-9.70927e-01, -1.13219e+00, 1.47351e+00);
refforces[300] = Vec3(-4.71070e+01, -7.19253e+01, 5.82986e+01);
refforces[301] = Vec3( 6.82929e-01, 1.00679e+00, -6.94522e-01);
refforces[302] = Vec3( 8.31359e-01, 7.09804e-01, -8.12652e-01);
refforces[303] = Vec3( 3.62309e+00, -3.42931e+01, 1.98231e+01);
refforces[304] = Vec3( 1.23138e+00, 8.49297e-01, -2.39283e+00);
refforces[305] = Vec3(-2.87428e+00, 1.41050e+00, -1.03948e+00);
refforces[306] = Vec3(-3.83149e+00, -2.61638e+01, 2.98550e+01);
refforces[307] = Vec3(-2.90010e+00, 1.38356e+00, -1.22906e+00);
refforces[308] = Vec3( 2.62337e-01, 9.72795e-01, -4.02660e+00);
refforces[309] = Vec3( 7.84655e+00, -5.09531e+01, 7.96762e+01);
refforces[310] = Vec3( 2.46967e+00, 9.48901e-01, -1.17317e+00);
refforces[311] = Vec3(-4.11596e+00, 7.95633e-01, -1.39335e+00);
refforces[312] = Vec3( 5.03705e+01, -8.09993e+01, 1.13172e+02);
refforces[313] = Vec3(-4.48925e-01, 4.29309e-01, -5.50572e-01);
refforces[314] = Vec3(-2.66201e+00, 1.05662e+00, -1.44247e+00);
refforces[315] = Vec3(-6.12660e+01, 2.31218e+01, 4.57287e+01);
refforces[316] = Vec3( 8.42017e-01, 1.41042e+00, -7.78795e-01);
refforces[317] = Vec3( 3.11298e+00, -8.04273e-01, -1.51273e+00);
refforces[318] = Vec3( 1.83823e+01, -2.83588e+01, 6.13597e+01);
refforces[319] = Vec3( 4.37781e+00, 8.12091e-02, -1.33992e+00);
refforces[320] = Vec3(-5.81396e-01, -3.61991e+00, -1.22489e+00);
refforces[321] = Vec3(-4.85270e+01, -6.50314e+01, 7.16441e+01);
refforces[322] = Vec3(-3.40093e-02, 9.01514e-01, -1.26573e+00);
refforces[323] = Vec3(-8.67193e-02, -3.94828e+00, -8.97127e-01);
refforces[324] = Vec3( 6.25833e+01, -2.31957e+01, 8.66089e+01);
refforces[325] = Vec3( 2.49809e+00, -7.64197e-01, -1.27775e+00);
refforces[326] = Vec3( 2.11019e-01, 7.81764e-01, -1.23664e+00);
refforces[327] = Vec3( 2.04801e+01, 3.14002e+01, 6.96727e+01);
refforces[328] = Vec3(-7.99932e-01, 4.35586e+00, -8.77957e-01);
refforces[329] = Vec3(-2.87129e+00, -1.02321e+00, -1.42702e+00);
refforces[330] = Vec3(-6.36347e+01, -3.58428e+01, 4.52682e+01);
refforces[331] = Vec3( 1.32210e+00, -2.58500e+00, -1.43327e+00);
refforces[332] = Vec3( 1.52218e+00, 1.63513e+00, -2.29784e+00);
refforces[333] = Vec3( 4.36105e+00, 3.70776e+01, 6.46133e+01);
refforces[334] = Vec3(-1.19452e+00, -1.01252e+00, -1.43172e+00);
refforces[335] = Vec3( 4.34983e+00, -6.52342e-02, -1.33662e+00);
refforces[336] = Vec3( 1.13050e+01, 4.99187e+01, 7.16119e+01);
refforces[337] = Vec3( 2.29221e-01, 6.35843e-01, -3.59259e+00);
refforces[338] = Vec3( 1.65239e+00, 4.20995e-01, -1.42878e+00);
refforces[339] = Vec3(-1.79210e+01, 1.92423e+01, 1.77516e+01);
refforces[340] = Vec3(-2.91278e+00, 9.22214e-01, -8.41281e-01);
refforces[341] = Vec3( 2.96465e+00, 1.05962e+00, -6.85280e-01);
refforces[342] = Vec3( 5.19378e+01, -2.55266e+01, 3.63518e+01);
refforces[343] = Vec3(-1.13088e+00, 4.54600e-01, -1.30862e+00);
refforces[344] = Vec3(-2.05369e+00, -9.69459e-03, -2.69351e+00);
refforces[345] = Vec3(-4.22214e+01, 4.88282e+01, 3.76741e+01);
refforces[346] = Vec3( 3.46996e+00, 9.57280e-01, -7.60128e-01);
refforces[347] = Vec3( 7.62585e-01, 1.14548e+00, -8.06697e-01);
refforces[348] = Vec3(-2.35024e+01, -6.73585e+01, 6.49050e+01);
refforces[349] = Vec3(-1.58984e+00, -6.44551e-01, -2.37758e+00);
refforces[350] = Vec3( 1.32604e+00, -2.37576e+00, -1.54939e+00);
refforces[351] = Vec3( 2.57776e+01, -1.40743e+01, 2.06580e+01);
refforces[352] = Vec3( 4.24916e+00, 6.10665e-02, -8.19360e-01);
refforces[353] = Vec3(-7.94423e-01, -1.75764e-01, -3.51414e+00);
refforces[354] = Vec3(-1.24260e+01, 6.96334e-01, 5.97705e+01);
refforces[355] = Vec3(-3.38899e+00, 9.44919e-01, -1.25780e+00);
refforces[356] = Vec3( 6.81664e-01, 1.16965e+00, -2.34256e+00);
refforces[357] = Vec3( 5.15292e+01, 5.13086e+01, 6.16724e+01);
refforces[358] = Vec3(-1.04216e+00, 3.34685e+00, -1.33787e+00);
refforces[359] = Vec3(-9.57017e-01, -1.59610e-01, -4.31963e+00);
refforces[360] = Vec3(-5.88173e+01, 3.30524e+01, 6.23031e+01);
refforces[361] = Vec3( 9.35413e-01, -1.09829e+00, -4.65202e+00);
refforces[362] = Vec3( 6.95250e-01, -1.24375e+00, -6.50832e-01);
refforces[363] = Vec3( 1.64454e+01, 1.08071e+02, 3.76968e+01);
refforces[364] = Vec3(-4.25249e+00, -1.10053e+00, -7.56357e-01);
refforces[365] = Vec3( 1.17898e+00, -1.10215e+00, -8.21366e-01);
refforces[366] = Vec3(-5.20527e+00, 5.49522e+01, 4.55303e+01);
refforces[367] = Vec3(-7.98794e-01, -2.78246e+00, -1.27815e+00);
refforces[368] = Vec3(-1.02109e+00, -1.21921e+00, -1.26706e+00);
refforces[369] = Vec3( 3.05185e+00, 3.99846e+01, 5.39902e+01);
refforces[370] = Vec3( 1.93675e+00, -1.28986e+00, -1.21655e+00);
refforces[371] = Vec3(-4.14952e+00, -1.06509e+00, -9.52154e-01);
refforces[372] = Vec3( 6.06000e+01, 2.50872e+01, 4.29623e+01);
refforces[373] = Vec3(-3.50284e+00, -1.47848e+00, -7.98049e-01);
refforces[374] = Vec3(-8.66087e-01, -1.73056e+00, -6.59554e-01);
// Find the exclusion information
vector<set<int> > exclusions(numAtoms);
for (int i = 0; i < forceField->getNumExceptions(); i++) {
int particle1, particle2;
double chargeProd, sigma, epsilon;
forceField->getExceptionParameters(i, particle1, particle2, chargeProd, sigma, epsilon);
exclusions[particle1].insert(particle2);
exclusions[particle2].insert(particle1);
}
const double longcutoff = 35.0*OpenMM::NmPerAngstrom;
const double longcutoff2 = longcutoff*longcutoff;
const double cutoff2 = cutoff*cutoff;
const double cutoff6inv = 1.0 / (cutoff2*cutoff2*cutoff2);
const int nboxes = ceil(longcutoff/boxEdgeLength);
double refenergy = 0.0;
// Loop over home box first...
for (int i = 0; i < numAtoms; ++ i) {
for (int j = i+1; j < numAtoms; ++j) {
Vec3 dR = positions[i] - positions[j];
double R2 = dR[0]*dR[0] + dR[1]*dR[1] + dR[2]*dR[2];
double sig2 = (sigvals[i] + sigvals[j])*(sigvals[i] + sigvals[j]) / R2;
double sig6 = sig2*sig2*sig2;
double eps = epsvals[i]*epsvals[j];
refenergy += 2.0*eps*(sig6-1.0)*sig6;
if (R2 < cutoff2) {
// Add a shift term for direct space parts withing t
refenergy += 2.0*eps*(pow(sigvals[i]+sigvals[j], 6) - 64.0*pow(sigvals[i]*sigvals[j], 3))*cutoff6inv;
}
}
}
// ... back out exclusions
for (int ii = 0; ii < numAtoms; ii++) {
for (set<int>::const_iterator iter = exclusions[ii].begin(); iter != exclusions[ii].end(); ++iter) {
if (*iter > ii) {
int i = ii;
int j = *iter;
Vec3 dR = positions[i] - positions[j];
double R2 = dR[0]*dR[0] + dR[1]*dR[1] + dR[2]*dR[2];
double sig2 = (sigvals[i] + sigvals[j])*(sigvals[i] + sigvals[j]) / R2;
double sig6 = sig2*sig2*sig2;
double eps = epsvals[i]*epsvals[j];
refenergy -= 2.0*eps*(sig6-1.0)*sig6;
if (R2 < cutoff2) {
// Add a shift term for direct space parts withing t
refenergy -= 2.0*eps*(pow(sigvals[i]+sigvals[j], 6) - 64.0*pow(sigvals[i]*sigvals[j], 3))*cutoff6inv;
}
}
}
}
// ... and now add in the image box terms
for (int bx = -nboxes; bx <= nboxes; ++bx) {
for (int by = -nboxes; by <= nboxes; ++by) {
for (int bz = -nboxes; bz <= nboxes; ++bz) {
if (bx==0 && by==0 && bz==0) continue;
Vec3 offset(bx*boxEdgeLength, by*boxEdgeLength, bz*boxEdgeLength);
for (int i = 0; i < numAtoms; ++ i) {
for (int j = 0; j < numAtoms; ++j) {
Vec3 dR = positions[i] - positions[j] + offset;
double R2 = dR[0]*dR[0] + dR[1]*dR[1] + dR[2]*dR[2];
if (R2 > longcutoff2) continue;
double sig2 = (sigvals[i] + sigvals[j])*(sigvals[i] + sigvals[j]) / R2;
double sig6 = sig2*sig2*sig2;
double eps = epsvals[i]*epsvals[j];
refenergy += eps*(sig6-1.0)*sig6;
if (R2 < cutoff2) {
// Add a shift term for direct space parts withing teh
refenergy += eps*(pow(sigvals[i]+sigvals[j], 6) - 64.0*pow(sigvals[i]*sigvals[j], 3))*cutoff6inv;
}
}
}
}
}
}
refenergy *= 0.5;
// For this test the reference energy is -294.078 kJ/mol, while the difference between DPME and 30A cutoffs
// is just 0.064 kJ/mol. The difference is due to the fact that arithmetic mean combination rules are used
// up to the cutoff, while the reciprocal space uses the geometric mean. See DOI: 10.1021/acs.jctc.5b00726
ASSERT_EQUAL_TOL(refenergy, energy, 5E-4);
ASSERT_EQUAL_TOL(gromacs_energy, energy, 5E-5);
// Forces accumulated in single precision are tested to a more permissive criterion; the double
// precision platform can match to 5E-5.
for (int n = 0; n < numAtoms; ++n)
ASSERT_EQUAL_VEC(refforces[n], forces[n], 1E-4);
}
void runPlatformTests();
int main(int argc, char* argv[]) {
try {
initializeTests(argc, argv);
testDMFDpmeEnergiesForcesWithExclusions();
testConvergence();
testErrorTolerance();
testPMEParameters();
testCoulombAndLJ();
testWater2DpmeEnergiesForcesNoExclusions();
testWater2DpmeEnergiesForcesWithExclusions();
testWater125DpmeVsLongCutoffNoExclusions();
testWater125DpmeVsLongCutoffWithExclusions();
runPlatformTests();
}
catch(const exception& e) {
cout << "exception: " << e.what() << endl;
return 1;
}
cout << "Done" << endl;
return 0;
}
...@@ -365,7 +365,7 @@ void testErrorTolerance(NonbondedForce::NonbondedMethod method) { ...@@ -365,7 +365,7 @@ void testErrorTolerance(NonbondedForce::NonbondedMethod method) {
double expectedAlpha, actualAlpha; double expectedAlpha, actualAlpha;
int expectedSize[3], actualSize[3]; int expectedSize[3], actualSize[3];
NonbondedForceImpl::calcPMEParameters(system, *force, expectedAlpha, expectedSize[0], expectedSize[1], expectedSize[2]); NonbondedForceImpl::calcPMEParameters(system, *force, expectedAlpha, expectedSize[0], expectedSize[1], expectedSize[2], false);
force->getPMEParametersInContext(context, actualAlpha, actualSize[0], actualSize[1], actualSize[2]); force->getPMEParametersInContext(context, actualAlpha, actualSize[0], actualSize[1], actualSize[2]);
ASSERT_EQUAL_TOL(expectedAlpha, actualAlpha, 1e-5); ASSERT_EQUAL_TOL(expectedAlpha, actualAlpha, 1e-5);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
......
...@@ -78,7 +78,7 @@ void testPointParticles() { ...@@ -78,7 +78,7 @@ void testPointParticles() {
State state2 = context.getState(State::Forces | State::Energy, false, 2); State state2 = context.getState(State::Forces | State::Energy, false, 2);
ASSERT_EQUAL_TOL(state1.getPotentialEnergy(), state2.getPotentialEnergy(), 1e-5); ASSERT_EQUAL_TOL(state1.getPotentialEnergy(), state2.getPotentialEnergy(), 1e-5);
for (int i = 0; i < numParticles; i++) for (int i = 0; i < numParticles; i++)
ASSERT_EQUAL_VEC(state1.getForces()[i], state2.getForces()[i], 1e-5); ASSERT_EQUAL_VEC(state1.getForces()[i], state2.getForces()[i], 1e-4);
} }
void testEnergyScales() { void testEnergyScales() {
......
...@@ -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-2015 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -74,9 +74,9 @@ void testSingleBond() { ...@@ -74,9 +74,9 @@ void testSingleBond() {
integrator.step(1); integrator.step(1);
} }
// Not set the friction to a tiny value and see if it conserves energy. // Now set the friction to 0 and see if it conserves energy.
integrator.setFriction(5e-5); integrator.setFriction(0.0);
context.setPositions(positions); context.setPositions(positions);
State state = context.getState(State::Energy); State state = context.getState(State::Energy);
double initialEnergy = state.getKineticEnergy()+state.getPotentialEnergy(); double initialEnergy = state.getKineticEnergy()+state.getPotentialEnergy();
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "openmm/internal/AssertionUtilities.h" #include "openmm/internal/AssertionUtilities.h"
#include "openmm/CustomExternalForce.h" #include "openmm/CustomExternalForce.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/MonteCarloBarostat.h" #include "openmm/MonteCarloBarostat.h"
#include "openmm/MonteCarloAnisotropicBarostat.h" #include "openmm/MonteCarloAnisotropicBarostat.h"
#include "openmm/Context.h" #include "openmm/Context.h"
...@@ -69,8 +70,9 @@ void testIdealGas() { ...@@ -69,8 +70,9 @@ void testIdealGas() {
} }
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], true, true, true, frequency); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], true, true, true, frequency);
system.addForce(barostat); system.addForce(barostat);
ASSERT(barostat->usesPeriodicBoundaryConditions()); HarmonicBondForce* bonds = new HarmonicBondForce();
ASSERT(system.usesPeriodicBoundaryConditions()); bonds->setUsesPeriodicBoundaryConditions(true);
system.addForce(bonds); // So it won't complain the system is non-periodic.
// Test it for three different temperatures. // Test it for three different temperatures.
...@@ -129,8 +131,9 @@ void testIdealGasAxis(int axis) { ...@@ -129,8 +131,9 @@ void testIdealGasAxis(int axis) {
} }
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], scaleX, scaleY, scaleZ, frequency); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], scaleX, scaleY, scaleZ, frequency);
system.addForce(barostat); system.addForce(barostat);
ASSERT(barostat->usesPeriodicBoundaryConditions()); HarmonicBondForce* bonds = new HarmonicBondForce();
ASSERT(system.usesPeriodicBoundaryConditions()); bonds->setUsesPeriodicBoundaryConditions(true);
system.addForce(bonds); // So it won't complain the system is non-periodic.
// Test it for three different temperatures. // Test it for three different temperatures.
...@@ -187,8 +190,6 @@ void testRandomSeed() { ...@@ -187,8 +190,6 @@ void testRandomSeed() {
system.addForce(forceField); system.addForce(forceField);
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp, true, true, true, 1); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp, true, true, true, 1);
system.addForce(barostat); system.addForce(barostat);
ASSERT(barostat->usesPeriodicBoundaryConditions());
ASSERT(system.usesPeriodicBoundaryConditions());
vector<Vec3> positions(numParticles); vector<Vec3> positions(numParticles);
vector<Vec3> velocities(numParticles); vector<Vec3> velocities(numParticles);
for (int i = 0; i < numParticles; ++i) { for (int i = 0; i < numParticles; ++i) {
...@@ -262,6 +263,9 @@ void testTriclinic() { ...@@ -262,6 +263,9 @@ void testTriclinic() {
} }
MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temperature, true, true, true, frequency); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temperature, true, true, true, frequency);
system.addForce(barostat); system.addForce(barostat);
HarmonicBondForce* bonds = new HarmonicBondForce();
bonds->setUsesPeriodicBoundaryConditions(true);
system.addForce(bonds); // So it won't complain the system is non-periodic.
// Run a simulation // Run a simulation
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "openmm/internal/AssertionUtilities.h" #include "openmm/internal/AssertionUtilities.h"
#include "openmm/MonteCarloBarostat.h" #include "openmm/MonteCarloBarostat.h"
#include "openmm/Context.h" #include "openmm/Context.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/NonbondedForce.h" #include "openmm/NonbondedForce.h"
#include "openmm/System.h" #include "openmm/System.h"
#include "openmm/LangevinIntegrator.h" #include "openmm/LangevinIntegrator.h"
...@@ -105,8 +106,9 @@ void testIdealGas() { ...@@ -105,8 +106,9 @@ void testIdealGas() {
} }
MonteCarloBarostat* barostat = new MonteCarloBarostat(pressure, temp[0], frequency); MonteCarloBarostat* barostat = new MonteCarloBarostat(pressure, temp[0], frequency);
system.addForce(barostat); system.addForce(barostat);
ASSERT(barostat->usesPeriodicBoundaryConditions()); HarmonicBondForce* bonds = new HarmonicBondForce();
ASSERT(system.usesPeriodicBoundaryConditions()); bonds->setUsesPeriodicBoundaryConditions(true);
system.addForce(bonds); // So it won't complain the system is non-periodic.
// Test it for three different temperatures. // Test it for three different temperatures.
...@@ -153,8 +155,6 @@ void testRandomSeed() { ...@@ -153,8 +155,6 @@ void testRandomSeed() {
system.addForce(forceField); system.addForce(forceField);
MonteCarloBarostat* barostat = new MonteCarloBarostat(pressure, temp, 1); MonteCarloBarostat* barostat = new MonteCarloBarostat(pressure, temp, 1);
system.addForce(barostat); system.addForce(barostat);
ASSERT(barostat->usesPeriodicBoundaryConditions());
ASSERT(system.usesPeriodicBoundaryConditions());
vector<Vec3> positions(numParticles); vector<Vec3> positions(numParticles);
vector<Vec3> velocities(numParticles); vector<Vec3> velocities(numParticles);
for (int i = 0; i < numParticles; ++i) { for (int i = 0; i < numParticles; ++i) {
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "SimTKOpenMMRealType.h" #include "SimTKOpenMMRealType.h"
#include "sfmt/SFMT.h" #include "sfmt/SFMT.h"
#include <iostream> #include <iostream>
#include <iomanip>
#include <vector> #include <vector>
using namespace OpenMM; using namespace OpenMM;
......
...@@ -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-2015 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -74,9 +74,9 @@ void testSingleBond() { ...@@ -74,9 +74,9 @@ void testSingleBond() {
integrator.step(1); integrator.step(1);
} }
// Now set the friction to a tiny value and see if it conserves energy. // Now set the friction to 0 and see if it conserves energy.
integrator.setFriction(5e-5); integrator.setFriction(0.0);
context.setPositions(positions); context.setPositions(positions);
State state = context.getState(State::Energy); State state = context.getState(State::Energy);
double initialEnergy = state.getKineticEnergy()+state.getPotentialEnergy(); double initialEnergy = state.getKineticEnergy()+state.getPotentialEnergy();
......
...@@ -274,7 +274,7 @@ add_custom_target(PythonSdist ...@@ -274,7 +274,7 @@ add_custom_target(PythonSdist
) )
# Install binary module (to system location) # Install binary module (to system location)
set(PYTHON_SETUP_COMMAND "install") set(PYTHON_SETUP_COMMAND "install --root=\$ENV{DESTDIR}/")
configure_file(pysetup.cmake.in configure_file(pysetup.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/pysetupinstall.cmake" @ONLY) "${CMAKE_CURRENT_BINARY_DIR}/pysetupinstall.cmake" @ONLY)
add_custom_target(PythonInstall add_custom_target(PythonInstall
......
...@@ -6,6 +6,7 @@ import re ...@@ -6,6 +6,7 @@ import re
import os import os
import sys import sys
import platform import platform
import numpy
from distutils.core import setup from distutils.core import setup
MAJOR_VERSION_NUM='@OPENMM_MAJOR_VERSION@' MAJOR_VERSION_NUM='@OPENMM_MAJOR_VERSION@'
...@@ -203,6 +204,7 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM, ...@@ -203,6 +204,7 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM,
library_dirs=[openmm_lib_path] library_dirs=[openmm_lib_path]
include_dirs=openmm_include_path.split(';') include_dirs=openmm_include_path.split(';')
include_dirs.append(numpy.get_include())
extensionArgs = {"name": "simtk.openmm._openmm", extensionArgs = {"name": "simtk.openmm._openmm",
"sources": ["src/swig_doxygen/OpenMMSwig.cxx"], "sources": ["src/swig_doxygen/OpenMMSwig.cxx"],
...@@ -229,8 +231,8 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM, ...@@ -229,8 +231,8 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM,
def main(): def main():
if sys.version_info < (2, 6): if sys.version_info < (2, 7):
reportError("OpenMM requires Python 2.6 or better.") reportError("OpenMM requires Python 2.7 or better.")
if platform.system() == 'Darwin': if platform.system() == 'Darwin':
macVersion = [int(x) for x in platform.mac_ver()[0].split('.')] macVersion = [int(x) for x in platform.mac_ver()[0].split('.')]
if tuple(macVersion) < (10, 5): if tuple(macVersion) < (10, 5):
......
...@@ -6,7 +6,7 @@ from __future__ import absolute_import ...@@ -6,7 +6,7 @@ from __future__ import absolute_import
__docformat__ = "epytext en" __docformat__ = "epytext en"
__author__ = "Peter Eastman" __author__ = "Peter Eastman"
__copyright__ = "Copyright 2015, Stanford University and Peter Eastman" __copyright__ = "Copyright 2016, Stanford University and Peter Eastman"
__credits__ = [] __credits__ = []
__license__ = "MIT" __license__ = "MIT"
__maintainer__ = "Peter Eastman" __maintainer__ = "Peter Eastman"
...@@ -40,7 +40,15 @@ CutoffNonPeriodic = forcefield.CutoffNonPeriodic ...@@ -40,7 +40,15 @@ CutoffNonPeriodic = forcefield.CutoffNonPeriodic
CutoffPeriodic = forcefield.CutoffPeriodic CutoffPeriodic = forcefield.CutoffPeriodic
Ewald = forcefield.Ewald Ewald = forcefield.Ewald
PME = forcefield.PME PME = forcefield.PME
LJPME = forcefield.LJPME
HBonds = forcefield.HBonds HBonds = forcefield.HBonds
AllBonds = forcefield.AllBonds AllBonds = forcefield.AllBonds
HAngles = forcefield.HAngles HAngles = forcefield.HAngles
Single = topology.Single
Double = topology.Double
Triple = topology.Triple
Aromatic = topology.Aromatic
Amide = topology.Amide
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