Commit a381a3ab authored by peastman's avatar peastman
Browse files

Merge branch 'master' into gayberne

parents 5ecc8e00 1f7866ad
...@@ -38,20 +38,19 @@ using namespace OpenMM; ...@@ -38,20 +38,19 @@ using namespace OpenMM;
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceCustomTorsionIxn::ReferenceCustomTorsionIxn(const Lepton::CompiledExpression& energyExpression, ReferenceCustomTorsionIxn::ReferenceCustomTorsionIxn(const Lepton::CompiledExpression& energyExpression,
const Lepton::CompiledExpression& forceExpression, const vector<string>& parameterNames, map<string, double> globalParameters) : const Lepton::CompiledExpression& forceExpression, const vector<string>& parameterNames, map<string, double> globalParameters,
energyExpression(energyExpression), forceExpression(forceExpression), usePeriodic(false) { const vector<Lepton::CompiledExpression> energyParamDerivExpressions) :
energyExpression(energyExpression), forceExpression(forceExpression), usePeriodic(false), energyParamDerivExpressions(energyParamDerivExpressions) {
energyTheta = ReferenceForce::getVariablePointer(this->energyExpression, "theta"); expressionSet.registerExpression(this->energyExpression);
forceTheta = ReferenceForce::getVariablePointer(this->forceExpression, "theta"); expressionSet.registerExpression(this->forceExpression);
for (int i = 0; i < this->energyParamDerivExpressions.size(); i++)
expressionSet.registerExpression(this->energyParamDerivExpressions[i]);
thetaIndex = expressionSet.getVariableIndex("theta");
numParameters = parameterNames.size(); numParameters = parameterNames.size();
for (int i = 0; i < (int) numParameters; i++) { for (int i = 0; i < (int) numParameters; i++)
energyParams.push_back(ReferenceForce::getVariablePointer(this->energyExpression, parameterNames[i])); torsionParamIndex.push_back(expressionSet.getVariableIndex(parameterNames[i]));
forceParams.push_back(ReferenceForce::getVariablePointer(this->forceExpression, parameterNames[i])); for (map<string, double>::const_iterator iter = globalParameters.begin(); iter != globalParameters.end(); ++iter)
} expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second);
for (map<string, double>::const_iterator iter = globalParameters.begin(); iter != globalParameters.end(); ++iter) {
ReferenceForce::setVariable(ReferenceForce::getVariablePointer(this->energyExpression, iter->first), iter->second);
ReferenceForce::setVariable(ReferenceForce::getVariablePointer(this->forceExpression, iter->first), iter->second);
}
} }
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -86,18 +85,10 @@ void ReferenceCustomTorsionIxn::calculateBondIxn(int* atomIndices, ...@@ -86,18 +85,10 @@ void ReferenceCustomTorsionIxn::calculateBondIxn(int* atomIndices,
vector<RealVec>& atomCoordinates, vector<RealVec>& atomCoordinates,
RealOpenMM* parameters, RealOpenMM* parameters,
vector<RealVec>& forces, vector<RealVec>& forces,
RealOpenMM* totalEnergy) const { RealOpenMM* totalEnergy, double* energyParamDerivs) {
static const std::string methodName = "\nReferenceCustomTorsionIxn::calculateTorsionIxn";
static const RealOpenMM zero = 0.0;
static const RealOpenMM one = 1.0;
RealOpenMM deltaR[3][ReferenceForce::LastDeltaRIndex]; RealOpenMM deltaR[3][ReferenceForce::LastDeltaRIndex];
for (int i = 0; i < numParameters; i++) { for (int i = 0; i < numParameters; i++)
ReferenceForce::setVariable(energyParams[i], parameters[i]); expressionSet.setVariable(torsionParamIndex[i], parameters[i]);
ReferenceForce::setVariable(forceParams[i], parameters[i]);
}
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
...@@ -130,8 +121,7 @@ void ReferenceCustomTorsionIxn::calculateBondIxn(int* atomIndices, ...@@ -130,8 +121,7 @@ void ReferenceCustomTorsionIxn::calculateBondIxn(int* atomIndices,
RealOpenMM dotDihedral; RealOpenMM dotDihedral;
RealOpenMM signOfAngle; RealOpenMM signOfAngle;
RealOpenMM angle = getDihedralAngleBetweenThreeVectors(deltaR[0], deltaR[1], deltaR[2], crossProduct, &dotDihedral, deltaR[0], &signOfAngle, 1); RealOpenMM angle = getDihedralAngleBetweenThreeVectors(deltaR[0], deltaR[1], deltaR[2], crossProduct, &dotDihedral, deltaR[0], &signOfAngle, 1);
ReferenceForce::setVariable(energyTheta, angle); expressionSet.setVariable(thetaIndex, angle);
ReferenceForce::setVariable(forceTheta, angle);
// evaluate delta angle, dE/d(angle) // evaluate delta angle, dE/d(angle)
...@@ -174,6 +164,11 @@ void ReferenceCustomTorsionIxn::calculateBondIxn(int* atomIndices, ...@@ -174,6 +164,11 @@ void ReferenceCustomTorsionIxn::calculateBondIxn(int* atomIndices,
forces[atomDIndex][ii] += internalF[3][ii]; forces[atomDIndex][ii] += internalF[3][ii];
} }
// Record parameter derivatives.
for (int i = 0; i < energyParamDerivExpressions.size(); i++)
energyParamDerivs[i] += energyParamDerivExpressions[i].evaluate();
// accumulate energies // accumulate energies
if (totalEnergy != NULL) if (totalEnergy != NULL)
......
...@@ -74,7 +74,7 @@ void ReferenceHarmonicBondIxn::calculateBondIxn(int* atomIndices, ...@@ -74,7 +74,7 @@ void ReferenceHarmonicBondIxn::calculateBondIxn(int* atomIndices,
vector<RealVec>& atomCoordinates, vector<RealVec>& atomCoordinates,
RealOpenMM* parameters, RealOpenMM* parameters,
vector<RealVec>& forces, vector<RealVec>& forces,
RealOpenMM* totalEnergy) const { RealOpenMM* totalEnergy, double* energyParamDerivs) {
static const std::string methodName = "\nReferenceHarmonicBondIxn::calculateBondIxn"; static const std::string methodName = "\nReferenceHarmonicBondIxn::calculateBondIxn";
......
/* Portions copyright (c) 2006 Stanford University and Simbios. /* Portions copyright (c) 2006-2016 Stanford University and Simbios.
* Contributors: Pande Group * Contributors: Pande Group
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -81,7 +81,7 @@ ReferenceLJCoulomb14::~ReferenceLJCoulomb14() { ...@@ -81,7 +81,7 @@ ReferenceLJCoulomb14::~ReferenceLJCoulomb14() {
void ReferenceLJCoulomb14::calculateBondIxn(int* atomIndices, vector<RealVec>& atomCoordinates, void ReferenceLJCoulomb14::calculateBondIxn(int* atomIndices, vector<RealVec>& atomCoordinates,
RealOpenMM* parameters, vector<RealVec>& forces, RealOpenMM* parameters, vector<RealVec>& forces,
RealOpenMM* totalEnergy) const { RealOpenMM* totalEnergy, double* energyParamDerivs) {
static const std::string methodName = "\nReferenceLJCoulomb14::calculateBondIxn"; static const std::string methodName = "\nReferenceLJCoulomb14::calculateBondIxn";
......
...@@ -420,6 +420,7 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec> ...@@ -420,6 +420,7 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec>
// Now subtract off the exclusions, since they were implicitly included in the reciprocal space sum. // Now subtract off the exclusions, since they were implicitly included in the reciprocal space sum.
RealOpenMM totalExclusionEnergy = 0.0f; RealOpenMM totalExclusionEnergy = 0.0f;
const double TWO_OVER_SQRT_PI = 2/sqrt(PI_M);
for (int i = 0; i < numberOfAtoms; i++) for (int i = 0; i < numberOfAtoms; i++)
for (set<int>::const_iterator iter = exclusions[i].begin(); iter != exclusions[i].end(); ++iter) { for (set<int>::const_iterator iter = exclusions[i].begin(); iter != exclusions[i].end(); ++iter) {
if (*iter > i) { if (*iter > i) {
...@@ -446,12 +447,15 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec> ...@@ -446,12 +447,15 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector<RealVec>
// accumulate energies // accumulate energies
realSpaceEwaldEnergy = (RealOpenMM) (ONE_4PI_EPS0*atomParameters[ii][QIndex]*atomParameters[jj][QIndex]*inverseR*erf(alphaR)); realSpaceEwaldEnergy = (RealOpenMM) (ONE_4PI_EPS0*atomParameters[ii][QIndex]*atomParameters[jj][QIndex]*inverseR*erf(alphaR));
}
else {
realSpaceEwaldEnergy = (RealOpenMM) (alphaEwald*TWO_OVER_SQRT_PI*ONE_4PI_EPS0*atomParameters[ii][QIndex]*atomParameters[jj][QIndex]);
}
totalExclusionEnergy += realSpaceEwaldEnergy; totalExclusionEnergy += realSpaceEwaldEnergy;
if (energyByAtom) { if (energyByAtom) {
energyByAtom[ii] -= realSpaceEwaldEnergy; energyByAtom[ii] -= realSpaceEwaldEnergy;
energyByAtom[jj] -= realSpaceEwaldEnergy; energyByAtom[jj] -= realSpaceEwaldEnergy;
}
} }
} }
} }
......
...@@ -75,7 +75,7 @@ void ReferenceProperDihedralBond::calculateBondIxn(int* atomIndices, ...@@ -75,7 +75,7 @@ void ReferenceProperDihedralBond::calculateBondIxn(int* atomIndices,
vector<RealVec>& atomCoordinates, vector<RealVec>& atomCoordinates,
RealOpenMM* parameters, RealOpenMM* parameters,
vector<RealVec>& forces, vector<RealVec>& forces,
RealOpenMM* totalEnergy) const { RealOpenMM* totalEnergy, double* energyParamDerivs) {
static const std::string methodName = "\nReferenceProperDihedralBond::calculateBondIxn"; static const std::string methodName = "\nReferenceProperDihedralBond::calculateBondIxn";
......
...@@ -73,7 +73,7 @@ void ReferenceRbDihedralBond::calculateBondIxn(int* atomIndices, ...@@ -73,7 +73,7 @@ void ReferenceRbDihedralBond::calculateBondIxn(int* atomIndices,
vector<RealVec>& atomCoordinates, vector<RealVec>& atomCoordinates,
RealOpenMM* parameters, RealOpenMM* parameters,
vector<RealVec>& forces, vector<RealVec>& forces,
RealOpenMM* totalEnergy) const { RealOpenMM* totalEnergy, double* energyParamDerivs) {
static const std::string methodName = "\nReferenceRbDihedralBond::calculateBondIxn"; static const std::string methodName = "\nReferenceRbDihedralBond::calculateBondIxn";
......
...@@ -383,8 +383,11 @@ void SimTKOpenMMUtilities::createCheckpoint(std::ostream& stream) { ...@@ -383,8 +383,11 @@ void SimTKOpenMMUtilities::createCheckpoint(std::ostream& stream) {
void SimTKOpenMMUtilities::loadCheckpoint(std::istream& stream) { void SimTKOpenMMUtilities::loadCheckpoint(std::istream& stream) {
stream.read((char*) &_randomNumberSeed, sizeof(uint32_t)); stream.read((char*) &_randomNumberSeed, sizeof(uint32_t));
bool prevInitialized = _randomInitialized;
stream.read((char*) &_randomInitialized, sizeof(bool)); stream.read((char*) &_randomInitialized, sizeof(bool));
if (_randomInitialized) { if (_randomInitialized) {
if (!prevInitialized)
init_gen_rand(0, sfmt);
stream.read((char*) &nextGaussianIsValid, sizeof(bool)); stream.read((char*) &nextGaussianIsValid, sizeof(bool));
stream.read((char*) &nextGaussian, sizeof(RealOpenMM)); stream.read((char*) &nextGaussian, sizeof(RealOpenMM));
sfmt.loadCheckpoint(stream); sfmt.loadCheckpoint(stream);
......
...@@ -147,11 +147,34 @@ public: ...@@ -147,11 +147,34 @@ public:
*/ */
void setCutoffDistance(double distance); void setCutoffDistance(double distance);
/**
* Get the parameters to use for PME calculations. If alpha is 0 (the default), these parameters are
* ignored and instead their values are chosen based on the Ewald error tolerance.
*
* @param[out] alpha the separation parameter
* @param[out] nx the number of grid points along the X axis
* @param[out] ny the number of grid points along the Y axis
* @param[out] nz the number of grid points along the Z axis
*/
void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const;
/**
* Set the parameters to use for PME calculations. If alpha is 0 (the default), these parameters are
* ignored and instead their values are chosen based on the Ewald error tolerance.
*
* @param alpha the separation parameter
* @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis
* @param nz the number of grid points along the Z axis
*/
void setPMEParameters(double alpha, int nx, int ny, int nz);
/** /**
* Get the Ewald alpha parameter. If this is 0 (the default), a value is chosen automatically * Get the Ewald alpha parameter. If this is 0 (the default), a value is chosen automatically
* based on the Ewald error tolerance. * based on the Ewald error tolerance.
* *
* @return the Ewald alpha parameter * @return the Ewald alpha parameter
* @deprecated This method exists only for backward compatibility. Use getPMEParameters() instead.
*/ */
double getAEwald() const; double getAEwald() const;
...@@ -160,6 +183,7 @@ public: ...@@ -160,6 +183,7 @@ public:
* based on the Ewald error tolerance. * based on the Ewald error tolerance.
* *
* @param aewald alpha parameter * @param aewald alpha parameter
* @deprecated This method exists only for backward compatibility. Use setPMEParameters() instead.
*/ */
void setAEwald(double aewald); void setAEwald(double aewald);
...@@ -175,6 +199,7 @@ public: ...@@ -175,6 +199,7 @@ public:
* are chosen automatically based on the Ewald error tolerance. * are chosen automatically based on the Ewald error tolerance.
* *
* @return the PME grid dimensions * @return the PME grid dimensions
* @deprecated This method exists only for backward compatibility. Use getPMEParameters() instead.
*/ */
void getPmeGridDimensions(std::vector<int>& gridDimension) const; void getPmeGridDimensions(std::vector<int>& gridDimension) const;
...@@ -183,6 +208,7 @@ public: ...@@ -183,6 +208,7 @@ public:
* are chosen automatically based on the Ewald error tolerance. * are chosen automatically based on the Ewald error tolerance.
* *
* @param gridDimension the PME grid dimensions * @param gridDimension the PME grid dimensions
* @deprecated This method exists only for backward compatibility. Use setPMEParameters() instead.
*/ */
void setPmeGridDimensions(const std::vector<int>& gridDimension); void setPmeGridDimensions(const std::vector<int>& gridDimension);
...@@ -344,7 +370,13 @@ public: ...@@ -344,7 +370,13 @@ public:
* This can be overridden by explicitly setting an alpha parameter and grid dimensions to use. * This can be overridden by explicitly setting an alpha parameter and grid dimensions to use.
*/ */
void setEwaldErrorTolerance(double tol); void setEwaldErrorTolerance(double tol);
/**
* Get the fixed dipole moments of all particles in the global reference frame.
*
* @param context the Context for which to get the fixed dipoles
* @param[out] dipoles the fixed dipole moment of particle i is stored into the i'th element
*/
void getLabFramePermanentDipoles(Context& context, std::vector<Vec3>& dipoles);
/** /**
* Get the induced dipole moments of all particles. * Get the induced dipole moments of all particles.
* *
...@@ -353,6 +385,14 @@ public: ...@@ -353,6 +385,14 @@ public:
*/ */
void getInducedDipoles(Context& context, std::vector<Vec3>& dipoles); void getInducedDipoles(Context& context, std::vector<Vec3>& dipoles);
/**
* Get the total dipole moments (fixed plus induced) of all particles.
*
* @param context the Context for which to get the total dipoles
* @param[out] dipoles the total dipole moment of particle i is stored into the i'th element
*/
void getTotalDipoles(Context& context, std::vector<Vec3>& dipoles);
/** /**
* Get the electrostatic potential. * Get the electrostatic potential.
* *
...@@ -408,9 +448,8 @@ private: ...@@ -408,9 +448,8 @@ private:
NonbondedMethod nonbondedMethod; NonbondedMethod nonbondedMethod;
PolarizationType polarizationType; PolarizationType polarizationType;
double cutoffDistance; double cutoffDistance;
double aewald; double alpha;
int pmeBSplineOrder; int pmeBSplineOrder, nx, ny, nz;
std::vector<int> pmeGridDimension;
int mutualInducedMaxIterations; int mutualInducedMaxIterations;
std::vector<double> extrapolationCoefficients; std::vector<double> extrapolationCoefficients;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2012 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Peter Eastman * * Authors: Mark Friedrichs, Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -183,13 +183,34 @@ public: ...@@ -183,13 +183,34 @@ public:
*/ */
void getParticleExclusions(int particleIndex, std::vector<int>& exclusions) const; void getParticleExclusions(int particleIndex, std::vector<int>& exclusions) const;
/**
* Get the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use
* is NoCutoff, this value will have no effect.
*
* @return the cutoff distance, measured in nm
*/
double getCutoffDistance() const;
/**
* Set the cutoff distance (in nm) being used for nonbonded interactions. If the NonbondedMethod in use
* is NoCutoff, this value will have no effect.
*
* @param distance the cutoff distance, measured in nm
*/
void setCutoffDistance(double distance);
/** /**
* Set the cutoff distance. * Set the cutoff distance.
*
* @deprecated This method exists only for backward compatibility. Use setCutoffDistance() instead.
*/ */
void setCutoff(double cutoff); void setCutoff(double cutoff);
/** /**
* Get the cutoff distance. * Get the cutoff distance.
*
* @deprecated This method exists only for backward compatibility. Use getCutoffDistance() instead.
*/ */
double getCutoff() const; double getCutoff() const;
......
...@@ -59,7 +59,7 @@ public: ...@@ -59,7 +59,7 @@ public:
/** /**
* Initialize the kernel. * Initialize the kernel.
* *
* @param system the System this kernel will be applied to * @param system the System this kernel will be applied to
* @param force the AmoebaBondForce this kernel will be used for * @param force the AmoebaBondForce this kernel will be used for
*/ */
...@@ -99,7 +99,7 @@ public: ...@@ -99,7 +99,7 @@ public:
/** /**
* Initialize the kernel. * Initialize the kernel.
* *
* @param system the System this kernel will be applied to * @param system the System this kernel will be applied to
* @param force the AmoebaAngleForce this kernel will be used for * @param force the AmoebaAngleForce this kernel will be used for
*/ */
...@@ -139,7 +139,7 @@ public: ...@@ -139,7 +139,7 @@ public:
/** /**
* Initialize the kernel. * Initialize the kernel.
* *
* @param system the System this kernel will be applied to * @param system the System this kernel will be applied to
* @param force the AmoebaInPlaneAngleForce this kernel will be used for * @param force the AmoebaInPlaneAngleForce this kernel will be used for
*/ */
...@@ -179,7 +179,7 @@ public: ...@@ -179,7 +179,7 @@ public:
/** /**
* Initialize the kernel. * Initialize the kernel.
* *
* @param system the System this kernel will be applied to * @param system the System this kernel will be applied to
* @param force the PiTorsionForce this kernel will be used for * @param force the PiTorsionForce this kernel will be used for
*/ */
...@@ -219,7 +219,7 @@ public: ...@@ -219,7 +219,7 @@ public:
/** /**
* Initialize the kernel. * Initialize the kernel.
* *
* @param system the System this kernel will be applied to * @param system the System this kernel will be applied to
* @param force the StretchBendForce this kernel will be used for * @param force the StretchBendForce this kernel will be used for
*/ */
...@@ -259,7 +259,7 @@ public: ...@@ -259,7 +259,7 @@ public:
/** /**
* Initialize the kernel. * Initialize the kernel.
* *
* @param system the System this kernel will be applied to * @param system the System this kernel will be applied to
* @param force the OutOfPlaneBendForce this kernel will be used for * @param force the OutOfPlaneBendForce this kernel will be used for
*/ */
...@@ -299,7 +299,7 @@ public: ...@@ -299,7 +299,7 @@ public:
/** /**
* Initialize the kernel. * Initialize the kernel.
* *
* @param system the System this kernel will be applied to * @param system the System this kernel will be applied to
* @param force the TorsionTorsionForce this kernel will be used for * @param force the TorsionTorsionForce this kernel will be used for
*/ */
...@@ -332,7 +332,7 @@ public: ...@@ -332,7 +332,7 @@ public:
/** /**
* Initialize the kernel. * Initialize the kernel.
* *
* @param system the System this kernel will be applied to * @param system the System this kernel will be applied to
* @param force the MultipoleForce this kernel will be used for * @param force the MultipoleForce this kernel will be used for
*/ */
...@@ -348,7 +348,9 @@ public: ...@@ -348,7 +348,9 @@ public:
*/ */
virtual double execute(ContextImpl& context, bool includeForces, bool includeEnergy) = 0; virtual double execute(ContextImpl& context, bool includeForces, bool includeEnergy) = 0;
virtual void getLabFramePermanentDipoles(ContextImpl& context, std::vector<Vec3>& dipoles) = 0;
virtual void getInducedDipoles(ContextImpl& context, std::vector<Vec3>& dipoles) = 0; virtual void getInducedDipoles(ContextImpl& context, std::vector<Vec3>& dipoles) = 0;
virtual void getTotalDipoles(ContextImpl& context, std::vector<Vec3>& dipoles) = 0;
virtual void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, virtual void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid,
std::vector< double >& outputElectrostaticPotential) = 0; std::vector< double >& outputElectrostaticPotential) = 0;
...@@ -364,7 +366,7 @@ public: ...@@ -364,7 +366,7 @@ public:
/** /**
* Get the parameters being used for PME. * Get the parameters being used for PME.
* *
* @param alpha the separation parameter * @param alpha the separation parameter
* @param nx the number of grid points along the X axis * @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis * @param ny the number of grid points along the Y axis
...@@ -389,7 +391,7 @@ public: ...@@ -389,7 +391,7 @@ public:
/** /**
* Initialize the kernel. * Initialize the kernel.
* *
* @param system the System this kernel will be applied to * @param system the System this kernel will be applied to
* @param force the GBSAOBCForce this kernel will be used for * @param force the GBSAOBCForce this kernel will be used for
*/ */
...@@ -429,7 +431,7 @@ public: ...@@ -429,7 +431,7 @@ public:
/** /**
* Initialize the kernel. * Initialize the kernel.
* *
* @param system the System this kernel will be applied to * @param system the System this kernel will be applied to
* @param force the GBSAOBCForce this kernel will be used for * @param force the GBSAOBCForce this kernel will be used for
*/ */
...@@ -469,7 +471,7 @@ public: ...@@ -469,7 +471,7 @@ public:
/** /**
* Initialize the kernel. * Initialize the kernel.
* *
* @param system the System this kernel will be applied to * @param system the System this kernel will be applied to
* @param force the GBSAOBCForce this kernel will be used for * @param force the GBSAOBCForce this kernel will be used for
*/ */
......
...@@ -64,7 +64,7 @@ public: ...@@ -64,7 +64,7 @@ public:
/** /**
* Get the CovalentMap for an atom * Get the CovalentMap for an atom
* *
* @param force AmoebaMultipoleForce force reference * @param force AmoebaMultipoleForce force reference
* @param index the index of the atom for which to set parameters * @param index the index of the atom for which to set parameters
* @param minCovalentIndex minimum covalent index * @param minCovalentIndex minimum covalent index
...@@ -76,13 +76,14 @@ public: ...@@ -76,13 +76,14 @@ public:
/** /**
* Get the covalent degree for the CovalentEnd lists * Get the covalent degree for the CovalentEnd lists
* *
* @param force AmoebaMultipoleForce force reference * @param force AmoebaMultipoleForce force reference
* @param covalentDegree covalent degrees for the CovalentEnd lists * @param covalentDegree covalent degrees for the CovalentEnd lists
*/ */
static void getCovalentDegree(const AmoebaMultipoleForce& force, std::vector<int>& covalentDegree); static void getCovalentDegree(const AmoebaMultipoleForce& force, std::vector<int>& covalentDegree);
void getLabFramePermanentDipoles(ContextImpl& context, std::vector<Vec3>& dipoles);
void getInducedDipoles(ContextImpl& context, std::vector<Vec3>& dipoles); void getInducedDipoles(ContextImpl& context, std::vector<Vec3>& dipoles);
void getTotalDipoles(ContextImpl& context, std::vector<Vec3>& dipoles);
void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid,
std::vector< double >& outputElectrostaticPotential); std::vector< double >& outputElectrostaticPotential);
...@@ -90,7 +91,7 @@ public: ...@@ -90,7 +91,7 @@ public:
void getSystemMultipoleMoments(ContextImpl& context, std::vector< double >& outputMultipoleMoments); void getSystemMultipoleMoments(ContextImpl& context, std::vector< double >& outputMultipoleMoments);
void updateParametersInContext(ContextImpl& context); void updateParametersInContext(ContextImpl& context);
void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const; void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const;
private: private:
const AmoebaMultipoleForce& owner; const AmoebaMultipoleForce& owner;
......
...@@ -40,9 +40,7 @@ using std::string; ...@@ -40,9 +40,7 @@ using std::string;
using std::vector; using std::vector;
AmoebaMultipoleForce::AmoebaMultipoleForce() : nonbondedMethod(NoCutoff), polarizationType(Mutual), pmeBSplineOrder(5), cutoffDistance(1.0), ewaldErrorTol(1e-4), mutualInducedMaxIterations(60), AmoebaMultipoleForce::AmoebaMultipoleForce() : nonbondedMethod(NoCutoff), polarizationType(Mutual), pmeBSplineOrder(5), cutoffDistance(1.0), ewaldErrorTol(1e-4), mutualInducedMaxIterations(60),
mutualInducedTargetEpsilon(1.0e-02), scalingDistanceCutoff(100.0), electricConstant(138.9354558456), aewald(0.0) { mutualInducedTargetEpsilon(1.0e-02), scalingDistanceCutoff(100.0), electricConstant(138.9354558456), alpha(0.0), nx(0), ny(0), nz(0) {
pmeGridDimension.resize(3);
pmeGridDimension[0] = pmeGridDimension[1] = pmeGridDimension[2];
extrapolationCoefficients.push_back(-0.154); extrapolationCoefficients.push_back(-0.154);
extrapolationCoefficients.push_back(0.017); extrapolationCoefficients.push_back(0.017);
extrapolationCoefficients.push_back(0.658); extrapolationCoefficients.push_back(0.658);
...@@ -81,12 +79,26 @@ void AmoebaMultipoleForce::setCutoffDistance(double distance) { ...@@ -81,12 +79,26 @@ void AmoebaMultipoleForce::setCutoffDistance(double distance) {
cutoffDistance = distance; cutoffDistance = distance;
} }
void AmoebaMultipoleForce::getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const {
alpha = this->alpha;
nx = this->nx;
ny = this->ny;
nz = this->nz;
}
void AmoebaMultipoleForce::setPMEParameters(double alpha, int nx, int ny, int nz) {
this->alpha = alpha;
this->nx = nx;
this->ny = ny;
this->nz = nz;
}
double AmoebaMultipoleForce::getAEwald() const { double AmoebaMultipoleForce::getAEwald() const {
return aewald; return alpha;
} }
void AmoebaMultipoleForce::setAEwald(double inputAewald) { void AmoebaMultipoleForce::setAEwald(double inputAewald) {
aewald = inputAewald; alpha = inputAewald;
} }
int AmoebaMultipoleForce::getPmeBSplineOrder() const { int AmoebaMultipoleForce::getPmeBSplineOrder() const {
...@@ -94,26 +106,18 @@ int AmoebaMultipoleForce::getPmeBSplineOrder() const { ...@@ -94,26 +106,18 @@ int AmoebaMultipoleForce::getPmeBSplineOrder() const {
} }
void AmoebaMultipoleForce::getPmeGridDimensions(std::vector<int>& gridDimension) const { void AmoebaMultipoleForce::getPmeGridDimensions(std::vector<int>& gridDimension) const {
if (gridDimension.size() < 3) { if (gridDimension.size() < 3)
gridDimension.resize(3); gridDimension.resize(3);
} gridDimension[0] = nx;
if (pmeGridDimension.size() > 2) { gridDimension[1] = ny;
gridDimension[0] = pmeGridDimension[0]; gridDimension[2] = nz;
gridDimension[1] = pmeGridDimension[1];
gridDimension[2] = pmeGridDimension[2];
} else {
gridDimension[0] = gridDimension[1] = gridDimension[2] = 0;
}
return;
} }
void AmoebaMultipoleForce::setPmeGridDimensions(const std::vector<int>& gridDimension) { void AmoebaMultipoleForce::setPmeGridDimensions(const std::vector<int>& gridDimension) {
pmeGridDimension.resize(3); nx = gridDimension[0];
pmeGridDimension[0] = gridDimension[0]; ny = gridDimension[1];
pmeGridDimension[1] = gridDimension[1]; nz = gridDimension[2];
pmeGridDimension[2] = gridDimension[2]; }
return;
}
void AmoebaMultipoleForce::getPMEParametersInContext(const Context& context, double& alpha, int& nx, int& ny, int& nz) const { void AmoebaMultipoleForce::getPMEParametersInContext(const Context& context, double& alpha, int& nx, int& ny, int& nz) const {
dynamic_cast<const AmoebaMultipoleForceImpl&>(getImplInContext(context)).getPMEParameters(alpha, nx, ny, nz); dynamic_cast<const AmoebaMultipoleForceImpl&>(getImplInContext(context)).getPMEParameters(alpha, nx, ny, nz);
...@@ -143,13 +147,13 @@ void AmoebaMultipoleForce::setEwaldErrorTolerance(double tol) { ...@@ -143,13 +147,13 @@ void AmoebaMultipoleForce::setEwaldErrorTolerance(double tol) {
ewaldErrorTol = tol; ewaldErrorTol = tol;
} }
int AmoebaMultipoleForce::addMultipole(double charge, const std::vector<double>& molecularDipole, const std::vector<double>& molecularQuadrupole, int axisType, int AmoebaMultipoleForce::addMultipole(double charge, const std::vector<double>& molecularDipole, const std::vector<double>& molecularQuadrupole, int axisType,
int multipoleAtomZ, int multipoleAtomX, int multipoleAtomY, double thole, double dampingFactor, double polarity) { int multipoleAtomZ, int multipoleAtomX, int multipoleAtomY, double thole, double dampingFactor, double polarity) {
multipoles.push_back(MultipoleInfo(charge, molecularDipole, molecularQuadrupole, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, thole, dampingFactor, polarity)); multipoles.push_back(MultipoleInfo(charge, molecularDipole, molecularQuadrupole, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, thole, dampingFactor, polarity));
return multipoles.size()-1; return multipoles.size()-1;
} }
void AmoebaMultipoleForce::getMultipoleParameters(int index, double& charge, std::vector<double>& molecularDipole, std::vector<double>& molecularQuadrupole, void AmoebaMultipoleForce::getMultipoleParameters(int index, double& charge, std::vector<double>& molecularDipole, std::vector<double>& molecularQuadrupole,
int& axisType, int& multipoleAtomZ, int& multipoleAtomX, int& multipoleAtomY, double& thole, double& dampingFactor, double& polarity) const { int& axisType, int& multipoleAtomZ, int& multipoleAtomX, int& multipoleAtomY, double& thole, double& dampingFactor, double& polarity) const {
charge = multipoles[index].charge; charge = multipoles[index].charge;
...@@ -179,7 +183,7 @@ void AmoebaMultipoleForce::getMultipoleParameters(int index, double& charge, std ...@@ -179,7 +183,7 @@ void AmoebaMultipoleForce::getMultipoleParameters(int index, double& charge, std
polarity = multipoles[index].polarity; polarity = multipoles[index].polarity;
} }
void AmoebaMultipoleForce::setMultipoleParameters(int index, double charge, const std::vector<double>& molecularDipole, const std::vector<double>& molecularQuadrupole, void AmoebaMultipoleForce::setMultipoleParameters(int index, double charge, const std::vector<double>& molecularDipole, const std::vector<double>& molecularQuadrupole,
int axisType, int multipoleAtomZ, int multipoleAtomX, int multipoleAtomY, double thole, double dampingFactor, double polarity) { int axisType, int multipoleAtomZ, int multipoleAtomX, int multipoleAtomY, double thole, double dampingFactor, double polarity) {
multipoles[index].charge = charge; multipoles[index].charge = charge;
...@@ -246,6 +250,14 @@ void AmoebaMultipoleForce::getInducedDipoles(Context& context, vector<Vec3>& dip ...@@ -246,6 +250,14 @@ void AmoebaMultipoleForce::getInducedDipoles(Context& context, vector<Vec3>& dip
dynamic_cast<AmoebaMultipoleForceImpl&>(getImplInContext(context)).getInducedDipoles(getContextImpl(context), dipoles); dynamic_cast<AmoebaMultipoleForceImpl&>(getImplInContext(context)).getInducedDipoles(getContextImpl(context), dipoles);
} }
void AmoebaMultipoleForce::getLabFramePermanentDipoles(Context& context, vector<Vec3>& dipoles) {
dynamic_cast<AmoebaMultipoleForceImpl&>(getImplInContext(context)).getLabFramePermanentDipoles(getContextImpl(context), dipoles);
}
void AmoebaMultipoleForce::getTotalDipoles(Context& context, vector<Vec3>& dipoles) {
dynamic_cast<AmoebaMultipoleForceImpl&>(getImplInContext(context)).getTotalDipoles(getContextImpl(context), dipoles);
}
void AmoebaMultipoleForce::getElectrostaticPotential(const std::vector< Vec3 >& inputGrid, Context& context, std::vector< double >& outputElectrostaticPotential) { void AmoebaMultipoleForce::getElectrostaticPotential(const std::vector< Vec3 >& inputGrid, Context& context, std::vector< double >& outputElectrostaticPotential) {
dynamic_cast<AmoebaMultipoleForceImpl&>(getImplInContext(context)).getElectrostaticPotential(getContextImpl(context), inputGrid, outputElectrostaticPotential); dynamic_cast<AmoebaMultipoleForceImpl&>(getImplInContext(context)).getElectrostaticPotential(getContextImpl(context), inputGrid, outputElectrostaticPotential);
} }
......
...@@ -61,7 +61,7 @@ void AmoebaMultipoleForceImpl::initialize(ContextImpl& context) { ...@@ -61,7 +61,7 @@ void AmoebaMultipoleForceImpl::initialize(ContextImpl& context) {
double cutoff = owner.getCutoffDistance(); double cutoff = owner.getCutoffDistance();
if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2]) if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2])
throw OpenMMException("AmoebaMultipoleForce: The cutoff distance cannot be greater than half the periodic box size."); throw OpenMMException("AmoebaMultipoleForce: The cutoff distance cannot be greater than half the periodic box size.");
} }
double quadrupoleValidationTolerance = 1.0e-05; double quadrupoleValidationTolerance = 1.0e-05;
for (int ii = 0; ii < system.getNumParticles(); ii++) { for (int ii = 0; ii < system.getNumParticles(); ii++) {
...@@ -170,7 +170,7 @@ void AmoebaMultipoleForceImpl::getCovalentRange(const AmoebaMultipoleForce& forc ...@@ -170,7 +170,7 @@ void AmoebaMultipoleForceImpl::getCovalentRange(const AmoebaMultipoleForce& forc
*maxCovalentIndex = covalentList[ii]; *maxCovalentIndex = covalentList[ii];
} }
} }
} }
return; return;
} }
...@@ -179,14 +179,22 @@ void AmoebaMultipoleForceImpl::getCovalentDegree(const AmoebaMultipoleForce& for ...@@ -179,14 +179,22 @@ void AmoebaMultipoleForceImpl::getCovalentDegree(const AmoebaMultipoleForce& for
const int* CovalentDegrees = AmoebaMultipoleForceImpl::getCovalentDegrees(); const int* CovalentDegrees = AmoebaMultipoleForceImpl::getCovalentDegrees();
for (unsigned int kk = 0; kk < AmoebaMultipoleForce::CovalentEnd; kk++) { for (unsigned int kk = 0; kk < AmoebaMultipoleForce::CovalentEnd; kk++) {
covalentDegree[kk] = CovalentDegrees[kk]; covalentDegree[kk] = CovalentDegrees[kk];
} }
return; return;
} }
void AmoebaMultipoleForceImpl::getLabFramePermanentDipoles(ContextImpl& context, vector<Vec3>& dipoles) {
kernel.getAs<CalcAmoebaMultipoleForceKernel>().getLabFramePermanentDipoles(context, dipoles);
}
void AmoebaMultipoleForceImpl::getInducedDipoles(ContextImpl& context, vector<Vec3>& dipoles) { void AmoebaMultipoleForceImpl::getInducedDipoles(ContextImpl& context, vector<Vec3>& dipoles) {
kernel.getAs<CalcAmoebaMultipoleForceKernel>().getInducedDipoles(context, dipoles); kernel.getAs<CalcAmoebaMultipoleForceKernel>().getInducedDipoles(context, dipoles);
} }
void AmoebaMultipoleForceImpl::getTotalDipoles(ContextImpl& context, vector<Vec3>& dipoles) {
kernel.getAs<CalcAmoebaMultipoleForceKernel>().getTotalDipoles(context, dipoles);
}
void AmoebaMultipoleForceImpl::getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, void AmoebaMultipoleForceImpl::getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid,
std::vector< double >& outputElectrostaticPotential) { std::vector< double >& outputElectrostaticPotential) {
kernel.getAs<CalcAmoebaMultipoleForceKernel>().getElectrostaticPotential(context, inputGrid, outputElectrostaticPotential); kernel.getAs<CalcAmoebaMultipoleForceKernel>().getElectrostaticPotential(context, inputGrid, outputElectrostaticPotential);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2009 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: * * Authors: *
* Contributors: * * Contributors: *
* * * *
...@@ -102,12 +102,20 @@ void AmoebaVdwForce::getParticleExclusions(int particleIndex, std::vector< int > ...@@ -102,12 +102,20 @@ void AmoebaVdwForce::getParticleExclusions(int particleIndex, std::vector< int >
} }
void AmoebaVdwForce::setCutoff(double inputCutoff) { double AmoebaVdwForce::getCutoffDistance() const {
return cutoff;
}
void AmoebaVdwForce::setCutoffDistance(double inputCutoff) {
cutoff = inputCutoff; cutoff = inputCutoff;
} }
void AmoebaVdwForce::setCutoff(double inputCutoff) {
setCutoffDistance(inputCutoff);
}
double AmoebaVdwForce::getCutoff() const { double AmoebaVdwForce::getCutoff() const {
return cutoff; return getCutoffDistance();
} }
AmoebaVdwForce::NonbondedMethod AmoebaVdwForce::getNonbondedMethod() const { AmoebaVdwForce::NonbondedMethod AmoebaVdwForce::getNonbondedMethod() const {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: * * Authors: *
* Contributors: * * Contributors: *
* * * *
...@@ -62,7 +62,7 @@ void AmoebaVdwForceImpl::initialize(ContextImpl& context) { ...@@ -62,7 +62,7 @@ void AmoebaVdwForceImpl::initialize(ContextImpl& context) {
if (owner.getNonbondedMethod() == AmoebaVdwForce::CutoffPeriodic) { if (owner.getNonbondedMethod() == AmoebaVdwForce::CutoffPeriodic) {
Vec3 boxVectors[3]; Vec3 boxVectors[3];
system.getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); system.getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]);
double cutoff = owner.getCutoff(); double cutoff = owner.getCutoffDistance();
if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2]) if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2])
throw OpenMMException("AmoebaVdwForce: The cutoff distance cannot be greater than half the periodic box size."); throw OpenMMException("AmoebaVdwForce: The cutoff distance cannot be greater than half the periodic box size.");
} }
...@@ -103,7 +103,7 @@ double AmoebaVdwForceImpl::calcDispersionCorrection(const System& system, const ...@@ -103,7 +103,7 @@ double AmoebaVdwForceImpl::calcDispersionCorrection(const System& system, const
} }
// Compute the VdW tapering coefficients. Mostly copied from amoebaCudaGpu.cpp. // Compute the VdW tapering coefficients. Mostly copied from amoebaCudaGpu.cpp.
double cutoff = force.getCutoff(); double cutoff = force.getCutoffDistance();
double vdwTaper = 0.90; // vdwTaper is a scaling factor, it is not a distance. double vdwTaper = 0.90; // vdwTaper is a scaling factor, it is not a distance.
double c0 = 0.0; double c0 = 0.0;
double c1 = 0.0; double c1 = 0.0;
......
...@@ -1146,11 +1146,10 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const ...@@ -1146,11 +1146,10 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const
coefficients << cu.doubleToString(sum); coefficients << cu.doubleToString(sum);
} }
defines["EXTRAPOLATION_COEFFICIENTS_SUM"] = coefficients.str(); defines["EXTRAPOLATION_COEFFICIENTS_SUM"] = coefficients.str();
alpha = force.getAEwald();
if (usePME) { if (usePME) {
vector<int> pmeGridDimension; int nx, ny, nz;
force.getPmeGridDimensions(pmeGridDimension); force.getPMEParameters(alpha, nx, ny, nz);
if (pmeGridDimension[0] == 0 || alpha == 0.0) { if (nx == 0 || alpha == 0.0) {
NonbondedForce nb; NonbondedForce nb;
nb.setEwaldErrorTolerance(force.getEwaldErrorTolerance()); nb.setEwaldErrorTolerance(force.getEwaldErrorTolerance());
nb.setCutoffDistance(force.getCutoffDistance()); nb.setCutoffDistance(force.getCutoffDistance());
...@@ -1159,9 +1158,9 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const ...@@ -1159,9 +1158,9 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const
gridSizeY = CudaFFT3D::findLegalDimension(gridSizeY); gridSizeY = CudaFFT3D::findLegalDimension(gridSizeY);
gridSizeZ = CudaFFT3D::findLegalDimension(gridSizeZ); gridSizeZ = CudaFFT3D::findLegalDimension(gridSizeZ);
} else { } else {
gridSizeX = CudaFFT3D::findLegalDimension(pmeGridDimension[0]); gridSizeX = CudaFFT3D::findLegalDimension(nx);
gridSizeY = CudaFFT3D::findLegalDimension(pmeGridDimension[1]); gridSizeY = CudaFFT3D::findLegalDimension(ny);
gridSizeZ = CudaFFT3D::findLegalDimension(pmeGridDimension[2]); gridSizeZ = CudaFFT3D::findLegalDimension(nz);
} }
defines["EWALD_ALPHA"] = cu.doubleToString(alpha); defines["EWALD_ALPHA"] = cu.doubleToString(alpha);
defines["SQRT_PI"] = cu.doubleToString(sqrt(M_PI)); defines["SQRT_PI"] = cu.doubleToString(sqrt(M_PI));
...@@ -1993,6 +1992,27 @@ void CudaCalcAmoebaMultipoleForceKernel::ensureMultipolesValid(ContextImpl& cont ...@@ -1993,6 +1992,27 @@ void CudaCalcAmoebaMultipoleForceKernel::ensureMultipolesValid(ContextImpl& cont
context.calcForcesAndEnergy(false, false, -1); context.calcForcesAndEnergy(false, false, -1);
} }
void CudaCalcAmoebaMultipoleForceKernel::getLabFramePermanentDipoles(ContextImpl& context, vector<Vec3>& dipoles) {
ensureMultipolesValid(context);
int numParticles = cu.getNumAtoms();
dipoles.resize(numParticles);
const vector<int>& order = cu.getAtomIndex();
if (cu.getUseDoublePrecision()) {
vector<double> labDipoleVec;
labFrameDipoles->download(labDipoleVec);
for (int i = 0; i < numParticles; i++)
dipoles[order[i]] = Vec3(labDipoleVec[3*i], labDipoleVec[3*i+1], labDipoleVec[3*i+2]);
}
else {
vector<float> labDipoleVec;
labFrameDipoles->download(labDipoleVec);
for (int i = 0; i < numParticles; i++)
dipoles[order[i]] = Vec3(labDipoleVec[3*i], labDipoleVec[3*i+1], labDipoleVec[3*i+2]);
}
}
void CudaCalcAmoebaMultipoleForceKernel::getInducedDipoles(ContextImpl& context, vector<Vec3>& dipoles) { void CudaCalcAmoebaMultipoleForceKernel::getInducedDipoles(ContextImpl& context, vector<Vec3>& dipoles) {
ensureMultipolesValid(context); ensureMultipolesValid(context);
int numParticles = cu.getNumAtoms(); int numParticles = cu.getNumAtoms();
...@@ -2012,6 +2032,48 @@ void CudaCalcAmoebaMultipoleForceKernel::getInducedDipoles(ContextImpl& context, ...@@ -2012,6 +2032,48 @@ void CudaCalcAmoebaMultipoleForceKernel::getInducedDipoles(ContextImpl& context,
} }
} }
void CudaCalcAmoebaMultipoleForceKernel::getTotalDipoles(ContextImpl& context, vector<Vec3>& dipoles) {
ensureMultipolesValid(context);
int numParticles = cu.getNumAtoms();
dipoles.resize(numParticles);
const vector<int>& order = cu.getAtomIndex();
if (cu.getUseDoublePrecision()) {
vector<double4> posqVec;
vector<double> labDipoleVec;
vector<double> inducedDipoleVec;
double totalDipoleVecX;
double totalDipoleVecY;
double totalDipoleVecZ;
inducedDipole->download(inducedDipoleVec);
labFrameDipoles->download(labDipoleVec);
cu.getPosq().download(posqVec);
for (int i = 0; i < numParticles; i++) {
totalDipoleVecX = labDipoleVec[3*i] + inducedDipoleVec[3*i];
totalDipoleVecY = labDipoleVec[3*i+1] + inducedDipoleVec[3*i+1];
totalDipoleVecZ = labDipoleVec[3*i+2] + inducedDipoleVec[3*i+2];
dipoles[order[i]] = Vec3(totalDipoleVecX, totalDipoleVecY, totalDipoleVecZ);
}
}
else {
vector<float4> posqVec;
vector<float> labDipoleVec;
vector<float> inducedDipoleVec;
float totalDipoleVecX;
float totalDipoleVecY;
float totalDipoleVecZ;
inducedDipole->download(inducedDipoleVec);
labFrameDipoles->download(labDipoleVec);
cu.getPosq().download(posqVec);
for (int i = 0; i < numParticles; i++) {
totalDipoleVecX = labDipoleVec[3*i] + inducedDipoleVec[3*i];
totalDipoleVecY = labDipoleVec[3*i+1] + inducedDipoleVec[3*i+1];
totalDipoleVecZ = labDipoleVec[3*i+2] + inducedDipoleVec[3*i+2];
dipoles[order[i]] = Vec3(totalDipoleVecX, totalDipoleVecY, totalDipoleVecZ);
}
}
}
void CudaCalcAmoebaMultipoleForceKernel::getElectrostaticPotential(ContextImpl& context, const vector<Vec3>& inputGrid, vector<double>& outputElectrostaticPotential) { void CudaCalcAmoebaMultipoleForceKernel::getElectrostaticPotential(ContextImpl& context, const vector<Vec3>& inputGrid, vector<double>& outputElectrostaticPotential) {
ensureMultipolesValid(context); ensureMultipolesValid(context);
int numPoints = inputGrid.size(); int numPoints = inputGrid.size();
...@@ -2165,6 +2227,7 @@ void CudaCalcAmoebaMultipoleForceKernel::computeSystemMultipoleMoments(ContextIm ...@@ -2165,6 +2227,7 @@ void CudaCalcAmoebaMultipoleForceKernel::computeSystemMultipoleMoments(ContextIm
outputMultipoleMoments[12] = 100.0*zzqdp*debye; outputMultipoleMoments[12] = 100.0*zzqdp*debye;
} }
void CudaCalcAmoebaMultipoleForceKernel::getSystemMultipoleMoments(ContextImpl& context, vector<double>& outputMultipoleMoments) { void CudaCalcAmoebaMultipoleForceKernel::getSystemMultipoleMoments(ContextImpl& context, vector<double>& outputMultipoleMoments) {
ensureMultipolesValid(context); ensureMultipolesValid(context);
if (cu.getUseDoublePrecision()) if (cu.getUseDoublePrecision())
...@@ -2601,15 +2664,15 @@ void CudaCalcAmoebaVdwForceKernel::initialize(const System& system, const Amoeba ...@@ -2601,15 +2664,15 @@ void CudaCalcAmoebaVdwForceKernel::initialize(const System& system, const Amoeba
replacements["EPSILON_COMBINING_RULE"] = "4"; replacements["EPSILON_COMBINING_RULE"] = "4";
else else
throw OpenMMException("Illegal combining rule for sigma: "+sigmaCombiningRule); throw OpenMMException("Illegal combining rule for sigma: "+sigmaCombiningRule);
double cutoff = force.getCutoff(); double cutoff = force.getCutoffDistance();
double taperCutoff = cutoff*0.9; double taperCutoff = cutoff*0.9;
replacements["CUTOFF_DISTANCE"] = cu.doubleToString(force.getCutoff()); replacements["CUTOFF_DISTANCE"] = cu.doubleToString(force.getCutoffDistance());
replacements["TAPER_CUTOFF"] = cu.doubleToString(taperCutoff); replacements["TAPER_CUTOFF"] = cu.doubleToString(taperCutoff);
replacements["TAPER_C3"] = cu.doubleToString(10/pow(taperCutoff-cutoff, 3.0)); replacements["TAPER_C3"] = cu.doubleToString(10/pow(taperCutoff-cutoff, 3.0));
replacements["TAPER_C4"] = cu.doubleToString(15/pow(taperCutoff-cutoff, 4.0)); replacements["TAPER_C4"] = cu.doubleToString(15/pow(taperCutoff-cutoff, 4.0));
replacements["TAPER_C5"] = cu.doubleToString(6/pow(taperCutoff-cutoff, 5.0)); replacements["TAPER_C5"] = cu.doubleToString(6/pow(taperCutoff-cutoff, 5.0));
bool useCutoff = (force.getNonbondedMethod() != AmoebaVdwForce::NoCutoff); bool useCutoff = (force.getNonbondedMethod() != AmoebaVdwForce::NoCutoff);
nonbonded->addInteraction(useCutoff, useCutoff, true, force.getCutoff(), exclusions, nonbonded->addInteraction(useCutoff, useCutoff, true, force.getCutoffDistance(), exclusions,
cu.replaceStrings(CudaAmoebaKernelSources::amoebaVdwForce2, replacements), 0); cu.replaceStrings(CudaAmoebaKernelSources::amoebaVdwForce2, replacements), 0);
// Create the other kernels. // Create the other kernels.
......
...@@ -328,6 +328,13 @@ public: ...@@ -328,6 +328,13 @@ public:
* @return the potential energy due to the force * @return the potential energy due to the force
*/ */
double execute(ContextImpl& context, bool includeForces, bool includeEnergy); double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
/**
* Get the LabFrame dipole moments of all particles.
*
* @param context the Context for which to get the induced dipoles
* @param dipoles the induced dipole moment of particle i is stored into the i'th element
*/
void getLabFramePermanentDipoles(ContextImpl& context, std::vector<Vec3>& dipoles);
/** /**
* Get the induced dipole moments of all particles. * Get the induced dipole moments of all particles.
* *
...@@ -335,6 +342,13 @@ public: ...@@ -335,6 +342,13 @@ public:
* @param dipoles the induced dipole moment of particle i is stored into the i'th element * @param dipoles the induced dipole moment of particle i is stored into the i'th element
*/ */
void getInducedDipoles(ContextImpl& context, std::vector<Vec3>& dipoles); void getInducedDipoles(ContextImpl& context, std::vector<Vec3>& dipoles);
/**
* Get the total dipole moments of all particles.
*
* @param context the Context for which to get the induced dipoles
* @param dipoles the induced dipole moment of particle i is stored into the i'th element
*/
void getTotalDipoles(ContextImpl& context, std::vector<Vec3>& dipoles);
/** /**
* Execute the kernel to calculate the electrostatic potential * Execute the kernel to calculate the electrostatic potential
* *
......
...@@ -488,6 +488,8 @@ extern "C" __global__ void computeElectrostatics( ...@@ -488,6 +488,8 @@ extern "C" __global__ void computeElectrostatics(
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
const unsigned int numTiles = interactionCount[0]; const unsigned int numTiles = interactionCount[0];
if (numTiles > maxTiles)
return; // There wasn't enough memory for the neighbor list.
int pos = (int) (numTiles > maxTiles ? startTileIndex+warp*(long long)numTileIndices/totalWarps : warp*(long long)numTiles/totalWarps); int pos = (int) (numTiles > maxTiles ? startTileIndex+warp*(long long)numTileIndices/totalWarps : warp*(long long)numTiles/totalWarps);
int end = (int) (numTiles > maxTiles ? startTileIndex+(warp+1)*(long long)numTileIndices/totalWarps : (warp+1)*(long long)numTiles/totalWarps); int end = (int) (numTiles > maxTiles ? startTileIndex+(warp+1)*(long long)numTileIndices/totalWarps : (warp+1)*(long long)numTiles/totalWarps);
#else #else
...@@ -508,34 +510,31 @@ extern "C" __global__ void computeElectrostatics( ...@@ -508,34 +510,31 @@ extern "C" __global__ void computeElectrostatics(
int x, y; int x, y;
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
if (numTiles <= maxTiles) x = tiles[pos];
x = tiles[pos]; #else
else y = (int) floor(NUM_BLOCKS+0.5f-SQRT((NUM_BLOCKS+0.5f)*(NUM_BLOCKS+0.5f)-2*pos));
#endif x = (pos-y*NUM_BLOCKS+y*(y+1)/2);
{ if (x < y || x >= NUM_BLOCKS) { // Occasionally happens due to roundoff error.
y = (int) floor(NUM_BLOCKS+0.5f-SQRT((NUM_BLOCKS+0.5f)*(NUM_BLOCKS+0.5f)-2*pos)); y += (x < y ? -1 : 1);
x = (pos-y*NUM_BLOCKS+y*(y+1)/2); x = (pos-y*NUM_BLOCKS+y*(y+1)/2);
if (x < y || x >= NUM_BLOCKS) { // Occasionally happens due to roundoff error. }
y += (x < y ? -1 : 1);
x = (pos-y*NUM_BLOCKS+y*(y+1)/2);
}
// Skip over tiles that have exclusions, since they were already processed. // Skip over tiles that have exclusions, since they were already processed.
while (skipTiles[tbx+TILE_SIZE-1] < pos) { while (skipTiles[tbx+TILE_SIZE-1] < pos) {
if (skipBase+tgx < NUM_TILES_WITH_EXCLUSIONS) { if (skipBase+tgx < NUM_TILES_WITH_EXCLUSIONS) {
ushort2 tile = exclusionTiles[skipBase+tgx]; ushort2 tile = exclusionTiles[skipBase+tgx];
skipTiles[threadIdx.x] = tile.x + tile.y*NUM_BLOCKS - tile.y*(tile.y+1)/2; skipTiles[threadIdx.x] = tile.x + tile.y*NUM_BLOCKS - tile.y*(tile.y+1)/2;
}
else
skipTiles[threadIdx.x] = end;
skipBase += TILE_SIZE;
currentSkipIndex = tbx;
} }
while (skipTiles[currentSkipIndex] < pos) else
currentSkipIndex++; skipTiles[threadIdx.x] = end;
includeTile = (skipTiles[currentSkipIndex] != pos); skipBase += TILE_SIZE;
currentSkipIndex = tbx;
} }
while (skipTiles[currentSkipIndex] < pos)
currentSkipIndex++;
includeTile = (skipTiles[currentSkipIndex] != pos);
#endif
if (includeTile) { if (includeTile) {
unsigned int atom1 = x*TILE_SIZE + tgx; unsigned int atom1 = x*TILE_SIZE + tgx;
......
...@@ -592,6 +592,8 @@ extern "C" __global__ void computeFixedField( ...@@ -592,6 +592,8 @@ extern "C" __global__ void computeFixedField(
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
const unsigned int numTiles = interactionCount[0]; const unsigned int numTiles = interactionCount[0];
if (numTiles > maxTiles)
return; // There wasn't enough memory for the neighbor list.
int pos = (int) (numTiles > maxTiles ? startTileIndex+warp*(long long)numTileIndices/totalWarps : warp*(long long)numTiles/totalWarps); int pos = (int) (numTiles > maxTiles ? startTileIndex+warp*(long long)numTileIndices/totalWarps : warp*(long long)numTiles/totalWarps);
int end = (int) (numTiles > maxTiles ? startTileIndex+(warp+1)*(long long)numTileIndices/totalWarps : (warp+1)*(long long)numTiles/totalWarps); int end = (int) (numTiles > maxTiles ? startTileIndex+(warp+1)*(long long)numTileIndices/totalWarps : (warp+1)*(long long)numTiles/totalWarps);
#else #else
...@@ -612,34 +614,31 @@ extern "C" __global__ void computeFixedField( ...@@ -612,34 +614,31 @@ extern "C" __global__ void computeFixedField(
int x, y; int x, y;
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
if (numTiles <= maxTiles) x = tiles[pos];
x = tiles[pos]; #else
else y = (int) floor(NUM_BLOCKS+0.5f-SQRT((NUM_BLOCKS+0.5f)*(NUM_BLOCKS+0.5f)-2*pos));
#endif x = (pos-y*NUM_BLOCKS+y*(y+1)/2);
{ if (x < y || x >= NUM_BLOCKS) { // Occasionally happens due to roundoff error.
y = (int) floor(NUM_BLOCKS+0.5f-SQRT((NUM_BLOCKS+0.5f)*(NUM_BLOCKS+0.5f)-2*pos)); y += (x < y ? -1 : 1);
x = (pos-y*NUM_BLOCKS+y*(y+1)/2); x = (pos-y*NUM_BLOCKS+y*(y+1)/2);
if (x < y || x >= NUM_BLOCKS) { // Occasionally happens due to roundoff error. }
y += (x < y ? -1 : 1);
x = (pos-y*NUM_BLOCKS+y*(y+1)/2);
}
// Skip over tiles that have exclusions, since they were already processed. // Skip over tiles that have exclusions, since they were already processed.
while (skipTiles[tbx+TILE_SIZE-1] < pos) { while (skipTiles[tbx+TILE_SIZE-1] < pos) {
if (skipBase+tgx < NUM_TILES_WITH_EXCLUSIONS) { if (skipBase+tgx < NUM_TILES_WITH_EXCLUSIONS) {
ushort2 tile = exclusionTiles[skipBase+tgx]; ushort2 tile = exclusionTiles[skipBase+tgx];
skipTiles[threadIdx.x] = tile.x + tile.y*NUM_BLOCKS - tile.y*(tile.y+1)/2; skipTiles[threadIdx.x] = tile.x + tile.y*NUM_BLOCKS - tile.y*(tile.y+1)/2;
}
else
skipTiles[threadIdx.x] = end;
skipBase += TILE_SIZE;
currentSkipIndex = tbx;
} }
while (skipTiles[currentSkipIndex] < pos) else
currentSkipIndex++; skipTiles[threadIdx.x] = end;
includeTile = (skipTiles[currentSkipIndex] != pos); skipBase += TILE_SIZE;
currentSkipIndex = tbx;
} }
while (skipTiles[currentSkipIndex] < pos)
currentSkipIndex++;
includeTile = (skipTiles[currentSkipIndex] != pos);
#endif
if (includeTile) { if (includeTile) {
unsigned int atom1 = x*TILE_SIZE + tgx; unsigned int atom1 = x*TILE_SIZE + tgx;
......
...@@ -454,6 +454,8 @@ extern "C" __global__ void computeInducedField( ...@@ -454,6 +454,8 @@ extern "C" __global__ void computeInducedField(
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
const unsigned int numTiles = interactionCount[0]; const unsigned int numTiles = interactionCount[0];
if (numTiles > maxTiles)
return; // There wasn't enough memory for the neighbor list.
int pos = (int) (numTiles > maxTiles ? startTileIndex+warp*(long long)numTileIndices/totalWarps : warp*(long long)numTiles/totalWarps); int pos = (int) (numTiles > maxTiles ? startTileIndex+warp*(long long)numTileIndices/totalWarps : warp*(long long)numTiles/totalWarps);
int end = (int) (numTiles > maxTiles ? startTileIndex+(warp+1)*(long long)numTileIndices/totalWarps : (warp+1)*(long long)numTiles/totalWarps); int end = (int) (numTiles > maxTiles ? startTileIndex+(warp+1)*(long long)numTileIndices/totalWarps : (warp+1)*(long long)numTiles/totalWarps);
#else #else
...@@ -474,34 +476,31 @@ extern "C" __global__ void computeInducedField( ...@@ -474,34 +476,31 @@ extern "C" __global__ void computeInducedField(
int x, y; int x, y;
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
if (numTiles <= maxTiles) x = tiles[pos];
x = tiles[pos]; #else
else y = (int) floor(NUM_BLOCKS+0.5f-SQRT((NUM_BLOCKS+0.5f)*(NUM_BLOCKS+0.5f)-2*pos));
#endif x = (pos-y*NUM_BLOCKS+y*(y+1)/2);
{ if (x < y || x >= NUM_BLOCKS) { // Occasionally happens due to roundoff error.
y = (int) floor(NUM_BLOCKS+0.5f-SQRT((NUM_BLOCKS+0.5f)*(NUM_BLOCKS+0.5f)-2*pos)); y += (x < y ? -1 : 1);
x = (pos-y*NUM_BLOCKS+y*(y+1)/2); x = (pos-y*NUM_BLOCKS+y*(y+1)/2);
if (x < y || x >= NUM_BLOCKS) { // Occasionally happens due to roundoff error. }
y += (x < y ? -1 : 1);
x = (pos-y*NUM_BLOCKS+y*(y+1)/2);
}
// Skip over tiles that have exclusions, since they were already processed. // Skip over tiles that have exclusions, since they were already processed.
while (skipTiles[tbx+TILE_SIZE-1] < pos) { while (skipTiles[tbx+TILE_SIZE-1] < pos) {
if (skipBase+tgx < NUM_TILES_WITH_EXCLUSIONS) { if (skipBase+tgx < NUM_TILES_WITH_EXCLUSIONS) {
ushort2 tile = exclusionTiles[skipBase+tgx]; ushort2 tile = exclusionTiles[skipBase+tgx];
skipTiles[threadIdx.x] = tile.x + tile.y*NUM_BLOCKS - tile.y*(tile.y+1)/2; skipTiles[threadIdx.x] = tile.x + tile.y*NUM_BLOCKS - tile.y*(tile.y+1)/2;
}
else
skipTiles[threadIdx.x] = end;
skipBase += TILE_SIZE;
currentSkipIndex = tbx;
} }
while (skipTiles[currentSkipIndex] < pos) else
currentSkipIndex++; skipTiles[threadIdx.x] = end;
includeTile = (skipTiles[currentSkipIndex] != pos); skipBase += TILE_SIZE;
currentSkipIndex = tbx;
} }
while (skipTiles[currentSkipIndex] < pos)
currentSkipIndex++;
includeTile = (skipTiles[currentSkipIndex] != pos);
#endif
if (includeTile) { if (includeTile) {
unsigned int atom1 = x*TILE_SIZE + tgx; unsigned int atom1 = x*TILE_SIZE + tgx;
......
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