Commit dca54ec7 authored by Saurabh Belsare's avatar Saurabh Belsare
Browse files

Merged fork with latest original master

parents cace5edf 01f9e415
......@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2010 Stanford University and the Authors. *
* Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -59,6 +59,7 @@ void testSerialization() {
// Create a Force.
AmoebaMultipoleForce force1;
force1.setForceGroup(3);
force1.setNonbondedMethod(AmoebaMultipoleForce::NoCutoff);
force1.setCutoffDistance(0.9);
force1.setAEwald(0.544);
......@@ -74,6 +75,12 @@ void testSerialization() {
force1.setMutualInducedTargetEpsilon(1.0e-05);
//force1.setElectricConstant(138.93);
force1.setEwaldErrorTolerance(1.0e-05);
vector<double> coeff;
coeff.push_back(0.0);
coeff.push_back(-0.1);
coeff.push_back(1.1);
force1.setExtrapolationCoefficients(coeff);
std::vector<std::string> covalentTypes;
getCovalentTypes(covalentTypes);
......@@ -105,14 +112,12 @@ void testSerialization() {
// Compare the two forces to see if they are identical.
AmoebaMultipoleForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.getCutoffDistance(), force2.getCutoffDistance());
ASSERT_EQUAL(force1.getNonbondedMethod(), force2.getNonbondedMethod());
ASSERT_EQUAL(force1.getAEwald(), force2.getAEwald());
//ASSERT_EQUAL(force1.getPmeBSplineOrder(), force2.getPmeBSplineOrder());
//ASSERT_EQUAL(force1.getMutualInducedIterationMethod(), force2.getMutualInducedIterationMethod());
ASSERT_EQUAL(force1.getMutualInducedMaxIterations(), force2.getMutualInducedMaxIterations());
ASSERT_EQUAL(force1.getMutualInducedTargetEpsilon(), force2.getMutualInducedTargetEpsilon());
//ASSERT_EQUAL(force1.getElectricConstant(), force2.getElectricConstant());
ASSERT_EQUAL(force1.getEwaldErrorTolerance(), force2.getEwaldErrorTolerance());
......@@ -125,6 +130,8 @@ void testSerialization() {
ASSERT_EQUAL(gridDimension1[jj], gridDimension2[jj]);
}
ASSERT_EQUAL_CONTAINERS(force1.getExtrapolationCoefficients(), force2.getExtrapolationCoefficients());
ASSERT_EQUAL(force1.getNumMultipoles(), force2.getNumMultipoles());
for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumMultipoles()); ii++) {
......
......@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2010 Stanford University and the Authors. *
* Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -46,6 +46,7 @@ void testSerialization() {
AmoebaOutOfPlaneBendForce force1;
force1.setForceGroup(3);
force1.setAmoebaGlobalOutOfPlaneBendCubic(12.3);
force1.setAmoebaGlobalOutOfPlaneBendQuartic(98.7);
force1.setAmoebaGlobalOutOfPlaneBendPentic(91.7);
......@@ -55,6 +56,7 @@ void testSerialization() {
force1.addOutOfPlaneBend(0, 2, 3, 5, 2.1);
force1.addOutOfPlaneBend(2, 3, 5, 6, 2.2);
force1.addOutOfPlaneBend(5, 1, 8, 8, 2.3);
force1.setUsesPeriodicBoundaryConditions(true);
// Serialize and then deserialize it.
......@@ -65,6 +67,8 @@ void testSerialization() {
// Compare the two forces to see if they are identical.
AmoebaOutOfPlaneBendForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.usesPeriodicBoundaryConditions(), force2.usesPeriodicBoundaryConditions());
ASSERT_EQUAL(force1.getAmoebaGlobalOutOfPlaneBendCubic(), force2.getAmoebaGlobalOutOfPlaneBendCubic());
ASSERT_EQUAL(force1.getAmoebaGlobalOutOfPlaneBendQuartic(), force2.getAmoebaGlobalOutOfPlaneBendQuartic());
ASSERT_EQUAL(force1.getAmoebaGlobalOutOfPlaneBendPentic(), force2.getAmoebaGlobalOutOfPlaneBendPentic());
......
......@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2010 Stanford University and the Authors. *
* Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -45,10 +45,12 @@ void testSerialization() {
// Create a Force.
AmoebaPiTorsionForce force1;
force1.setForceGroup(3);
force1.addPiTorsion(0, 1, 3, 4, 5, 6, 2.0);
force1.addPiTorsion(0, 2, 3, 5, 12, 13, 2.1);
force1.addPiTorsion(2, 3, 5, 6, 81, 91, 2.2);
force1.addPiTorsion(5, 1, 8, 8, 101, 102, 2.3);
force1.setUsesPeriodicBoundaryConditions(true);
// Serialize and then deserialize it.
......@@ -58,6 +60,8 @@ void testSerialization() {
// Compare the two forces to see if they are identical.
AmoebaPiTorsionForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.usesPeriodicBoundaryConditions(), force2.usesPeriodicBoundaryConditions());
ASSERT_EQUAL(force1.getNumPiTorsions(), force2.getNumPiTorsions());
for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumPiTorsions()); ii++) {
int a1, a2, a3, a4, a5, a6, b1, b2, b3, b4, b5, b6;
......
......@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2010 Stanford University and the Authors. *
* Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -45,9 +45,11 @@ void testSerialization() {
// Create a Force.
AmoebaStretchBendForce force1;
force1.setForceGroup(3);
force1.addStretchBend(0, 1, 3, 1.0, 1.2, 150.1, 83.2, 100.);
force1.addStretchBend(2, 4, 4, 1.1, 2.2, 180.1, 89.2, 100.);
force1.addStretchBend(5, 0, 1, 3.1, 8.2, 140.1, 98.2, 100.);
force1.setUsesPeriodicBoundaryConditions(true);
// Serialize and then deserialize it.
......@@ -57,6 +59,8 @@ void testSerialization() {
// Compare the two forces to see if they are identical.
AmoebaStretchBendForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.usesPeriodicBoundaryConditions(), force2.usesPeriodicBoundaryConditions());
ASSERT_EQUAL(force1.getNumStretchBends(), force2.getNumStretchBends());
for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumStretchBends()); ii++) {
int p11, p12, p13;
......
......@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2010 Stanford University and the Authors. *
* Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -81,6 +81,7 @@ void testSerialization() {
AmoebaTorsionTorsionForce force1;
force1.setForceGroup(3);
for (unsigned int ii = 0; ii < 5; ii++) {
std::vector< std::vector< std::vector<double> > > gridVector;
loadTorsionTorsionGrid(gridVector);
......@@ -89,6 +90,7 @@ void testSerialization() {
for (unsigned int ii = 0; ii < 5; ii++) {
force1.addTorsionTorsion(ii, ii+1,ii+3, ii+4, ii+5, ((ii % 2) ? 1 : 0), (ii % 4));
}
force1.setUsesPeriodicBoundaryConditions(true);
// Serialize and then deserialize it.
......@@ -99,6 +101,8 @@ void testSerialization() {
// Compare the two force1s to see if they are identical.
AmoebaTorsionTorsionForce & force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.usesPeriodicBoundaryConditions(), force2.usesPeriodicBoundaryConditions());
ASSERT_EQUAL(force1.getNumTorsionTorsions(), force2.getNumTorsionTorsions());
for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumTorsionTorsions()); ii++) {
......
......@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2010 Stanford University and the Authors. *
* Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -45,6 +45,7 @@ void testSerialization() {
// Create a Force.
AmoebaVdwForce force1;
force1.setForceGroup(3);
force1.setSigmaCombiningRule("GEOMETRIC");
force1.setEpsilonCombiningRule("GEOMETRIC");
force1.setCutoff(0.9);
......@@ -70,6 +71,7 @@ void testSerialization() {
// Compare the two forces to see if they are identical.
AmoebaVdwForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.getSigmaCombiningRule(), force2.getSigmaCombiningRule());
ASSERT_EQUAL(force1.getEpsilonCombiningRule(), force2.getEpsilonCombiningRule());
ASSERT_EQUAL(force1.getCutoff(), force2.getCutoff());
......
......@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2010 Stanford University and the Authors. *
* Portions copyright (c) 2010-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -45,6 +45,7 @@ void testSerialization() {
// Create a Force.
AmoebaWcaDispersionForce force1;
force1.setForceGroup(3);
force1.setEpso( 1.0);
force1.setEpsh( 1.1);
force1.setRmino( 1.2);
......@@ -68,6 +69,7 @@ void testSerialization() {
AmoebaWcaDispersionForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.getEpso(), force2.getEpso());
ASSERT_EQUAL(force1.getEpsh(), force2.getEpsh());
ASSERT_EQUAL(force1.getRmino(), force2.getRmino());
......
......@@ -37,6 +37,7 @@
#include "openmm/internal/hardware.h"
#include "openmm/internal/vectorize.h"
#include <cmath>
#include <algorithm>
#include <cstring>
#include <sstream>
#include <cstdlib>
......@@ -395,7 +396,7 @@ void CpuCalcPmeReciprocalForceKernel::initialize(int xsize, int ysize, int zsize
// Initialize the b-spline moduli.
int maxSize = max(max(gridx, gridy), gridz);
int maxSize = std::max(std::max(gridx, gridy), gridz);
vector<double> data(PME_ORDER);
vector<double> ddata(PME_ORDER);
vector<double> bsplinesData(maxSize);
......@@ -521,7 +522,7 @@ void CpuCalcPmeReciprocalForceKernel::runWorkerThread(ThreadPool& threads, int i
int gridStart = 4*((index*gridSize)/numThreads);
int gridEnd = 4*(((index+1)*gridSize)/numThreads);
int complexSize = gridx*gridy*(gridz/2+1);
int complexStart = max(1, ((index*complexSize)/numThreads));
int complexStart = std::max(1, ((index*complexSize)/numThreads));
int complexEnd = (((index+1)*complexSize)/numThreads);
spreadCharge(posq, tempGrid[index], gridx, gridy, gridz, numParticles, periodicBoxVectors, recipBoxVectors, atomicCounter);
threads.syncThreads();
......
......@@ -364,9 +364,11 @@ void CudaIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, const D
// Apply hard wall constraints.
void* hardwallArgs[] = {&cu.getPosq().getDevicePointer(), &posCorrection, &cu.getVelm().getDevicePointer(),
&pairParticles->getDevicePointer(), &integration.getStepSize().getDevicePointer(), maxDrudeDistancePtr, hardwallscaleDrudePtr};
cu.executeKernel(hardwallKernel, hardwallArgs, pairParticles->getSize());
if (maxDrudeDistance > 0) {
void* hardwallArgs[] = {&cu.getPosq().getDevicePointer(), &posCorrection, &cu.getVelm().getDevicePointer(),
&pairParticles->getDevicePointer(), &integration.getStepSize().getDevicePointer(), maxDrudeDistancePtr, hardwallscaleDrudePtr};
cu.executeKernel(hardwallKernel, hardwallArgs, pairParticles->getSize());
}
integration.computeVirtualSites();
// Update the time and step count.
......
......@@ -32,7 +32,7 @@ if (k1 != 0) {
// Compute the second anisotropic force.
if (k2 != 0) {
real3 dir = make_real3(pos3.x-pos4.x, pos3.y-pos4.y, pos3.z-pos4.z);
real3 dir = make_real3(pos4.x-pos5.x, pos4.y-pos5.y, pos4.z-pos5.z);
real invDist = RSQRT(dot(dir, dir));
dir *= invDist;
real rprime = dot(dir, delta);
......
......@@ -197,7 +197,7 @@ int main(int argc, char* argv[]) {
try {
registerDrudeCudaKernelFactories();
if (argc > 1)
Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1]));
Platform::getPlatformByName("CUDA").setPropertyDefaultValue("Precision", std::string(argv[1]));
testSingleParticle();
testAnisotropicParticle();
testThole();
......
......@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2013-2015 Stanford University and the Authors. *
* Portions copyright (c) 2013-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -179,13 +179,74 @@ void testWater() {
ASSERT_USUALLY_EQUAL_TOL(expectedTemp, ke/(0.5*numDof*BOLTZ), 0.02);
}
void testForceEnergyConsistency() {
// Create a box of polarizable particles.
const int gridSize = 3;
const int numAtoms = gridSize*gridSize*gridSize;
const double spacing = 0.6;
const double boxSize = spacing*(gridSize+1);
const double temperature = 300.0;
const double temperatureDrude = 10.0;
System system;
vector<Vec3> positions;
NonbondedForce* nonbonded = new NonbondedForce();
DrudeForce* drude = new DrudeForce();
system.addForce(nonbonded);
system.addForce(drude);
system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize));
nonbonded->setNonbondedMethod(NonbondedForce::PME);
nonbonded->setCutoffDistance(1.0);
nonbonded->setUseSwitchingFunction(true);
nonbonded->setSwitchingDistance(0.9);
nonbonded->setEwaldErrorTolerance(5e-5);
for (int i = 0; i < numAtoms; i++) {
int startIndex = system.getNumParticles();
system.addParticle(1.0);
system.addParticle(1.0);
nonbonded->addParticle(1.0, 0.3, 1.0);
nonbonded->addParticle(-1.0, 0.3, 1.0);
nonbonded->addException(startIndex, startIndex+1, 0, 1, 0);
drude->addParticle(startIndex+1, startIndex, -1, -1, -1, -1.0, 0.001, 1, 1);
}
for (int i = 0; i < gridSize; i++)
for (int j = 0; j < gridSize; j++)
for (int k = 0; k < gridSize; k++) {
Vec3 pos(i*spacing, j*spacing, k*spacing);
positions.push_back(pos);
positions.push_back(pos);
}
// Simulate it and check that force and energy remain consistent.
DrudeLangevinIntegrator integ(temperature, 50.0, temperatureDrude, 50.0, 0.001);
Platform& platform = Platform::getPlatformByName("CUDA");
Context context(system, integ, platform);
context.setPositions(positions);
State prevState;
for (int i = 0; i < 100; i++) {
State state = context.getState(State::Energy | State::Forces | State::Positions);
if (i > 0) {
double expectedEnergyChange = 0;
for (int j = 0; j < system.getNumParticles(); j++) {
Vec3 delta = state.getPositions()[j]-prevState.getPositions()[j];
expectedEnergyChange -= 0.5*(state.getForces()[j]+prevState.getForces()[j]).dot(delta);
}
ASSERT_EQUAL_TOL(expectedEnergyChange, state.getPotentialEnergy()-prevState.getPotentialEnergy(), 0.05);
}
prevState = state;
integ.step(1);
}
}
int main(int argc, char* argv[]) {
try {
registerDrudeCudaKernelFactories();
if (argc > 1)
Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", string(argv[1]));
Platform::getPlatformByName("CUDA").setPropertyDefaultValue("Precision", string(argv[1]));
testSinglePair();
testWater();
testForceEnergyConsistency();
}
catch(const std::exception& e) {
std::cout << "exception: " << e.what() << std::endl;
......
......@@ -110,7 +110,7 @@ void testWater() {
State state = context.getState(State::Energy);
double initialEnergy;
int numSteps = 1000;
double maxNorm = (platform.getPropertyValue(context, "CudaPrecision") == "double" ? 1.0 : 5.0);
double maxNorm = (platform.getPropertyValue(context, "Precision") == "double" ? 1.0 : 5.0);
for (int i = 0; i < numSteps; i++) {
integ.step(1);
state = context.getState(State::Energy | State::Forces);
......@@ -131,7 +131,7 @@ int main(int argc, char* argv[]) {
try {
registerDrudeCudaKernelFactories();
if (argc > 1)
Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", string(argv[1]));
Platform::getPlatformByName("CUDA").setPropertyDefaultValue("Precision", string(argv[1]));
testWater();
}
catch(const std::exception& e) {
......
......@@ -376,7 +376,8 @@ void OpenCLIntegrateDrudeLangevinStepKernel::execute(ContextImpl& context, const
// Apply hard wall constraints.
cl.executeKernel(hardwallKernel, pairParticles->getSize());
if (maxDrudeDistance > 0)
cl.executeKernel(hardwallKernel, pairParticles->getSize());
integration.computeVirtualSites();
// Update the time and step count.
......
......@@ -32,7 +32,7 @@ if (k1 != 0) {
// Compute the second anisotropic force.
if (k2 != 0) {
real4 dir = (real4) (pos3.xyz-pos4.xyz, 0);
real4 dir = (real4) (pos4.xyz-pos5.xyz, 0);
real invDist = RSQRT(dot(dir, dir));
dir *= invDist;
real rprime = dot(dir, delta);
......
......@@ -197,7 +197,7 @@ int main(int argc, char* argv[]) {
try {
registerDrudeOpenCLKernelFactories();
if (argc > 1)
Platform::getPlatformByName("OpenCL").setPropertyDefaultValue("OpenCLPrecision", std::string(argv[1]));
Platform::getPlatformByName("OpenCL").setPropertyDefaultValue("Precision", std::string(argv[1]));
testSingleParticle();
testAnisotropicParticle();
testThole();
......
......@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2013-2015 Stanford University and the Authors. *
* Portions copyright (c) 2013-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -179,13 +179,74 @@ void testWater() {
ASSERT_USUALLY_EQUAL_TOL(expectedTemp, ke/(0.5*numDof*BOLTZ), 0.02);
}
void testForceEnergyConsistency() {
// Create a box of polarizable particles.
const int gridSize = 3;
const int numAtoms = gridSize*gridSize*gridSize;
const double spacing = 0.6;
const double boxSize = spacing*(gridSize+1);
const double temperature = 300.0;
const double temperatureDrude = 10.0;
System system;
vector<Vec3> positions;
NonbondedForce* nonbonded = new NonbondedForce();
DrudeForce* drude = new DrudeForce();
system.addForce(nonbonded);
system.addForce(drude);
system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize));
nonbonded->setNonbondedMethod(NonbondedForce::PME);
nonbonded->setCutoffDistance(1.0);
nonbonded->setUseSwitchingFunction(true);
nonbonded->setSwitchingDistance(0.9);
nonbonded->setEwaldErrorTolerance(5e-5);
for (int i = 0; i < numAtoms; i++) {
int startIndex = system.getNumParticles();
system.addParticle(1.0);
system.addParticle(1.0);
nonbonded->addParticle(1.0, 0.3, 1.0);
nonbonded->addParticle(-1.0, 0.3, 1.0);
nonbonded->addException(startIndex, startIndex+1, 0, 1, 0);
drude->addParticle(startIndex+1, startIndex, -1, -1, -1, -1.0, 0.001, 1, 1);
}
for (int i = 0; i < gridSize; i++)
for (int j = 0; j < gridSize; j++)
for (int k = 0; k < gridSize; k++) {
Vec3 pos(i*spacing, j*spacing, k*spacing);
positions.push_back(pos);
positions.push_back(pos);
}
// Simulate it and check that force and energy remain consistent.
DrudeLangevinIntegrator integ(temperature, 50.0, temperatureDrude, 50.0, 0.001);
Platform& platform = Platform::getPlatformByName("OpenCL");
Context context(system, integ, platform);
context.setPositions(positions);
State prevState;
for (int i = 0; i < 100; i++) {
State state = context.getState(State::Energy | State::Forces | State::Positions);
if (i > 0) {
double expectedEnergyChange = 0;
for (int j = 0; j < system.getNumParticles(); j++) {
Vec3 delta = state.getPositions()[j]-prevState.getPositions()[j];
expectedEnergyChange -= 0.5*(state.getForces()[j]+prevState.getForces()[j]).dot(delta);
}
ASSERT_EQUAL_TOL(expectedEnergyChange, state.getPotentialEnergy()-prevState.getPotentialEnergy(), 0.05);
}
prevState = state;
integ.step(1);
}
}
int main(int argc, char* argv[]) {
try {
registerDrudeOpenCLKernelFactories();
if (argc > 1)
Platform::getPlatformByName("OpenCL").setPropertyDefaultValue("OpenCLPrecision", string(argv[1]));
Platform::getPlatformByName("OpenCL").setPropertyDefaultValue("Precision", string(argv[1]));
testSinglePair();
testWater();
testForceEnergyConsistency();
}
catch(const std::exception& e) {
std::cout << "exception: " << e.what() << std::endl;
......
......@@ -110,7 +110,7 @@ void testWater() {
State state = context.getState(State::Energy);
double initialEnergy;
int numSteps = 1000;
double maxNorm = (platform.getPropertyValue(context, "OpenCLPrecision") == "double" ? 1.0 : 5.0);
double maxNorm = (platform.getPropertyValue(context, "Precision") == "double" ? 1.0 : 5.0);
for (int i = 0; i < numSteps; i++) {
integ.step(1);
state = context.getState(State::Energy | State::Forces);
......@@ -131,7 +131,7 @@ int main(int argc, char* argv[]) {
try {
registerDrudeOpenCLKernelFactories();
if (argc > 1)
Platform::getPlatformByName("OpenCL").setPropertyDefaultValue("OpenCLPrecision", string(argv[1]));
Platform::getPlatformByName("OpenCL").setPropertyDefaultValue("Precision", string(argv[1]));
testWater();
}
catch(const std::exception& e) {
......
......@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2013-2015 Stanford University and the Authors. *
* Portions copyright (c) 2013-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -179,11 +179,72 @@ void testWater() {
ASSERT_USUALLY_EQUAL_TOL(expectedTemp, ke/(0.5*numDof*BOLTZ), 0.03);
}
void testForceEnergyConsistency() {
// Create a box of polarizable particles.
const int gridSize = 3;
const int numAtoms = gridSize*gridSize*gridSize;
const double spacing = 0.6;
const double boxSize = spacing*(gridSize+1);
const double temperature = 300.0;
const double temperatureDrude = 10.0;
System system;
vector<Vec3> positions;
NonbondedForce* nonbonded = new NonbondedForce();
DrudeForce* drude = new DrudeForce();
system.addForce(nonbonded);
system.addForce(drude);
system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize));
nonbonded->setNonbondedMethod(NonbondedForce::PME);
nonbonded->setCutoffDistance(1.0);
nonbonded->setUseSwitchingFunction(true);
nonbonded->setSwitchingDistance(0.9);
nonbonded->setEwaldErrorTolerance(5e-5);
for (int i = 0; i < numAtoms; i++) {
int startIndex = system.getNumParticles();
system.addParticle(1.0);
system.addParticle(1.0);
nonbonded->addParticle(1.0, 0.3, 1.0);
nonbonded->addParticle(-1.0, 0.3, 1.0);
nonbonded->addException(startIndex, startIndex+1, 0, 1, 0);
drude->addParticle(startIndex+1, startIndex, -1, -1, -1, -1.0, 0.001, 1, 1);
}
for (int i = 0; i < gridSize; i++)
for (int j = 0; j < gridSize; j++)
for (int k = 0; k < gridSize; k++) {
Vec3 pos(i*spacing, j*spacing, k*spacing);
positions.push_back(pos);
positions.push_back(pos);
}
// Simulate it and check that force and energy remain consistent.
DrudeLangevinIntegrator integ(temperature, 50.0, temperatureDrude, 50.0, 0.001);
Platform& platform = Platform::getPlatformByName("Reference");
Context context(system, integ, platform);
context.setPositions(positions);
State prevState;
for (int i = 0; i < 100; i++) {
State state = context.getState(State::Energy | State::Forces | State::Positions);
if (i > 0) {
double expectedEnergyChange = 0;
for (int j = 0; j < system.getNumParticles(); j++) {
Vec3 delta = state.getPositions()[j]-prevState.getPositions()[j];
expectedEnergyChange -= 0.5*(state.getForces()[j]+prevState.getForces()[j]).dot(delta);
}
ASSERT_EQUAL_TOL(expectedEnergyChange, state.getPotentialEnergy()-prevState.getPotentialEnergy(), 0.05);
}
prevState = state;
integ.step(1);
}
}
int main() {
try {
registerDrudeReferenceKernelFactories();
testSinglePair();
testWater();
testForceEnergyConsistency();
}
catch(const std::exception& e) {
std::cout << "exception: " << e.what() << std::endl;
......
......@@ -554,7 +554,7 @@ int main(int argc, char* argv[]) {
try {
registerRPMDCudaKernelFactories();
if (argc > 1)
Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", string(argv[1]));
Platform::getPlatformByName("CUDA").setPropertyDefaultValue("Precision", string(argv[1]));
testFreeParticles();
testParaHydrogen();
testCMMotionRemoval();
......
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