Unverified Commit bb3073d4 authored by Peter Eastman's avatar Peter Eastman Committed by GitHub
Browse files

Virtual site for symmetric molecules (#4185)

* Reference implementation of SymmetrySite

* Common implementation of SymmetrySite

* Removed duplicated code

* Serialization for SymmetrySite

* Fixed compilation error building C wrapper

* Added SymmetrySite to user guide

* Bug fix

* Added P21 test case
parent b6196754
...@@ -38,6 +38,7 @@ class that the other classes extend. ...@@ -38,6 +38,7 @@ class that the other classes extend.
generated/OutOfPlaneSite generated/OutOfPlaneSite
generated/ThreeParticleAverageSite generated/ThreeParticleAverageSite
generated/TwoParticleAverageSite generated/TwoParticleAverageSite
generated/SymmetrySite
Serialization Serialization
============= =============
......
...@@ -191,6 +191,21 @@ specific types of rules. They are: ...@@ -191,6 +191,21 @@ specific types of rules. They are:
\mathbf{r}=\mathbf{o}+p_1\mathbf{\hat{x}}+p_2\mathbf{\hat{y}}+p_3\mathbf{\hat{z}} \mathbf{r}=\mathbf{o}+p_1\mathbf{\hat{x}}+p_2\mathbf{\hat{y}}+p_3\mathbf{\hat{z}}
.. ..
* SymmetrySite: The virtual site location is computed by applying a rotation and
translation to the position of a single other particle:
.. math::
\mathbf{r}=\mathbf{R} \mathbf{r}_0 + \mathbf{v}
..
where :math:`\mathbf{r}_0` is the position of the original particle,
:math:`\mathbf{R}` is a rotation matrix, and :math:`\mathbf{v}` is a fixed
vector. The calculation can be performed either in Cartesian coordinates (for
example, to build a symmetric copy of a molecule to create a dimer) or in
fractional coordinates as defined by the periodic box (for example, to create
a crystallographic unit cell consisting of multiple identical molecules
related by symmetry).
Random Numbers with Stochastic Integrators and Forces Random Numbers with Stochastic Integrators and Forces
***************************************************** *****************************************************
......
...@@ -257,6 +257,66 @@ private: ...@@ -257,6 +257,66 @@ private:
Vec3 localPosition; Vec3 localPosition;
}; };
/**
* This is a VirtualSite that applies a rotation and translation to the position of
* a single other particle. It is useful for creating multiple copies of a molecule
* that are symmetrically arranged either with respect to each other or to the
* periodic box.
*
* The transformation is defined by a rotation matrix R (specified by its rows Rx, Ry, and Rz).
* and a translation vector v. The position r' of the virtual site is computed from the
* position r of the original particle as
*
* r'<sub>x</sub> = Rx<sub>x</sub>r<sub>x</sub> + Rx<sub>y</sub>r<sub>y</sub> + Rx<sub>z</sub>r<sub>z</sub> + v<sub>x</sub>
*
* r'<sub>x</sub> = Ry<sub>y</sub>r<sub>x</sub> + Ry<sub>y</sub>r<sub>y</sub> + Ry<sub>z</sub>r<sub>z</sub> + v<sub>y</sub>
*
* r'<sub>x</sub> = Rz<sub>z</sub>r<sub>x</sub> + Rz<sub>y</sub>r<sub>y</sub> + Rz<sub>z</sub>r<sub>z</sub> + v<sub>z</sub>
*
* It can be applied in two different modes. When useBoxVectors is false the transformation
* is performed in Cartesian coordinates. When useBoxVectors is true it is performed in
* fractional coordinates as defined by the periodic box, which means that v acts as a set
* of scale factors for the periodic box vectors. This latter mode is convenient for building
* crystallographic unit cells composed of multiple symmetric molecules. It should be used
* with care: if R represents a rotation by any angle other than 0 or 180 degrees, performing
* the rotation in fractional coordinates can distort the molecule.
*/
class OPENMM_EXPORT SymmetrySite : public VirtualSite {
public:
/**
* Create a new SymmetrySite virtual site.
*
* The arguments Rx, Ry, and Rz must form an orthogonal matrix (its transpose is its inverse).
*
* @param particle the index of the particle the site depends on
* @param Rx the first row of the rotation matrix
* @param Ry the second row of the rotation matrix
* @param Rz the third row of the rotation matrix
* @param v the offset vector
* @param useBoxVectors specifies whether the transformation is performed in Cartesian or fractional coordinates
*/
SymmetrySite(int particle, const Vec3& Rx, const Vec3& Ry, const Vec3& Rz, const Vec3& v, bool useBoxVectors);
/**
* Get the rotation matrix.
*
* @param Rx the first row of the rotation matrix
* @param Ry the second row of the rotation matrix
* @param Rz the third row of the rotation matrix
*/
void getRotationMatrix(Vec3& Rx, Vec3& Ry, Vec3& Rz) const;
/**
* Get the offset vector.
*/
const Vec3& getOffsetVector() const;
/**
* Get whether whether the transformation is performed in Cartesian or fractional coordinates.
*/
bool getUseBoxVectors() const;
private:
Vec3 Rx, Ry, Rz, v;
bool useBoxVectors;
};
} // namespace OpenMM } // namespace OpenMM
#endif /*OPENMM_VIRTUALSITE_H_*/ #endif /*OPENMM_VIRTUALSITE_H_*/
...@@ -184,3 +184,29 @@ Vec3 LocalCoordinatesSite::getYWeights() const { ...@@ -184,3 +184,29 @@ Vec3 LocalCoordinatesSite::getYWeights() const {
const Vec3& LocalCoordinatesSite::getLocalPosition() const { const Vec3& LocalCoordinatesSite::getLocalPosition() const {
return localPosition; return localPosition;
} }
SymmetrySite::SymmetrySite(int particle, const Vec3& Rx, const Vec3& Ry, const Vec3& Rz, const Vec3& v, bool useBoxVectors) :
Rx(Rx), Ry(Ry), Rz(Rz), v(v), useBoxVectors(useBoxVectors) {
setParticles({particle});
Vec3 R[] = {Rx, Ry, Rz};
for (int i = 0; i < 3; i++)
for (int j = i; j < 3; j++) {
double dot = R[i].dot(R[j]);
if ((i == j && fabs(dot-1) > 1e-6) || (i != j && fabs(dot) > 1e-6))
throw OpenMMException("SymmetrySite: The rotation matrix must be orthogonal");
}
}
void SymmetrySite::getRotationMatrix(Vec3& Rx, Vec3& Ry, Vec3& Rz) const {
Rx = this->Rx;
Ry = this->Ry;
Rz = this->Rz;
}
const Vec3& SymmetrySite::getOffsetVector() const {
return v;
}
bool SymmetrySite::getUseBoxVectors() const {
return useBoxVectors;
}
...@@ -488,6 +488,10 @@ public: ...@@ -488,6 +488,10 @@ public:
* Set the vectors defining the periodic box. * Set the vectors defining the periodic box.
*/ */
virtual void setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3& c) = 0; virtual void setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3& c) = 0;
/**
* Compute the reciprocal space box vectors.
*/
void computeReciprocalBoxVectors(mm_double4 recipBoxVectors[3]);
/** /**
* Get the IntegrationUtilities for this context. * Get the IntegrationUtilities for this context.
*/ */
......
...@@ -165,17 +165,12 @@ protected: ...@@ -165,17 +165,12 @@ protected:
ComputeArray ccmaDelta1; ComputeArray ccmaDelta1;
ComputeArray ccmaDelta2; ComputeArray ccmaDelta2;
ComputeArray ccmaConverged; ComputeArray ccmaConverged;
ComputeArray vsite2AvgAtoms; ComputeArray vsite2AvgAtoms, vsite2AvgWeights;
ComputeArray vsite2AvgWeights; ComputeArray vsite3AvgAtoms, vsite3AvgWeights;
ComputeArray vsite3AvgAtoms; ComputeArray vsiteOutOfPlaneAtoms, vsiteOutOfPlaneWeights;
ComputeArray vsite3AvgWeights; ComputeArray vsiteLocalCoordsIndex, vsiteLocalCoordsAtoms, vsiteLocalCoordsWeights;
ComputeArray vsiteOutOfPlaneAtoms; ComputeArray vsiteLocalCoordsPos, vsiteLocalCoordsStartIndex;
ComputeArray vsiteOutOfPlaneWeights; ComputeArray vsiteSymmetryAtoms, vsiteSymmetryMatrix, vsiteSymmetryOffset, vsiteSymmetryUseBox;
ComputeArray vsiteLocalCoordsIndex;
ComputeArray vsiteLocalCoordsAtoms;
ComputeArray vsiteLocalCoordsWeights;
ComputeArray vsiteLocalCoordsPos;
ComputeArray vsiteLocalCoordsStartIndex;
ComputeArray vsiteStage; ComputeArray vsiteStage;
ComputeArray kineticEnergy; ComputeArray kineticEnergy;
int randomPos, lastSeed, numVsites, numVsiteStages, keWorkGroupSize; int randomPos, lastSeed, numVsites, numVsiteStages, keWorkGroupSize;
......
...@@ -136,6 +136,17 @@ string ComputeContext::intToString(int value) const { ...@@ -136,6 +136,17 @@ string ComputeContext::intToString(int value) const {
return s.str(); return s.str();
} }
void ComputeContext::computeReciprocalBoxVectors(mm_double4 recipBoxVectors[3]) {
Vec3 boxVectors[3];
getPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]);
double determinant = boxVectors[0][0]*boxVectors[1][1]*boxVectors[2][2];
assert(determinant > 0);
double scale = 1.0/determinant;
recipBoxVectors[0] = mm_double4(boxVectors[1][1]*boxVectors[2][2]*scale, 0, 0, 0);
recipBoxVectors[1] = mm_double4(-boxVectors[1][0]*boxVectors[2][2]*scale, boxVectors[0][0]*boxVectors[2][2]*scale, 0, 0);
recipBoxVectors[2] = mm_double4((boxVectors[1][0]*boxVectors[2][1]-boxVectors[1][1]*boxVectors[2][0])*scale, -boxVectors[0][0]*boxVectors[2][1]*scale, boxVectors[0][0]*boxVectors[1][1]*scale, 0);
}
/** /**
* This class ensures that atom reordering doesn't break virtual sites. * This class ensures that atom reordering doesn't break virtual sites.
*/ */
...@@ -175,6 +186,20 @@ public: ...@@ -175,6 +186,20 @@ public:
weights.push_back(site.getWeight13()); weights.push_back(site.getWeight13());
weights.push_back(site.getWeightCross()); weights.push_back(site.getWeightCross());
} }
else if (dynamic_cast<const SymmetrySite*>(&vsite) != NULL) {
// An out of plane site.
const SymmetrySite& site = dynamic_cast<const SymmetrySite&>(vsite);
Vec3 Rx, Ry, Rz, offset;
site.getRotationMatrix(Rx, Ry, Rz);
offset = site.getOffsetVector();
for (int j = 0; j < 3; j++) {
weights.push_back(Rx[j]);
weights.push_back(Ry[j]);
weights.push_back(Rz[j]);
weights.push_back(offset[j]);
}
}
siteWeights.push_back(weights); siteWeights.push_back(weights);
} }
} }
......
...@@ -437,6 +437,10 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System ...@@ -437,6 +437,10 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System
vector<int> vsiteLocalCoordsStartVec; vector<int> vsiteLocalCoordsStartVec;
vector<double> vsiteLocalCoordsWeightVec; vector<double> vsiteLocalCoordsWeightVec;
vector<mm_double4> vsiteLocalCoordsPosVec; vector<mm_double4> vsiteLocalCoordsPosVec;
vector<mm_int2> vsiteSymmetryAtomVec;
vector<mm_double4> vsiteSymmetryMatrixVec;
vector<mm_double4> vsiteSymmetryOffsetVec;
vector<int> vsiteSymmetryUseBoxVec;
for (int i = 0; i < numAtoms; i++) { for (int i = 0; i < numAtoms; i++) {
if (system.isVirtualSite(i)) { if (system.isVirtualSite(i)) {
if (dynamic_cast<const TwoParticleAverageSite*>(&system.getVirtualSite(i)) != NULL) { if (dynamic_cast<const TwoParticleAverageSite*>(&system.getVirtualSite(i)) != NULL) {
...@@ -480,6 +484,20 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System ...@@ -480,6 +484,20 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System
Vec3 pos = site.getLocalPosition(); Vec3 pos = site.getLocalPosition();
vsiteLocalCoordsPosVec.push_back(mm_double4(pos[0], pos[1], pos[2], 0.0)); vsiteLocalCoordsPosVec.push_back(mm_double4(pos[0], pos[1], pos[2], 0.0));
} }
else if (dynamic_cast<const SymmetrySite*>(&system.getVirtualSite(i)) != NULL) {
// A symmetry site.
const SymmetrySite& site = dynamic_cast<const SymmetrySite&>(system.getVirtualSite(i));
vsiteSymmetryAtomVec.push_back(mm_int2(i, site.getParticle(0)));
Vec3 Rx, Ry, Rz;
site.getRotationMatrix(Rx, Ry, Rz);
vsiteSymmetryMatrixVec.push_back(mm_double4(Rx[0], Rx[1], Rx[2], 0.0));
vsiteSymmetryMatrixVec.push_back(mm_double4(Ry[0], Ry[1], Ry[2], 0.0));
vsiteSymmetryMatrixVec.push_back(mm_double4(Rz[0], Rz[1], Rz[2], 0.0));
Vec3 v = site.getOffsetVector();
vsiteSymmetryOffsetVec.push_back(mm_double4(v[0], v[1], v[2], 0.0));
vsiteSymmetryUseBoxVec.push_back(site.getUseBoxVectors() ? 1 : 0);
}
} }
} }
vsiteLocalCoordsStartVec.push_back(vsiteLocalCoordsAtomVec.size()); vsiteLocalCoordsStartVec.push_back(vsiteLocalCoordsAtomVec.size());
...@@ -487,13 +505,15 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System ...@@ -487,13 +505,15 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System
int num3Avg = vsite3AvgAtomVec.size(); int num3Avg = vsite3AvgAtomVec.size();
int numOutOfPlane = vsiteOutOfPlaneAtomVec.size(); int numOutOfPlane = vsiteOutOfPlaneAtomVec.size();
int numLocalCoords = vsiteLocalCoordsPosVec.size(); int numLocalCoords = vsiteLocalCoordsPosVec.size();
numVsites = num2Avg+num3Avg+numOutOfPlane+numLocalCoords; int numSymmetry = vsiteSymmetryAtomVec.size();
numVsites = num2Avg+num3Avg+numOutOfPlane+numLocalCoords+numSymmetry;
vsite2AvgAtoms.initialize<mm_int4>(context, max(1, num2Avg), "vsite2AvgAtoms"); vsite2AvgAtoms.initialize<mm_int4>(context, max(1, num2Avg), "vsite2AvgAtoms");
vsite3AvgAtoms.initialize<mm_int4>(context, max(1, num3Avg), "vsite3AvgAtoms"); vsite3AvgAtoms.initialize<mm_int4>(context, max(1, num3Avg), "vsite3AvgAtoms");
vsiteOutOfPlaneAtoms.initialize<mm_int4>(context, max(1, numOutOfPlane), "vsiteOutOfPlaneAtoms"); vsiteOutOfPlaneAtoms.initialize<mm_int4>(context, max(1, numOutOfPlane), "vsiteOutOfPlaneAtoms");
vsiteLocalCoordsIndex.initialize<int>(context, max(1, (int) vsiteLocalCoordsIndexVec.size()), "vsiteLocalCoordsIndex"); vsiteLocalCoordsIndex.initialize<int>(context, max(1, (int) vsiteLocalCoordsIndexVec.size()), "vsiteLocalCoordsIndex");
vsiteLocalCoordsAtoms.initialize<int>(context, max(1, (int) vsiteLocalCoordsAtomVec.size()), "vsiteLocalCoordsAtoms"); vsiteLocalCoordsAtoms.initialize<int>(context, max(1, (int) vsiteLocalCoordsAtomVec.size()), "vsiteLocalCoordsAtoms");
vsiteLocalCoordsStartIndex.initialize<int>(context, max(1, (int) vsiteLocalCoordsStartVec.size()), "vsiteLocalCoordsStartIndex"); vsiteLocalCoordsStartIndex.initialize<int>(context, max(1, (int) vsiteLocalCoordsStartVec.size()), "vsiteLocalCoordsStartIndex");
vsiteSymmetryAtoms.initialize<mm_int2>(context, max(1, numSymmetry), "vsiteSymmetryAtoms");
if (num2Avg > 0) if (num2Avg > 0)
vsite2AvgAtoms.upload(vsite2AvgAtomVec); vsite2AvgAtoms.upload(vsite2AvgAtomVec);
if (num3Avg > 0) if (num3Avg > 0)
...@@ -505,12 +525,17 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System ...@@ -505,12 +525,17 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System
vsiteLocalCoordsAtoms.upload(vsiteLocalCoordsAtomVec); vsiteLocalCoordsAtoms.upload(vsiteLocalCoordsAtomVec);
vsiteLocalCoordsStartIndex.upload(vsiteLocalCoordsStartVec); vsiteLocalCoordsStartIndex.upload(vsiteLocalCoordsStartVec);
} }
if (numSymmetry > 0)
vsiteSymmetryAtoms.upload(vsiteSymmetryAtomVec);
int elementSize = (context.getUseDoublePrecision() ? sizeof(double) : sizeof(float)); int elementSize = (context.getUseDoublePrecision() ? sizeof(double) : sizeof(float));
vsite2AvgWeights.initialize(context, max(1, num2Avg), 2*elementSize, "vsite2AvgWeights"); vsite2AvgWeights.initialize(context, max(1, num2Avg), 2*elementSize, "vsite2AvgWeights");
vsite3AvgWeights.initialize(context, max(1, num3Avg), 4*elementSize, "vsite3AvgWeights"); vsite3AvgWeights.initialize(context, max(1, num3Avg), 4*elementSize, "vsite3AvgWeights");
vsiteOutOfPlaneWeights.initialize(context, max(1, numOutOfPlane), 4*elementSize, "vsiteOutOfPlaneWeights"); vsiteOutOfPlaneWeights.initialize(context, max(1, numOutOfPlane), 4*elementSize, "vsiteOutOfPlaneWeights");
vsiteLocalCoordsWeights.initialize(context, max(1, (int) vsiteLocalCoordsWeightVec.size()), elementSize, "vsiteLocalCoordsWeights"); vsiteLocalCoordsWeights.initialize(context, max(1, (int) vsiteLocalCoordsWeightVec.size()), elementSize, "vsiteLocalCoordsWeights");
vsiteLocalCoordsPos.initialize(context, max(1, (int) vsiteLocalCoordsPosVec.size()), 4*elementSize, "vsiteLocalCoordsPos"); vsiteLocalCoordsPos.initialize(context, max(1, (int) vsiteLocalCoordsPosVec.size()), 4*elementSize, "vsiteLocalCoordsPos");
vsiteSymmetryMatrix.initialize(context, max(1, 3*numSymmetry), 4*elementSize, "vsiteSymmetryMatrix");
vsiteSymmetryOffset.initialize(context, max(1, numSymmetry), 4*elementSize, "vsiteSymmetryOffset");
vsiteSymmetryUseBox.initialize<int>(context, max(1, numSymmetry), "vsiteSymmetryUseBox");
if (num2Avg > 0) if (num2Avg > 0)
vsite2AvgWeights.upload(vsite2AvgWeightVec, true); vsite2AvgWeights.upload(vsite2AvgWeightVec, true);
if (num3Avg > 0) if (num3Avg > 0)
...@@ -521,6 +546,11 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System ...@@ -521,6 +546,11 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System
vsiteLocalCoordsWeights.upload(vsiteLocalCoordsWeightVec, true); vsiteLocalCoordsWeights.upload(vsiteLocalCoordsWeightVec, true);
vsiteLocalCoordsPos.upload(vsiteLocalCoordsPosVec, true); vsiteLocalCoordsPos.upload(vsiteLocalCoordsPosVec, true);
} }
if (numSymmetry > 0) {
vsiteSymmetryMatrix.upload(vsiteSymmetryMatrixVec, true);
vsiteSymmetryOffset.upload(vsiteSymmetryOffsetVec, true);
vsiteSymmetryUseBox.upload(vsiteSymmetryUseBoxVec);
}
// If multiple virtual sites depend on the same particle, make sure the force distribution // If multiple virtual sites depend on the same particle, make sure the force distribution
// can be done safely. // can be done safely.
...@@ -577,6 +607,7 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System ...@@ -577,6 +607,7 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System
defines["NUM_3_AVERAGE"] = context.intToString(num3Avg); defines["NUM_3_AVERAGE"] = context.intToString(num3Avg);
defines["NUM_OUT_OF_PLANE"] = context.intToString(numOutOfPlane); defines["NUM_OUT_OF_PLANE"] = context.intToString(numOutOfPlane);
defines["NUM_LOCAL_COORDS"] = context.intToString(numLocalCoords); defines["NUM_LOCAL_COORDS"] = context.intToString(numLocalCoords);
defines["NUM_SYMMETRY"] = context.intToString(numSymmetry);
defines["PADDED_NUM_ATOMS"] = context.intToString(context.getPaddedNumAtoms()); defines["PADDED_NUM_ATOMS"] = context.intToString(context.getPaddedNumAtoms());
defines["KE_WORK_GROUP_SIZE"] = context.intToString(keWorkGroupSize); defines["KE_WORK_GROUP_SIZE"] = context.intToString(keWorkGroupSize);
if (hasOverlappingVsites) if (hasOverlappingVsites)
...@@ -619,6 +650,12 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System ...@@ -619,6 +650,12 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System
vsitePositionKernel->addArg(vsiteLocalCoordsWeights); vsitePositionKernel->addArg(vsiteLocalCoordsWeights);
vsitePositionKernel->addArg(vsiteLocalCoordsPos); vsitePositionKernel->addArg(vsiteLocalCoordsPos);
vsitePositionKernel->addArg(vsiteLocalCoordsStartIndex); vsitePositionKernel->addArg(vsiteLocalCoordsStartIndex);
vsitePositionKernel->addArg(vsiteSymmetryAtoms);
vsitePositionKernel->addArg(vsiteSymmetryMatrix);
vsitePositionKernel->addArg(vsiteSymmetryOffset);
vsitePositionKernel->addArg(vsiteSymmetryUseBox);
for (int i = 0; i < 6; i++)
vsitePositionKernel->addArg(); // Arguments for periodic box
vsitePositionKernel->addArg(vsiteStage); vsitePositionKernel->addArg(vsiteStage);
vsitePositionKernel->addArg(); vsitePositionKernel->addArg();
vsiteForceKernel->addArg(context.getPosq()); vsiteForceKernel->addArg(context.getPosq());
...@@ -638,6 +675,12 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System ...@@ -638,6 +675,12 @@ IntegrationUtilities::IntegrationUtilities(ComputeContext& context, const System
vsiteForceKernel->addArg(vsiteLocalCoordsWeights); vsiteForceKernel->addArg(vsiteLocalCoordsWeights);
vsiteForceKernel->addArg(vsiteLocalCoordsPos); vsiteForceKernel->addArg(vsiteLocalCoordsPos);
vsiteForceKernel->addArg(vsiteLocalCoordsStartIndex); vsiteForceKernel->addArg(vsiteLocalCoordsStartIndex);
vsiteForceKernel->addArg(vsiteSymmetryAtoms);
vsiteForceKernel->addArg(vsiteSymmetryMatrix);
vsiteForceKernel->addArg(vsiteSymmetryOffset);
vsiteForceKernel->addArg(vsiteSymmetryUseBox);
for (int i = 0; i < 6; i++)
vsiteForceKernel->addArg(); // Arguments for periodic box
vsiteForceKernel->addArg(vsiteStage); vsiteForceKernel->addArg(vsiteStage);
vsiteForceKernel->addArg(); vsiteForceKernel->addArg();
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
...@@ -787,9 +830,39 @@ void IntegrationUtilities::applyVelocityConstraints(double tol) { ...@@ -787,9 +830,39 @@ void IntegrationUtilities::applyVelocityConstraints(double tol) {
void IntegrationUtilities::computeVirtualSites() { void IntegrationUtilities::computeVirtualSites() {
ContextSelector selector(context); ContextSelector selector(context);
for (int i = 0; i < numVsiteStages; i++) { if (numVsites > 0) {
vsitePositionKernel->setArg(14, i); Vec3 boxVectors[3];
vsitePositionKernel->execute(numVsites); context.getPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]);
mm_double4 recipBoxVectorsDouble[3];
context.computeReciprocalBoxVectors(recipBoxVectorsDouble);
if (context.getUseDoublePrecision()) {
mm_double4 boxVectorsDouble[3];
for (int i = 0; i < 3; i++)
boxVectorsDouble[i] = mm_double4(boxVectors[i][0], boxVectors[i][1], boxVectors[i][2], 0);
vsitePositionKernel->setArg(17, boxVectorsDouble[0]);
vsitePositionKernel->setArg(18, boxVectorsDouble[1]);
vsitePositionKernel->setArg(19, boxVectorsDouble[2]);
vsitePositionKernel->setArg(20, recipBoxVectorsDouble[0]);
vsitePositionKernel->setArg(21, recipBoxVectorsDouble[1]);
vsitePositionKernel->setArg(22, recipBoxVectorsDouble[2]);
}
else {
mm_float4 boxVectorsFloat[3], recipBoxVectorsFloat[3];
for (int i = 0; i < 3; i++) {
boxVectorsFloat[i] = mm_float4((float) boxVectors[i][0], (float) boxVectors[i][1], (float) boxVectors[i][2], 0);
recipBoxVectorsFloat[i] = mm_float4((float) recipBoxVectorsDouble[i].x, (float) recipBoxVectorsDouble[i].y, (float) recipBoxVectorsDouble[i].z, 0);
}
vsitePositionKernel->setArg(17, boxVectorsFloat[0]);
vsitePositionKernel->setArg(18, boxVectorsFloat[1]);
vsitePositionKernel->setArg(19, boxVectorsFloat[2]);
vsitePositionKernel->setArg(20, recipBoxVectorsFloat[0]);
vsitePositionKernel->setArg(21, recipBoxVectorsFloat[1]);
vsitePositionKernel->setArg(22, recipBoxVectorsFloat[2]);
}
for (int i = 0; i < numVsiteStages; i++) {
vsitePositionKernel->setArg(24, i);
vsitePositionKernel->execute(numVsites);
}
} }
} }
......
...@@ -808,8 +808,11 @@ KERNEL void computeVirtualSites(GLOBAL real4* RESTRICT posq, GLOBAL real4* RESTR ...@@ -808,8 +808,11 @@ KERNEL void computeVirtualSites(GLOBAL real4* RESTRICT posq, GLOBAL real4* RESTR
GLOBAL const int4* RESTRICT outOfPlaneAtoms, GLOBAL const real4* RESTRICT outOfPlaneWeights, GLOBAL const int4* RESTRICT outOfPlaneAtoms, GLOBAL const real4* RESTRICT outOfPlaneWeights,
GLOBAL const int* RESTRICT localCoordsIndex, GLOBAL const int* RESTRICT localCoordsAtoms, GLOBAL const int* RESTRICT localCoordsIndex, GLOBAL const int* RESTRICT localCoordsAtoms,
GLOBAL const real* RESTRICT localCoordsWeights, GLOBAL const real4* RESTRICT localCoordsPos, GLOBAL const real* RESTRICT localCoordsWeights, GLOBAL const real4* RESTRICT localCoordsPos,
GLOBAL const int* RESTRICT localCoordsStartIndex, GLOBAL const int* RESTRICT vsiteStage, GLOBAL const int* RESTRICT localCoordsStartIndex, GLOBAL const int2* RESTRICT symmetryAtoms,
int currentStage) { GLOBAL const real4* RESTRICT symmetryMatrix, GLOBAL const real4* RESTRICT symmetryOffset,
GLOBAL const int* RESTRICT symmetryUseBox, real4 periodicBoxVecX, real4 periodicBoxVecY,
real4 periodicBoxVecZ, real4 recipBoxVecX, real4 recipBoxVecY, real4 recipBoxVecZ,
GLOBAL const int* RESTRICT vsiteStage, int currentStage) {
// Two particle average sites. // Two particle average sites.
...@@ -903,6 +906,33 @@ KERNEL void computeVirtualSites(GLOBAL real4* RESTRICT posq, GLOBAL real4* RESTR ...@@ -903,6 +906,33 @@ KERNEL void computeVirtualSites(GLOBAL real4* RESTRICT posq, GLOBAL real4* RESTR
pos.z = origin.z + xdir.z*localPosition.x + ydir.z*localPosition.y + zdir.z*localPosition.z; pos.z = origin.z + xdir.z*localPosition.x + ydir.z*localPosition.y + zdir.z*localPosition.z;
storePos(posq, posqCorrection, siteAtomIndex, pos); storePos(posq, posqCorrection, siteAtomIndex, pos);
} }
// Symmetry sites.
for (int index = GLOBAL_ID; index < NUM_SYMMETRY; index += GLOBAL_SIZE) {
int2 atoms = symmetryAtoms[index];
real4 Rx = symmetryMatrix[3*index];
real4 Ry = symmetryMatrix[3*index+1];
real4 Rz = symmetryMatrix[3*index+2];
real4 v = symmetryOffset[index];
int useBoxVectors = symmetryUseBox[index];
mixed4 pos = loadPos(posq, posqCorrection, atoms.x);
mixed4 r = loadPos(posq, posqCorrection, atoms.y);
if (useBoxVectors) {
r.x = r.x*recipBoxVecX.x + r.y*recipBoxVecY.x + r.z*recipBoxVecZ.x;
r.y = r.y*recipBoxVecY.y + r.z*recipBoxVecZ.y,
r.z = r.z*recipBoxVecZ.z;
}
pos.x = Rx.x*r.x + Rx.y*r.y + Rx.z*r.z + v.x;
pos.y = Ry.x*r.x + Ry.y*r.y + Ry.z*r.z + v.y;
pos.z = Rz.x*r.x + Rz.y*r.y + Rz.z*r.z + v.z;
if (useBoxVectors) {
pos.x = pos.x*periodicBoxVecX.x + pos.y*periodicBoxVecY.x + pos.z*periodicBoxVecZ.x;
pos.y = pos.y*periodicBoxVecY.y + pos.z*periodicBoxVecZ.y,
pos.z = pos.z*periodicBoxVecZ.z;
}
storePos(posq, posqCorrection, atoms.x, pos);
}
} }
inline DEVICE real3 loadForce(int index, GLOBAL const mm_long* RESTRICT force) { inline DEVICE real3 loadForce(int index, GLOBAL const mm_long* RESTRICT force) {
...@@ -932,8 +962,11 @@ KERNEL void distributeVirtualSiteForces(GLOBAL const real4* RESTRICT posq, GLOBA ...@@ -932,8 +962,11 @@ KERNEL void distributeVirtualSiteForces(GLOBAL const real4* RESTRICT posq, GLOBA
GLOBAL const int4* RESTRICT outOfPlaneAtoms, GLOBAL const real4* RESTRICT outOfPlaneWeights, GLOBAL const int4* RESTRICT outOfPlaneAtoms, GLOBAL const real4* RESTRICT outOfPlaneWeights,
GLOBAL const int* RESTRICT localCoordsIndex, GLOBAL const int* RESTRICT localCoordsAtoms, GLOBAL const int* RESTRICT localCoordsIndex, GLOBAL const int* RESTRICT localCoordsAtoms,
GLOBAL const real* RESTRICT localCoordsWeights, GLOBAL const real4* RESTRICT localCoordsPos, GLOBAL const real* RESTRICT localCoordsWeights, GLOBAL const real4* RESTRICT localCoordsPos,
GLOBAL const int* RESTRICT localCoordsStartIndex, GLOBAL const int* RESTRICT vsiteStage, GLOBAL const int* RESTRICT localCoordsStartIndex, GLOBAL const int2* RESTRICT symmetryAtoms,
int currentStage) { GLOBAL const real4* RESTRICT symmetryMatrix, GLOBAL const real4* RESTRICT symmetryOffset,
GLOBAL const int* RESTRICT symmetryUseBox, real4 periodicBoxVecX, real4 periodicBoxVecY,
real4 periodicBoxVecZ, real4 recipBoxVecX, real4 recipBoxVecY, real4 recipBoxVecZ,
GLOBAL const int* RESTRICT vsiteStage, int currentStage) {
// Two particle average sites. // Two particle average sites.
...@@ -1048,6 +1081,32 @@ KERNEL void distributeVirtualSiteForces(GLOBAL const real4* RESTRICT posq, GLOBA ...@@ -1048,6 +1081,32 @@ KERNEL void distributeVirtualSiteForces(GLOBAL const real4* RESTRICT posq, GLOBA
addForce(localCoordsAtoms[j], force, fresult); addForce(localCoordsAtoms[j], force, fresult);
} }
} }
// Symmetry sites.
for (int index = GLOBAL_ID; index < NUM_SYMMETRY; index += GLOBAL_SIZE) {
int2 atoms = symmetryAtoms[index];
real4 Rx = symmetryMatrix[3*index];
real4 Ry = symmetryMatrix[3*index+1];
real4 Rz = symmetryMatrix[3*index+2];
real4 v = symmetryOffset[index];
int useBoxVectors = symmetryUseBox[index];
real3 f = loadForce(atoms.x, force);
if (useBoxVectors) {
f.x = f.x*periodicBoxVecX.x + f.y*periodicBoxVecY.x + f.z*periodicBoxVecZ.x;
f.y = f.y*periodicBoxVecY.y + f.z*periodicBoxVecZ.y,
f.z = f.z*periodicBoxVecZ.z;
}
real3 f1 = make_real3(Rx.x*f.x + Ry.x*f.y + Rz.x*f.z,
Rx.y*f.x + Ry.y*f.y + Rz.y*f.z,
Rx.z*f.x + Ry.z*f.y + Rz.z*f.z);
if (useBoxVectors) {
f1.x = f1.x*recipBoxVecX.x + f1.y*recipBoxVecY.x + f1.z*recipBoxVecZ.x;
f1.y = f1.y*recipBoxVecY.y + f1.z*recipBoxVecZ.y,
f1.z = f1.z*recipBoxVecZ.z;
}
addForce(atoms.y, force, f1);
}
} }
/** /**
......
...@@ -1516,7 +1516,7 @@ void CpuIntegrateLangevinMiddleStepKernel::execute(ContextImpl& context, const L ...@@ -1516,7 +1516,7 @@ void CpuIntegrateLangevinMiddleStepKernel::execute(ContextImpl& context, const L
prevFriction = friction; prevFriction = friction;
prevStepSize = stepSize; prevStepSize = stepSize;
} }
dynamics->update(context, posData, velData, masses, integrator.getConstraintTolerance()); dynamics->update(context, posData, velData, masses, integrator.getConstraintTolerance(), extractBoxVectors(context));
ReferencePlatform::PlatformData* refData = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData()); ReferencePlatform::PlatformData* refData = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData());
refData->time += stepSize; refData->time += stepSize;
refData->stepCount++; refData->stepCount++;
......
...@@ -134,9 +134,39 @@ void CudaIntegrationUtilities::applyConstraintsImpl(bool constrainVelocities, do ...@@ -134,9 +134,39 @@ void CudaIntegrationUtilities::applyConstraintsImpl(bool constrainVelocities, do
void CudaIntegrationUtilities::distributeForcesFromVirtualSites() { void CudaIntegrationUtilities::distributeForcesFromVirtualSites() {
ContextSelector selector(context); ContextSelector selector(context);
for (int i = numVsiteStages-1; i >= 0; i--) { if (numVsites > 0) {
vsiteForceKernel->setArg(2, context.getLongForceBuffer()); Vec3 boxVectors[3];
vsiteForceKernel->setArg(15, i); context.getPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]);
vsiteForceKernel->execute(numVsites); mm_double4 recipBoxVectorsDouble[3];
context.computeReciprocalBoxVectors(recipBoxVectorsDouble);
if (context.getUseDoublePrecision()) {
mm_double4 boxVectorsDouble[3];
for (int i = 0; i < 3; i++)
boxVectorsDouble[i] = mm_double4(boxVectors[i][0], boxVectors[i][1], boxVectors[i][2], 0);
vsiteForceKernel->setArg(18, boxVectorsDouble[0]);
vsiteForceKernel->setArg(19, boxVectorsDouble[1]);
vsiteForceKernel->setArg(20, boxVectorsDouble[2]);
vsiteForceKernel->setArg(21, recipBoxVectorsDouble[0]);
vsiteForceKernel->setArg(22, recipBoxVectorsDouble[1]);
vsiteForceKernel->setArg(23, recipBoxVectorsDouble[2]);
}
else {
mm_float4 boxVectorsFloat[3], recipBoxVectorsFloat[3];
for (int i = 0; i < 3; i++) {
boxVectorsFloat[i] = mm_float4((float) boxVectors[i][0], (float) boxVectors[i][1], (float) boxVectors[i][2], 0);
recipBoxVectorsFloat[i] = mm_float4((float) recipBoxVectorsDouble[i].x, (float) recipBoxVectorsDouble[i].y, (float) recipBoxVectorsDouble[i].z, 0);
}
vsiteForceKernel->setArg(18, boxVectorsFloat[0]);
vsiteForceKernel->setArg(19, boxVectorsFloat[1]);
vsiteForceKernel->setArg(20, boxVectorsFloat[2]);
vsiteForceKernel->setArg(21, recipBoxVectorsFloat[0]);
vsiteForceKernel->setArg(22, recipBoxVectorsFloat[1]);
vsiteForceKernel->setArg(23, recipBoxVectorsFloat[2]);
}
for (int i = numVsiteStages-1; i >= 0; i--) {
vsiteForceKernel->setArg(2, context.getLongForceBuffer());
vsiteForceKernel->setArg(25, i);
vsiteForceKernel->execute(numVsites);
}
} }
} }
...@@ -131,12 +131,42 @@ void OpenCLIntegrationUtilities::applyConstraintsImpl(bool constrainVelocities, ...@@ -131,12 +131,42 @@ void OpenCLIntegrationUtilities::applyConstraintsImpl(bool constrainVelocities,
} }
void OpenCLIntegrationUtilities::distributeForcesFromVirtualSites() { void OpenCLIntegrationUtilities::distributeForcesFromVirtualSites() {
for (int i = numVsiteStages-1; i >= 0; i--) { if (numVsites > 0) {
vsiteForceKernel->setArg(2, context.getLongForceBuffer()); Vec3 boxVectors[3];
vsiteForceKernel->setArg(15, i); context.getPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]);
vsiteForceKernel->execute(numVsites); mm_double4 recipBoxVectorsDouble[3];
vsiteSaveForcesKernel->setArg(0, context.getLongForceBuffer()); context.computeReciprocalBoxVectors(recipBoxVectorsDouble);
vsiteSaveForcesKernel->setArg(1, context.getForceBuffers()); if (context.getUseDoublePrecision()) {
vsiteSaveForcesKernel->execute(context.getNumAtoms()); mm_double4 boxVectorsDouble[3];
} for (int i = 0; i < 3; i++)
boxVectorsDouble[i] = mm_double4(boxVectors[i][0], boxVectors[i][1], boxVectors[i][2], 0);
vsiteForceKernel->setArg(18, boxVectorsDouble[0]);
vsiteForceKernel->setArg(19, boxVectorsDouble[1]);
vsiteForceKernel->setArg(20, boxVectorsDouble[2]);
vsiteForceKernel->setArg(21, recipBoxVectorsDouble[0]);
vsiteForceKernel->setArg(22, recipBoxVectorsDouble[1]);
vsiteForceKernel->setArg(23, recipBoxVectorsDouble[2]);
}
else {
mm_float4 boxVectorsFloat[3], recipBoxVectorsFloat[3];
for (int i = 0; i < 3; i++) {
boxVectorsFloat[i] = mm_float4((float) boxVectors[i][0], (float) boxVectors[i][1], (float) boxVectors[i][2], 0);
recipBoxVectorsFloat[i] = mm_float4((float) recipBoxVectorsDouble[i].x, (float) recipBoxVectorsDouble[i].y, (float) recipBoxVectorsDouble[i].z, 0);
}
vsiteForceKernel->setArg(18, boxVectorsFloat[0]);
vsiteForceKernel->setArg(19, boxVectorsFloat[1]);
vsiteForceKernel->setArg(20, boxVectorsFloat[2]);
vsiteForceKernel->setArg(21, recipBoxVectorsFloat[0]);
vsiteForceKernel->setArg(22, recipBoxVectorsFloat[1]);
vsiteForceKernel->setArg(23, recipBoxVectorsFloat[2]);
}
for (int i = numVsiteStages-1; i >= 0; i--) {
vsiteForceKernel->setArg(2, context.getLongForceBuffer());
vsiteForceKernel->setArg(25, i);
vsiteForceKernel->execute(numVsites);
vsiteSaveForcesKernel->setArg(0, context.getLongForceBuffer());
vsiteSaveForcesKernel->setArg(1, context.getForceBuffers());
vsiteSaveForcesKernel->execute(context.getNumAtoms());
}
}
} }
/* Portions copyright (c) 2006-2012 Stanford University and Simbios. /* Portions copyright (c) 2006-2023 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
...@@ -80,11 +80,12 @@ class ReferenceBrownianDynamics : public ReferenceDynamics { ...@@ -80,11 +80,12 @@ class ReferenceBrownianDynamics : public ReferenceDynamics {
@param forces forces @param forces forces
@param masses atom masses @param masses atom masses
@param tolerance the constraint tolerance @param tolerance the constraint tolerance
@param boxVectors the current periodic box vectors
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void update(const OpenMM::System& system, std::vector<OpenMM::Vec3>& atomCoordinates, void update(const OpenMM::System& system, std::vector<OpenMM::Vec3>& atomCoordinates,
std::vector<OpenMM::Vec3>& velocities, std::vector<OpenMM::Vec3>& forces, std::vector<double>& masses, double tolerance); std::vector<OpenMM::Vec3>& velocities, std::vector<OpenMM::Vec3>& forces, std::vector<double>& masses, double tolerance, const Vec3* boxVectors);
}; };
......
/* Portions copyright (c) 2011-2016 Stanford University and Simbios. /* Portions copyright (c) 2011-2023 Stanford University and Simbios.
* Contributors: Peter Eastman * Contributors: Peter Eastman
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -114,12 +114,13 @@ public: ...@@ -114,12 +114,13 @@ public:
@param perDof the values of per-DOF variables @param perDof the values of per-DOF variables
@param forcesAreValid whether the current forces are valid or need to be recomputed @param forcesAreValid whether the current forces are valid or need to be recomputed
@param tolerance the constraint tolerance @param tolerance the constraint tolerance
@param boxVectors the current periodic box vectors
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void update(OpenMM::ContextImpl& context, int numberOfAtoms, std::vector<OpenMM::Vec3>& atomCoordinates, void update(OpenMM::ContextImpl& context, int numberOfAtoms, std::vector<OpenMM::Vec3>& atomCoordinates,
std::vector<OpenMM::Vec3>& velocities, std::vector<OpenMM::Vec3>& forces, std::vector<double>& masses, std::vector<OpenMM::Vec3>& velocities, std::vector<OpenMM::Vec3>& forces, std::vector<double>& masses,
std::map<std::string, double>& globals, std::vector<std::vector<OpenMM::Vec3> >& perDof, bool& forcesAreValid, double tolerance); std::map<std::string, double>& globals, std::vector<std::vector<OpenMM::Vec3> >& perDof, bool& forcesAreValid, double tolerance, const Vec3* boxVectors);
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
......
...@@ -76,9 +76,10 @@ public: ...@@ -76,9 +76,10 @@ public:
* @param velocities velocities * @param velocities velocities
* @param masses atom masses * @param masses atom masses
* @param tolerance the constraint tolerance * @param tolerance the constraint tolerance
* @param boxVectors the current periodic box vectors
*/ */
void update(OpenMM::ContextImpl& context, std::vector<OpenMM::Vec3>& atomCoordinates, void update(OpenMM::ContextImpl& context, std::vector<OpenMM::Vec3>& atomCoordinates,
std::vector<OpenMM::Vec3>& velocities, std::vector<double>& masses, double tolerance); std::vector<OpenMM::Vec3>& velocities, std::vector<double>& masses, double tolerance, const Vec3* boxVectors);
/** /**
* The first stage of the update algorithm. * The first stage of the update algorithm.
......
/* Portions copyright (c) 2006-2013 Stanford University and Simbios. /* Portions copyright (c) 2006-2023 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
...@@ -141,6 +141,10 @@ class OPENMM_EXPORT ReferenceForce { ...@@ -141,6 +141,10 @@ class OPENMM_EXPORT ReferenceForce {
static Vec3 getDeltaRPeriodic(const OpenMM::Vec3& atomCoordinatesI, const OpenMM::Vec3& atomCoordinatesJ, static Vec3 getDeltaRPeriodic(const OpenMM::Vec3& atomCoordinatesI, const OpenMM::Vec3& atomCoordinatesJ,
const OpenMM::Vec3* boxVectors); const OpenMM::Vec3* boxVectors);
/**
* Invert the periodic box vectors to get the corresponding vectors in reciprocal space.
*/
static void invertBoxVectors(const OpenMM::Vec3* boxVectors, OpenMM::Vec3* recipBoxVectors);
/** /**
* Get a pointer to the memory for setting a variable in a CompiledExpression. If the expression * Get a pointer to the memory for setting a variable in a CompiledExpression. If the expression
* does not use the specified variable, return NULL. * does not use the specified variable, return NULL.
......
/* Portions copyright (c) 2006-2020 Stanford University and Simbios. /* Portions copyright (c) 2006-2023 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
...@@ -80,11 +80,12 @@ class OPENMM_EXPORT ReferenceLangevinMiddleDynamics : public ReferenceDynamics { ...@@ -80,11 +80,12 @@ class OPENMM_EXPORT ReferenceLangevinMiddleDynamics : public ReferenceDynamics {
@param velocities velocities @param velocities velocities
@param masses atom masses @param masses atom masses
@param tolerance the constraint tolerance @param tolerance the constraint tolerance
@param boxVectors the current periodic box vectors
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void update(OpenMM::ContextImpl& context, std::vector<OpenMM::Vec3>& atomCoordinates, void update(OpenMM::ContextImpl& context, std::vector<OpenMM::Vec3>& atomCoordinates,
std::vector<OpenMM::Vec3>& velocities, std::vector<double>& masses, double tolerance); std::vector<OpenMM::Vec3>& velocities, std::vector<double>& masses, double tolerance, const Vec3* boxVectors);
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
......
...@@ -95,11 +95,12 @@ class ReferenceNoseHooverDynamics : public ReferenceDynamics { ...@@ -95,11 +95,12 @@ class ReferenceNoseHooverDynamics : public ReferenceDynamics {
@param allAtoms a list of all atoms not involved in a Drude-like pair @param allAtoms a list of all atoms not involved in a Drude-like pair
@param allPairs a list of all Drude-like pairs, and their KT values, in the system @param allPairs a list of all Drude-like pairs, and their KT values, in the system
@param maxPairDistance the maximum separation allowed for a Drude-like pair @param maxPairDistance the maximum separation allowed for a Drude-like pair
@param boxVectors the current periodic box vectors
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void step2(OpenMM::ContextImpl &context, const OpenMM::System& system, std::vector<OpenMM::Vec3>& atomCoordinates, void step2(OpenMM::ContextImpl &context, const OpenMM::System& system, std::vector<OpenMM::Vec3>& atomCoordinates,
std::vector<OpenMM::Vec3>& velocities, std::vector<OpenMM::Vec3>& forces, std::vector<double>& masses, double tolerance, std::vector<OpenMM::Vec3>& velocities, std::vector<OpenMM::Vec3>& forces, std::vector<double>& masses, double tolerance,
const std::vector<int> & allAtoms, const std::vector<std::tuple<int, int, double>> & allPairs, double maxPairDistance); const std::vector<int> & allAtoms, const std::vector<std::tuple<int, int, double>> & allPairs, double maxPairDistance, const Vec3* boxVectors);
}; };
......
...@@ -97,11 +97,12 @@ class ReferenceVariableStochasticDynamics : public ReferenceDynamics { ...@@ -97,11 +97,12 @@ class ReferenceVariableStochasticDynamics : public ReferenceDynamics {
@param masses atom masses @param masses atom masses
@param maxStepSize maximum time step @param maxStepSize maximum time step
@param tolerance the constraint tolerance @param tolerance the constraint tolerance
@param boxVectors the current periodic box vectors
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void update(const OpenMM::System& system, std::vector<OpenMM::Vec3>& atomCoordinates, void update(const OpenMM::System& system, std::vector<OpenMM::Vec3>& atomCoordinates,
std::vector<OpenMM::Vec3>& velocities, std::vector<OpenMM::Vec3>& forces, std::vector<double>& masses, double maxStepSize, double tolerance); std::vector<OpenMM::Vec3>& velocities, std::vector<OpenMM::Vec3>& forces, std::vector<double>& masses, double maxStepSize, double tolerance, const Vec3* boxVectors);
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
......
/* Portions copyright (c) 2006-2012 Stanford University and Simbios. /* Portions copyright (c) 2006-2023 Stanford University and Simbios.
* Contributors: Peter Eastman, Pande Group * Contributors: Peter Eastman, Pande Group
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -87,11 +87,12 @@ class ReferenceVariableVerletDynamics : public ReferenceDynamics { ...@@ -87,11 +87,12 @@ class ReferenceVariableVerletDynamics : public ReferenceDynamics {
@param masses atom masses @param masses atom masses
@param maxStepSize maximum time step @param maxStepSize maximum time step
@param tolerance the constraint tolerance @param tolerance the constraint tolerance
@param boxVectors the current periodic box vectors
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void update(const OpenMM::System& system, std::vector<OpenMM::Vec3>& atomCoordinates, void update(const OpenMM::System& system, std::vector<OpenMM::Vec3>& atomCoordinates,
std::vector<OpenMM::Vec3>& velocities, std::vector<OpenMM::Vec3>& forces, std::vector<double>& masses, double maxStepSize, double tolerance); std::vector<OpenMM::Vec3>& velocities, std::vector<OpenMM::Vec3>& forces, std::vector<double>& masses, double maxStepSize, double tolerance, const Vec3* boxVectors);
}; };
......
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