Commit 047934e2 authored by Rafal P. Wiewiora's avatar Rafal P. Wiewiora
Browse files

Merge remote-tracking branch 'upstream/master'

parents ce3a5dc0 d12c9bd1
...@@ -39,13 +39,6 @@ using namespace OpenMM; ...@@ -39,13 +39,6 @@ using namespace OpenMM;
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceBondIxn::ReferenceBondIxn() { ReferenceBondIxn::ReferenceBondIxn() {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceBondIxn::ReferenceBondIxn";
// ---------------------------------------------------------------------------------------
} }
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -55,13 +48,6 @@ ReferenceBondIxn::ReferenceBondIxn() { ...@@ -55,13 +48,6 @@ ReferenceBondIxn::ReferenceBondIxn() {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceBondIxn::~ReferenceBondIxn() { ReferenceBondIxn::~ReferenceBondIxn() {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceBondIxn::~ReferenceBondIxn";
// ---------------------------------------------------------------------------------------
} }
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -76,15 +62,9 @@ ReferenceBondIxn::~ReferenceBondIxn() { ...@@ -76,15 +62,9 @@ ReferenceBondIxn::~ReferenceBondIxn() {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceBondIxn::calculateBondIxn(int* atomIndices, vector<RealVec>& atomCoordinates, void ReferenceBondIxn::calculateBondIxn(int* atomIndices, vector<Vec3>& atomCoordinates,
RealOpenMM* parameters, vector<RealVec>& forces, double* parameters, vector<Vec3>& forces,
RealOpenMM* totalEnergy, double* energyParamDerivs) { double* totalEnergy, double* energyParamDerivs) {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "\nReferenceBondIxn::calculateBondIxn";
// ---------------------------------------------------------------------------------------
} }
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -102,67 +82,26 @@ ReferenceBondIxn::~ReferenceBondIxn() { ...@@ -102,67 +82,26 @@ ReferenceBondIxn::~ReferenceBondIxn() {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM ReferenceBondIxn::getNormedDotProduct(RealOpenMM* vector1, RealOpenMM* vector2, double ReferenceBondIxn::getNormedDotProduct(double* vector1, double* vector2,
int hasREntry = 0) { int hasREntry = 0) {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "\nReferenceBondIxn::getNormedDotProduct";
static const RealOpenMM zero = 0.0;
static const RealOpenMM one = 1.0;
// ---------------------------------------------------------------------------------------
// for angles near pi, double is required due to the 'steepness' of acos()
// in this regime.
//#define USE_DOUBLE_FOR_NORMED_DOT_PRODUCT
#if defined USE_DOUBLE_FOR_NORMED_DOT_PRODUCT double dotProduct = DOT3(vector1, vector2);
double v1D[3]; if (dotProduct != 0.0) {
double v2D[3];
v1D[0] = static_cast<double>(vector1[0]);
v1D[1] = static_cast<double>(vector1[1]);
v1D[2] = static_cast<double>(vector1[2]);
v2D[0] = static_cast<double>(vector2[0]);
v2D[1] = static_cast<double>(vector2[1]);
v2D[2] = static_cast<double>(vector2[2]);
double dotProductD = DOT3(v1D, v2D);
if (dotProductD != 0.0) {
if (hasREntry) {
dotProductD /= (static_cast<double>(vector1[ReferenceForce::RIndex])*static_cast<double>(vector2[ReferenceForce::RIndex]));
} else {
double norm1 = DOT3(v1D, v1D);
double norm2 = DOT3(v2D, v2D);
dotProductD /= sqrt(norm1*norm2);
}
}
RealOpenMM dotProduct = static_cast<RealOpenMM>(dotProductD);
#else
RealOpenMM dotProduct = DOT3(vector1, vector2);
if (dotProduct != zero) {
if (hasREntry) { if (hasREntry) {
dotProduct /= (vector1[ReferenceForce::RIndex]*vector2[ReferenceForce::RIndex]); dotProduct /= (vector1[ReferenceForce::RIndex]*vector2[ReferenceForce::RIndex]);
} else { } else {
RealOpenMM norm1 = DOT3(vector1, vector1); double norm1 = DOT3(vector1, vector1);
RealOpenMM norm2 = DOT3(vector2, vector2); double norm2 = DOT3(vector2, vector2);
dotProduct /= SQRT(norm1*norm2); dotProduct /= sqrt(norm1*norm2);
} }
} }
#endif
#undef USE_DOUBLE_FOR_NORMED_DOT_PRODUCT
// clamp dot product to [-1,1] // clamp dot product to [-1,1]
if (dotProduct > one) { if (dotProduct > 1.0) {
dotProduct = one; dotProduct = 1.0;
} else if (dotProduct < -one) { } else if (dotProduct < -1.0) {
dotProduct = -one; dotProduct = -1.0;
} }
return dotProduct; return dotProduct;
...@@ -183,35 +122,26 @@ RealOpenMM ReferenceBondIxn::getNormedDotProduct(RealOpenMM* vector1, RealOpenMM ...@@ -183,35 +122,26 @@ RealOpenMM ReferenceBondIxn::getNormedDotProduct(RealOpenMM* vector1, RealOpenMM
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM ReferenceBondIxn::getAngleBetweenTwoVectors(RealOpenMM* vector1, RealOpenMM* vector2, double ReferenceBondIxn::getAngleBetweenTwoVectors(double* vector1, double* vector2,
RealOpenMM* outputDotProduct = NULL, double* outputDotProduct = NULL,
int hasREntry = 0) { int hasREntry = 0) {
// --------------------------------------------------------------------------------------- // get dot product betweenn vectors and then angle
// static const std::string methodName = "\nReferenceBondIxn::getAngle"; double dotProduct = getNormedDotProduct(vector1, vector2, hasREntry);
static const RealOpenMM zero = 0.0; double angle;
static const RealOpenMM one = 1.0; if (dotProduct > 0.99 || dotProduct < -0.99) {
// ---------------------------------------------------------------------------------------
// get dot product betweenn vectors and then angle
RealOpenMM dotProduct = getNormedDotProduct(vector1, vector2, hasREntry);
RealOpenMM angle;
if (dotProduct > (RealOpenMM) 0.99 || dotProduct < (RealOpenMM) -0.99) {
// We're close to the singularity in acos(), so take the cross product and use asin() instead. // We're close to the singularity in acos(), so take the cross product and use asin() instead.
RealOpenMM cross[3]; double cross[3];
SimTKOpenMMUtilities::crossProductVector3(vector1, vector2, cross); SimTKOpenMMUtilities::crossProductVector3(vector1, vector2, cross);
RealOpenMM scale = DOT3(vector1, vector1)*DOT3(vector2, vector2); double scale = DOT3(vector1, vector1)*DOT3(vector2, vector2);
angle = ASIN(SQRT(DOT3(cross, cross)/scale)); angle = asin(sqrt(DOT3(cross, cross)/scale));
if (dotProduct < zero) if (dotProduct < 0.0)
angle = (RealOpenMM) (M_PI-angle); angle = M_PI-angle;
} else { } else {
angle = ACOS(dotProduct); angle = acos(dotProduct);
} }
if (outputDotProduct) { if (outputDotProduct) {
...@@ -240,29 +170,20 @@ RealOpenMM ReferenceBondIxn::getAngleBetweenTwoVectors(RealOpenMM* vector1, Real ...@@ -240,29 +170,20 @@ RealOpenMM ReferenceBondIxn::getAngleBetweenTwoVectors(RealOpenMM* vector1, Real
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM ReferenceBondIxn::getDihedralAngleBetweenThreeVectors(RealOpenMM* vector1, double ReferenceBondIxn::getDihedralAngleBetweenThreeVectors(double* vector1,
RealOpenMM* vector2, double* vector2,
RealOpenMM* vector3, double* vector3,
RealOpenMM** outputCrossProduct = NULL, double** outputCrossProduct = NULL,
RealOpenMM* cosineOfAngle = NULL, double* cosineOfAngle = NULL,
RealOpenMM* signVector = NULL, double* signVector = NULL,
RealOpenMM* signOfAngle = NULL, double* signOfAngle = NULL,
int hasREntry = 0) { int hasREntry = 0) {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "\nReferenceBondIxn::getDihedralAngleBetweenThreeVectors";
static const RealOpenMM zero = 0.0;
static const RealOpenMM one = 1.0;
RealOpenMM tempVectors[6] = { zero, zero, zero, zero, zero, zero };
// --------------------------------------------------------------------------------------- double tempVectors[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
// get cross products between vectors and then angle between cross product vectors // get cross products between vectors and then angle between cross product vectors
RealOpenMM* crossProduct[2]; double* crossProduct[2];
if (outputCrossProduct) { if (outputCrossProduct) {
crossProduct[0] = outputCrossProduct[0]; crossProduct[0] = outputCrossProduct[0];
crossProduct[1] = outputCrossProduct[1]; crossProduct[1] = outputCrossProduct[1];
...@@ -274,13 +195,13 @@ RealOpenMM ReferenceBondIxn::getDihedralAngleBetweenThreeVectors(RealOpenMM* ve ...@@ -274,13 +195,13 @@ RealOpenMM ReferenceBondIxn::getDihedralAngleBetweenThreeVectors(RealOpenMM* ve
SimTKOpenMMUtilities::crossProductVector3(vector1, vector2, crossProduct[0]); SimTKOpenMMUtilities::crossProductVector3(vector1, vector2, crossProduct[0]);
SimTKOpenMMUtilities::crossProductVector3(vector2, vector3, crossProduct[1]); SimTKOpenMMUtilities::crossProductVector3(vector2, vector3, crossProduct[1]);
RealOpenMM angle = getAngleBetweenTwoVectors(crossProduct[0], crossProduct[1], cosineOfAngle, 0); double angle = getAngleBetweenTwoVectors(crossProduct[0], crossProduct[1], cosineOfAngle, 0);
// take care of sign of angle // take care of sign of angle
if (signVector) { if (signVector) {
RealOpenMM dotProduct = DOT3(signVector, crossProduct[1]); double dotProduct = DOT3(signVector, crossProduct[1]);
RealOpenMM sign = dotProduct < zero ? -one : one; double sign = dotProduct < 0.0 ? -1.0 : 1.0;
if (signOfAngle) { if (signOfAngle) {
*signOfAngle = sign; *signOfAngle = sign;
} }
......
...@@ -47,8 +47,8 @@ using namespace OpenMM; ...@@ -47,8 +47,8 @@ using namespace OpenMM;
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceBrownianDynamics::ReferenceBrownianDynamics(int numberOfAtoms, ReferenceBrownianDynamics::ReferenceBrownianDynamics(int numberOfAtoms,
RealOpenMM deltaT, RealOpenMM friction, double deltaT, double friction,
RealOpenMM temperature) : double temperature) :
ReferenceDynamics(numberOfAtoms, deltaT, temperature), friction(friction) { ReferenceDynamics(numberOfAtoms, deltaT, temperature), friction(friction) {
if (friction <= 0) { if (friction <= 0) {
...@@ -67,13 +67,6 @@ ReferenceBrownianDynamics::ReferenceBrownianDynamics(int numberOfAtoms, ...@@ -67,13 +67,6 @@ ReferenceBrownianDynamics::ReferenceBrownianDynamics(int numberOfAtoms,
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceBrownianDynamics::~ReferenceBrownianDynamics() { ReferenceBrownianDynamics::~ReferenceBrownianDynamics() {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceBrownianDynamics::~ReferenceBrownianDynamics";
// ---------------------------------------------------------------------------------------
} }
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -84,14 +77,7 @@ ReferenceBrownianDynamics::~ReferenceBrownianDynamics() { ...@@ -84,14 +77,7 @@ ReferenceBrownianDynamics::~ReferenceBrownianDynamics() {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM ReferenceBrownianDynamics::getFriction() const { double ReferenceBrownianDynamics::getFriction() const {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceBrownianDynamics::getFriction";
// ---------------------------------------------------------------------------------------
return friction; return friction;
} }
...@@ -108,18 +94,9 @@ RealOpenMM ReferenceBrownianDynamics::getFriction() const { ...@@ -108,18 +94,9 @@ RealOpenMM ReferenceBrownianDynamics::getFriction() const {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceBrownianDynamics::update(const OpenMM::System& system, vector<RealVec>& atomCoordinates, void ReferenceBrownianDynamics::update(const OpenMM::System& system, vector<Vec3>& atomCoordinates,
vector<RealVec>& velocities, vector<Vec3>& velocities,
vector<RealVec>& forces, vector<RealOpenMM>& masses, RealOpenMM tolerance) { vector<Vec3>& forces, vector<double>& masses, double tolerance) {
// ---------------------------------------------------------------------------------------
static const char* methodName = "\nReferenceBrownianDynamics::update";
static const RealOpenMM zero = 0.0;
static const RealOpenMM one = 1.0;
// ---------------------------------------------------------------------------------------
// first-time-through initialization // first-time-through initialization
...@@ -128,21 +105,21 @@ void ReferenceBrownianDynamics::update(const OpenMM::System& system, vector<Real ...@@ -128,21 +105,21 @@ void ReferenceBrownianDynamics::update(const OpenMM::System& system, vector<Real
// invert masses // invert masses
for (int ii = 0; ii < numberOfAtoms; ii++) { for (int ii = 0; ii < numberOfAtoms; ii++) {
if (masses[ii] == zero) if (masses[ii] == 0.0)
inverseMasses[ii] = zero; inverseMasses[ii] = 0.0;
else else
inverseMasses[ii] = one/masses[ii]; inverseMasses[ii] = 1.0/masses[ii];
} }
} }
// Perform the integration. // Perform the integration.
const RealOpenMM noiseAmplitude = static_cast<RealOpenMM>(sqrt(2.0*BOLTZ*getTemperature()*getDeltaT()/getFriction())); const double noiseAmplitude = sqrt(2.0*BOLTZ*getTemperature()*getDeltaT()/getFriction());
const RealOpenMM forceScale = getDeltaT()/getFriction(); const double forceScale = getDeltaT()/getFriction();
for (int i = 0; i < numberOfAtoms; ++i) { for (int i = 0; i < numberOfAtoms; ++i) {
if (masses[i] != zero) if (masses[i] != 0.0)
for (int j = 0; j < 3; ++j) { for (int j = 0; j < 3; ++j) {
xPrime[i][j] = atomCoordinates[i][j] + forceScale*inverseMasses[i]*forces[i][j] + noiseAmplitude*SQRT(inverseMasses[i])*SimTKOpenMMUtilities::getNormallyDistributedRandomNumber(); xPrime[i][j] = atomCoordinates[i][j] + forceScale*inverseMasses[i]*forces[i][j] + noiseAmplitude*sqrt(inverseMasses[i])*SimTKOpenMMUtilities::getNormallyDistributedRandomNumber();
} }
} }
ReferenceConstraintAlgorithm* referenceConstraintAlgorithm = getReferenceConstraintAlgorithm(); ReferenceConstraintAlgorithm* referenceConstraintAlgorithm = getReferenceConstraintAlgorithm();
...@@ -151,9 +128,9 @@ void ReferenceBrownianDynamics::update(const OpenMM::System& system, vector<Real ...@@ -151,9 +128,9 @@ void ReferenceBrownianDynamics::update(const OpenMM::System& system, vector<Real
// Update the positions and velocities. // Update the positions and velocities.
RealOpenMM velocityScale = static_cast<RealOpenMM>(1.0/getDeltaT()); double velocityScale = 1.0/getDeltaT();
for (int i = 0; i < numberOfAtoms; ++i) { for (int i = 0; i < numberOfAtoms; ++i) {
if (masses[i] != zero) if (masses[i] != 0.0)
for (int j = 0; j < 3; ++j) { for (int j = 0; j < 3; ++j) {
velocities[i][j] = velocityScale*(xPrime[i][j] - atomCoordinates[i][j]); velocities[i][j] = velocityScale*(xPrime[i][j] - atomCoordinates[i][j]);
atomCoordinates[i][j] = xPrime[i][j]; atomCoordinates[i][j] = xPrime[i][j];
......
/* Portions copyright (c) 2006-2015 Stanford University and Simbios. /* Portions copyright (c) 2006-2017 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
...@@ -38,49 +38,13 @@ ...@@ -38,49 +38,13 @@
using namespace OpenMM; using namespace OpenMM;
using namespace std; using namespace std;
// This class extracts columns from the inverse matrix one at a time. It is done in parallel,
// since this can be very slow.
class ExtractMatrixTask : public ThreadPool::Task {
public:
ExtractMatrixTask(int numConstraints, vector<vector<pair<int, RealOpenMM> > >& transposedMatrix, const vector<RealOpenMM>& distance, RealOpenMM elementCutoff,
const int* qRowStart, const int* qColIndex, const int* rRowStart, const int* rColIndex, const double* qValue, const double* rValue) :
numConstraints(numConstraints), transposedMatrix(transposedMatrix), distance(distance), elementCutoff(elementCutoff), qRowStart(qRowStart), qColIndex(qColIndex),
rRowStart(rRowStart), rColIndex(rColIndex), qValue(qValue), rValue(rValue) {
}
void execute(ThreadPool& pool, int threadIndex) {
vector<double> rhs(numConstraints);
for (int i = threadIndex; i < numConstraints; i += pool.getNumThreads()) {
// Extract column i of the inverse matrix.
for (int j = 0; j < numConstraints; j++)
rhs[j] = (i == j ? 1.0 : 0.0);
QUERN_multiply_with_q_transpose(numConstraints, qRowStart, qColIndex, qValue, &rhs[0]);
QUERN_solve_with_r(numConstraints, rRowStart, rColIndex, rValue, &rhs[0], &rhs[0]);
for (int j = 0; j < numConstraints; j++) {
double value = rhs[j]*distance[i]/distance[j];
if (FABS((RealOpenMM) value) > elementCutoff)
transposedMatrix[i].push_back(pair<int, RealOpenMM>(j, (RealOpenMM) value));
}
}
}
private:
int numConstraints;
vector<vector<pair<int, RealOpenMM> > >& transposedMatrix;
const vector<RealOpenMM>& distance;
RealOpenMM elementCutoff;
const int *qRowStart, *qColIndex, *rRowStart, *rColIndex;
const double *qValue, *rValue;
};
ReferenceCCMAAlgorithm::ReferenceCCMAAlgorithm(int numberOfAtoms, ReferenceCCMAAlgorithm::ReferenceCCMAAlgorithm(int numberOfAtoms,
int numberOfConstraints, int numberOfConstraints,
const vector<pair<int, int> >& atomIndices, const vector<pair<int, int> >& atomIndices,
const vector<RealOpenMM>& distance, const vector<double>& distance,
vector<RealOpenMM>& masses, vector<double>& masses,
vector<AngleInfo>& angles, vector<AngleInfo>& angles,
RealOpenMM elementCutoff) { double elementCutoff) {
_numberOfConstraints = numberOfConstraints; _numberOfConstraints = numberOfConstraints;
_elementCutoff = elementCutoff; _elementCutoff = elementCutoff;
_atomIndices = atomIndices; _atomIndices = atomIndices;
...@@ -116,8 +80,8 @@ ReferenceCCMAAlgorithm::ReferenceCCMAAlgorithm(int numberOfAtoms, ...@@ -116,8 +80,8 @@ ReferenceCCMAAlgorithm::ReferenceCCMAAlgorithm(int numberOfAtoms,
int atomj1 = _atomIndices[j].second; int atomj1 = _atomIndices[j].second;
int atomk0 = _atomIndices[k].first; int atomk0 = _atomIndices[k].first;
int atomk1 = _atomIndices[k].second; int atomk1 = _atomIndices[k].second;
RealOpenMM invMass0 = 1/masses[atomj0]; double invMass0 = 1/masses[atomj0];
RealOpenMM invMass1 = 1/masses[atomj1]; double invMass1 = 1/masses[atomj1];
int atoma, atomb, atomc; int atoma, atomb, atomc;
if (atomj0 == atomk0) { if (atomj0 == atomk0) {
atoma = atomj1; atoma = atomj1;
...@@ -192,18 +156,36 @@ ReferenceCCMAAlgorithm::ReferenceCCMAAlgorithm(int numberOfAtoms, ...@@ -192,18 +156,36 @@ ReferenceCCMAAlgorithm::ReferenceCCMAAlgorithm(int numberOfAtoms,
double *qValue, *rValue; double *qValue, *rValue;
QUERN_compute_qr(numberOfConstraints, numberOfConstraints, &matrixRowStart[0], &matrixColIndex[0], &matrixValue[0], NULL, QUERN_compute_qr(numberOfConstraints, numberOfConstraints, &matrixRowStart[0], &matrixColIndex[0], &matrixValue[0], NULL,
&qRowStart, &qColIndex, &qValue, &rRowStart, &rColIndex, &rValue); &qRowStart, &qColIndex, &qValue, &rRowStart, &rColIndex, &rValue);
vector<vector<pair<int, RealOpenMM> > > transposedMatrix(numberOfConstraints); vector<vector<pair<int, double> > > transposedMatrix(numberOfConstraints);
_matrix.resize(numberOfConstraints); _matrix.resize(numberOfConstraints);
// Extract columns from the inverse matrix one at a time. It is done in parallel,
// since this can be very slow.
ThreadPool threads; ThreadPool threads;
ExtractMatrixTask task(numberOfConstraints, transposedMatrix, _distance, _elementCutoff, qRowStart, qColIndex, rRowStart, rColIndex, qValue, rValue); threads.execute([&] (ThreadPool& pool, int threadIndex) {
threads.execute(task); vector<double> rhs(numberOfConstraints);
for (int i = threadIndex; i < numberOfConstraints; i += pool.getNumThreads()) {
// Extract column i of the inverse matrix.
for (int j = 0; j < numberOfConstraints; j++)
rhs[j] = (i == j ? 1.0 : 0.0);
QUERN_multiply_with_q_transpose(numberOfConstraints, qRowStart, qColIndex, qValue, &rhs[0]);
QUERN_solve_with_r(numberOfConstraints, rRowStart, rColIndex, rValue, &rhs[0], &rhs[0]);
for (int j = 0; j < numberOfConstraints; j++) {
double value = rhs[j]*distance[i]/distance[j];
if (fabs(value) > elementCutoff)
transposedMatrix[i].push_back(pair<int, double>(j, value));
}
}
});
threads.waitForThreads(); threads.waitForThreads();
// For purposes of thread safety we extracted the matrix in transposed form, so we need to transpose it again. // For purposes of thread safety we extracted the matrix in transposed form, so we need to transpose it again.
for (int i = 0; i < numberOfConstraints; i++) { for (int i = 0; i < numberOfConstraints; i++) {
for (int j = 0; j < transposedMatrix[i].size(); j++) { for (int j = 0; j < transposedMatrix[i].size(); j++) {
pair<int, RealOpenMM> value = transposedMatrix[i][j]; pair<int, double> value = transposedMatrix[i][j];
_matrix[value.first].push_back(make_pair(i, value.second)); _matrix[value.first].push_back(make_pair(i, value.second));
} }
} }
...@@ -232,25 +214,25 @@ void ReferenceCCMAAlgorithm::setMaximumNumberOfIterations(int maximumNumberOfIte ...@@ -232,25 +214,25 @@ void ReferenceCCMAAlgorithm::setMaximumNumberOfIterations(int maximumNumberOfIte
_maximumNumberOfIterations = maximumNumberOfIterations; _maximumNumberOfIterations = maximumNumberOfIterations;
} }
void ReferenceCCMAAlgorithm::apply(vector<RealVec>& atomCoordinates, void ReferenceCCMAAlgorithm::apply(vector<Vec3>& atomCoordinates,
vector<RealVec>& atomCoordinatesP, vector<Vec3>& atomCoordinatesP,
vector<RealOpenMM>& inverseMasses, RealOpenMM tolerance) { vector<double>& inverseMasses, double tolerance) {
applyConstraints(atomCoordinates, atomCoordinatesP, inverseMasses, false, tolerance); applyConstraints(atomCoordinates, atomCoordinatesP, inverseMasses, false, tolerance);
} }
void ReferenceCCMAAlgorithm::applyToVelocities(std::vector<OpenMM::RealVec>& atomCoordinates, void ReferenceCCMAAlgorithm::applyToVelocities(std::vector<OpenMM::Vec3>& atomCoordinates,
std::vector<OpenMM::RealVec>& velocities, std::vector<RealOpenMM>& inverseMasses, RealOpenMM tolerance) { std::vector<OpenMM::Vec3>& velocities, std::vector<double>& inverseMasses, double tolerance) {
applyConstraints(atomCoordinates, velocities, inverseMasses, true, tolerance); applyConstraints(atomCoordinates, velocities, inverseMasses, true, tolerance);
} }
void ReferenceCCMAAlgorithm::applyConstraints(vector<RealVec>& atomCoordinates, void ReferenceCCMAAlgorithm::applyConstraints(vector<Vec3>& atomCoordinates,
vector<RealVec>& atomCoordinatesP, vector<Vec3>& atomCoordinatesP,
vector<RealOpenMM>& inverseMasses, bool constrainingVelocities, RealOpenMM tolerance) { vector<double>& inverseMasses, bool constrainingVelocities, double tolerance) {
// temp arrays // temp arrays
vector<RealVec>& r_ij = _r_ij; vector<Vec3>& r_ij = _r_ij;
RealOpenMM* d_ij2 = _d_ij2; double* d_ij2 = _d_ij2;
RealOpenMM* reducedMasses = _reducedMasses; double* reducedMasses = _reducedMasses;
// calculate reduced masses on 1st pass // calculate reduced masses on 1st pass
...@@ -271,33 +253,33 @@ void ReferenceCCMAAlgorithm::applyConstraints(vector<RealVec>& atomCoordinates, ...@@ -271,33 +253,33 @@ void ReferenceCCMAAlgorithm::applyConstraints(vector<RealVec>& atomCoordinates,
r_ij[ii] = atomCoordinates[atomI] - atomCoordinates[atomJ]; r_ij[ii] = atomCoordinates[atomI] - atomCoordinates[atomJ];
d_ij2[ii] = r_ij[ii].dot(r_ij[ii]); d_ij2[ii] = r_ij[ii].dot(r_ij[ii]);
} }
RealOpenMM lowerTol = 1-2*tolerance+tolerance*tolerance; double lowerTol = 1-2*tolerance+tolerance*tolerance;
RealOpenMM upperTol = 1+2*tolerance+tolerance*tolerance; double upperTol = 1+2*tolerance+tolerance*tolerance;
// main loop // main loop
int iterations = 0; int iterations = 0;
int numberConverged = 0; int numberConverged = 0;
vector<RealOpenMM> constraintDelta(_numberOfConstraints); vector<double> constraintDelta(_numberOfConstraints);
vector<RealOpenMM> tempDelta(_numberOfConstraints); vector<double> tempDelta(_numberOfConstraints);
while (iterations < getMaximumNumberOfIterations()) { while (iterations < getMaximumNumberOfIterations()) {
numberConverged = 0; numberConverged = 0;
for (int ii = 0; ii < _numberOfConstraints; ii++) { for (int ii = 0; ii < _numberOfConstraints; ii++) {
int atomI = _atomIndices[ii].first; int atomI = _atomIndices[ii].first;
int atomJ = _atomIndices[ii].second; int atomJ = _atomIndices[ii].second;
RealVec rp_ij = atomCoordinatesP[atomI] - atomCoordinatesP[atomJ]; Vec3 rp_ij = atomCoordinatesP[atomI] - atomCoordinatesP[atomJ];
if (constrainingVelocities) { if (constrainingVelocities) {
RealOpenMM rrpr = rp_ij.dot(r_ij[ii]); double rrpr = rp_ij.dot(r_ij[ii]);
constraintDelta[ii] = -2*reducedMasses[ii]*rrpr/d_ij2[ii]; constraintDelta[ii] = -2*reducedMasses[ii]*rrpr/d_ij2[ii];
if (fabs(constraintDelta[ii]) <= tolerance) if (fabs(constraintDelta[ii]) <= tolerance)
numberConverged++; numberConverged++;
} }
else { else {
RealOpenMM rp2 = rp_ij.dot(rp_ij); double rp2 = rp_ij.dot(rp_ij);
RealOpenMM dist2 = _distance[ii]*_distance[ii]; double dist2 = _distance[ii]*_distance[ii];
RealOpenMM diff = dist2 - rp2; double diff = dist2 - rp2;
constraintDelta[ii] = 0; constraintDelta[ii] = 0;
RealOpenMM rrpr = DOT3(rp_ij, r_ij[ii]); double rrpr = DOT3(rp_ij, r_ij[ii]);
constraintDelta[ii] = reducedMasses[ii]*diff/rrpr; constraintDelta[ii] = reducedMasses[ii]*diff/rrpr;
if (rp2 >= lowerTol*dist2 && rp2 <= upperTol*dist2) if (rp2 >= lowerTol*dist2 && rp2 <= upperTol*dist2)
numberConverged++; numberConverged++;
...@@ -309,9 +291,9 @@ void ReferenceCCMAAlgorithm::applyConstraints(vector<RealVec>& atomCoordinates, ...@@ -309,9 +291,9 @@ void ReferenceCCMAAlgorithm::applyConstraints(vector<RealVec>& atomCoordinates,
if (_matrix.size() > 0) { if (_matrix.size() > 0) {
for (int i = 0; i < _numberOfConstraints; i++) { for (int i = 0; i < _numberOfConstraints; i++) {
RealOpenMM sum = 0.0; double sum = 0.0;
for (int j = 0; j < (int) _matrix[i].size(); j++) { for (int j = 0; j < (int) _matrix[i].size(); j++) {
pair<int, RealOpenMM> element = _matrix[i][j]; pair<int, double> element = _matrix[i][j];
sum += element.second*constraintDelta[element.first]; sum += element.second*constraintDelta[element.first];
} }
tempDelta[i] = sum; tempDelta[i] = sum;
...@@ -321,13 +303,13 @@ void ReferenceCCMAAlgorithm::applyConstraints(vector<RealVec>& atomCoordinates, ...@@ -321,13 +303,13 @@ void ReferenceCCMAAlgorithm::applyConstraints(vector<RealVec>& atomCoordinates,
for (int ii = 0; ii < _numberOfConstraints; ii++) { for (int ii = 0; ii < _numberOfConstraints; ii++) {
int atomI = _atomIndices[ii].first; int atomI = _atomIndices[ii].first;
int atomJ = _atomIndices[ii].second; int atomJ = _atomIndices[ii].second;
RealVec dr = r_ij[ii]*constraintDelta[ii]; Vec3 dr = r_ij[ii]*constraintDelta[ii];
atomCoordinatesP[atomI] += dr*inverseMasses[atomI]; atomCoordinatesP[atomI] += dr*inverseMasses[atomI];
atomCoordinatesP[atomJ] -= dr*inverseMasses[atomJ]; atomCoordinatesP[atomJ] -= dr*inverseMasses[atomJ];
} }
} }
} }
const vector<vector<pair<int, RealOpenMM> > >& ReferenceCCMAAlgorithm::getMatrix() const { const vector<vector<pair<int, double> > >& ReferenceCCMAAlgorithm::getMatrix() const {
return _matrix; return _matrix;
} }
...@@ -34,12 +34,12 @@ using namespace OpenMM; ...@@ -34,12 +34,12 @@ using namespace OpenMM;
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceCMAPTorsionIxn::ReferenceCMAPTorsionIxn(const vector<vector<vector<RealOpenMM> > >& coeff, ReferenceCMAPTorsionIxn::ReferenceCMAPTorsionIxn(const vector<vector<vector<double> > >& coeff,
const vector<int>& torsionMaps, const vector<vector<int> >& torsionIndices) : const vector<int>& torsionMaps, const vector<vector<int> >& torsionIndices) :
coeff(coeff), torsionMaps(torsionMaps), torsionIndices(torsionIndices), usePeriodic(false) { coeff(coeff), torsionMaps(torsionMaps), torsionIndices(torsionIndices), usePeriodic(false) {
} }
void ReferenceCMAPTorsionIxn::setPeriodic(OpenMM::RealVec* vectors) { void ReferenceCMAPTorsionIxn::setPeriodic(OpenMM::Vec3* vectors) {
usePeriodic = true; usePeriodic = true;
boxVectors[0] = vectors[0]; boxVectors[0] = vectors[0];
boxVectors[1] = vectors[1]; boxVectors[1] = vectors[1];
...@@ -59,7 +59,7 @@ void ReferenceCMAPTorsionIxn::setPeriodic(OpenMM::RealVec* vectors) { ...@@ -59,7 +59,7 @@ void ReferenceCMAPTorsionIxn::setPeriodic(OpenMM::RealVec* vectors) {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCMAPTorsionIxn::calculateIxn(vector<RealVec>& atomCoordinates, vector<RealVec>& forces, RealOpenMM* totalEnergy) const { void ReferenceCMAPTorsionIxn::calculateIxn(vector<Vec3>& atomCoordinates, vector<Vec3>& forces, double* totalEnergy) const {
for (unsigned int i = 0; i < torsionMaps.size(); i++) for (unsigned int i = 0; i < torsionMaps.size(); i++)
calculateOneIxn(i, atomCoordinates, forces, totalEnergy); calculateOneIxn(i, atomCoordinates, forces, totalEnergy);
} }
...@@ -75,8 +75,8 @@ void ReferenceCMAPTorsionIxn::calculateIxn(vector<RealVec>& atomCoordinates, vec ...@@ -75,8 +75,8 @@ void ReferenceCMAPTorsionIxn::calculateIxn(vector<RealVec>& atomCoordinates, vec
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCMAPTorsionIxn::calculateOneIxn(int index, vector<RealVec>& atomCoordinates, vector<RealVec>& forces, void ReferenceCMAPTorsionIxn::calculateOneIxn(int index, vector<Vec3>& atomCoordinates, vector<Vec3>& forces,
RealOpenMM* totalEnergy) const { double* totalEnergy) const {
int map = torsionMaps[index]; int map = torsionMaps[index];
int a1 = torsionIndices[index][0]; int a1 = torsionIndices[index][0];
int a2 = torsionIndices[index][1]; int a2 = torsionIndices[index][1];
...@@ -89,8 +89,8 @@ void ReferenceCMAPTorsionIxn::calculateOneIxn(int index, vector<RealVec>& atomCo ...@@ -89,8 +89,8 @@ void ReferenceCMAPTorsionIxn::calculateOneIxn(int index, vector<RealVec>& atomCo
// Compute deltas between the various atoms involved. // Compute deltas between the various atoms involved.
RealOpenMM deltaA[3][ReferenceForce::LastDeltaRIndex]; double deltaA[3][ReferenceForce::LastDeltaRIndex];
RealOpenMM deltaB[3][ReferenceForce::LastDeltaRIndex]; double deltaB[3][ReferenceForce::LastDeltaRIndex];
if (usePeriodic) { if (usePeriodic) {
ReferenceForce::getDeltaRPeriodic(atomCoordinates[a2], atomCoordinates[a1], boxVectors, deltaA[0]); ReferenceForce::getDeltaRPeriodic(atomCoordinates[a2], atomCoordinates[a1], boxVectors, deltaA[0]);
ReferenceForce::getDeltaRPeriodic(atomCoordinates[a2], atomCoordinates[a3], boxVectors, deltaA[1]); ReferenceForce::getDeltaRPeriodic(atomCoordinates[a2], atomCoordinates[a3], boxVectors, deltaA[1]);
...@@ -110,40 +110,40 @@ void ReferenceCMAPTorsionIxn::calculateOneIxn(int index, vector<RealVec>& atomCo ...@@ -110,40 +110,40 @@ void ReferenceCMAPTorsionIxn::calculateOneIxn(int index, vector<RealVec>& atomCo
// Visual Studio complains if crossProduct declared as 'crossProduct[2][3]' // Visual Studio complains if crossProduct declared as 'crossProduct[2][3]'
RealOpenMM crossProductMemory[12]; double crossProductMemory[12];
RealOpenMM* cpA[2]; double* cpA[2];
cpA[0] = crossProductMemory; cpA[0] = crossProductMemory;
cpA[1] = crossProductMemory + 3; cpA[1] = crossProductMemory + 3;
RealOpenMM* cpB[2]; double* cpB[2];
cpB[0] = crossProductMemory + 6; cpB[0] = crossProductMemory + 6;
cpB[1] = crossProductMemory + 9; cpB[1] = crossProductMemory + 9;
// Compute the dihedral angles. // Compute the dihedral angles.
RealOpenMM dotDihedral; double dotDihedral;
RealOpenMM signOfAngle; double signOfAngle;
RealOpenMM angleA = getDihedralAngleBetweenThreeVectors(deltaA[0], deltaA[1], deltaA[2], double angleA = getDihedralAngleBetweenThreeVectors(deltaA[0], deltaA[1], deltaA[2],
cpA, &dotDihedral, deltaA[0], &signOfAngle, 1); cpA, &dotDihedral, deltaA[0], &signOfAngle, 1);
RealOpenMM angleB = getDihedralAngleBetweenThreeVectors(deltaB[0], deltaB[1], deltaB[2], double angleB = getDihedralAngleBetweenThreeVectors(deltaB[0], deltaB[1], deltaB[2],
cpB, &dotDihedral, deltaB[0], &signOfAngle, 1); cpB, &dotDihedral, deltaB[0], &signOfAngle, 1);
angleA = fmod(angleA+2.0*M_PI, 2.0*M_PI); angleA = fmod(angleA+2.0*M_PI, 2.0*M_PI);
angleB = fmod(angleB+2.0*M_PI, 2.0*M_PI); angleB = fmod(angleB+2.0*M_PI, 2.0*M_PI);
// Identify which patch this is in. // Identify which patch this is in.
int size = (int) SQRT((RealOpenMM) coeff[map].size()); int size = (int) sqrt(coeff[map].size());
RealOpenMM delta = 2*M_PI/size; double delta = 2*M_PI/size;
int s = (int) (angleA/delta); int s = (int) (angleA/delta);
int t = (int) (angleB/delta); int t = (int) (angleB/delta);
const vector<RealOpenMM>& c = coeff[map][s+size*t]; const vector<double>& c = coeff[map][s+size*t];
RealOpenMM da = angleA/delta-s; double da = angleA/delta-s;
RealOpenMM db = angleB/delta-t; double db = angleB/delta-t;
// Evaluate the spline to determine the energy and gradients. // Evaluate the spline to determine the energy and gradients.
RealOpenMM energy = 0; double energy = 0;
RealOpenMM dEdA = 0; double dEdA = 0;
RealOpenMM dEdB = 0; double dEdB = 0;
for (int i = 3; i >= 0; i--) { for (int i = 3; i >= 0; i--) {
energy = da*energy + ((c[i*4+3]*db + c[i*4+2])*db + c[i*4+1])*db + c[i*4+0]; energy = da*energy + ((c[i*4+3]*db + c[i*4+2])*db + c[i*4+1])*db + c[i*4+0];
dEdA = db*dEdA + (3.0*c[i+3*4]*da + 2.0*c[i+2*4])*da + c[i+1*4]; dEdA = db*dEdA + (3.0*c[i+3*4]*da + 2.0*c[i+2*4])*da + c[i+1*4];
...@@ -156,20 +156,20 @@ void ReferenceCMAPTorsionIxn::calculateOneIxn(int index, vector<RealVec>& atomCo ...@@ -156,20 +156,20 @@ void ReferenceCMAPTorsionIxn::calculateOneIxn(int index, vector<RealVec>& atomCo
// Apply the force to the first torsion. // Apply the force to the first torsion.
RealOpenMM forceFactors[4]; double forceFactors[4];
RealOpenMM normCross1 = DOT3(cpA[0], cpA[0]); double normCross1 = DOT3(cpA[0], cpA[0]);
RealOpenMM normBC = deltaA[1][ReferenceForce::RIndex]; double normBC = deltaA[1][ReferenceForce::RIndex];
forceFactors[0] = (-dEdA*normBC)/normCross1; forceFactors[0] = (-dEdA*normBC)/normCross1;
RealOpenMM normCross2 = DOT3(cpA[1], cpA[1]); double normCross2 = DOT3(cpA[1], cpA[1]);
forceFactors[3] = (dEdA*normBC)/normCross2; forceFactors[3] = (dEdA*normBC)/normCross2;
forceFactors[1] = DOT3(deltaA[0], deltaA[1]); forceFactors[1] = DOT3(deltaA[0], deltaA[1]);
forceFactors[1] /= deltaA[1][ReferenceForce::R2Index]; forceFactors[1] /= deltaA[1][ReferenceForce::R2Index];
forceFactors[2] = DOT3(deltaA[2], deltaA[1]); forceFactors[2] = DOT3(deltaA[2], deltaA[1]);
forceFactors[2] /= deltaA[1][ReferenceForce::R2Index]; forceFactors[2] /= deltaA[1][ReferenceForce::R2Index];
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
RealOpenMM f0 = forceFactors[0]*cpA[0][i]; double f0 = forceFactors[0]*cpA[0][i];
RealOpenMM f3 = forceFactors[3]*cpA[1][i]; double f3 = forceFactors[3]*cpA[1][i];
RealOpenMM s = forceFactors[1]*f0 - forceFactors[2]*f3; double s = forceFactors[1]*f0 - forceFactors[2]*f3;
forces[a1][i] += f0; forces[a1][i] += f0;
forces[a2][i] -= f0-s; forces[a2][i] -= f0-s;
forces[a3][i] -= f3+s; forces[a3][i] -= f3+s;
...@@ -188,9 +188,9 @@ void ReferenceCMAPTorsionIxn::calculateOneIxn(int index, vector<RealVec>& atomCo ...@@ -188,9 +188,9 @@ void ReferenceCMAPTorsionIxn::calculateOneIxn(int index, vector<RealVec>& atomCo
forceFactors[2] = DOT3(deltaB[2], deltaB[1]); forceFactors[2] = DOT3(deltaB[2], deltaB[1]);
forceFactors[2] /= deltaB[1][ReferenceForce::R2Index]; forceFactors[2] /= deltaB[1][ReferenceForce::R2Index];
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
RealOpenMM f0 = forceFactors[0]*cpB[0][i]; double f0 = forceFactors[0]*cpB[0][i];
RealOpenMM f3 = forceFactors[3]*cpB[1][i]; double f3 = forceFactors[3]*cpB[1][i];
RealOpenMM s = forceFactors[1]*f0 - forceFactors[2]*f3; double s = forceFactors[1]*f0 - forceFactors[2]*f3;
forces[b1][i] += f0; forces[b1][i] += f0;
forces[b2][i] -= f0-s; forces[b2][i] -= f0-s;
forces[b3][i] -= f3+s; forces[b3][i] -= f3+s;
...@@ -206,6 +206,6 @@ void ReferenceCMAPTorsionIxn::calculateOneIxn(int index, vector<RealVec>& atomCo ...@@ -206,6 +206,6 @@ void ReferenceCMAPTorsionIxn::calculateOneIxn(int index, vector<RealVec>& atomCo
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCMAPTorsionIxn::calculateBondIxn(int* atomIndices, vector<RealVec>& atomCoordinates, void ReferenceCMAPTorsionIxn::calculateBondIxn(int* atomIndices, vector<Vec3>& atomCoordinates,
RealOpenMM* parameters, vector<RealVec>& forces, RealOpenMM* totalEnergy, double* energyParamDerivs) { double* parameters, vector<Vec3>& forces, double* totalEnergy, double* energyParamDerivs) {
} }
...@@ -43,9 +43,9 @@ using namespace std; ...@@ -43,9 +43,9 @@ using namespace std;
ReferenceConstraints::ReferenceConstraints(const System& system) : ccma(NULL), settle(NULL) { ReferenceConstraints::ReferenceConstraints(const System& system) : ccma(NULL), settle(NULL) {
int numParticles = system.getNumParticles(); int numParticles = system.getNumParticles();
vector<RealOpenMM> masses(numParticles); vector<double> masses(numParticles);
for (int i = 0; i < numParticles; ++i) for (int i = 0; i < numParticles; ++i)
masses[i] = (RealOpenMM) system.getParticleMass(i); masses[i] = system.getParticleMass(i);
// Record the set of constraints and how many constraints each atom is involved in. // Record the set of constraints and how many constraints each atom is involved in.
...@@ -102,8 +102,8 @@ ReferenceConstraints::ReferenceConstraints(const System& system) : ccma(NULL), s ...@@ -102,8 +102,8 @@ ReferenceConstraints::ReferenceConstraints(const System& system) : ccma(NULL), s
vector<int> atom1; vector<int> atom1;
vector<int> atom2; vector<int> atom2;
vector<int> atom3; vector<int> atom3;
vector<RealOpenMM> distance1; vector<double> distance1;
vector<RealOpenMM> distance2; vector<double> distance2;
for (int i = 0; i < settleClusters.size(); i++) { for (int i = 0; i < settleClusters.size(); i++) {
int p1 = settleClusters[i]; int p1 = settleClusters[i];
int p2 = settleConstraints[p1].begin()->first; int p2 = settleConstraints[p1].begin()->first;
...@@ -156,7 +156,7 @@ ReferenceConstraints::ReferenceConstraints(const System& system) : ccma(NULL), s ...@@ -156,7 +156,7 @@ ReferenceConstraints::ReferenceConstraints(const System& system) : ccma(NULL), s
// Record particles and distances for CCMA. // Record particles and distances for CCMA.
vector<pair<int, int> > ccmaIndices(numCCMA); vector<pair<int, int> > ccmaIndices(numCCMA);
vector<RealOpenMM> ccmaDistance(numCCMA); vector<double> ccmaDistance(numCCMA);
for (int i = 0; i < numCCMA; i++) { for (int i = 0; i < numCCMA; i++) {
int index = ccmaConstraints[i]; int index = ccmaConstraints[i];
ccmaIndices[i] = make_pair(atom1[index], atom2[index]); ccmaIndices[i] = make_pair(atom1[index], atom2[index]);
...@@ -173,7 +173,7 @@ ReferenceConstraints::ReferenceConstraints(const System& system) : ccma(NULL), s ...@@ -173,7 +173,7 @@ ReferenceConstraints::ReferenceConstraints(const System& system) : ccma(NULL), s
int atom1, atom2, atom3; int atom1, atom2, atom3;
double angle, k; double angle, k;
force->getAngleParameters(j, atom1, atom2, atom3, angle, k); force->getAngleParameters(j, atom1, atom2, atom3, angle, k);
angles.push_back(ReferenceCCMAAlgorithm::AngleInfo(atom1, atom2, atom3, (RealOpenMM) angle)); angles.push_back(ReferenceCCMAAlgorithm::AngleInfo(atom1, atom2, atom3, angle));
} }
} }
} }
...@@ -191,14 +191,14 @@ ReferenceConstraints::~ReferenceConstraints() { ...@@ -191,14 +191,14 @@ ReferenceConstraints::~ReferenceConstraints() {
delete settle; delete settle;
} }
void ReferenceConstraints::apply(vector<OpenMM::RealVec>& atomCoordinates, vector<OpenMM::RealVec>& atomCoordinatesP, vector<RealOpenMM>& inverseMasses, RealOpenMM tolerance) { void ReferenceConstraints::apply(vector<OpenMM::Vec3>& atomCoordinates, vector<OpenMM::Vec3>& atomCoordinatesP, vector<double>& inverseMasses, double tolerance) {
if (ccma != NULL) if (ccma != NULL)
ccma->apply(atomCoordinates, atomCoordinatesP, inverseMasses, tolerance); ccma->apply(atomCoordinates, atomCoordinatesP, inverseMasses, tolerance);
if (settle != NULL) if (settle != NULL)
settle->apply(atomCoordinates, atomCoordinatesP, inverseMasses, tolerance); settle->apply(atomCoordinates, atomCoordinatesP, inverseMasses, tolerance);
} }
void ReferenceConstraints::applyToVelocities(vector<OpenMM::RealVec>& atomCoordinates, vector<OpenMM::RealVec>& velocities, vector<RealOpenMM>& inverseMasses, RealOpenMM tolerance) { void ReferenceConstraints::applyToVelocities(vector<OpenMM::Vec3>& atomCoordinates, vector<OpenMM::Vec3>& velocities, vector<double>& inverseMasses, double tolerance) {
if (ccma != NULL) if (ccma != NULL)
ccma->applyToVelocities(atomCoordinates, velocities, inverseMasses, tolerance); ccma->applyToVelocities(atomCoordinates, velocities, inverseMasses, tolerance);
if (settle != NULL) if (settle != NULL)
......
...@@ -62,7 +62,7 @@ ReferenceCustomAngleIxn::ReferenceCustomAngleIxn(const Lepton::CompiledExpressio ...@@ -62,7 +62,7 @@ ReferenceCustomAngleIxn::ReferenceCustomAngleIxn(const Lepton::CompiledExpressio
ReferenceCustomAngleIxn::~ReferenceCustomAngleIxn() { ReferenceCustomAngleIxn::~ReferenceCustomAngleIxn() {
} }
void ReferenceCustomAngleIxn::setPeriodic(OpenMM::RealVec* vectors) { void ReferenceCustomAngleIxn::setPeriodic(OpenMM::Vec3* vectors) {
usePeriodic = true; usePeriodic = true;
boxVectors[0] = vectors[0]; boxVectors[0] = vectors[0];
boxVectors[1] = vectors[1]; boxVectors[1] = vectors[1];
...@@ -82,11 +82,11 @@ void ReferenceCustomAngleIxn::setPeriodic(OpenMM::RealVec* vectors) { ...@@ -82,11 +82,11 @@ void ReferenceCustomAngleIxn::setPeriodic(OpenMM::RealVec* vectors) {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomAngleIxn::calculateBondIxn(int* atomIndices, void ReferenceCustomAngleIxn::calculateBondIxn(int* atomIndices,
vector<RealVec>& atomCoordinates, vector<Vec3>& atomCoordinates,
RealOpenMM* parameters, double* parameters,
vector<RealVec>& forces, vector<Vec3>& forces,
RealOpenMM* totalEnergy, double* energyParamDerivs) { double* totalEnergy, double* energyParamDerivs) {
RealOpenMM deltaR[2][ReferenceForce::LastDeltaRIndex]; double deltaR[2][ReferenceForce::LastDeltaRIndex];
for (int i = 0; i < numParameters; i++) for (int i = 0; i < numParameters; i++)
expressionSet.setVariable(angleParamIndex[i], parameters[i]); expressionSet.setVariable(angleParamIndex[i], parameters[i]);
...@@ -105,30 +105,30 @@ void ReferenceCustomAngleIxn::calculateBondIxn(int* atomIndices, ...@@ -105,30 +105,30 @@ void ReferenceCustomAngleIxn::calculateBondIxn(int* atomIndices,
ReferenceForce::getDeltaR(atomCoordinates[atomAIndex], atomCoordinates[atomBIndex], deltaR[0]); ReferenceForce::getDeltaR(atomCoordinates[atomAIndex], atomCoordinates[atomBIndex], deltaR[0]);
ReferenceForce::getDeltaR(atomCoordinates[atomCIndex], atomCoordinates[atomBIndex], deltaR[1]); ReferenceForce::getDeltaR(atomCoordinates[atomCIndex], atomCoordinates[atomBIndex], deltaR[1]);
} }
RealOpenMM pVector[3]; double pVector[3];
SimTKOpenMMUtilities::crossProductVector3(deltaR[0], deltaR[1], pVector); SimTKOpenMMUtilities::crossProductVector3(deltaR[0], deltaR[1], pVector);
RealOpenMM rp = SQRT(DOT3(pVector, pVector)); double rp = sqrt(DOT3(pVector, pVector));
if (rp < 1.0e-06) if (rp < 1.0e-06)
rp = (RealOpenMM) 1.0e-06; rp = 1.0e-06;
RealOpenMM dot = DOT3(deltaR[0], deltaR[1]); double dot = DOT3(deltaR[0], deltaR[1]);
RealOpenMM cosine = dot/SQRT((deltaR[0][ReferenceForce::R2Index]*deltaR[1][ReferenceForce::R2Index])); double cosine = dot/sqrt((deltaR[0][ReferenceForce::R2Index]*deltaR[1][ReferenceForce::R2Index]));
RealOpenMM angle; double angle;
if (cosine >= 1.0) if (cosine >= 1.0)
angle = 0.0; angle = 0.0;
else if (cosine <= -1.0) else if (cosine <= -1.0)
angle = PI_M; angle = PI_M;
else else
angle = ACOS(cosine); angle = acos(cosine);
expressionSet.setVariable(thetaIndex, angle); expressionSet.setVariable(thetaIndex, angle);
// Compute the force and energy, and apply them to the atoms. // Compute the force and energy, and apply them to the atoms.
RealOpenMM energy = (RealOpenMM) energyExpression.evaluate(); double energy = energyExpression.evaluate();
RealOpenMM dEdR = (RealOpenMM) forceExpression.evaluate(); double dEdR = forceExpression.evaluate();
RealOpenMM termA = dEdR/(deltaR[0][ReferenceForce::R2Index]*rp); double termA = dEdR/(deltaR[0][ReferenceForce::R2Index]*rp);
RealOpenMM termC = -dEdR/(deltaR[1][ReferenceForce::R2Index]*rp); double termC = -dEdR/(deltaR[1][ReferenceForce::R2Index]*rp);
RealOpenMM deltaCrossP[3][3]; double deltaCrossP[3][3];
SimTKOpenMMUtilities::crossProductVector3(deltaR[0], pVector, deltaCrossP[0]); SimTKOpenMMUtilities::crossProductVector3(deltaR[0], pVector, deltaCrossP[0]);
SimTKOpenMMUtilities::crossProductVector3(deltaR[1], pVector, deltaCrossP[2]); SimTKOpenMMUtilities::crossProductVector3(deltaR[1], pVector, deltaCrossP[2]);
......
...@@ -63,7 +63,7 @@ ReferenceCustomBondIxn::ReferenceCustomBondIxn(const Lepton::CompiledExpression& ...@@ -63,7 +63,7 @@ ReferenceCustomBondIxn::ReferenceCustomBondIxn(const Lepton::CompiledExpression&
ReferenceCustomBondIxn::~ReferenceCustomBondIxn() { ReferenceCustomBondIxn::~ReferenceCustomBondIxn() {
} }
void ReferenceCustomBondIxn::setPeriodic(OpenMM::RealVec* vectors) { void ReferenceCustomBondIxn::setPeriodic(OpenMM::Vec3* vectors) {
usePeriodic = true; usePeriodic = true;
boxVectors[0] = vectors[0]; boxVectors[0] = vectors[0];
boxVectors[1] = vectors[1]; boxVectors[1] = vectors[1];
...@@ -83,11 +83,11 @@ void ReferenceCustomBondIxn::setPeriodic(OpenMM::RealVec* vectors) { ...@@ -83,11 +83,11 @@ void ReferenceCustomBondIxn::setPeriodic(OpenMM::RealVec* vectors) {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomBondIxn::calculateBondIxn(int* atomIndices, void ReferenceCustomBondIxn::calculateBondIxn(int* atomIndices,
vector<RealVec>& atomCoordinates, vector<Vec3>& atomCoordinates,
RealOpenMM* parameters, double* parameters,
vector<RealVec>& forces, vector<Vec3>& forces,
RealOpenMM* totalEnergy, double* energyParamDerivs) { double* totalEnergy, double* energyParamDerivs) {
RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; double deltaR[ReferenceForce::LastDeltaRIndex];
for (int i = 0; i < numParameters; i++) for (int i = 0; i < numParameters; i++)
expressionSet.setVariable(bondParamIndex[i], parameters[i]); expressionSet.setVariable(bondParamIndex[i], parameters[i]);
...@@ -103,19 +103,19 @@ void ReferenceCustomBondIxn::calculateBondIxn(int* atomIndices, ...@@ -103,19 +103,19 @@ void ReferenceCustomBondIxn::calculateBondIxn(int* atomIndices,
ReferenceForce::getDeltaR(atomCoordinates[atomAIndex], atomCoordinates[atomBIndex], deltaR); ReferenceForce::getDeltaR(atomCoordinates[atomAIndex], atomCoordinates[atomBIndex], deltaR);
expressionSet.setVariable(rIndex, deltaR[ReferenceForce::RIndex]); expressionSet.setVariable(rIndex, deltaR[ReferenceForce::RIndex]);
RealOpenMM dEdR = (RealOpenMM) forceExpression.evaluate(); double dEdR = forceExpression.evaluate();
dEdR = deltaR[ReferenceForce::RIndex] > 0 ? (dEdR/deltaR[ReferenceForce::RIndex]) : 0; dEdR = deltaR[ReferenceForce::RIndex] > 0 ? (dEdR/deltaR[ReferenceForce::RIndex]) : 0;
forces[atomAIndex][0] += dEdR*deltaR[ReferenceForce::XIndex]; forces[atomAIndex][0] += dEdR*deltaR[ReferenceForce::XIndex];
forces[atomAIndex][1] += dEdR*deltaR[ReferenceForce::YIndex]; forces[atomAIndex][1] += dEdR*deltaR[ReferenceForce::YIndex];
forces[atomAIndex][2] += dEdR*deltaR[ReferenceForce::ZIndex]; forces[atomAIndex][2] += dEdR*deltaR[ReferenceForce::ZIndex];
forces[atomBIndex][0] -= dEdR*deltaR[ReferenceForce::XIndex]; forces[atomBIndex][0] -= dEdR*deltaR[ReferenceForce::XIndex];
forces[atomBIndex][1] -= dEdR*deltaR[ReferenceForce::YIndex]; forces[atomBIndex][1] -= dEdR*deltaR[ReferenceForce::YIndex];
forces[atomBIndex][2] -= dEdR*deltaR[ReferenceForce::ZIndex]; forces[atomBIndex][2] -= dEdR*deltaR[ReferenceForce::ZIndex];
for (int i = 0; i < energyParamDerivExpressions.size(); i++) for (int i = 0; i < energyParamDerivExpressions.size(); i++)
energyParamDerivs[i] += energyParamDerivExpressions[i].evaluate(); energyParamDerivs[i] += energyParamDerivExpressions[i].evaluate();
if (totalEnergy != NULL) if (totalEnergy != NULL)
*totalEnergy += (RealOpenMM) energyExpression.evaluate(); *totalEnergy += energyExpression.evaluate();
} }
...@@ -86,21 +86,21 @@ ReferenceCustomCentroidBondIxn::ReferenceCustomCentroidBondIxn(int numGroupsPerB ...@@ -86,21 +86,21 @@ ReferenceCustomCentroidBondIxn::ReferenceCustomCentroidBondIxn(int numGroupsPerB
ReferenceCustomCentroidBondIxn::~ReferenceCustomCentroidBondIxn() { ReferenceCustomCentroidBondIxn::~ReferenceCustomCentroidBondIxn() {
} }
void ReferenceCustomCentroidBondIxn::setPeriodic(OpenMM::RealVec* vectors) { void ReferenceCustomCentroidBondIxn::setPeriodic(OpenMM::Vec3* vectors) {
usePeriodic = true; usePeriodic = true;
boxVectors[0] = vectors[0]; boxVectors[0] = vectors[0];
boxVectors[1] = vectors[1]; boxVectors[1] = vectors[1];
boxVectors[2] = vectors[2]; boxVectors[2] = vectors[2];
} }
void ReferenceCustomCentroidBondIxn::calculatePairIxn(vector<RealVec>& atomCoordinates, RealOpenMM** bondParameters, void ReferenceCustomCentroidBondIxn::calculatePairIxn(vector<Vec3>& atomCoordinates, double** bondParameters,
const map<string, double>& globalParameters, vector<RealVec>& forces, const map<string, double>& globalParameters, vector<Vec3>& forces,
RealOpenMM* totalEnergy, double* energyParamDerivs) { double* totalEnergy, double* energyParamDerivs) {
// First compute the center of each group. // First compute the center of each group.
int numGroups = groupAtoms.size(); int numGroups = groupAtoms.size();
vector<RealVec> groupCenters(numGroups); vector<Vec3> groupCenters(numGroups);
for (int group = 0; group < numGroups; group++) { for (int group = 0; group < numGroups; group++) {
for (int i = 0; i < groupAtoms[group].size(); i++) for (int i = 0; i < groupAtoms[group].size(); i++)
groupCenters[group] += atomCoordinates[groupAtoms[group][i]]*normalizedWeights[group][i]; groupCenters[group] += atomCoordinates[groupAtoms[group][i]]*normalizedWeights[group][i];
...@@ -110,7 +110,7 @@ void ReferenceCustomCentroidBondIxn::calculatePairIxn(vector<RealVec>& atomCoord ...@@ -110,7 +110,7 @@ void ReferenceCustomCentroidBondIxn::calculatePairIxn(vector<RealVec>& atomCoord
for (map<string, double>::const_iterator iter = globalParameters.begin(); iter != globalParameters.end(); ++iter) for (map<string, double>::const_iterator iter = globalParameters.begin(); iter != globalParameters.end(); ++iter)
expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second); expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second);
vector<RealVec> groupForces(numGroups); vector<Vec3> groupForces(numGroups);
int numBonds = bondGroups.size(); int numBonds = bondGroups.size();
for (int bond = 0; bond < numBonds; bond++) { for (int bond = 0; bond < numBonds; bond++) {
for (int i = 0; i < numParameters; i++) for (int i = 0; i < numParameters; i++)
...@@ -126,8 +126,8 @@ void ReferenceCustomCentroidBondIxn::calculatePairIxn(vector<RealVec>& atomCoord ...@@ -126,8 +126,8 @@ void ReferenceCustomCentroidBondIxn::calculatePairIxn(vector<RealVec>& atomCoord
} }
} }
void ReferenceCustomCentroidBondIxn::calculateOneIxn(int bond, vector<RealVec>& groupCenters, void ReferenceCustomCentroidBondIxn::calculateOneIxn(int bond, vector<Vec3>& groupCenters,
vector<RealVec>& forces, RealOpenMM* totalEnergy, double* energyParamDerivs) { vector<Vec3>& forces, double* totalEnergy, double* energyParamDerivs) {
// Compute all of the variables the energy can depend on. // Compute all of the variables the energy can depend on.
const vector<int>& groups = bondGroups[bond]; const vector<int>& groups = bondGroups[bond];
...@@ -151,8 +151,8 @@ void ReferenceCustomCentroidBondIxn::calculateOneIxn(int bond, vector<RealVec>& ...@@ -151,8 +151,8 @@ void ReferenceCustomCentroidBondIxn::calculateOneIxn(int bond, vector<RealVec>&
computeDelta(groups[term.g2], groups[term.g1], term.delta1, groupCenters); computeDelta(groups[term.g2], groups[term.g1], term.delta1, groupCenters);
computeDelta(groups[term.g2], groups[term.g3], term.delta2, groupCenters); computeDelta(groups[term.g2], groups[term.g3], term.delta2, groupCenters);
computeDelta(groups[term.g4], groups[term.g3], term.delta3, groupCenters); computeDelta(groups[term.g4], groups[term.g3], term.delta3, groupCenters);
RealOpenMM dotDihedral, signOfDihedral; double dotDihedral, signOfDihedral;
RealOpenMM* crossProduct[] = {term.cross1, term.cross2}; double* crossProduct[] = {term.cross1, term.cross2};
expressionSet.setVariable(term.index, getDihedralAngleBetweenThreeVectors(term.delta1, term.delta2, term.delta3, crossProduct, &dotDihedral, term.delta1, &signOfDihedral, 1)); expressionSet.setVariable(term.index, getDihedralAngleBetweenThreeVectors(term.delta1, term.delta2, term.delta3, crossProduct, &dotDihedral, term.delta1, &signOfDihedral, 1));
} }
...@@ -167,9 +167,9 @@ void ReferenceCustomCentroidBondIxn::calculateOneIxn(int bond, vector<RealVec>& ...@@ -167,9 +167,9 @@ void ReferenceCustomCentroidBondIxn::calculateOneIxn(int bond, vector<RealVec>&
for (int i = 0; i < (int) distanceTerms.size(); i++) { for (int i = 0; i < (int) distanceTerms.size(); i++) {
const DistanceTermInfo& term = distanceTerms[i]; const DistanceTermInfo& term = distanceTerms[i];
RealOpenMM dEdR = (RealOpenMM) (term.forceExpression.evaluate()/(term.delta[ReferenceForce::RIndex])); double dEdR = term.forceExpression.evaluate()/(term.delta[ReferenceForce::RIndex]);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
RealOpenMM force = -dEdR*term.delta[i]; double force = -dEdR*term.delta[i];
forces[groups[term.g1]][i] -= force; forces[groups[term.g1]][i] -= force;
forces[groups[term.g2]][i] += force; forces[groups[term.g2]][i] += force;
} }
...@@ -179,15 +179,15 @@ void ReferenceCustomCentroidBondIxn::calculateOneIxn(int bond, vector<RealVec>& ...@@ -179,15 +179,15 @@ void ReferenceCustomCentroidBondIxn::calculateOneIxn(int bond, vector<RealVec>&
for (int i = 0; i < (int) angleTerms.size(); i++) { for (int i = 0; i < (int) angleTerms.size(); i++) {
const AngleTermInfo& term = angleTerms[i]; const AngleTermInfo& term = angleTerms[i];
RealOpenMM dEdTheta = (RealOpenMM) term.forceExpression.evaluate(); double dEdTheta = term.forceExpression.evaluate();
RealOpenMM thetaCross[ReferenceForce::LastDeltaRIndex]; double thetaCross[ReferenceForce::LastDeltaRIndex];
SimTKOpenMMUtilities::crossProductVector3(term.delta1, term.delta2, thetaCross); SimTKOpenMMUtilities::crossProductVector3(term.delta1, term.delta2, thetaCross);
RealOpenMM lengthThetaCross = SQRT(DOT3(thetaCross, thetaCross)); double lengthThetaCross = sqrt(DOT3(thetaCross, thetaCross));
if (lengthThetaCross < 1.0e-06) if (lengthThetaCross < 1.0e-06)
lengthThetaCross = (RealOpenMM) 1.0e-06; lengthThetaCross = 1.0e-06;
RealOpenMM termA = dEdTheta/(term.delta1[ReferenceForce::R2Index]*lengthThetaCross); double termA = dEdTheta/(term.delta1[ReferenceForce::R2Index]*lengthThetaCross);
RealOpenMM termC = -dEdTheta/(term.delta2[ReferenceForce::R2Index]*lengthThetaCross); double termC = -dEdTheta/(term.delta2[ReferenceForce::R2Index]*lengthThetaCross);
RealOpenMM deltaCrossP[3][3]; double deltaCrossP[3][3];
SimTKOpenMMUtilities::crossProductVector3(term.delta1, thetaCross, deltaCrossP[0]); SimTKOpenMMUtilities::crossProductVector3(term.delta1, thetaCross, deltaCrossP[0]);
SimTKOpenMMUtilities::crossProductVector3(term.delta2, thetaCross, deltaCrossP[2]); SimTKOpenMMUtilities::crossProductVector3(term.delta2, thetaCross, deltaCrossP[2]);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
...@@ -206,22 +206,22 @@ void ReferenceCustomCentroidBondIxn::calculateOneIxn(int bond, vector<RealVec>& ...@@ -206,22 +206,22 @@ void ReferenceCustomCentroidBondIxn::calculateOneIxn(int bond, vector<RealVec>&
for (int i = 0; i < (int) dihedralTerms.size(); i++) { for (int i = 0; i < (int) dihedralTerms.size(); i++) {
const DihedralTermInfo& term = dihedralTerms[i]; const DihedralTermInfo& term = dihedralTerms[i];
RealOpenMM dEdTheta = (RealOpenMM) term.forceExpression.evaluate(); double dEdTheta = term.forceExpression.evaluate();
RealOpenMM internalF[4][3]; double internalF[4][3];
RealOpenMM forceFactors[4]; double forceFactors[4];
RealOpenMM normCross1 = DOT3(term.cross1, term.cross1); double normCross1 = DOT3(term.cross1, term.cross1);
RealOpenMM normBC = term.delta2[ReferenceForce::RIndex]; double normBC = term.delta2[ReferenceForce::RIndex];
forceFactors[0] = (-dEdTheta*normBC)/normCross1; forceFactors[0] = (-dEdTheta*normBC)/normCross1;
RealOpenMM normCross2 = DOT3(term.cross2, term.cross2); double normCross2 = DOT3(term.cross2, term.cross2);
forceFactors[3] = (dEdTheta*normBC)/normCross2; forceFactors[3] = (dEdTheta*normBC)/normCross2;
forceFactors[1] = DOT3(term.delta1, term.delta2); forceFactors[1] = DOT3(term.delta1, term.delta2);
forceFactors[1] /= term.delta2[ReferenceForce::R2Index]; forceFactors[1] /= term.delta2[ReferenceForce::R2Index];
forceFactors[2] = DOT3(term.delta3, term.delta2); forceFactors[2] = DOT3(term.delta3, term.delta2);
forceFactors[2] /= term.delta2[ReferenceForce::R2Index]; forceFactors[2] /= term.delta2[ReferenceForce::R2Index];
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
internalF[0][i] = forceFactors[0]*term.cross1[i]; internalF[0][i] = forceFactors[0]*term.cross1[i];
internalF[3][i] = forceFactors[3]*term.cross2[i]; internalF[3][i] = forceFactors[3]*term.cross2[i];
RealOpenMM s = forceFactors[1]*internalF[0][i] - forceFactors[2]*internalF[3][i]; double s = forceFactors[1]*internalF[0][i] - forceFactors[2]*internalF[3][i];
internalF[1][i] = internalF[0][i] - s; internalF[1][i] = internalF[0][i] - s;
internalF[2][i] = internalF[3][i] + s; internalF[2][i] = internalF[3][i] + s;
} }
...@@ -236,7 +236,7 @@ void ReferenceCustomCentroidBondIxn::calculateOneIxn(int bond, vector<RealVec>& ...@@ -236,7 +236,7 @@ void ReferenceCustomCentroidBondIxn::calculateOneIxn(int bond, vector<RealVec>&
// Add the energy // Add the energy
if (totalEnergy) if (totalEnergy)
*totalEnergy += (RealOpenMM) energyExpression.evaluate(); *totalEnergy += energyExpression.evaluate();
// Compute derivatives of the energy. // Compute derivatives of the energy.
...@@ -244,22 +244,22 @@ void ReferenceCustomCentroidBondIxn::calculateOneIxn(int bond, vector<RealVec>& ...@@ -244,22 +244,22 @@ void ReferenceCustomCentroidBondIxn::calculateOneIxn(int bond, vector<RealVec>&
energyParamDerivs[i] += energyParamDerivExpressions[i].evaluate(); energyParamDerivs[i] += energyParamDerivExpressions[i].evaluate();
} }
void ReferenceCustomCentroidBondIxn::computeDelta(int group1, int group2, RealOpenMM* delta, vector<RealVec>& groupCenters) const { void ReferenceCustomCentroidBondIxn::computeDelta(int group1, int group2, double* delta, vector<Vec3>& groupCenters) const {
if (usePeriodic) if (usePeriodic)
ReferenceForce::getDeltaRPeriodic(groupCenters[group1], groupCenters[group2], boxVectors, delta); ReferenceForce::getDeltaRPeriodic(groupCenters[group1], groupCenters[group2], boxVectors, delta);
else else
ReferenceForce::getDeltaR(groupCenters[group1], groupCenters[group2], delta); ReferenceForce::getDeltaR(groupCenters[group1], groupCenters[group2], delta);
} }
RealOpenMM ReferenceCustomCentroidBondIxn::computeAngle(RealOpenMM* vec1, RealOpenMM* vec2) { double ReferenceCustomCentroidBondIxn::computeAngle(double* vec1, double* vec2) {
RealOpenMM dot = DOT3(vec1, vec2); double dot = DOT3(vec1, vec2);
RealOpenMM cosine = dot/SQRT((vec1[ReferenceForce::R2Index]*vec2[ReferenceForce::R2Index])); double cosine = dot/sqrt((vec1[ReferenceForce::R2Index]*vec2[ReferenceForce::R2Index]));
RealOpenMM angle; double angle;
if (cosine >= 1) if (cosine >= 1)
angle = 0; angle = 0;
else if (cosine <= -1) else if (cosine <= -1)
angle = PI_M; angle = PI_M;
else else
angle = ACOS(cosine); angle = acos(cosine);
return angle; return angle;
} }
...@@ -97,7 +97,7 @@ ReferenceCustomCompoundBondIxn::ReferenceCustomCompoundBondIxn(int numParticlesP ...@@ -97,7 +97,7 @@ ReferenceCustomCompoundBondIxn::ReferenceCustomCompoundBondIxn(int numParticlesP
ReferenceCustomCompoundBondIxn::~ReferenceCustomCompoundBondIxn() { ReferenceCustomCompoundBondIxn::~ReferenceCustomCompoundBondIxn() {
} }
void ReferenceCustomCompoundBondIxn::setPeriodic(OpenMM::RealVec* vectors) { void ReferenceCustomCompoundBondIxn::setPeriodic(OpenMM::Vec3* vectors) {
usePeriodic = true; usePeriodic = true;
boxVectors[0] = vectors[0]; boxVectors[0] = vectors[0];
boxVectors[1] = vectors[1]; boxVectors[1] = vectors[1];
...@@ -116,9 +116,9 @@ void ReferenceCustomCompoundBondIxn::setPeriodic(OpenMM::RealVec* vectors) { ...@@ -116,9 +116,9 @@ void ReferenceCustomCompoundBondIxn::setPeriodic(OpenMM::RealVec* vectors) {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomCompoundBondIxn::calculatePairIxn(vector<RealVec>& atomCoordinates, RealOpenMM** bondParameters, void ReferenceCustomCompoundBondIxn::calculatePairIxn(vector<Vec3>& atomCoordinates, double** bondParameters,
const map<string, double>& globalParameters, vector<RealVec>& forces, const map<string, double>& globalParameters, vector<Vec3>& forces,
RealOpenMM* totalEnergy, double* energyParamDerivs) { double* totalEnergy, double* energyParamDerivs) {
for (map<string, double>::const_iterator iter = globalParameters.begin(); iter != globalParameters.end(); ++iter) for (map<string, double>::const_iterator iter = globalParameters.begin(); iter != globalParameters.end(); ++iter)
expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second); expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second);
int numBonds = bondAtoms.size(); int numBonds = bondAtoms.size();
...@@ -141,8 +141,8 @@ void ReferenceCustomCompoundBondIxn::calculatePairIxn(vector<RealVec>& atomCoord ...@@ -141,8 +141,8 @@ void ReferenceCustomCompoundBondIxn::calculatePairIxn(vector<RealVec>& atomCoord
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector<RealVec>& atomCoordinates, void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector<Vec3>& atomCoordinates,
vector<RealVec>& forces, RealOpenMM* totalEnergy, double* energyParamDerivs) { vector<Vec3>& forces, double* totalEnergy, double* energyParamDerivs) {
// Compute all of the variables the energy can depend on. // Compute all of the variables the energy can depend on.
const vector<int>& atoms = bondAtoms[bond]; const vector<int>& atoms = bondAtoms[bond];
...@@ -166,8 +166,8 @@ void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector<RealVec>& ...@@ -166,8 +166,8 @@ void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector<RealVec>&
computeDelta(atoms[term.p2], atoms[term.p1], term.delta1, atomCoordinates); computeDelta(atoms[term.p2], atoms[term.p1], term.delta1, atomCoordinates);
computeDelta(atoms[term.p2], atoms[term.p3], term.delta2, atomCoordinates); computeDelta(atoms[term.p2], atoms[term.p3], term.delta2, atomCoordinates);
computeDelta(atoms[term.p4], atoms[term.p3], term.delta3, atomCoordinates); computeDelta(atoms[term.p4], atoms[term.p3], term.delta3, atomCoordinates);
RealOpenMM dotDihedral, signOfDihedral; double dotDihedral, signOfDihedral;
RealOpenMM* crossProduct[] = {term.cross1, term.cross2}; double* crossProduct[] = {term.cross1, term.cross2};
expressionSet.setVariable(term.index,getDihedralAngleBetweenThreeVectors(term.delta1, term.delta2, term.delta3, crossProduct, &dotDihedral, term.delta1, &signOfDihedral, 1)); expressionSet.setVariable(term.index,getDihedralAngleBetweenThreeVectors(term.delta1, term.delta2, term.delta3, crossProduct, &dotDihedral, term.delta1, &signOfDihedral, 1));
} }
...@@ -182,9 +182,9 @@ void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector<RealVec>& ...@@ -182,9 +182,9 @@ void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector<RealVec>&
for (int i = 0; i < (int) distanceTerms.size(); i++) { for (int i = 0; i < (int) distanceTerms.size(); i++) {
const DistanceTermInfo& term = distanceTerms[i]; const DistanceTermInfo& term = distanceTerms[i];
RealOpenMM dEdR = (RealOpenMM) (term.forceExpression.evaluate()/(term.delta[ReferenceForce::RIndex])); double dEdR = term.forceExpression.evaluate()/(term.delta[ReferenceForce::RIndex]);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
RealOpenMM force = -dEdR*term.delta[i]; double force = -dEdR*term.delta[i];
forces[atoms[term.p1]][i] -= force; forces[atoms[term.p1]][i] -= force;
forces[atoms[term.p2]][i] += force; forces[atoms[term.p2]][i] += force;
} }
...@@ -194,15 +194,15 @@ void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector<RealVec>& ...@@ -194,15 +194,15 @@ void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector<RealVec>&
for (int i = 0; i < (int) angleTerms.size(); i++) { for (int i = 0; i < (int) angleTerms.size(); i++) {
const AngleTermInfo& term = angleTerms[i]; const AngleTermInfo& term = angleTerms[i];
RealOpenMM dEdTheta = (RealOpenMM) term.forceExpression.evaluate(); double dEdTheta = term.forceExpression.evaluate();
RealOpenMM thetaCross[ReferenceForce::LastDeltaRIndex]; double thetaCross[ReferenceForce::LastDeltaRIndex];
SimTKOpenMMUtilities::crossProductVector3(term.delta1, term.delta2, thetaCross); SimTKOpenMMUtilities::crossProductVector3(term.delta1, term.delta2, thetaCross);
RealOpenMM lengthThetaCross = SQRT(DOT3(thetaCross, thetaCross)); double lengthThetaCross = sqrt(DOT3(thetaCross, thetaCross));
if (lengthThetaCross < 1.0e-06) if (lengthThetaCross < 1.0e-06)
lengthThetaCross = (RealOpenMM) 1.0e-06; lengthThetaCross = 1.0e-06;
RealOpenMM termA = dEdTheta/(term.delta1[ReferenceForce::R2Index]*lengthThetaCross); double termA = dEdTheta/(term.delta1[ReferenceForce::R2Index]*lengthThetaCross);
RealOpenMM termC = -dEdTheta/(term.delta2[ReferenceForce::R2Index]*lengthThetaCross); double termC = -dEdTheta/(term.delta2[ReferenceForce::R2Index]*lengthThetaCross);
RealOpenMM deltaCrossP[3][3]; double deltaCrossP[3][3];
SimTKOpenMMUtilities::crossProductVector3(term.delta1, thetaCross, deltaCrossP[0]); SimTKOpenMMUtilities::crossProductVector3(term.delta1, thetaCross, deltaCrossP[0]);
SimTKOpenMMUtilities::crossProductVector3(term.delta2, thetaCross, deltaCrossP[2]); SimTKOpenMMUtilities::crossProductVector3(term.delta2, thetaCross, deltaCrossP[2]);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
...@@ -221,22 +221,22 @@ void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector<RealVec>& ...@@ -221,22 +221,22 @@ void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector<RealVec>&
for (int i = 0; i < (int) dihedralTerms.size(); i++) { for (int i = 0; i < (int) dihedralTerms.size(); i++) {
const DihedralTermInfo& term = dihedralTerms[i]; const DihedralTermInfo& term = dihedralTerms[i];
RealOpenMM dEdTheta = (RealOpenMM) term.forceExpression.evaluate(); double dEdTheta = term.forceExpression.evaluate();
RealOpenMM internalF[4][3]; double internalF[4][3];
RealOpenMM forceFactors[4]; double forceFactors[4];
RealOpenMM normCross1 = DOT3(term.cross1, term.cross1); double normCross1 = DOT3(term.cross1, term.cross1);
RealOpenMM normBC = term.delta2[ReferenceForce::RIndex]; double normBC = term.delta2[ReferenceForce::RIndex];
forceFactors[0] = (-dEdTheta*normBC)/normCross1; forceFactors[0] = (-dEdTheta*normBC)/normCross1;
RealOpenMM normCross2 = DOT3(term.cross2, term.cross2); double normCross2 = DOT3(term.cross2, term.cross2);
forceFactors[3] = (dEdTheta*normBC)/normCross2; forceFactors[3] = (dEdTheta*normBC)/normCross2;
forceFactors[1] = DOT3(term.delta1, term.delta2); forceFactors[1] = DOT3(term.delta1, term.delta2);
forceFactors[1] /= term.delta2[ReferenceForce::R2Index]; forceFactors[1] /= term.delta2[ReferenceForce::R2Index];
forceFactors[2] = DOT3(term.delta3, term.delta2); forceFactors[2] = DOT3(term.delta3, term.delta2);
forceFactors[2] /= term.delta2[ReferenceForce::R2Index]; forceFactors[2] /= term.delta2[ReferenceForce::R2Index];
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
internalF[0][i] = forceFactors[0]*term.cross1[i]; internalF[0][i] = forceFactors[0]*term.cross1[i];
internalF[3][i] = forceFactors[3]*term.cross2[i]; internalF[3][i] = forceFactors[3]*term.cross2[i];
RealOpenMM s = forceFactors[1]*internalF[0][i] - forceFactors[2]*internalF[3][i]; double s = forceFactors[1]*internalF[0][i] - forceFactors[2]*internalF[3][i];
internalF[1][i] = internalF[0][i] - s; internalF[1][i] = internalF[0][i] - s;
internalF[2][i] = internalF[3][i] + s; internalF[2][i] = internalF[3][i] + s;
} }
...@@ -251,7 +251,7 @@ void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector<RealVec>& ...@@ -251,7 +251,7 @@ void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector<RealVec>&
// Add the energy // Add the energy
if (totalEnergy) if (totalEnergy)
*totalEnergy += (RealOpenMM) energyExpression.evaluate(); *totalEnergy += energyExpression.evaluate();
// Compute derivatives of the energy. // Compute derivatives of the energy.
...@@ -259,22 +259,22 @@ void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector<RealVec>& ...@@ -259,22 +259,22 @@ void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector<RealVec>&
energyParamDerivs[i] += energyParamDerivExpressions[i].evaluate(); energyParamDerivs[i] += energyParamDerivExpressions[i].evaluate();
} }
void ReferenceCustomCompoundBondIxn::computeDelta(int atom1, int atom2, RealOpenMM* delta, vector<RealVec>& atomCoordinates) const { void ReferenceCustomCompoundBondIxn::computeDelta(int atom1, int atom2, double* delta, vector<Vec3>& atomCoordinates) const {
if (usePeriodic) if (usePeriodic)
ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom1], atomCoordinates[atom2], boxVectors, delta); ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom1], atomCoordinates[atom2], boxVectors, delta);
else else
ReferenceForce::getDeltaR(atomCoordinates[atom1], atomCoordinates[atom2], delta); ReferenceForce::getDeltaR(atomCoordinates[atom1], atomCoordinates[atom2], delta);
} }
RealOpenMM ReferenceCustomCompoundBondIxn::computeAngle(RealOpenMM* vec1, RealOpenMM* vec2) { double ReferenceCustomCompoundBondIxn::computeAngle(double* vec1, double* vec2) {
RealOpenMM dot = DOT3(vec1, vec2); double dot = DOT3(vec1, vec2);
RealOpenMM cosine = dot/SQRT((vec1[ReferenceForce::R2Index]*vec2[ReferenceForce::R2Index])); double cosine = dot/sqrt((vec1[ReferenceForce::R2Index]*vec2[ReferenceForce::R2Index]));
RealOpenMM angle; double angle;
if (cosine >= 1) if (cosine >= 1)
angle = 0; angle = 0;
else if (cosine <= -1) else if (cosine <= -1)
angle = PI_M; angle = PI_M;
else else
angle = ACOS(cosine); angle = acos(cosine);
return angle; return angle;
} }
...@@ -89,7 +89,7 @@ ReferenceCustomDynamics::ReferenceCustomDynamics(int numberOfAtoms, const Custom ...@@ -89,7 +89,7 @@ ReferenceCustomDynamics::ReferenceCustomDynamics(int numberOfAtoms, const Custom
ReferenceCustomDynamics::~ReferenceCustomDynamics() { ReferenceCustomDynamics::~ReferenceCustomDynamics() {
} }
void ReferenceCustomDynamics::initialize(ContextImpl& context, vector<RealOpenMM>& masses, map<string, RealOpenMM>& globals) { void ReferenceCustomDynamics::initialize(ContextImpl& context, vector<double>& masses, map<string, double>& globals) {
// Some initialization can't be done in the constructor, since we need a ContextImpl from which to get the list of // Some initialization can't be done in the constructor, since we need a ContextImpl from which to get the list of
// Context parameters. Instead, we do it the first time update() or computeKineticEnergy() is called. // Context parameters. Instead, we do it the first time update() or computeKineticEnergy() is called.
...@@ -197,14 +197,14 @@ ExpressionTreeNode ReferenceCustomDynamics::replaceDerivFunctions(const Expressi ...@@ -197,14 +197,14 @@ ExpressionTreeNode ReferenceCustomDynamics::replaceDerivFunctions(const Expressi
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, vector<RealVec>& atomCoordinates, void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, vector<Vec3>& atomCoordinates,
vector<RealVec>& velocities, vector<RealVec>& forces, vector<RealOpenMM>& masses, vector<Vec3>& velocities, vector<Vec3>& forces, vector<double>& masses,
map<string, RealOpenMM>& globals, vector<vector<RealVec> >& perDof, bool& forcesAreValid, RealOpenMM tolerance) { map<string, double>& globals, vector<vector<Vec3> >& perDof, bool& forcesAreValid, double tolerance) {
if (invalidatesForces.size() == 0) if (invalidatesForces.size() == 0)
initialize(context, masses, globals); initialize(context, masses, globals);
int numSteps = stepType.size(); int numSteps = stepType.size();
globals.insert(context.getParameters().begin(), context.getParameters().end()); globals.insert(context.getParameters().begin(), context.getParameters().end());
for (map<string, RealOpenMM>::const_iterator iter = globals.begin(); iter != globals.end(); ++iter) for (map<string, double>::const_iterator iter = globals.begin(); iter != globals.end(); ++iter)
expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second); expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second);
oldPos = atomCoordinates; oldPos = atomCoordinates;
...@@ -217,7 +217,7 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve ...@@ -217,7 +217,7 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
bool computeForce = needsForces[step] || computeBothForceAndEnergy[step]; bool computeForce = needsForces[step] || computeBothForceAndEnergy[step];
bool computeEnergy = needsEnergy[step] || computeBothForceAndEnergy[step]; bool computeEnergy = needsEnergy[step] || computeBothForceAndEnergy[step];
recordChangedParameters(context, globals); recordChangedParameters(context, globals);
RealOpenMM e = context.calcForcesAndEnergy(computeForce, computeEnergy, forceGroupFlags[step]); double e = context.calcForcesAndEnergy(computeForce, computeEnergy, forceGroupFlags[step]);
if (computeEnergy) { if (computeEnergy) {
energy = e; energy = e;
context.getEnergyParameterDerivatives(energyParamDerivs); context.getEnergyParameterDerivatives(energyParamDerivs);
...@@ -232,13 +232,13 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve ...@@ -232,13 +232,13 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
case CustomIntegrator::ComputeGlobal: { case CustomIntegrator::ComputeGlobal: {
uniform = SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber(); uniform = SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber();
gaussian = SimTKOpenMMUtilities::getNormallyDistributedRandomNumber(); gaussian = SimTKOpenMMUtilities::getNormallyDistributedRandomNumber();
RealOpenMM result = stepExpressions[step][0].evaluate(); double result = stepExpressions[step][0].evaluate();
globals[stepVariable[step]] = result; globals[stepVariable[step]] = result;
expressionSet.setVariable(stepVariableIndex[step], result); expressionSet.setVariable(stepVariableIndex[step], result);
break; break;
} }
case CustomIntegrator::ComputePerDof: { case CustomIntegrator::ComputePerDof: {
vector<RealVec>* results = NULL; vector<Vec3>* results = NULL;
if (stepVariableIndex[step] == xIndex) if (stepVariableIndex[step] == xIndex)
results = &atomCoordinates; results = &atomCoordinates;
else if (stepVariableIndex[step] == vIndex) else if (stepVariableIndex[step] == vIndex)
...@@ -255,7 +255,7 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve ...@@ -255,7 +255,7 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
} }
case CustomIntegrator::ComputeSum: { case CustomIntegrator::ComputeSum: {
computePerDof(numberOfAtoms, sumBuffer, atomCoordinates, velocities, forces, masses, perDof, stepExpressions[step][0]); computePerDof(numberOfAtoms, sumBuffer, atomCoordinates, velocities, forces, masses, perDof, stepExpressions[step][0]);
RealOpenMM sum = 0.0; double sum = 0.0;
for (int j = 0; j < numberOfAtoms; j++) for (int j = 0; j < numberOfAtoms; j++)
if (masses[j] != 0.0) if (masses[j] != 0.0)
sum += sumBuffer[j][0]+sumBuffer[j][1]+sumBuffer[j][2]; sum += sumBuffer[j][0]+sumBuffer[j][1]+sumBuffer[j][2];
...@@ -276,7 +276,7 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve ...@@ -276,7 +276,7 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
recordChangedParameters(context, globals); recordChangedParameters(context, globals);
context.updateContextState(); context.updateContextState();
globals.insert(context.getParameters().begin(), context.getParameters().end()); globals.insert(context.getParameters().begin(), context.getParameters().end());
for (map<string, RealOpenMM>::const_iterator iter = globals.begin(); iter != globals.end(); ++iter) for (map<string, double>::const_iterator iter = globals.begin(); iter != globals.end(); ++iter)
expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second); expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second);
break; break;
} }
...@@ -305,9 +305,9 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve ...@@ -305,9 +305,9 @@ void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, ve
recordChangedParameters(context, globals); recordChangedParameters(context, globals);
} }
void ReferenceCustomDynamics::computePerDof(int numberOfAtoms, vector<RealVec>& results, const vector<RealVec>& atomCoordinates, void ReferenceCustomDynamics::computePerDof(int numberOfAtoms, vector<Vec3>& results, const vector<Vec3>& atomCoordinates,
const vector<RealVec>& velocities, const vector<RealVec>& forces, const vector<RealOpenMM>& masses, const vector<Vec3>& velocities, const vector<Vec3>& forces, const vector<double>& masses,
const vector<vector<RealVec> >& perDof, const CompiledExpression& expression) { const vector<vector<Vec3> >& perDof, const CompiledExpression& expression) {
// Loop over all degrees of freedom. // Loop over all degrees of freedom.
for (int i = 0; i < numberOfAtoms; i++) { for (int i = 0; i < numberOfAtoms; i++) {
...@@ -354,7 +354,7 @@ bool ReferenceCustomDynamics::evaluateCondition(int step) { ...@@ -354,7 +354,7 @@ bool ReferenceCustomDynamics::evaluateCondition(int step) {
/** /**
* Check which context parameters have changed and register them with the context. * Check which context parameters have changed and register them with the context.
*/ */
void ReferenceCustomDynamics::recordChangedParameters(OpenMM::ContextImpl& context, std::map<std::string, RealOpenMM>& globals) { void ReferenceCustomDynamics::recordChangedParameters(OpenMM::ContextImpl& context, std::map<std::string, double>& globals) {
for (map<string, double>::const_iterator iter = context.getParameters().begin(); iter != context.getParameters().end(); ++iter) { for (map<string, double>::const_iterator iter = context.getParameters().begin(); iter != context.getParameters().end(); ++iter) {
string name = iter->first; string name = iter->first;
double value = globals[name]; double value = globals[name];
...@@ -379,20 +379,20 @@ void ReferenceCustomDynamics::recordChangedParameters(OpenMM::ContextImpl& conte ...@@ -379,20 +379,20 @@ void ReferenceCustomDynamics::recordChangedParameters(OpenMM::ContextImpl& conte
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
double ReferenceCustomDynamics::computeKineticEnergy(OpenMM::ContextImpl& context, int numberOfAtoms, std::vector<OpenMM::RealVec>& atomCoordinates, double ReferenceCustomDynamics::computeKineticEnergy(OpenMM::ContextImpl& context, int numberOfAtoms, std::vector<OpenMM::Vec3>& atomCoordinates,
std::vector<OpenMM::RealVec>& velocities, std::vector<OpenMM::RealVec>& forces, std::vector<RealOpenMM>& masses, std::vector<OpenMM::Vec3>& velocities, std::vector<OpenMM::Vec3>& forces, std::vector<double>& masses,
std::map<std::string, RealOpenMM>& globals, std::vector<std::vector<OpenMM::RealVec> >& perDof, bool& forcesAreValid) { std::map<std::string, double>& globals, std::vector<std::vector<OpenMM::Vec3> >& perDof, bool& forcesAreValid) {
if (invalidatesForces.size() == 0) if (invalidatesForces.size() == 0)
initialize(context, masses, globals); initialize(context, masses, globals);
globals.insert(context.getParameters().begin(), context.getParameters().end()); globals.insert(context.getParameters().begin(), context.getParameters().end());
for (map<string, RealOpenMM>::const_iterator iter = globals.begin(); iter != globals.end(); ++iter) for (map<string, double>::const_iterator iter = globals.begin(); iter != globals.end(); ++iter)
expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second); expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second);
if (kineticEnergyNeedsForce) { if (kineticEnergyNeedsForce) {
energy = context.calcForcesAndEnergy(true, true, -1); energy = context.calcForcesAndEnergy(true, true, -1);
forcesAreValid = true; forcesAreValid = true;
} }
computePerDof(numberOfAtoms, sumBuffer, atomCoordinates, velocities, forces, masses, perDof, kineticEnergyExpression); computePerDof(numberOfAtoms, sumBuffer, atomCoordinates, velocities, forces, masses, perDof, kineticEnergyExpression);
RealOpenMM sum = 0.0; double sum = 0.0;
for (int j = 0; j < numberOfAtoms; j++) for (int j = 0; j < numberOfAtoms; j++)
if (masses[j] != 0.0) if (masses[j] != 0.0)
sum += sumBuffer[j][0]+sumBuffer[j][1]+sumBuffer[j][2]; sum += sumBuffer[j][0]+sumBuffer[j][1]+sumBuffer[j][2];
......
...@@ -78,13 +78,6 @@ ReferenceCustomExternalIxn::ReferenceCustomExternalIxn(const Lepton::CompiledExp ...@@ -78,13 +78,6 @@ ReferenceCustomExternalIxn::ReferenceCustomExternalIxn(const Lepton::CompiledExp
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceCustomExternalIxn::~ReferenceCustomExternalIxn() { ReferenceCustomExternalIxn::~ReferenceCustomExternalIxn() {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceCustomExternalIxn::~ReferenceCustomExternalIxn";
// ---------------------------------------------------------------------------------------
} }
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -100,12 +93,10 @@ ReferenceCustomExternalIxn::~ReferenceCustomExternalIxn() { ...@@ -100,12 +93,10 @@ ReferenceCustomExternalIxn::~ReferenceCustomExternalIxn() {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomExternalIxn::calculateForce(int atomIndex, void ReferenceCustomExternalIxn::calculateForce(int atomIndex,
vector<RealVec>& atomCoordinates, vector<Vec3>& atomCoordinates,
RealOpenMM* parameters, double* parameters,
vector<RealVec>& forces, vector<Vec3>& forces,
RealOpenMM* energy) const { double* energy) const {
static const std::string methodName = "\nReferenceCustomExternalIxn::calculateBondIxn";
for (int i = 0; i < numParameters; i++) { for (int i = 0; i < numParameters; i++) {
ReferenceForce::setVariable(energyParams[i], parameters[i]); ReferenceForce::setVariable(energyParams[i], parameters[i]);
...@@ -128,9 +119,9 @@ void ReferenceCustomExternalIxn::calculateForce(int atomIndex, ...@@ -128,9 +119,9 @@ void ReferenceCustomExternalIxn::calculateForce(int atomIndex,
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
forces[atomIndex][0] -= (RealOpenMM) forceExpressionX.evaluate(); forces[atomIndex][0] -= forceExpressionX.evaluate();
forces[atomIndex][1] -= (RealOpenMM) forceExpressionY.evaluate(); forces[atomIndex][1] -= forceExpressionY.evaluate();
forces[atomIndex][2] -= (RealOpenMM) forceExpressionZ.evaluate(); forces[atomIndex][2] -= forceExpressionZ.evaluate();
if (energy != NULL) if (energy != NULL)
*energy += (RealOpenMM) energyExpression.evaluate(); *energy += energyExpression.evaluate();
} }
...@@ -120,7 +120,7 @@ ReferenceCustomGBIxn::~ReferenceCustomGBIxn() { ...@@ -120,7 +120,7 @@ ReferenceCustomGBIxn::~ReferenceCustomGBIxn() {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomGBIxn::setUseCutoff(RealOpenMM distance, const OpenMM::NeighborList& neighbors) { void ReferenceCustomGBIxn::setUseCutoff(double distance, const OpenMM::NeighborList& neighbors) {
cutoff = true; cutoff = true;
cutoffDistance = distance; cutoffDistance = distance;
...@@ -137,7 +137,7 @@ ReferenceCustomGBIxn::~ReferenceCustomGBIxn() { ...@@ -137,7 +137,7 @@ ReferenceCustomGBIxn::~ReferenceCustomGBIxn() {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomGBIxn::setPeriodic(RealVec* vectors) { void ReferenceCustomGBIxn::setPeriodic(Vec3* vectors) {
if (cutoff) { if (cutoff) {
assert(vectors[0][0] >= 2.0*cutoffDistance); assert(vectors[0][0] >= 2.0*cutoffDistance);
...@@ -150,9 +150,9 @@ ReferenceCustomGBIxn::~ReferenceCustomGBIxn() { ...@@ -150,9 +150,9 @@ ReferenceCustomGBIxn::~ReferenceCustomGBIxn() {
periodicBoxVectors[2] = vectors[2]; periodicBoxVectors[2] = vectors[2];
} }
void ReferenceCustomGBIxn::calculateIxn(int numberOfAtoms, vector<RealVec>& atomCoordinates, RealOpenMM** atomParameters, void ReferenceCustomGBIxn::calculateIxn(int numberOfAtoms, vector<Vec3>& atomCoordinates, double** atomParameters,
const vector<set<int> >& exclusions, map<string, double>& globalParameters, vector<RealVec>& forces, const vector<set<int> >& exclusions, map<string, double>& globalParameters, vector<Vec3>& forces,
RealOpenMM* totalEnergy, double* energyParamDerivs) { double* totalEnergy, double* energyParamDerivs) {
for (map<string, double>::const_iterator iter = globalParameters.begin(); iter != globalParameters.end(); ++iter) for (map<string, double>::const_iterator iter = globalParameters.begin(); iter != globalParameters.end(); ++iter)
expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second); expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second);
...@@ -161,10 +161,10 @@ void ReferenceCustomGBIxn::calculateIxn(int numberOfAtoms, vector<RealVec>& atom ...@@ -161,10 +161,10 @@ void ReferenceCustomGBIxn::calculateIxn(int numberOfAtoms, vector<RealVec>& atom
int numValues = valueTypes.size(); int numValues = valueTypes.size();
int numDerivs = valueParamDerivExpressions[0].size(); int numDerivs = valueParamDerivExpressions[0].size();
values.resize(numValues); values.resize(numValues);
dEdV.resize(numValues, vector<RealOpenMM>(numberOfAtoms, 0.0)); dEdV.resize(numValues, vector<double>(numberOfAtoms, 0.0));
dValuedParam.resize(numValues); dValuedParam.resize(numValues);
for (int i = 0; i < numValues; i++) for (int i = 0; i < numValues; i++)
dValuedParam[i].resize(numDerivs, vector<RealOpenMM>(numberOfAtoms, 0.0)); dValuedParam[i].resize(numDerivs, vector<double>(numberOfAtoms, 0.0));
// First calculate the computed values. // First calculate the computed values.
...@@ -193,7 +193,7 @@ void ReferenceCustomGBIxn::calculateIxn(int numberOfAtoms, vector<RealVec>& atom ...@@ -193,7 +193,7 @@ void ReferenceCustomGBIxn::calculateIxn(int numberOfAtoms, vector<RealVec>& atom
calculateChainRuleForces(numberOfAtoms, atomCoordinates, atomParameters, exclusions, forces, energyParamDerivs); calculateChainRuleForces(numberOfAtoms, atomCoordinates, atomParameters, exclusions, forces, energyParamDerivs);
} }
void ReferenceCustomGBIxn::calculateSingleParticleValue(int index, int numAtoms, vector<RealVec>& atomCoordinates, RealOpenMM** atomParameters) { void ReferenceCustomGBIxn::calculateSingleParticleValue(int index, int numAtoms, vector<Vec3>& atomCoordinates, double** atomParameters) {
values[index].resize(numAtoms); values[index].resize(numAtoms);
for (int i = 0; i < numAtoms; i++) { for (int i = 0; i < numAtoms; i++) {
expressionSet.setVariable(xIndex, atomCoordinates[i][0]); expressionSet.setVariable(xIndex, atomCoordinates[i][0]);
...@@ -203,25 +203,25 @@ void ReferenceCustomGBIxn::calculateSingleParticleValue(int index, int numAtoms, ...@@ -203,25 +203,25 @@ void ReferenceCustomGBIxn::calculateSingleParticleValue(int index, int numAtoms,
expressionSet.setVariable(paramIndex[j], atomParameters[i][j]); expressionSet.setVariable(paramIndex[j], atomParameters[i][j]);
for (int j = 0; j < index; j++) for (int j = 0; j < index; j++)
expressionSet.setVariable(valueIndex[j], values[j][i]); expressionSet.setVariable(valueIndex[j], values[j][i]);
values[index][i] = (RealOpenMM) valueExpressions[index].evaluate(); values[index][i] = valueExpressions[index].evaluate();
// Calculate derivatives with respect to parameters. // Calculate derivatives with respect to parameters.
for (int j = 0; j < valueParamDerivExpressions[index].size(); j++) for (int j = 0; j < valueParamDerivExpressions[index].size(); j++)
dValuedParam[index][j][i] += valueParamDerivExpressions[index][j].evaluate(); dValuedParam[index][j][i] += valueParamDerivExpressions[index][j].evaluate();
for (int j = 0; j < index; j++) { for (int j = 0; j < index; j++) {
RealOpenMM dVdV = valueDerivExpressions[index][j].evaluate(); double dVdV = valueDerivExpressions[index][j].evaluate();
for (int k = 0; k < valueParamDerivExpressions[index].size(); k++) for (int k = 0; k < valueParamDerivExpressions[index].size(); k++)
dValuedParam[index][k][i] += dVdV*dValuedParam[j][k][i]; dValuedParam[index][k][i] += dVdV*dValuedParam[j][k][i];
} }
} }
} }
void ReferenceCustomGBIxn::calculateParticlePairValue(int index, int numAtoms, vector<RealVec>& atomCoordinates, RealOpenMM** atomParameters, void ReferenceCustomGBIxn::calculateParticlePairValue(int index, int numAtoms, vector<Vec3>& atomCoordinates, double** atomParameters,
const vector<set<int> >& exclusions, bool useExclusions) { const vector<set<int> >& exclusions, bool useExclusions) {
values[index].resize(numAtoms); values[index].resize(numAtoms);
for (int i = 0; i < numAtoms; i++) for (int i = 0; i < numAtoms; i++)
values[index][i] = (RealOpenMM) 0.0; values[index][i] = 0.0;
if (cutoff) { if (cutoff) {
// Loop over all pairs in the neighbor list. // Loop over all pairs in the neighbor list.
...@@ -247,13 +247,13 @@ void ReferenceCustomGBIxn::calculateParticlePairValue(int index, int numAtoms, v ...@@ -247,13 +247,13 @@ void ReferenceCustomGBIxn::calculateParticlePairValue(int index, int numAtoms, v
} }
} }
void ReferenceCustomGBIxn::calculateOnePairValue(int index, int atom1, int atom2, vector<RealVec>& atomCoordinates, RealOpenMM** atomParameters) { void ReferenceCustomGBIxn::calculateOnePairValue(int index, int atom1, int atom2, vector<Vec3>& atomCoordinates, double** atomParameters) {
RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; double deltaR[ReferenceForce::LastDeltaRIndex];
if (periodic) if (periodic)
ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxVectors, deltaR); ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxVectors, deltaR);
else else
ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR); ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR);
RealOpenMM r = deltaR[ReferenceForce::RIndex]; double r = deltaR[ReferenceForce::RIndex];
if (cutoff && r >= cutoffDistance) if (cutoff && r >= cutoffDistance)
return; return;
for (int i = 0; i < (int) paramIndex.size(); i++) { for (int i = 0; i < (int) paramIndex.size(); i++) {
...@@ -265,7 +265,7 @@ void ReferenceCustomGBIxn::calculateOnePairValue(int index, int atom1, int atom2 ...@@ -265,7 +265,7 @@ void ReferenceCustomGBIxn::calculateOnePairValue(int index, int atom1, int atom2
expressionSet.setVariable(particleValueIndex[i*2], values[i][atom1]); expressionSet.setVariable(particleValueIndex[i*2], values[i][atom1]);
expressionSet.setVariable(particleValueIndex[i*2+1], values[i][atom2]); expressionSet.setVariable(particleValueIndex[i*2+1], values[i][atom2]);
} }
values[index][atom1] += (RealOpenMM) valueExpressions[index].evaluate(); values[index][atom1] += valueExpressions[index].evaluate();
// Calculate derivatives with respect to parameters. // Calculate derivatives with respect to parameters.
...@@ -273,8 +273,8 @@ void ReferenceCustomGBIxn::calculateOnePairValue(int index, int atom1, int atom2 ...@@ -273,8 +273,8 @@ void ReferenceCustomGBIxn::calculateOnePairValue(int index, int atom1, int atom2
dValuedParam[index][i][atom1] += valueParamDerivExpressions[index][i].evaluate(); dValuedParam[index][i][atom1] += valueParamDerivExpressions[index][i].evaluate();
} }
void ReferenceCustomGBIxn::calculateSingleParticleEnergyTerm(int index, int numAtoms, vector<RealVec>& atomCoordinates, void ReferenceCustomGBIxn::calculateSingleParticleEnergyTerm(int index, int numAtoms, vector<Vec3>& atomCoordinates,
RealOpenMM** atomParameters, vector<RealVec>& forces, RealOpenMM* totalEnergy, double* energyParamDerivs) { double** atomParameters, vector<Vec3>& forces, double* totalEnergy, double* energyParamDerivs) {
for (int i = 0; i < numAtoms; i++) { for (int i = 0; i < numAtoms; i++) {
expressionSet.setVariable(xIndex, atomCoordinates[i][0]); expressionSet.setVariable(xIndex, atomCoordinates[i][0]);
expressionSet.setVariable(yIndex, atomCoordinates[i][1]); expressionSet.setVariable(yIndex, atomCoordinates[i][1]);
...@@ -287,12 +287,12 @@ void ReferenceCustomGBIxn::calculateSingleParticleEnergyTerm(int index, int numA ...@@ -287,12 +287,12 @@ void ReferenceCustomGBIxn::calculateSingleParticleEnergyTerm(int index, int numA
// Compute energy and force. // Compute energy and force.
if (totalEnergy != NULL) if (totalEnergy != NULL)
*totalEnergy += (RealOpenMM) energyExpressions[index].evaluate(); *totalEnergy += energyExpressions[index].evaluate();
for (int j = 0; j < (int) valueIndex.size(); j++) for (int j = 0; j < (int) valueIndex.size(); j++)
dEdV[j][i] += (RealOpenMM) energyDerivExpressions[index][j].evaluate(); dEdV[j][i] += energyDerivExpressions[index][j].evaluate();
forces[i][0] -= (RealOpenMM) energyGradientExpressions[index][0].evaluate(); forces[i][0] -= energyGradientExpressions[index][0].evaluate();
forces[i][1] -= (RealOpenMM) energyGradientExpressions[index][1].evaluate(); forces[i][1] -= energyGradientExpressions[index][1].evaluate();
forces[i][2] -= (RealOpenMM) energyGradientExpressions[index][2].evaluate(); forces[i][2] -= energyGradientExpressions[index][2].evaluate();
// Compute derivatives with respect to parameters. // Compute derivatives with respect to parameters.
...@@ -301,8 +301,8 @@ void ReferenceCustomGBIxn::calculateSingleParticleEnergyTerm(int index, int numA ...@@ -301,8 +301,8 @@ void ReferenceCustomGBIxn::calculateSingleParticleEnergyTerm(int index, int numA
} }
} }
void ReferenceCustomGBIxn::calculateParticlePairEnergyTerm(int index, int numAtoms, vector<RealVec>& atomCoordinates, RealOpenMM** atomParameters, void ReferenceCustomGBIxn::calculateParticlePairEnergyTerm(int index, int numAtoms, vector<Vec3>& atomCoordinates, double** atomParameters,
const vector<set<int> >& exclusions, bool useExclusions, vector<RealVec>& forces, RealOpenMM* totalEnergy, double* energyParamDerivs) { const vector<set<int> >& exclusions, bool useExclusions, vector<Vec3>& forces, double* totalEnergy, double* energyParamDerivs) {
if (cutoff) { if (cutoff) {
// Loop over all pairs in the neighbor list. // Loop over all pairs in the neighbor list.
...@@ -326,16 +326,16 @@ void ReferenceCustomGBIxn::calculateParticlePairEnergyTerm(int index, int numAto ...@@ -326,16 +326,16 @@ void ReferenceCustomGBIxn::calculateParticlePairEnergyTerm(int index, int numAto
} }
} }
void ReferenceCustomGBIxn::calculateOnePairEnergyTerm(int index, int atom1, int atom2, vector<RealVec>& atomCoordinates, RealOpenMM** atomParameters, void ReferenceCustomGBIxn::calculateOnePairEnergyTerm(int index, int atom1, int atom2, vector<Vec3>& atomCoordinates, double** atomParameters,
vector<RealVec>& forces, RealOpenMM* totalEnergy, double* energyParamDerivs) { vector<Vec3>& forces, double* totalEnergy, double* energyParamDerivs) {
// Compute the displacement. // Compute the displacement.
RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; double deltaR[ReferenceForce::LastDeltaRIndex];
if (periodic) if (periodic)
ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxVectors, deltaR); ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxVectors, deltaR);
else else
ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR); ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR);
RealOpenMM r = deltaR[ReferenceForce::RIndex]; double r = deltaR[ReferenceForce::RIndex];
if (cutoff && r >= cutoffDistance) if (cutoff && r >= cutoffDistance)
return; return;
...@@ -354,16 +354,16 @@ void ReferenceCustomGBIxn::calculateOnePairEnergyTerm(int index, int atom1, int ...@@ -354,16 +354,16 @@ void ReferenceCustomGBIxn::calculateOnePairEnergyTerm(int index, int atom1, int
// Evaluate the energy and its derivatives. // Evaluate the energy and its derivatives.
if (totalEnergy != NULL) if (totalEnergy != NULL)
*totalEnergy += (RealOpenMM) energyExpressions[index].evaluate(); *totalEnergy += energyExpressions[index].evaluate();
RealOpenMM dEdR = (RealOpenMM) energyDerivExpressions[index][0].evaluate(); double dEdR = energyDerivExpressions[index][0].evaluate();
dEdR *= 1/r; dEdR *= 1/r;
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
forces[atom1][i] -= dEdR*deltaR[i]; forces[atom1][i] -= dEdR*deltaR[i];
forces[atom2][i] += dEdR*deltaR[i]; forces[atom2][i] += dEdR*deltaR[i];
} }
for (int i = 0; i < (int) valueIndex.size(); i++) { for (int i = 0; i < (int) valueIndex.size(); i++) {
dEdV[i][atom1] += (RealOpenMM) energyDerivExpressions[index][2*i+1].evaluate(); dEdV[i][atom1] += energyDerivExpressions[index][2*i+1].evaluate();
dEdV[i][atom2] += (RealOpenMM) energyDerivExpressions[index][2*i+2].evaluate(); dEdV[i][atom2] += energyDerivExpressions[index][2*i+2].evaluate();
} }
// Compute derivatives with respect to parameters. // Compute derivatives with respect to parameters.
...@@ -372,8 +372,8 @@ void ReferenceCustomGBIxn::calculateOnePairEnergyTerm(int index, int atom1, int ...@@ -372,8 +372,8 @@ void ReferenceCustomGBIxn::calculateOnePairEnergyTerm(int index, int atom1, int
energyParamDerivs[i] += energyParamDerivExpressions[index][i].evaluate(); energyParamDerivs[i] += energyParamDerivExpressions[index][i].evaluate();
} }
void ReferenceCustomGBIxn::calculateChainRuleForces(int numAtoms, vector<RealVec>& atomCoordinates, RealOpenMM** atomParameters, void ReferenceCustomGBIxn::calculateChainRuleForces(int numAtoms, vector<Vec3>& atomCoordinates, double** atomParameters,
const vector<set<int> >& exclusions, vector<RealVec>& forces, double* energyParamDerivs) { const vector<set<int> >& exclusions, vector<Vec3>& forces, double* energyParamDerivs) {
if (cutoff) { if (cutoff) {
// Loop over all pairs in the neighbor list. // Loop over all pairs in the neighbor list.
...@@ -402,22 +402,22 @@ void ReferenceCustomGBIxn::calculateChainRuleForces(int numAtoms, vector<RealVec ...@@ -402,22 +402,22 @@ void ReferenceCustomGBIxn::calculateChainRuleForces(int numAtoms, vector<RealVec
expressionSet.setVariable(xIndex, atomCoordinates[i][0]); expressionSet.setVariable(xIndex, atomCoordinates[i][0]);
expressionSet.setVariable(yIndex, atomCoordinates[i][1]); expressionSet.setVariable(yIndex, atomCoordinates[i][1]);
expressionSet.setVariable(zIndex, atomCoordinates[i][2]); expressionSet.setVariable(zIndex, atomCoordinates[i][2]);
vector<RealOpenMM> dVdX(valueDerivExpressions.size(), 0.0); vector<double> dVdX(valueDerivExpressions.size(), 0.0);
vector<RealOpenMM> dVdY(valueDerivExpressions.size(), 0.0); vector<double> dVdY(valueDerivExpressions.size(), 0.0);
vector<RealOpenMM> dVdZ(valueDerivExpressions.size(), 0.0); vector<double> dVdZ(valueDerivExpressions.size(), 0.0);
for (int j = 0; j < (int) paramIndex.size(); j++) for (int j = 0; j < (int) paramIndex.size(); j++)
expressionSet.setVariable(paramIndex[j], atomParameters[i][j]); expressionSet.setVariable(paramIndex[j], atomParameters[i][j]);
for (int j = 1; j < (int) valueIndex.size(); j++) { for (int j = 1; j < (int) valueIndex.size(); j++) {
expressionSet.setVariable(valueIndex[j-1], values[j-1][i]); expressionSet.setVariable(valueIndex[j-1], values[j-1][i]);
for (int k = 1; k < j; k++) { for (int k = 1; k < j; k++) {
RealOpenMM dVdV = (RealOpenMM) valueDerivExpressions[j][k].evaluate(); double dVdV = valueDerivExpressions[j][k].evaluate();
dVdX[j] += dVdV*dVdX[k]; dVdX[j] += dVdV*dVdX[k];
dVdY[j] += dVdV*dVdY[k]; dVdY[j] += dVdV*dVdY[k];
dVdZ[j] += dVdV*dVdZ[k]; dVdZ[j] += dVdV*dVdZ[k];
} }
dVdX[j] += (RealOpenMM) valueGradientExpressions[j][0].evaluate(); dVdX[j] += valueGradientExpressions[j][0].evaluate();
dVdY[j] += (RealOpenMM) valueGradientExpressions[j][1].evaluate(); dVdY[j] += valueGradientExpressions[j][1].evaluate();
dVdZ[j] += (RealOpenMM) valueGradientExpressions[j][2].evaluate(); dVdZ[j] += valueGradientExpressions[j][2].evaluate();
forces[i][0] -= dEdV[j][i]*dVdX[j]; forces[i][0] -= dEdV[j][i]*dVdX[j];
forces[i][1] -= dEdV[j][i]*dVdY[j]; forces[i][1] -= dEdV[j][i]*dVdY[j];
forces[i][2] -= dEdV[j][i]*dVdZ[j]; forces[i][2] -= dEdV[j][i]*dVdZ[j];
...@@ -432,16 +432,16 @@ void ReferenceCustomGBIxn::calculateChainRuleForces(int numAtoms, vector<RealVec ...@@ -432,16 +432,16 @@ void ReferenceCustomGBIxn::calculateChainRuleForces(int numAtoms, vector<RealVec
energyParamDerivs[k] += dEdV[j][i]*dValuedParam[j][k][i]; energyParamDerivs[k] += dEdV[j][i]*dValuedParam[j][k][i];
} }
void ReferenceCustomGBIxn::calculateOnePairChainRule(int atom1, int atom2, vector<RealVec>& atomCoordinates, RealOpenMM** atomParameters, void ReferenceCustomGBIxn::calculateOnePairChainRule(int atom1, int atom2, vector<Vec3>& atomCoordinates, double** atomParameters,
vector<RealVec>& forces, bool isExcluded) { vector<Vec3>& forces, bool isExcluded) {
// Compute the displacement. // Compute the displacement.
RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; double deltaR[ReferenceForce::LastDeltaRIndex];
if (periodic) if (periodic)
ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxVectors, deltaR); ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxVectors, deltaR);
else else
ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR); ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR);
RealOpenMM r = deltaR[ReferenceForce::RIndex]; double r = deltaR[ReferenceForce::RIndex];
if (cutoff && r >= cutoffDistance) if (cutoff && r >= cutoffDistance)
return; return;
...@@ -457,14 +457,14 @@ void ReferenceCustomGBIxn::calculateOnePairChainRule(int atom1, int atom2, vecto ...@@ -457,14 +457,14 @@ void ReferenceCustomGBIxn::calculateOnePairChainRule(int atom1, int atom2, vecto
// Evaluate the derivative of each parameter with respect to position and apply forces. // Evaluate the derivative of each parameter with respect to position and apply forces.
RealOpenMM rinv = 1/r; double rinv = 1/r;
deltaR[0] *= rinv; deltaR[0] *= rinv;
deltaR[1] *= rinv; deltaR[1] *= rinv;
deltaR[2] *= rinv; deltaR[2] *= rinv;
vector<RealOpenMM> dVdR1(valueDerivExpressions.size(), 0.0); vector<double> dVdR1(valueDerivExpressions.size(), 0.0);
vector<RealOpenMM> dVdR2(valueDerivExpressions.size(), 0.0); vector<double> dVdR2(valueDerivExpressions.size(), 0.0);
if (!isExcluded || valueTypes[0] != OpenMM::CustomGBForce::ParticlePair) { if (!isExcluded || valueTypes[0] != OpenMM::CustomGBForce::ParticlePair) {
dVdR1[0] = (RealOpenMM) valueDerivExpressions[0][0].evaluate(); dVdR1[0] = valueDerivExpressions[0][0].evaluate();
dVdR2[0] = -dVdR1[0]; dVdR2[0] = -dVdR1[0];
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
forces[atom1][i] -= dEdV[0][atom1]*dVdR1[0]*deltaR[i]; forces[atom1][i] -= dEdV[0][atom1]*dVdR1[0]*deltaR[i];
...@@ -480,7 +480,7 @@ void ReferenceCustomGBIxn::calculateOnePairChainRule(int atom1, int atom2, vecto ...@@ -480,7 +480,7 @@ void ReferenceCustomGBIxn::calculateOnePairChainRule(int atom1, int atom2, vecto
expressionSet.setVariable(yIndex, atomCoordinates[atom1][1]); expressionSet.setVariable(yIndex, atomCoordinates[atom1][1]);
expressionSet.setVariable(zIndex, atomCoordinates[atom1][2]); expressionSet.setVariable(zIndex, atomCoordinates[atom1][2]);
for (int j = 0; j < i; j++) { for (int j = 0; j < i; j++) {
RealOpenMM dVdV = (RealOpenMM) valueDerivExpressions[i][j].evaluate(); double dVdV = valueDerivExpressions[i][j].evaluate();
dVdR1[i] += dVdV*dVdR1[j]; dVdR1[i] += dVdV*dVdR1[j];
dVdR2[i] += dVdV*dVdR2[j]; dVdR2[i] += dVdV*dVdR2[j];
} }
......
...@@ -74,7 +74,7 @@ ReferenceCustomHbondIxn::~ReferenceCustomHbondIxn() { ...@@ -74,7 +74,7 @@ ReferenceCustomHbondIxn::~ReferenceCustomHbondIxn() {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomHbondIxn::setUseCutoff(RealOpenMM distance) { void ReferenceCustomHbondIxn::setUseCutoff(double distance) {
cutoff = true; cutoff = true;
cutoffDistance = distance; cutoffDistance = distance;
} }
...@@ -89,7 +89,7 @@ void ReferenceCustomHbondIxn::setUseCutoff(RealOpenMM distance) { ...@@ -89,7 +89,7 @@ void ReferenceCustomHbondIxn::setUseCutoff(RealOpenMM distance) {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomHbondIxn::setPeriodic(RealVec* vectors) { void ReferenceCustomHbondIxn::setPeriodic(Vec3* vectors) {
assert(cutoff); assert(cutoff);
assert(vectors[0][0] >= 2.0*cutoffDistance); assert(vectors[0][0] >= 2.0*cutoffDistance);
assert(vectors[1][1] >= 2.0*cutoffDistance); assert(vectors[1][1] >= 2.0*cutoffDistance);
...@@ -116,9 +116,9 @@ void ReferenceCustomHbondIxn::setPeriodic(RealVec* vectors) { ...@@ -116,9 +116,9 @@ void ReferenceCustomHbondIxn::setPeriodic(RealVec* vectors) {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomHbondIxn::calculatePairIxn(vector<RealVec>& atomCoordinates, RealOpenMM** donorParameters, RealOpenMM** acceptorParameters, void ReferenceCustomHbondIxn::calculatePairIxn(vector<Vec3>& atomCoordinates, double** donorParameters, double** acceptorParameters,
vector<set<int> >& exclusions, const map<string, double>& globalParameters, vector<RealVec>& forces, vector<set<int> >& exclusions, const map<string, double>& globalParameters, vector<Vec3>& forces,
RealOpenMM* totalEnergy) const { double* totalEnergy) const {
map<string, double> variables = globalParameters; map<string, double> variables = globalParameters;
...@@ -159,14 +159,8 @@ void ReferenceCustomHbondIxn::calculatePairIxn(vector<RealVec>& atomCoordinates, ...@@ -159,14 +159,8 @@ void ReferenceCustomHbondIxn::calculatePairIxn(vector<RealVec>& atomCoordinates,
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector<RealVec>& atomCoordinates, void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector<Vec3>& atomCoordinates,
map<string, double>& variables, vector<RealVec>& forces, RealOpenMM* totalEnergy) const { map<string, double>& variables, vector<Vec3>& forces, double* totalEnergy) const {
// ---------------------------------------------------------------------------------------
static const std::string methodName = "\nReferenceCustomHbondIxn::calculateOneIxn";
// ---------------------------------------------------------------------------------------
int atoms[6]; int atoms[6];
atoms[0] = acceptorAtoms[acceptor][0]; atoms[0] = acceptorAtoms[acceptor][0];
...@@ -179,7 +173,7 @@ void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector<Re ...@@ -179,7 +173,7 @@ void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector<Re
// Compute the distance between the primary donor and acceptor atoms, and compare to the cutoff. // Compute the distance between the primary donor and acceptor atoms, and compare to the cutoff.
if (cutoff) { if (cutoff) {
RealOpenMM delta[ReferenceForce::LastDeltaRIndex]; double delta[ReferenceForce::LastDeltaRIndex];
computeDelta(atoms[0], atoms[3], delta, atomCoordinates); computeDelta(atoms[0], atoms[3], delta, atomCoordinates);
if (delta[ReferenceForce::RIndex] >= cutoffDistance) if (delta[ReferenceForce::RIndex] >= cutoffDistance)
return; return;
...@@ -203,8 +197,8 @@ void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector<Re ...@@ -203,8 +197,8 @@ void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector<Re
computeDelta(atoms[term.p2], atoms[term.p1], term.delta1, atomCoordinates); computeDelta(atoms[term.p2], atoms[term.p1], term.delta1, atomCoordinates);
computeDelta(atoms[term.p2], atoms[term.p3], term.delta2, atomCoordinates); computeDelta(atoms[term.p2], atoms[term.p3], term.delta2, atomCoordinates);
computeDelta(atoms[term.p4], atoms[term.p3], term.delta3, atomCoordinates); computeDelta(atoms[term.p4], atoms[term.p3], term.delta3, atomCoordinates);
RealOpenMM dotDihedral, signOfDihedral; double dotDihedral, signOfDihedral;
RealOpenMM* crossProduct[] = {term.cross1, term.cross2}; double* crossProduct[] = {term.cross1, term.cross2};
variables[term.name] = getDihedralAngleBetweenThreeVectors(term.delta1, term.delta2, term.delta3, crossProduct, &dotDihedral, term.delta1, &signOfDihedral, 1); variables[term.name] = getDihedralAngleBetweenThreeVectors(term.delta1, term.delta2, term.delta3, crossProduct, &dotDihedral, term.delta1, &signOfDihedral, 1);
} }
...@@ -212,9 +206,9 @@ void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector<Re ...@@ -212,9 +206,9 @@ void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector<Re
for (int i = 0; i < (int) distanceTerms.size(); i++) { for (int i = 0; i < (int) distanceTerms.size(); i++) {
const DistanceTermInfo& term = distanceTerms[i]; const DistanceTermInfo& term = distanceTerms[i];
RealOpenMM dEdR = (RealOpenMM) (term.forceExpression.evaluate(variables)/(term.delta[ReferenceForce::RIndex])); double dEdR = term.forceExpression.evaluate(variables)/(term.delta[ReferenceForce::RIndex]);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
RealOpenMM force = -dEdR*term.delta[i]; double force = -dEdR*term.delta[i];
forces[atoms[term.p1]][i] -= force; forces[atoms[term.p1]][i] -= force;
forces[atoms[term.p2]][i] += force; forces[atoms[term.p2]][i] += force;
} }
...@@ -224,15 +218,15 @@ void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector<Re ...@@ -224,15 +218,15 @@ void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector<Re
for (int i = 0; i < (int) angleTerms.size(); i++) { for (int i = 0; i < (int) angleTerms.size(); i++) {
const AngleTermInfo& term = angleTerms[i]; const AngleTermInfo& term = angleTerms[i];
RealOpenMM dEdTheta = (RealOpenMM) term.forceExpression.evaluate(variables); double dEdTheta = term.forceExpression.evaluate(variables);
RealOpenMM thetaCross[ReferenceForce::LastDeltaRIndex]; double thetaCross[ReferenceForce::LastDeltaRIndex];
SimTKOpenMMUtilities::crossProductVector3(term.delta1, term.delta2, thetaCross); SimTKOpenMMUtilities::crossProductVector3(term.delta1, term.delta2, thetaCross);
RealOpenMM lengthThetaCross = SQRT(DOT3(thetaCross, thetaCross)); double lengthThetaCross = sqrt(DOT3(thetaCross, thetaCross));
if (lengthThetaCross < 1.0e-06) if (lengthThetaCross < 1.0e-06)
lengthThetaCross = (RealOpenMM) 1.0e-06; lengthThetaCross = 1.0e-06;
RealOpenMM termA = dEdTheta/(term.delta1[ReferenceForce::R2Index]*lengthThetaCross); double termA = dEdTheta/(term.delta1[ReferenceForce::R2Index]*lengthThetaCross);
RealOpenMM termC = -dEdTheta/(term.delta2[ReferenceForce::R2Index]*lengthThetaCross); double termC = -dEdTheta/(term.delta2[ReferenceForce::R2Index]*lengthThetaCross);
RealOpenMM deltaCrossP[3][3]; double deltaCrossP[3][3];
SimTKOpenMMUtilities::crossProductVector3(term.delta1, thetaCross, deltaCrossP[0]); SimTKOpenMMUtilities::crossProductVector3(term.delta1, thetaCross, deltaCrossP[0]);
SimTKOpenMMUtilities::crossProductVector3(term.delta2, thetaCross, deltaCrossP[2]); SimTKOpenMMUtilities::crossProductVector3(term.delta2, thetaCross, deltaCrossP[2]);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
...@@ -251,22 +245,22 @@ void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector<Re ...@@ -251,22 +245,22 @@ void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector<Re
for (int i = 0; i < (int) dihedralTerms.size(); i++) { for (int i = 0; i < (int) dihedralTerms.size(); i++) {
const DihedralTermInfo& term = dihedralTerms[i]; const DihedralTermInfo& term = dihedralTerms[i];
RealOpenMM dEdTheta = (RealOpenMM) term.forceExpression.evaluate(variables); double dEdTheta = term.forceExpression.evaluate(variables);
RealOpenMM internalF[4][3]; double internalF[4][3];
RealOpenMM forceFactors[4]; double forceFactors[4];
RealOpenMM normCross1 = DOT3(term.cross1, term.cross1); double normCross1 = DOT3(term.cross1, term.cross1);
RealOpenMM normBC = term.delta2[ReferenceForce::RIndex]; double normBC = term.delta2[ReferenceForce::RIndex];
forceFactors[0] = (-dEdTheta*normBC)/normCross1; forceFactors[0] = (-dEdTheta*normBC)/normCross1;
RealOpenMM normCross2 = DOT3(term.cross2, term.cross2); double normCross2 = DOT3(term.cross2, term.cross2);
forceFactors[3] = (dEdTheta*normBC)/normCross2; forceFactors[3] = (dEdTheta*normBC)/normCross2;
forceFactors[1] = DOT3(term.delta1, term.delta2); forceFactors[1] = DOT3(term.delta1, term.delta2);
forceFactors[1] /= term.delta2[ReferenceForce::R2Index]; forceFactors[1] /= term.delta2[ReferenceForce::R2Index];
forceFactors[2] = DOT3(term.delta3, term.delta2); forceFactors[2] = DOT3(term.delta3, term.delta2);
forceFactors[2] /= term.delta2[ReferenceForce::R2Index]; forceFactors[2] /= term.delta2[ReferenceForce::R2Index];
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
internalF[0][i] = forceFactors[0]*term.cross1[i]; internalF[0][i] = forceFactors[0]*term.cross1[i];
internalF[3][i] = forceFactors[3]*term.cross2[i]; internalF[3][i] = forceFactors[3]*term.cross2[i];
RealOpenMM s = forceFactors[1]*internalF[0][i] - forceFactors[2]*internalF[3][i]; double s = forceFactors[1]*internalF[0][i] - forceFactors[2]*internalF[3][i];
internalF[1][i] = internalF[0][i] - s; internalF[1][i] = internalF[0][i] - s;
internalF[2][i] = internalF[3][i] + s; internalF[2][i] = internalF[3][i] + s;
} }
...@@ -281,25 +275,25 @@ void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector<Re ...@@ -281,25 +275,25 @@ void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector<Re
// Add the energy // Add the energy
if (totalEnergy) if (totalEnergy)
*totalEnergy += (RealOpenMM) energyExpression.evaluate(variables); *totalEnergy += energyExpression.evaluate(variables);
} }
void ReferenceCustomHbondIxn::computeDelta(int atom1, int atom2, RealOpenMM* delta, vector<RealVec>& atomCoordinates) const { void ReferenceCustomHbondIxn::computeDelta(int atom1, int atom2, double* delta, vector<Vec3>& atomCoordinates) const {
if (periodic) if (periodic)
ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom1], atomCoordinates[atom2], periodicBoxVectors, delta); ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom1], atomCoordinates[atom2], periodicBoxVectors, delta);
else else
ReferenceForce::getDeltaR(atomCoordinates[atom1], atomCoordinates[atom2], delta); ReferenceForce::getDeltaR(atomCoordinates[atom1], atomCoordinates[atom2], delta);
} }
RealOpenMM ReferenceCustomHbondIxn::computeAngle(RealOpenMM* vec1, RealOpenMM* vec2) { double ReferenceCustomHbondIxn::computeAngle(double* vec1, double* vec2) {
RealOpenMM dot = DOT3(vec1, vec2); double dot = DOT3(vec1, vec2);
RealOpenMM cosine = dot/SQRT((vec1[ReferenceForce::R2Index]*vec2[ReferenceForce::R2Index])); double cosine = dot/sqrt((vec1[ReferenceForce::R2Index]*vec2[ReferenceForce::R2Index]));
RealOpenMM angle; double angle;
if (cosine >= 1) if (cosine >= 1)
angle = 0; angle = 0;
else if (cosine <= -1) else if (cosine <= -1)
angle = PI_M; angle = PI_M;
else else
angle = ACOS(cosine); angle = acos(cosine);
return angle; return angle;
} }
...@@ -105,20 +105,20 @@ ReferenceCustomManyParticleIxn::ReferenceCustomManyParticleIxn(const CustomManyP ...@@ -105,20 +105,20 @@ ReferenceCustomManyParticleIxn::ReferenceCustomManyParticleIxn(const CustomManyP
ReferenceCustomManyParticleIxn::~ReferenceCustomManyParticleIxn() { ReferenceCustomManyParticleIxn::~ReferenceCustomManyParticleIxn() {
} }
void ReferenceCustomManyParticleIxn::calculateIxn(vector<RealVec>& atomCoordinates, RealOpenMM** particleParameters, void ReferenceCustomManyParticleIxn::calculateIxn(vector<Vec3>& atomCoordinates, double** particleParameters,
const map<string, double>& globalParameters, vector<RealVec>& forces, const map<string, double>& globalParameters, vector<Vec3>& forces,
RealOpenMM* totalEnergy) const { double* totalEnergy) const {
map<string, double> variables = globalParameters; map<string, double> variables = globalParameters;
vector<int> particles(numParticlesPerSet); vector<int> particles(numParticlesPerSet);
loopOverInteractions(particles, 0, atomCoordinates, particleParameters, variables, forces, totalEnergy); loopOverInteractions(particles, 0, atomCoordinates, particleParameters, variables, forces, totalEnergy);
} }
void ReferenceCustomManyParticleIxn::setUseCutoff(RealOpenMM distance) { void ReferenceCustomManyParticleIxn::setUseCutoff(double distance) {
useCutoff = true; useCutoff = true;
cutoffDistance = distance; cutoffDistance = distance;
} }
void ReferenceCustomManyParticleIxn::setPeriodic(RealVec* vectors) { void ReferenceCustomManyParticleIxn::setPeriodic(Vec3* vectors) {
assert(useCutoff); assert(useCutoff);
assert(vectors[0][0] >= 2.0*cutoffDistance); assert(vectors[0][0] >= 2.0*cutoffDistance);
assert(vectors[1][1] >= 2.0*cutoffDistance); assert(vectors[1][1] >= 2.0*cutoffDistance);
...@@ -129,9 +129,9 @@ void ReferenceCustomManyParticleIxn::setPeriodic(RealVec* vectors) { ...@@ -129,9 +129,9 @@ void ReferenceCustomManyParticleIxn::setPeriodic(RealVec* vectors) {
periodicBoxVectors[2] = vectors[2]; periodicBoxVectors[2] = vectors[2];
} }
void ReferenceCustomManyParticleIxn::loopOverInteractions(vector<int>& particles, int loopIndex, vector<OpenMM::RealVec>& atomCoordinates, void ReferenceCustomManyParticleIxn::loopOverInteractions(vector<int>& particles, int loopIndex, vector<OpenMM::Vec3>& atomCoordinates,
RealOpenMM** particleParameters, map<string, double>& variables, vector<OpenMM::RealVec>& forces, double** particleParameters, map<string, double>& variables, vector<OpenMM::Vec3>& forces,
RealOpenMM* totalEnergy) const { double* totalEnergy) const {
int numParticles = atomCoordinates.size(); int numParticles = atomCoordinates.size();
int firstPartialLoop = (centralParticleMode ? 2 : 1); int firstPartialLoop = (centralParticleMode ? 2 : 1);
int start = (loopIndex < firstPartialLoop ? 0 : particles[loopIndex-1]+1); int start = (loopIndex < firstPartialLoop ? 0 : particles[loopIndex-1]+1);
...@@ -146,8 +146,8 @@ void ReferenceCustomManyParticleIxn::loopOverInteractions(vector<int>& particles ...@@ -146,8 +146,8 @@ void ReferenceCustomManyParticleIxn::loopOverInteractions(vector<int>& particles
} }
} }
void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector<int>& particles, vector<RealVec>& atomCoordinates, void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector<int>& particles, vector<Vec3>& atomCoordinates,
RealOpenMM** particleParameters, map<string, double>& variables, vector<RealVec>& forces, RealOpenMM* totalEnergy) const { double** particleParameters, map<string, double>& variables, vector<Vec3>& forces, double* totalEnergy) const {
// Select the ordering to use for the particles. // Select the ordering to use for the particles.
vector<int> permutedParticles(numParticlesPerSet); vector<int> permutedParticles(numParticlesPerSet);
...@@ -176,7 +176,7 @@ void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector<int>& particle ...@@ -176,7 +176,7 @@ void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector<int>& particle
if (exclusions[p1].find(p2) != exclusions[p1].end()) if (exclusions[p1].find(p2) != exclusions[p1].end())
return; return;
if (useCutoff && (i == 0 || !centralParticleMode)) { if (useCutoff && (i == 0 || !centralParticleMode)) {
RealOpenMM delta[ReferenceForce::LastDeltaRIndex]; double delta[ReferenceForce::LastDeltaRIndex];
computeDelta(p1, p2, delta, atomCoordinates); computeDelta(p1, p2, delta, atomCoordinates);
if (delta[ReferenceForce::RIndex] >= cutoffDistance) if (delta[ReferenceForce::RIndex] >= cutoffDistance)
return; return;
...@@ -212,8 +212,8 @@ void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector<int>& particle ...@@ -212,8 +212,8 @@ void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector<int>& particle
computeDelta(permutedParticles[term.p2], permutedParticles[term.p1], term.delta1, atomCoordinates); computeDelta(permutedParticles[term.p2], permutedParticles[term.p1], term.delta1, atomCoordinates);
computeDelta(permutedParticles[term.p2], permutedParticles[term.p3], term.delta2, atomCoordinates); computeDelta(permutedParticles[term.p2], permutedParticles[term.p3], term.delta2, atomCoordinates);
computeDelta(permutedParticles[term.p4], permutedParticles[term.p3], term.delta3, atomCoordinates); computeDelta(permutedParticles[term.p4], permutedParticles[term.p3], term.delta3, atomCoordinates);
RealOpenMM dotDihedral, signOfDihedral; double dotDihedral, signOfDihedral;
RealOpenMM* crossProduct[] = {term.cross1, term.cross2}; double* crossProduct[] = {term.cross1, term.cross2};
variables[term.name] = ReferenceBondIxn::getDihedralAngleBetweenThreeVectors(term.delta1, term.delta2, term.delta3, crossProduct, &dotDihedral, term.delta1, &signOfDihedral, 1); variables[term.name] = ReferenceBondIxn::getDihedralAngleBetweenThreeVectors(term.delta1, term.delta2, term.delta3, crossProduct, &dotDihedral, term.delta1, &signOfDihedral, 1);
} }
...@@ -228,9 +228,9 @@ void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector<int>& particle ...@@ -228,9 +228,9 @@ void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector<int>& particle
for (int i = 0; i < (int) distanceTerms.size(); i++) { for (int i = 0; i < (int) distanceTerms.size(); i++) {
const DistanceTermInfo& term = distanceTerms[i]; const DistanceTermInfo& term = distanceTerms[i];
RealOpenMM dEdR = (RealOpenMM) (term.forceExpression.evaluate(variables)/(term.delta[ReferenceForce::RIndex])); double dEdR = term.forceExpression.evaluate(variables)/(term.delta[ReferenceForce::RIndex]);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
RealOpenMM force = -dEdR*term.delta[i]; double force = -dEdR*term.delta[i];
forces[permutedParticles[term.p1]][i] -= force; forces[permutedParticles[term.p1]][i] -= force;
forces[permutedParticles[term.p2]][i] += force; forces[permutedParticles[term.p2]][i] += force;
} }
...@@ -240,15 +240,15 @@ void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector<int>& particle ...@@ -240,15 +240,15 @@ void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector<int>& particle
for (int i = 0; i < (int) angleTerms.size(); i++) { for (int i = 0; i < (int) angleTerms.size(); i++) {
const AngleTermInfo& term = angleTerms[i]; const AngleTermInfo& term = angleTerms[i];
RealOpenMM dEdTheta = (RealOpenMM) term.forceExpression.evaluate(variables); double dEdTheta = term.forceExpression.evaluate(variables);
RealOpenMM thetaCross[ReferenceForce::LastDeltaRIndex]; double thetaCross[ReferenceForce::LastDeltaRIndex];
SimTKOpenMMUtilities::crossProductVector3(term.delta1, term.delta2, thetaCross); SimTKOpenMMUtilities::crossProductVector3(term.delta1, term.delta2, thetaCross);
RealOpenMM lengthThetaCross = SQRT(DOT3(thetaCross, thetaCross)); double lengthThetaCross = sqrt(DOT3(thetaCross, thetaCross));
if (lengthThetaCross < 1.0e-06) if (lengthThetaCross < 1.0e-06)
lengthThetaCross = (RealOpenMM) 1.0e-06; lengthThetaCross = 1.0e-06;
RealOpenMM termA = dEdTheta/(term.delta1[ReferenceForce::R2Index]*lengthThetaCross); double termA = dEdTheta/(term.delta1[ReferenceForce::R2Index]*lengthThetaCross);
RealOpenMM termC = -dEdTheta/(term.delta2[ReferenceForce::R2Index]*lengthThetaCross); double termC = -dEdTheta/(term.delta2[ReferenceForce::R2Index]*lengthThetaCross);
RealOpenMM deltaCrossP[3][3]; double deltaCrossP[3][3];
SimTKOpenMMUtilities::crossProductVector3(term.delta1, thetaCross, deltaCrossP[0]); SimTKOpenMMUtilities::crossProductVector3(term.delta1, thetaCross, deltaCrossP[0]);
SimTKOpenMMUtilities::crossProductVector3(term.delta2, thetaCross, deltaCrossP[2]); SimTKOpenMMUtilities::crossProductVector3(term.delta2, thetaCross, deltaCrossP[2]);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
...@@ -267,22 +267,22 @@ void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector<int>& particle ...@@ -267,22 +267,22 @@ void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector<int>& particle
for (int i = 0; i < (int) dihedralTerms.size(); i++) { for (int i = 0; i < (int) dihedralTerms.size(); i++) {
const DihedralTermInfo& term = dihedralTerms[i]; const DihedralTermInfo& term = dihedralTerms[i];
RealOpenMM dEdTheta = (RealOpenMM) term.forceExpression.evaluate(variables); double dEdTheta = term.forceExpression.evaluate(variables);
RealOpenMM internalF[4][3]; double internalF[4][3];
RealOpenMM forceFactors[4]; double forceFactors[4];
RealOpenMM normCross1 = DOT3(term.cross1, term.cross1); double normCross1 = DOT3(term.cross1, term.cross1);
RealOpenMM normBC = term.delta2[ReferenceForce::RIndex]; double normBC = term.delta2[ReferenceForce::RIndex];
forceFactors[0] = (-dEdTheta*normBC)/normCross1; forceFactors[0] = (-dEdTheta*normBC)/normCross1;
RealOpenMM normCross2 = DOT3(term.cross2, term.cross2); double normCross2 = DOT3(term.cross2, term.cross2);
forceFactors[3] = (dEdTheta*normBC)/normCross2; forceFactors[3] = (dEdTheta*normBC)/normCross2;
forceFactors[1] = DOT3(term.delta1, term.delta2); forceFactors[1] = DOT3(term.delta1, term.delta2);
forceFactors[1] /= term.delta2[ReferenceForce::R2Index]; forceFactors[1] /= term.delta2[ReferenceForce::R2Index];
forceFactors[2] = DOT3(term.delta3, term.delta2); forceFactors[2] = DOT3(term.delta3, term.delta2);
forceFactors[2] /= term.delta2[ReferenceForce::R2Index]; forceFactors[2] /= term.delta2[ReferenceForce::R2Index];
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
internalF[0][i] = forceFactors[0]*term.cross1[i]; internalF[0][i] = forceFactors[0]*term.cross1[i];
internalF[3][i] = forceFactors[3]*term.cross2[i]; internalF[3][i] = forceFactors[3]*term.cross2[i];
RealOpenMM s = forceFactors[1]*internalF[0][i] - forceFactors[2]*internalF[3][i]; double s = forceFactors[1]*internalF[0][i] - forceFactors[2]*internalF[3][i];
internalF[1][i] = internalF[0][i] - s; internalF[1][i] = internalF[0][i] - s;
internalF[2][i] = internalF[3][i] + s; internalF[2][i] = internalF[3][i] + s;
} }
...@@ -297,25 +297,25 @@ void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector<int>& particle ...@@ -297,25 +297,25 @@ void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector<int>& particle
// Add the energy // Add the energy
if (totalEnergy) if (totalEnergy)
*totalEnergy += (RealOpenMM) energyExpression.evaluate(variables); *totalEnergy += energyExpression.evaluate(variables);
} }
void ReferenceCustomManyParticleIxn::computeDelta(int atom1, int atom2, RealOpenMM* delta, vector<RealVec>& atomCoordinates) const { void ReferenceCustomManyParticleIxn::computeDelta(int atom1, int atom2, double* delta, vector<Vec3>& atomCoordinates) const {
if (usePeriodic) if (usePeriodic)
ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom1], atomCoordinates[atom2], periodicBoxVectors, delta); ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom1], atomCoordinates[atom2], periodicBoxVectors, delta);
else else
ReferenceForce::getDeltaR(atomCoordinates[atom1], atomCoordinates[atom2], delta); ReferenceForce::getDeltaR(atomCoordinates[atom1], atomCoordinates[atom2], delta);
} }
RealOpenMM ReferenceCustomManyParticleIxn::computeAngle(RealOpenMM* vec1, RealOpenMM* vec2) { double ReferenceCustomManyParticleIxn::computeAngle(double* vec1, double* vec2) {
RealOpenMM dot = DOT3(vec1, vec2); double dot = DOT3(vec1, vec2);
RealOpenMM cosine = dot/SQRT((vec1[ReferenceForce::R2Index]*vec2[ReferenceForce::R2Index])); double cosine = dot/sqrt((vec1[ReferenceForce::R2Index]*vec2[ReferenceForce::R2Index]));
RealOpenMM angle; double angle;
if (cosine >= 1) if (cosine >= 1)
angle = 0; angle = 0;
else if (cosine <= -1) else if (cosine <= -1)
angle = PI_M; angle = PI_M;
else else
angle = ACOS(cosine); angle = acos(cosine);
return angle; return angle;
} }
...@@ -69,13 +69,6 @@ ReferenceCustomNonbondedIxn::ReferenceCustomNonbondedIxn(const Lepton::CompiledE ...@@ -69,13 +69,6 @@ ReferenceCustomNonbondedIxn::ReferenceCustomNonbondedIxn(const Lepton::CompiledE
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceCustomNonbondedIxn::~ReferenceCustomNonbondedIxn() { ReferenceCustomNonbondedIxn::~ReferenceCustomNonbondedIxn() {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceCustomNonbondedIxn::~ReferenceCustomNonbondedIxn";
// ---------------------------------------------------------------------------------------
} }
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -87,7 +80,7 @@ ReferenceCustomNonbondedIxn::~ReferenceCustomNonbondedIxn() { ...@@ -87,7 +80,7 @@ ReferenceCustomNonbondedIxn::~ReferenceCustomNonbondedIxn() {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomNonbondedIxn::setUseCutoff(RealOpenMM distance, const OpenMM::NeighborList& neighbors) { void ReferenceCustomNonbondedIxn::setUseCutoff(double distance, const OpenMM::NeighborList& neighbors) {
cutoff = true; cutoff = true;
cutoffDistance = distance; cutoffDistance = distance;
...@@ -115,7 +108,7 @@ void ReferenceCustomNonbondedIxn::setInteractionGroups(const vector<pair<set<int ...@@ -115,7 +108,7 @@ void ReferenceCustomNonbondedIxn::setInteractionGroups(const vector<pair<set<int
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomNonbondedIxn::setUseSwitchingFunction(RealOpenMM distance) { void ReferenceCustomNonbondedIxn::setUseSwitchingFunction(double distance) {
useSwitch = true; useSwitch = true;
switchingDistance = distance; switchingDistance = distance;
} }
...@@ -130,7 +123,7 @@ void ReferenceCustomNonbondedIxn::setUseSwitchingFunction(RealOpenMM distance) { ...@@ -130,7 +123,7 @@ void ReferenceCustomNonbondedIxn::setUseSwitchingFunction(RealOpenMM distance) {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomNonbondedIxn::setPeriodic(OpenMM::RealVec* vectors) { void ReferenceCustomNonbondedIxn::setPeriodic(OpenMM::Vec3* vectors) {
assert(cutoff); assert(cutoff);
assert(vectors[0][0] >= 2.0*cutoffDistance); assert(vectors[0][0] >= 2.0*cutoffDistance);
...@@ -161,10 +154,10 @@ void ReferenceCustomNonbondedIxn::setUseSwitchingFunction(RealOpenMM distance) { ...@@ -161,10 +154,10 @@ void ReferenceCustomNonbondedIxn::setUseSwitchingFunction(RealOpenMM distance) {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomNonbondedIxn::calculatePairIxn(int numberOfAtoms, vector<RealVec>& atomCoordinates, void ReferenceCustomNonbondedIxn::calculatePairIxn(int numberOfAtoms, vector<Vec3>& atomCoordinates,
RealOpenMM** atomParameters, vector<set<int> >& exclusions, double** atomParameters, vector<set<int> >& exclusions,
RealOpenMM* fixedParameters, const map<string, double>& globalParameters, vector<RealVec>& forces, double* fixedParameters, const map<string, double>& globalParameters, vector<Vec3>& forces,
RealOpenMM* energyByAtom, RealOpenMM* totalEnergy, double* energyParamDerivs) { double* energyByAtom, double* totalEnergy, double* energyParamDerivs) {
for (map<string, double>::const_iterator iter = globalParameters.begin(); iter != globalParameters.end(); ++iter) for (map<string, double>::const_iterator iter = globalParameters.begin(); iter != globalParameters.end(); ++iter)
expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second); expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second);
...@@ -232,38 +225,38 @@ void ReferenceCustomNonbondedIxn::calculatePairIxn(int numberOfAtoms, vector<Rea ...@@ -232,38 +225,38 @@ void ReferenceCustomNonbondedIxn::calculatePairIxn(int numberOfAtoms, vector<Rea
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomNonbondedIxn::calculateOneIxn(int ii, int jj, vector<RealVec>& atomCoordinates, vector<RealVec>& forces, void ReferenceCustomNonbondedIxn::calculateOneIxn(int ii, int jj, vector<Vec3>& atomCoordinates, vector<Vec3>& forces,
RealOpenMM* energyByAtom, RealOpenMM* totalEnergy, double* energyParamDerivs) { double* energyByAtom, double* totalEnergy, double* energyParamDerivs) {
// get deltaR, R2, and R between 2 atoms // get deltaR, R2, and R between 2 atoms
RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; double deltaR[ReferenceForce::LastDeltaRIndex];
if (periodic) if (periodic)
ReferenceForce::getDeltaRPeriodic(atomCoordinates[jj], atomCoordinates[ii], periodicBoxVectors, deltaR); ReferenceForce::getDeltaRPeriodic(atomCoordinates[jj], atomCoordinates[ii], periodicBoxVectors, deltaR);
else else
ReferenceForce::getDeltaR(atomCoordinates[jj], atomCoordinates[ii], deltaR); ReferenceForce::getDeltaR(atomCoordinates[jj], atomCoordinates[ii], deltaR);
RealOpenMM r = deltaR[ReferenceForce::RIndex]; double r = deltaR[ReferenceForce::RIndex];
if (cutoff && r >= cutoffDistance) if (cutoff && r >= cutoffDistance)
return; return;
// accumulate forces // accumulate forces
expressionSet.setVariable(rIndex, r); expressionSet.setVariable(rIndex, r);
RealOpenMM dEdR = (RealOpenMM) (forceExpression.evaluate()/(deltaR[ReferenceForce::RIndex])); double dEdR = forceExpression.evaluate()/(deltaR[ReferenceForce::RIndex]);
RealOpenMM energy = (RealOpenMM) energyExpression.evaluate(); double energy = energyExpression.evaluate();
RealOpenMM switchValue = 1.0; double switchValue = 1.0;
if (useSwitch) { if (useSwitch) {
if (r > switchingDistance) { if (r > switchingDistance) {
RealOpenMM t = (r-switchingDistance)/(cutoffDistance-switchingDistance); double t = (r-switchingDistance)/(cutoffDistance-switchingDistance);
switchValue = 1+t*t*t*(-10+t*(15-t*6)); switchValue = 1+t*t*t*(-10+t*(15-t*6));
RealOpenMM switchDeriv = t*t*(-30+t*(60-t*30))/(cutoffDistance-switchingDistance); double switchDeriv = t*t*(-30+t*(60-t*30))/(cutoffDistance-switchingDistance);
dEdR = switchValue*dEdR + energy*switchDeriv/r; dEdR = switchValue*dEdR + energy*switchDeriv/r;
energy *= switchValue; energy *= switchValue;
} }
} }
for (int kk = 0; kk < 3; kk++) { for (int kk = 0; kk < 3; kk++) {
RealOpenMM force = -dEdR*deltaR[kk]; double force = -dEdR*deltaR[kk];
forces[ii][kk] += force; forces[ii][kk] += force;
forces[jj][kk] -= force; forces[jj][kk] -= force;
} }
for (int i = 0; i < energyParamDerivExpressions.size(); i++) for (int i = 0; i < energyParamDerivExpressions.size(); i++)
energyParamDerivs[i] += switchValue*energyParamDerivExpressions[i].evaluate(); energyParamDerivs[i] += switchValue*energyParamDerivExpressions[i].evaluate();
......
...@@ -62,7 +62,7 @@ ReferenceCustomTorsionIxn::ReferenceCustomTorsionIxn(const Lepton::CompiledExpre ...@@ -62,7 +62,7 @@ ReferenceCustomTorsionIxn::ReferenceCustomTorsionIxn(const Lepton::CompiledExpre
ReferenceCustomTorsionIxn::~ReferenceCustomTorsionIxn() { ReferenceCustomTorsionIxn::~ReferenceCustomTorsionIxn() {
} }
void ReferenceCustomTorsionIxn::setPeriodic(OpenMM::RealVec* vectors) { void ReferenceCustomTorsionIxn::setPeriodic(OpenMM::Vec3* vectors) {
usePeriodic = true; usePeriodic = true;
boxVectors[0] = vectors[0]; boxVectors[0] = vectors[0];
boxVectors[1] = vectors[1]; boxVectors[1] = vectors[1];
...@@ -82,11 +82,11 @@ void ReferenceCustomTorsionIxn::setPeriodic(OpenMM::RealVec* vectors) { ...@@ -82,11 +82,11 @@ void ReferenceCustomTorsionIxn::setPeriodic(OpenMM::RealVec* vectors) {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomTorsionIxn::calculateBondIxn(int* atomIndices, void ReferenceCustomTorsionIxn::calculateBondIxn(int* atomIndices,
vector<RealVec>& atomCoordinates, vector<Vec3>& atomCoordinates,
RealOpenMM* parameters, double* parameters,
vector<RealVec>& forces, vector<Vec3>& forces,
RealOpenMM* totalEnergy, double* energyParamDerivs) { double* totalEnergy, double* energyParamDerivs) {
RealOpenMM deltaR[3][ReferenceForce::LastDeltaRIndex]; double deltaR[3][ReferenceForce::LastDeltaRIndex];
for (int i = 0; i < numParameters; i++) for (int i = 0; i < numParameters; i++)
expressionSet.setVariable(torsionParamIndex[i], parameters[i]); expressionSet.setVariable(torsionParamIndex[i], parameters[i]);
...@@ -111,45 +111,45 @@ void ReferenceCustomTorsionIxn::calculateBondIxn(int* atomIndices, ...@@ -111,45 +111,45 @@ void ReferenceCustomTorsionIxn::calculateBondIxn(int* atomIndices,
// Visual Studio complains if crossProduct declared as 'crossProduct[2][3]' // Visual Studio complains if crossProduct declared as 'crossProduct[2][3]'
RealOpenMM crossProductMemory[6]; double crossProductMemory[6];
RealOpenMM* crossProduct[2]; double* crossProduct[2];
crossProduct[0] = crossProductMemory; crossProduct[0] = crossProductMemory;
crossProduct[1] = crossProductMemory + 3; crossProduct[1] = crossProductMemory + 3;
// get dihedral angle // get dihedral angle
RealOpenMM dotDihedral; double dotDihedral;
RealOpenMM signOfAngle; double signOfAngle;
RealOpenMM angle = getDihedralAngleBetweenThreeVectors(deltaR[0], deltaR[1], deltaR[2], crossProduct, &dotDihedral, deltaR[0], &signOfAngle, 1); double angle = getDihedralAngleBetweenThreeVectors(deltaR[0], deltaR[1], deltaR[2], crossProduct, &dotDihedral, deltaR[0], &signOfAngle, 1);
expressionSet.setVariable(thetaIndex, angle); expressionSet.setVariable(thetaIndex, angle);
// evaluate delta angle, dE/d(angle) // evaluate delta angle, dE/d(angle)
RealOpenMM dEdAngle = (RealOpenMM) forceExpression.evaluate(); double dEdAngle = forceExpression.evaluate();
// compute force // compute force
RealOpenMM internalF[4][3]; double internalF[4][3];
RealOpenMM forceFactors[4]; double forceFactors[4];
RealOpenMM normCross1 = DOT3(crossProduct[0], crossProduct[0]); double normCross1 = DOT3(crossProduct[0], crossProduct[0]);
RealOpenMM normBC = deltaR[1][ReferenceForce::RIndex]; double normBC = deltaR[1][ReferenceForce::RIndex];
forceFactors[0] = (-dEdAngle*normBC)/normCross1; forceFactors[0] = (-dEdAngle*normBC)/normCross1;
RealOpenMM normCross2 = DOT3(crossProduct[1], crossProduct[1]); double normCross2 = DOT3(crossProduct[1], crossProduct[1]);
forceFactors[3] = (dEdAngle*normBC)/normCross2; forceFactors[3] = (dEdAngle*normBC)/normCross2;
forceFactors[1] = DOT3(deltaR[0], deltaR[1]); forceFactors[1] = DOT3(deltaR[0], deltaR[1]);
forceFactors[1] /= deltaR[1][ReferenceForce::R2Index]; forceFactors[1] /= deltaR[1][ReferenceForce::R2Index];
forceFactors[2] = DOT3(deltaR[2], deltaR[1]); forceFactors[2] = DOT3(deltaR[2], deltaR[1]);
forceFactors[2] /= deltaR[1][ReferenceForce::R2Index]; forceFactors[2] /= deltaR[1][ReferenceForce::R2Index];
for (int ii = 0; ii < 3; ii++) { for (int ii = 0; ii < 3; ii++) {
internalF[0][ii] = forceFactors[0]*crossProduct[0][ii]; internalF[0][ii] = forceFactors[0]*crossProduct[0][ii];
internalF[3][ii] = forceFactors[3]*crossProduct[1][ii]; internalF[3][ii] = forceFactors[3]*crossProduct[1][ii];
RealOpenMM s = forceFactors[1]*internalF[0][ii] - forceFactors[2]*internalF[3][ii]; double s = forceFactors[1]*internalF[0][ii] - forceFactors[2]*internalF[3][ii];
internalF[1][ii] = internalF[0][ii] - s; internalF[1][ii] = internalF[0][ii] - s;
internalF[2][ii] = internalF[3][ii] + s; internalF[2][ii] = internalF[3][ii] + s;
...@@ -172,6 +172,6 @@ void ReferenceCustomTorsionIxn::calculateBondIxn(int* atomIndices, ...@@ -172,6 +172,6 @@ void ReferenceCustomTorsionIxn::calculateBondIxn(int* atomIndices,
// accumulate energies // accumulate energies
if (totalEnergy != NULL) if (totalEnergy != NULL)
*totalEnergy += (RealOpenMM) energyExpression.evaluate(); *totalEnergy += energyExpression.evaluate();
} }
...@@ -44,19 +44,10 @@ using namespace OpenMM; ...@@ -44,19 +44,10 @@ using namespace OpenMM;
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceDynamics::ReferenceDynamics(int numberOfAtoms, RealOpenMM deltaT, RealOpenMM temperature) : ReferenceDynamics::ReferenceDynamics(int numberOfAtoms, double deltaT, double temperature) :
_numberOfAtoms(numberOfAtoms), _deltaT(deltaT), _temperature(temperature) { _numberOfAtoms(numberOfAtoms), _deltaT(deltaT), _temperature(temperature) {
// --------------------------------------------------------------------------------------- _timeStep = 0;
// static const char* methodName = "\nReferenceDynamics::ReferenceDynamics";
static const RealOpenMM one = 1.0;
// ---------------------------------------------------------------------------------------
_timeStep = 0;
_ownReferenceConstraint = false; _ownReferenceConstraint = false;
_referenceConstraint = NULL; _referenceConstraint = NULL;
} }
...@@ -68,13 +59,6 @@ ReferenceDynamics::ReferenceDynamics(int numberOfAtoms, RealOpenMM deltaT, Real ...@@ -68,13 +59,6 @@ ReferenceDynamics::ReferenceDynamics(int numberOfAtoms, RealOpenMM deltaT, Real
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceDynamics::~ReferenceDynamics() { ReferenceDynamics::~ReferenceDynamics() {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceDynamics::~ReferenceDynamics";
// ---------------------------------------------------------------------------------------
if (_ownReferenceConstraint) { if (_ownReferenceConstraint) {
delete _referenceConstraint; delete _referenceConstraint;
} }
...@@ -89,13 +73,6 @@ ReferenceDynamics::~ReferenceDynamics() { ...@@ -89,13 +73,6 @@ ReferenceDynamics::~ReferenceDynamics() {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
int ReferenceDynamics::getNumberOfAtoms() const { int ReferenceDynamics::getNumberOfAtoms() const {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceDynamics::getNumberOfAtoms";
// ---------------------------------------------------------------------------------------
return _numberOfAtoms; return _numberOfAtoms;
} }
...@@ -108,13 +85,6 @@ int ReferenceDynamics::getNumberOfAtoms() const { ...@@ -108,13 +85,6 @@ int ReferenceDynamics::getNumberOfAtoms() const {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
int ReferenceDynamics::getTimeStep() const { int ReferenceDynamics::getTimeStep() const {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceDynamics::getTimeStep";
// ---------------------------------------------------------------------------------------
return _timeStep; return _timeStep;
} }
...@@ -127,13 +97,6 @@ int ReferenceDynamics::getTimeStep() const { ...@@ -127,13 +97,6 @@ int ReferenceDynamics::getTimeStep() const {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
int ReferenceDynamics::incrementTimeStep() { int ReferenceDynamics::incrementTimeStep() {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceDynamics::getTimeStep";
// ---------------------------------------------------------------------------------------
return (++_timeStep); return (++_timeStep);
} }
...@@ -145,14 +108,7 @@ int ReferenceDynamics::incrementTimeStep() { ...@@ -145,14 +108,7 @@ int ReferenceDynamics::incrementTimeStep() {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM ReferenceDynamics::getDeltaT() const { double ReferenceDynamics::getDeltaT() const {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceDynamics::getDeltaT";
// ---------------------------------------------------------------------------------------
return _deltaT; return _deltaT;
} }
...@@ -162,14 +118,7 @@ RealOpenMM ReferenceDynamics::getDeltaT() const { ...@@ -162,14 +118,7 @@ RealOpenMM ReferenceDynamics::getDeltaT() const {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceDynamics::setDeltaT(RealOpenMM deltaT) { void ReferenceDynamics::setDeltaT(double deltaT) {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceDynamics::setDeltaT";
// ---------------------------------------------------------------------------------------
_deltaT = deltaT; _deltaT = deltaT;
} }
...@@ -181,14 +130,7 @@ void ReferenceDynamics::setDeltaT(RealOpenMM deltaT) { ...@@ -181,14 +130,7 @@ void ReferenceDynamics::setDeltaT(RealOpenMM deltaT) {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM ReferenceDynamics::getTemperature() const { double ReferenceDynamics::getTemperature() const {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceDynamics::getTemperature";
// ---------------------------------------------------------------------------------------
return _temperature; return _temperature;
} }
...@@ -201,13 +143,6 @@ RealOpenMM ReferenceDynamics::getTemperature() const { ...@@ -201,13 +143,6 @@ RealOpenMM ReferenceDynamics::getTemperature() const {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceConstraintAlgorithm* ReferenceDynamics::getReferenceConstraintAlgorithm() const { ReferenceConstraintAlgorithm* ReferenceDynamics::getReferenceConstraintAlgorithm() const {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceDynamics::getReferenceConstraint";
// ---------------------------------------------------------------------------------------
return _referenceConstraint; return _referenceConstraint;
} }
...@@ -220,13 +155,6 @@ ReferenceConstraintAlgorithm* ReferenceDynamics::getReferenceConstraintAlgorithm ...@@ -220,13 +155,6 @@ ReferenceConstraintAlgorithm* ReferenceDynamics::getReferenceConstraintAlgorithm
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceDynamics::setReferenceConstraintAlgorithm(ReferenceConstraintAlgorithm* referenceConstraint) { void ReferenceDynamics::setReferenceConstraintAlgorithm(ReferenceConstraintAlgorithm* referenceConstraint) {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceDynamics::setReferenceConstraint";
// ---------------------------------------------------------------------------------------
// delete if own // delete if own
if (_referenceConstraint && _ownReferenceConstraint) { if (_referenceConstraint && _ownReferenceConstraint) {
...@@ -251,15 +179,6 @@ void ReferenceDynamics::setReferenceConstraintAlgorithm(ReferenceConstraintAlgor ...@@ -251,15 +179,6 @@ void ReferenceDynamics::setReferenceConstraintAlgorithm(ReferenceConstraintAlgor
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceDynamics::update(const OpenMM::System& system, vector<RealVec>& atomCoordinates, void ReferenceDynamics::update(const OpenMM::System& system, vector<Vec3>& atomCoordinates,
vector<RealVec>& velocities, vector<RealVec>& forces, vector<RealOpenMM>& masses, RealOpenMM tolerance) { vector<Vec3>& velocities, vector<Vec3>& forces, vector<double>& masses, double tolerance) {
// ---------------------------------------------------------------------------------------
static const char* methodName = "\nReferenceDynamics::update";
static const RealOpenMM zero = 0.0;
static const RealOpenMM one = 1.0;
// ---------------------------------------------------------------------------------------
} }
...@@ -56,40 +56,40 @@ ReferenceForce::~ReferenceForce() { ...@@ -56,40 +56,40 @@ ReferenceForce::~ReferenceForce() {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM ReferenceForce::periodicDifference(RealOpenMM val1, RealOpenMM val2, RealOpenMM period) { double ReferenceForce::periodicDifference(double val1, double val2, double period) {
RealOpenMM diff = val1-val2; double diff = val1-val2;
RealOpenMM base = (RealOpenMM) (floor(diff/period+0.5)*period); double base = floor(diff/period+0.5)*period;
return diff-base; return diff-base;
} }
void ReferenceForce::getDeltaR(const RealVec& atomCoordinatesI, const RealVec& atomCoordinatesJ, void ReferenceForce::getDeltaR(const Vec3& atomCoordinatesI, const Vec3& atomCoordinatesJ,
RealOpenMM* deltaR) { double* deltaR) {
deltaR[XIndex] = atomCoordinatesJ[0] - atomCoordinatesI[0]; deltaR[XIndex] = atomCoordinatesJ[0] - atomCoordinatesI[0];
deltaR[YIndex] = atomCoordinatesJ[1] - atomCoordinatesI[1]; deltaR[YIndex] = atomCoordinatesJ[1] - atomCoordinatesI[1];
deltaR[ZIndex] = atomCoordinatesJ[2] - atomCoordinatesI[2]; deltaR[ZIndex] = atomCoordinatesJ[2] - atomCoordinatesI[2];
deltaR[R2Index] = DOT3(deltaR, deltaR); deltaR[R2Index] = DOT3(deltaR, deltaR);
deltaR[RIndex] = (RealOpenMM) SQRT(deltaR[R2Index]); deltaR[RIndex] = sqrt(deltaR[R2Index]);
} }
RealVec ReferenceForce::getDeltaR(const RealVec& atomCoordinatesI, const RealVec& atomCoordinatesJ) { Vec3 ReferenceForce::getDeltaR(const Vec3& atomCoordinatesI, const Vec3& atomCoordinatesJ) {
return atomCoordinatesJ-atomCoordinatesI; return atomCoordinatesJ-atomCoordinatesI;
} }
void ReferenceForce::getDeltaRPeriodic(const RealVec& atomCoordinatesI, const RealVec& atomCoordinatesJ, void ReferenceForce::getDeltaRPeriodic(const Vec3& atomCoordinatesI, const Vec3& atomCoordinatesJ,
const RealOpenMM* boxSize, RealOpenMM* deltaR) { const double* boxSize, double* deltaR) {
deltaR[XIndex] = periodicDifference(atomCoordinatesJ[0], atomCoordinatesI[0], boxSize[0]); deltaR[XIndex] = periodicDifference(atomCoordinatesJ[0], atomCoordinatesI[0], boxSize[0]);
deltaR[YIndex] = periodicDifference(atomCoordinatesJ[1], atomCoordinatesI[1], boxSize[1]); deltaR[YIndex] = periodicDifference(atomCoordinatesJ[1], atomCoordinatesI[1], boxSize[1]);
deltaR[ZIndex] = periodicDifference(atomCoordinatesJ[2], atomCoordinatesI[2], boxSize[2]); deltaR[ZIndex] = periodicDifference(atomCoordinatesJ[2], atomCoordinatesI[2], boxSize[2]);
deltaR[R2Index] = DOT3(deltaR, deltaR); deltaR[R2Index] = DOT3(deltaR, deltaR);
deltaR[RIndex] = (RealOpenMM) SQRT(deltaR[R2Index]); deltaR[RIndex] = sqrt(deltaR[R2Index]);
} }
void ReferenceForce::getDeltaRPeriodic(const RealVec& atomCoordinatesI, const RealVec& atomCoordinatesJ, void ReferenceForce::getDeltaRPeriodic(const Vec3& atomCoordinatesI, const Vec3& atomCoordinatesJ,
const RealVec* boxVectors, RealOpenMM* deltaR) { const Vec3* boxVectors, double* deltaR) {
RealVec diff = atomCoordinatesJ-atomCoordinatesI; Vec3 diff = atomCoordinatesJ-atomCoordinatesI;
diff -= boxVectors[2]*floor(diff[2]/boxVectors[2][2]+0.5); diff -= boxVectors[2]*floor(diff[2]/boxVectors[2][2]+0.5);
diff -= boxVectors[1]*floor(diff[1]/boxVectors[1][1]+0.5); diff -= boxVectors[1]*floor(diff[1]/boxVectors[1][1]+0.5);
diff -= boxVectors[0]*floor(diff[0]/boxVectors[0][0]+0.5); diff -= boxVectors[0]*floor(diff[0]/boxVectors[0][0]+0.5);
...@@ -97,12 +97,12 @@ void ReferenceForce::getDeltaRPeriodic(const RealVec& atomCoordinatesI, const Re ...@@ -97,12 +97,12 @@ void ReferenceForce::getDeltaRPeriodic(const RealVec& atomCoordinatesI, const Re
deltaR[YIndex] = diff[1]; deltaR[YIndex] = diff[1];
deltaR[ZIndex] = diff[2]; deltaR[ZIndex] = diff[2];
deltaR[R2Index] = diff.dot(diff); deltaR[R2Index] = diff.dot(diff);
deltaR[RIndex] = SQRT(deltaR[R2Index]); deltaR[RIndex] = sqrt(deltaR[R2Index]);
} }
RealVec ReferenceForce::getDeltaRPeriodic(const RealVec& atomCoordinatesI, const RealVec& atomCoordinatesJ, Vec3 ReferenceForce::getDeltaRPeriodic(const Vec3& atomCoordinatesI, const Vec3& atomCoordinatesJ,
const RealVec* boxVectors) { const Vec3* boxVectors) {
RealVec diff = atomCoordinatesJ-atomCoordinatesI; Vec3 diff = atomCoordinatesJ-atomCoordinatesI;
diff -= boxVectors[2]*floor(diff[2]/boxVectors[2][2]+0.5); diff -= boxVectors[2]*floor(diff[2]/boxVectors[2][2]+0.5);
diff -= boxVectors[1]*floor(diff[1]/boxVectors[1][1]+0.5); diff -= boxVectors[1]*floor(diff[1]/boxVectors[1][1]+0.5);
diff -= boxVectors[0]*floor(diff[0]/boxVectors[0][0]+0.5); diff -= boxVectors[0]*floor(diff[0]/boxVectors[0][0]+0.5);
......
...@@ -78,11 +78,11 @@ ReferenceGayBerneForce::ReferenceGayBerneForce(const GayBerneForce& force) { ...@@ -78,11 +78,11 @@ ReferenceGayBerneForce::ReferenceGayBerneForce(const GayBerneForce& force) {
for (int i = 0; i < numParticles; i++) { for (int i = 0; i < numParticles; i++) {
ParticleInfo& p = particles[i]; ParticleInfo& p = particles[i];
s[i] = (p.rx*p.ry + p.rz*p.rz)*SQRT(p.rx*p.ry); s[i] = (p.rx*p.ry + p.rz*p.rz)*sqrt(p.rx*p.ry);
} }
} }
RealOpenMM ReferenceGayBerneForce::calculateForce(const vector<RealVec>& positions, vector<RealVec>& forces, const RealVec* boxVectors) { double ReferenceGayBerneForce::calculateForce(const vector<Vec3>& positions, vector<Vec3>& forces, const Vec3* boxVectors) {
if (nonbondedMethod == GayBerneForce::CutoffPeriodic) { if (nonbondedMethod == GayBerneForce::CutoffPeriodic) {
double minAllowedSize = 1.999999*cutoffDistance; double minAllowedSize = 1.999999*cutoffDistance;
if (boxVectors[0][0] < minAllowedSize || boxVectors[1][1] < minAllowedSize || boxVectors[2][2] < minAllowedSize) if (boxVectors[0][0] < minAllowedSize || boxVectors[1][1] < minAllowedSize || boxVectors[2][2] < minAllowedSize)
...@@ -95,9 +95,9 @@ RealOpenMM ReferenceGayBerneForce::calculateForce(const vector<RealVec>& positio ...@@ -95,9 +95,9 @@ RealOpenMM ReferenceGayBerneForce::calculateForce(const vector<RealVec>& positio
// Compute standard interactions. // Compute standard interactions.
RealOpenMM energy = 0; double energy = 0;
int numParticles = particles.size(); int numParticles = particles.size();
vector<RealVec> torques(numParticles, Vec3()); vector<Vec3> torques(numParticles, Vec3());
for (int i = 1; i < numParticles; i++) { for (int i = 1; i < numParticles; i++) {
if (particles[i].epsilon == 0.0) if (particles[i].epsilon == 0.0)
continue; continue;
...@@ -106,8 +106,8 @@ RealOpenMM ReferenceGayBerneForce::calculateForce(const vector<RealVec>& positio ...@@ -106,8 +106,8 @@ RealOpenMM ReferenceGayBerneForce::calculateForce(const vector<RealVec>& positio
continue; continue;
if (exclusions.find(make_pair(j, i)) != exclusions.end()) if (exclusions.find(make_pair(j, i)) != exclusions.end())
continue; // This interaction will be handled by an exception. continue; // This interaction will be handled by an exception.
RealOpenMM sigma = 0.5*(particles[i].sigma+particles[j].sigma); double sigma = 0.5*(particles[i].sigma+particles[j].sigma);
RealOpenMM epsilon = SQRT(particles[i].epsilon*particles[j].epsilon); double epsilon = sqrt(particles[i].epsilon*particles[j].epsilon);
energy += computeOneInteraction(i, j, sigma, epsilon, positions, forces, torques, boxVectors); energy += computeOneInteraction(i, j, sigma, epsilon, positions, forces, torques, boxVectors);
} }
} }
...@@ -126,39 +126,39 @@ RealOpenMM ReferenceGayBerneForce::calculateForce(const vector<RealVec>& positio ...@@ -126,39 +126,39 @@ RealOpenMM ReferenceGayBerneForce::calculateForce(const vector<RealVec>& positio
return energy; return energy;
} }
void ReferenceGayBerneForce::computeEllipsoidFrames(const vector<RealVec>& positions) { void ReferenceGayBerneForce::computeEllipsoidFrames(const vector<Vec3>& positions) {
int numParticles = particles.size(); int numParticles = particles.size();
for (int particle = 0; particle < numParticles; particle++) { for (int particle = 0; particle < numParticles; particle++) {
ParticleInfo& p = particles[particle]; ParticleInfo& p = particles[particle];
// Compute the local coordinate system of the ellipsoid; // Compute the local coordinate system of the ellipsoid;
RealVec xdir, ydir, zdir; Vec3 xdir, ydir, zdir;
if (p.xparticle == -1) { if (p.xparticle == -1) {
xdir = RealVec(1, 0, 0); xdir = Vec3(1, 0, 0);
ydir = RealVec(0, 1, 0); ydir = Vec3(0, 1, 0);
} }
else { else {
xdir = positions[particle]-positions[p.xparticle]; xdir = positions[particle]-positions[p.xparticle];
xdir /= SQRT(xdir.dot(xdir)); xdir /= sqrt(xdir.dot(xdir));
if (p.yparticle == -1) { if (p.yparticle == -1) {
if (xdir[1] > -0.5 && xdir[1] < 0.5) if (xdir[1] > -0.5 && xdir[1] < 0.5)
ydir = RealVec(0, 1, 0); ydir = Vec3(0, 1, 0);
else else
ydir = RealVec(1, 0, 0); ydir = Vec3(1, 0, 0);
} }
else else
ydir = positions[particle]-positions[p.yparticle]; ydir = positions[particle]-positions[p.yparticle];
ydir -= xdir*(xdir.dot(ydir)); ydir -= xdir*(xdir.dot(ydir));
ydir /= SQRT(ydir.dot(ydir)); ydir /= sqrt(ydir.dot(ydir));
} }
zdir = xdir.cross(ydir); zdir = xdir.cross(ydir);
// Compute matrices we will need later. // Compute matrices we will need later.
RealOpenMM (&a)[3][3] = A[particle].v; double (&a)[3][3] = A[particle].v;
RealOpenMM (&b)[3][3] = B[particle].v; double (&b)[3][3] = B[particle].v;
RealOpenMM (&g)[3][3] = G[particle].v; double (&g)[3][3] = G[particle].v;
a[0][0] = xdir[0]; a[0][0] = xdir[0];
a[0][1] = xdir[1]; a[0][1] = xdir[1];
a[0][2] = xdir[2]; a[0][2] = xdir[2];
...@@ -168,8 +168,8 @@ void ReferenceGayBerneForce::computeEllipsoidFrames(const vector<RealVec>& posit ...@@ -168,8 +168,8 @@ void ReferenceGayBerneForce::computeEllipsoidFrames(const vector<RealVec>& posit
a[2][0] = zdir[0]; a[2][0] = zdir[0];
a[2][1] = zdir[1]; a[2][1] = zdir[1];
a[2][2] = zdir[2]; a[2][2] = zdir[2];
RealVec r2(p.rx*p.rx, p.ry*p.ry, p.rz*p.rz); Vec3 r2(p.rx*p.rx, p.ry*p.ry, p.rz*p.rz);
RealVec e2(1/sqrt(p.ex), 1/sqrt(p.ey), 1/sqrt(p.ez)); Vec3 e2(1/sqrt(p.ex), 1/sqrt(p.ey), 1/sqrt(p.ez));
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
b[i][j] = 0; b[i][j] = 0;
...@@ -182,26 +182,26 @@ void ReferenceGayBerneForce::computeEllipsoidFrames(const vector<RealVec>& posit ...@@ -182,26 +182,26 @@ void ReferenceGayBerneForce::computeEllipsoidFrames(const vector<RealVec>& posit
} }
} }
void ReferenceGayBerneForce::applyTorques(const vector<RealVec>& positions, vector<RealVec>& forces, const vector<RealVec>& torques) { void ReferenceGayBerneForce::applyTorques(const vector<Vec3>& positions, vector<Vec3>& forces, const vector<Vec3>& torques) {
int numParticles = particles.size(); int numParticles = particles.size();
for (int particle = 0; particle < numParticles; particle++) { for (int particle = 0; particle < numParticles; particle++) {
ParticleInfo& p = particles[particle]; ParticleInfo& p = particles[particle];
RealVec pos = positions[particle]; Vec3 pos = positions[particle];
if (p.xparticle != -1) { if (p.xparticle != -1) {
// Apply a force to the x particle. // Apply a force to the x particle.
RealVec dx = positions[p.xparticle]-pos; Vec3 dx = positions[p.xparticle]-pos;
double dx2 = dx.dot(dx); double dx2 = dx.dot(dx);
RealVec f = torques[particle].cross(dx)/dx2; Vec3 f = torques[particle].cross(dx)/dx2;
forces[p.xparticle] += f; forces[p.xparticle] += f;
forces[particle] -= f; forces[particle] -= f;
if (p.yparticle != -1) { if (p.yparticle != -1) {
// Apply a force to the y particle. This is based on the component of the torque // Apply a force to the y particle. This is based on the component of the torque
// that was not already applied to the x particle. // that was not already applied to the x particle.
RealVec dy = positions[p.yparticle]-pos; Vec3 dy = positions[p.yparticle]-pos;
double dy2 = dy.dot(dy); double dy2 = dy.dot(dy);
RealVec torque = dx*(torques[particle].dot(dx)/dx2); Vec3 torque = dx*(torques[particle].dot(dx)/dx2);
f = torque.cross(dy)/dy2; f = torque.cross(dy)/dy2;
forces[p.yparticle] += f; forces[p.yparticle] += f;
forces[particle] -= f; forces[particle] -= f;
...@@ -210,62 +210,62 @@ void ReferenceGayBerneForce::applyTorques(const vector<RealVec>& positions, vect ...@@ -210,62 +210,62 @@ void ReferenceGayBerneForce::applyTorques(const vector<RealVec>& positions, vect
} }
} }
RealOpenMM ReferenceGayBerneForce::computeOneInteraction(int particle1, int particle2, RealOpenMM sigma, RealOpenMM epsilon, const vector<RealVec>& positions, double ReferenceGayBerneForce::computeOneInteraction(int particle1, int particle2, double sigma, double epsilon, const vector<Vec3>& positions,
vector<RealVec>& forces, vector<RealVec>& torques, const RealVec* boxVectors) { vector<Vec3>& forces, vector<Vec3>& torques, const Vec3* boxVectors) {
// Compute the displacement and check against the cutoff. // Compute the displacement and check against the cutoff.
RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; double deltaR[ReferenceForce::LastDeltaRIndex];
if (nonbondedMethod == GayBerneForce::CutoffPeriodic) if (nonbondedMethod == GayBerneForce::CutoffPeriodic)
ReferenceForce::getDeltaRPeriodic(positions[particle2], positions[particle1], boxVectors, deltaR); ReferenceForce::getDeltaRPeriodic(positions[particle2], positions[particle1], boxVectors, deltaR);
else else
ReferenceForce::getDeltaR(positions[particle2], positions[particle1], deltaR); ReferenceForce::getDeltaR(positions[particle2], positions[particle1], deltaR);
RealOpenMM r = deltaR[ReferenceForce::RIndex]; double r = deltaR[ReferenceForce::RIndex];
if (nonbondedMethod != GayBerneForce::NoCutoff && r >= cutoffDistance) if (nonbondedMethod != GayBerneForce::NoCutoff && r >= cutoffDistance)
return 0; return 0;
// Compute vectors and matrices we'll be needing. // Compute vectors and matrices we'll be needing.
RealOpenMM rInv = 1/r; double rInv = 1/r;
RealVec dr(deltaR[ReferenceForce::XIndex], deltaR[ReferenceForce::YIndex], deltaR[ReferenceForce::ZIndex]); Vec3 dr(deltaR[ReferenceForce::XIndex], deltaR[ReferenceForce::YIndex], deltaR[ReferenceForce::ZIndex]);
RealVec drUnit = dr*rInv; Vec3 drUnit = dr*rInv;
Matrix B12 = B[particle1]+B[particle2]; Matrix B12 = B[particle1]+B[particle2];
Matrix G12 = G[particle1]+G[particle2]; Matrix G12 = G[particle1]+G[particle2];
Matrix B12inv = B12.inverse(); Matrix B12inv = B12.inverse();
Matrix G12inv = G12.inverse(); Matrix G12inv = G12.inverse();
RealOpenMM detG12 = G12.determinant(); double detG12 = G12.determinant();
// Compute the switching function. // Compute the switching function.
RealOpenMM switchValue = 1, switchDeriv = 0; double switchValue = 1, switchDeriv = 0;
if (useSwitchingFunction && r > switchingDistance) { if (useSwitchingFunction && r > switchingDistance) {
RealOpenMM t = (r-switchingDistance)/(cutoffDistance-switchingDistance); double t = (r-switchingDistance)/(cutoffDistance-switchingDistance);
switchValue = 1+t*t*t*(-10+t*(15-t*6)); switchValue = 1+t*t*t*(-10+t*(15-t*6));
switchDeriv = t*t*(-30+t*(60-t*30))/(cutoffDistance-switchingDistance); switchDeriv = t*t*(-30+t*(60-t*30))/(cutoffDistance-switchingDistance);
} }
// Estimate the distance between the ellipsoids and compute the first terms needed for the energy. // Estimate the distance between the ellipsoids and compute the first terms needed for the energy.
RealOpenMM sigma12 = 1/SQRT(0.5*drUnit.dot(G12inv*drUnit)); double sigma12 = 1/sqrt(0.5*drUnit.dot(G12inv*drUnit));
RealOpenMM h12 = r - sigma12; double h12 = r - sigma12;
RealOpenMM rho = sigma/(h12+sigma); double rho = sigma/(h12+sigma);
RealOpenMM rho2 = rho*rho; double rho2 = rho*rho;
RealOpenMM rho6 = rho2*rho2*rho2; double rho6 = rho2*rho2*rho2;
RealOpenMM u = 4*epsilon*(rho6*rho6-rho6); double u = 4*epsilon*(rho6*rho6-rho6);
RealOpenMM eta = SQRT(2*s[particle1]*s[particle2]/detG12); double eta = sqrt(2*s[particle1]*s[particle2]/detG12);
RealOpenMM chi = 2*drUnit.dot(B12inv*drUnit); double chi = 2*drUnit.dot(B12inv*drUnit);
chi *= chi; chi *= chi;
RealOpenMM energy = u*eta*chi; double energy = u*eta*chi;
// Compute the terms needed for the force. // Compute the terms needed for the force.
RealVec kappa = G12inv*dr; Vec3 kappa = G12inv*dr;
RealVec iota = B12inv*dr; Vec3 iota = B12inv*dr;
RealOpenMM rInv2 = rInv*rInv; double rInv2 = rInv*rInv;
RealOpenMM dUSLJdr = 24*epsilon*(2*rho6-1)*rho6*rho/sigma; double dUSLJdr = 24*epsilon*(2*rho6-1)*rho6*rho/sigma;
RealOpenMM temp = 0.5*sigma12*sigma12*sigma12*rInv2; double temp = 0.5*sigma12*sigma12*sigma12*rInv2;
RealVec dudr = (drUnit + (kappa-drUnit*kappa.dot(drUnit))*temp)*dUSLJdr; Vec3 dudr = (drUnit + (kappa-drUnit*kappa.dot(drUnit))*temp)*dUSLJdr;
RealVec dchidr = (iota-drUnit*iota.dot(drUnit))*(-8*rInv2*SQRT(chi)); Vec3 dchidr = (iota-drUnit*iota.dot(drUnit))*(-8*rInv2*sqrt(chi));
RealVec force = (dchidr*u + dudr*chi)*(eta*switchValue) - drUnit*(energy*switchDeriv); Vec3 force = (dchidr*u + dudr*chi)*(eta*switchValue) - drUnit*(energy*switchDeriv);
forces[particle1] += force; forces[particle1] += force;
forces[particle2] -= force; forces[particle2] -= force;
...@@ -273,14 +273,14 @@ RealOpenMM ReferenceGayBerneForce::computeOneInteraction(int particle1, int part ...@@ -273,14 +273,14 @@ RealOpenMM ReferenceGayBerneForce::computeOneInteraction(int particle1, int part
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
int particle = (j == 0 ? particle1 : particle2); int particle = (j == 0 ? particle1 : particle2);
RealVec dudq = (kappa*G[particle]).cross(kappa*(temp*dUSLJdr)); Vec3 dudq = (kappa*G[particle]).cross(kappa*(temp*dUSLJdr));
RealVec dchidq = (iota*B[particle]).cross(iota)*(-4*rInv2); Vec3 dchidq = (iota*B[particle]).cross(iota)*(-4*rInv2);
RealOpenMM (&g12)[3][3] = G12.v; double (&g12)[3][3] = G12.v;
RealOpenMM (&a)[3][3] = A[particle].v; double (&a)[3][3] = A[particle].v;
ParticleInfo& p = particles[particle]; ParticleInfo& p = particles[particle];
RealVec scale = RealVec(p.rx*p.rx, p.ry*p.ry, p.rz*p.rz)*(-0.5*eta/detG12); Vec3 scale = Vec3(p.rx*p.rx, p.ry*p.ry, p.rz*p.rz)*(-0.5*eta/detG12);
Matrix D; Matrix D;
RealOpenMM (&d)[3][3] = D.v; double (&d)[3][3] = D.v;
d[0][0] = scale[0]*(2*a[0][0]*(g12[1][1]*g12[2][2] - g12[1][2]*g12[2][1]) + d[0][0] = scale[0]*(2*a[0][0]*(g12[1][1]*g12[2][2] - g12[1][2]*g12[2][1]) +
a[0][2]*(g12[1][2]*g12[0][1] + g12[1][0]*g12[2][1] - g12[1][1]*(g12[0][2] + g12[2][0])) + a[0][2]*(g12[1][2]*g12[0][1] + g12[1][0]*g12[2][1] - g12[1][1]*(g12[0][2] + g12[2][0])) +
a[0][1]*(g12[0][2]*g12[2][1] + g12[2][0]*g12[1][2] - g12[2][2]*(g12[0][1] + g12[1][0]))); a[0][1]*(g12[0][2]*g12[2][1] + g12[2][0]*g12[1][2] - g12[2][2]*(g12[0][1] + g12[1][0])));
...@@ -308,10 +308,10 @@ RealOpenMM ReferenceGayBerneForce::computeOneInteraction(int particle1, int part ...@@ -308,10 +308,10 @@ RealOpenMM ReferenceGayBerneForce::computeOneInteraction(int particle1, int part
d[2][2] = scale[2]*( a[2][0]*(g12[0][1]*g12[1][2] + g12[2][1]*g12[1][0] - g12[1][1]*(g12[0][2] + g12[2][0])) + d[2][2] = scale[2]*( a[2][0]*(g12[0][1]*g12[1][2] + g12[2][1]*g12[1][0] - g12[1][1]*(g12[0][2] + g12[2][0])) +
a[2][1]*(g12[1][0]*g12[0][2] + g12[2][0]*g12[0][1] - g12[0][0]*(g12[1][2] + g12[2][1])) + a[2][1]*(g12[1][0]*g12[0][2] + g12[2][0]*g12[0][1] - g12[0][0]*(g12[1][2] + g12[2][1])) +
2*a[2][2]*(g12[1][1]*g12[0][0] - g12[1][0]*g12[0][1])); 2*a[2][2]*(g12[1][1]*g12[0][0] - g12[1][0]*g12[0][1]));
RealVec detadq; Vec3 detadq;
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
detadq += RealVec(a[i][0], a[i][1], a[i][2]).cross(RealVec(d[i][0], d[i][1], d[i][2])); detadq += Vec3(a[i][0], a[i][1], a[i][2]).cross(Vec3(d[i][0], d[i][1], d[i][2]));
RealVec torque = (dchidq*(u*eta) + detadq*(u*chi) + dudq*(eta*chi))*switchValue; Vec3 torque = (dchidq*(u*eta) + detadq*(u*chi) + dudq*(eta*chi))*switchValue;
torques[particle] -= torque; torques[particle] -= torque;
} }
return switchValue*energy; return switchValue*energy;
......
...@@ -50,7 +50,7 @@ ReferenceHarmonicBondIxn::ReferenceHarmonicBondIxn() : usePeriodic(false) { ...@@ -50,7 +50,7 @@ ReferenceHarmonicBondIxn::ReferenceHarmonicBondIxn() : usePeriodic(false) {
ReferenceHarmonicBondIxn::~ReferenceHarmonicBondIxn() { ReferenceHarmonicBondIxn::~ReferenceHarmonicBondIxn() {
} }
void ReferenceHarmonicBondIxn::setPeriodic(OpenMM::RealVec* vectors) { void ReferenceHarmonicBondIxn::setPeriodic(OpenMM::Vec3* vectors) {
usePeriodic = true; usePeriodic = true;
boxVectors[0] = vectors[0]; boxVectors[0] = vectors[0];
boxVectors[1] = vectors[1]; boxVectors[1] = vectors[1];
...@@ -71,20 +71,11 @@ void ReferenceHarmonicBondIxn::setPeriodic(OpenMM::RealVec* vectors) { ...@@ -71,20 +71,11 @@ void ReferenceHarmonicBondIxn::setPeriodic(OpenMM::RealVec* vectors) {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceHarmonicBondIxn::calculateBondIxn(int* atomIndices, void ReferenceHarmonicBondIxn::calculateBondIxn(int* atomIndices,
vector<RealVec>& atomCoordinates, vector<Vec3>& atomCoordinates,
RealOpenMM* parameters, double* parameters,
vector<RealVec>& forces, vector<Vec3>& forces,
RealOpenMM* totalEnergy, double* energyParamDerivs) { double* totalEnergy, double* energyParamDerivs) {
double deltaR[ReferenceForce::LastDeltaRIndex];
static const std::string methodName = "\nReferenceHarmonicBondIxn::calculateBondIxn";
static const int twoI = 2;
static const RealOpenMM zero = 0.0;
static const RealOpenMM two = 2.0;
static const RealOpenMM half = 0.5;
RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex];
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
...@@ -99,14 +90,14 @@ void ReferenceHarmonicBondIxn::calculateBondIxn(int* atomIndices, ...@@ -99,14 +90,14 @@ void ReferenceHarmonicBondIxn::calculateBondIxn(int* atomIndices,
// deltaIdeal = r - r_0 // deltaIdeal = r - r_0
RealOpenMM deltaIdeal = deltaR[ReferenceForce::RIndex] - parameters[0]; double deltaIdeal = deltaR[ReferenceForce::RIndex] - parameters[0];
RealOpenMM deltaIdeal2 = deltaIdeal*deltaIdeal; double deltaIdeal2 = deltaIdeal*deltaIdeal;
RealOpenMM dEdR = parameters[1]*deltaIdeal; double dEdR = parameters[1]*deltaIdeal;
// chain rule // chain rule
dEdR = deltaR[ReferenceForce::RIndex] > zero ? (dEdR/deltaR[ReferenceForce::RIndex]) : zero; dEdR = deltaR[ReferenceForce::RIndex] > 0.0 ? (dEdR/deltaR[ReferenceForce::RIndex]) : 0.0;
forces[atomAIndex][0] += dEdR*deltaR[ReferenceForce::XIndex]; forces[atomAIndex][0] += dEdR*deltaR[ReferenceForce::XIndex];
forces[atomAIndex][1] += dEdR*deltaR[ReferenceForce::YIndex]; forces[atomAIndex][1] += dEdR*deltaR[ReferenceForce::YIndex];
...@@ -117,5 +108,5 @@ void ReferenceHarmonicBondIxn::calculateBondIxn(int* atomIndices, ...@@ -117,5 +108,5 @@ void ReferenceHarmonicBondIxn::calculateBondIxn(int* atomIndices,
forces[atomBIndex][2] -= dEdR*deltaR[ReferenceForce::ZIndex]; forces[atomBIndex][2] -= dEdR*deltaR[ReferenceForce::ZIndex];
if (totalEnergy != NULL) if (totalEnergy != NULL)
*totalEnergy += half*parameters[1]*deltaIdeal2; *totalEnergy += 0.5*parameters[1]*deltaIdeal2;
} }
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