Unverified Commit 8dd60914 authored by Tristan Croll's avatar Tristan Croll Committed by GitHub
Browse files

Merge pull request #3 from openmm/master

Sync with official repo
parents 3475b790 75c1fcb6
/* Portions copyright (c) 2006-2019 Stanford University and Simbios.
* Contributors: Pande Group
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <cstring>
#include <sstream>
#include "SimTKOpenMMUtilities.h"
#include "ReferenceBAOABDynamics.h"
#include "ReferencePlatform.h"
#include "ReferenceVirtualSites.h"
#include "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h"
using std::vector;
using namespace OpenMM;
ReferenceBAOABDynamics::ReferenceBAOABDynamics(int numberOfAtoms,
double deltaT, double friction,
double temperature) :
ReferenceDynamics(numberOfAtoms, deltaT, temperature), friction(friction) {
xPrime.resize(numberOfAtoms);
oldx.resize(numberOfAtoms);
inverseMasses.resize(numberOfAtoms);
}
ReferenceBAOABDynamics::~ReferenceBAOABDynamics() {
}
double ReferenceBAOABDynamics::getFriction() const {
return friction;
}
void ReferenceBAOABDynamics::updatePart1(int numberOfAtoms, vector<Vec3>& atomCoordinates,
vector<Vec3>& velocities, vector<Vec3>& forces, vector<double>& inverseMasses,
vector<Vec3>& xPrime) {
const double halfdt = 0.5*getDeltaT();
for (int i = 0; i < numberOfAtoms; i++) {
if (inverseMasses[i] != 0.0) {
velocities[i] += (halfdt*inverseMasses[i])*forces[i];
xPrime[i] = atomCoordinates[i] + velocities[i]*halfdt;
oldx[i] = xPrime[i];
}
}
}
void ReferenceBAOABDynamics::updatePart2(int numberOfAtoms, vector<Vec3>& atomCoordinates,
vector<Vec3>& velocities, vector<double>& inverseMasses,
vector<Vec3>& xPrime) {
const double halfdt = 0.5*getDeltaT();
const double kT = BOLTZ*getTemperature();
const double friction = getFriction();
const double vscale = exp(-getDeltaT()*friction);
const double noisescale = sqrt(1-vscale*vscale);
for (int i = 0; i < numberOfAtoms; i++) {
if (inverseMasses[i] != 0.0) {
velocities[i] += (xPrime[i]-oldx[i])/halfdt;
velocities[i] = vscale*velocities[i] + noisescale*sqrt(kT*inverseMasses[i])*Vec3(
SimTKOpenMMUtilities::getNormallyDistributedRandomNumber(),
SimTKOpenMMUtilities::getNormallyDistributedRandomNumber(),
SimTKOpenMMUtilities::getNormallyDistributedRandomNumber());
atomCoordinates[i] = xPrime[i];
xPrime[i] = atomCoordinates[i] + velocities[i]*halfdt;
oldx[i] = xPrime[i];
}
}
}
void ReferenceBAOABDynamics::updatePart3(OpenMM::ContextImpl& context, int numberOfAtoms, vector<Vec3>& atomCoordinates,
vector<Vec3>& velocities, vector<Vec3>& forces, vector<double>& inverseMasses,
vector<Vec3>& xPrime) {
const double halfdt = 0.5*getDeltaT();
for (int i = 0; i < numberOfAtoms; i++) {
if (inverseMasses[i] != 0.0) {
velocities[i] += (xPrime[i]-oldx[i])/halfdt;
atomCoordinates[i] = xPrime[i];
}
}
context.calcForcesAndEnergy(true, false);
for (int i = 0; i < numberOfAtoms; i++) {
if (inverseMasses[i] != 0.0)
velocities[i] += (halfdt*inverseMasses[i])*forces[i];
}
}
void ReferenceBAOABDynamics::update(ContextImpl& context, vector<Vec3>& atomCoordinates,
vector<Vec3>& velocities, vector<double>& masses, bool& forcesAreValid, double tolerance) {
int numberOfAtoms = context.getSystem().getNumParticles();
ReferenceConstraintAlgorithm* referenceConstraintAlgorithm = getReferenceConstraintAlgorithm();
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];
}
}
if (!forcesAreValid) {
context.calcForcesAndEnergy(true, false);
forcesAreValid = true;
}
ReferencePlatform::PlatformData* data = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData());
vector<Vec3>& forces = *data->forces;
// 1st update
updatePart1(numberOfAtoms, atomCoordinates, velocities, forces, inverseMasses, xPrime);
if (referenceConstraintAlgorithm)
referenceConstraintAlgorithm->apply(atomCoordinates, xPrime, inverseMasses, tolerance);
// 2nd update
updatePart2(numberOfAtoms, atomCoordinates, velocities, inverseMasses, xPrime);
if (referenceConstraintAlgorithm)
referenceConstraintAlgorithm->apply(atomCoordinates, xPrime, inverseMasses, tolerance);
// 3rd update
updatePart3(context, numberOfAtoms, atomCoordinates, velocities, forces, inverseMasses, xPrime);
if (referenceConstraintAlgorithm)
referenceConstraintAlgorithm->applyToVelocities(atomCoordinates, velocities, inverseMasses, tolerance);
ReferenceVirtualSites::computePositions(context.getSystem(), atomCoordinates);
incrementTimeStep();
}
......@@ -463,10 +463,6 @@ double ReferenceCustomDynamics::computeKineticEnergy(OpenMM::ContextImpl& contex
globals.insert(context.getParameters().begin(), context.getParameters().end());
for (auto& global : globals)
expressionSet.setVariable(expressionSet.getVariableIndex(global.first), global.second);
if (kineticEnergyNeedsForce) {
energy = context.calcForcesAndEnergy(true, true, -1);
forcesAreValid = true;
}
computePerDof(numberOfAtoms, sumBuffer, atomCoordinates, velocities, forces, masses, perDof, kineticEnergyExpression);
double sum = 0.0;
for (int j = 0; j < numberOfAtoms; j++)
......
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2019 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "ReferenceTests.h"
#include "TestBAOABLangevinIntegrator.h"
void runPlatformTests() {
}
......@@ -50,10 +50,31 @@ namespace OpenMM {
* particle to another one. This is typically done for hydrogens to place the interaction site slightly
* closer to the parent atom. The fraction is known as the "reduction factor", since it reduces the distance
* from the parent atom to the interaction site.
*
* Support is also available for softcore interactions based on setting a per particle alchemical flag and
* setting the AmoebaVdwForce to use an "AlchemicalMethod" -- either Decouple or Annihilate.
* For Decouple, two alchemical atoms interact normally. For Annihilate, all interactions involving an
* alchemical atom are influenced. The softcore state is specified by setting a single
* Context parameter "AmoebaVdwLambda" between 0.0 and 1.0.
*
* The softcore functional form can be modified by setting the softcore power (default of 5) and the softcore
* alpha (default of 0,7). For more information on the softcore functional form see Eq. 2 from:
* Jiao, D.; Golubkov, P. A.; Darden, T. A.; Ren, P.,
* Calculation of protein-ligand binding free energy by using a polarizable potential.
* Proc. Natl. Acad. Sci. U.S.A. 2008, 105 (17), 6290-6295.
* https://www.pnas.org/content/105/17/6290.
*/
class OPENMM_EXPORT_AMOEBA AmoebaVdwForce : public Force {
public:
/**
* This is the name of the parameter which stores the current Amoeba vdW lambda value.
*/
static const std::string& Lambda() {
static const std::string key = "AmoebaVdwLambda";
return key;
}
/**
* This is an enumeration of the different methods that may be used for handling long range nonbonded forces.
*/
......@@ -70,6 +91,24 @@ public:
CutoffPeriodic = 1,
};
/**
* This is an enumeration of the different alchemical methods used when applying softcore interactions.
*/
enum AlchemicalMethod {
/**
* All vdW interactions are treated normally. This is the default.
*/
None = 0,
/**
* Maintain full strength vdW interactions between two alchemical particles.
*/
Decouple = 1,
/**
* Interactions between two alchemical particles are turned off at lambda=0.
*/
Annihilate = 2,
};
/**
* Create an Amoeba VdwForce.
*/
......@@ -91,8 +130,10 @@ public:
* @param epsilon vdw epsilon
* @param reductionFactor the fraction of the distance along the line from the parent particle to this particle
* at which the interaction site should be placed
* @param isAlchemical if true, this vdW particle is undergoing an alchemical change.
*/
void setParticleParameters(int particleIndex, int parentIndex, double sigma, double epsilon, double reductionFactor);
void setParticleParameters(int particleIndex, int parentIndex, double sigma, double epsilon,
double reductionFactor, bool isAlchemical = false);
/**
* Get the force field parameters for a vdw particle.
......@@ -103,8 +144,10 @@ public:
* @param[out] epsilon vdw epsilon
* @param[out] reductionFactor the fraction of the distance along the line from the parent particle to this particle
* at which the interaction site should be placed
* @param[out] isAlchemical if true, this vdW particle is undergoing an alchemical change.
*/
void getParticleParameters(int particleIndex, int& parentIndex, double& sigma, double& epsilon, double& reductionFactor) const;
void getParticleParameters(int particleIndex, int& parentIndex, double& sigma, double& epsilon,
double& reductionFactor, bool& isAlchemical) const;
/**
......@@ -115,9 +158,10 @@ public:
* @param epsilon vdw epsilon
* @param reductionFactor the fraction of the distance along the line from the parent particle to this particle
* at which the interaction site should be placed
* @param isAlchemical if true, this vdW particle is undergoing an alchemical change.
* @return index of added particle
*/
int addParticle(int parentIndex, double sigma, double epsilon, double reductionFactor);
int addParticle(int parentIndex, double sigma, double epsilon, double reductionFactor, bool isAlchemical = false);
/**
* Set sigma combining rule
......@@ -136,14 +180,14 @@ public:
/**
* Set epsilon combining rule
*
* @param epsilonCombiningRule epsilon combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'HARMONIC', 'HHG'
* @param epsilonCombiningRule epsilon combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'HARMONIC', 'W-H', 'HHG'
*/
void setEpsilonCombiningRule(const std::string& epsilonCombiningRule);
/**
* Get epsilon combining rule
*
* @return epsilonCombiningRule epsilon combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'HARMONIC', 'HHG'
* @return epsilonCombiningRule epsilon combining rule: 'ARITHMETIC', 'GEOMETRIC'. 'HARMONIC', 'W-H', 'HHG'
*/
const std::string& getEpsilonCombiningRule(void) const;
......@@ -223,6 +267,37 @@ public:
* Set the method used for handling long range nonbonded interactions.
*/
void setNonbondedMethod(NonbondedMethod method);
/**
* Set the softcore power on lambda (default = 5).
*/
void setSoftcorePower(int n);
/**
* Get the softcore power on lambda.
*/
int getSoftcorePower() const;
/**
* Set the softcore alpha value (default = 0.7).
*/
void setSoftcoreAlpha(double alpha);
/**
* Get the softcore alpha value.
*/
double getSoftcoreAlpha() const;
/**
* Get the method used for alchemical interactions.
*/
AlchemicalMethod getAlchemicalMethod() const;
/**
* Set the method used for handling long range nonbonded interactions.
*/
void setAlchemicalMethod(AlchemicalMethod method);
/**
* Update the per-particle parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
......@@ -250,6 +325,9 @@ private:
NonbondedMethod nonbondedMethod;
double cutoff;
bool useDispersionCorrection;
AlchemicalMethod alchemicalMethod;
int n;
double alpha;
std::string sigmaCombiningRule;
std::string epsilonCombiningRule;
......@@ -267,14 +345,16 @@ class AmoebaVdwForce::VdwInfo {
public:
int parentIndex;
double reductionFactor, sigma, epsilon, cutoff;
bool isAlchemical;
VdwInfo() {
parentIndex = -1;
reductionFactor = 0.0;
sigma = 1.0;
epsilon = 0.0;
isAlchemical = false;
}
VdwInfo(int parentIndex, double sigma, double epsilon, double reductionFactor) :
parentIndex(parentIndex), reductionFactor(reductionFactor), sigma(sigma), epsilon(epsilon) {
VdwInfo(int parentIndex, double sigma, double epsilon, double reductionFactor, bool isAlchemical) :
parentIndex(parentIndex), reductionFactor(reductionFactor), sigma(sigma), epsilon(epsilon), isAlchemical(isAlchemical) {
}
};
......
......@@ -60,7 +60,9 @@ public:
}
double calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups);
std::map<std::string, double> getDefaultParameters() {
return std::map<std::string, double>(); // This force field doesn't define any parameters.
std::map<std::string, double> parameters;
parameters[AmoebaVdwForce::Lambda()] = 1.0;
return parameters;
}
std::vector<std::string> getKernelNames();
/**
......
......@@ -132,9 +132,9 @@ void AmoebaTorsionTorsionForceImpl::reorderGrid(const TorsionTorsionGrid& grid,
// increment map iterators
mapJJ++;
++mapJJ;
if (mapJJ == map_Double_IntPair.end()) {
mapII++;
++mapII;
if (mapII == mapAngles.end()) {
if ((jj != (grid[ii].size()-1)) && (ii != (grid.size()-1))) {
char buffer[1024];
......
......@@ -38,28 +38,30 @@ using namespace OpenMM;
using std::string;
using std::vector;
AmoebaVdwForce::AmoebaVdwForce() : nonbondedMethod(NoCutoff), sigmaCombiningRule("CUBIC-MEAN"), epsilonCombiningRule("HHG"), cutoff(1.0e+10), useDispersionCorrection(true) {
AmoebaVdwForce::AmoebaVdwForce() : nonbondedMethod(NoCutoff), sigmaCombiningRule("CUBIC-MEAN"), epsilonCombiningRule("HHG"), cutoff(1.0e+10), useDispersionCorrection(true), alchemicalMethod(None), n(5), alpha(0.7) {
}
int AmoebaVdwForce::addParticle(int parentIndex, double sigma, double epsilon, double reductionFactor) {
parameters.push_back(VdwInfo(parentIndex, sigma, epsilon, reductionFactor));
int AmoebaVdwForce::addParticle(int parentIndex, double sigma, double epsilon, double reductionFactor, bool isAlchemical) {
parameters.push_back(VdwInfo(parentIndex, sigma, epsilon, reductionFactor, isAlchemical));
return parameters.size()-1;
}
void AmoebaVdwForce::getParticleParameters(int particleIndex, int& parentIndex,
double& sigma, double& epsilon, double& reductionFactor) const {
double& sigma, double& epsilon, double& reductionFactor, bool& isAlchemical) const {
parentIndex = parameters[particleIndex].parentIndex;
sigma = parameters[particleIndex].sigma;
epsilon = parameters[particleIndex].epsilon;
reductionFactor = parameters[particleIndex].reductionFactor;
isAlchemical = parameters[particleIndex].isAlchemical;
}
void AmoebaVdwForce::setParticleParameters(int particleIndex, int parentIndex,
double sigma, double epsilon, double reductionFactor) {
double sigma, double epsilon, double reductionFactor, bool isAlchemical) {
parameters[particleIndex].parentIndex = parentIndex;
parameters[particleIndex].sigma = sigma;
parameters[particleIndex].epsilon = epsilon;
parameters[particleIndex].reductionFactor = reductionFactor;
parameters[particleIndex].isAlchemical = isAlchemical;
}
void AmoebaVdwForce::setSigmaCombiningRule(const std::string& inputSigmaCombiningRule) {
......@@ -128,6 +130,33 @@ void AmoebaVdwForce::setNonbondedMethod(NonbondedMethod method) {
nonbondedMethod = method;
}
AmoebaVdwForce::AlchemicalMethod AmoebaVdwForce::getAlchemicalMethod() const {
return alchemicalMethod;
}
void AmoebaVdwForce::setAlchemicalMethod(AlchemicalMethod method) {
if (method < 0 || method > 2)
throw OpenMMException("AmoebaVdwForce: Illegal value for alchemical method");
alchemicalMethod = method;
}
void AmoebaVdwForce::setSoftcorePower(int power) {
n = power;
}
int AmoebaVdwForce::getSoftcorePower() const {
return n;
}
void AmoebaVdwForce::setSoftcoreAlpha(double a) {
alpha = a;
}
double AmoebaVdwForce::getSoftcoreAlpha() const {
return alpha;
}
ForceImpl* AmoebaVdwForce::createImpl() const {
return new AmoebaVdwForceImpl(*this);
}
......
......@@ -90,10 +90,11 @@ double AmoebaVdwForceImpl::calcDispersionCorrection(const System& system, const
map<pair<double, double>, int> classCounts;
for (int i = 0; i < force.getNumParticles(); i++) {
double sigma, epsilon, reduction;
// The variables reduction, ivindex are not used.
bool isAlchemical;
// The variables reduction, ivindex and isAlchemical are not used.
int ivindex;
// Get the sigma and epsilon parameters, ignoring everything else.
force.getParticleParameters(i, ivindex, sigma, epsilon, reduction);
force.getParticleParameters(i, ivindex, sigma, epsilon, reduction, isAlchemical);
pair<double, double> key = make_pair(sigma, epsilon);
map<pair<double, double>, int>::iterator entry = classCounts.find(key);
if (entry == classCounts.end())
......@@ -151,8 +152,11 @@ double AmoebaVdwForceImpl::calcDispersionCorrection(const System& system, const
int ndelta = int(double(nstep) * (range - cut));
double rdelta = (range - cut) / double(ndelta);
double offset = cut - 0.5 * rdelta;
double dhal = 0.07; // This magic number also appears in kCalculateAmoebaCudaVdw14_7.cu
double ghal = 0.12; // This magic number also appears in kCalculateAmoebaCudaVdw14_7.cu
// Buffered-14-7 buffering constants
double dhal = 0.07;
double ghal = 0.12;
double elrc = 0.0; // This number is incremented and passed out at the end
double e = 0.0;
double sigma, epsilon; // The pairwise sigma and epsilon parameters.
......@@ -188,7 +192,8 @@ double AmoebaVdwForceImpl::calcDispersionCorrection(const System& system, const
// ARITHMETIC = 1
// GEOMETRIC = 2
// HARMONIC = 3
// HHG = 4
// W-H = 4
// HHG = 5
if (epsilonCombiningRule == "ARITHMETIC") {
epsilon = 0.5f * (iEpsilon + jEpsilon);
} else if (epsilonCombiningRule == "GEOMETRIC") {
......@@ -199,6 +204,13 @@ double AmoebaVdwForceImpl::calcDispersionCorrection(const System& system, const
} else {
epsilon = 0.0;
}
} else if (epsilonCombiningRule == "W-H") {
double iSigma3 = iSigma * iSigma * iSigma;
double jSigma3 = jSigma * jSigma * jSigma;
double iSigma6 = iSigma3 * iSigma3;
double jSigma6 = jSigma3 * jSigma3;
double eps_s = std::sqrt(iEpsilon*jEpsilon);
epsilon = (eps_s == 0.0 ? 0.0 : 2.0f*eps_s*iSigma3*jSigma3/(iSigma6 + jSigma6));
} else {
double epsilonS = std::sqrt(iEpsilon) + std::sqrt(jEpsilon);
if (epsilonS != 0.0) {
......@@ -259,3 +271,5 @@ std::vector<std::string> AmoebaVdwForceImpl::getKernelNames() {
void AmoebaVdwForceImpl::updateParametersInContext(ContextImpl& context) {
kernel.getAs<CalcAmoebaVdwForceKernel>().copyParametersToContext(context, owner);
}
......@@ -88,7 +88,7 @@ private:
const AmoebaBondForce& force;
};
CudaCalcAmoebaBondForceKernel::CudaCalcAmoebaBondForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) :
CudaCalcAmoebaBondForceKernel::CudaCalcAmoebaBondForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system) :
CalcAmoebaBondForceKernel(name, platform), cu(cu), system(system) {
}
......@@ -180,7 +180,7 @@ private:
const AmoebaAngleForce& force;
};
CudaCalcAmoebaAngleForceKernel::CudaCalcAmoebaAngleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) :
CudaCalcAmoebaAngleForceKernel::CudaCalcAmoebaAngleForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system) :
CalcAmoebaAngleForceKernel(name, platform), cu(cu), system(system) {
}
......@@ -276,7 +276,7 @@ private:
const AmoebaInPlaneAngleForce& force;
};
CudaCalcAmoebaInPlaneAngleForceKernel::CudaCalcAmoebaInPlaneAngleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) :
CudaCalcAmoebaInPlaneAngleForceKernel::CudaCalcAmoebaInPlaneAngleForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system) :
CalcAmoebaInPlaneAngleForceKernel(name, platform), cu(cu), system(system) {
}
......@@ -373,7 +373,7 @@ private:
const AmoebaPiTorsionForce& force;
};
CudaCalcAmoebaPiTorsionForceKernel::CudaCalcAmoebaPiTorsionForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) :
CudaCalcAmoebaPiTorsionForceKernel::CudaCalcAmoebaPiTorsionForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system) :
CalcAmoebaPiTorsionForceKernel(name, platform), cu(cu), system(system) {
}
......@@ -462,7 +462,7 @@ private:
const AmoebaStretchBendForce& force;
};
CudaCalcAmoebaStretchBendForceKernel::CudaCalcAmoebaStretchBendForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) :
CudaCalcAmoebaStretchBendForceKernel::CudaCalcAmoebaStretchBendForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system) :
CalcAmoebaStretchBendForceKernel(name, platform), cu(cu), system(system) {
}
......@@ -561,7 +561,7 @@ private:
const AmoebaOutOfPlaneBendForce& force;
};
CudaCalcAmoebaOutOfPlaneBendForceKernel::CudaCalcAmoebaOutOfPlaneBendForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) :
CudaCalcAmoebaOutOfPlaneBendForceKernel::CudaCalcAmoebaOutOfPlaneBendForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system) :
CalcAmoebaOutOfPlaneBendForceKernel(name, platform), cu(cu), system(system) {
}
......@@ -656,7 +656,7 @@ private:
const AmoebaTorsionTorsionForce& force;
};
CudaCalcAmoebaTorsionTorsionForceKernel::CudaCalcAmoebaTorsionTorsionForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) :
CudaCalcAmoebaTorsionTorsionForceKernel::CudaCalcAmoebaTorsionTorsionForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system) :
CalcAmoebaTorsionTorsionForceKernel(name, platform), cu(cu), system(system) {
}
......@@ -763,7 +763,7 @@ private:
const AmoebaMultipoleForce& force;
};
CudaCalcAmoebaMultipoleForceKernel::CudaCalcAmoebaMultipoleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) :
CudaCalcAmoebaMultipoleForceKernel::CudaCalcAmoebaMultipoleForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system) :
CalcAmoebaMultipoleForceKernel(name, platform), cu(cu), system(system), hasInitializedScaleFactors(false), hasInitializedFFT(false), multipolesAreValid(false), hasCreatedEvent(false),
gkKernel(NULL) {
}
......@@ -2119,7 +2119,7 @@ private:
const AmoebaGeneralizedKirkwoodForce& force;
};
CudaCalcAmoebaGeneralizedKirkwoodForceKernel::CudaCalcAmoebaGeneralizedKirkwoodForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) :
CudaCalcAmoebaGeneralizedKirkwoodForceKernel::CudaCalcAmoebaGeneralizedKirkwoodForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system) :
CalcAmoebaGeneralizedKirkwoodForceKernel(name, platform), cu(cu), system(system), hasInitializedKernels(false) {
}
......@@ -2343,43 +2343,57 @@ public:
bool areParticlesIdentical(int particle1, int particle2) {
int iv1, iv2;
double sigma1, sigma2, epsilon1, epsilon2, reduction1, reduction2;
force.getParticleParameters(particle1, iv1, sigma1, epsilon1, reduction1);
force.getParticleParameters(particle2, iv2, sigma2, epsilon2, reduction2);
return (sigma1 == sigma2 && epsilon1 == epsilon2 && reduction1 == reduction2);
bool isAlchemical1, isAlchemical2;
force.getParticleParameters(particle1, iv1, sigma1, epsilon1, reduction1, isAlchemical1);
force.getParticleParameters(particle2, iv2, sigma2, epsilon2, reduction2, isAlchemical2);
return (sigma1 == sigma2 && epsilon1 == epsilon2 && reduction1 == reduction2 && isAlchemical1 == isAlchemical2);
}
private:
const AmoebaVdwForce& force;
};
CudaCalcAmoebaVdwForceKernel::CudaCalcAmoebaVdwForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) :
CalcAmoebaVdwForceKernel(name, platform), cu(cu), system(system), hasInitializedNonbonded(false), nonbonded(NULL) {
CudaCalcAmoebaVdwForceKernel::CudaCalcAmoebaVdwForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system) :
CalcAmoebaVdwForceKernel(name, platform), cu(cu), system(system), hasInitializedNonbonded(false), nonbonded(NULL), vdwLambdaPinnedBuffer(NULL) {
}
CudaCalcAmoebaVdwForceKernel::~CudaCalcAmoebaVdwForceKernel() {
cu.setAsCurrent();
if (nonbonded != NULL)
delete nonbonded;
if (vdwLambdaPinnedBuffer != NULL)
cuMemFreeHost(vdwLambdaPinnedBuffer);
}
void CudaCalcAmoebaVdwForceKernel::initialize(const System& system, const AmoebaVdwForce& force) {
cu.setAsCurrent();
sigmaEpsilon.initialize<float2>(cu, cu.getPaddedNumAtoms(), "sigmaEpsilon");
bondReductionAtoms.initialize<int>(cu, cu.getPaddedNumAtoms(), "bondReductionAtoms");
bondReductionFactors.initialize<float>(cu, cu.getPaddedNumAtoms(), "sigmaEpsilon");
bondReductionFactors.initialize<float>(cu, cu.getPaddedNumAtoms(), "bondReductionFactors");
tempPosq.initialize(cu, cu.getPaddedNumAtoms(), cu.getUseDoublePrecision() ? sizeof(double4) : sizeof(float4), "tempPosq");
tempForces.initialize<long long>(cu, 3*cu.getPaddedNumAtoms(), "tempForces");
// Record atom parameters.
vector<float2> sigmaEpsilonVec(cu.getPaddedNumAtoms(), make_float2(0, 1));
vector<float> isAlchemicalVec(cu.getPaddedNumAtoms(), 0);
vector<int> bondReductionAtomsVec(cu.getPaddedNumAtoms(), 0);
vector<float> bondReductionFactorsVec(cu.getPaddedNumAtoms(), 0);
vector<vector<int> > exclusions(cu.getNumAtoms());
// Handle Alchemical parameters.
hasAlchemical = force.getAlchemicalMethod() != AmoebaVdwForce::None;
if (hasAlchemical) {
isAlchemical.initialize<float>(cu, cu.getPaddedNumAtoms(), "isAlchemical");
vdwLambda.initialize<float>(cu, 1, "vdwLambda");
CHECK_RESULT(cuMemHostAlloc(&vdwLambdaPinnedBuffer, sizeof(float), 0), "Error allocating vdwLambda pinned buffer");
}
for (int i = 0; i < force.getNumParticles(); i++) {
int ivIndex;
double sigma, epsilon, reductionFactor;
force.getParticleParameters(i, ivIndex, sigma, epsilon, reductionFactor);
bool alchemical;
force.getParticleParameters(i, ivIndex, sigma, epsilon, reductionFactor, alchemical);
sigmaEpsilonVec[i] = make_float2((float) sigma, (float) epsilon);
isAlchemicalVec[i] = (alchemical) ? 1.0f : 0.0f;
bondReductionAtomsVec[i] = ivIndex;
bondReductionFactorsVec[i] = (float) reductionFactor;
force.getParticleExclusions(i, exclusions[i]);
......@@ -2400,6 +2414,15 @@ void CudaCalcAmoebaVdwForceKernel::initialize(const System& system, const Amoeba
nonbonded = new CudaNonbondedUtilities(cu);
nonbonded->addParameter(CudaNonbondedUtilities::ParameterInfo("sigmaEpsilon", "float", 2, sizeof(float2), sigmaEpsilon.getDevicePointer()));
if (hasAlchemical) {
isAlchemical.upload(isAlchemicalVec);
((float*) vdwLambdaPinnedBuffer)[0] = 1.0f;
currentVdwLambda = 1.0f;
vdwLambda.upload(vdwLambdaPinnedBuffer, false);
nonbonded->addParameter(CudaNonbondedUtilities::ParameterInfo("isAlchemical", "float", 1, sizeof(float), isAlchemical.getDevicePointer()));
nonbonded->addArgument(CudaNonbondedUtilities::ParameterInfo("vdwLambda", "float", 1, sizeof(float), vdwLambda.getDevicePointer()));
}
// Create the interaction kernel.
map<string, string> replacements;
......@@ -2417,12 +2440,19 @@ void CudaCalcAmoebaVdwForceKernel::initialize(const System& system, const Amoeba
replacements["EPSILON_COMBINING_RULE"] = "1";
else if (epsilonCombiningRule == "GEOMETRIC")
replacements["EPSILON_COMBINING_RULE"] = "2";
else if (epsilonCombiningRule == "HARMONIC")
else if (epsilonCombiningRule =="HARMONIC")
replacements["EPSILON_COMBINING_RULE"] = "3";
else if (epsilonCombiningRule == "HHG")
else if (epsilonCombiningRule == "W-H")
replacements["EPSILON_COMBINING_RULE"] = "4";
else if (epsilonCombiningRule == "HHG")
replacements["EPSILON_COMBINING_RULE"] = "5";
else
throw OpenMMException("Illegal combining rule for sigma: "+sigmaCombiningRule);
replacements["VDW_ALCHEMICAL_METHOD"] = cu.intToString(force.getAlchemicalMethod());
replacements["VDW_SOFTCORE_POWER"] = cu.intToString(force.getSoftcorePower());
replacements["VDW_SOFTCORE_ALPHA"] = cu.doubleToString(force.getSoftcoreAlpha());
double cutoff = force.getCutoffDistance();
double taperCutoff = cutoff*0.9;
replacements["CUTOFF_DISTANCE"] = cu.doubleToString(force.getCutoffDistance());
......@@ -2449,6 +2479,17 @@ double CudaCalcAmoebaVdwForceKernel::execute(ContextImpl& context, bool includeF
hasInitializedNonbonded = true;
nonbonded->initialize(system);
}
if (hasAlchemical) {
float contextLambda = context.getParameter(AmoebaVdwForce::Lambda());
if (contextLambda != currentVdwLambda) {
// Non-blocking copy of vdwLambda to device memory
((float*) vdwLambdaPinnedBuffer)[0] = contextLambda;
vdwLambda.upload(vdwLambdaPinnedBuffer, false);
currentVdwLambda = contextLambda;
}
}
cu.getPosq().copyTo(tempPosq);
cu.getForce().copyTo(tempForces);
void* prepareArgs[] = {&cu.getForce().getDevicePointer(), &cu.getPosq().getDevicePointer(), &tempPosq.getDevicePointer(),
......@@ -2472,19 +2513,22 @@ void CudaCalcAmoebaVdwForceKernel::copyParametersToContext(ContextImpl& context,
throw OpenMMException("updateParametersInContext: The number of particles has changed");
// Record the per-particle parameters.
vector<float2> sigmaEpsilonVec(cu.getPaddedNumAtoms(), make_float2(0, 1));
vector<float> isAlchemicalVec(cu.getPaddedNumAtoms(), 0);
vector<int> bondReductionAtomsVec(cu.getPaddedNumAtoms(), 0);
vector<float> bondReductionFactorsVec(cu.getPaddedNumAtoms(), 0);
for (int i = 0; i < force.getNumParticles(); i++) {
int ivIndex;
double sigma, epsilon, reductionFactor;
force.getParticleParameters(i, ivIndex, sigma, epsilon, reductionFactor);
bool alchemical;
force.getParticleParameters(i, ivIndex, sigma, epsilon, reductionFactor, alchemical);
sigmaEpsilonVec[i] = make_float2((float) sigma, (float) epsilon);
isAlchemicalVec[i] = (alchemical) ? 1.0f : 0.0f;
bondReductionAtomsVec[i] = ivIndex;
bondReductionFactorsVec[i] = (float) reductionFactor;
}
sigmaEpsilon.upload(sigmaEpsilonVec);
if (hasAlchemical) isAlchemical.upload(isAlchemicalVec);
bondReductionAtoms.upload(bondReductionAtomsVec);
bondReductionFactors.upload(bondReductionFactorsVec);
if (force.getUseDispersionCorrection())
......@@ -2512,7 +2556,7 @@ private:
const AmoebaWcaDispersionForce& force;
};
CudaCalcAmoebaWcaDispersionForceKernel::CudaCalcAmoebaWcaDispersionForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) :
CudaCalcAmoebaWcaDispersionForceKernel::CudaCalcAmoebaWcaDispersionForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system) :
CalcAmoebaWcaDispersionForceKernel(name, platform), cu(cu), system(system) {
}
......@@ -2655,7 +2699,7 @@ private:
CudaCalcHippoNonbondedForceKernel& owner;
};
CudaCalcHippoNonbondedForceKernel::CudaCalcHippoNonbondedForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) :
CudaCalcHippoNonbondedForceKernel::CudaCalcHippoNonbondedForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system) :
CalcHippoNonbondedForceKernel(name, platform), cu(cu), system(system), sort(NULL), hasInitializedKernels(false), hasInitializedFFT(false), multipolesAreValid(false) {
}
......
......@@ -45,7 +45,7 @@ class CudaCalcAmoebaGeneralizedKirkwoodForceKernel;
*/
class CudaCalcAmoebaBondForceKernel : public CalcAmoebaBondForceKernel {
public:
CudaCalcAmoebaBondForceKernel(std::string name,
CudaCalcAmoebaBondForceKernel(const std::string& name,
const Platform& platform,
CudaContext& cu,
const System& system);
......@@ -85,7 +85,7 @@ private:
*/
class CudaCalcAmoebaAngleForceKernel : public CalcAmoebaAngleForceKernel {
public:
CudaCalcAmoebaAngleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
CudaCalcAmoebaAngleForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system);
/**
* Initialize the kernel.
*
......@@ -122,7 +122,7 @@ private:
*/
class CudaCalcAmoebaInPlaneAngleForceKernel : public CalcAmoebaInPlaneAngleForceKernel {
public:
CudaCalcAmoebaInPlaneAngleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
CudaCalcAmoebaInPlaneAngleForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system);
/**
* Initialize the kernel.
*
......@@ -159,7 +159,7 @@ private:
*/
class CudaCalcAmoebaPiTorsionForceKernel : public CalcAmoebaPiTorsionForceKernel {
public:
CudaCalcAmoebaPiTorsionForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
CudaCalcAmoebaPiTorsionForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system);
/**
* Initialize the kernel.
*
......@@ -196,7 +196,7 @@ private:
*/
class CudaCalcAmoebaStretchBendForceKernel : public CalcAmoebaStretchBendForceKernel {
public:
CudaCalcAmoebaStretchBendForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
CudaCalcAmoebaStretchBendForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system);
/**
* Initialize the kernel.
*
......@@ -234,7 +234,7 @@ private:
*/
class CudaCalcAmoebaOutOfPlaneBendForceKernel : public CalcAmoebaOutOfPlaneBendForceKernel {
public:
CudaCalcAmoebaOutOfPlaneBendForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
CudaCalcAmoebaOutOfPlaneBendForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system);
/**
* Initialize the kernel.
*
......@@ -271,7 +271,7 @@ private:
*/
class CudaCalcAmoebaTorsionTorsionForceKernel : public CalcAmoebaTorsionTorsionForceKernel {
public:
CudaCalcAmoebaTorsionTorsionForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
CudaCalcAmoebaTorsionTorsionForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system);
/**
* Initialize the kernel.
*
......@@ -304,7 +304,7 @@ private:
*/
class CudaCalcAmoebaMultipoleForceKernel : public CalcAmoebaMultipoleForceKernel {
public:
CudaCalcAmoebaMultipoleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
CudaCalcAmoebaMultipoleForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system);
~CudaCalcAmoebaMultipoleForceKernel();
/**
* Initialize the kernel.
......@@ -466,7 +466,7 @@ private:
*/
class CudaCalcAmoebaGeneralizedKirkwoodForceKernel : public CalcAmoebaGeneralizedKirkwoodForceKernel {
public:
CudaCalcAmoebaGeneralizedKirkwoodForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
CudaCalcAmoebaGeneralizedKirkwoodForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system);
/**
* Initialize the kernel.
*
......@@ -541,13 +541,13 @@ private:
*/
class CudaCalcAmoebaVdwForceKernel : public CalcAmoebaVdwForceKernel {
public:
CudaCalcAmoebaVdwForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
CudaCalcAmoebaVdwForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system);
~CudaCalcAmoebaVdwForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the AmoebaMultipoleForce this kernel will be used for
* @param force the AmoebaVdwForce this kernel will be used for
*/
void initialize(const System& system, const AmoebaVdwForce& force);
/**
......@@ -571,6 +571,18 @@ private:
CudaContext& cu;
const System& system;
bool hasInitializedNonbonded;
// True if the AmoebaVdwForce AlchemicalMethod is not None.
bool hasAlchemical;
// Pinned host memory; allocated if necessary in initialize, and freed in the destructor.
void* vdwLambdaPinnedBuffer;
// Device memory for the alchemical state.
CudaArray vdwLambda;
// Only update device memory when lambda changes.
float currentVdwLambda;
// Per particle alchemical flag.
CudaArray isAlchemical;
double dispersionCoefficient;
CudaArray sigmaEpsilon;
CudaArray bondReductionAtoms;
......@@ -586,7 +598,7 @@ private:
*/
class CudaCalcAmoebaWcaDispersionForceKernel : public CalcAmoebaWcaDispersionForceKernel {
public:
CudaCalcAmoebaWcaDispersionForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
CudaCalcAmoebaWcaDispersionForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system);
/**
* Initialize the kernel.
*
......@@ -624,7 +636,7 @@ private:
*/
class CudaCalcHippoNonbondedForceKernel : public CalcHippoNonbondedForceKernel {
public:
CudaCalcHippoNonbondedForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system);
CudaCalcHippoNonbondedForceKernel(const std::string& name, const Platform& platform, CudaContext& cu, const System& system);
~CudaCalcHippoNonbondedForceKernel();
/**
* Initialize the kernel.
......
......@@ -22,24 +22,49 @@
#elif EPSILON_COMBINING_RULE == 3
real epssum = sigmaEpsilon1.y+sigmaEpsilon2.y;
real epsilon = (epssum == 0.0f ? (real) 0 : 2*(sigmaEpsilon1.y*sigmaEpsilon2.y)/(sigmaEpsilon1.y+sigmaEpsilon2.y));
#elif EPSILON_COMBINING_RULE == 4
real sigma1_3 = sigmaEpsilon1.x*sigmaEpsilon1.x*sigmaEpsilon1.x;
real sigma2_3 = sigmaEpsilon2.x*sigmaEpsilon2.x*sigmaEpsilon2.x;
real sigma1_6 = sigma1_3*sigma1_3;
real sigma2_6 = sigma2_3*sigma2_3;
real eps_s = SQRT(sigmaEpsilon1.y*sigmaEpsilon2.y);
real epsilon = (eps_s == 0.0f ? (real) 0 : 2*eps_s*sigma1_3*sigma2_3/(sigma1_6 + sigma2_6));
#else
real epsilon_s = SQRT(sigmaEpsilon1.y) + SQRT(sigmaEpsilon2.y);
real epsilon = (epsilon_s == 0.0f ? (real) 0 : 4*sigmaEpsilon1.y*sigmaEpsilon2.y/(epsilon_s*epsilon_s));
#endif
real r6 = r2*r2*r2;
real r7 = r6*r;
real sigma7 = sigma*sigma;
sigma7 = sigma7*sigma7*sigma7*sigma;
real rho = r7 + sigma7*0.12f;
real invRho = RECIP(rho);
real tau = 1.07f/(r + 0.07f*sigma);
real tau7 = tau*tau*tau;
tau7 = tau7*tau7*tau;
real dTau = tau/1.07f;
real tmp = sigma7*invRho;
real gTau = epsilon*tau7*r6*1.12f*tmp*tmp;
real termEnergy = epsilon*sigma7*tau7*((sigma7*1.12f*invRho)-2.0f);
real deltaE = -7.0f*(dTau*termEnergy+gTau);
real softcore = 0.0f;
#if VDW_ALCHEMICAL_METHOD == 1
if (isAlchemical1 != isAlchemical2) {
#elif VDW_ALCHEMICAL_METHOD == 2
if (isAlchemical1 || isAlchemical2) {
#endif
#if VDW_ALCHEMICAL_METHOD != 0
real lambda = vdwLambda[0];
epsilon = epsilon * POW(lambda, VDW_SOFTCORE_POWER);
softcore = VDW_SOFTCORE_ALPHA * (1.0f - lambda) * (1.0f - lambda);
}
#endif
real dhal = 0.07f;
real ghal = 0.12f;
real dhal1 = 1.07f;
real ghal1 = 1.12f;
real rho = r / sigma;
real rho2 = rho * rho;
real rho6 = rho2 * rho2 * rho2;
real rhoplus = rho + dhal;
real rhodec2 = rhoplus * rhoplus;
real rhodec = rhodec2 * rhodec2 * rhodec2;
real s1 = 1.0f / (softcore + rhodec * rhoplus);
real s2 = 1.0f / (softcore + rho6 * rho + ghal);
real point72 = dhal1 * dhal1;
real t1 = dhal1 * point72 * point72 * point72 * s1;
real t2 = ghal1 * s2;
real t2min = t2 - 2.0f;
real dt1 = -7.0f * rhodec * t1 * s1;
real dt2 = -7.0f * rho6 * t2 * s2;
real termEnergy = epsilon * t1 * t2min;
real deltaE = epsilon * (dt1 * t2min + t1 * dt2) / sigma;
#ifdef USE_CUTOFF
if (r > TAPER_CUTOFF) {
real x = r-TAPER_CUTOFF;
......
......@@ -880,7 +880,7 @@ static void testQuadrupoleValidation() {
static void setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::NonbondedMethod nonbondedMethod,
AmoebaMultipoleForce::PolarizationType polarizationType,
double cutoff, int inputPmeGridDimension, std::string testName,
double cutoff, int inputPmeGridDimension, const std::string& testName,
std::vector<Vec3>& forces, double& energy) {
// beginning of Multipole setup
......
......@@ -140,10 +140,11 @@ void testVdw() {
for (int ii = 0; ii < amoebaVdwForce->getNumParticles(); ii++) {
int indexIV;
double sigma, epsilon, reduction;
amoebaVdwForce->getParticleParameters(ii, indexIV, sigma, epsilon, reduction);
bool isAlchemical;
amoebaVdwForce->getParticleParameters(ii, indexIV, sigma, epsilon, reduction, isAlchemical);
sigma *= AngstromToNm;
epsilon *= CalToJoule;
amoebaVdwForce->setParticleParameters(ii, indexIV, sigma, epsilon, reduction);
amoebaVdwForce->setParticleParameters(ii, indexIV, sigma, epsilon, reduction, isAlchemical);
}
platformName = "CUDA";
Context context(system, integrator, Platform::getPlatformByName(platformName));
......@@ -170,8 +171,9 @@ void testVdw() {
for (int i = 0; i < numberOfParticles; i++) {
int indexIV;
double mass, sigma, epsilon, reduction;
amoebaVdwForce->getParticleParameters(i, indexIV, sigma, epsilon, reduction);
amoebaVdwForce->setParticleParameters(i, indexIV, 0.9*sigma, 2.0*epsilon, 0.95*reduction);
bool isAlchemical;
amoebaVdwForce->getParticleParameters(i, indexIV, sigma, epsilon, reduction, isAlchemical);
amoebaVdwForce->setParticleParameters(i, indexIV, 0.9*sigma, 2.0*epsilon, 0.95*reduction, isAlchemical);
}
LangevinIntegrator integrator2(0.0, 0.1, 0.01);
Context context2(system, integrator2, Platform::getPlatformByName(platformName));
......@@ -195,17 +197,25 @@ void testVdw() {
ASSERT_EQUAL_TOL(state1.getPotentialEnergy(), state2.getPotentialEnergy(), tolerance);
}
void setupAndGetForcesEnergyVdwAmmonia(const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff,
double boxDimension, std::vector<Vec3>& forces, double& energy) {
void setupAndGetForcesEnergyVdwAmmonia2(const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff,
double boxDimension, std::vector<Vec3>& forces, double& energy,
AmoebaVdwForce::AlchemicalMethod alchemicalMethod, int softcorePower, double softcoreAlpha, double vdwLambda){
// beginning of Vdw setup
System system;
AmoebaVdwForce* amoebaVdwForce = new AmoebaVdwForce();;
AmoebaVdwForce* amoebaVdwForce = new AmoebaVdwForce();
int numberOfParticles = 8;
amoebaVdwForce->setSigmaCombiningRule(sigmaCombiningRule);
amoebaVdwForce->setEpsilonCombiningRule(epsilonCombiningRule);
amoebaVdwForce->setCutoff(cutoff);
bool alchemical = false;
if (alchemicalMethod != AmoebaVdwForce::None) {
amoebaVdwForce->setAlchemicalMethod(alchemicalMethod);
amoebaVdwForce->setSoftcorePower(softcorePower);
amoebaVdwForce->setSoftcoreAlpha(softcoreAlpha);
alchemical = true;
}
if (boxDimension > 0.0) {
Vec3 a(boxDimension, 0.0, 0.0);
Vec3 b(0.0, boxDimension, 0.0);
......@@ -213,11 +223,13 @@ void setupAndGetForcesEnergyVdwAmmonia(const std::string& sigmaCombiningRule, co
system.setDefaultPeriodicBoxVectors(a, b, c);
amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::CutoffPeriodic);
amoebaVdwForce->setUseDispersionCorrection(1);
} else {
}
else {
amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::NoCutoff);
amoebaVdwForce->setUseDispersionCorrection(0);
}
// addParticle: ivIndex, radius, epsilon, reductionFactor
system.addParticle( 1.4007000e+01);
......@@ -233,16 +245,16 @@ void setupAndGetForcesEnergyVdwAmmonia(const std::string& sigmaCombiningRule, co
amoebaVdwForce->addParticle(0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01);
system.addParticle( 1.4007000e+01);
amoebaVdwForce->addParticle(4, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00);
amoebaVdwForce->addParticle(4, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00, alchemical);
system.addParticle( 1.0080000e+00);
amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01);
amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01, alchemical);
system.addParticle( 1.0080000e+00);
amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01);
amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01, alchemical);
system.addParticle( 1.0080000e+00);
amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01);
amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01, alchemical);
// ParticleExclusions
......@@ -323,12 +335,28 @@ void setupAndGetForcesEnergyVdwAmmonia(const std::string& sigmaCombiningRule, co
LangevinIntegrator integrator(0.0, 0.1, 0.01);
Context context(system, integrator, Platform::getPlatformByName(platformName));
// Load the vdw lambda value into the context.
if (alchemicalMethod != AmoebaVdwForce::None) {
context.setParameter(AmoebaVdwForce::Lambda(), vdwLambda);
}
context.setPositions(positions);
State state = context.getState(State::Forces | State::Energy);
forces = state.getForces();
energy = state.getPotentialEnergy();
}
void setupAndGetForcesEnergyVdwAmmonia(const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff,
double boxDimension, std::vector<Vec3>& forces, double& energy) {
AmoebaVdwForce::AlchemicalMethod alchemicalMethod = AmoebaVdwForce::None;
int softcorePower = 5;
double softcoreAlpha = 0.7;
double vdwLambda = 1.0;
setupAndGetForcesEnergyVdwAmmonia2(sigmaCombiningRule, epsilonCombiningRule, cutoff, boxDimension, forces, energy,
alchemicalMethod, softcorePower, softcoreAlpha, vdwLambda);
}
void compareForcesEnergy(std::string& testName, double expectedEnergy, double energy,
std::vector<Vec3>& expectedForces,
std::vector<Vec3>& forces, double tolerance) {
......@@ -368,6 +396,74 @@ void testVdwAmmoniaCubicMeanHhg() {
compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance);
}
// test VDW w/ sigmaRule=CubicMean and epsilonRule=W-H
void testVdwAmmoniaCubicMeanWH() {
std::string testName = "testVdwAmmoniaCubicMeanWH";
int numberOfParticles = 8;
double boxDimension = -1.0;
double cutoff = 9000000.0;
std::vector<Vec3> forces;
double energy;
setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "W-H", cutoff, boxDimension, forces, energy);
std::vector<Vec3> expectedForces(numberOfParticles);
double expectedEnergy = 3.771794e+00;
expectedForces[0] = Vec3( 2.3979839e+02, -1.1829842e-02, -5.3258772e+00);
expectedForces[1] = Vec3(-1.9942459e+00, 4.3142144e-01, -1.7290171e-01);
expectedForces[2] = Vec3(-1.9935442e+00, -4.2937965e-01, -1.7369876e-01);
expectedForces[3] = Vec3(-8.9050582e-01, -4.8659920e-04, 2.2190848e-01);
expectedForces[4] = Vec3(-5.2306326e+01, 1.4895040e-03, -3.3588483e-01);
expectedForces[5] = Vec3( 1.4153288e+00, -2.7130186e-01, -1.5480591e-01);
expectedForces[6] = Vec3(-1.8544507e+02, 8.4027272e-03, 6.0950274e+00);
expectedForces[7] = Vec3( 1.4159723e+00, 2.7168386e-01, -1.5376786e-01);
double tolerance = 1.0e-04;
compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance);
}
// test alchemical VDW
void testVdwAlchemical(int power, double alpha, double lambda, AmoebaVdwForce::AlchemicalMethod method) {
std::string testName = "testVdwAlchemical";
int numberOfParticles = 8;
double boxDimension = -1.0;
double cutoff = 9000000.0;
std::vector<Vec3> forces;
double energy;
setupAndGetForcesEnergyVdwAmmonia2("CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy,
method, power, alpha, lambda);
std::vector<Vec3> expectedForces(numberOfParticles);
double expectedEnergy = 4.8012258e+00;
expectedForces[0] = Vec3( 2.9265247e+02, -1.4507808e-02, -6.9562123e+00);
expectedForces[1] = Vec3(-2.2451693e+00, 4.8143073e-01, -2.0041494e-01);
expectedForces[2] = Vec3(-2.2440698e+00, -4.7905450e-01, -2.0125284e-01);
expectedForces[3] = Vec3(-1.0840394e+00, -5.8531253e-04, 2.6934135e-01);
expectedForces[4] = Vec3(-5.6305662e+01, 1.4733908e-03, -1.8083306e-01);
expectedForces[5] = Vec3( 1.6750145e+00, -3.2448374e-01, -1.8030914e-01);
expectedForces[6] = Vec3(-2.3412420e+02, 1.0754069e-02, 7.6287492e+00);
expectedForces[7] = Vec3( 1.6756544e+00, 3.2497316e-01, -1.7906832e-01);
double scale = pow(lambda, power);
expectedEnergy *= scale;
for (int i=0; i<8; i++) {
expectedForces[i] *= scale;
}
double tolerance = 1.0e-04;
compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance);
}
// test VDW w/ sigmaRule=Arithmetic and epsilonRule=Arithmetic
void testVdwAmmoniaArithmeticArithmetic() {
......@@ -2025,6 +2121,10 @@ int main(int argc, char* argv[]) {
testVdwAmmoniaCubicMeanHhg();
// test VDW w/ sigmaRule=CubicMean and epsilonRule=HHG
testVdwAmmoniaCubicMeanWH();
// test VDW w/ sigmaRule=Arithmetic and epsilonRule=Arithmetic
testVdwAmmoniaArithmeticArithmetic();
......@@ -2062,6 +2162,25 @@ int main(int argc, char* argv[]) {
testTriclinic();
// Set lambda and the softcore power (n) to any values, while softcore alpha set to 0.
// The energy and forces are equal to scaling those from testVdwAmmoniaCubicMeanHhg by lambda^n;
int n = 5;
double alpha = 0.0;
double lambda = 0.9;
AmoebaVdwForce::AlchemicalMethod method = AmoebaVdwForce::Annihilate;
testVdwAlchemical(n, alpha, lambda, method);
// Test the Decouple alchemical method.
lambda = 0.5;
method = AmoebaVdwForce::Decouple;
testVdwAlchemical(n, alpha, lambda, method);
// Test alpha > 0.
// This requires lambda = 0, since the energy and forces are not simply scaled by lambda^n.
lambda = 0.0;
alpha = 0.7;
testVdwAlchemical(n, alpha, lambda, method);
} catch(const std::exception& e) {
std::cout << "exception: " << e.what() << std::endl;
std::cout << "FAIL - ERROR. Test failed." << std::endl;
......
......@@ -58,32 +58,32 @@ using namespace std;
static vector<Vec3>& extractPositions(ContextImpl& context) {
ReferencePlatform::PlatformData* data = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData());
return *((vector<Vec3>*) data->positions);
return *data->positions;
}
static vector<Vec3>& extractVelocities(ContextImpl& context) {
ReferencePlatform::PlatformData* data = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData());
return *((vector<Vec3>*) data->velocities);
return *data->velocities;
}
static vector<Vec3>& extractForces(ContextImpl& context) {
ReferencePlatform::PlatformData* data = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData());
return *((vector<Vec3>*) data->forces);
return *data->forces;
}
static Vec3& extractBoxSize(ContextImpl& context) {
ReferencePlatform::PlatformData* data = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData());
return *(Vec3*) data->periodicBoxSize;
return *data->periodicBoxSize;
}
static Vec3* extractBoxVectors(ContextImpl& context) {
ReferencePlatform::PlatformData* data = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData());
return (Vec3*) data->periodicBoxVectors;
return data->periodicBoxVectors;
}
// ***************************************************************************
ReferenceCalcAmoebaBondForceKernel::ReferenceCalcAmoebaBondForceKernel(std::string name, const Platform& platform, const System& system) :
ReferenceCalcAmoebaBondForceKernel::ReferenceCalcAmoebaBondForceKernel(const std::string& name, const Platform& platform, const System& system) :
CalcAmoebaBondForceKernel(name, platform), system(system) {
}
......@@ -140,7 +140,7 @@ void ReferenceCalcAmoebaBondForceKernel::copyParametersToContext(ContextImpl& co
// ***************************************************************************
ReferenceCalcAmoebaAngleForceKernel::ReferenceCalcAmoebaAngleForceKernel(std::string name, const Platform& platform, const System& system) :
ReferenceCalcAmoebaAngleForceKernel::ReferenceCalcAmoebaAngleForceKernel(const std::string& name, const Platform& platform, const System& system) :
CalcAmoebaAngleForceKernel(name, platform), system(system) {
}
......@@ -196,7 +196,7 @@ void ReferenceCalcAmoebaAngleForceKernel::copyParametersToContext(ContextImpl& c
}
}
ReferenceCalcAmoebaInPlaneAngleForceKernel::ReferenceCalcAmoebaInPlaneAngleForceKernel(std::string name, const Platform& platform, const System& system) :
ReferenceCalcAmoebaInPlaneAngleForceKernel::ReferenceCalcAmoebaInPlaneAngleForceKernel(const std::string& name, const Platform& platform, const System& system) :
CalcAmoebaInPlaneAngleForceKernel(name, platform), system(system) {
}
......@@ -254,7 +254,7 @@ void ReferenceCalcAmoebaInPlaneAngleForceKernel::copyParametersToContext(Context
}
}
ReferenceCalcAmoebaPiTorsionForceKernel::ReferenceCalcAmoebaPiTorsionForceKernel(std::string name, const Platform& platform, const System& system) :
ReferenceCalcAmoebaPiTorsionForceKernel::ReferenceCalcAmoebaPiTorsionForceKernel(const std::string& name, const Platform& platform, const System& system) :
CalcAmoebaPiTorsionForceKernel(name, platform), system(system) {
}
......@@ -309,7 +309,7 @@ void ReferenceCalcAmoebaPiTorsionForceKernel::copyParametersToContext(ContextImp
}
}
ReferenceCalcAmoebaStretchBendForceKernel::ReferenceCalcAmoebaStretchBendForceKernel(std::string name, const Platform& platform, const System& system) :
ReferenceCalcAmoebaStretchBendForceKernel::ReferenceCalcAmoebaStretchBendForceKernel(const std::string& name, const Platform& platform, const System& system) :
CalcAmoebaStretchBendForceKernel(name, platform), system(system) {
}
......@@ -367,7 +367,7 @@ void ReferenceCalcAmoebaStretchBendForceKernel::copyParametersToContext(ContextI
}
}
ReferenceCalcAmoebaOutOfPlaneBendForceKernel::ReferenceCalcAmoebaOutOfPlaneBendForceKernel(std::string name, const Platform& platform, const System& system) :
ReferenceCalcAmoebaOutOfPlaneBendForceKernel::ReferenceCalcAmoebaOutOfPlaneBendForceKernel(const std::string& name, const Platform& platform, const System& system) :
CalcAmoebaOutOfPlaneBendForceKernel(name, platform), system(system) {
}
......@@ -428,7 +428,7 @@ void ReferenceCalcAmoebaOutOfPlaneBendForceKernel::copyParametersToContext(Conte
}
}
ReferenceCalcAmoebaTorsionTorsionForceKernel::ReferenceCalcAmoebaTorsionTorsionForceKernel(std::string name, const Platform& platform, const System& system) :
ReferenceCalcAmoebaTorsionTorsionForceKernel::ReferenceCalcAmoebaTorsionTorsionForceKernel(const std::string& name, const Platform& platform, const System& system) :
CalcAmoebaTorsionTorsionForceKernel(name, platform), system(system) {
}
......@@ -510,7 +510,7 @@ double ReferenceCalcAmoebaTorsionTorsionForceKernel::execute(ContextImpl& contex
* AmoebaMultipole *
* -------------------------------------------------------------------------- */
ReferenceCalcAmoebaMultipoleForceKernel::ReferenceCalcAmoebaMultipoleForceKernel(std::string name, const Platform& platform, const System& system) :
ReferenceCalcAmoebaMultipoleForceKernel::ReferenceCalcAmoebaMultipoleForceKernel(const std::string& name, const Platform& platform, const System& system) :
CalcAmoebaMultipoleForceKernel(name, platform), system(system), numMultipoles(0), mutualInducedMaxIterations(60), mutualInducedTargetEpsilon(1.0e-03),
usePme(false),alphaEwald(0.0), cutoffDistance(1.0) {
......@@ -871,7 +871,7 @@ void ReferenceCalcAmoebaMultipoleForceKernel::getPMEParameters(double& alpha, in
* AmoebaGeneralizedKirkwood *
* -------------------------------------------------------------------------- */
ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel(std::string name, const Platform& platform, const System& system) :
ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel(const std::string& name, const Platform& platform, const System& system) :
CalcAmoebaGeneralizedKirkwoodForceKernel(name, platform), system(system) {
}
......@@ -992,7 +992,7 @@ void ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::copyParametersToContext(
}
}
ReferenceCalcAmoebaVdwForceKernel::ReferenceCalcAmoebaVdwForceKernel(std::string name, const Platform& platform, const System& system) :
ReferenceCalcAmoebaVdwForceKernel::ReferenceCalcAmoebaVdwForceKernel(const std::string& name, const Platform& platform, const System& system) :
CalcAmoebaVdwForceKernel(name, platform), system(system) {
useCutoff = 0;
usePBC = 0;
......@@ -1017,14 +1017,16 @@ void ReferenceCalcAmoebaVdwForceKernel::initialize(const System& system, const A
sigmas.resize(numParticles);
epsilons.resize(numParticles);
reductions.resize(numParticles);
isAlchemical.resize(numParticles);
for (int ii = 0; ii < numParticles; ii++) {
int indexIV;
double sigma, epsilon, reduction;
bool alchemical;
std::vector<int> exclusions;
force.getParticleParameters(ii, indexIV, sigma, epsilon, reduction);
force.getParticleParameters(ii, indexIV, sigma, epsilon, reduction, alchemical);
force.getParticleExclusions(ii, exclusions);
for (unsigned int jj = 0; jj < exclusions.size(); jj++) {
allExclusions[ii].insert(exclusions[jj]);
......@@ -1034,6 +1036,7 @@ void ReferenceCalcAmoebaVdwForceKernel::initialize(const System& system, const A
sigmas[ii] = sigma;
epsilons[ii] = epsilon;
reductions[ii] = reduction;
isAlchemical[ii] = alchemical;
}
sigmaCombiningRule = force.getSigmaCombiningRule();
epsilonCombiningRule = force.getEpsilonCombiningRule();
......@@ -1042,7 +1045,9 @@ void ReferenceCalcAmoebaVdwForceKernel::initialize(const System& system, const A
cutoff = force.getCutoffDistance();
neighborList = useCutoff ? new NeighborList() : NULL;
dispersionCoefficient = force.getUseDispersionCorrection() ? AmoebaVdwForceImpl::calcDispersionCorrection(system, force) : 0.0;
alchemicalMethod = force.getAlchemicalMethod();
n = force.getSoftcorePower();
alpha = force.getSoftcoreAlpha();
}
double ReferenceCalcAmoebaVdwForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
......@@ -1050,7 +1055,17 @@ double ReferenceCalcAmoebaVdwForceKernel::execute(ContextImpl& context, bool inc
vector<Vec3>& posData = extractPositions(context);
vector<Vec3>& forceData = extractForces(context);
AmoebaReferenceVdwForce vdwForce(sigmaCombiningRule, epsilonCombiningRule);
if (alchemicalMethod == AmoebaVdwForce::Decouple) {
vdwForce.setAlchemicalMethod(AmoebaReferenceVdwForce::Decouple);
} else if (alchemicalMethod == AmoebaVdwForce::Annihilate) {
vdwForce.setAlchemicalMethod(AmoebaReferenceVdwForce::Annihilate);
} else {
vdwForce.setAlchemicalMethod(AmoebaReferenceVdwForce::None);
}
vdwForce.setSoftcorePower(n);
vdwForce.setSoftcoreAlpha(alpha);
double energy;
double lambda = context.getParameter(AmoebaVdwForce::Lambda());
if (useCutoff) {
vdwForce.setCutoff(cutoff);
computeNeighborListVoxelHash(*neighborList, numParticles, posData, allExclusions, extractBoxVectors(context), usePBC, cutoff, 0.0);
......@@ -1062,14 +1077,16 @@ double ReferenceCalcAmoebaVdwForceKernel::execute(ContextImpl& context, bool inc
throw OpenMMException("The periodic box size has decreased to less than twice the cutoff.");
}
vdwForce.setPeriodicBox(boxVectors);
energy = vdwForce.calculateForceAndEnergy(numParticles, posData, indexIVs, sigmas, epsilons, reductions, *neighborList, forceData);
energy = vdwForce.calculateForceAndEnergy(numParticles, lambda, posData, indexIVs, sigmas, epsilons,
reductions, isAlchemical, *neighborList, forceData);
energy += dispersionCoefficient/(boxVectors[0][0]*boxVectors[1][1]*boxVectors[2][2]);
} else {
vdwForce.setNonbondedMethod(AmoebaReferenceVdwForce::CutoffNonPeriodic);
}
} else {
vdwForce.setNonbondedMethod(AmoebaReferenceVdwForce::NoCutoff);
energy = vdwForce.calculateForceAndEnergy(numParticles, posData, indexIVs, sigmas, epsilons, reductions, allExclusions, forceData);
energy = vdwForce.calculateForceAndEnergy(numParticles, lambda, posData, indexIVs, sigmas, epsilons,
reductions, isAlchemical, allExclusions, forceData);
}
return static_cast<double>(energy);
}
......@@ -1079,15 +1096,16 @@ void ReferenceCalcAmoebaVdwForceKernel::copyParametersToContext(ContextImpl& con
throw OpenMMException("updateParametersInContext: The number of particles has changed");
// Record the values.
for (int i = 0; i < numParticles; ++i) {
int indexIV;
double sigma, epsilon, reduction;
force.getParticleParameters(i, indexIV, sigma, epsilon, reduction);
bool alchemical;
force.getParticleParameters(i, indexIV, sigma, epsilon, reduction, alchemical);
indexIVs[i] = indexIV;
sigmas[i] = sigma;
epsilons[i] = epsilon;
reductions[i]= reduction;
isAlchemical[i]= alchemical;
}
}
......@@ -1095,7 +1113,7 @@ void ReferenceCalcAmoebaVdwForceKernel::copyParametersToContext(ContextImpl& con
* AmoebaWcaDispersion *
* -------------------------------------------------------------------------- */
ReferenceCalcAmoebaWcaDispersionForceKernel::ReferenceCalcAmoebaWcaDispersionForceKernel(std::string name, const Platform& platform, const System& system) :
ReferenceCalcAmoebaWcaDispersionForceKernel::ReferenceCalcAmoebaWcaDispersionForceKernel(const std::string& name, const Platform& platform, const System& system) :
CalcAmoebaWcaDispersionForceKernel(name, platform), system(system) {
}
......@@ -1158,7 +1176,7 @@ void ReferenceCalcAmoebaWcaDispersionForceKernel::copyParametersToContext(Contex
* HippoNonbonded *
* -------------------------------------------------------------------------- */
ReferenceCalcHippoNonbondedForceKernel::ReferenceCalcHippoNonbondedForceKernel(std::string name, const Platform& platform, const System& system) :
ReferenceCalcHippoNonbondedForceKernel::ReferenceCalcHippoNonbondedForceKernel(const std::string& name, const Platform& platform, const System& system) :
CalcHippoNonbondedForceKernel(name, platform), ixn(NULL) {
}
......
......@@ -43,7 +43,7 @@ namespace OpenMM {
*/
class ReferenceCalcAmoebaBondForceKernel : public CalcAmoebaBondForceKernel {
public:
ReferenceCalcAmoebaBondForceKernel(std::string name,
ReferenceCalcAmoebaBondForceKernel(const std::string& name,
const Platform& platform,
const System& system);
~ReferenceCalcAmoebaBondForceKernel();
......@@ -87,7 +87,7 @@ private:
*/
class ReferenceCalcAmoebaAngleForceKernel : public CalcAmoebaAngleForceKernel {
public:
ReferenceCalcAmoebaAngleForceKernel(std::string name, const Platform& platform, const System& system);
ReferenceCalcAmoebaAngleForceKernel(const std::string& name, const Platform& platform, const System& system);
~ReferenceCalcAmoebaAngleForceKernel();
/**
* Initialize the kernel.
......@@ -132,7 +132,7 @@ private:
*/
class ReferenceCalcAmoebaInPlaneAngleForceKernel : public CalcAmoebaInPlaneAngleForceKernel {
public:
ReferenceCalcAmoebaInPlaneAngleForceKernel(std::string name, const Platform& platform, const System& system);
ReferenceCalcAmoebaInPlaneAngleForceKernel(const std::string& name, const Platform& platform, const System& system);
~ReferenceCalcAmoebaInPlaneAngleForceKernel();
/**
* Initialize the kernel.
......@@ -178,7 +178,7 @@ private:
*/
class ReferenceCalcAmoebaPiTorsionForceKernel : public CalcAmoebaPiTorsionForceKernel {
public:
ReferenceCalcAmoebaPiTorsionForceKernel(std::string name, const Platform& platform, const System& system);
ReferenceCalcAmoebaPiTorsionForceKernel(const std::string& name, const Platform& platform, const System& system);
~ReferenceCalcAmoebaPiTorsionForceKernel();
/**
* Initialize the kernel.
......@@ -221,7 +221,7 @@ private:
*/
class ReferenceCalcAmoebaStretchBendForceKernel : public CalcAmoebaStretchBendForceKernel {
public:
ReferenceCalcAmoebaStretchBendForceKernel(std::string name, const Platform& platform, const System& system);
ReferenceCalcAmoebaStretchBendForceKernel(const std::string& name, const Platform& platform, const System& system);
~ReferenceCalcAmoebaStretchBendForceKernel();
/**
* Initialize the kernel.
......@@ -265,7 +265,7 @@ private:
*/
class ReferenceCalcAmoebaOutOfPlaneBendForceKernel : public CalcAmoebaOutOfPlaneBendForceKernel {
public:
ReferenceCalcAmoebaOutOfPlaneBendForceKernel(std::string name, const Platform& platform, const System& system);
ReferenceCalcAmoebaOutOfPlaneBendForceKernel(const std::string& name, const Platform& platform, const System& system);
~ReferenceCalcAmoebaOutOfPlaneBendForceKernel();
/**
* Initialize the kernel.
......@@ -310,7 +310,7 @@ private:
*/
class ReferenceCalcAmoebaTorsionTorsionForceKernel : public CalcAmoebaTorsionTorsionForceKernel {
public:
ReferenceCalcAmoebaTorsionTorsionForceKernel(std::string name, const Platform& platform, const System& system);
ReferenceCalcAmoebaTorsionTorsionForceKernel(const std::string& name, const Platform& platform, const System& system);
~ReferenceCalcAmoebaTorsionTorsionForceKernel();
/**
* Initialize the kernel.
......@@ -350,7 +350,7 @@ private:
*/
class ReferenceCalcAmoebaMultipoleForceKernel : public CalcAmoebaMultipoleForceKernel {
public:
ReferenceCalcAmoebaMultipoleForceKernel(std::string name, const Platform& platform, const System& system);
ReferenceCalcAmoebaMultipoleForceKernel(const std::string& name, const Platform& platform, const System& system);
~ReferenceCalcAmoebaMultipoleForceKernel();
/**
* Initialize the kernel.
......@@ -470,7 +470,7 @@ private:
*/
class ReferenceCalcAmoebaVdwForceKernel : public CalcAmoebaVdwForceKernel {
public:
ReferenceCalcAmoebaVdwForceKernel(std::string name, const Platform& platform, const System& system);
ReferenceCalcAmoebaVdwForceKernel(const std::string& name, const Platform& platform, const System& system);
~ReferenceCalcAmoebaVdwForceKernel();
/**
* Initialize the kernel.
......@@ -501,11 +501,15 @@ private:
int usePBC;
double cutoff;
double dispersionCoefficient;
AmoebaVdwForce::AlchemicalMethod alchemicalMethod;
int n;
double alpha;
std::vector<int> indexIVs;
std::vector< std::set<int> > allExclusions;
std::vector<double> sigmas;
std::vector<double> epsilons;
std::vector<double> reductions;
std::vector<bool> isAlchemical;
std::string sigmaCombiningRule;
std::string epsilonCombiningRule;
const System& system;
......@@ -517,7 +521,7 @@ private:
*/
class ReferenceCalcAmoebaWcaDispersionForceKernel : public CalcAmoebaWcaDispersionForceKernel {
public:
ReferenceCalcAmoebaWcaDispersionForceKernel(std::string name, const Platform& platform, const System& system);
ReferenceCalcAmoebaWcaDispersionForceKernel(const std::string& name, const Platform& platform, const System& system);
~ReferenceCalcAmoebaWcaDispersionForceKernel();
/**
* Initialize the kernel.
......@@ -564,7 +568,7 @@ private:
*/
class ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel : public CalcAmoebaGeneralizedKirkwoodForceKernel {
public:
ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel(std::string name, const Platform& platform, const System& system);
ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel(const std::string& name, const Platform& platform, const System& system);
~ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel();
/**
* Initialize the kernel.
......@@ -698,7 +702,7 @@ private:
*/
class ReferenceCalcHippoNonbondedForceKernel : public CalcHippoNonbondedForceKernel {
public:
ReferenceCalcHippoNonbondedForceKernel(std::string name, const Platform& platform, const System& system);
ReferenceCalcHippoNonbondedForceKernel(const std::string& name, const Platform& platform, const System& system);
~ReferenceCalcHippoNonbondedForceKernel();
/**
* Initialize the kernel.
......
......@@ -828,7 +828,7 @@ static void testQuadrupoleValidation() {
static void setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::NonbondedMethod nonbondedMethod,
AmoebaMultipoleForce::PolarizationType polarizationType,
double cutoff, int inputPmeGridDimension, std::string testName,
double cutoff, int inputPmeGridDimension, const std::string& testName,
std::vector<Vec3>& forces, double& energy) {
// beginning of Multipole setup
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment