void CudaIntegrateDrudeSCFStepKernel::execute(ContextImpl& context, const DrudeSCFIntegrator& integrator) { cu.setAsCurrent(); CudaIntegrationUtilities& integration = cu.getIntegrationUtilities(); int numAtoms = cu.getNumAtoms(); int paddedNumAtoms = cu.getPaddedNumAtoms(); double dt = integrator.getStepSize(); if (dt != prevStepSize) { if (cu.getUseDoublePrecision() || cu.getUseMixedPrecision()) { vector<double2> stepSizeVec(1); stepSizeVec[0] = make_double2(dt, dt); cu.getIntegrationUtilities().getStepSize().upload(stepSizeVec); } else { vector<float2> stepSizeVec(1); stepSizeVec[0] = make_float2((float) dt, (float) dt); cu.getIntegrationUtilities().getStepSize().upload(stepSizeVec); } prevStepSize = dt; } // Call the first integration kernel. CUdeviceptr posCorrection = (cu.getUseMixedPrecision() ? cu.getPosqCorrection().getDevicePointer() : 0); void* args1[] = {&numAtoms, &paddedNumAtoms, &cu.getIntegrationUtilities().getStepSize().getDevicePointer(), &cu.getPosq().getDevicePointer(), &posCorrection, &cu.getVelm().getDevicePointer(), &cu.getForce().getDevicePointer(), &integration.getPosDelta().getDevicePointer()}; cu.executeKernel(kernel1, args1, numAtoms); // Apply constraints. integration.applyConstraints(integrator.getConstraintTolerance()); // Call the second integration kernel. void* args2[] = {&numAtoms, &cu.getIntegrationUtilities().getStepSize().getDevicePointer(), &cu.getPosq().getDevicePointer(), &posCorrection, &cu.getVelm().getDevicePointer(), &integration.getPosDelta().getDevicePointer()}; cu.executeKernel(kernel2, args2, numAtoms); // Update the positions of virtual sites and Drude particles. integration.computeVirtualSites(); minimize(context, integrator.getMinimizationErrorTolerance()); // Update the time and step count. cu.setTime(cu.getTime()+dt); cu.setStepCount(cu.getStepCount()+1); cu.reorderAtoms(); }
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. extractConstraints(context).apply(pos, xPrime, particleInvMass, integrator.getConstraintTolerance()); // 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++; }
void ReferenceIntegrateDrudeSCFStepKernel::initialize(const System& system, const DrudeSCFIntegrator& integrator, const DrudeForce& force) { // Identify Drude particles. for (int i = 0; i < force.getNumParticles(); i++) { int p, p1, p2, p3, p4; double charge, polarizability, aniso12, aniso34; force.getParticleParameters(i, p, p1, p2, p3, p4, charge, polarizability, aniso12, aniso34); drudeParticles.push_back(p); } // Record particle masses. vector<RealOpenMM> particleMass; for (int i = 0; i < system.getNumParticles(); i++) { double mass = system.getParticleMass(i); particleMass.push_back(mass); particleInvMass.push_back(mass == 0.0 ? 0.0 : 1.0/mass); } // Prepare constraints. int numConstraints = system.getNumConstraints(); if (numConstraints > 0) { vector<pair<int, int> > constraintIndices(numConstraints); vector<RealOpenMM> constraintDistances(numConstraints); for (int i = 0; i < numConstraints; ++i) { int particle1, particle2; double distance; system.getConstraintParameters(i, particle1, particle2, distance); constraintIndices[i].first = particle1; constraintIndices[i].second = particle2; constraintDistances[i] = static_cast<RealOpenMM>(distance); } vector<ReferenceCCMAAlgorithm::AngleInfo> angles; findAnglesForCCMA(system, angles); constraints = new ReferenceCCMAAlgorithm(system.getNumParticles(), numConstraints, constraintIndices, constraintDistances, particleMass, angles, (RealOpenMM)integrator.getConstraintTolerance()); } // Initialize the energy minimizer. minimizerPos = lbfgs_malloc(drudeParticles.size()*3); if (minimizerPos == NULL) throw OpenMMException("DrudeSCFIntegrator: Failed to allocate memory"); lbfgs_parameter_init(&minimizerParams); minimizerParams.linesearch = LBFGS_LINESEARCH_BACKTRACKING_STRONG_WOLFE; if (sizeof(RealOpenMM) < 8) minimizerParams.xtol = 1e-7; }