Commit 94ca75c6 authored by Jason Swails's avatar Jason Swails
Browse files

First stab at adjusting AmoebaStretchBendForce to take 2 force constants instead

of just 1.  Backwards compatibility is provided by making the 2nd force constant
default to -1, which is reinterpreted as "copy the first force constant".

Updates both the reference and CUDA kernels.
parent 3a80b0f1
...@@ -71,11 +71,12 @@ public: ...@@ -71,11 +71,12 @@ public:
* @param lengthAB the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm * @param lengthAB the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm
* @param lengthCB the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm * @param lengthCB the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm
* @param angle the equilibrium angle in radians * @param angle the equilibrium angle in radians
* @param k the force constant for the stretch-bend * @param k1 the force constant of the product of bond ab and angle a-b-c
* @param k2 the force constant of the product of bond bc and angle a-b-c (optional, default is the same as k1)
* @return the index of the stretch-bend that was added * @return the index of the stretch-bend that was added
*/ */
int addStretchBend(int particle1, int particle2, int particle3, double lengthAB, double lengthCB, double angle, int addStretchBend(int particle1, int particle2, int particle3, double lengthAB, double lengthCB, double angle,
double k ); double k1, double k2=-1.0);
/** /**
* Get the force field parameters for a stretch-bend term. * Get the force field parameters for a stretch-bend term.
...@@ -87,10 +88,11 @@ public: ...@@ -87,10 +88,11 @@ public:
* @param lengthAB the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm * @param lengthAB the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm
* @param lengthCB the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm * @param lengthCB the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm
* @param angle the equilibrium angle in radians * @param angle the equilibrium angle in radians
* @param k the force constant for the stretch-bend * @param k1 the force constant of the product of bond ab and angle a-b-c
* @param k2 the force constant of the product of bond bc and angle a-b-c
*/ */
void getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3, void getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3, double& lengthAB,
double& lengthAB, double& lengthCB, double& angle, double& k ) const; double& lengthCB, double& angle, double& k1, double& k2) const;
/** /**
* Set the force field parameters for a stretch-bend term. * Set the force field parameters for a stretch-bend term.
...@@ -102,10 +104,11 @@ public: ...@@ -102,10 +104,11 @@ public:
* @param lengthAB the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm * @param lengthAB the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm
* @param lengthCB the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm * @param lengthCB the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm
* @param angle the equilibrium angle in radians * @param angle the equilibrium angle in radians
* @param k the force constant for the stretch-bend * @param k1 the force constant of the product of bond ab and angle a-b-c
* @param k2 the force constant of the product of bond bc and angle a-b-c (optional, default is the same as k1)
*/ */
void setStretchBendParameters(int index, int particle1, int particle2, int particle3, void setStretchBendParameters(int index, int particle1, int particle2, int particle3,
double lengthAB, double lengthCB, double angle, double k ); double lengthAB, double lengthCB, double angle, double k1, double k2=-1.0 );
/** /**
* Update the per-stretch-bend term parameters in a Context to match those stored in this Force object. This method provides * Update the per-stretch-bend term parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it. * an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
...@@ -139,16 +142,15 @@ private: ...@@ -139,16 +142,15 @@ private:
class AmoebaStretchBendForce::StretchBendInfo { class AmoebaStretchBendForce::StretchBendInfo {
public: public:
int particle1, particle2, particle3; int particle1, particle2, particle3;
double lengthAB, lengthCB, angle, k; double lengthAB, lengthCB, angle, k1, k2;
StretchBendInfo() { StretchBendInfo() {
particle1 = particle2 = particle3 = -1; particle1 = particle2 = particle3 = -1;
lengthAB = lengthCB = angle = k = 0.0; lengthAB = lengthCB = angle = k1 = k2 = 0.0;
} }
StretchBendInfo(int particle1, int particle2, int particle3, StretchBendInfo(int particle1, int particle2, int particle3,
double lengthAB, double lengthCB, double angle, double k ) : double lengthAB, double lengthCB, double angle, double k1, double k2 ) :
particle1(particle1), particle2(particle2), particle3(particle3), particle1(particle1), particle2(particle2), particle3(particle3),
lengthAB(lengthAB), lengthCB(lengthCB), angle(angle), k(k) { lengthAB(lengthAB), lengthCB(lengthCB), angle(angle), k1(k1), k2(k2) {
} }
}; };
......
...@@ -40,31 +40,37 @@ AmoebaStretchBendForce::AmoebaStretchBendForce() { ...@@ -40,31 +40,37 @@ AmoebaStretchBendForce::AmoebaStretchBendForce() {
} }
int AmoebaStretchBendForce::addStretchBend(int particle1, int particle2, int particle3, int AmoebaStretchBendForce::addStretchBend(int particle1, int particle2, int particle3,
double lengthAB, double lengthCB, double angle, double k) { double lengthAB, double lengthCB, double angle, double k1, double k2) {
stretchBends.push_back(StretchBendInfo(particle1, particle2, particle3, lengthAB, lengthCB, angle, k)); if (k2 == -1.0) k2 = k1
stretchBends.push_back(StretchBendInfo(particle1, particle2, particle3, lengthAB, lengthCB, angle, k1, k2));
return stretchBends.size()-1; return stretchBends.size()-1;
} }
void AmoebaStretchBendForce::getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3, void AmoebaStretchBendForce::getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3,
double& lengthAB, double& lengthCB, double& angle, double& k ) const { double& lengthAB, double& lengthCB, double& angle, double& k1, double& k2 ) const {
particle1 = stretchBends[index].particle1; particle1 = stretchBends[index].particle1;
particle2 = stretchBends[index].particle2; particle2 = stretchBends[index].particle2;
particle3 = stretchBends[index].particle3; particle3 = stretchBends[index].particle3;
lengthAB = stretchBends[index].lengthAB; lengthAB = stretchBends[index].lengthAB;
lengthCB = stretchBends[index].lengthCB; lengthCB = stretchBends[index].lengthCB;
angle = stretchBends[index].angle; angle = stretchBends[index].angle;
k = stretchBends[index].k; k1 = stretchBends[index].k1;
k2 = stretchBends[index].k2;
} }
void AmoebaStretchBendForce::setStretchBendParameters(int index, int particle1, int particle2, int particle3, void AmoebaStretchBendForce::setStretchBendParameters(int index, int particle1, int particle2, int particle3,
double lengthAB, double lengthCB, double angle, double k) { double lengthAB, double lengthCB, double angle, double k1, double k2) {
stretchBends[index].particle1 = particle1; stretchBends[index].particle1 = particle1;
stretchBends[index].particle2 = particle2; stretchBends[index].particle2 = particle2;
stretchBends[index].particle3 = particle3; stretchBends[index].particle3 = particle3;
stretchBends[index].lengthAB = lengthAB; stretchBends[index].lengthAB = lengthAB;
stretchBends[index].lengthCB = lengthCB; stretchBends[index].lengthCB = lengthCB;
stretchBends[index].angle = angle; stretchBends[index].angle = angle;
stretchBends[index].k = k; stretchBends[index].k1 = k1;
if (k2 == -1.0)
stretchBends[index].k2 = k1;
else
stretchBends[index].k2 = k2;
} }
ForceImpl* AmoebaStretchBendForce::createImpl() const { ForceImpl* AmoebaStretchBendForce::createImpl() const {
......
...@@ -464,8 +464,8 @@ public: ...@@ -464,8 +464,8 @@ public:
} }
void getParticlesInGroup(int index, std::vector<int>& particles) { void getParticlesInGroup(int index, std::vector<int>& particles) {
int particle1, particle2, particle3; int particle1, particle2, particle3;
double lengthAB, lengthCB, angle, k; double lengthAB, lengthCB, angle, k1, k2;
force.getStretchBendParameters(index, particle1, particle2, particle3, lengthAB, lengthCB, angle, k); force.getStretchBendParameters(index, particle1, particle2, particle3, lengthAB, lengthCB, angle, k1, k2);
particles.resize(3); particles.resize(3);
particles[0] = particle1; particles[0] = particle1;
particles[1] = particle2; particles[1] = particle2;
...@@ -473,10 +473,10 @@ public: ...@@ -473,10 +473,10 @@ public:
} }
bool areGroupsIdentical(int group1, int group2) { bool areGroupsIdentical(int group1, int group2) {
int particle1, particle2, particle3; int particle1, particle2, particle3;
double lengthAB1, lengthAB2, lengthCB1, lengthCB2, angle1, angle2, k1, k2; double lengthAB1, lengthAB2, lengthCB1, lengthCB2, angle1, angle2, k11, k12, k21, k22;
force.getStretchBendParameters(group1, particle1, particle2, particle3, lengthAB1, lengthCB1, angle1, k1); force.getStretchBendParameters(group1, particle1, particle2, particle3, lengthAB1, lengthCB1, angle1, k11, k12);
force.getStretchBendParameters(group2, particle1, particle2, particle3, lengthAB2, lengthCB2, angle2, k2); force.getStretchBendParameters(group2, particle1, particle2, particle3, lengthAB2, lengthCB2, angle2, k21, k22);
return (lengthAB1 == lengthAB2 && lengthCB1 == lengthCB2 && angle1 == angle2 && k1 == k2); return (lengthAB1 == lengthAB2 && lengthCB1 == lengthCB2 && angle1 == angle2 && k11 == k21 && k12 == k22);
} }
private: private:
const AmoebaStretchBendForce& force; const AmoebaStretchBendForce& force;
...@@ -488,8 +488,10 @@ CudaCalcAmoebaStretchBendForceKernel::CudaCalcAmoebaStretchBendForceKernel(std:: ...@@ -488,8 +488,10 @@ CudaCalcAmoebaStretchBendForceKernel::CudaCalcAmoebaStretchBendForceKernel(std::
CudaCalcAmoebaStretchBendForceKernel::~CudaCalcAmoebaStretchBendForceKernel() { CudaCalcAmoebaStretchBendForceKernel::~CudaCalcAmoebaStretchBendForceKernel() {
cu.setAsCurrent(); cu.setAsCurrent();
if (params != NULL) if (params1 != NULL)
delete params; delete params1;
if (params2 != NULL)
delete params2;
} }
void CudaCalcAmoebaStretchBendForceKernel::initialize(const System& system, const AmoebaStretchBendForce& force) { void CudaCalcAmoebaStretchBendForceKernel::initialize(const System& system, const AmoebaStretchBendForce& force) {
...@@ -501,16 +503,21 @@ void CudaCalcAmoebaStretchBendForceKernel::initialize(const System& system, cons ...@@ -501,16 +503,21 @@ void CudaCalcAmoebaStretchBendForceKernel::initialize(const System& system, cons
if (numStretchBends == 0) if (numStretchBends == 0)
return; return;
vector<vector<int> > atoms(numStretchBends, vector<int>(3)); vector<vector<int> > atoms(numStretchBends, vector<int>(3));
params = CudaArray::create<float4>(cu, numStretchBends, "stretchBendParams"); params1 = CudaArray::create<float3>(cu, numStretchBends, "stretchBendParams");
vector<float4> paramVector(numStretchBends); params2 = CudaArray::create<float2>(cu, numStretchBends, "stretchBendForceConstants");
vector<float3> paramVector(numStretchBends);
vector<float2> paramVectorK(numStretchBends);
for (int i = 0; i < numStretchBends; i++) { for (int i = 0; i < numStretchBends; i++) {
double lengthAB, lengthCB, angle, k; double lengthAB, lengthCB, angle, k1, k2;
force.getStretchBendParameters(startIndex+i, atoms[i][0], atoms[i][1], atoms[i][2], lengthAB, lengthCB, angle, k); force.getStretchBendParameters(startIndex+i, atoms[i][0], atoms[i][1], atoms[i][2], lengthAB, lengthCB, angle, k1, k2);
paramVector[i] = make_float4((float) lengthAB, (float) lengthCB, (float) angle, (float) k); paramVector[i] = make_float3((float) lengthAB, (float) lengthCB, (float) angle);
paramVectorK[i] = make_float2((float) k1, (float) k2);
} }
params->upload(paramVector); params1->upload(paramVector);
params2->upload(paramVectorK);
map<string, string> replacements; map<string, string> replacements;
replacements["PARAMS"] = cu.getBondedUtilities().addArgument(params->getDevicePointer(), "float4"); replacements["PARAMS"] = cu.getBondedUtilities().addArgument(params1->getDevicePointer(), "float3");
replacements["FORCE_CONSTANTS"] = cu.getBondedUtilities().addArgument(params2->getDevicePointer(), "float2");
replacements["RAD_TO_DEG"] = cu.doubleToString(180/M_PI); replacements["RAD_TO_DEG"] = cu.doubleToString(180/M_PI);
cu.getBondedUtilities().addInteraction(atoms, cu.replaceStrings(CudaAmoebaKernelSources::amoebaStretchBendForce, replacements), force.getForceGroup()); cu.getBondedUtilities().addInteraction(atoms, cu.replaceStrings(CudaAmoebaKernelSources::amoebaStretchBendForce, replacements), force.getForceGroup());
cu.addForce(new ForceInfo(force)); cu.addForce(new ForceInfo(force));
......
...@@ -229,7 +229,8 @@ private: ...@@ -229,7 +229,8 @@ private:
int numStretchBends; int numStretchBends;
CudaContext& cu; CudaContext& cu;
const System& system; const System& system;
CudaArray* params; CudaArray* params1; // Equilibrium values
CudaArray* params2; // force constants
}; };
/** /**
......
...@@ -25,7 +25,8 @@ real angle = ACOS(cosine); ...@@ -25,7 +25,8 @@ real angle = ACOS(cosine);
// find chain rule terms for the bond angle deviation // find chain rule terms for the bond angle deviation
float4 parameters = PARAMS[index]; float3 parameters = PARAMS[index];
float2 force_constants = FORCE_CONSTANTS[index];
real dt = RAD_TO_DEG*(angle - parameters.z); real dt = RAD_TO_DEG*(angle - parameters.z);
real terma = rab*rp != 0 ? (-RAD_TO_DEG/(rab*rab*rp)) : (real) 0; real terma = rab*rp != 0 ? (-RAD_TO_DEG/(rab*rab*rp)) : (real) 0;
...@@ -41,11 +42,15 @@ real ddtdzic = termc * (xcb*yp-ycb*xp); ...@@ -41,11 +42,15 @@ real ddtdzic = termc * (xcb*yp-ycb*xp);
// find chain rule terms for the bond length deviations // find chain rule terms for the bond length deviations
real dr = (parameters.x > 0 ? (rab - parameters.x) : (real) 0); real dr1 = (parameters.x > 0 ? (rab - parameters.x) : (real) 0);
terma = (parameters.x > 0 ? RECIP(rab) : (real) 0); terma = (parameters.x > 0 ? RECIP(rab) : (real) 0);
dr += (parameters.y > 0 ? (rcb - parameters.y) : (real) 0); real dr2 = (parameters.y > 0 ? (rcb - parameters.y) : (real) 0);
termc = (parameters.y > 0 ? RECIP(rcb) : (real) 0); termc = (parameters.y > 0 ? RECIP(rcb) : (real) 0);
real frc1 = ((rp != 0) ? force_constants.x : (real) 0);
real frc2 = ((rp != 0) ? force_constants.y : (real) 0);
real drkk = dr1*frc1 + dr2*frc2;
real ddrdxia = terma * xab; real ddrdxia = terma * xab;
real ddrdyia = terma * yab; real ddrdyia = terma * yab;
...@@ -57,9 +62,8 @@ real ddrdzic = termc * zcb; ...@@ -57,9 +62,8 @@ real ddrdzic = termc * zcb;
// get the energy and master chain rule terms for derivatives // get the energy and master chain rule terms for derivatives
real term = ((rp != 0) ? parameters.w : (real) 0); energy += dt*drkk;
energy += term*dt*dr;
real3 force1 = make_real3(-term*(dt*ddrdxia+ddtdxia*dr), -term*(dt*ddrdyia+ddtdyia*dr), -term*(dt*ddrdzia+ddtdzia*dr)); real3 force1 = make_real3(-frc1*dt*ddrdxia+ddtdxia*drkk, -frc1*dt*ddrdyia+ddtdyia*drkk, -frc1*dt*ddrdzia+ddtdzia*drkk);
real3 force3 = make_real3(-term*(dt*ddrdxic+ddtdxic*dr), -term*(dt*ddrdyic+ddtdyic*dr), -term*(dt*ddrdzic+ddtdzic*dr)); real3 force3 = make_real3(-frc2*dt*ddrdxic+ddtdxic*drkk, -frc2*dt*ddrdyic+ddtdyic*drkk, -frc2*dt*ddrdzic+ddtdzic*drkk);
real3 force2 = make_real3(-force1.x-force3.x, -force1.y-force3.y, -force1.z-force3.z); real3 force2 = make_real3(-force1.x-force3.x, -force1.y-force3.y, -force1.z-force3.z);
...@@ -307,15 +307,16 @@ void ReferenceCalcAmoebaStretchBendForceKernel::initialize(const System& system, ...@@ -307,15 +307,16 @@ void ReferenceCalcAmoebaStretchBendForceKernel::initialize(const System& system,
numStretchBends = force.getNumStretchBends(); numStretchBends = force.getNumStretchBends();
for ( int ii = 0; ii < numStretchBends; ii++) { for ( int ii = 0; ii < numStretchBends; ii++) {
int particle1Index, particle2Index, particle3Index; int particle1Index, particle2Index, particle3Index;
double lengthAB, lengthCB, angle, k; double lengthAB, lengthCB, angle, k1, k2;
force.getStretchBendParameters(ii, particle1Index, particle2Index, particle3Index, lengthAB, lengthCB, angle, k); force.getStretchBendParameters(ii, particle1Index, particle2Index, particle3Index, lengthAB, lengthCB, angle, k1, k2);
particle1.push_back( particle1Index ); particle1.push_back( particle1Index );
particle2.push_back( particle2Index ); particle2.push_back( particle2Index );
particle3.push_back( particle3Index ); particle3.push_back( particle3Index );
lengthABParameters.push_back( static_cast<RealOpenMM>(lengthAB) ); lengthABParameters.push_back( static_cast<RealOpenMM>(lengthAB) );
lengthCBParameters.push_back( static_cast<RealOpenMM>(lengthCB) ); lengthCBParameters.push_back( static_cast<RealOpenMM>(lengthCB) );
angleParameters.push_back( static_cast<RealOpenMM>(angle) ); angleParameters.push_back( static_cast<RealOpenMM>(angle) );
kParameters.push_back( static_cast<RealOpenMM>(k) ); k1Parameters.push_back( static_cast<RealOpenMM>(k1) );
k2Parameters.push_back( static_cast<RealOpenMM>(k2) );
} }
} }
...@@ -324,7 +325,8 @@ double ReferenceCalcAmoebaStretchBendForceKernel::execute(ContextImpl& context, ...@@ -324,7 +325,8 @@ double ReferenceCalcAmoebaStretchBendForceKernel::execute(ContextImpl& context,
vector<RealVec>& forceData = extractForces(context); vector<RealVec>& forceData = extractForces(context);
AmoebaReferenceStretchBendForce amoebaReferenceStretchBendForce; AmoebaReferenceStretchBendForce amoebaReferenceStretchBendForce;
RealOpenMM energy = amoebaReferenceStretchBendForce.calculateForceAndEnergy( numStretchBends, posData, particle1, particle2, particle3, RealOpenMM energy = amoebaReferenceStretchBendForce.calculateForceAndEnergy( numStretchBends, posData, particle1, particle2, particle3,
lengthABParameters, lengthCBParameters, angleParameters, kParameters, forceData ); lengthABParameters, lengthCBParameters, angleParameters, k1Parameters,
k2Parameters, forceData );
return static_cast<double>(energy); return static_cast<double>(energy);
} }
...@@ -336,14 +338,15 @@ void ReferenceCalcAmoebaStretchBendForceKernel::copyParametersToContext(ContextI ...@@ -336,14 +338,15 @@ void ReferenceCalcAmoebaStretchBendForceKernel::copyParametersToContext(ContextI
for (int i = 0; i < numStretchBends; ++i) { for (int i = 0; i < numStretchBends; ++i) {
int particle1Index, particle2Index, particle3Index; int particle1Index, particle2Index, particle3Index;
double lengthAB, lengthCB, angle, k; double lengthAB, lengthCB, angle, k1, k2;
force.getStretchBendParameters(i, particle1Index, particle2Index, particle3Index, lengthAB, lengthCB, angle, k); force.getStretchBendParameters(i, particle1Index, particle2Index, particle3Index, lengthAB, lengthCB, angle, k1, k2);
if (particle1Index != particle1[i] || particle2Index != particle2[i] || particle3Index != particle3[i]) if (particle1Index != particle1[i] || particle2Index != particle2[i] || particle3Index != particle3[i])
throw OpenMMException("updateParametersInContext: The set of particles in a stretch-bend has changed"); throw OpenMMException("updateParametersInContext: The set of particles in a stretch-bend has changed");
lengthABParameters[i] = (RealOpenMM) lengthAB; lengthABParameters[i] = (RealOpenMM) lengthAB;
lengthCBParameters[i] = (RealOpenMM) lengthCB; lengthCBParameters[i] = (RealOpenMM) lengthCB;
angleParameters[i] = (RealOpenMM) angle; angleParameters[i] = (RealOpenMM) angle;
kParameters[i] = (RealOpenMM) k; k1Parameters[i] = (RealOpenMM) k1;
k1Parameters[i] = (RealOpenMM) k2;
} }
} }
......
...@@ -248,7 +248,8 @@ private: ...@@ -248,7 +248,8 @@ private:
std::vector<RealOpenMM> lengthABParameters; std::vector<RealOpenMM> lengthABParameters;
std::vector<RealOpenMM> lengthCBParameters; std::vector<RealOpenMM> lengthCBParameters;
std::vector<RealOpenMM> angleParameters; std::vector<RealOpenMM> angleParameters;
std::vector<RealOpenMM> kParameters; std::vector<RealOpenMM> k1Parameters;
std::vector<RealOpenMM> k2Parameters;
const System& system; const System& system;
}; };
......
...@@ -53,7 +53,7 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV ...@@ -53,7 +53,7 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV
const RealVec& positionAtomC, const RealVec& positionAtomC,
RealOpenMM lengthAB, RealOpenMM lengthCB, RealOpenMM lengthAB, RealOpenMM lengthCB,
RealOpenMM idealAngle, RealOpenMM kParameter, RealOpenMM idealAngle, RealOpenMM kParameter,
RealVec* forces ) const { RealOpenMM k2Parameter, RealVec* forces ) const {
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
...@@ -112,7 +112,9 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV ...@@ -112,7 +112,9 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV
deltaR[CBxP][ii] *= termC; deltaR[CBxP][ii] *= termC;
} }
RealOpenMM dr = rAB - lengthAB + rCB - lengthCB; RealOpenMM dr1 = rAB - lengthAB;
RealOpenMM dr2 = rCB - lengthCB;
RealOpenMM drkk = dr1*k1Parameter + dr2*k2Parameter;
termA = one/rAB; termA = one/rAB;
termC = one/rCB; termC = one/rCB;
...@@ -129,8 +131,8 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV ...@@ -129,8 +131,8 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV
} }
RealOpenMM dt = angle - idealAngle*RADIAN; RealOpenMM dt = angle - idealAngle*RADIAN;
for( int jj = 0; jj < 3; jj++ ){ for( int jj = 0; jj < 3; jj++ ){
subForce[A][jj] = kParameter*(dt*termA*deltaR[AB][jj] + dr*deltaR[ABxP][jj] ); subForce[A][jj] = k1Parameter*dt*termA*deltaR[AB][jj] + drkk*deltaR[ABxP][jj];
subForce[C][jj] = kParameter*(dt*termC*deltaR[CB][jj] + dr*deltaR[CBxP][jj] ); subForce[C][jj] = k2Parameter*dt*termC*deltaR[CB][jj] + drkk*deltaR[CBxP][jj];
subForce[B][jj] = -( subForce[A][jj] + subForce[C][jj] ); subForce[B][jj] = -( subForce[A][jj] + subForce[C][jj] );
} }
...@@ -144,7 +146,7 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV ...@@ -144,7 +146,7 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
return (kParameter*dt*dr); return dt*drkk;
} }
RealOpenMM AmoebaReferenceStretchBendForce::calculateForceAndEnergy( int numStretchBends, vector<RealVec>& posData, RealOpenMM AmoebaReferenceStretchBendForce::calculateForceAndEnergy( int numStretchBends, vector<RealVec>& posData,
......
...@@ -47,9 +47,9 @@ void AmoebaStretchBendForceProxy::serialize(const void* object, SerializationNod ...@@ -47,9 +47,9 @@ void AmoebaStretchBendForceProxy::serialize(const void* object, SerializationNod
SerializationNode& bonds = node.createChildNode("StretchBendAngles"); SerializationNode& bonds = node.createChildNode("StretchBendAngles");
for (unsigned int ii = 0; ii < static_cast<unsigned int>(force.getNumStretchBends()); ii++) { for (unsigned int ii = 0; ii < static_cast<unsigned int>(force.getNumStretchBends()); ii++) {
int particle1, particle2, particle3; int particle1, particle2, particle3;
double distanceAB, distanceCB, angle, k; double distanceAB, distanceCB, angle, k1, k2;
force.getStretchBendParameters(ii, particle1, particle2, particle3, distanceAB, distanceCB, angle, k); force.getStretchBendParameters(ii, particle1, particle2, particle3, distanceAB, distanceCB, angle, k1, k2);
bonds.createChildNode("StretchBendAngle").setIntProperty("p1", particle1).setIntProperty("p2", particle2).setIntProperty("p3", particle3).setDoubleProperty("dAB", distanceAB).setDoubleProperty("dCB", distanceCB).setDoubleProperty("angle", angle).setDoubleProperty("k", k); bonds.createChildNode("StretchBendAngle").setIntProperty("p1", particle1).setIntProperty("p2", particle2).setIntProperty("p3", particle3).setDoubleProperty("dAB", distanceAB).setDoubleProperty("dCB", distanceCB).setDoubleProperty("angle", angle).setDoubleProperty("k1", k1).setDoubleProperty("k2", k2);
} }
} }
...@@ -62,7 +62,7 @@ void* AmoebaStretchBendForceProxy::deserialize(const SerializationNode& node) co ...@@ -62,7 +62,7 @@ void* AmoebaStretchBendForceProxy::deserialize(const SerializationNode& node) co
const SerializationNode& bonds = node.getChildNode("StretchBendAngles"); const SerializationNode& bonds = node.getChildNode("StretchBendAngles");
for ( unsigned int ii = 0; ii < (int) bonds.getChildren().size(); ii++) { for ( unsigned int ii = 0; ii < (int) bonds.getChildren().size(); ii++) {
const SerializationNode& bond = bonds.getChildren()[ii]; const SerializationNode& bond = bonds.getChildren()[ii];
force->addStretchBend(bond.getIntProperty("p1"), bond.getIntProperty("p2"), bond.getIntProperty("p3"), bond.getDoubleProperty("dAB"), bond.getDoubleProperty("dCB"), bond.getDoubleProperty("angle"), bond.getDoubleProperty("k")); force->addStretchBend(bond.getIntProperty("p1"), bond.getIntProperty("p2"), bond.getIntProperty("p3"), bond.getDoubleProperty("dAB"), bond.getDoubleProperty("dCB"), bond.getDoubleProperty("angle"), bond.getDoubleProperty("k1"), bond.getDoubleProperty("k2"));
} }
} }
......
...@@ -64,10 +64,10 @@ void testSerialization() { ...@@ -64,10 +64,10 @@ void testSerialization() {
double dAB1, dAB2; double dAB1, dAB2;
double dCB1, dCB2; double dCB1, dCB2;
double angle1, angle2; double angle1, angle2;
double k1, k2; double k11, k12, k21, k22;
force1.getStretchBendParameters(ii, p11, p12, p13, dAB1, dCB1, angle1, k1); force1.getStretchBendParameters(ii, p11, p12, p13, dAB1, dCB1, angle1, k11, k12);
force2.getStretchBendParameters(ii, p21, p22, p23, dAB2, dCB2, angle2, k2); force2.getStretchBendParameters(ii, p21, p22, p23, dAB2, dCB2, angle2, k21, k22);
ASSERT_EQUAL(p11, p21); ASSERT_EQUAL(p11, p21);
ASSERT_EQUAL(p12, p22); ASSERT_EQUAL(p12, p22);
...@@ -75,7 +75,8 @@ void testSerialization() { ...@@ -75,7 +75,8 @@ void testSerialization() {
ASSERT_EQUAL(dAB1, dAB2); ASSERT_EQUAL(dAB1, dAB2);
ASSERT_EQUAL(dCB1, dCB2); ASSERT_EQUAL(dCB1, dCB2);
ASSERT_EQUAL(angle1, angle2); ASSERT_EQUAL(angle1, angle2);
ASSERT_EQUAL(k1, k2); ASSERT_EQUAL(k11, k21);
ASSERT_EQUAL(k12, k22);
} }
} }
......
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