Commit 2e9c418a authored by peastman's avatar peastman
Browse files

Merge branch 'master' into gayberne

parents 8f532e31 a4d327f5
...@@ -104,12 +104,15 @@ void ReferenceCalcAmoebaBondForceKernel::initialize(const System& system, const ...@@ -104,12 +104,15 @@ void ReferenceCalcAmoebaBondForceKernel::initialize(const System& system, const
} }
globalBondCubic = static_cast<RealOpenMM>(force.getAmoebaGlobalBondCubic()); globalBondCubic = static_cast<RealOpenMM>(force.getAmoebaGlobalBondCubic());
globalBondQuartic = static_cast<RealOpenMM>(force.getAmoebaGlobalBondQuartic()); globalBondQuartic = static_cast<RealOpenMM>(force.getAmoebaGlobalBondQuartic());
usePeriodic = force.usesPeriodicBoundaryConditions();
} }
double ReferenceCalcAmoebaBondForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { double ReferenceCalcAmoebaBondForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
vector<RealVec>& posData = extractPositions(context); vector<RealVec>& posData = extractPositions(context);
vector<RealVec>& forceData = extractForces(context); vector<RealVec>& forceData = extractForces(context);
AmoebaReferenceBondForce amoebaReferenceBondForce; AmoebaReferenceBondForce amoebaReferenceBondForce;
if (usePeriodic)
amoebaReferenceBondForce.setPeriodic(extractBoxVectors(context));
RealOpenMM energy = amoebaReferenceBondForce.calculateForceAndEnergy(numBonds, posData, particle1, particle2, length, kQuadratic, RealOpenMM energy = amoebaReferenceBondForce.calculateForceAndEnergy(numBonds, posData, particle1, particle2, length, kQuadratic,
globalBondCubic, globalBondQuartic, globalBondCubic, globalBondQuartic,
forceData); forceData);
...@@ -160,12 +163,15 @@ void ReferenceCalcAmoebaAngleForceKernel::initialize(const System& system, const ...@@ -160,12 +163,15 @@ void ReferenceCalcAmoebaAngleForceKernel::initialize(const System& system, const
globalAngleQuartic = static_cast<RealOpenMM>(force.getAmoebaGlobalAngleQuartic()); globalAngleQuartic = static_cast<RealOpenMM>(force.getAmoebaGlobalAngleQuartic());
globalAnglePentic = static_cast<RealOpenMM>(force.getAmoebaGlobalAnglePentic()); globalAnglePentic = static_cast<RealOpenMM>(force.getAmoebaGlobalAnglePentic());
globalAngleSextic = static_cast<RealOpenMM>(force.getAmoebaGlobalAngleSextic()); globalAngleSextic = static_cast<RealOpenMM>(force.getAmoebaGlobalAngleSextic());
usePeriodic = force.usesPeriodicBoundaryConditions();
} }
double ReferenceCalcAmoebaAngleForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { double ReferenceCalcAmoebaAngleForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
vector<RealVec>& posData = extractPositions(context); vector<RealVec>& posData = extractPositions(context);
vector<RealVec>& forceData = extractForces(context); vector<RealVec>& forceData = extractForces(context);
AmoebaReferenceAngleForce amoebaReferenceAngleForce; AmoebaReferenceAngleForce amoebaReferenceAngleForce;
if (usePeriodic)
amoebaReferenceAngleForce.setPeriodic(extractBoxVectors(context));
RealOpenMM energy = amoebaReferenceAngleForce.calculateForceAndEnergy(numAngles, RealOpenMM energy = amoebaReferenceAngleForce.calculateForceAndEnergy(numAngles,
posData, particle1, particle2, particle3, angle, kQuadratic, globalAngleCubic, globalAngleQuartic, globalAnglePentic, globalAngleSextic, forceData); posData, particle1, particle2, particle3, angle, kQuadratic, globalAngleCubic, globalAngleQuartic, globalAnglePentic, globalAngleSextic, forceData);
return static_cast<double>(energy); return static_cast<double>(energy);
...@@ -213,6 +219,7 @@ void ReferenceCalcAmoebaInPlaneAngleForceKernel::initialize(const System& system ...@@ -213,6 +219,7 @@ void ReferenceCalcAmoebaInPlaneAngleForceKernel::initialize(const System& system
globalInPlaneAngleQuartic = static_cast<RealOpenMM>(force.getAmoebaGlobalInPlaneAngleQuartic()); globalInPlaneAngleQuartic = static_cast<RealOpenMM>(force.getAmoebaGlobalInPlaneAngleQuartic());
globalInPlaneAnglePentic = static_cast<RealOpenMM>(force.getAmoebaGlobalInPlaneAnglePentic()); globalInPlaneAnglePentic = static_cast<RealOpenMM>(force.getAmoebaGlobalInPlaneAnglePentic());
globalInPlaneAngleSextic = static_cast<RealOpenMM>(force.getAmoebaGlobalInPlaneAngleSextic()); globalInPlaneAngleSextic = static_cast<RealOpenMM>(force.getAmoebaGlobalInPlaneAngleSextic());
usePeriodic = force.usesPeriodicBoundaryConditions();
} }
double ReferenceCalcAmoebaInPlaneAngleForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { double ReferenceCalcAmoebaInPlaneAngleForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
...@@ -220,6 +227,8 @@ double ReferenceCalcAmoebaInPlaneAngleForceKernel::execute(ContextImpl& context, ...@@ -220,6 +227,8 @@ double ReferenceCalcAmoebaInPlaneAngleForceKernel::execute(ContextImpl& context,
vector<RealVec>& posData = extractPositions(context); vector<RealVec>& posData = extractPositions(context);
vector<RealVec>& forceData = extractForces(context); vector<RealVec>& forceData = extractForces(context);
AmoebaReferenceInPlaneAngleForce amoebaReferenceInPlaneAngleForce; AmoebaReferenceInPlaneAngleForce amoebaReferenceInPlaneAngleForce;
if (usePeriodic)
amoebaReferenceInPlaneAngleForce.setPeriodic(extractBoxVectors(context));
RealOpenMM energy = amoebaReferenceInPlaneAngleForce.calculateForceAndEnergy(numAngles, posData, particle1, particle2, particle3, particle4, RealOpenMM energy = amoebaReferenceInPlaneAngleForce.calculateForceAndEnergy(numAngles, posData, particle1, particle2, particle3, particle4,
angle, kQuadratic, globalInPlaneAngleCubic, globalInPlaneAngleQuartic, angle, kQuadratic, globalInPlaneAngleCubic, globalInPlaneAngleQuartic,
globalInPlaneAnglePentic, globalInPlaneAngleSextic, forceData); globalInPlaneAnglePentic, globalInPlaneAngleSextic, forceData);
...@@ -266,12 +275,15 @@ void ReferenceCalcAmoebaPiTorsionForceKernel::initialize(const System& system, c ...@@ -266,12 +275,15 @@ void ReferenceCalcAmoebaPiTorsionForceKernel::initialize(const System& system, c
particle6.push_back(particle6Index); particle6.push_back(particle6Index);
kTorsion.push_back(static_cast<RealOpenMM>(kTorsionParameter)); kTorsion.push_back(static_cast<RealOpenMM>(kTorsionParameter));
} }
usePeriodic = force.usesPeriodicBoundaryConditions();
} }
double ReferenceCalcAmoebaPiTorsionForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { double ReferenceCalcAmoebaPiTorsionForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
vector<RealVec>& posData = extractPositions(context); vector<RealVec>& posData = extractPositions(context);
vector<RealVec>& forceData = extractForces(context); vector<RealVec>& forceData = extractForces(context);
AmoebaReferencePiTorsionForce amoebaReferencePiTorsionForce; AmoebaReferencePiTorsionForce amoebaReferencePiTorsionForce;
if (usePeriodic)
amoebaReferencePiTorsionForce.setPeriodic(extractBoxVectors(context));
RealOpenMM energy = amoebaReferencePiTorsionForce.calculateForceAndEnergy(numPiTorsions, posData, particle1, particle2, RealOpenMM energy = amoebaReferencePiTorsionForce.calculateForceAndEnergy(numPiTorsions, posData, particle1, particle2,
particle3, particle4, particle5, particle6, particle3, particle4, particle5, particle6,
kTorsion, forceData); kTorsion, forceData);
...@@ -318,12 +330,15 @@ void ReferenceCalcAmoebaStretchBendForceKernel::initialize(const System& system, ...@@ -318,12 +330,15 @@ void ReferenceCalcAmoebaStretchBendForceKernel::initialize(const System& system,
k1Parameters.push_back(static_cast<RealOpenMM>(k1)); k1Parameters.push_back(static_cast<RealOpenMM>(k1));
k2Parameters.push_back(static_cast<RealOpenMM>(k2)); k2Parameters.push_back(static_cast<RealOpenMM>(k2));
} }
usePeriodic = force.usesPeriodicBoundaryConditions();
} }
double ReferenceCalcAmoebaStretchBendForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { double ReferenceCalcAmoebaStretchBendForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
vector<RealVec>& posData = extractPositions(context); vector<RealVec>& posData = extractPositions(context);
vector<RealVec>& forceData = extractForces(context); vector<RealVec>& forceData = extractForces(context);
AmoebaReferenceStretchBendForce amoebaReferenceStretchBendForce; AmoebaReferenceStretchBendForce amoebaReferenceStretchBendForce;
if (usePeriodic)
amoebaReferenceStretchBendForce.setPeriodic(extractBoxVectors(context));
RealOpenMM energy = amoebaReferenceStretchBendForce.calculateForceAndEnergy(numStretchBends, posData, particle1, particle2, particle3, RealOpenMM energy = amoebaReferenceStretchBendForce.calculateForceAndEnergy(numStretchBends, posData, particle1, particle2, particle3,
lengthABParameters, lengthCBParameters, angleParameters, k1Parameters, lengthABParameters, lengthCBParameters, angleParameters, k1Parameters,
k2Parameters, forceData); k2Parameters, forceData);
...@@ -376,13 +391,15 @@ void ReferenceCalcAmoebaOutOfPlaneBendForceKernel::initialize(const System& syst ...@@ -376,13 +391,15 @@ void ReferenceCalcAmoebaOutOfPlaneBendForceKernel::initialize(const System& syst
globalOutOfPlaneBendAngleQuartic = static_cast<RealOpenMM>(force.getAmoebaGlobalOutOfPlaneBendQuartic()); globalOutOfPlaneBendAngleQuartic = static_cast<RealOpenMM>(force.getAmoebaGlobalOutOfPlaneBendQuartic());
globalOutOfPlaneBendAnglePentic = static_cast<RealOpenMM>(force.getAmoebaGlobalOutOfPlaneBendPentic()); globalOutOfPlaneBendAnglePentic = static_cast<RealOpenMM>(force.getAmoebaGlobalOutOfPlaneBendPentic());
globalOutOfPlaneBendAngleSextic = static_cast<RealOpenMM>(force.getAmoebaGlobalOutOfPlaneBendSextic()); globalOutOfPlaneBendAngleSextic = static_cast<RealOpenMM>(force.getAmoebaGlobalOutOfPlaneBendSextic());
usePeriodic = force.usesPeriodicBoundaryConditions();
} }
double ReferenceCalcAmoebaOutOfPlaneBendForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { double ReferenceCalcAmoebaOutOfPlaneBendForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
vector<RealVec>& posData = extractPositions(context); vector<RealVec>& posData = extractPositions(context);
vector<RealVec>& forceData = extractForces(context); vector<RealVec>& forceData = extractForces(context);
AmoebaReferenceOutOfPlaneBendForce amoebaReferenceOutOfPlaneBendForce; AmoebaReferenceOutOfPlaneBendForce amoebaReferenceOutOfPlaneBendForce;
if (usePeriodic)
amoebaReferenceOutOfPlaneBendForce.setPeriodic(extractBoxVectors(context));
RealOpenMM energy = amoebaReferenceOutOfPlaneBendForce.calculateForceAndEnergy(numOutOfPlaneBends, posData, RealOpenMM energy = amoebaReferenceOutOfPlaneBendForce.calculateForceAndEnergy(numOutOfPlaneBends, posData,
particle1, particle2, particle3, particle4, particle1, particle2, particle3, particle4,
kParameters, kParameters,
...@@ -434,6 +451,7 @@ void ReferenceCalcAmoebaTorsionTorsionForceKernel::initialize(const System& syst ...@@ -434,6 +451,7 @@ void ReferenceCalcAmoebaTorsionTorsionForceKernel::initialize(const System& syst
chiralCheckAtom.push_back(chiralCheckAtomIndex); chiralCheckAtom.push_back(chiralCheckAtomIndex);
gridIndices.push_back(gridIndex); gridIndices.push_back(gridIndex);
} }
usePeriodic = force.usesPeriodicBoundaryConditions();
// torsion-torsion grids // torsion-torsion grids
...@@ -478,6 +496,8 @@ double ReferenceCalcAmoebaTorsionTorsionForceKernel::execute(ContextImpl& contex ...@@ -478,6 +496,8 @@ double ReferenceCalcAmoebaTorsionTorsionForceKernel::execute(ContextImpl& contex
vector<RealVec>& posData = extractPositions(context); vector<RealVec>& posData = extractPositions(context);
vector<RealVec>& forceData = extractForces(context); vector<RealVec>& forceData = extractForces(context);
AmoebaReferenceTorsionTorsionForce amoebaReferenceTorsionTorsionForce; AmoebaReferenceTorsionTorsionForce amoebaReferenceTorsionTorsionForce;
if (usePeriodic)
amoebaReferenceTorsionTorsionForce.setPeriodic(extractBoxVectors(context));
RealOpenMM energy = amoebaReferenceTorsionTorsionForce.calculateForceAndEnergy(numTorsionTorsions, posData, RealOpenMM energy = amoebaReferenceTorsionTorsionForce.calculateForceAndEnergy(numTorsionTorsions, posData,
particle1, particle2, particle3, particle4, particle5, particle1, particle2, particle3, particle4, particle5,
chiralCheckAtom, gridIndices, torsionTorsionGrids, forceData); chiralCheckAtom, gridIndices, torsionTorsionGrids, forceData);
......
...@@ -77,6 +77,7 @@ private: ...@@ -77,6 +77,7 @@ private:
RealOpenMM globalBondCubic; RealOpenMM globalBondCubic;
RealOpenMM globalBondQuartic; RealOpenMM globalBondQuartic;
const System& system; const System& system;
bool usePeriodic;
}; };
/** /**
...@@ -121,6 +122,7 @@ private: ...@@ -121,6 +122,7 @@ private:
RealOpenMM globalAnglePentic; RealOpenMM globalAnglePentic;
RealOpenMM globalAngleSextic; RealOpenMM globalAngleSextic;
const System& system; const System& system;
bool usePeriodic;
}; };
/** /**
...@@ -166,6 +168,7 @@ private: ...@@ -166,6 +168,7 @@ private:
RealOpenMM globalInPlaneAnglePentic; RealOpenMM globalInPlaneAnglePentic;
RealOpenMM globalInPlaneAngleSextic; RealOpenMM globalInPlaneAngleSextic;
const System& system; const System& system;
bool usePeriodic;
}; };
/** /**
...@@ -208,6 +211,7 @@ private: ...@@ -208,6 +211,7 @@ private:
std::vector<int> particle6; std::vector<int> particle6;
std::vector<RealOpenMM> kTorsion; std::vector<RealOpenMM> kTorsion;
const System& system; const System& system;
bool usePeriodic;
}; };
/** /**
...@@ -251,6 +255,7 @@ private: ...@@ -251,6 +255,7 @@ private:
std::vector<RealOpenMM> k1Parameters; std::vector<RealOpenMM> k1Parameters;
std::vector<RealOpenMM> k2Parameters; std::vector<RealOpenMM> k2Parameters;
const System& system; const System& system;
bool usePeriodic;
}; };
/** /**
...@@ -295,6 +300,7 @@ private: ...@@ -295,6 +300,7 @@ private:
RealOpenMM globalOutOfPlaneBendAnglePentic; RealOpenMM globalOutOfPlaneBendAnglePentic;
RealOpenMM globalOutOfPlaneBendAngleSextic; RealOpenMM globalOutOfPlaneBendAngleSextic;
const System& system; const System& system;
bool usePeriodic;
}; };
/** /**
...@@ -334,6 +340,7 @@ private: ...@@ -334,6 +340,7 @@ private:
std::vector< std::vector< std::vector< std::vector<RealOpenMM> > > > torsionTorsionGrids; std::vector< std::vector< std::vector< std::vector<RealOpenMM> > > > torsionTorsionGrids;
const System& system; const System& system;
bool usePeriodic;
}; };
/** /**
......
/* Portions copyright (c) 2006 Stanford University and Simbios. /* Portions copyright (c) 2006-2016 Stanford University and Simbios.
* Contributors: Pande Group * Contributors: Pande Group
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -28,6 +28,13 @@ ...@@ -28,6 +28,13 @@
using std::vector; using std::vector;
using namespace OpenMM; using namespace OpenMM;
void AmoebaReferenceAngleForce::setPeriodic(OpenMM::RealVec* vectors) {
usePeriodic = true;
boxVectors[0] = vectors[0];
boxVectors[1] = vectors[1];
boxVectors[2] = vectors[2];
}
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Get dEdT and energy prefactor given cosine of angle :: the calculation for different Get dEdT and energy prefactor given cosine of angle :: the calculation for different
...@@ -132,11 +139,17 @@ RealOpenMM AmoebaReferenceAngleForce::calculateAngleIxn(const RealVec& positionA ...@@ -132,11 +139,17 @@ RealOpenMM AmoebaReferenceAngleForce::calculateAngleIxn(const RealVec& positionA
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
std::vector<RealOpenMM> deltaR[2]; std::vector<RealOpenMM> deltaR[2];
AmoebaReferenceForce::loadDeltaR(positionAtomA, positionAtomB, deltaR[0]); if (usePeriodic)
AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomA, positionAtomB, deltaR[0], boxVectors);
else
AmoebaReferenceForce::loadDeltaR(positionAtomA, positionAtomB, deltaR[0]);
RealOpenMM rAB2 = AmoebaReferenceForce::getNormSquared3(deltaR[0]); RealOpenMM rAB2 = AmoebaReferenceForce::getNormSquared3(deltaR[0]);
RealOpenMM rAB = SQRT(rAB2); RealOpenMM rAB = SQRT(rAB2);
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomB, deltaR[1]); if (usePeriodic)
AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomC, positionAtomB, deltaR[1], boxVectors);
else
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomB, deltaR[1]);
RealOpenMM rCB2 = AmoebaReferenceForce::getNormSquared3(deltaR[1]); RealOpenMM rCB2 = AmoebaReferenceForce::getNormSquared3(deltaR[1]);
RealOpenMM rCB = SQRT(rCB2); RealOpenMM rCB = SQRT(rCB2);
......
/* Portions copyright (c) 2006 Stanford University and Simbios. /* Portions copyright (c) 2006-2016 Stanford University and Simbios.
* Contributors: Pande Group * Contributors: Pande Group
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -40,7 +40,7 @@ public: ...@@ -40,7 +40,7 @@ public:
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
AmoebaReferenceAngleForce() {}; AmoebaReferenceAngleForce() : usePeriodic(false) {};
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -50,6 +50,16 @@ public: ...@@ -50,6 +50,16 @@ public:
~AmoebaReferenceAngleForce() {}; ~AmoebaReferenceAngleForce() {};
/**---------------------------------------------------------------------------------------
Set the force to use periodic boundary conditions.
@param vectors the vectors defining the periodic box
--------------------------------------------------------------------------------------- */
void setPeriodic(OpenMM::RealVec* vectors);
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate Amoeba angle ixns (force and energy) Calculate Amoeba angle ixns (force and energy)
...@@ -86,6 +96,9 @@ public: ...@@ -86,6 +96,9 @@ public:
private: private:
bool usePeriodic;
RealVec boxVectors[3];
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Get dEdT and energy prefactor given cosine of angle :: the calculation for different Get dEdT and energy prefactor given cosine of angle :: the calculation for different
......
...@@ -28,6 +28,13 @@ ...@@ -28,6 +28,13 @@
using std::vector; using std::vector;
using namespace OpenMM; using namespace OpenMM;
void AmoebaReferenceBondForce::setPeriodic(OpenMM::RealVec* vectors) {
usePeriodic = true;
boxVectors[0] = vectors[0];
boxVectors[1] = vectors[1];
boxVectors[2] = vectors[2];
}
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate Amoeba bond ixn (force and energy) Calculate Amoeba bond ixn (force and energy)
...@@ -63,7 +70,10 @@ RealOpenMM AmoebaReferenceBondForce::calculateBondIxn(const RealVec& positionAto ...@@ -63,7 +70,10 @@ RealOpenMM AmoebaReferenceBondForce::calculateBondIxn(const RealVec& positionAto
// get deltaR, R2, and R between 2 atoms // get deltaR, R2, and R between 2 atoms
std::vector<RealOpenMM> deltaR; std::vector<RealOpenMM> deltaR;
AmoebaReferenceForce::loadDeltaR(positionAtomA, positionAtomB, deltaR); if (usePeriodic)
AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomA, positionAtomB, deltaR, boxVectors);
else
AmoebaReferenceForce::loadDeltaR(positionAtomA, positionAtomB, deltaR);
RealOpenMM r = AmoebaReferenceForce::getNorm3(deltaR); RealOpenMM r = AmoebaReferenceForce::getNorm3(deltaR);
// deltaIdeal = r - r_0 // deltaIdeal = r - r_0
......
/* Portions copyright (c) 2006 Stanford University and Simbios. /* Portions copyright (c) 2006-2016 Stanford University and Simbios.
* Contributors: Pande Group * Contributors: Pande Group
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -40,7 +40,7 @@ public: ...@@ -40,7 +40,7 @@ public:
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
AmoebaReferenceBondForce() {}; AmoebaReferenceBondForce() : usePeriodic(false) {};
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -49,7 +49,16 @@ public: ...@@ -49,7 +49,16 @@ public:
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
~AmoebaReferenceBondForce() {}; ~AmoebaReferenceBondForce() {};
/**---------------------------------------------------------------------------------------
Set the force to use periodic boundary conditions.
@param vectors the vectors defining the periodic box
--------------------------------------------------------------------------------------- */
void setPeriodic(OpenMM::RealVec* vectors);
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -79,6 +88,9 @@ public: ...@@ -79,6 +88,9 @@ public:
private: private:
bool usePeriodic;
RealVec boxVectors[3];
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate Amoeba bond ixns (force and energy) Calculate Amoeba bond ixns (force and energy)
......
...@@ -39,18 +39,33 @@ using namespace OpenMM; ...@@ -39,18 +39,33 @@ using namespace OpenMM;
void AmoebaReferenceForce::loadDeltaR(const RealVec& xVector, const RealVec& yVector, void AmoebaReferenceForce::loadDeltaR(const RealVec& xVector, const RealVec& yVector,
std::vector<RealOpenMM>& deltaR) { std::vector<RealOpenMM>& deltaR) {
deltaR.resize(0);
deltaR.push_back(yVector[0] - xVector[0]);
deltaR.push_back(yVector[1] - xVector[1]);
deltaR.push_back(yVector[2] - xVector[2]);
}
/**---------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------- Load delta of two vectors, applying periodic boundary conditions
//static const std::string methodName = "AmoebaReferenceForce::loadDeltaR"; @param xVector first vector
@param yVector second vector
@param deltaR output vector: y - x
@param boxVectors periodic box vectors
// --------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------- */
void AmoebaReferenceForce::loadDeltaRPeriodic(const RealVec& xVector, const RealVec& yVector,
std::vector<RealOpenMM>& deltaR, const RealVec* boxVectors) {
RealVec diff = yVector-xVector;
diff -= boxVectors[2]*floor(diff[2]/boxVectors[2][2]+0.5);
diff -= boxVectors[1]*floor(diff[1]/boxVectors[1][1]+0.5);
diff -= boxVectors[0]*floor(diff[0]/boxVectors[0][0]+0.5);
deltaR.resize(0); deltaR.resize(0);
deltaR.push_back(yVector[0] - xVector[0]); deltaR.push_back(diff[0]);
deltaR.push_back(yVector[1] - xVector[1]); deltaR.push_back(diff[1]);
deltaR.push_back(yVector[2] - xVector[2]); deltaR.push_back(diff[2]);
} }
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -64,13 +79,6 @@ void AmoebaReferenceForce::loadDeltaR(const RealVec& xVector, const RealVec& yVe ...@@ -64,13 +79,6 @@ void AmoebaReferenceForce::loadDeltaR(const RealVec& xVector, const RealVec& yVe
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM AmoebaReferenceForce::getNormSquared3(const std::vector<RealOpenMM>& inputVector) { RealOpenMM AmoebaReferenceForce::getNormSquared3(const std::vector<RealOpenMM>& inputVector) {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "AmoebaReferenceForce::getNorm3";
// ---------------------------------------------------------------------------------------
// get 3 norm // get 3 norm
return (inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]); return (inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]);
...@@ -87,13 +95,6 @@ RealOpenMM AmoebaReferenceForce::getNormSquared3(const std::vector<RealOpenMM>& ...@@ -87,13 +95,6 @@ RealOpenMM AmoebaReferenceForce::getNormSquared3(const std::vector<RealOpenMM>&
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM AmoebaReferenceForce::getNormSquared3(const RealOpenMM* inputVector) { RealOpenMM AmoebaReferenceForce::getNormSquared3(const RealOpenMM* inputVector) {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "AmoebaReferenceForce::getNorm3";
// ---------------------------------------------------------------------------------------
// get 3 norm // get 3 norm
return (inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]); return (inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]);
...@@ -110,39 +111,18 @@ RealOpenMM AmoebaReferenceForce::getNormSquared3(const RealOpenMM* inputVector) ...@@ -110,39 +111,18 @@ RealOpenMM AmoebaReferenceForce::getNormSquared3(const RealOpenMM* inputVector)
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM AmoebaReferenceForce::getNorm3(const std::vector<RealOpenMM>& inputVector) { RealOpenMM AmoebaReferenceForce::getNorm3(const std::vector<RealOpenMM>& inputVector) {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "AmoebaReferenceForce::getNorm3";
// ---------------------------------------------------------------------------------------
// get 3 norm // get 3 norm
return SQRT(inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]); return SQRT(inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]);
} }
RealOpenMM AmoebaReferenceForce::getNorm3(const RealOpenMM* inputVector) { RealOpenMM AmoebaReferenceForce::getNorm3(const RealOpenMM* inputVector) {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "AmoebaReferenceForce::getNorm3";
// ---------------------------------------------------------------------------------------
// get 3 norm // get 3 norm
return SQRT(inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]); return SQRT(inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]);
} }
RealOpenMM AmoebaReferenceForce::normalizeVector3(RealOpenMM* inputVector) { RealOpenMM AmoebaReferenceForce::normalizeVector3(RealOpenMM* inputVector) {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "AmoebaReferenceForce::normalizeVector3";
// ---------------------------------------------------------------------------------------
RealOpenMM norm = SQRT(inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]); RealOpenMM norm = SQRT(inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]);
if (norm > 0.0) { if (norm > 0.0) {
RealOpenMM normI = 1.0/norm; RealOpenMM normI = 1.0/norm;
...@@ -166,13 +146,6 @@ RealOpenMM AmoebaReferenceForce::normalizeVector3(RealOpenMM* inputVector) { ...@@ -166,13 +146,6 @@ RealOpenMM AmoebaReferenceForce::normalizeVector3(RealOpenMM* inputVector) {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM AmoebaReferenceForce::getDotProduct3(const std::vector<RealOpenMM>& xVector, const std::vector<RealOpenMM>& yVector) { RealOpenMM AmoebaReferenceForce::getDotProduct3(const std::vector<RealOpenMM>& xVector, const std::vector<RealOpenMM>& yVector) {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "AmoebaReferenceForce::getDotProduct3";
// ---------------------------------------------------------------------------------------
// get dot product // get dot product
return xVector[0]*yVector[0] + xVector[1]*yVector[1] + xVector[2]*yVector[2]; return xVector[0]*yVector[0] + xVector[1]*yVector[1] + xVector[2]*yVector[2];
...@@ -190,26 +163,12 @@ RealOpenMM AmoebaReferenceForce::getDotProduct3(const std::vector<RealOpenMM>& x ...@@ -190,26 +163,12 @@ RealOpenMM AmoebaReferenceForce::getDotProduct3(const std::vector<RealOpenMM>& x
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM AmoebaReferenceForce::getDotProduct3(const RealOpenMM* xVector, const RealOpenMM* yVector) { RealOpenMM AmoebaReferenceForce::getDotProduct3(const RealOpenMM* xVector, const RealOpenMM* yVector) {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "AmoebaReferenceForce::getDotProduct3";
// ---------------------------------------------------------------------------------------
// get dot product // get dot product
return xVector[0]*yVector[0] + xVector[1]*yVector[1] + xVector[2]*yVector[2]; return xVector[0]*yVector[0] + xVector[1]*yVector[1] + xVector[2]*yVector[2];
} }
RealOpenMM AmoebaReferenceForce::getDotProduct3(const RealOpenMM* xVector, const OpenMM::Vec3& yVector) { RealOpenMM AmoebaReferenceForce::getDotProduct3(const RealOpenMM* xVector, const OpenMM::Vec3& yVector) {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "AmoebaReferenceForce::getDotProduct3";
// ---------------------------------------------------------------------------------------
// get dot product // get dot product
return xVector[0]*yVector[0] + xVector[1]*yVector[1] + xVector[2]*yVector[2]; return xVector[0]*yVector[0] + xVector[1]*yVector[1] + xVector[2]*yVector[2];
...@@ -228,13 +187,6 @@ RealOpenMM AmoebaReferenceForce::getDotProduct3(const RealOpenMM* xVector, const ...@@ -228,13 +187,6 @@ RealOpenMM AmoebaReferenceForce::getDotProduct3(const RealOpenMM* xVector, const
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
RealOpenMM AmoebaReferenceForce::getDotProduct3(unsigned int vectorOffset, const std::vector<RealOpenMM>& xVector, const RealOpenMM* yVector) { RealOpenMM AmoebaReferenceForce::getDotProduct3(unsigned int vectorOffset, const std::vector<RealOpenMM>& xVector, const RealOpenMM* yVector) {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "AmoebaReferenceForce::getDotProduct3";
// ---------------------------------------------------------------------------------------
// get dot product // get dot product
return xVector[vectorOffset+0]*yVector[0] + xVector[vectorOffset+1]*yVector[1] + xVector[vectorOffset+2]*yVector[2]; return xVector[vectorOffset+0]*yVector[0] + xVector[vectorOffset+1]*yVector[1] + xVector[vectorOffset+2]*yVector[2];
...@@ -253,18 +205,9 @@ RealOpenMM AmoebaReferenceForce::getDotProduct3(unsigned int vectorOffset, const ...@@ -253,18 +205,9 @@ RealOpenMM AmoebaReferenceForce::getDotProduct3(unsigned int vectorOffset, const
void AmoebaReferenceForce::getCrossProduct(const std::vector<RealOpenMM>& xVector, void AmoebaReferenceForce::getCrossProduct(const std::vector<RealOpenMM>& xVector,
const std::vector<RealOpenMM>& yVector, const std::vector<RealOpenMM>& yVector,
std::vector<RealOpenMM>& zVector) { std::vector<RealOpenMM>& zVector) {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "AmoebaReferenceForce::getCrossProduct";
// ---------------------------------------------------------------------------------------
zVector[0] = xVector[1]*yVector[2] - xVector[2]*yVector[1]; zVector[0] = xVector[1]*yVector[2] - xVector[2]*yVector[1];
zVector[1] = xVector[2]*yVector[0] - xVector[0]*yVector[2]; zVector[1] = xVector[2]*yVector[0] - xVector[0]*yVector[2];
zVector[2] = xVector[0]*yVector[1] - xVector[1]*yVector[0]; zVector[2] = xVector[0]*yVector[1] - xVector[1]*yVector[0];
return;
} }
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -280,17 +223,8 @@ void AmoebaReferenceForce::getCrossProduct(const std::vector<RealOpenMM>& xVecto ...@@ -280,17 +223,8 @@ void AmoebaReferenceForce::getCrossProduct(const std::vector<RealOpenMM>& xVecto
void AmoebaReferenceForce::getCrossProduct(const RealOpenMM* xVector, void AmoebaReferenceForce::getCrossProduct(const RealOpenMM* xVector,
const RealOpenMM* yVector, const RealOpenMM* yVector,
RealOpenMM* zVector) { RealOpenMM* zVector) {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "AmoebaReferenceForce::getCrossProduct";
// ---------------------------------------------------------------------------------------
zVector[0] = xVector[1]*yVector[2] - xVector[2]*yVector[1]; zVector[0] = xVector[1]*yVector[2] - xVector[2]*yVector[1];
zVector[1] = xVector[2]*yVector[0] - xVector[0]*yVector[2]; zVector[1] = xVector[2]*yVector[0] - xVector[0]*yVector[2];
zVector[2] = xVector[0]*yVector[1] - xVector[1]*yVector[0]; zVector[2] = xVector[0]*yVector[1] - xVector[1]*yVector[0];
return;
} }
...@@ -64,6 +64,18 @@ public: ...@@ -64,6 +64,18 @@ public:
static void loadDeltaR(const OpenMM::RealVec& xVector, const OpenMM::RealVec& yVector, static void loadDeltaR(const OpenMM::RealVec& xVector, const OpenMM::RealVec& yVector,
std::vector<RealOpenMM>& deltaR); std::vector<RealOpenMM>& deltaR);
/**---------------------------------------------------------------------------------------
Load delta of two vectors, applying periodic boundary conditions
@param xVector first vector
@param yVector second vector
@param deltaR output vector: y - x
@param boxVectors periodic box vectors
--------------------------------------------------------------------------------------- */
static void loadDeltaRPeriodic(const RealVec& xVector, const RealVec& yVector, std::vector<RealOpenMM>& deltaR, const RealVec* boxVectors);
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
......
...@@ -24,10 +24,18 @@ ...@@ -24,10 +24,18 @@
#include "AmoebaReferenceForce.h" #include "AmoebaReferenceForce.h"
#include "AmoebaReferenceInPlaneAngleForce.h" #include "AmoebaReferenceInPlaneAngleForce.h"
#include "ReferenceForce.h"
using std::vector; using std::vector;
using namespace OpenMM; using namespace OpenMM;
void AmoebaReferenceInPlaneAngleForce::setPeriodic(OpenMM::RealVec* vectors) {
usePeriodic = true;
boxVectors[0] = vectors[0];
boxVectors[1] = vectors[1];
boxVectors[2] = vectors[2];
}
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Get dEdT and energy prefactor given cosine of angle :: the calculation for different Get dEdT and energy prefactor given cosine of angle :: the calculation for different
...@@ -120,17 +128,6 @@ RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateAngleIxn(const RealVec& po ...@@ -120,17 +128,6 @@ RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateAngleIxn(const RealVec& po
RealOpenMM angleCubic, RealOpenMM angleQuartic, RealOpenMM angleCubic, RealOpenMM angleQuartic,
RealOpenMM anglePentic, RealOpenMM angleSextic, RealOpenMM anglePentic, RealOpenMM angleSextic,
RealVec* forces) const { RealVec* forces) const {
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "AmoebaReferenceInPlaneAngleForce::calculateAngleIxn";
static const RealOpenMM zero = 0.0;
static const RealOpenMM one = 1.0;
static const RealOpenMM two = 2.0;
// ---------------------------------------------------------------------------------------
// T = AD x CD // T = AD x CD
// P = B + T*delta // P = B + T*delta
// AP = A - P // AP = A - P
...@@ -139,40 +136,48 @@ RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateAngleIxn(const RealVec& po ...@@ -139,40 +136,48 @@ RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateAngleIxn(const RealVec& po
enum { AD, BD, CD, T, AP, P, CP, M, APxM, CPxM, ADxBD, BDxCD, TxCD, ADxT, dBxAD, CDxdB, LastDeltaAtomIndex }; enum { AD, BD, CD, T, AP, P, CP, M, APxM, CPxM, ADxBD, BDxCD, TxCD, ADxT, dBxAD, CDxdB, LastDeltaAtomIndex };
std::vector<RealOpenMM> deltaR[LastDeltaAtomIndex]; RealVec deltaR[LastDeltaAtomIndex];
for (int ii = 0; ii < LastDeltaAtomIndex; ii++) { if (usePeriodic) {
deltaR[ii].resize(3); deltaR[AD] = ReferenceForce::getDeltaRPeriodic(positionAtomD, positionAtomA, boxVectors);
deltaR[BD] = ReferenceForce::getDeltaRPeriodic(positionAtomD, positionAtomB, boxVectors);
deltaR[CD] = ReferenceForce::getDeltaRPeriodic(positionAtomD, positionAtomC, boxVectors);
}
else {
deltaR[AD] = ReferenceForce::getDeltaR(positionAtomD, positionAtomA);
deltaR[BD] = ReferenceForce::getDeltaR(positionAtomD, positionAtomB);
deltaR[CD] = ReferenceForce::getDeltaR(positionAtomD, positionAtomC);
} }
AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomA, deltaR[AD]);
AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomB, deltaR[BD]);
AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomC, deltaR[CD]);
AmoebaReferenceForce::getCrossProduct(deltaR[AD], deltaR[CD], deltaR[T]); deltaR[T] = deltaR[AD].cross(deltaR[CD]);
RealOpenMM rT2 = AmoebaReferenceForce::getNormSquared3(deltaR[T]); RealOpenMM rT2 = deltaR[T].dot(deltaR[T]);
RealOpenMM delta = AmoebaReferenceForce::getDotProduct3(deltaR[T], deltaR[BD])/rT2; RealOpenMM delta = deltaR[T].dot(deltaR[BD])/rT2;
delta *= -one; delta *= -1;
for (int ii = 0; ii < 3; ii++) { deltaR[P] = positionAtomB + deltaR[T]*delta;
deltaR[P][ii] = positionAtomB[ii] + deltaR[T][ii]*delta; if (usePeriodic) {
deltaR[AP][ii] = positionAtomA[ii] - deltaR[P][ii]; deltaR[AP] = ReferenceForce::getDeltaRPeriodic(deltaR[P], positionAtomA, boxVectors);
deltaR[CP][ii] = positionAtomC[ii] - deltaR[P][ii]; deltaR[CP] = ReferenceForce::getDeltaRPeriodic(deltaR[P], positionAtomC, boxVectors);
}
else {
deltaR[AP] = ReferenceForce::getDeltaR(deltaR[P], positionAtomA);
deltaR[CP] = ReferenceForce::getDeltaR(deltaR[P], positionAtomC);
} }
RealOpenMM rAp2 = AmoebaReferenceForce::getNormSquared3(deltaR[AP]); RealOpenMM rAp2 = deltaR[AP].dot(deltaR[AP]);
RealOpenMM rCp2 = AmoebaReferenceForce::getNormSquared3(deltaR[CP]); RealOpenMM rCp2 = deltaR[CP].dot(deltaR[CP]);
if (rAp2 <= zero && rCp2 <= zero) { if (rAp2 <= 0 && rCp2 <= 0) {
return zero; return 0;
} }
AmoebaReferenceForce::getCrossProduct(deltaR[CP], deltaR[AP], deltaR[M]); deltaR[M] = deltaR[CP].cross(deltaR[AP]);
RealOpenMM rm = AmoebaReferenceForce::getNorm3(deltaR[M]); RealOpenMM rm = SQRT(deltaR[M].dot(deltaR[M]));
if (rm < 1.0e-06) { if (rm < 1.0e-06) {
rm = 1.0e-06; rm = 1.0e-06;
} }
RealOpenMM dot = AmoebaReferenceForce::getDotProduct3(deltaR[AP], deltaR[CP]); RealOpenMM dot = deltaR[AP].dot(deltaR[CP]);
RealOpenMM cosine = dot/SQRT(rAp2*rCp2); RealOpenMM cosine = dot/SQRT(rAp2*rCp2);
RealOpenMM dEdR; RealOpenMM dEdR;
...@@ -182,64 +187,47 @@ RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateAngleIxn(const RealVec& po ...@@ -182,64 +187,47 @@ RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateAngleIxn(const RealVec& po
RealOpenMM termA = -dEdR/(rAp2*rm); RealOpenMM termA = -dEdR/(rAp2*rm);
RealOpenMM termC = dEdR/(rCp2*rm); RealOpenMM termC = dEdR/(rCp2*rm);
AmoebaReferenceForce::getCrossProduct(deltaR[AP], deltaR[M], deltaR[APxM]); deltaR[APxM] = deltaR[AP].cross(deltaR[M]);
AmoebaReferenceForce::getCrossProduct(deltaR[CP], deltaR[M], deltaR[CPxM]); deltaR[CPxM] = deltaR[CP].cross(deltaR[M]);
// forces will be gathered here // forces will be gathered here
enum { dA, dB, dC, dD, LastDIndex }; enum { dA, dB, dC, dD, LastDIndex };
std::vector<RealOpenMM> forceTerm[LastDIndex]; RealVec forceTerm[LastDIndex];
for (int ii = 0; ii < LastDIndex; ii++) {
forceTerm[ii].resize(3);
}
for (int ii = 0; ii < 3; ii++) { forceTerm[dA] = deltaR[APxM]*termA;
forceTerm[dA][ii] = deltaR[APxM][ii]*termA; forceTerm[dC] = deltaR[CPxM]*termC;
forceTerm[dC][ii] = deltaR[CPxM][ii]*termC; forceTerm[dB] = -(forceTerm[dA] + forceTerm[dC]);
forceTerm[dB][ii] = -one*(forceTerm[dA][ii] + forceTerm[dC][ii]);
} RealOpenMM pTrT2 = forceTerm[dB].dot(deltaR[T]);
RealOpenMM pTrT2 = AmoebaReferenceForce::getDotProduct3(forceTerm[dB], deltaR[T]);
pTrT2 /= rT2; pTrT2 /= rT2;
AmoebaReferenceForce::getCrossProduct(deltaR[CD], forceTerm[dB], deltaR[CDxdB]); deltaR[CDxdB] = deltaR[CD].cross(forceTerm[dB]);
AmoebaReferenceForce::getCrossProduct(forceTerm[dB], deltaR[AD], deltaR[dBxAD]); deltaR[dBxAD] = forceTerm[dB].cross(deltaR[AD]);
if (FABS(pTrT2) > 1.0e-08) { if (FABS(pTrT2) > 1.0e-08) {
RealOpenMM delta2 = delta*two; RealOpenMM delta2 = delta*2;
AmoebaReferenceForce::getCrossProduct(deltaR[BD], deltaR[CD], deltaR[BDxCD]); deltaR[BDxCD] = forceTerm[dB].cross(deltaR[CD]);
AmoebaReferenceForce::getCrossProduct(deltaR[T], deltaR[CD], deltaR[TxCD]); deltaR[TxCD] = forceTerm[T].cross(deltaR[CD]);
AmoebaReferenceForce::getCrossProduct(deltaR[AD], deltaR[BD], deltaR[ADxBD]); deltaR[ADxBD] = forceTerm[AD].cross(deltaR[BD]);
AmoebaReferenceForce::getCrossProduct(deltaR[AD], deltaR[T], deltaR[ADxT]); deltaR[ADxT] = forceTerm[AD].cross(deltaR[T]);
for (int ii = 0; ii < 3; ii++) { RealVec term = deltaR[BDxCD] + deltaR[TxCD]*delta2;
forceTerm[dA] += deltaR[CDxdB]*delta + term*pTrT2;
RealOpenMM term = deltaR[BDxCD][ii] + delta2*deltaR[TxCD][ii]; term = deltaR[ADxBD] + deltaR[ADxT]*delta2;
forceTerm[dA][ii] += delta*deltaR[CDxdB][ii] + term*pTrT2; forceTerm[dC] += deltaR[dBxAD]*delta + term*pTrT2;
forceTerm[dD] = -(forceTerm[dA] + forceTerm[dB] + forceTerm[dC]);
term = deltaR[ADxBD][ii] + delta2*deltaR[ADxT][ii];
forceTerm[dC][ii] += delta*deltaR[dBxAD][ii] + term*pTrT2;
forceTerm[dD][ii] = -(forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii]);
}
} else { } else {
for (int ii = 0; ii < 3; ii++) { forceTerm[dA] += deltaR[CDxdB]*delta;
forceTerm[dC] += deltaR[dBxAD]*delta;
forceTerm[dA][ii] += delta*deltaR[CDxdB][ii]; forceTerm[dD] = -(forceTerm[dA] + forceTerm[dB] + forceTerm[dC]);
forceTerm[dC][ii] += delta*deltaR[dBxAD][ii];
forceTerm[dD][ii] = -(forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii]);
}
} }
// accumulate forces // accumulate forces
for (int jj = 0; jj < 4; jj++) { for (int jj = 0; jj < 4; jj++)
forces[jj][0] = forceTerm[jj][0]; forces[jj] = forceTerm[jj];
forces[jj][1] = forceTerm[jj][1];
forces[jj][2] = forceTerm[jj][2];
}
return energy; return energy;
......
/* Portions copyright (c) 2006 Stanford University and Simbios. /* Portions copyright (c) 2006-2016 Stanford University and Simbios.
* Contributors: Pande Group * Contributors: Pande Group
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -40,7 +40,7 @@ public: ...@@ -40,7 +40,7 @@ public:
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
AmoebaReferenceInPlaneAngleForce() {}; AmoebaReferenceInPlaneAngleForce() : usePeriodic(false) {};
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -50,6 +50,16 @@ public: ...@@ -50,6 +50,16 @@ public:
~AmoebaReferenceInPlaneAngleForce() {}; ~AmoebaReferenceInPlaneAngleForce() {};
/**---------------------------------------------------------------------------------------
Set the force to use periodic boundary conditions.
@param vectors the vectors defining the periodic box
--------------------------------------------------------------------------------------- */
void setPeriodic(OpenMM::RealVec* vectors);
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate Amoeba in-plane angle ixns (force and energy) Calculate Amoeba in-plane angle ixns (force and energy)
...@@ -88,6 +98,9 @@ public: ...@@ -88,6 +98,9 @@ public:
private: private:
bool usePeriodic;
RealVec boxVectors[3];
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Get dEdT and energy prefactor given cosine of angle :: the calculation for different Get dEdT and energy prefactor given cosine of angle :: the calculation for different
......
...@@ -28,6 +28,13 @@ ...@@ -28,6 +28,13 @@
using std::vector; using std::vector;
using namespace OpenMM; using namespace OpenMM;
void AmoebaReferenceOutOfPlaneBendForce::setPeriodic(OpenMM::RealVec* vectors) {
usePeriodic = true;
boxVectors[0] = vectors[0];
boxVectors[1] = vectors[1];
boxVectors[2] = vectors[2];
}
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate Amoeba Out-Of-Plane-Bend ixn (force and energy) Calculate Amoeba Out-Of-Plane-Bend ixn (force and energy)
...@@ -78,12 +85,21 @@ RealOpenMM AmoebaReferenceOutOfPlaneBendForce::calculateOutOfPlaneBendIxn(const ...@@ -78,12 +85,21 @@ RealOpenMM AmoebaReferenceOutOfPlaneBendForce::calculateOutOfPlaneBendIxn(const
std::vector<RealOpenMM> deltaR[LastDeltaIndex]; std::vector<RealOpenMM> deltaR[LastDeltaIndex];
for (int ii = 0; ii < LastDeltaIndex; ii++) { for (int ii = 0; ii < LastDeltaIndex; ii++) {
deltaR[ii].resize(3); deltaR[ii].resize(3);
} }
AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomA, deltaR[AB]); if (usePeriodic) {
AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomC, deltaR[CB]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomB, positionAtomA, deltaR[AB], boxVectors);
AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomD, deltaR[DB]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomB, positionAtomC, deltaR[CB], boxVectors);
AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomA, deltaR[AD]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomB, positionAtomD, deltaR[DB], boxVectors);
AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomC, deltaR[CD]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomD, positionAtomA, deltaR[AD], boxVectors);
AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomD, positionAtomC, deltaR[CD], boxVectors);
}
else {
AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomA, deltaR[AB]);
AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomC, deltaR[CB]);
AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomD, deltaR[DB]);
AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomA, deltaR[AD]);
AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomC, deltaR[CD]);
}
RealOpenMM rDB2 = AmoebaReferenceForce::getNormSquared3(deltaR[DB]); RealOpenMM rDB2 = AmoebaReferenceForce::getNormSquared3(deltaR[DB]);
RealOpenMM rAD2 = AmoebaReferenceForce::getNormSquared3(deltaR[AD]); RealOpenMM rAD2 = AmoebaReferenceForce::getNormSquared3(deltaR[AD]);
......
/* Portions copyright (c) 2006 Stanford University and Simbios. /* Portions copyright (c) 2006-2016 Stanford University and Simbios.
* Contributors: Pande Group * Contributors: Pande Group
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -40,7 +40,7 @@ public: ...@@ -40,7 +40,7 @@ public:
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
AmoebaReferenceOutOfPlaneBendForce() {}; AmoebaReferenceOutOfPlaneBendForce() : usePeriodic(false) {};
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -50,6 +50,16 @@ public: ...@@ -50,6 +50,16 @@ public:
~AmoebaReferenceOutOfPlaneBendForce() {}; ~AmoebaReferenceOutOfPlaneBendForce() {};
/**---------------------------------------------------------------------------------------
Set the force to use periodic boundary conditions.
@param vectors the vectors defining the periodic box
--------------------------------------------------------------------------------------- */
void setPeriodic(OpenMM::RealVec* vectors);
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate Amoeba out-of-plane-bend angle (force and energy) Calculate Amoeba out-of-plane-bend angle (force and energy)
...@@ -86,6 +96,9 @@ public: ...@@ -86,6 +96,9 @@ public:
private: private:
bool usePeriodic;
RealVec boxVectors[3];
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate Amoeba Out-Of-Plane-Bend ixn (force and energy) Calculate Amoeba Out-Of-Plane-Bend ixn (force and energy)
......
/* Portions copyright (c) 2006-2016 Stanford University and Simbios.
/* Portions copyright (c) 2006 Stanford University and Simbios.
* Contributors: Pande Group * Contributors: Pande Group
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -29,6 +28,13 @@ ...@@ -29,6 +28,13 @@
using std::vector; using std::vector;
using namespace OpenMM; using namespace OpenMM;
void AmoebaReferencePiTorsionForce::setPeriodic(OpenMM::RealVec* vectors) {
usePeriodic = true;
boxVectors[0] = vectors[0];
boxVectors[1] = vectors[1];
boxVectors[2] = vectors[2];
}
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate Amoeba pi-torsion ixn (force and energy) Calculate Amoeba pi-torsion ixn (force and energy)
...@@ -66,11 +72,19 @@ RealOpenMM AmoebaReferencePiTorsionForce::calculatePiTorsionIxn(const RealVec& p ...@@ -66,11 +72,19 @@ RealOpenMM AmoebaReferencePiTorsionForce::calculatePiTorsionIxn(const RealVec& p
std::vector<RealOpenMM> deltaR[LastDeltaIndex]; std::vector<RealOpenMM> deltaR[LastDeltaIndex];
for (unsigned int ii = 0; ii < LastDeltaIndex; ii++) { for (unsigned int ii = 0; ii < LastDeltaIndex; ii++) {
deltaR[ii].resize(3); deltaR[ii].resize(3);
} }
AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomA, deltaR[AD]); if (usePeriodic) {
AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomB, deltaR[BD]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomD, positionAtomA, deltaR[AD], boxVectors);
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomE, deltaR[EC]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomD, positionAtomB, deltaR[BD], boxVectors);
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomF, deltaR[FC]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomC, positionAtomE, deltaR[EC], boxVectors);
AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomC, positionAtomF, deltaR[FC], boxVectors);
}
else {
AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomA, deltaR[AD]);
AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomB, deltaR[BD]);
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomE, deltaR[EC]);
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomF, deltaR[FC]);
}
enum { A, B, C, D, E, F, LastAtomIndex }; enum { A, B, C, D, E, F, LastAtomIndex };
std::vector<RealOpenMM> d[LastAtomIndex]; std::vector<RealOpenMM> d[LastAtomIndex];
......
/* Portions copyright (c) 2006 Stanford University and Simbios. /* Portions copyright (c) 2006-2016 Stanford University and Simbios.
* Contributors: Pande Group * Contributors: Pande Group
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -40,7 +40,7 @@ public: ...@@ -40,7 +40,7 @@ public:
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
AmoebaReferencePiTorsionForce() {}; AmoebaReferencePiTorsionForce() : usePeriodic(false) {};
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -50,6 +50,16 @@ public: ...@@ -50,6 +50,16 @@ public:
~AmoebaReferencePiTorsionForce() {}; ~AmoebaReferencePiTorsionForce() {};
/**---------------------------------------------------------------------------------------
Set the force to use periodic boundary conditions.
@param vectors the vectors defining the periodic box
--------------------------------------------------------------------------------------- */
void setPeriodic(OpenMM::RealVec* vectors);
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate Amoeba torsion ixns (force and energy) Calculate Amoeba torsion ixns (force and energy)
...@@ -85,6 +95,9 @@ public: ...@@ -85,6 +95,9 @@ public:
private: private:
bool usePeriodic;
RealVec boxVectors[3];
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate Amoeba pi-torsion ixn (force and energy) Calculate Amoeba pi-torsion ixn (force and energy)
......
/* Portions copyright (c) 2006 Stanford University and Simbios. /* Portions copyright (c) 2006-2016 Stanford University and Simbios.
* Contributors: Pande Group * Contributors: Pande Group
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -29,6 +29,13 @@ ...@@ -29,6 +29,13 @@
using std::vector; using std::vector;
using namespace OpenMM; using namespace OpenMM;
void AmoebaReferenceStretchBendForce::setPeriodic(OpenMM::RealVec* vectors) {
usePeriodic = true;
boxVectors[0] = vectors[0];
boxVectors[1] = vectors[1];
boxVectors[2] = vectors[2];
}
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate Amoeba stretch bend angle ixn (force and energy) Calculate Amoeba stretch bend angle ixn (force and energy)
...@@ -76,8 +83,14 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn(const RealVe ...@@ -76,8 +83,14 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn(const RealVe
for (unsigned int ii = 0; ii < LastDeltaIndex; ii++) { for (unsigned int ii = 0; ii < LastDeltaIndex; ii++) {
deltaR[ii].resize(3); deltaR[ii].resize(3);
} }
AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomA, deltaR[AB]); if (usePeriodic) {
AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomC, deltaR[CB]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomB, positionAtomA, deltaR[AB], boxVectors);
AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomB, positionAtomC, deltaR[CB], boxVectors);
}
else {
AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomA, deltaR[AB]);
AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomC, deltaR[CB]);
}
RealOpenMM rAB2 = AmoebaReferenceForce::getNormSquared3(deltaR[AB]); RealOpenMM rAB2 = AmoebaReferenceForce::getNormSquared3(deltaR[AB]);
RealOpenMM rAB = SQRT(rAB2); RealOpenMM rAB = SQRT(rAB2);
RealOpenMM rCB2 = AmoebaReferenceForce::getNormSquared3(deltaR[CB]); RealOpenMM rCB2 = AmoebaReferenceForce::getNormSquared3(deltaR[CB]);
......
/* Portions copyright (c) 2006 Stanford University and Simbios. /* Portions copyright (c) 2006-2016 Stanford University and Simbios.
* Contributors: Pande Group * Contributors: Pande Group
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -40,7 +40,7 @@ public: ...@@ -40,7 +40,7 @@ public:
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
AmoebaReferenceStretchBendForce() {}; AmoebaReferenceStretchBendForce() : usePeriodic(false) {};
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -50,6 +50,16 @@ public: ...@@ -50,6 +50,16 @@ public:
~AmoebaReferenceStretchBendForce() {}; ~AmoebaReferenceStretchBendForce() {};
/**---------------------------------------------------------------------------------------
Set the force to use periodic boundary conditions.
@param vectors the vectors defining the periodic box
--------------------------------------------------------------------------------------- */
void setPeriodic(OpenMM::RealVec* vectors);
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate Amoeba stretch bend ixns (force and energy) Calculate Amoeba stretch bend ixns (force and energy)
...@@ -84,6 +94,9 @@ public: ...@@ -84,6 +94,9 @@ public:
private: private:
bool usePeriodic;
RealVec boxVectors[3];
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate Amoeba stretch bend angle ixn (force and energy) Calculate Amoeba stretch bend angle ixn (force and energy)
......
/* Portions copyright (c) 2006-2016 Stanford University and Simbios.
/* Portions copyright (c) 2006 Stanford University and Simbios.
* Contributors: Pande Group * Contributors: Pande Group
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -28,6 +27,13 @@ ...@@ -28,6 +27,13 @@
using std::vector; using std::vector;
using namespace OpenMM; using namespace OpenMM;
void AmoebaReferenceTorsionTorsionForce::setPeriodic(OpenMM::RealVec* vectors) {
usePeriodic = true;
boxVectors[0] = vectors[0];
boxVectors[1] = vectors[1];
boxVectors[2] = vectors[2];
}
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Load grid values from rectenclosing angles Load grid values from rectenclosing angles
...@@ -294,9 +300,16 @@ int AmoebaReferenceTorsionTorsionForce::checkTorsionSign( ...@@ -294,9 +300,16 @@ int AmoebaReferenceTorsionTorsionForce::checkTorsionSign(
deltaR[ii].resize(3); deltaR[ii].resize(3);
} }
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomA, deltaR[CA]); if (usePeriodic) {
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomB, deltaR[CB]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomC, positionAtomA, deltaR[CA], boxVectors);
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomD, deltaR[CD]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomC, positionAtomB, deltaR[CB], boxVectors);
AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomC, positionAtomD, deltaR[CD], boxVectors);
}
else {
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomA, deltaR[CA]);
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomB, deltaR[CB]);
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomD, deltaR[CD]);
}
RealOpenMM volume = deltaR[CA][0]*(deltaR[CB][1]*deltaR[CD][2] - deltaR[CB][2]*deltaR[CD][1]) + RealOpenMM volume = deltaR[CA][0]*(deltaR[CB][1]*deltaR[CD][2] - deltaR[CB][2]*deltaR[CD][1]) +
deltaR[CB][0]*(deltaR[CD][1]*deltaR[CA][2] - deltaR[CD][2]*deltaR[CA][1]) + deltaR[CB][0]*(deltaR[CD][1]*deltaR[CA][2] - deltaR[CD][2]*deltaR[CA][1]) +
...@@ -351,13 +364,24 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn(const ...@@ -351,13 +364,24 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn(const
deltaR[ii].resize(3); deltaR[ii].resize(3);
} }
AmoebaReferenceForce::loadDeltaR(positionAtomA, positionAtomB, deltaR[BA]); if (usePeriodic) {
AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomC, deltaR[CB]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomA, positionAtomB, deltaR[BA], boxVectors);
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomD, deltaR[DC]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomB, positionAtomC, deltaR[CB], boxVectors);
AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomE, deltaR[ED]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomC, positionAtomD, deltaR[DC], boxVectors);
AmoebaReferenceForce::loadDeltaR(positionAtomA, positionAtomC, deltaR[CA]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomD, positionAtomE, deltaR[ED], boxVectors);
AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomD, deltaR[DB]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomA, positionAtomC, deltaR[CA], boxVectors);
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomE, deltaR[EC]); AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomB, positionAtomD, deltaR[DB], boxVectors);
AmoebaReferenceForce::loadDeltaRPeriodic(positionAtomC, positionAtomE, deltaR[EC], boxVectors);
}
else {
AmoebaReferenceForce::loadDeltaR(positionAtomA, positionAtomB, deltaR[BA]);
AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomC, deltaR[CB]);
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomD, deltaR[DC]);
AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomE, deltaR[ED]);
AmoebaReferenceForce::loadDeltaR(positionAtomA, positionAtomC, deltaR[CA]);
AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomD, deltaR[DB]);
AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomE, deltaR[EC]);
}
std::vector<RealOpenMM> d[LastAtomIndex]; std::vector<RealOpenMM> d[LastAtomIndex];
for (unsigned int ii = 0; ii < LastAtomIndex; ii++) { for (unsigned int ii = 0; ii < LastAtomIndex; ii++) {
......
/* Portions copyright (c) 2006 Stanford University and Simbios. /* Portions copyright (c) 2006-2016 Stanford University and Simbios.
* Contributors: Pande Group * Contributors: Pande Group
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -40,7 +40,7 @@ public: ...@@ -40,7 +40,7 @@ public:
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
AmoebaReferenceTorsionTorsionForce() {}; AmoebaReferenceTorsionTorsionForce() : usePeriodic(false) {};
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -50,6 +50,16 @@ public: ...@@ -50,6 +50,16 @@ public:
~AmoebaReferenceTorsionTorsionForce() {}; ~AmoebaReferenceTorsionTorsionForce() {};
/**---------------------------------------------------------------------------------------
Set the force to use periodic boundary conditions.
@param vectors the vectors defining the periodic box
--------------------------------------------------------------------------------------- */
void setPeriodic(OpenMM::RealVec* vectors);
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate Amoeba torsion-torsion ixns (force and energy) Calculate Amoeba torsion-torsion ixns (force and energy)
...@@ -84,6 +94,9 @@ public: ...@@ -84,6 +94,9 @@ public:
private: private:
bool usePeriodic;
RealVec boxVectors[3];
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Load grid values from rectangle enclosing angles Load grid values from rectangle enclosing angles
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "openmm/internal/AssertionUtilities.h" #include "openmm/internal/AssertionUtilities.h"
#include "openmm/Context.h" #include "openmm/Context.h"
#include "openmm/CustomAngleForce.h"
#include "OpenMMAmoeba.h" #include "OpenMMAmoeba.h"
#include "openmm/System.h" #include "openmm/System.h"
#include "openmm/LangevinIntegrator.h" #include "openmm/LangevinIntegrator.h"
...@@ -274,12 +275,63 @@ void testOneAngle() { ...@@ -274,12 +275,63 @@ void testOneAngle() {
compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle"); compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle");
} }
void testPeriodic() {
// Create a force that uses periodic boundary conditions, then compare to an identical custom force.
System system;
system.setDefaultPeriodicBoxVectors(Vec3(3, 0, 0), Vec3(0, 3, 0), Vec3(0, 0, 3));
int numParticles = 3;
for (int ii = 0; ii < numParticles; ii++)
system.addParticle(1.0);
LangevinIntegrator integrator(0.0, 0.1, 0.01);
AmoebaAngleForce* amoebaAngleForce = new AmoebaAngleForce();
double angle = 100.0;
double quadraticK = 1.0;
double cubicK = 1.0e-01;
double quarticK = 1.0e-02;
double penticK = 1.0e-03;
double sexticK = 1.0e-04;
amoebaAngleForce->addAngle(0, 1, 2, angle, quadraticK);
amoebaAngleForce->setAmoebaGlobalAngleCubic(cubicK);
amoebaAngleForce->setAmoebaGlobalAngleQuartic(quarticK);
amoebaAngleForce->setAmoebaGlobalAnglePentic(penticK);
amoebaAngleForce->setAmoebaGlobalAngleSextic(sexticK);
amoebaAngleForce->setUsesPeriodicBoundaryConditions(true);
system.addForce(amoebaAngleForce);
CustomAngleForce* customForce = new CustomAngleForce("k2*delta^2 + k3*delta^3 + k4*delta^4 + k5*delta^5 + k6*delta^6; delta=theta-theta0");
customForce->addGlobalParameter("theta0", angle*M_PI/180);
customForce->addGlobalParameter("k2", quadraticK*pow(180/M_PI, 2.0));
customForce->addGlobalParameter("k3", cubicK*pow(180/M_PI, 3.0));
customForce->addGlobalParameter("k4", quarticK*pow(180/M_PI, 4.0));
customForce->addGlobalParameter("k5", penticK*pow(180/M_PI, 5.0));
customForce->addGlobalParameter("k6", sexticK*pow(180/M_PI, 6.0));
customForce->addAngle(0, 1, 2);
customForce->setUsesPeriodicBoundaryConditions(true);
customForce->setForceGroup(1);
system.addForce(customForce);
Context context(system, integrator, Platform::getPlatformByName("Reference"));
std::vector<Vec3> positions(numParticles);
positions[0] = Vec3(0, 1, 0);
positions[1] = Vec3(0, 0, 0);
positions[2] = Vec3(0, 0, 2);
context.setPositions(positions);
State s1 = context.getState(State::Forces | State::Energy, true, 1);
State s2 = context.getState(State::Forces | State::Energy, true, 2);
ASSERT_EQUAL_TOL(s2.getPotentialEnergy(), s1.getPotentialEnergy(), 1e-5);
for (int i = 0; i < numParticles; i++)
ASSERT_EQUAL_VEC(s2.getForces()[i], s1.getForces()[i], 1e-5);
}
int main(int numberOfArguments, char* argv[]) { int main(int numberOfArguments, char* argv[]) {
try { try {
std::cout << "TestCudaAmoebaAngleForce running test..." << std::endl; std::cout << "TestReferenceAmoebaAngleForce running test..." << std::endl;
registerAmoebaReferenceKernelFactories(); registerAmoebaReferenceKernelFactories();
testOneAngle(); testOneAngle();
testPeriodic();
} }
catch(const std::exception& e) { catch(const std::exception& e) {
std::cout << "exception: " << e.what() << std::endl; std::cout << "exception: " << e.what() << std::endl;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "openmm/internal/AssertionUtilities.h" #include "openmm/internal/AssertionUtilities.h"
#include "openmm/Context.h" #include "openmm/Context.h"
#include "openmm/CustomBondForce.h"
#include "OpenMMAmoeba.h" #include "OpenMMAmoeba.h"
#include "openmm/System.h" #include "openmm/System.h"
#include "openmm/LangevinIntegrator.h" #include "openmm/LangevinIntegrator.h"
...@@ -201,6 +202,49 @@ void testTwoBond() { ...@@ -201,6 +202,49 @@ void testTwoBond() {
compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond"); compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond");
} }
void testPeriodic() {
// Create a force that uses periodic boundary conditions, then compare to an identical custom force.
System system;
system.setDefaultPeriodicBoxVectors(Vec3(3, 0, 0), Vec3(0, 3, 0), Vec3(0, 0, 3));
int numParticles = 2;
for (int ii = 0; ii < numParticles; ii++)
system.addParticle(1.0);
LangevinIntegrator integrator(0.0, 0.1, 0.01);
AmoebaBondForce* amoebaBondForce = new AmoebaBondForce();
double bondLength = 1.5;
double quadraticK = 1.0;
double cubicK = 2.0;
double quarticK = 3.0;
amoebaBondForce->setAmoebaGlobalBondCubic(cubicK);
amoebaBondForce->setAmoebaGlobalBondQuartic(quarticK);
amoebaBondForce->addBond(0, 1, bondLength, quadraticK);
amoebaBondForce->setUsesPeriodicBoundaryConditions(true);
system.addForce(amoebaBondForce);
CustomBondForce* customForce = new CustomBondForce("k2*delta^2 + k3*delta^3 + k4*delta^4; delta=r-r0");
customForce->addGlobalParameter("r0", bondLength);
customForce->addGlobalParameter("k2", quadraticK);
customForce->addGlobalParameter("k3", cubicK);
customForce->addGlobalParameter("k4", quarticK);
customForce->addBond(0, 1);
customForce->setUsesPeriodicBoundaryConditions(true);
customForce->setForceGroup(1);
system.addForce(customForce);
Context context(system, integrator, Platform::getPlatformByName("Reference"));
std::vector<Vec3> positions(numParticles);
positions[0] = Vec3(0, 2, 0);
positions[1] = Vec3(0, 0, 0);
context.setPositions(positions);
State s1 = context.getState(State::Forces | State::Energy, true, 1);
State s2 = context.getState(State::Forces | State::Energy, true, 2);
ASSERT_EQUAL_TOL(s2.getPotentialEnergy(), s1.getPotentialEnergy(), 1e-5);
for (int i = 0; i < numParticles; i++)
ASSERT_EQUAL_VEC(s2.getForces()[i], s1.getForces()[i], 1e-5);
}
int main(int numberOfArguments, char* argv[]) { int main(int numberOfArguments, char* argv[]) {
try { try {
...@@ -208,6 +252,7 @@ int main(int numberOfArguments, char* argv[]) { ...@@ -208,6 +252,7 @@ int main(int numberOfArguments, char* argv[]) {
registerAmoebaReferenceKernelFactories(); registerAmoebaReferenceKernelFactories();
//testOneBond(); //testOneBond();
testTwoBond(); testTwoBond();
testPeriodic();
} }
catch(const std::exception& e) { catch(const std::exception& e) {
std::cout << "exception: " << e.what() << std::endl; std::cout << "exception: " << e.what() << std::endl;
......
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