void RMSDForceImpl::initialize(ContextImpl& context) { kernel = context.getPlatform().createKernel(CalcRMSDForceKernel::Name(), context); // Check for errors in the specification of particles. const System& system = context.getSystem(); int numParticles = system.getNumParticles(); if (owner.getReferencePositions().size() != numParticles) throw OpenMMException("RMSDForce: Number of reference positions does not equal number of particles in the System"); set<int> particles; for (int i : owner.getParticles()) { if (i < 0 || i >= numParticles) { stringstream msg; msg << "RMSDForce: Illegal particle index for RMSD: "; msg << i; throw OpenMMException(msg.str()); } if (particles.find(i) != particles.end()) { stringstream msg; msg << "RMSDForce: Duplicated particle index for RMSD: "; msg << i; throw OpenMMException(msg.str()); } particles.insert(i); } kernel.getAs<CalcRMSDForceKernel>().initialize(context.getSystem(), owner); }
CORBA::Context_ptr TIDorb::core::ContextImpl::read(TIDorb::portable::InputStream& input) { CORBA::ULong pair_count; input.read_ulong(pair_count); if (pair_count == 0) return 0; if ((pair_count < 1) || (pair_count%2 != 0)) throw CORBA::MARSHAL(0,CORBA::COMPLETED_NO); //"Malformed context name-value pairs",0, //CompletionStatus.COMPLETED_NO); CORBA::ULong num_values = pair_count / 2; ContextImpl* context = new ContextImpl(input.orb(), ""); char* name = 0; char* str_val = 0; CORBA::Any value; for(CORBA::ULong i = 0; i < num_values; i++) { input.read_string(name); input.read_string(str_val); value <<= str_val; context->set_one_value(name,value); //free string CORBA::string_free(name); } return context; }
void CustomNonbondedForceImpl::initialize(ContextImpl& context) { kernel = context.getPlatform().createKernel(CalcCustomNonbondedForceKernel::Name(), context); // Check for errors in the specification of parameters and exclusions. const System& system = context.getSystem(); if (owner.getNumParticles() != system.getNumParticles()) throw OpenMMException("CustomNonbondedForce must have exactly as many particles as the System it belongs to."); if (owner.getUseSwitchingFunction()) { if (owner.getSwitchingDistance() < 0 || owner.getSwitchingDistance() >= owner.getCutoffDistance()) throw OpenMMException("CustomNonbondedForce: Switching distance must satisfy 0 <= r_switch < r_cutoff"); } vector<set<int> > exclusions(owner.getNumParticles()); vector<double> parameters; int numParameters = owner.getNumPerParticleParameters(); for (int i = 0; i < owner.getNumParticles(); i++) { owner.getParticleParameters(i, parameters); if (parameters.size() != numParameters) { stringstream msg; msg << "CustomNonbondedForce: Wrong number of parameters for particle "; msg << i; throw OpenMMException(msg.str()); } } for (int i = 0; i < owner.getNumExclusions(); i++) { int particle1, particle2; owner.getExclusionParticles(i, particle1, particle2); if (particle1 < 0 || particle1 >= owner.getNumParticles()) { stringstream msg; msg << "CustomNonbondedForce: Illegal particle index for an exclusion: "; msg << particle1; throw OpenMMException(msg.str()); } if (particle2 < 0 || particle2 >= owner.getNumParticles()) { stringstream msg; msg << "CustomNonbondedForce: Illegal particle index for an exclusion: "; msg << particle2; throw OpenMMException(msg.str()); } if (exclusions[particle1].count(particle2) > 0 || exclusions[particle2].count(particle1) > 0) { stringstream msg; msg << "CustomNonbondedForce: Multiple exclusions are specified for particles "; msg << particle1; msg << " and "; msg << particle2; throw OpenMMException(msg.str()); } exclusions[particle1].insert(particle2); exclusions[particle2].insert(particle1); } if (owner.getNonbondedMethod() == CustomNonbondedForce::CutoffPeriodic) { Vec3 boxVectors[3]; system.getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); double cutoff = owner.getCutoffDistance(); if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2]) throw OpenMMException("CustomNonbondedForce: The cutoff distance cannot be greater than half the periodic box size."); } kernel.getAs<CalcCustomNonbondedForceKernel>().initialize(context.getSystem(), owner); }
void VariableLangevinIntegrator::initialize(ContextImpl& contextRef) { if (owner != NULL && &contextRef.getOwner() != owner) throw OpenMMException("This Integrator is already bound to a context"); context = &contextRef; owner = &contextRef.getOwner(); kernel = context->getPlatform().createKernel(IntegrateVariableLangevinStepKernel::Name(), contextRef); kernel.getAs<IntegrateVariableLangevinStepKernel>().initialize(contextRef.getSystem(), *this); }
void AmoebaWcaDispersionForceImpl::initialize(ContextImpl& context) { const System& system = context.getSystem(); if (owner.getNumParticles() != system.getNumParticles()) throw OpenMMException("AmoebaWcaDispersionForce must have exactly as many particles as the System it belongs to."); kernel = context.getPlatform().createKernel(CalcAmoebaWcaDispersionForceKernel::Name(), context); kernel.getAs<CalcAmoebaWcaDispersionForceKernel>().initialize(context.getSystem(), owner); }
void RPMDIntegrator::initialize(ContextImpl& contextRef) { if (owner != NULL && &contextRef.getOwner() != owner) throw OpenMMException("This Integrator is already bound to a context"); if (contextRef.getSystem().getNumConstraints() > 0) throw OpenMMException("RPMDIntegrator cannot be used with Systems that include constraints"); context = &contextRef; owner = &contextRef.getOwner(); kernel = context->getPlatform().createKernel(IntegrateRPMDStepKernel::Name(), contextRef); kernel.getAs<IntegrateRPMDStepKernel>().initialize(contextRef.getSystem(), *this); }
void CudaIntegrateRPMDStepKernel::computeForces(ContextImpl& context) { // Compute forces from all groups that didn't have a specified contraction. for (int i = 0; i < numCopies; i++) { void* copyToContextArgs[] = {&velocities->getDevicePointer(), &cu.getVelm().getDevicePointer(), &positions->getDevicePointer(), &cu.getPosq().getDevicePointer(), &cu.getAtomIndexArray().getDevicePointer(), &i}; cu.executeKernel(copyToContextKernel, copyToContextArgs, cu.getNumAtoms()); context.computeVirtualSites(); context.updateContextState(); context.calcForcesAndEnergy(true, false, groupsNotContracted); void* copyFromContextArgs[] = {&cu.getForce().getDevicePointer(), &forces->getDevicePointer(), &cu.getVelm().getDevicePointer(), &velocities->getDevicePointer(), &cu.getPosq().getDevicePointer(), &positions->getDevicePointer(), &cu.getAtomIndexArray().getDevicePointer(), &i}; cu.executeKernel(copyFromContextKernel, copyFromContextArgs, cu.getNumAtoms()); } // Now loop over contractions and compute forces from them. for (map<int, int>::const_iterator iter = groupsByCopies.begin(); iter != groupsByCopies.end(); ++iter) { int copies = iter->first; int groupFlags = iter->second; // Find the contracted positions. void* contractPosArgs[] = {&positions->getDevicePointer(), &contractedPositions->getDevicePointer()}; cu.executeKernel(positionContractionKernels[copies], contractPosArgs, numParticles*numCopies, workgroupSize); // Compute forces. for (int i = 0; i < copies; i++) { void* copyToContextArgs[] = {&velocities->getDevicePointer(), &cu.getVelm().getDevicePointer(), &contractedPositions->getDevicePointer(), &cu.getPosq().getDevicePointer(), &cu.getAtomIndexArray().getDevicePointer(), &i}; cu.executeKernel(copyToContextKernel, copyToContextArgs, cu.getNumAtoms()); context.computeVirtualSites(); context.calcForcesAndEnergy(true, false, groupFlags); void* copyFromContextArgs[] = {&cu.getForce().getDevicePointer(), &contractedForces->getDevicePointer(), &cu.getVelm().getDevicePointer(), &velocities->getDevicePointer(), &cu.getPosq().getDevicePointer(), &contractedPositions->getDevicePointer(), &cu.getAtomIndexArray().getDevicePointer(), &i}; cu.executeKernel(copyFromContextKernel, copyFromContextArgs, cu.getNumAtoms()); } // Apply the forces to the original copies. void* contractForceArgs[] = {&forces->getDevicePointer(), &contractedForces->getDevicePointer()}; cu.executeKernel(forceContractionKernels[copies], contractForceArgs, numParticles*numCopies, workgroupSize); } if (groupsByCopies.size() > 0) { // Ensure the Context contains the positions from the last copy, since we'll assume that later. int i = numCopies-1; void* copyToContextArgs[] = {&velocities->getDevicePointer(), &cu.getVelm().getDevicePointer(), &positions->getDevicePointer(), &cu.getPosq().getDevicePointer(), &cu.getAtomIndexArray().getDevicePointer(), &i}; cu.executeKernel(copyToContextKernel, copyToContextArgs, cu.getNumAtoms()); } }
void NonbondedForceImpl::initialize(ContextImpl& context) { kernel = context.getPlatform().createKernel(CalcNonbondedForceKernel::Name(), context); // Check for errors in the specification of exceptions. const System& system = context.getSystem(); if (owner.getNumParticles() != system.getNumParticles()) throw OpenMMException("NonbondedForce must have exactly as many particles as the System it belongs to."); if (owner.getUseSwitchingFunction()) { if (owner.getSwitchingDistance() < 0 || owner.getSwitchingDistance() >= owner.getCutoffDistance()) throw OpenMMException("NonbondedForce: Switching distance must satisfy 0 <= r_switch < r_cutoff"); } vector<set<int> > exceptions(owner.getNumParticles()); for (int i = 0; i < owner.getNumExceptions(); i++) { int particle1, particle2; double chargeProd, sigma, epsilon; owner.getExceptionParameters(i, particle1, particle2, chargeProd, sigma, epsilon); if (particle1 < 0 || particle1 >= owner.getNumParticles()) { stringstream msg; msg << "NonbondedForce: Illegal particle index for an exception: "; msg << particle1; throw OpenMMException(msg.str()); } if (particle2 < 0 || particle2 >= owner.getNumParticles()) { stringstream msg; msg << "NonbondedForce: Illegal particle index for an exception: "; msg << particle2; throw OpenMMException(msg.str()); } if (exceptions[particle1].count(particle2) > 0 || exceptions[particle2].count(particle1) > 0) { stringstream msg; msg << "NonbondedForce: Multiple exceptions are specified for particles "; msg << particle1; msg << " and "; msg << particle2; throw OpenMMException(msg.str()); } exceptions[particle1].insert(particle2); exceptions[particle2].insert(particle1); } if (owner.getNonbondedMethod() == NonbondedForce::CutoffPeriodic || owner.getNonbondedMethod() == NonbondedForce::Ewald || owner.getNonbondedMethod() == NonbondedForce::PME) { Vec3 boxVectors[3]; system.getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); double cutoff = owner.getCutoffDistance(); if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2]) throw OpenMMException("NonbondedForce: The cutoff distance cannot be greater than half the periodic box size."); if (owner.getNonbondedMethod() == NonbondedForce::Ewald && (boxVectors[1][0] != 0.0 || boxVectors[2][0] != 0.0 || boxVectors[2][1] != 0)) throw OpenMMException("NonbondedForce: Ewald is not supported with non-rectangular boxes. Use PME instead."); } kernel.getAs<CalcNonbondedForceKernel>().initialize(context.getSystem(), owner); }
void GBSAOBCForceImpl::initialize(ContextImpl& context) { kernel = context.getPlatform().createKernel(CalcGBSAOBCForceKernel::Name(), context); if (owner.getNumParticles() != context.getSystem().getNumParticles()) throw OpenMMException("GBSAOBCForce must have exactly as many particles as the System it belongs to."); if (owner.getNonbondedMethod() == GBSAOBCForce::CutoffPeriodic) { Vec3 boxVectors[3]; context.getSystem().getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); double cutoff = owner.getCutoffDistance(); if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2]) throw OpenMMException("GBSAOBCForce: The cutoff distance cannot be greater than half the periodic box size."); } kernel.getAs<CalcGBSAOBCForceKernel>().initialize(context.getSystem(), owner); }
void MonteCarloAnisotropicBarostatImpl::initialize(ContextImpl& context) { kernel = context.getPlatform().createKernel(ApplyMonteCarloBarostatKernel::Name(), context); kernel.getAs<ApplyMonteCarloBarostatKernel>().initialize(context.getSystem(), owner); Vec3 box[3]; context.getPeriodicBoxVectors(box[0], box[1], box[2]); double volume = box[0][0]*box[1][1]*box[2][2]; for (int i=0; i<3; i++) { volumeScale[i] = 0.01*volume; numAttempted[i] = 0; numAccepted[i] = 0; } init_gen_rand(owner.getRandomNumberSeed(), random); }
void MonteCarloBarostatImpl::initialize(ContextImpl& context) { kernel = context.getPlatform().createKernel(ApplyMonteCarloBarostatKernel::Name(), context); kernel.getAs<ApplyMonteCarloBarostatKernel>().initialize(context.getSystem(), owner); Vec3 box[3]; context.getPeriodicBoxVectors(box[0], box[1], box[2]); double volume = box[0][0]*box[1][1]*box[2][2]; volumeScale = 0.01*volume; numAttempted = 0; numAccepted = 0; int randSeed = owner.getRandomNumberSeed(); // A random seed of 0 means use a unique one if (randSeed == 0) randSeed = osrngseed(); init_gen_rand(randSeed, random); }
ExpressionTreeNode ReferenceCustomDynamics::replaceDerivFunctions(const ExpressionTreeNode& node, ContextImpl& context) { const Operation& op = node.getOperation(); if (op.getId() == Operation::CUSTOM && op.getName() == "deriv") { string param = node.getChildren()[1].getOperation().getName(); if (context.getParameters().find(param) == context.getParameters().end()) throw OpenMMException("The second argument to deriv() must be a context parameter"); return ExpressionTreeNode(new Operation::Custom("deriv", new DerivFunction(energyParamDerivs, param))); } else { vector<ExpressionTreeNode> children; for (int i = 0; i < (int) node.getChildren().size(); i++) children.push_back(replaceDerivFunctions(node.getChildren()[i], context)); return ExpressionTreeNode(op.clone(), children); } }
static double computeShiftedKineticEnergy(ContextImpl& context, vector<double>& inverseMasses, double timeShift, ReferenceConstraintAlgorithm* constraints) { const System& system = context.getSystem(); int numParticles = system.getNumParticles(); vector<RealVec>& posData = extractPositions(context); vector<RealVec>& velData = extractVelocities(context); vector<RealVec>& forceData = extractForces(context); // Compute the shifted velocities. vector<RealVec> shiftedVel(numParticles); for (int i = 0; i < numParticles; ++i) { if (inverseMasses[i] > 0) shiftedVel[i] = velData[i]+forceData[i]*(timeShift*inverseMasses[i]); else shiftedVel[i] = velData[i]; } // Apply constraints to them. if (constraints != NULL) { constraints->setTolerance(1e-4); constraints->applyToVelocities(numParticles, posData, shiftedVel, inverseMasses); } // Compute the kinetic energy. double energy = 0.0; for (int i = 0; i < numParticles; ++i) if (inverseMasses[i] > 0) energy += (shiftedVel[i].dot(shiftedVel[i]))/inverseMasses[i]; return 0.5*energy; }
/** * Compute the kinetic energy of the system, possibly shifting the velocities in time to account * for a leapfrog integrator. */ static double computeShiftedKineticEnergy(ContextImpl& context, vector<double>& masses, double timeShift) { vector<RealVec>& posData = extractPositions(context); vector<RealVec>& velData = extractVelocities(context); vector<RealVec>& forceData = extractForces(context); int numParticles = context.getSystem().getNumParticles(); // Compute the shifted velocities. vector<RealVec> shiftedVel(numParticles); for (int i = 0; i < numParticles; ++i) { if (masses[i] > 0) shiftedVel[i] = velData[i]+forceData[i]*(timeShift/masses[i]); else shiftedVel[i] = velData[i]; } // Apply constraints to them. vector<double> inverseMasses(numParticles); for (int i = 0; i < numParticles; i++) inverseMasses[i] = (masses[i] == 0 ? 0 : 1/masses[i]); extractConstraints(context).applyToVelocities(posData, shiftedVel, inverseMasses, 1e-4); // Compute the kinetic energy. double energy = 0.0; for (int i = 0; i < numParticles; ++i) if (masses[i] > 0) energy += masses[i]*(shiftedVel[i].dot(shiftedVel[i])); return 0.5*energy; }
// constructor TypeImpl::TypeImpl(Type* owner, ModulePtr module) : m_owner(owner), m_backendVariableType(0) , m_backendThisType(0) , m_thisConverter(0), m_backendPointer(0), m_virtualTable(0), m_addressMap(0) , m_fields(0), m_methods(0), m_ancestors(0) { llvm::Module* backendModule = module->getMetadata()->getBackendModule(); llvm::LLVMContext& context = backendModule->getContext(); // create pointer to type llvm::Type* pointerType = llvm::Type::getInt8Ty(context); m_backendPointer = new llvm::GlobalVariable(*backendModule, pointerType, false, llvm::GlobalValue::ExternalLinkage, 0, "::_type"); // map pointer to type ContextImpl* meta = module->getContext()->getMetadata(); llvm::ExecutionEngine* engine = meta->getBackendEngine(); engine->addGlobalMapping(m_backendPointer, owner); }
double CpuCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups) { // Sum the forces from all the threads. SumForceTask task(context.getSystem().getNumParticles(), extractForces(context), data); data.threads.execute(task); data.threads.waitForThreads(); return referenceKernel.getAs<ReferenceCalcForcesAndEnergyKernel>().finishComputation(context, includeForce, includeEnergy, groups); }
void CpuCalcForcesAndEnergyKernel::beginComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups) { referenceKernel.getAs<ReferenceCalcForcesAndEnergyKernel>().beginComputation(context, includeForce, includeEnergy, groups); // Convert positions to single precision and clear the forces. InitForceTask task(context.getSystem().getNumParticles(), context, data); data.threads.execute(task); data.threads.waitForThreads(); }
void Integrator::initialize( ContextImpl &contextRef ) { context = &contextRef; if( context->getSystem().getNumConstraints() > 0 ) { throw OpenMMException( "LTMD Integrator does not support constraints" ); } kernel = context->getPlatform().createKernel( StepKernel::Name(), contextRef ); ( ( StepKernel & )( kernel.getImpl() ) ).initialize( contextRef.getSystem(), *this ); //(dynamic_cast<StepKernel &>( kernel.getImpl() )).initialize( contextRef.getSystem(), *this ); }
void DrudeLangevinIntegrator::initialize(ContextImpl& contextRef) { if (owner != NULL && &contextRef.getOwner() != owner) throw OpenMMException("This Integrator is already bound to a context"); const DrudeForce* force = NULL; const System& system = contextRef.getSystem(); for (int i = 0; i < system.getNumForces(); i++) if (dynamic_cast<const DrudeForce*>(&system.getForce(i)) != NULL) { if (force == NULL) force = dynamic_cast<const DrudeForce*>(&system.getForce(i)); else throw OpenMMException("The System contains multiple DrudeForces"); } if (force == NULL) throw OpenMMException("The System does not contain a DrudeForce"); context = &contextRef; owner = &contextRef.getOwner(); kernel = context->getPlatform().createKernel(IntegrateDrudeLangevinStepKernel::Name(), contextRef); kernel.getAs<IntegrateDrudeLangevinStepKernel>().initialize(contextRef.getSystem(), *this, *force); }
void CustomIntegrator::initialize(ContextImpl& contextRef) { if (owner != NULL && &contextRef.getOwner() != owner) throw OpenMMException("This Integrator is already bound to a context"); vector<std::string> variableList; set<std::string> variableSet; variableList.insert(variableList.end(), globalNames.begin(), globalNames.end()); variableList.insert(variableList.end(), perDofNames.begin(), perDofNames.end()); for (int i = 0; i < (int) variableList.size(); i++) { string& name = variableList[i]; if (variableSet.find(name) != variableSet.end()) throw OpenMMException("The Integrator defines two variables with the same name: "+name); variableSet.insert(name); if (contextRef.getParameters().find(name) != contextRef.getParameters().end()) throw OpenMMException("The Integrator defines a variable with the same name as a Context parameter: "+name); } set<std::string> globalTargets; globalTargets.insert(globalNames.begin(), globalNames.end()); globalTargets.insert("dt"); for (map<string, double>::const_iterator iter = contextRef.getParameters().begin(); iter != contextRef.getParameters().end(); ++iter) globalTargets.insert(iter->first); for (int i = 0; i < computations.size(); i++) { if (computations[i].type == ComputeGlobal && globalTargets.find(computations[i].variable) == globalTargets.end()) throw OpenMMException("Unknown global variable: "+computations[i].variable); } context = &contextRef; owner = &contextRef.getOwner(); kernel = context->getPlatform().createKernel(IntegrateCustomStepKernel::Name(), contextRef); kernel.getAs<IntegrateCustomStepKernel>().initialize(contextRef.getSystem(), *this); kernel.getAs<IntegrateCustomStepKernel>().setGlobalVariables(contextRef, globalValues); for (int i = 0; i < (int) perDofValues.size(); i++) { if (perDofValues[i].size() == 1) perDofValues[i].resize(context->getSystem().getNumParticles(), perDofValues[i][0]); kernel.getAs<IntegrateCustomStepKernel>().setPerDofVariable(contextRef, i, perDofValues[i]); } }
void MonteCarloBarostatImpl::updateContextState(ContextImpl& context) { if (++step < owner.getFrequency() || owner.getFrequency() == 0) return; step = 0; // Compute the current potential energy. double initialEnergy = context.getOwner().getState(State::Energy).getPotentialEnergy(); // Modify the periodic box size. Vec3 box[3]; context.getPeriodicBoxVectors(box[0], box[1], box[2]); double volume = box[0][0]*box[1][1]*box[2][2]; double deltaVolume = volumeScale*2*(genrand_real2(random)-0.5); double newVolume = volume+deltaVolume; double lengthScale = std::pow(newVolume/volume, 1.0/3.0); kernel.getAs<ApplyMonteCarloBarostatKernel>().scaleCoordinates(context, lengthScale, lengthScale, lengthScale); context.getOwner().setPeriodicBoxVectors(box[0]*lengthScale, box[1]*lengthScale, box[2]*lengthScale); // Compute the energy of the modified system. double finalEnergy = context.getOwner().getState(State::Energy).getPotentialEnergy(); double pressure = context.getParameter(MonteCarloBarostat::Pressure())*(AVOGADRO*1e-25); double kT = BOLTZ*context.getParameter(MonteCarloBarostat::Temperature()); double w = finalEnergy-initialEnergy + pressure*deltaVolume - context.getMolecules().size()*kT*std::log(newVolume/volume); if (w > 0 && genrand_real2(random) > std::exp(-w/kT)) { // Reject the step. kernel.getAs<ApplyMonteCarloBarostatKernel>().restoreCoordinates(context); context.getOwner().setPeriodicBoxVectors(box[0], box[1], box[2]); volume = newVolume; } else numAccepted++; numAttempted++; if (numAttempted >= 10) { if (numAccepted < 0.25*numAttempted) { volumeScale /= 1.1; numAttempted = 0; numAccepted = 0; } else if (numAccepted > 0.75*numAttempted) { volumeScale = std::min(volumeScale*1.1, volume*0.3); numAttempted = 0; numAccepted = 0; } } }
double ReferenceIntegrateRPMDStepKernel::computeKineticEnergy(ContextImpl& context, const RPMDIntegrator& integrator) { const System& system = context.getSystem(); int numParticles = system.getNumParticles(); vector<RealVec>& velData = extractVelocities(context); double energy = 0.0; for (int i = 0; i < numParticles; ++i) { double mass = system.getParticleMass(i); if (mass > 0) { RealVec v = velData[i]; energy += mass*(v.dot(v)); } } return 0.5*energy; }
void CpuIntegrateLangevinStepKernel::execute(ContextImpl& context, const LangevinIntegrator& integrator) { double temperature = integrator.getTemperature(); double friction = integrator.getFriction(); double stepSize = integrator.getStepSize(); vector<RealVec>& posData = extractPositions(context); vector<RealVec>& velData = extractVelocities(context); vector<RealVec>& forceData = extractForces(context); if (dynamics == 0 || temperature != prevTemp || friction != prevFriction || stepSize != prevStepSize) { // Recreate the computation objects with the new parameters. if (dynamics) delete dynamics; RealOpenMM tau = (friction == 0.0 ? 0.0 : 1.0/friction); dynamics = new CpuLangevinDynamics(context.getSystem().getNumParticles(), stepSize, tau, temperature, data.threads, data.random); dynamics->setReferenceConstraintAlgorithm(&extractConstraints(context)); prevTemp = temperature; prevFriction = friction; prevStepSize = stepSize; } dynamics->update(context.getSystem(), posData, velData, forceData, masses, integrator.getConstraintTolerance()); ReferencePlatform::PlatformData* refData = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData()); refData->time += stepSize; refData->stepCount++; }
void CpuCalcNonbondedForceKernel::copyParametersToContext(ContextImpl& context, const NonbondedForce& force) { if (force.getNumParticles() != numParticles) throw OpenMMException("updateParametersInContext: The number of particles has changed"); vector<int> nb14s; for (int i = 0; i < force.getNumExceptions(); i++) { int particle1, particle2; double chargeProd, sigma, epsilon; force.getExceptionParameters(i, particle1, particle2, chargeProd, sigma, epsilon); if (chargeProd != 0.0 || epsilon != 0.0) nb14s.push_back(i); } if (nb14s.size() != num14) throw OpenMMException("updateParametersInContext: The number of non-excluded exceptions has changed"); // Record the values. double sumSquaredCharges = 0.0; for (int i = 0; i < numParticles; ++i) { double charge, radius, depth; force.getParticleParameters(i, charge, radius, depth); data.posq[4*i+3] = (float) charge; particleParams[i] = make_pair((float) (0.5*radius), (float) (2.0*sqrt(depth))); sumSquaredCharges += charge*charge; } if (nonbondedMethod == Ewald || nonbondedMethod == PME) ewaldSelfEnergy = -ONE_4PI_EPS0*ewaldAlpha*sumSquaredCharges/sqrt(M_PI); else ewaldSelfEnergy = 0.0; for (int i = 0; i < num14; ++i) { int particle1, particle2; double charge, radius, depth; force.getExceptionParameters(nb14s[i], particle1, particle2, charge, radius, depth); bonded14IndexArray[i][0] = particle1; bonded14IndexArray[i][1] = particle2; bonded14ParamArray[i][0] = static_cast<RealOpenMM>(radius); bonded14ParamArray[i][1] = static_cast<RealOpenMM>(4.0*depth); bonded14ParamArray[i][2] = static_cast<RealOpenMM>(charge); } // Recompute the coefficient for the dispersion correction. NonbondedForce::NonbondedMethod method = force.getNonbondedMethod(); if (force.getUseDispersionCorrection() && (method == NonbondedForce::CutoffPeriodic || method == NonbondedForce::Ewald || method == NonbondedForce::PME)) dispersionCoefficient = NonbondedForceImpl::calcDispersionCorrection(context.getSystem(), force); }
void ReferenceCalcMBPolElectrostaticsForceKernel::getSystemElectrostaticsMoments(ContextImpl& context, std::vector< double >& outputElectrostaticsMoments){ // retrieve masses const OpenMM::System& system = context.getSystem(); vector<RealOpenMM> masses; for (int i = 0; i < system.getNumParticles(); ++i) { masses.push_back( static_cast<RealOpenMM>(system.getParticleMass(i)) ); } MBPolReferenceElectrostaticsForce* mbpolReferenceElectrostaticsForce = setupMBPolReferenceElectrostaticsForce( context ); vector<RealVec>& posData = extractPositions(context); mbpolReferenceElectrostaticsForce->calculateMBPolSystemElectrostaticsMoments( masses, posData, charges, tholes, dampingFactors, polarity, axisTypes, multipoleAtomZs, multipoleAtomXs, multipoleAtomYs, multipoleAtomCovalentInfo, outputElectrostaticsMoments ); delete mbpolReferenceElectrostaticsForce; return; }
void ReferenceIntegrateDrudeSCFStepKernel::execute(ContextImpl& context, const DrudeSCFIntegrator& integrator) { vector<RealVec>& pos = extractPositions(context); vector<RealVec>& vel = extractVelocities(context); vector<RealVec>& force = extractForces(context); // Update the positions and velocities. int numParticles = particleInvMass.size(); vector<RealVec> xPrime(numParticles); RealOpenMM dt = integrator.getStepSize(); for (int i = 0; i < numParticles; i++) { if (particleInvMass[i] != 0.0) { vel[i] += force[i]*particleInvMass[i]*dt; xPrime[i] = pos[i]+vel[i]*dt; } } // Apply constraints. if (constraints != NULL) constraints->apply(numParticles, pos, xPrime, particleInvMass); // Record the constrained positions and velocities. RealOpenMM dtInv = 1.0/dt; for (int i = 0; i < numParticles; i++) { if (particleInvMass[i] != 0.0) { vel[i] = (xPrime[i]-pos[i])*dtInv; pos[i] = xPrime[i]; } } // Update the positions of virtual sites and Drude particles. ReferenceVirtualSites::computePositions(context.getSystem(), pos); minimize(context, integrator.getMinimizationErrorTolerance()); data.time += integrator.getStepSize(); data.stepCount++; }
double CpuCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { vector<RealVec>& posData = extractPositions(context); vector<RealVec>& forceData = extractForces(context); RealVec& box = extractBoxSize(context); float floatBoxSize[3] = {(float) box[0], (float) box[1], (float) box[2]}; double energy = 0; bool periodic = (nonbondedMethod == CutoffPeriodic); if (nonbondedMethod != NoCutoff) { neighborList->computeNeighborList(numParticles, data.posq, exclusions, floatBoxSize, data.isPeriodic, nonbondedCutoff, data.threads); nonbonded->setUseCutoff(nonbondedCutoff, *neighborList); } if (periodic) { double minAllowedSize = 2*nonbondedCutoff; if (box[0] < minAllowedSize || box[1] < minAllowedSize || box[2] < minAllowedSize) throw OpenMMException("The periodic box size has decreased to less than twice the nonbonded cutoff."); nonbonded->setPeriodic(box); } bool globalParamsChanged = false; for (int i = 0; i < (int) globalParameterNames.size(); i++) { double value = context.getParameter(globalParameterNames[i]); if (globalParamValues[globalParameterNames[i]] != value) globalParamsChanged = true; globalParamValues[globalParameterNames[i]] = value; } if (useSwitchingFunction) nonbonded->setUseSwitchingFunction(switchingDistance); nonbonded->calculatePairIxn(numParticles, &data.posq[0], posData, particleParamArray, 0, globalParamValues, data.threadForce, includeForces, includeEnergy, energy); // Add in the long range correction. if (!hasInitializedLongRangeCorrection || (globalParamsChanged && forceCopy != NULL)) { longRangeCoefficient = CustomNonbondedForceImpl::calcLongRangeCorrection(*forceCopy, context.getOwner()); hasInitializedLongRangeCorrection = true; } energy += longRangeCoefficient/(box[0]*box[1]*box[2]); return energy; }
void CustomHbondForceImpl::initialize(ContextImpl& context) { kernel = context.getPlatform().createKernel(CalcCustomHbondForceKernel::Name(), context); // Check for errors in the specification of parameters and exclusions. const System& system = context.getSystem(); vector<set<int> > exclusions(owner.getNumDonors()); vector<double> parameters; int numDonorParameters = owner.getNumPerDonorParameters(); for (int i = 0; i < owner.getNumDonors(); i++) { int d1, d2, d3; owner.getDonorParameters(i, d1, d2, d3, parameters); if (d1 < 0 || d1 >= system.getNumParticles()) { stringstream msg; msg << "CustomHbondForce: Illegal particle index for a donor: "; msg << d1; throw OpenMMException(msg.str()); } if (d2 < -1 || d2 >= system.getNumParticles()) { stringstream msg; msg << "CustomHbondForce: Illegal particle index for a donor: "; msg << d2; throw OpenMMException(msg.str()); } if (d3 < -1 || d3 >= system.getNumParticles()) { stringstream msg; msg << "CustomHbondForce: Illegal particle index for a donor: "; msg << d3; throw OpenMMException(msg.str()); } if (parameters.size() != numDonorParameters) { stringstream msg; msg << "CustomHbondForce: Wrong number of parameters for donor "; msg << i; throw OpenMMException(msg.str()); } } int numAcceptorParameters = owner.getNumPerAcceptorParameters(); for (int i = 0; i < owner.getNumAcceptors(); i++) { int a1, a2, a3; owner.getAcceptorParameters(i, a1, a2, a3, parameters); if (a1 < 0 || a1 >= system.getNumParticles()) { stringstream msg; msg << "CustomHbondForce: Illegal particle index for an acceptor: "; msg << a1; throw OpenMMException(msg.str()); } if (a2 < -1 || a2 >= system.getNumParticles()) { stringstream msg; msg << "CustomHbondForce: Illegal particle index for an acceptor: "; msg << a2; throw OpenMMException(msg.str()); } if (a3 < -1 || a3 >= system.getNumParticles()) { stringstream msg; msg << "CustomHbondForce: Illegal particle index for an acceptor: "; msg << a3; throw OpenMMException(msg.str()); } if (parameters.size() != numAcceptorParameters) { stringstream msg; msg << "CustomHbondForce: Wrong number of parameters for acceptor "; msg << i; throw OpenMMException(msg.str()); } } for (int i = 0; i < owner.getNumExclusions(); i++) { int donor, acceptor; owner.getExclusionParticles(i, donor, acceptor); if (donor < 0 || donor >= owner.getNumDonors()) { stringstream msg; msg << "CustomHbondForce: Illegal donor index for an exclusion: "; msg << donor; throw OpenMMException(msg.str()); } if (acceptor < 0 || acceptor >= owner.getNumAcceptors()) { stringstream msg; msg << "CustomHbondForce: Illegal acceptor index for an exclusion: "; msg << acceptor; throw OpenMMException(msg.str()); } if (exclusions[donor].count(acceptor) > 0) { stringstream msg; msg << "CustomHbondForce: Multiple exclusions are specified for donor "; msg << donor; msg << " and acceptor "; msg << acceptor; throw OpenMMException(msg.str()); } exclusions[donor].insert(acceptor); } if (owner.getNonbondedMethod() == CustomHbondForce::CutoffPeriodic) { Vec3 boxVectors[3]; system.getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); double cutoff = owner.getCutoffDistance(); if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2]) throw OpenMMException("CustomHbondForce: The cutoff distance cannot be greater than half the periodic box size."); } kernel.getAs<CalcCustomHbondForceKernel>().initialize(context.getSystem(), owner); }
void RMSDForceImpl::updateParametersInContext(ContextImpl& context) { kernel.getAs<CalcRMSDForceKernel>().copyParametersToContext(context, owner); context.systemChanged(); }
void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, vector<RealVec>& atomCoordinates, vector<RealVec>& velocities, vector<RealVec>& forces, vector<RealOpenMM>& masses, map<string, RealOpenMM>& globals, vector<vector<RealVec> >& perDof, bool& forcesAreValid, RealOpenMM tolerance) { if (invalidatesForces.size() == 0) initialize(context, masses, globals); int numSteps = stepType.size(); globals.insert(context.getParameters().begin(), context.getParameters().end()); for (map<string, RealOpenMM>::const_iterator iter = globals.begin(); iter != globals.end(); ++iter) expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second); oldPos = atomCoordinates; // Loop over steps and execute them. for (int step = 0; step < numSteps; ) { if ((needsForces[step] || needsEnergy[step]) && (!forcesAreValid || context.getLastForceGroups() != forceGroupFlags[step])) { // Recompute forces and/or energy. bool computeForce = needsForces[step] || computeBothForceAndEnergy[step]; bool computeEnergy = needsEnergy[step] || computeBothForceAndEnergy[step]; recordChangedParameters(context, globals); RealOpenMM e = context.calcForcesAndEnergy(computeForce, computeEnergy, forceGroupFlags[step]); if (computeEnergy) { energy = e; context.getEnergyParameterDerivatives(energyParamDerivs); } forcesAreValid = true; } // Execute the step. int nextStep = step+1; switch (stepType[step]) { case CustomIntegrator::ComputeGlobal: { uniform = SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber(); gaussian = SimTKOpenMMUtilities::getNormallyDistributedRandomNumber(); RealOpenMM result = stepExpressions[step][0].evaluate(); globals[stepVariable[step]] = result; expressionSet.setVariable(stepVariableIndex[step], result); break; } case CustomIntegrator::ComputePerDof: { vector<RealVec>* results = NULL; if (stepVariableIndex[step] == xIndex) results = &atomCoordinates; else if (stepVariableIndex[step] == vIndex) results = &velocities; else { for (int j = 0; j < integrator.getNumPerDofVariables(); j++) if (stepVariableIndex[step] == perDofVariableIndex[j]) results = &perDof[j]; } if (results == NULL) throw OpenMMException("Illegal per-DOF output variable: "+stepVariable[step]); computePerDof(numberOfAtoms, *results, atomCoordinates, velocities, forces, masses, perDof, stepExpressions[step][0]); break; } case CustomIntegrator::ComputeSum: { computePerDof(numberOfAtoms, sumBuffer, atomCoordinates, velocities, forces, masses, perDof, stepExpressions[step][0]); RealOpenMM sum = 0.0; for (int j = 0; j < numberOfAtoms; j++) if (masses[j] != 0.0) sum += sumBuffer[j][0]+sumBuffer[j][1]+sumBuffer[j][2]; globals[stepVariable[step]] = sum; expressionSet.setVariable(stepVariableIndex[step], sum); break; } case CustomIntegrator::ConstrainPositions: { getReferenceConstraintAlgorithm()->apply(oldPos, atomCoordinates, inverseMasses, tolerance); oldPos = atomCoordinates; break; } case CustomIntegrator::ConstrainVelocities: { getReferenceConstraintAlgorithm()->applyToVelocities(oldPos, velocities, inverseMasses, tolerance); break; } case CustomIntegrator::UpdateContextState: { recordChangedParameters(context, globals); context.updateContextState(); globals.insert(context.getParameters().begin(), context.getParameters().end()); for (map<string, RealOpenMM>::const_iterator iter = globals.begin(); iter != globals.end(); ++iter) expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second); break; } case CustomIntegrator::IfBlockStart: { if (!evaluateCondition(step)) nextStep = blockEnd[step]+1; break; } case CustomIntegrator::WhileBlockStart: { if (!evaluateCondition(step)) nextStep = blockEnd[step]+1; break; } case CustomIntegrator::BlockEnd: { if (blockEnd[step] != -1) nextStep = blockEnd[step]; // Return to the start of a while block. break; } } if (invalidatesForces[step]) forcesAreValid = false; step = nextStep; } ReferenceVirtualSites::computePositions(context.getSystem(), atomCoordinates); incrementTimeStep(); recordChangedParameters(context, globals); }