ReferenceCustomManyParticleIxn::ReferenceCustomManyParticleIxn(const CustomManyParticleForce& force) : useCutoff(false), usePeriodic(false) { numParticlesPerSet = force.getNumParticlesPerSet(); numPerParticleParameters = force.getNumPerParticleParameters(); centralParticleMode = (force.getPermutationMode() == CustomManyParticleForce::UniqueCentralParticle); // Create custom functions for the tabulated functions. map<string, Lepton::CustomFunction*> functions; for (int i = 0; i < (int) force.getNumTabulatedFunctions(); i++) functions[force.getTabulatedFunctionName(i)] = createReferenceTabulatedFunction(force.getTabulatedFunction(i)); // Parse the expression and create the object used to calculate the interaction. map<string, vector<int> > distances; map<string, vector<int> > angles; map<string, vector<int> > dihedrals; Lepton::ParsedExpression energyExpr = CustomManyParticleForceImpl::prepareExpression(force, functions, distances, angles, dihedrals); energyExpression = energyExpr.createProgram(); vector<string> particleParameterNames; if (force.getNonbondedMethod() != CustomManyParticleForce::NoCutoff) setUseCutoff(force.getCutoffDistance()); // Delete the custom functions. for (auto& function : functions) delete function.second; // Differentiate the energy to get expressions for the force. particleParamNames.resize(numParticlesPerSet); for (int i = 0; i < numParticlesPerSet; i++) { stringstream xname, yname, zname; xname << 'x' << (i+1); yname << 'y' << (i+1); zname << 'z' << (i+1); particleTerms.push_back(ReferenceCustomManyParticleIxn::ParticleTermInfo(xname.str(), i, 0, energyExpr.differentiate(xname.str()).optimize().createProgram())); particleTerms.push_back(ReferenceCustomManyParticleIxn::ParticleTermInfo(yname.str(), i, 1, energyExpr.differentiate(yname.str()).optimize().createProgram())); particleTerms.push_back(ReferenceCustomManyParticleIxn::ParticleTermInfo(zname.str(), i, 2, energyExpr.differentiate(zname.str()).optimize().createProgram())); for (int j = 0; j < numPerParticleParameters; j++) { stringstream paramname; paramname << force.getPerParticleParameterName(j) << (i+1); particleParamNames[i].push_back(paramname.str()); } } for (auto& term : distances) distanceTerms.push_back(ReferenceCustomManyParticleIxn::DistanceTermInfo(term.first, term.second, energyExpr.differentiate(term.first).optimize().createProgram())); for (auto& term : angles) angleTerms.push_back(ReferenceCustomManyParticleIxn::AngleTermInfo(term.first, term.second, energyExpr.differentiate(term.first).optimize().createProgram())); for (auto& term : dihedrals) dihedralTerms.push_back(ReferenceCustomManyParticleIxn::DihedralTermInfo(term.first, term.second, energyExpr.differentiate(term.first).optimize().createProgram())); // Record exclusions. exclusions.resize(force.getNumParticles()); for (int i = 0; i < (int) force.getNumExclusions(); i++) { int p1, p2; force.getExclusionParticles(i, p1, p2); exclusions[p1].insert(p2); exclusions[p2].insert(p1); } // Record information about type filters. CustomManyParticleForceImpl::buildFilterArrays(force, numTypes, particleTypes, orderIndex, particleOrder); }
void CpuCalcCustomNonbondedForceKernel::initialize(const System& system, const CustomNonbondedForce& force) { // Record the exclusions. numParticles = force.getNumParticles(); exclusions.resize(numParticles); for (int i = 0; i < force.getNumExclusions(); i++) { int particle1, particle2; force.getExclusionParticles(i, particle1, particle2); exclusions[particle1].insert(particle2); exclusions[particle2].insert(particle1); } // Build the arrays. int numParameters = force.getNumPerParticleParameters(); particleParamArray = new double*[numParticles]; for (int i = 0; i < numParticles; i++) particleParamArray[i] = new double[numParameters]; for (int i = 0; i < numParticles; ++i) { vector<double> parameters; force.getParticleParameters(i, parameters); for (int j = 0; j < numParameters; j++) particleParamArray[i][j] = parameters[j]; } nonbondedMethod = CalcCustomNonbondedForceKernel::NonbondedMethod(force.getNonbondedMethod()); nonbondedCutoff = force.getCutoffDistance(); if (nonbondedMethod == NoCutoff) useSwitchingFunction = false; else { neighborList = new CpuNeighborList(4); useSwitchingFunction = force.getUseSwitchingFunction(); switchingDistance = force.getSwitchingDistance(); } // Create custom functions for the tabulated functions. map<string, Lepton::CustomFunction*> functions; for (int i = 0; i < force.getNumFunctions(); i++) functions[force.getTabulatedFunctionName(i)] = createReferenceTabulatedFunction(force.getTabulatedFunction(i)); // Parse the various expressions used to calculate the force. Lepton::ParsedExpression expression = Lepton::Parser::parse(force.getEnergyFunction(), functions).optimize(); Lepton::CompiledExpression energyExpression = expression.createCompiledExpression(); Lepton::CompiledExpression forceExpression = expression.differentiate("r").createCompiledExpression(); for (int i = 0; i < numParameters; i++) parameterNames.push_back(force.getPerParticleParameterName(i)); for (int i = 0; i < force.getNumGlobalParameters(); i++) { globalParameterNames.push_back(force.getGlobalParameterName(i)); globalParamValues[force.getGlobalParameterName(i)] = force.getGlobalParameterDefaultValue(i); } // Delete the custom functions. for (map<string, Lepton::CustomFunction*>::iterator iter = functions.begin(); iter != functions.end(); iter++) delete iter->second; // Record information for the long range correction. if (force.getNonbondedMethod() == CustomNonbondedForce::CutoffPeriodic && force.getUseLongRangeCorrection()) { forceCopy = new CustomNonbondedForce(force); hasInitializedLongRangeCorrection = false; } else { longRangeCoefficient = 0.0; hasInitializedLongRangeCorrection = true; } // Record the interaction groups. for (int i = 0; i < force.getNumInteractionGroups(); i++) { set<int> set1, set2; force.getInteractionGroupParameters(i, set1, set2); interactionGroups.push_back(make_pair(set1, set2)); } data.isPeriodic = (nonbondedMethod == CutoffPeriodic); nonbonded = new CpuCustomNonbondedForce(energyExpression, forceExpression, parameterNames, exclusions, data.threads); if (interactionGroups.size() > 0) nonbonded->setInteractionGroups(interactionGroups); }
ReferenceCustomCompoundBondIxn::ReferenceCustomCompoundBondIxn(int numParticlesPerBond, const vector<vector<int> >& bondAtoms, const Lepton::ParsedExpression& energyExpression, const vector<string>& bondParameterNames, const map<string, vector<int> >& distances, const map<string, vector<int> >& angles, const map<string, vector<int> >& dihedrals, const std::vector<Lepton::CompiledExpression> energyParamDerivExpressions) : bondAtoms(bondAtoms), energyExpression(energyExpression.createCompiledExpression()), usePeriodic(false), energyParamDerivExpressions(energyParamDerivExpressions) { expressionSet.registerExpression(this->energyExpression); for (int i = 0; i < this->energyParamDerivExpressions.size(); i++) expressionSet.registerExpression(this->energyParamDerivExpressions[i]); for (int i = 0; i < numParticlesPerBond; i++) { stringstream xname, yname, zname; xname << 'x' << (i+1); yname << 'y' << (i+1); zname << 'z' << (i+1); particleTerms.push_back(ReferenceCustomCompoundBondIxn::ParticleTermInfo(xname.str(), i, 0, energyExpression.differentiate(xname.str()).createCompiledExpression())); particleTerms.push_back(ReferenceCustomCompoundBondIxn::ParticleTermInfo(yname.str(), i, 1, energyExpression.differentiate(yname.str()).createCompiledExpression())); particleTerms.push_back(ReferenceCustomCompoundBondIxn::ParticleTermInfo(zname.str(), i, 2, energyExpression.differentiate(zname.str()).createCompiledExpression())); } for (map<string, vector<int> >::const_iterator iter = distances.begin(); iter != distances.end(); ++iter) distanceTerms.push_back(ReferenceCustomCompoundBondIxn::DistanceTermInfo(iter->first, iter->second, energyExpression.differentiate(iter->first).createCompiledExpression())); for (map<string, vector<int> >::const_iterator iter = angles.begin(); iter != angles.end(); ++iter) angleTerms.push_back(ReferenceCustomCompoundBondIxn::AngleTermInfo(iter->first, iter->second, energyExpression.differentiate(iter->first).createCompiledExpression())); for (map<string, vector<int> >::const_iterator iter = dihedrals.begin(); iter != dihedrals.end(); ++iter) dihedralTerms.push_back(ReferenceCustomCompoundBondIxn::DihedralTermInfo(iter->first, iter->second, energyExpression.differentiate(iter->first).createCompiledExpression())); for (int i = 0; i < particleTerms.size(); i++) { expressionSet.registerExpression(particleTerms[i].forceExpression); particleTerms[i].index = expressionSet.getVariableIndex(particleTerms[i].name); } for (int i = 0; i < distanceTerms.size(); i++) { expressionSet.registerExpression(distanceTerms[i].forceExpression); distanceTerms[i].index = expressionSet.getVariableIndex(distanceTerms[i].name); } for (int i = 0; i < angleTerms.size(); i++) { expressionSet.registerExpression(angleTerms[i].forceExpression); angleTerms[i].index = expressionSet.getVariableIndex(angleTerms[i].name); } for (int i = 0; i < dihedralTerms.size(); i++) { expressionSet.registerExpression(dihedralTerms[i].forceExpression); dihedralTerms[i].index = expressionSet.getVariableIndex(dihedralTerms[i].name); } numParameters = bondParameterNames.size(); for (int i = 0; i < numParameters; i++) bondParamIndex.push_back(expressionSet.getVariableIndex(bondParameterNames[i])); }
ReferenceCustomCompoundBondIxn::ReferenceCustomCompoundBondIxn(int numParticlesPerBond, const vector<vector<int> >& bondAtoms, const Lepton::ParsedExpression& energyExpression, const vector<string>& bondParameterNames, const map<string, vector<int> >& distances, const map<string, vector<int> >& angles, const map<string, vector<int> >& dihedrals) : bondAtoms(bondAtoms), energyExpression(energyExpression.createProgram()), bondParamNames(bondParameterNames) { for (int i = 0; i < numParticlesPerBond; i++) { stringstream xname, yname, zname; xname << 'x' << (i+1); yname << 'y' << (i+1); zname << 'z' << (i+1); particleTerms.push_back(ReferenceCustomCompoundBondIxn::ParticleTermInfo(xname.str(), i, 0, energyExpression.differentiate(xname.str()).optimize().createProgram())); particleTerms.push_back(ReferenceCustomCompoundBondIxn::ParticleTermInfo(yname.str(), i, 1, energyExpression.differentiate(yname.str()).optimize().createProgram())); particleTerms.push_back(ReferenceCustomCompoundBondIxn::ParticleTermInfo(zname.str(), i, 2, energyExpression.differentiate(zname.str()).optimize().createProgram())); } for (map<string, vector<int> >::const_iterator iter = distances.begin(); iter != distances.end(); ++iter) distanceTerms.push_back(ReferenceCustomCompoundBondIxn::DistanceTermInfo(iter->first, iter->second, energyExpression.differentiate(iter->first).optimize().createProgram())); for (map<string, vector<int> >::const_iterator iter = angles.begin(); iter != angles.end(); ++iter) angleTerms.push_back(ReferenceCustomCompoundBondIxn::AngleTermInfo(iter->first, iter->second, energyExpression.differentiate(iter->first).optimize().createProgram())); for (map<string, vector<int> >::const_iterator iter = dihedrals.begin(); iter != dihedrals.end(); ++iter) dihedralTerms.push_back(ReferenceCustomCompoundBondIxn::DihedralTermInfo(iter->first, iter->second, energyExpression.differentiate(iter->first).optimize().createProgram())); }
CpuCustomManyParticleForce::ThreadData::ThreadData(const CustomManyParticleForce& force, Lepton::ParsedExpression& energyExpr, map<string, vector<int> >& distances, map<string, vector<int> >& angles, map<string, vector<int> >& dihedrals) { int numParticlesPerSet = force.getNumParticlesPerSet(); int numPerParticleParameters = force.getNumPerParticleParameters(); particleParamIndices.resize(numParticlesPerSet); permutedParticles.resize(numParticlesPerSet); f.resize(numParticlesPerSet); energyExpression = energyExpr.createCompiledExpression(); expressionSet.registerExpression(energyExpression); // Differentiate the energy to get expressions for the force. for (int i = 0; i < numParticlesPerSet; i++) { stringstream xname, yname, zname; xname << 'x' << (i+1); yname << 'y' << (i+1); zname << 'z' << (i+1); particleTerms.push_back(CpuCustomManyParticleForce::ParticleTermInfo(xname.str(), i, 0, energyExpr.differentiate(xname.str()).optimize().createCompiledExpression(), *this)); particleTerms.push_back(CpuCustomManyParticleForce::ParticleTermInfo(yname.str(), i, 1, energyExpr.differentiate(yname.str()).optimize().createCompiledExpression(), *this)); particleTerms.push_back(CpuCustomManyParticleForce::ParticleTermInfo(zname.str(), i, 2, energyExpr.differentiate(zname.str()).optimize().createCompiledExpression(), *this)); for (int j = 0; j < numPerParticleParameters; j++) { stringstream paramname; paramname << force.getPerParticleParameterName(j) << (i+1); particleParamIndices[i].push_back(expressionSet.getVariableIndex(paramname.str())); } } for (map<string, vector<int> >::const_iterator iter = dihedrals.begin(); iter != dihedrals.end(); ++iter) dihedralTerms.push_back(CpuCustomManyParticleForce::DihedralTermInfo(iter->first, iter->second, energyExpr.differentiate(iter->first).optimize().createCompiledExpression(), *this)); for (map<string, vector<int> >::const_iterator iter = distances.begin(); iter != distances.end(); ++iter) distanceTerms.push_back(CpuCustomManyParticleForce::DistanceTermInfo(iter->first, iter->second, energyExpr.differentiate(iter->first).optimize().createCompiledExpression(), *this)); for (map<string, vector<int> >::const_iterator iter = angles.begin(); iter != angles.end(); ++iter) angleTerms.push_back(CpuCustomManyParticleForce::AngleTermInfo(iter->first, iter->second, energyExpr.differentiate(iter->first).optimize().createCompiledExpression(), *this)); for (int i = 0; i < particleTerms.size(); i++) expressionSet.registerExpression(particleTerms[i].forceExpression); for (int i = 0; i < distanceTerms.size(); i++) expressionSet.registerExpression(distanceTerms[i].forceExpression); for (int i = 0; i < angleTerms.size(); i++) expressionSet.registerExpression(angleTerms[i].forceExpression); for (int i = 0; i < dihedralTerms.size(); i++) expressionSet.registerExpression(dihedralTerms[i].forceExpression); int numDeltas = deltaPairs.size(); delta.resize(numDeltas); normDelta.resize(numDeltas); norm2Delta.resize(numDeltas); cross1.resize(numDeltas); cross2.resize(numDeltas); }
ReferenceCustomHbondIxn::ReferenceCustomHbondIxn(const vector<vector<int> >& donorAtoms, const vector<vector<int> >& acceptorAtoms, const Lepton::ParsedExpression& energyExpression, const vector<string>& donorParameterNames, const vector<string>& acceptorParameterNames, const map<string, vector<int> >& distances, const map<string, vector<int> >& angles, const map<string, vector<int> >& dihedrals) : cutoff(false), periodic(false), donorAtoms(donorAtoms), acceptorAtoms(acceptorAtoms), energyExpression(energyExpression.createProgram()), donorParamNames(donorParameterNames), acceptorParamNames(acceptorParameterNames) { for (map<string, vector<int> >::const_iterator iter = distances.begin(); iter != distances.end(); ++iter) distanceTerms.push_back(ReferenceCustomHbondIxn::DistanceTermInfo(iter->first, iter->second, energyExpression.differentiate(iter->first).optimize().createProgram())); for (map<string, vector<int> >::const_iterator iter = angles.begin(); iter != angles.end(); ++iter) angleTerms.push_back(ReferenceCustomHbondIxn::AngleTermInfo(iter->first, iter->second, energyExpression.differentiate(iter->first).optimize().createProgram())); for (map<string, vector<int> >::const_iterator iter = dihedrals.begin(); iter != dihedrals.end(); ++iter) dihedralTerms.push_back(ReferenceCustomHbondIxn::DihedralTermInfo(iter->first, iter->second, energyExpression.differentiate(iter->first).optimize().createProgram())); }