void ReferenceVariableVerletDynamics::update(const OpenMM::System& system, vector<Vec3>& atomCoordinates, vector<Vec3>& velocities, vector<Vec3>& forces, vector<double>& masses, double maxStepSize, double tolerance) { // first-time-through initialization int numberOfAtoms = system.getNumParticles(); if (getTimeStep() == 0) { // invert masses for (int ii = 0; ii < numberOfAtoms; ii++) { if (masses[ii] == 0.0) inverseMasses[ii] = 0.0; else inverseMasses[ii] = 1.0/masses[ii]; } } double error = 0.0; for (int i = 0; i < numberOfAtoms; ++i) { for (int j = 0; j < 3; ++j) { double xerror = inverseMasses[i]*forces[i][j]; error += xerror*xerror; } } error = sqrt(error/(numberOfAtoms*3)); double newStepSize = sqrt(getAccuracy()/error); if (getDeltaT() > 0.0f) newStepSize = std::min(newStepSize, getDeltaT()*2.0f); // For safety, limit how quickly dt can increase. if (newStepSize > getDeltaT() && newStepSize < 1.2f*getDeltaT()) newStepSize = getDeltaT(); // Keeping dt constant between steps improves the behavior of the integrator. if (newStepSize > maxStepSize) newStepSize = maxStepSize; double vstep = 0.5f*(newStepSize+getDeltaT()); // The time interval by which to advance the velocities setDeltaT(newStepSize); for (int i = 0; i < numberOfAtoms; ++i) { if (masses[i] != 0.0) for (int j = 0; j < 3; ++j) { double vPrime = velocities[i][j] + inverseMasses[i]*forces[i][j]*vstep; xPrime[i][j] = atomCoordinates[i][j] + vPrime*getDeltaT(); } } ReferenceConstraintAlgorithm* referenceConstraintAlgorithm = getReferenceConstraintAlgorithm(); if (referenceConstraintAlgorithm) referenceConstraintAlgorithm->apply(atomCoordinates, xPrime, inverseMasses, tolerance); // Update the positions and velocities. double velocityScale = 1.0/getDeltaT(); for (int i = 0; i < numberOfAtoms; ++i) { if (masses[i] != 0.0) for (int j = 0; j < 3; ++j) { velocities[i][j] = velocityScale*(xPrime[i][j] - atomCoordinates[i][j]); atomCoordinates[i][j] = xPrime[i][j]; } } ReferenceVirtualSites::computePositions(system, atomCoordinates); incrementTimeStep(); }
void ReferenceVerletDynamics::update(const OpenMM::System& system, vector<RealVec>& atomCoordinates, vector<RealVec>& velocities, vector<RealVec>& forces, vector<RealOpenMM>& masses, RealOpenMM tolerance) { // --------------------------------------------------------------------------------------- static const char* methodName = "\nReferenceVerletDynamics::update"; static const RealOpenMM zero = 0.0; static const RealOpenMM one = 1.0; // --------------------------------------------------------------------------------------- // first-time-through initialization int numberOfAtoms = system.getNumParticles(); if( getTimeStep() == 0 ){ // invert masses for( int ii = 0; ii < numberOfAtoms; ii++ ){ if (masses[ii] == zero) inverseMasses[ii] = zero; else inverseMasses[ii] = one/masses[ii]; } } // Perform the integration. for (int i = 0; i < numberOfAtoms; ++i) { if (masses[i] != zero) for (int j = 0; j < 3; ++j) { velocities[i][j] += inverseMasses[i]*forces[i][j]*getDeltaT(); xPrime[i][j] = atomCoordinates[i][j] + velocities[i][j]*getDeltaT(); } } ReferenceConstraintAlgorithm* referenceConstraintAlgorithm = getReferenceConstraintAlgorithm(); if (referenceConstraintAlgorithm) referenceConstraintAlgorithm->apply(atomCoordinates, xPrime, inverseMasses, tolerance); // Update the positions and velocities. RealOpenMM velocityScale = static_cast<RealOpenMM>( 1.0/getDeltaT() ); for (int i = 0; i < numberOfAtoms; ++i) { if (masses[i] != zero) for (int j = 0; j < 3; ++j) { velocities[i][j] = velocityScale*(xPrime[i][j] - atomCoordinates[i][j]); atomCoordinates[i][j] = xPrime[i][j]; } } ReferenceVirtualSites::computePositions(system, atomCoordinates); incrementTimeStep(); }
void ReferenceBrownianDynamics::update(const OpenMM::System& system, vector<RealVec>& atomCoordinates, vector<RealVec>& velocities, vector<RealVec>& forces, vector<RealOpenMM>& masses, RealOpenMM tolerance) { // --------------------------------------------------------------------------------------- static const char* methodName = "\nReferenceBrownianDynamics::update"; static const RealOpenMM zero = 0.0; static const RealOpenMM one = 1.0; // --------------------------------------------------------------------------------------- // first-time-through initialization int numberOfAtoms = system.getNumParticles(); if( getTimeStep() == 0 ){ // invert masses for( int ii = 0; ii < numberOfAtoms; ii++ ){ if (masses[ii] == zero) inverseMasses[ii] = zero; else inverseMasses[ii] = one/masses[ii]; } } // Perform the integration. const RealOpenMM noiseAmplitude = static_cast<RealOpenMM>( sqrt(2.0*BOLTZ*getTemperature()*getDeltaT()/getFriction()) ); const RealOpenMM forceScale = getDeltaT()/getFriction(); for (int i = 0; i < numberOfAtoms; ++i) { if (masses[i] != zero) for (int j = 0; j < 3; ++j) { xPrime[i][j] = atomCoordinates[i][j] + forceScale*inverseMasses[i]*forces[i][j] + noiseAmplitude*SQRT(inverseMasses[i])*SimTKOpenMMUtilities::getNormallyDistributedRandomNumber(); } } ReferenceConstraintAlgorithm* referenceConstraintAlgorithm = getReferenceConstraintAlgorithm(); if (referenceConstraintAlgorithm) referenceConstraintAlgorithm->apply(atomCoordinates, xPrime, inverseMasses, tolerance); // Update the positions and velocities. RealOpenMM velocityScale = static_cast<RealOpenMM>( 1.0/getDeltaT() ); for (int i = 0; i < numberOfAtoms; ++i) { if (masses[i] != zero) for (int j = 0; j < 3; ++j) { velocities[i][j] = velocityScale*(xPrime[i][j] - atomCoordinates[i][j]); atomCoordinates[i][j] = xPrime[i][j]; } } ReferenceVirtualSites::computePositions(system, atomCoordinates); incrementTimeStep(); }
void ReferenceStochasticDynamics::update(const OpenMM::System& system, vector<RealVec>& atomCoordinates, vector<RealVec>& velocities, vector<RealVec>& forces, vector<RealOpenMM>& masses, RealOpenMM tolerance) { // --------------------------------------------------------------------------------------- static const char* methodName = "\nReferenceStochasticDynamics::update"; static const RealOpenMM zero = 0.0; static const RealOpenMM one = 1.0; // --------------------------------------------------------------------------------------- // first-time-through initialization int numberOfAtoms = system.getNumParticles(); if( getTimeStep() == 0 ){ // invert masses for( int ii = 0; ii < numberOfAtoms; ii++ ){ if (masses[ii] == zero) inverseMasses[ii] = zero; else inverseMasses[ii] = one/masses[ii]; } } // 1st update updatePart1( numberOfAtoms, atomCoordinates, velocities, forces, inverseMasses, xPrime ); // 2nd update updatePart2( numberOfAtoms, atomCoordinates, velocities, forces, inverseMasses, xPrime ); ReferenceConstraintAlgorithm* referenceConstraintAlgorithm = getReferenceConstraintAlgorithm(); if (referenceConstraintAlgorithm) referenceConstraintAlgorithm->apply(atomCoordinates, xPrime, inverseMasses, tolerance); // copy xPrime -> atomCoordinates RealOpenMM invStepSize = 1.0/getDeltaT(); for (int i = 0; i < numberOfAtoms; ++i) if (masses[i] != zero) for (int j = 0; j < 3; ++j) { velocities[i][j] = invStepSize*(xPrime[i][j]-atomCoordinates[i][j]); atomCoordinates[i][j] = xPrime[i][j]; } ReferenceVirtualSites::computePositions(system, atomCoordinates); incrementTimeStep(); }
TEST(TestControlBerendsenBins,SingleBin){ std::ifstream file("../foam-1728.json"); if(!file.is_open()){ std::cout<<"File not found"<<std::endl; exit(0); } std::string jsonstr; std::string line; while (!file.eof()) { getline(file, line); jsonstr += line; } file.close(); rapidjson::Document document; if(document.Parse<0>(jsonstr.c_str()).HasParseError()){ std::cout<<"Parsing error "<<std::endl; exit(0); } const double stepSizeInFs = document["StepSizeInFs"].GetDouble(); const int numParticles = document["NumberAtoms"].GetInt(); std::string equationStr = document["Equation"].GetString(); const double rCut = document["rCut"].GetDouble(); const rapidjson::Value& b = document["Boxsize"]; double bx = b[(rapidjson::SizeType)0].GetDouble(); double by = b[(rapidjson::SizeType)1].GetDouble(); double bz = b[(rapidjson::SizeType)2].GetDouble(); int numSpecies = document["NumberSpecies"].GetInt(); std::vector<OpenMM::Vec3> posInNm; std::vector<OpenMM::Vec3> velInNm; OpenMM::Platform::loadPluginsFromDirectory( OpenMM::Platform::getDefaultPluginsDirectory()); OpenMM::System system; //add particles to the system by reading from json file system.setDefaultPeriodicBoxVectors(OpenMM::Vec3(bx,0,0),OpenMM::Vec3(0,by,0),OpenMM::Vec3(0,0,bz)); const rapidjson::Value& mass = document["masses"]; const rapidjson::Value& pos = document["Positions"]; const rapidjson::Value& vel = document["Velocities"]; posInNm.clear(); velInNm.clear(); for(rapidjson::SizeType m=0;m<mass.Size();m++){ double tm = mass[(rapidjson::SizeType) m].GetDouble(); system.addParticle(tm); posInNm.push_back(OpenMM::Vec3(pos[(rapidjson::SizeType) m]["0"].GetDouble(), pos[(rapidjson::SizeType) m]["1"].GetDouble(), pos[(rapidjson::SizeType) m]["2"].GetDouble() )); velInNm.push_back(OpenMM::Vec3(vel[(rapidjson::SizeType) m]["0"].GetDouble(), vel[(rapidjson::SizeType) m]["1"].GetDouble(), vel[(rapidjson::SizeType) m]["2"].GetDouble() )); } std::cout<<"Initialized System with "<<system.getNumParticles()<<" Particles."<<std::endl; OpenMM::CustomNonbondedForce* nonbonded = new OpenMM::CustomNonbondedForce(equationStr); nonbonded->setNonbondedMethod(OpenMM::CustomNonbondedForce::CutoffPeriodic); nonbonded->setCutoffDistance(rCut);// * OpenMM::NmPerAngstrom nonbonded->addPerParticleParameter("Ar");//later on collect it from json string based on OF for(int p=0;p<numParticles;p++){ std::vector<double> params(numSpecies); params[0] = (double) 1; nonbonded->addParticle(params); } system.addForce(nonbonded); std::vector<std::string> ctools(1); ctools[0] = "ControlBerendsenInBins"; OpenMM::Vec3 startPoint = OpenMM::Vec3((10*0.34),(0*0.34),(10*0.34)); OpenMM::Vec3 endPoint = OpenMM::Vec3((10*0.34),(20*0.34),(10*0.34)); OpenMM::ControlTools controls(ctools,(double)292,0.001, startPoint,endPoint); int num_plat = OpenMM::Platform::getNumPlatforms(); std::cout<<"Number of registered platforms: "<< num_plat <<std::endl; for(int i=0;i<num_plat;i++) { OpenMM::Platform& tempPlatform = OpenMM::Platform::getPlatform(i); std::string tempPlatformName = tempPlatform.getName(); std::cout<<"Platform "<<(i+1)<<" is "<<tempPlatformName.c_str()<<std::endl; } OpenMM::Platform& platform = OpenMM::Platform::getPlatformByName("OpenCL"); OpenMM::VelocityVerletIntegrator integrator(stepSizeInFs * OpenMM::PsPerFs); OpenMM::Context context(system,integrator,platform,controls); string Platformname = context.getPlatform().getName(); std::cout<<"Using OpenMM "<<Platformname.c_str()<<" Platform"<<std::endl; context.setPositions(posInNm); context.setVelocities(velInNm); int nbs = context.getControls().getNBins(); printf("Using %d bins for the system\n",nbs); //start the simulation loop integrator.step(1); printf("Finished initial integration\n"); int counter=0; std::cout<<"starting the loop\n"; for(int frame=1;frame<400;++frame){ // OpenMM::State state = context.getState(OpenMM::State::Velocities); // const double time = state.getTime(); double* mola = context.getControls().getBinTemperature(); // OpenMM::Vec3* tv = context.getControls().getTestVariable(); double gpuMol = 0.0; for(int k=0;k<nbs;k++){ gpuMol += mola[k]; } EXPECT_EQ((double) numParticles,gpuMol); integrator.step(1); } std::cout<<"Simulation completed with counter value "<<counter<<std::endl; }