void testPeriodic() { // Create a force that uses periodic boundary conditions, then compare to an identical custom force. System system; system.setDefaultPeriodicBoxVectors(Vec3(3, 0, 0), Vec3(0, 3, 0), Vec3(0, 0, 3)); int numParticles = 3; for (int ii = 0; ii < numParticles; ii++) system.addParticle(1.0); LangevinIntegrator integrator(0.0, 0.1, 0.01); AmoebaAngleForce* amoebaAngleForce = new AmoebaAngleForce(); double angle = 100.0; double quadraticK = 1.0; double cubicK = 1.0e-01; double quarticK = 1.0e-02; double penticK = 1.0e-03; double sexticK = 1.0e-04; amoebaAngleForce->addAngle(0, 1, 2, angle, quadraticK); amoebaAngleForce->setAmoebaGlobalAngleCubic(cubicK); amoebaAngleForce->setAmoebaGlobalAngleQuartic(quarticK); amoebaAngleForce->setAmoebaGlobalAnglePentic(penticK); amoebaAngleForce->setAmoebaGlobalAngleSextic(sexticK); amoebaAngleForce->setUsesPeriodicBoundaryConditions(true); system.addForce(amoebaAngleForce); CustomAngleForce* customForce = new CustomAngleForce("k2*delta^2 + k3*delta^3 + k4*delta^4 + k5*delta^5 + k6*delta^6; delta=theta-theta0"); customForce->addGlobalParameter("theta0", angle*M_PI/180); customForce->addGlobalParameter("k2", quadraticK*pow(180/M_PI, 2.0)); customForce->addGlobalParameter("k3", cubicK*pow(180/M_PI, 3.0)); customForce->addGlobalParameter("k4", quarticK*pow(180/M_PI, 4.0)); customForce->addGlobalParameter("k5", penticK*pow(180/M_PI, 5.0)); customForce->addGlobalParameter("k6", sexticK*pow(180/M_PI, 6.0)); customForce->addAngle(0, 1, 2); customForce->setUsesPeriodicBoundaryConditions(true); customForce->setForceGroup(1); system.addForce(customForce); Context context(system, integrator, Platform::getPlatformByName("CUDA")); std::vector<Vec3> positions(numParticles); positions[0] = Vec3(0, 1, 0); positions[1] = Vec3(0, 0, 0); positions[2] = Vec3(0, 0, 2); context.setPositions(positions); State s1 = context.getState(State::Forces | State::Energy, true, 1); State s2 = context.getState(State::Forces | State::Energy, true, 2); ASSERT_EQUAL_TOL(s2.getPotentialEnergy(), s1.getPotentialEnergy(), 1e-5); for (int i = 0; i < numParticles; i++) ASSERT_EQUAL_VEC(s2.getForces()[i], s1.getForces()[i], 1e-5); }
void* CustomAngleForceProxy::deserialize(const SerializationNode& node) const { int version = node.getIntProperty("version"); if (version < 1 || version > 3) throw OpenMMException("Unsupported version number"); CustomAngleForce* force = NULL; try { CustomAngleForce* force = new CustomAngleForce(node.getStringProperty("energy")); force->setForceGroup(node.getIntProperty("forceGroup", 0)); if (version > 1) force->setUsesPeriodicBoundaryConditions(node.getBoolProperty("usesPeriodic")); const SerializationNode& perAngleParams = node.getChildNode("PerAngleParameters"); for (int i = 0; i < (int) perAngleParams.getChildren().size(); i++) { const SerializationNode& parameter = perAngleParams.getChildren()[i]; force->addPerAngleParameter(parameter.getStringProperty("name")); } const SerializationNode& globalParams = node.getChildNode("GlobalParameters"); for (int i = 0; i < (int) globalParams.getChildren().size(); i++) { const SerializationNode& parameter = globalParams.getChildren()[i]; force->addGlobalParameter(parameter.getStringProperty("name"), parameter.getDoubleProperty("default")); } if (version > 2) { const SerializationNode& energyDerivs = node.getChildNode("EnergyParameterDerivatives"); for (int i = 0; i < (int) energyDerivs.getChildren().size(); i++) { const SerializationNode& parameter = energyDerivs.getChildren()[i]; force->addEnergyParameterDerivative(parameter.getStringProperty("name")); } } const SerializationNode& angles = node.getChildNode("Angles"); vector<double> params(force->getNumPerAngleParameters()); for (int i = 0; i < (int) angles.getChildren().size(); i++) { const SerializationNode& angle = angles.getChildren()[i]; for (int j = 0; j < (int) params.size(); j++) { stringstream key; key << "param"; key << j+1; params[j] = angle.getDoubleProperty(key.str()); } force->addAngle(angle.getIntProperty("p1"), angle.getIntProperty("p2"), angle.getIntProperty("p3"), params); } return force; } catch (...) { if (force != NULL) delete force; throw; } }