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())); }
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); }
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())); }