Commit 8df54762 authored by Lee-Ping Wang's avatar Lee-Ping Wang
Browse files

Merge branch 'master' of github.com:leeping/openmm

parents 3cb25ad8 59854c5e
...@@ -56,6 +56,7 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe ...@@ -56,6 +56,7 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe
const int numMolecules = 70; const int numMolecules = 70;
const int numParticles = numMolecules*2; const int numParticles = numMolecules*2;
const double boxSize = 10.0; const double boxSize = 10.0;
const double cutoff = 2.0;
// Create two systems: one with a GBSAOBCForce, and one using a CustomGBForce to implement the same interaction. // Create two systems: one with a GBSAOBCForce, and one using a CustomGBForce to implement the same interaction.
...@@ -69,8 +70,8 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe ...@@ -69,8 +70,8 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe
customSystem.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0.0, 0.0), Vec3(0.0, boxSize, 0.0), Vec3(0.0, 0.0, boxSize)); customSystem.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0.0, 0.0), Vec3(0.0, boxSize, 0.0), Vec3(0.0, 0.0, boxSize));
GBSAOBCForce* obc = new GBSAOBCForce(); GBSAOBCForce* obc = new GBSAOBCForce();
CustomGBForce* custom = new CustomGBForce(); CustomGBForce* custom = new CustomGBForce();
obc->setCutoffDistance(2.0); obc->setCutoffDistance(cutoff);
custom->setCutoffDistance(2.0); custom->setCutoffDistance(cutoff);
custom->addPerParticleParameter("q"); custom->addPerParticleParameter("q");
custom->addPerParticleParameter("radius"); custom->addPerParticleParameter("radius");
custom->addPerParticleParameter("scale"); custom->addPerParticleParameter("scale");
...@@ -86,7 +87,13 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe ...@@ -86,7 +87,13 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe
custom->addComputedValue("B", "1/(1/or-tanh(1*psi-0.8*psi^2+4.85*psi^3)/radius);" custom->addComputedValue("B", "1/(1/or-tanh(1*psi-0.8*psi^2+4.85*psi^3)/radius);"
"psi=I*or; or=radius-0.009", CustomGBForce::SingleParticle); "psi=I*or; or=radius-0.009", CustomGBForce::SingleParticle);
custom->addEnergyTerm("28.3919551*(radius+0.14)^2*(radius/B)^6-0.5*138.935456*(1/soluteDielectric-1/solventDielectric)*q^2/B", CustomGBForce::SingleParticle); custom->addEnergyTerm("28.3919551*(radius+0.14)^2*(radius/B)^6-0.5*138.935456*(1/soluteDielectric-1/solventDielectric)*q^2/B", CustomGBForce::SingleParticle);
custom->addEnergyTerm("-138.935456*(1/soluteDielectric-1/solventDielectric)*q1*q2/f;" string invCutoffString = "";
if (obcMethod != GBSAOBCForce::NoCutoff) {
stringstream s;
s<<(1.0/cutoff);
invCutoffString = s.str();
}
custom->addEnergyTerm("138.935485*(1/soluteDielectric-1/solventDielectric)*q1*q2*("+invCutoffString+"-1/f);"
"f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))", CustomGBForce::ParticlePairNoExclusions); "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))", CustomGBForce::ParticlePairNoExclusions);
vector<Vec3> positions(numParticles); vector<Vec3> positions(numParticles);
vector<Vec3> velocities(numParticles); vector<Vec3> velocities(numParticles);
......
...@@ -233,6 +233,43 @@ void testVelocityConstraints() { ...@@ -233,6 +233,43 @@ void testVelocityConstraints() {
} }
} }
void testConstrainedMasslessParticles() {
System system;
system.addParticle(0.0);
system.addParticle(1.0);
system.addConstraint(0, 1, 1.5);
vector<Vec3> positions(2);
positions[0] = Vec3(-1, 0, 0);
positions[1] = Vec3(1, 0, 0);
CustomIntegrator integrator(0.002);
integrator.addPerDofVariable("oldx", 0);
integrator.addComputePerDof("v", "v+dt*f/m");
integrator.addComputePerDof("oldx", "x");
integrator.addComputePerDof("x", "x+dt*v");
integrator.addConstrainPositions();
integrator.addComputePerDof("v", "(x-oldx)/dt");
bool failed = false;
try {
// This should throw an exception.
Context context(system, integrator, platform);
}
catch (exception& ex) {
failed = true;
}
ASSERT(failed);
// Now make both particles massless, which should work.
system.setParticleMass(1, 0.0);
Context context(system, integrator, platform);
context.setPositions(positions);
context.setVelocitiesToTemperature(300.0);
integrator.step(1);
State state = context.getState(State::Velocities | State::Positions);
ASSERT_EQUAL(0.0, state.getVelocities()[0][0]);
}
/** /**
* Test an integrator with an AndersenThermostat to see if updateContextState() * Test an integrator with an AndersenThermostat to see if updateContextState()
* is being handled correctly. * is being handled correctly.
...@@ -724,6 +761,7 @@ int main(int argc, char* argv[]) { ...@@ -724,6 +761,7 @@ int main(int argc, char* argv[]) {
testSingleBond(); testSingleBond();
testConstraints(); testConstraints();
testVelocityConstraints(); testVelocityConstraints();
testConstrainedMasslessParticles();
testWithThermostat(); testWithThermostat();
testMonteCarlo(); testMonteCarlo();
testSum(); testSum();
......
...@@ -177,6 +177,37 @@ void testConstraints() { ...@@ -177,6 +177,37 @@ void testConstraints() {
} }
} }
void testConstrainedMasslessParticles() {
System system;
system.addParticle(0.0);
system.addParticle(1.0);
system.addConstraint(0, 1, 1.5);
vector<Vec3> positions(2);
positions[0] = Vec3(-1, 0, 0);
positions[1] = Vec3(1, 0, 0);
LangevinIntegrator integrator(300.0, 2.0, 0.01);
bool failed = false;
try {
// This should throw an exception.
Context context(system, integrator, platform);
}
catch (exception& ex) {
failed = true;
}
ASSERT(failed);
// Now make both particles massless, which should work.
system.setParticleMass(1, 0.0);
Context context(system, integrator, platform);
context.setPositions(positions);
context.setVelocitiesToTemperature(300.0);
integrator.step(1);
State state = context.getState(State::Velocities);
ASSERT_EQUAL(0.0, state.getVelocities()[0][0]);
}
void testRandomSeed() { void testRandomSeed() {
const int numParticles = 8; const int numParticles = 8;
const double temp = 100.0; const double temp = 100.0;
...@@ -241,6 +272,7 @@ int main(int argc, char* argv[]) { ...@@ -241,6 +272,7 @@ int main(int argc, char* argv[]) {
testSingleBond(); testSingleBond();
testTemperature(); testTemperature();
testConstraints(); testConstraints();
testConstrainedMasslessParticles();
testRandomSeed(); testRandomSeed();
} }
catch(const exception& e) { catch(const exception& e) {
......
...@@ -172,6 +172,37 @@ void testConstraints() { ...@@ -172,6 +172,37 @@ void testConstraints() {
} }
} }
void testConstrainedMasslessParticles() {
System system;
system.addParticle(0.0);
system.addParticle(1.0);
system.addConstraint(0, 1, 1.5);
vector<Vec3> positions(2);
positions[0] = Vec3(-1, 0, 0);
positions[1] = Vec3(1, 0, 0);
VariableLangevinIntegrator integrator(300.0, 2.0, 0.01);
bool failed = false;
try {
// This should throw an exception.
Context context(system, integrator, platform);
}
catch (exception& ex) {
failed = true;
}
ASSERT(failed);
// Now make both particles massless, which should work.
system.setParticleMass(1, 0.0);
Context context(system, integrator, platform);
context.setPositions(positions);
context.setVelocitiesToTemperature(300.0);
integrator.step(1);
State state = context.getState(State::Velocities);
ASSERT_EQUAL(0.0, state.getVelocities()[0][0]);
}
void testRandomSeed() { void testRandomSeed() {
const int numParticles = 8; const int numParticles = 8;
const double temp = 100.0; const double temp = 100.0;
...@@ -295,6 +326,7 @@ int main(int argc, char* argv[]) { ...@@ -295,6 +326,7 @@ int main(int argc, char* argv[]) {
testSingleBond(); testSingleBond();
testTemperature(); testTemperature();
testConstraints(); testConstraints();
testConstrainedMasslessParticles();
testRandomSeed(); testRandomSeed();
testArgonBox(); testArgonBox();
} }
......
...@@ -211,6 +211,37 @@ void testConstrainedClusters() { ...@@ -211,6 +211,37 @@ void testConstrainedClusters() {
ASSERT(context.getState(State::Positions).getTime() > 0.1); ASSERT(context.getState(State::Positions).getTime() > 0.1);
} }
void testConstrainedMasslessParticles() {
System system;
system.addParticle(0.0);
system.addParticle(1.0);
system.addConstraint(0, 1, 1.5);
vector<Vec3> positions(2);
positions[0] = Vec3(-1, 0, 0);
positions[1] = Vec3(1, 0, 0);
VariableVerletIntegrator integrator(0.01);
bool failed = false;
try {
// This should throw an exception.
Context context(system, integrator, platform);
}
catch (exception& ex) {
failed = true;
}
ASSERT(failed);
// Now make both particles massless, which should work.
system.setParticleMass(1, 0.0);
Context context(system, integrator, platform);
context.setPositions(positions);
context.setVelocitiesToTemperature(300.0);
integrator.step(1);
State state = context.getState(State::Velocities);
ASSERT_EQUAL(0.0, state.getVelocities()[0][0]);
}
void testArgonBox() { void testArgonBox() {
const int gridSize = 8; const int gridSize = 8;
const double mass = 40.0; // Ar atomic mass const double mass = 40.0; // Ar atomic mass
...@@ -274,6 +305,7 @@ int main(int argc, char* argv[]) { ...@@ -274,6 +305,7 @@ int main(int argc, char* argv[]) {
testSingleBond(); testSingleBond();
testConstraints(); testConstraints();
testConstrainedClusters(); testConstrainedClusters();
testConstrainedMasslessParticles();
testArgonBox(); testArgonBox();
} }
catch(const exception& e) { catch(const exception& e) {
......
...@@ -203,6 +203,37 @@ void testConstrainedClusters() { ...@@ -203,6 +203,37 @@ void testConstrainedClusters() {
} }
} }
void testConstrainedMasslessParticles() {
System system;
system.addParticle(0.0);
system.addParticle(1.0);
system.addConstraint(0, 1, 1.5);
vector<Vec3> positions(2);
positions[0] = Vec3(-1, 0, 0);
positions[1] = Vec3(1, 0, 0);
VerletIntegrator integrator(0.01);
bool failed = false;
try {
// This should throw an exception.
Context context(system, integrator, platform);
}
catch (exception& ex) {
failed = true;
}
ASSERT(failed);
// Now make both particles massless, which should work.
system.setParticleMass(1, 0.0);
Context context(system, integrator, platform);
context.setPositions(positions);
context.setVelocitiesToTemperature(300.0);
integrator.step(1);
State state = context.getState(State::Velocities);
ASSERT_EQUAL(0.0, state.getVelocities()[0][0]);
}
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
try { try {
if (argc > 1) if (argc > 1)
...@@ -210,6 +241,7 @@ int main(int argc, char* argv[]) { ...@@ -210,6 +241,7 @@ int main(int argc, char* argv[]) {
testSingleBond(); testSingleBond();
testConstraints(); testConstraints();
testConstrainedClusters(); testConstrainedClusters();
testConstrainedMasslessParticles();
} }
catch(const exception& e) { catch(const exception& e) {
cout << "exception: " << e.what() << endl; cout << "exception: " << e.what() << endl;
......
...@@ -227,10 +227,10 @@ cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threa ...@@ -227,10 +227,10 @@ cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threa
source<<"for (int z = get_local_id(0); z < ZSIZE; z += get_local_size(0))\n"; source<<"for (int z = get_local_id(0); z < ZSIZE; z += get_local_size(0))\n";
source<<"out[y*(ZSIZE*XSIZE)+z*XSIZE+x] = data"<<(stage%2)<<"[z];\n"; source<<"out[y*(ZSIZE*XSIZE)+z*XSIZE+x] = data"<<(stage%2)<<"[z];\n";
} }
else { else {
source<<"if (index < XSIZE*YSIZE)\n"; source<<"if (index < XSIZE*YSIZE)\n";
source<<"out[y*(ZSIZE*XSIZE)+(get_local_id(0)%ZSIZE)*XSIZE+x] = data"<<(stage%2)<<"[get_local_id(0)];\n"; source<<"out[y*(ZSIZE*XSIZE)+(get_local_id(0)%ZSIZE)*XSIZE+x] = data"<<(stage%2)<<"[get_local_id(0)];\n";
} }
source<<"barrier(CLK_GLOBAL_MEM_FENCE);"; source<<"barrier(CLK_GLOBAL_MEM_FENCE);";
map<string, string> replacements; map<string, string> replacements;
replacements["XSIZE"] = context.intToString(xsize); replacements["XSIZE"] = context.intToString(xsize);
......
...@@ -141,15 +141,21 @@ OpenCLIntegrationUtilities::OpenCLIntegrationUtilities(OpenCLContext& context, c ...@@ -141,15 +141,21 @@ OpenCLIntegrationUtilities::OpenCLIntegrationUtilities(OpenCLContext& context, c
// Record the set of constraints and how many constraints each atom is involved in. // Record the set of constraints and how many constraints each atom is involved in.
int numConstraints = system.getNumConstraints(); vector<int> atom1;
vector<int> atom1(numConstraints); vector<int> atom2;
vector<int> atom2(numConstraints); vector<double> distance;
vector<double> distance(numConstraints);
vector<int> constraintCount(context.getNumAtoms(), 0); vector<int> constraintCount(context.getNumAtoms(), 0);
for (int i = 0; i < numConstraints; i++) { for (int i = 0; i < system.getNumConstraints(); i++) {
system.getConstraintParameters(i, atom1[i], atom2[i], distance[i]); int p1, p2;
constraintCount[atom1[i]]++; double d;
constraintCount[atom2[i]]++; system.getConstraintParameters(i, p1, p2, d);
if (system.getParticleMass(p1) != 0 || system.getParticleMass(p2) != 0) {
atom1.push_back(p1);
atom2.push_back(p2);
distance.push_back(d);
constraintCount[p1]++;
constraintCount[p2]++;
}
} }
// Identify clusters of three atoms that can be treated with SETTLE. First, for every // Identify clusters of three atoms that can be treated with SETTLE. First, for every
......
...@@ -5978,7 +5978,7 @@ void OpenCLRemoveCMMotionKernel::initialize(const System& system, const CMMotion ...@@ -5978,7 +5978,7 @@ void OpenCLRemoveCMMotionKernel::initialize(const System& system, const CMMotion
for (int i = 0; i < numAtoms; i++) for (int i = 0; i < numAtoms; i++)
totalMass += system.getParticleMass(i); totalMass += system.getParticleMass(i);
map<string, string> defines; map<string, string> defines;
defines["INVERSE_TOTAL_MASS"] = cl.doubleToString(1.0/totalMass); defines["INVERSE_TOTAL_MASS"] = cl.doubleToString(totalMass == 0 ? 0.0 : 1.0/totalMass);
cl::Program program = cl.createProgram(OpenCLKernelSources::removeCM, defines); cl::Program program = cl.createProgram(OpenCLKernelSources::removeCM, defines);
kernel1 = cl::Kernel(program, "calcCenterOfMassMomentum"); kernel1 = cl::Kernel(program, "calcCenterOfMassMomentum");
kernel1.setArg<cl_int>(0, numAtoms); kernel1.setArg<cl_int>(0, numAtoms);
......
...@@ -12,19 +12,18 @@ __kernel void execFFT(__global const real2* restrict in, __global real2* restric ...@@ -12,19 +12,18 @@ __kernel void execFFT(__global const real2* restrict in, __global real2* restric
w[i] = (real2) (cos(-sign*i*2*M_PI/ZSIZE), sin(-sign*i*2*M_PI/ZSIZE)); w[i] = (real2) (cos(-sign*i*2*M_PI/ZSIZE), sin(-sign*i*2*M_PI/ZSIZE));
barrier(CLK_LOCAL_MEM_FENCE); barrier(CLK_LOCAL_MEM_FENCE);
for (int baseIndex = get_group_id(0)*BLOCKS_PER_GROUP; baseIndex < XSIZE*YSIZE; baseIndex += get_num_groups(0)*BLOCKS_PER_GROUP) { for (int baseIndex = get_group_id(0)*BLOCKS_PER_GROUP; baseIndex < XSIZE*YSIZE; baseIndex += get_num_groups(0)*BLOCKS_PER_GROUP) {
int index = baseIndex+get_local_id(0)/ZSIZE; int index = baseIndex+get_local_id(0)/ZSIZE;
int x = index/YSIZE; int x = index/YSIZE;
int y = index-x*YSIZE; int y = index-x*YSIZE;
#if LOOP_REQUIRED #if LOOP_REQUIRED
for (int z = get_local_id(0); z < ZSIZE; z += get_local_size(0)) for (int z = get_local_id(0); z < ZSIZE; z += get_local_size(0))
data0[z] = in[x*(YSIZE*ZSIZE)+y*ZSIZE+z]; data0[z] = in[x*(YSIZE*ZSIZE)+y*ZSIZE+z];
#else #else
if (index < XSIZE*YSIZE) if (index < XSIZE*YSIZE)
data0[get_local_id(0)] = in[x*(YSIZE*ZSIZE)+y*ZSIZE+get_local_id(0)%ZSIZE]; data0[get_local_id(0)] = in[x*(YSIZE*ZSIZE)+y*ZSIZE+get_local_id(0)%ZSIZE];
#endif #endif
barrier(CLK_LOCAL_MEM_FENCE); barrier(CLK_LOCAL_MEM_FENCE);
COMPUTE_FFT COMPUTE_FFT
} }
} }
...@@ -444,11 +444,16 @@ __kernel void computeGBSAForce1( ...@@ -444,11 +444,16 @@ __kernel void computeGBSAForce1(
real expTerm = EXP(-D_ij); real expTerm = EXP(-D_ij);
real denominator2 = r2 + alpha2_ij*expTerm; real denominator2 = r2 + alpha2_ij*expTerm;
real denominator = SQRT(denominator2); real denominator = SQRT(denominator2);
real tempEnergy = (PREFACTOR*posq1.w*posq2.w)*RECIP(denominator); real scaledChargeProduct = PREFACTOR*posq1.w*posq2.w;
real tempEnergy = scaledChargeProduct*RECIP(denominator);
real Gpol = tempEnergy*RECIP(denominator2); real Gpol = tempEnergy*RECIP(denominator2);
real dGpol_dalpha2_ij = -0.5f*Gpol*expTerm*(1.0f+D_ij); real dGpol_dalpha2_ij = -0.5f*Gpol*expTerm*(1.0f+D_ij);
real dEdR = Gpol*(1.0f - 0.25f*expTerm); real dEdR = Gpol*(1.0f - 0.25f*expTerm);
force.w += dGpol_dalpha2_ij*bornRadius2; force.w += dGpol_dalpha2_ij*bornRadius2;
#ifdef USE_CUTOFF
if (atom1 != y*TILE_SIZE+j)
tempEnergy -= scaledChargeProduct/CUTOFF;
#endif
energy += 0.5f*tempEnergy; energy += 0.5f*tempEnergy;
delta.xyz *= dEdR; delta.xyz *= dEdR;
force.xyz -= delta.xyz; force.xyz -= delta.xyz;
...@@ -494,11 +499,15 @@ __kernel void computeGBSAForce1( ...@@ -494,11 +499,15 @@ __kernel void computeGBSAForce1(
real expTerm = EXP(-D_ij); real expTerm = EXP(-D_ij);
real denominator2 = r2 + alpha2_ij*expTerm; real denominator2 = r2 + alpha2_ij*expTerm;
real denominator = SQRT(denominator2); real denominator = SQRT(denominator2);
real tempEnergy = (PREFACTOR*posq1.w*posq2.w)*RECIP(denominator); real scaledChargeProduct = PREFACTOR*posq1.w*posq2.w;
real tempEnergy = scaledChargeProduct*RECIP(denominator);
real Gpol = tempEnergy*RECIP(denominator2); real Gpol = tempEnergy*RECIP(denominator2);
real dGpol_dalpha2_ij = -0.5f*Gpol*expTerm*(1.0f+D_ij); real dGpol_dalpha2_ij = -0.5f*Gpol*expTerm*(1.0f+D_ij);
real dEdR = Gpol*(1.0f - 0.25f*expTerm); real dEdR = Gpol*(1.0f - 0.25f*expTerm);
force.w += dGpol_dalpha2_ij*bornRadius2; force.w += dGpol_dalpha2_ij*bornRadius2;
#ifdef USE_CUTOFF
tempEnergy -= scaledChargeProduct/CUTOFF;
#endif
energy += tempEnergy; energy += tempEnergy;
delta.xyz *= dEdR; delta.xyz *= dEdR;
force.xyz -= delta.xyz; force.xyz -= delta.xyz;
...@@ -657,11 +666,15 @@ __kernel void computeGBSAForce1( ...@@ -657,11 +666,15 @@ __kernel void computeGBSAForce1(
real expTerm = EXP(-D_ij); real expTerm = EXP(-D_ij);
real denominator2 = r2 + alpha2_ij*expTerm; real denominator2 = r2 + alpha2_ij*expTerm;
real denominator = SQRT(denominator2); real denominator = SQRT(denominator2);
real tempEnergy = (PREFACTOR*posq1.w*posq2.w)*RECIP(denominator); real scaledChargeProduct = PREFACTOR*posq1.w*posq2.w;
real tempEnergy = scaledChargeProduct*RECIP(denominator);
real Gpol = tempEnergy*RECIP(denominator2); real Gpol = tempEnergy*RECIP(denominator2);
real dGpol_dalpha2_ij = -0.5f*Gpol*expTerm*(1.0f+D_ij); real dGpol_dalpha2_ij = -0.5f*Gpol*expTerm*(1.0f+D_ij);
real dEdR = Gpol*(1.0f - 0.25f*expTerm); real dEdR = Gpol*(1.0f - 0.25f*expTerm);
force.w += dGpol_dalpha2_ij*bornRadius2; force.w += dGpol_dalpha2_ij*bornRadius2;
#ifdef USE_CUTOFF
tempEnergy -= scaledChargeProduct/CUTOFF;
#endif
energy += tempEnergy; energy += tempEnergy;
delta.xyz *= dEdR; delta.xyz *= dEdR;
force.xyz -= delta.xyz; force.xyz -= delta.xyz;
...@@ -701,11 +714,15 @@ __kernel void computeGBSAForce1( ...@@ -701,11 +714,15 @@ __kernel void computeGBSAForce1(
real expTerm = EXP(-D_ij); real expTerm = EXP(-D_ij);
real denominator2 = r2 + alpha2_ij*expTerm; real denominator2 = r2 + alpha2_ij*expTerm;
real denominator = SQRT(denominator2); real denominator = SQRT(denominator2);
real tempEnergy = (PREFACTOR*posq1.w*posq2.w)*RECIP(denominator); real scaledChargeProduct = PREFACTOR*posq1.w*posq2.w;
real tempEnergy = scaledChargeProduct*RECIP(denominator);
real Gpol = tempEnergy*RECIP(denominator2); real Gpol = tempEnergy*RECIP(denominator2);
real dGpol_dalpha2_ij = -0.5f*Gpol*expTerm*(1.0f+D_ij); real dGpol_dalpha2_ij = -0.5f*Gpol*expTerm*(1.0f+D_ij);
real dEdR = Gpol*(1.0f - 0.25f*expTerm); real dEdR = Gpol*(1.0f - 0.25f*expTerm);
force.w += dGpol_dalpha2_ij*bornRadius2; force.w += dGpol_dalpha2_ij*bornRadius2;
#ifdef USE_CUTOFF
tempEnergy -= scaledChargeProduct/CUTOFF;
#endif
energy += tempEnergy; energy += tempEnergy;
delta.xyz *= dEdR; delta.xyz *= dEdR;
force.xyz -= delta.xyz; force.xyz -= delta.xyz;
......
...@@ -172,6 +172,37 @@ void testConstraints() { ...@@ -172,6 +172,37 @@ void testConstraints() {
} }
} }
void testConstrainedMasslessParticles() {
System system;
system.addParticle(0.0);
system.addParticle(1.0);
system.addConstraint(0, 1, 1.5);
vector<Vec3> positions(2);
positions[0] = Vec3(-1, 0, 0);
positions[1] = Vec3(1, 0, 0);
BrownianIntegrator integrator(300.0, 2.0, 0.01);
bool failed = false;
try {
// This should throw an exception.
Context context(system, integrator, platform);
}
catch (exception& ex) {
failed = true;
}
ASSERT(failed);
// Now make both particles massless, which should work.
system.setParticleMass(1, 0.0);
Context context(system, integrator, platform);
context.setPositions(positions);
context.setVelocitiesToTemperature(300.0);
integrator.step(1);
State state = context.getState(State::Velocities);
ASSERT_EQUAL(0.0, state.getVelocities()[0][0]);
}
void testRandomSeed() { void testRandomSeed() {
const int numParticles = 8; const int numParticles = 8;
const double temp = 100.0; const double temp = 100.0;
...@@ -237,6 +268,7 @@ int main(int argc, char* argv[]) { ...@@ -237,6 +268,7 @@ int main(int argc, char* argv[]) {
testSingleBond(); testSingleBond();
testTemperature(); testTemperature();
testConstraints(); testConstraints();
testConstrainedMasslessParticles();
testRandomSeed(); testRandomSeed();
} }
catch(const exception& e) { catch(const exception& e) {
......
...@@ -56,6 +56,7 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe ...@@ -56,6 +56,7 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe
const int numMolecules = 70; const int numMolecules = 70;
const int numParticles = numMolecules*2; const int numParticles = numMolecules*2;
const double boxSize = 10.0; const double boxSize = 10.0;
const double cutoff = 2.0;
// Create two systems: one with a GBSAOBCForce, and one using a CustomGBForce to implement the same interaction. // Create two systems: one with a GBSAOBCForce, and one using a CustomGBForce to implement the same interaction.
...@@ -69,8 +70,8 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe ...@@ -69,8 +70,8 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe
customSystem.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0.0, 0.0), Vec3(0.0, boxSize, 0.0), Vec3(0.0, 0.0, boxSize)); customSystem.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0.0, 0.0), Vec3(0.0, boxSize, 0.0), Vec3(0.0, 0.0, boxSize));
GBSAOBCForce* obc = new GBSAOBCForce(); GBSAOBCForce* obc = new GBSAOBCForce();
CustomGBForce* custom = new CustomGBForce(); CustomGBForce* custom = new CustomGBForce();
obc->setCutoffDistance(2.0); obc->setCutoffDistance(cutoff);
custom->setCutoffDistance(2.0); custom->setCutoffDistance(cutoff);
custom->addPerParticleParameter("q"); custom->addPerParticleParameter("q");
custom->addPerParticleParameter("radius"); custom->addPerParticleParameter("radius");
custom->addPerParticleParameter("scale"); custom->addPerParticleParameter("scale");
...@@ -86,7 +87,13 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe ...@@ -86,7 +87,13 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe
custom->addComputedValue("B", "1/(1/or-tanh(1*psi-0.8*psi^2+4.85*psi^3)/radius);" custom->addComputedValue("B", "1/(1/or-tanh(1*psi-0.8*psi^2+4.85*psi^3)/radius);"
"psi=I*or; or=radius-0.009", CustomGBForce::SingleParticle); "psi=I*or; or=radius-0.009", CustomGBForce::SingleParticle);
custom->addEnergyTerm("28.3919551*(radius+0.14)^2*(radius/B)^6-0.5*138.935456*(1/soluteDielectric-1/solventDielectric)*q^2/B", CustomGBForce::SingleParticle); custom->addEnergyTerm("28.3919551*(radius+0.14)^2*(radius/B)^6-0.5*138.935456*(1/soluteDielectric-1/solventDielectric)*q^2/B", CustomGBForce::SingleParticle);
custom->addEnergyTerm("-138.935456*(1/soluteDielectric-1/solventDielectric)*q1*q2/f;" string invCutoffString = "";
if (obcMethod != GBSAOBCForce::NoCutoff) {
stringstream s;
s<<(1.0/cutoff);
invCutoffString = s.str();
}
custom->addEnergyTerm("138.935485*(1/soluteDielectric-1/solventDielectric)*q1*q2*("+invCutoffString+"-1/f);"
"f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))", CustomGBForce::ParticlePairNoExclusions); "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))", CustomGBForce::ParticlePairNoExclusions);
vector<Vec3> positions(numParticles); vector<Vec3> positions(numParticles);
vector<Vec3> velocities(numParticles); vector<Vec3> velocities(numParticles);
......
...@@ -233,6 +233,43 @@ void testVelocityConstraints() { ...@@ -233,6 +233,43 @@ void testVelocityConstraints() {
} }
} }
void testConstrainedMasslessParticles() {
System system;
system.addParticle(0.0);
system.addParticle(1.0);
system.addConstraint(0, 1, 1.5);
vector<Vec3> positions(2);
positions[0] = Vec3(-1, 0, 0);
positions[1] = Vec3(1, 0, 0);
CustomIntegrator integrator(0.002);
integrator.addPerDofVariable("oldx", 0);
integrator.addComputePerDof("v", "v+dt*f/m");
integrator.addComputePerDof("oldx", "x");
integrator.addComputePerDof("x", "x+dt*v");
integrator.addConstrainPositions();
integrator.addComputePerDof("v", "(x-oldx)/dt");
bool failed = false;
try {
// This should throw an exception.
Context context(system, integrator, platform);
}
catch (exception& ex) {
failed = true;
}
ASSERT(failed);
// Now make both particles massless, which should work.
system.setParticleMass(1, 0.0);
Context context(system, integrator, platform);
context.setPositions(positions);
context.setVelocitiesToTemperature(300.0);
integrator.step(1);
State state = context.getState(State::Velocities | State::Positions);
ASSERT_EQUAL(0.0, state.getVelocities()[0][0]);
}
/** /**
* Test an integrator with an AndersenThermostat to see if updateContextState() * Test an integrator with an AndersenThermostat to see if updateContextState()
* is being handled correctly. * is being handled correctly.
...@@ -724,6 +761,7 @@ int main(int argc, char* argv[]) { ...@@ -724,6 +761,7 @@ int main(int argc, char* argv[]) {
testSingleBond(); testSingleBond();
testConstraints(); testConstraints();
testVelocityConstraints(); testVelocityConstraints();
testConstrainedMasslessParticles();
testWithThermostat(); testWithThermostat();
testMonteCarlo(); testMonteCarlo();
testSum(); testSum();
......
...@@ -177,6 +177,37 @@ void testConstraints() { ...@@ -177,6 +177,37 @@ void testConstraints() {
} }
} }
void testConstrainedMasslessParticles() {
System system;
system.addParticle(0.0);
system.addParticle(1.0);
system.addConstraint(0, 1, 1.5);
vector<Vec3> positions(2);
positions[0] = Vec3(-1, 0, 0);
positions[1] = Vec3(1, 0, 0);
LangevinIntegrator integrator(300.0, 2.0, 0.01);
bool failed = false;
try {
// This should throw an exception.
Context context(system, integrator, platform);
}
catch (exception& ex) {
failed = true;
}
ASSERT(failed);
// Now make both particles massless, which should work.
system.setParticleMass(1, 0.0);
Context context(system, integrator, platform);
context.setPositions(positions);
context.setVelocitiesToTemperature(300.0);
integrator.step(1);
State state = context.getState(State::Velocities);
ASSERT_EQUAL(0.0, state.getVelocities()[0][0]);
}
void testRandomSeed() { void testRandomSeed() {
const int numParticles = 8; const int numParticles = 8;
const double temp = 100.0; const double temp = 100.0;
...@@ -241,6 +272,7 @@ int main(int argc, char* argv[]) { ...@@ -241,6 +272,7 @@ int main(int argc, char* argv[]) {
testSingleBond(); testSingleBond();
testTemperature(); testTemperature();
testConstraints(); testConstraints();
testConstrainedMasslessParticles();
testRandomSeed(); testRandomSeed();
} }
catch(const exception& e) { catch(const exception& e) {
......
...@@ -172,6 +172,37 @@ void testConstraints() { ...@@ -172,6 +172,37 @@ void testConstraints() {
} }
} }
void testConstrainedMasslessParticles() {
System system;
system.addParticle(0.0);
system.addParticle(1.0);
system.addConstraint(0, 1, 1.5);
vector<Vec3> positions(2);
positions[0] = Vec3(-1, 0, 0);
positions[1] = Vec3(1, 0, 0);
VariableLangevinIntegrator integrator(300.0, 2.0, 0.01);
bool failed = false;
try {
// This should throw an exception.
Context context(system, integrator, platform);
}
catch (exception& ex) {
failed = true;
}
ASSERT(failed);
// Now make both particles massless, which should work.
system.setParticleMass(1, 0.0);
Context context(system, integrator, platform);
context.setPositions(positions);
context.setVelocitiesToTemperature(300.0);
integrator.step(1);
State state = context.getState(State::Velocities);
ASSERT_EQUAL(0.0, state.getVelocities()[0][0]);
}
void testRandomSeed() { void testRandomSeed() {
const int numParticles = 8; const int numParticles = 8;
const double temp = 100.0; const double temp = 100.0;
...@@ -295,6 +326,7 @@ int main(int argc, char* argv[]) { ...@@ -295,6 +326,7 @@ int main(int argc, char* argv[]) {
testSingleBond(); testSingleBond();
testTemperature(); testTemperature();
testConstraints(); testConstraints();
testConstrainedMasslessParticles();
testRandomSeed(); testRandomSeed();
testArgonBox(); testArgonBox();
} }
......
...@@ -210,6 +210,38 @@ void testConstrainedClusters() { ...@@ -210,6 +210,38 @@ void testConstrainedClusters() {
ASSERT(context.getState(State::Positions).getTime() > 0.1); ASSERT(context.getState(State::Positions).getTime() > 0.1);
} }
void testConstrainedMasslessParticles() {
System system;
system.addParticle(0.0);
system.addParticle(1.0);
system.addConstraint(0, 1, 1.5);
vector<Vec3> positions(2);
positions[0] = Vec3(-1, 0, 0);
positions[1] = Vec3(1, 0, 0);
VariableVerletIntegrator integrator(0.01);
bool failed = false;
try {
// This should throw an exception.
Context context(system, integrator, platform);
}
catch (exception& ex) {
failed = true;
}
ASSERT(failed);
// Now make both particles massless, which should work.
system.setParticleMass(1, 0.0);
Context context(system, integrator, platform);
context.setPositions(positions);
context.setVelocitiesToTemperature(300.0);
integrator.step(1);
State state = context.getState(State::Velocities);
ASSERT_EQUAL(0.0, state.getVelocities()[0][0]);
}
void testArgonBox() { void testArgonBox() {
const int gridSize = 8; const int gridSize = 8;
const double mass = 40.0; // Ar atomic mass const double mass = 40.0; // Ar atomic mass
...@@ -273,6 +305,7 @@ int main(int argc, char* argv[]) { ...@@ -273,6 +305,7 @@ int main(int argc, char* argv[]) {
testSingleBond(); testSingleBond();
testConstraints(); testConstraints();
testConstrainedClusters(); testConstrainedClusters();
testConstrainedMasslessParticles();
testArgonBox(); testArgonBox();
} }
catch(const exception& e) { catch(const exception& e) {
......
...@@ -201,6 +201,37 @@ void testConstrainedClusters() { ...@@ -201,6 +201,37 @@ void testConstrainedClusters() {
} }
} }
void testConstrainedMasslessParticles() {
System system;
system.addParticle(0.0);
system.addParticle(1.0);
system.addConstraint(0, 1, 1.5);
vector<Vec3> positions(2);
positions[0] = Vec3(-1, 0, 0);
positions[1] = Vec3(1, 0, 0);
VerletIntegrator integrator(0.01);
bool failed = false;
try {
// This should throw an exception.
Context context(system, integrator, platform);
}
catch (exception& ex) {
failed = true;
}
ASSERT(failed);
// Now make both particles massless, which should work.
system.setParticleMass(1, 0.0);
Context context(system, integrator, platform);
context.setPositions(positions);
context.setVelocitiesToTemperature(300.0);
integrator.step(1);
State state = context.getState(State::Velocities);
ASSERT_EQUAL(0.0, state.getVelocities()[0][0]);
}
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
try { try {
if (argc > 1) if (argc > 1)
...@@ -208,6 +239,7 @@ int main(int argc, char* argv[]) { ...@@ -208,6 +239,7 @@ int main(int argc, char* argv[]) {
testSingleBond(); testSingleBond();
testConstraints(); testConstraints();
testConstrainedClusters(); testConstrainedClusters();
testConstrainedMasslessParticles();
} }
catch(const exception& e) { catch(const exception& e) {
cout << "exception: " << e.what() << endl; cout << "exception: " << e.what() << endl;
......
...@@ -305,7 +305,7 @@ class ObcParameters { ...@@ -305,7 +305,7 @@ class ObcParameters {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
bool getUseCutoff(); bool getUseCutoff() const;
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -313,7 +313,7 @@ class ObcParameters { ...@@ -313,7 +313,7 @@ class ObcParameters {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM getCutoffDistance(); RealOpenMM getCutoffDistance() const;
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
......
/* Portions copyright (c) 2006-2009 Stanford University and Simbios. /* Portions copyright (c) 2006-2013 Stanford University and Simbios.
* Contributors: Pande Group * Contributors: Pande Group
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -34,151 +34,89 @@ ...@@ -34,151 +34,89 @@
class OPENMM_EXPORT ReferenceCCMAAlgorithm : public ReferenceConstraintAlgorithm { class OPENMM_EXPORT ReferenceCCMAAlgorithm : public ReferenceConstraintAlgorithm {
protected: protected:
int _maximumNumberOfIterations; int _maximumNumberOfIterations;
RealOpenMM _tolerance; RealOpenMM _tolerance;
int _numberOfConstraints; int _numberOfConstraints;
std::vector<std::pair<int, int> > _atomIndices; std::vector<std::pair<int, int> > _atomIndices;
std::vector<RealOpenMM> _distance; std::vector<RealOpenMM> _distance;
std::vector<OpenMM::RealVec> _r_ij; std::vector<OpenMM::RealVec> _r_ij;
RealOpenMM* _d_ij2; RealOpenMM* _d_ij2;
RealOpenMM* _distanceTolerance; RealOpenMM* _distanceTolerance;
RealOpenMM* _reducedMasses; RealOpenMM* _reducedMasses;
bool _hasInitializedMasses; bool _hasInitializedMasses;
std::vector<std::vector<std::pair<int, RealOpenMM> > > _matrix; std::vector<std::vector<std::pair<int, RealOpenMM> > > _matrix;
private: private:
int applyConstraints(int numberOfAtoms, std::vector<OpenMM::RealVec>& atomCoordinates, void applyConstraints(std::vector<OpenMM::RealVec>& atomCoordinates,
std::vector<OpenMM::RealVec>& atomCoordinatesP, std::vector<RealOpenMM>& inverseMasses, bool constrainingVelocities); std::vector<OpenMM::RealVec>& atomCoordinatesP, std::vector<RealOpenMM>& inverseMasses, bool constrainingVelocities);
public: public:
class AngleInfo; class AngleInfo;
/**--------------------------------------------------------------------------------------- /**
* Create a ReferenceCCMAAlgorithm object.
ReferenceCCMAAlgorithm constructor *
* @param numberOfAtoms the number of atoms in the system
@param numberOfAtoms number of atoms * @param numberOfConstraints the number of constraints
@param numberOfConstraints number of constraints * @param atomIndices atom indices for contraints
@param atomIndices atom indices for contraints * @param distance distances for constraints
@param distance distances for constraints * @param masses atom masses
@param masses atom masses * @param angles angle force field terms
@param angles angle force field terms * @param tolerance constraint tolerance
@param tolerance constraint tolerance */
ReferenceCCMAAlgorithm( int numberOfAtoms, int numberOfConstraints, const std::vector<std::pair<int, int> >& atomIndices, const std::vector<RealOpenMM>& distance, std::vector<RealOpenMM>& masses, std::vector<AngleInfo>& angles, RealOpenMM tolerance );
--------------------------------------------------------------------------------------- */
~ReferenceCCMAAlgorithm( );
ReferenceCCMAAlgorithm( int numberOfAtoms, int numberOfConstraints, const std::vector<std::pair<int, int> >& atomIndices, const std::vector<RealOpenMM>& distance, std::vector<RealOpenMM>& masses, std::vector<AngleInfo>& angles, RealOpenMM tolerance );
/**
/**--------------------------------------------------------------------------------------- * Get the number of constraints.
*/
Destructor int getNumberOfConstraints( void ) const;
--------------------------------------------------------------------------------------- */ /**
* Get the maximum number of iterations to perform.
~ReferenceCCMAAlgorithm( ); */
int getMaximumNumberOfIterations( void ) const;
/**---------------------------------------------------------------------------------------
/**
Get number of constraints * Set the maximum number of iterations to perform.
*/
@return number of constraints void setMaximumNumberOfIterations( int maximumNumberOfIterations );
--------------------------------------------------------------------------------------- */ /**
* Get the constraint tolerance.
int getNumberOfConstraints( void ) const; */
RealOpenMM getTolerance( void ) const;
/**---------------------------------------------------------------------------------------
/**
Get maximum number of iterations * Set the constraint tolerance.
*/
@return maximum number of iterations void setTolerance( RealOpenMM tolerance );
--------------------------------------------------------------------------------------- */ /**
* Apply the constraint algorithm.
int getMaximumNumberOfIterations( void ) const; *
* @param atomCoordinates the original atom coordinates
/**--------------------------------------------------------------------------------------- * @param atomCoordinatesP the new atom coordinates
* @param inverseMasses 1/mass
Set maximum number of iterations */
void apply(std::vector<OpenMM::RealVec>& atomCoordinates,
@param maximumNumberOfIterations new maximum number of iterations std::vector<OpenMM::RealVec>& atomCoordinatesP, std::vector<RealOpenMM>& inverseMasses);
--------------------------------------------------------------------------------------- */ /**
* Apply the constraint algorithm to velocities.
void setMaximumNumberOfIterations( int maximumNumberOfIterations ); *
* @param atomCoordinates the atom coordinates
/**--------------------------------------------------------------------------------------- * @param atomCoordinatesP the velocities to modify
* @param inverseMasses 1/mass
Get tolerance */
void applyToVelocities(std::vector<OpenMM::RealVec>& atomCoordinates,
@return tolerance
--------------------------------------------------------------------------------------- */
RealOpenMM getTolerance( void ) const;
/**---------------------------------------------------------------------------------------
Set tolerance
@param tolerance new tolerance
--------------------------------------------------------------------------------------- */
void setTolerance( RealOpenMM tolerance );
/**---------------------------------------------------------------------------------------
Apply CCMA algorithm
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param atomCoordinatesP atom coordinates prime
@param inverseMasses 1/mass
@return SimTKOpenMMCommon::DefaultReturn if converge; else
return SimTKOpenMMCommon::ErrorReturn
--------------------------------------------------------------------------------------- */
int apply( int numberOfAtoms, std::vector<OpenMM::RealVec>& atomCoordinates,
std::vector<OpenMM::RealVec>& atomCoordinatesP, std::vector<RealOpenMM>& inverseMasses );
/**---------------------------------------------------------------------------------------
Apply constraint algorithm to velocities.
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param velocities atom velocities
@param inverseMasses 1/mass
@return SimTKOpenMMCommon::DefaultReturn if converge; else
return SimTKOpenMMCommon::ErrorReturn
--------------------------------------------------------------------------------------- */
int applyToVelocities(int numberOfAtoms, std::vector<OpenMM::RealVec>& atomCoordinates,
std::vector<OpenMM::RealVec>& velocities, std::vector<RealOpenMM>& inverseMasses); std::vector<OpenMM::RealVec>& velocities, std::vector<RealOpenMM>& inverseMasses);
/**---------------------------------------------------------------------------------------
Report any violated constraints
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param message report
@return number of violated constraints
--------------------------------------------------------------------------------------- */
int reportCCMA( int numberOfAtoms, std::vector<OpenMM::RealVec>& atomCoordinates, std::stringstream& message );
}; };
class ReferenceCCMAAlgorithm::AngleInfo class ReferenceCCMAAlgorithm::AngleInfo
......
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