Commit 06c82bc0 authored by peastman's avatar peastman Committed by GitHub
Browse files

Merge pull request #1711 from peastman/constraints

Added more error checking to constraints
parents a51caf73 adb3cda7
...@@ -56,12 +56,13 @@ const static char CHECKPOINT_MAGIC_BYTES[] = "OpenMM Binary Checkpoint\n"; ...@@ -56,12 +56,13 @@ const static char CHECKPOINT_MAGIC_BYTES[] = "OpenMM Binary Checkpoint\n";
ContextImpl::ContextImpl(Context& owner, const System& system, Integrator& integrator, Platform* platform, const map<string, string>& properties) : ContextImpl::ContextImpl(Context& owner, const System& system, Integrator& integrator, Platform* platform, const map<string, string>& properties) :
owner(owner), system(system), integrator(integrator), hasInitializedForces(false), hasSetPositions(false), integratorIsDeleted(false), owner(owner), system(system), integrator(integrator), hasInitializedForces(false), hasSetPositions(false), integratorIsDeleted(false),
lastForceGroups(-1), platform(platform), platformData(NULL) { lastForceGroups(-1), platform(platform), platformData(NULL) {
if (system.getNumParticles() == 0) int numParticles = system.getNumParticles();
if (numParticles == 0)
throw OpenMMException("Cannot create a Context for a System with no particles"); throw OpenMMException("Cannot create a Context for a System with no particles");
// Check for errors in virtual sites and massless particles. // Check for errors in virtual sites and massless particles.
for (int i = 0; i < system.getNumParticles(); i++) { for (int i = 0; i < numParticles; i++) {
if (system.isVirtualSite(i)) { if (system.isVirtualSite(i)) {
if (system.getParticleMass(i) != 0.0) if (system.getParticleMass(i) != 0.0)
throw OpenMMException("Virtual site has nonzero mass"); throw OpenMMException("Virtual site has nonzero mass");
...@@ -71,14 +72,23 @@ ContextImpl::ContextImpl(Context& owner, const System& system, Integrator& integ ...@@ -71,14 +72,23 @@ ContextImpl::ContextImpl(Context& owner, const System& system, Integrator& integ
throw OpenMMException("A virtual site cannot depend on another virtual site"); throw OpenMMException("A virtual site cannot depend on another virtual site");
} }
} }
set<pair<int, int> > constraintAtoms;
for (int i = 0; i < system.getNumConstraints(); i++) { for (int i = 0; i < system.getNumConstraints(); i++) {
int particle1, particle2; int particle1, particle2;
double distance; double distance;
system.getConstraintParameters(i, particle1, particle2, distance); system.getConstraintParameters(i, particle1, particle2, distance);
if (particle1 == particle2)
throw OpenMMException("A constraint cannot connect a particle to itself");
if (particle1 < 0 || particle2 < 0 || particle1 >= numParticles || particle2 >= numParticles)
throw OpenMMException("Illegal particle index in constraint");
double mass1 = system.getParticleMass(particle1); double mass1 = system.getParticleMass(particle1);
double mass2 = system.getParticleMass(particle2); double mass2 = system.getParticleMass(particle2);
if ((mass1 == 0.0 && mass2 != 0.0) || (mass2 == 0.0 && mass1 != 0.0)) if ((mass1 == 0.0 && mass2 != 0.0) || (mass2 == 0.0 && mass1 != 0.0))
throw OpenMMException("A constraint cannot involve a massless particle"); throw OpenMMException("A constraint cannot involve a massless particle");
pair<int, int> atoms = make_pair(min(particle1, particle2), max(particle1, particle2));
if (constraintAtoms.find(atoms) != constraintAtoms.end())
throw OpenMMException("The System has two constraints between the same atoms. This will produce a singular constraint matrix.");
constraintAtoms.insert(atoms);
} }
// Validate the list of properties. // Validate the list of properties.
...@@ -170,7 +180,7 @@ ContextImpl::ContextImpl(Context& owner, const System& system, Integrator& integ ...@@ -170,7 +180,7 @@ ContextImpl::ContextImpl(Context& owner, const System& system, Integrator& integ
for (size_t i = 0; i < forceImpls.size(); ++i) for (size_t i = 0; i < forceImpls.size(); ++i)
forceImpls[i]->initialize(*this); forceImpls[i]->initialize(*this);
integrator.initialize(*this); integrator.initialize(*this);
updateStateDataKernel.getAs<UpdateStateDataKernel>().setVelocities(*this, vector<Vec3>(system.getNumParticles())); updateStateDataKernel.getAs<UpdateStateDataKernel>().setVelocities(*this, vector<Vec3>(numParticles));
} }
ContextImpl::~ContextImpl() { ContextImpl::~ContextImpl() {
...@@ -259,10 +269,14 @@ void ContextImpl::setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3 ...@@ -259,10 +269,14 @@ void ContextImpl::setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3
} }
void ContextImpl::applyConstraints(double tol) { void ContextImpl::applyConstraints(double tol) {
if (!hasSetPositions)
throw OpenMMException("Particle positions have not been set");
applyConstraintsKernel.getAs<ApplyConstraintsKernel>().apply(*this, tol); applyConstraintsKernel.getAs<ApplyConstraintsKernel>().apply(*this, tol);
} }
void ContextImpl::applyVelocityConstraints(double tol) { void ContextImpl::applyVelocityConstraints(double tol) {
if (!hasSetPositions)
throw OpenMMException("Particle positions have not been set");
applyConstraintsKernel.getAs<ApplyConstraintsKernel>().applyToVelocities(*this, tol); applyConstraintsKernel.getAs<ApplyConstraintsKernel>().applyToVelocities(*this, tol);
} }
......
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