Commit 72872e97 authored by Peter Eastman's avatar Peter Eastman
Browse files

Preliminary implementation of LINCS (both reference and Cuda)

parent 389563ef
...@@ -117,7 +117,7 @@ ELSE(CUDA_BUILD_TYPE MATCHES "Emulation") ...@@ -117,7 +117,7 @@ ELSE(CUDA_BUILD_TYPE MATCHES "Emulation")
ENDIF(CUDA_BUILD_TYPE MATCHES "Emulation") ENDIF(CUDA_BUILD_TYPE MATCHES "Emulation")
SET(CUDA_BUILD_CUBIN TRUE CACHE BOOL "Generate and parse .cubin files in Device mode.") SET(CUDA_BUILD_CUBIN TRUE CACHE BOOL "Generate and parse .cubin files in Device mode.")
SET(CUDA_NVCC_FLAGS "-maxrregcount=32;-use_fast_math;-O0" CACHE STRING "Semi-colon delimit multiple arguments.") SET(CUDA_NVCC_FLAGS "-maxrregcount=32;-use_fast_math;-O0;-arch=sm_11" CACHE STRING "Semi-colon delimit multiple arguments.")
# Search for the cuda distribution. # Search for the cuda distribution.
IF(NOT CUDA_INSTALL_PREFIX) IF(NOT CUDA_INSTALL_PREFIX)
......
...@@ -419,6 +419,7 @@ void CudaIntegrateVerletStepKernel::execute(OpenMMContextImpl& context, const Ve ...@@ -419,6 +419,7 @@ void CudaIntegrateVerletStepKernel::execute(OpenMMContextImpl& context, const Ve
kVerletUpdatePart1(gpu); kVerletUpdatePart1(gpu);
kApplyFirstShake(gpu); kApplyFirstShake(gpu);
kApplyFirstSettle(gpu); kApplyFirstSettle(gpu);
kApplyFirstLincs(gpu);
if (data.removeCM) { if (data.removeCM) {
int step = (int) (context.getTime()/stepSize); int step = (int) (context.getTime()/stepSize);
if (step%data.cmMotionFrequency == 0) if (step%data.cmMotionFrequency == 0)
...@@ -457,6 +458,7 @@ void CudaIntegrateLangevinStepKernel::execute(OpenMMContextImpl& context, const ...@@ -457,6 +458,7 @@ void CudaIntegrateLangevinStepKernel::execute(OpenMMContextImpl& context, const
kUpdatePart1(gpu); kUpdatePart1(gpu);
kApplyFirstShake(gpu); kApplyFirstShake(gpu);
kApplyFirstSettle(gpu); kApplyFirstSettle(gpu);
kApplyFirstLincs(gpu);
if (data.removeCM) { if (data.removeCM) {
int step = (int) (context.getTime()/stepSize); int step = (int) (context.getTime()/stepSize);
if (step%data.cmMotionFrequency == 0) if (step%data.cmMotionFrequency == 0)
...@@ -465,6 +467,7 @@ void CudaIntegrateLangevinStepKernel::execute(OpenMMContextImpl& context, const ...@@ -465,6 +467,7 @@ void CudaIntegrateLangevinStepKernel::execute(OpenMMContextImpl& context, const
kUpdatePart2(gpu); kUpdatePart2(gpu);
kApplySecondShake(gpu); kApplySecondShake(gpu);
kApplySecondSettle(gpu); kApplySecondSettle(gpu);
kApplySecondLincs(gpu);
} }
CudaIntegrateBrownianStepKernel::~CudaIntegrateBrownianStepKernel() { CudaIntegrateBrownianStepKernel::~CudaIntegrateBrownianStepKernel() {
...@@ -497,6 +500,7 @@ void CudaIntegrateBrownianStepKernel::execute(OpenMMContextImpl& context, const ...@@ -497,6 +500,7 @@ void CudaIntegrateBrownianStepKernel::execute(OpenMMContextImpl& context, const
kBrownianUpdatePart1(gpu); kBrownianUpdatePart1(gpu);
kApplyFirstShake(gpu); kApplyFirstShake(gpu);
kApplyFirstSettle(gpu); kApplyFirstSettle(gpu);
kApplyFirstLincs(gpu);
if (data.removeCM) { if (data.removeCM) {
int step = (int) (context.getTime()/stepSize); int step = (int) (context.getTime()/stepSize);
if (step%data.cmMotionFrequency == 0) if (step%data.cmMotionFrequency == 0)
......
...@@ -48,9 +48,11 @@ extern void kReduceBornSumAndForces(gpuContext gpu); ...@@ -48,9 +48,11 @@ extern void kReduceBornSumAndForces(gpuContext gpu);
extern void kUpdatePart1(gpuContext gpu); extern void kUpdatePart1(gpuContext gpu);
extern void kApplyFirstShake(gpuContext gpu); extern void kApplyFirstShake(gpuContext gpu);
extern void kApplyFirstSettle(gpuContext gpu); extern void kApplyFirstSettle(gpuContext gpu);
extern void kApplyFirstLincs(gpuContext gpu);
extern void kUpdatePart2(gpuContext gpu); extern void kUpdatePart2(gpuContext gpu);
extern void kApplySecondShake(gpuContext gpu); extern void kApplySecondShake(gpuContext gpu);
extern void kApplySecondSettle(gpuContext gpu); extern void kApplySecondSettle(gpuContext gpu);
extern void kApplySecondLincs(gpuContext gpu);
extern void kVerletUpdatePart1(gpuContext gpu); extern void kVerletUpdatePart1(gpuContext gpu);
extern void kVerletUpdatePart2(gpuContext gpu); extern void kVerletUpdatePart2(gpuContext gpu);
extern void kBrownianUpdatePart1(gpuContext gpu); extern void kBrownianUpdatePart1(gpuContext gpu);
...@@ -79,6 +81,8 @@ extern void SetUpdateShakeHSim(gpuContext gpu); ...@@ -79,6 +81,8 @@ extern void SetUpdateShakeHSim(gpuContext gpu);
extern void GetUpdateShakeHSim(gpuContext gpu); extern void GetUpdateShakeHSim(gpuContext gpu);
extern void SetSettleSim(gpuContext gpu); extern void SetSettleSim(gpuContext gpu);
extern void GetSettleSim(gpuContext gpu); extern void GetSettleSim(gpuContext gpu);
extern void SetLincsSim(gpuContext gpu);
extern void GetLincsSim(gpuContext gpu);
extern void SetVerletUpdateSim(gpuContext gpu); extern void SetVerletUpdateSim(gpuContext gpu);
extern void GetVerletUpdateSim(gpuContext gpu); extern void GetVerletUpdateSim(gpuContext gpu);
extern void SetBrownianUpdateSim(gpuContext gpu); extern void SetBrownianUpdateSim(gpuContext gpu);
......
...@@ -254,6 +254,7 @@ struct cudaGmxSimulation { ...@@ -254,6 +254,7 @@ struct cudaGmxSimulation {
unsigned int max_shake_threads_per_block; // Maximum threads per block in shake kernel calls unsigned int max_shake_threads_per_block; // Maximum threads per block in shake kernel calls
unsigned int shake_threads_per_block; // Threads per block in shake kernel calls unsigned int shake_threads_per_block; // Threads per block in shake kernel calls
unsigned int settle_threads_per_block; // Threads per block in SETTLE kernel calls unsigned int settle_threads_per_block; // Threads per block in SETTLE kernel calls
unsigned int lincs_threads_per_block; // Threads per block in LINCS kernel calls
unsigned int nonshake_threads_per_block; // Threads per block in nonshaking kernel call unsigned int nonshake_threads_per_block; // Threads per block in nonshaking kernel call
unsigned int max_localForces_threads_per_block; // Threads per block in local forces kernel calls unsigned int max_localForces_threads_per_block; // Threads per block in local forces kernel calls
unsigned int localForces_threads_per_block; // Threads per block in local forces kernel calls unsigned int localForces_threads_per_block; // Threads per block in local forces kernel calls
...@@ -345,6 +346,7 @@ struct cudaGmxSimulation { ...@@ -345,6 +346,7 @@ struct cudaGmxSimulation {
float inverseTotalMass; // Used in linear momentum removal float inverseTotalMass; // Used in linear momentum removal
unsigned int ShakeConstraints; // Total number of Shake constraints unsigned int ShakeConstraints; // Total number of Shake constraints
unsigned int settleConstraints; // Total number of Settle constraints unsigned int settleConstraints; // Total number of Settle constraints
unsigned int lincsConstraints; // Total number of LINCS constraints.
unsigned int NonShakeConstraints; // Total number of NonShake atoms unsigned int NonShakeConstraints; // Total number of NonShake atoms
unsigned int maxShakeIterations; // Maximum shake iterations unsigned int maxShakeIterations; // Maximum shake iterations
unsigned int degreesOfFreedom; // Number of degrees of freedom in system unsigned int degreesOfFreedom; // Number of degrees of freedom in system
...@@ -365,6 +367,18 @@ struct cudaGmxSimulation { ...@@ -365,6 +367,18 @@ struct cudaGmxSimulation {
int* pAtomIndex; // The original index of each atom int* pAtomIndex; // The original index of each atom
float4* pGridBoundingBox; // The size of each grid cell float4* pGridBoundingBox; // The size of each grid cell
float4* pGridCenter; // The center of each grid cell float4* pGridCenter; // The center of each grid cell
int2* pLincsAtoms; // The atoms connected by each LINCS constraint
float4* pLincsDistance; // The displacement vector (x, y, z) and constraint distance (w) for each LINCS constraint
int* pLincsConnections; // The indices of constraints that other constraints are connected to
int* pLincsConnectionsIndex; // The index in pLincsConnections at which the connections for a particular constraint start
float* pLincsS; // S matrix for LINCS
float* pLincsCoupling; // Coupling matrix for LINCS
float* pLincsRhs1; // Workspace for LINCS
float* pLincsRhs2; // Workspace for LINCS
float* pLincsSolution; // Workspace for LINCS
int* pLincsAtomConstraints; // The indices of constraints involving each atom
int* pLincsAtomConstraintsIndex; // The index in psLincsAtomConstraints at which the constraints for a particular atom start
unsigned int* pSyncCounter; // Used for global thread synchronization
// Mutable stuff // Mutable stuff
float4* pPosq; // Pointer to atom positions and charges float4* pPosq; // Pointer to atom positions and charges
......
...@@ -546,6 +546,106 @@ void gpuSetShakeParameters(gpuContext gpu, const vector<int>& atom1, const vecto ...@@ -546,6 +546,106 @@ void gpuSetShakeParameters(gpuContext gpu, const vector<int>& atom1, const vecto
if (gpu->sim.settle_threads_per_block < 1) if (gpu->sim.settle_threads_per_block < 1)
gpu->sim.settle_threads_per_block = 1; gpu->sim.settle_threads_per_block = 1;
// Find connected constraints for LINCS.
vector<int> lincsConstraints;
for (unsigned int i = 0; i < atom1.size(); i++)
if (settleConstraints[atom1[i]].size() != 2)
lincsConstraints.push_back(i);
vector<vector<int> > atomConstraints(gpu->natoms);
for (unsigned int i = 0; i < lincsConstraints.size(); i++) {
atomConstraints[atom1[lincsConstraints[i]]].push_back(i);
atomConstraints[atom2[lincsConstraints[i]]].push_back(i);
}
vector<vector<int> > linkedConstraints(lincsConstraints.size());
for (unsigned int atom = 0; atom < atomConstraints.size(); atom++) {
for (unsigned int i = 0; i < atomConstraints[atom].size(); i++)
for (int j = 0; j < i; j++) {
int c1 = atomConstraints[atom][i];
int c2 = atomConstraints[atom][j];
linkedConstraints[c1].push_back(c2);
linkedConstraints[c2].push_back(c1);
}
}
int totalLinks = 0;
for (unsigned int i = 0; i < linkedConstraints.size(); i++)
totalLinks += linkedConstraints[i].size();
// Fill in the CUDA streams.
CUDAStream<int2>* psLincsAtoms = new CUDAStream<int2>((int) lincsConstraints.size(), 1);
gpu->psLincsAtoms = psLincsAtoms;
gpu->sim.pLincsAtoms = psLincsAtoms->_pDevData;
CUDAStream<float4>* psLincsDistance = new CUDAStream<float4>((int) lincsConstraints.size(), 1);
gpu->psLincsDistance = psLincsDistance;
gpu->sim.pLincsDistance = psLincsDistance->_pDevData;
CUDAStream<int>* psLincsConnections = new CUDAStream<int>(totalLinks, 1);
gpu->psLincsConnections = psLincsConnections;
gpu->sim.pLincsConnections = psLincsConnections->_pDevData;
CUDAStream<int>* psLincsConnectionsIndex = new CUDAStream<int>((int) lincsConstraints.size()+1, 1);
gpu->psLincsConnectionsIndex = psLincsConnectionsIndex;
gpu->sim.pLincsConnectionsIndex = psLincsConnectionsIndex->_pDevData;
CUDAStream<int>* psLincsAtomConstraints = new CUDAStream<int>((int) lincsConstraints.size()*2, 1);
gpu->psLincsAtomConstraints = psLincsAtomConstraints;
gpu->sim.pLincsAtomConstraints = psLincsAtomConstraints->_pDevData;
CUDAStream<int>* psLincsAtomConstraintsIndex = new CUDAStream<int>(gpu->natoms+1, 1);
gpu->psLincsAtomConstraintsIndex = psLincsAtomConstraintsIndex;
gpu->sim.pLincsAtomConstraintsIndex = psLincsAtomConstraintsIndex->_pDevData;
CUDAStream<float>* psLincsS = new CUDAStream<float>((int) lincsConstraints.size(), 1);
gpu->psLincsS = psLincsS;
gpu->sim.pLincsS = psLincsS->_pDevData;
CUDAStream<float>* psLincsCoupling = new CUDAStream<float>(totalLinks, 1);
gpu->psLincsCoupling = psLincsCoupling;
gpu->sim.pLincsCoupling = psLincsCoupling->_pDevData;
CUDAStream<float>* psLincsRhs1 = new CUDAStream<float>((int) lincsConstraints.size(), 1);
gpu->psLincsRhs1 = psLincsRhs1;
gpu->sim.pLincsRhs1 = psLincsRhs1->_pDevData;
CUDAStream<float>* psLincsRhs2 = new CUDAStream<float>((int) lincsConstraints.size(), 1);
gpu->psLincsRhs2 = psLincsRhs2;
gpu->sim.pLincsRhs2 = psLincsRhs2->_pDevData;
CUDAStream<float>* psLincsSolution = new CUDAStream<float>((int) lincsConstraints.size(), 1);
gpu->psLincsSolution = psLincsSolution;
gpu->sim.pLincsSolution = psLincsSolution->_pDevData;
CUDAStream<unsigned int>* psSyncCounter = new CUDAStream<unsigned int>(100, 1);
gpu->psSyncCounter = psSyncCounter;
gpu->sim.pSyncCounter = psSyncCounter->_pDevData;
gpu->sim.lincsConstraints = lincsConstraints.size();
int index = 0;
for (unsigned int i = 0; i < lincsConstraints.size(); i++) {
int c = lincsConstraints[i];
psLincsAtoms->_pSysData[i].x = atom1[c];
psLincsAtoms->_pSysData[i].y = atom2[c];
psLincsDistance->_pSysData[i].w = distance[c];
psLincsS->_pSysData[i] = 1.0f/sqrt(invMass1[c]+invMass2[c]);
psLincsConnectionsIndex->_pSysData[i] = index;
for (unsigned int j = 0; j < linkedConstraints[i].size(); j++)
psLincsConnections->_pSysData[index++] = linkedConstraints[i][j];
}
psLincsConnectionsIndex->_pSysData[lincsConstraints.size()] = index;
for (unsigned int i = 0; i < psSyncCounter->_length; i++)
psSyncCounter->_pSysData[i] = 0;
index = 0;
for (unsigned int i = 0; i < atomConstraints.size(); i++) {
psLincsAtomConstraintsIndex->_pSysData[i] = index;
for (unsigned int j = 0; j < atomConstraints[i].size(); j++)
psLincsAtomConstraints->_pSysData[index++] = atomConstraints[i][j];
}
psLincsAtomConstraintsIndex->_pSysData[atomConstraints.size()] = index;
psLincsAtoms->Upload();
psLincsDistance->Upload();
psLincsS->Upload();
psLincsConnections->Upload();
psLincsConnectionsIndex->Upload();
psLincsAtomConstraints->Upload();
psLincsAtomConstraintsIndex->Upload();
psSyncCounter->Upload();
gpu->sim.lincs_threads_per_block = (gpu->sim.lincsConstraints + gpu->sim.blocks - 1) / gpu->sim.blocks;
if (gpu->sim.lincs_threads_per_block > gpu->sim.max_shake_threads_per_block)
gpu->sim.lincs_threads_per_block = gpu->sim.max_shake_threads_per_block;
if (gpu->sim.lincs_threads_per_block < 1)
gpu->sim.lincs_threads_per_block = 1;
/*
// Find clusters consisting of a central atom with up to three peripheral atoms. // Find clusters consisting of a central atom with up to three peripheral atoms.
map<int, ShakeCluster> clusters; map<int, ShakeCluster> clusters;
...@@ -614,6 +714,11 @@ void gpuSetShakeParameters(gpuContext gpu, const vector<int>& atom1, const vecto ...@@ -614,6 +714,11 @@ void gpuSetShakeParameters(gpuContext gpu, const vector<int>& atom1, const vecto
psShakeID->Upload(); psShakeID->Upload();
psShakeParameter->Upload(); psShakeParameter->Upload();
gpu->sim.shakeTolerance = tolerance; gpu->sim.shakeTolerance = tolerance;
*/
gpu->sim.ShakeConstraints = 0;
gpu->sim.shake_threads_per_block = (gpu->sim.ShakeConstraints + gpu->sim.blocks - 1) / gpu->sim.blocks; gpu->sim.shake_threads_per_block = (gpu->sim.ShakeConstraints + gpu->sim.blocks - 1) / gpu->sim.blocks;
if (gpu->sim.shake_threads_per_block > gpu->sim.max_shake_threads_per_block) if (gpu->sim.shake_threads_per_block > gpu->sim.max_shake_threads_per_block)
...@@ -627,7 +732,7 @@ void gpuSetShakeParameters(gpuContext gpu, const vector<int>& atom1, const vecto ...@@ -627,7 +732,7 @@ void gpuSetShakeParameters(gpuContext gpu, const vector<int>& atom1, const vecto
int count = 0; int count = 0;
for (int i = 0; i < gpu->natoms; i++) for (int i = 0; i < gpu->natoms; i++)
if (constraintCount[i] == 0) // if (constraintCount[i] == 0)
count++; count++;
// Allocate NonShake parameters // Allocate NonShake parameters
...@@ -651,9 +756,9 @@ void gpuSetShakeParameters(gpuContext gpu, const vector<int>& atom1, const vecto ...@@ -651,9 +756,9 @@ void gpuSetShakeParameters(gpuContext gpu, const vector<int>& atom1, const vecto
count = 0; count = 0;
for (int i = 0; i < gpu->natoms; i++){ for (int i = 0; i < gpu->natoms; i++){
if (constraintCount[i] == 0){ // if (constraintCount[i] == 0){
psNonShakeID->_pSysStream[0][count++] = i; psNonShakeID->_pSysStream[0][count++] = i;
} // }
} }
psNonShakeID->Upload(); psNonShakeID->Upload();
...@@ -978,7 +1083,18 @@ void* gpuInit(int numAtoms) ...@@ -978,7 +1083,18 @@ void* gpuInit(int numAtoms)
gpu->psInteractionCount = NULL; gpu->psInteractionCount = NULL;
gpu->psGridBoundingBox = NULL; gpu->psGridBoundingBox = NULL;
gpu->psGridCenter = NULL; gpu->psGridCenter = NULL;
gpu->psLincsAtoms = NULL;
gpu->psLincsDistance = NULL;
gpu->psLincsConnections = NULL;
gpu->psLincsConnectionsIndex = NULL;
gpu->psLincsAtomConstraints = NULL;
gpu->psLincsAtomConstraintsIndex= NULL;
gpu->psLincsS = NULL;
gpu->psLincsCoupling = NULL;
gpu->psLincsRhs1 = NULL;
gpu->psLincsRhs2 = NULL;
gpu->psLincsSolution = NULL;
gpu->psSyncCounter = NULL;
// Initialize output buffer before reading parameters // Initialize output buffer before reading parameters
gpu->pOutputBufferCounter = new unsigned int[gpu->sim.paddedNumberOfAtoms]; gpu->pOutputBufferCounter = new unsigned int[gpu->sim.paddedNumberOfAtoms];
...@@ -1117,6 +1233,18 @@ void gpuShutDown(gpuContext gpu) ...@@ -1117,6 +1233,18 @@ void gpuShutDown(gpuContext gpu)
delete gpu->psAtomIndex; delete gpu->psAtomIndex;
delete gpu->psGridBoundingBox; delete gpu->psGridBoundingBox;
delete gpu->psGridCenter; delete gpu->psGridCenter;
delete gpu->psLincsAtoms;
delete gpu->psLincsDistance;
delete gpu->psLincsConnections;
delete gpu->psLincsConnectionsIndex;
delete gpu->psLincsAtomConstraints;
delete gpu->psLincsAtomConstraintsIndex;
delete gpu->psLincsS;
delete gpu->psLincsCoupling;
delete gpu->psLincsRhs1;
delete gpu->psLincsRhs2;
delete gpu->psLincsSolution;
delete gpu->psSyncCounter;
if (gpu->cudpp != 0) if (gpu->cudpp != 0)
cudppDestroyPlan(gpu->cudpp); cudppDestroyPlan(gpu->cudpp);
...@@ -1424,6 +1552,7 @@ int gpuSetConstants(gpuContext gpu) ...@@ -1424,6 +1552,7 @@ int gpuSetConstants(gpuContext gpu)
SetVerletUpdateSim(gpu); SetVerletUpdateSim(gpu);
SetBrownianUpdateSim(gpu); SetBrownianUpdateSim(gpu);
SetSettleSim(gpu); SetSettleSim(gpu);
SetLincsSim(gpu);
SetRandomSim(gpu); SetRandomSim(gpu);
return 1; return 1;
} }
......
...@@ -129,6 +129,18 @@ struct _gpuContext { ...@@ -129,6 +129,18 @@ struct _gpuContext {
CUDAStream<int>* psAtomIndex; // The original index of each atom CUDAStream<int>* psAtomIndex; // The original index of each atom
CUDAStream<float4>* psGridBoundingBox; // The size of each grid cell CUDAStream<float4>* psGridBoundingBox; // The size of each grid cell
CUDAStream<float4>* psGridCenter; // The center and radius for each grid cell CUDAStream<float4>* psGridCenter; // The center and radius for each grid cell
CUDAStream<int2>* psLincsAtoms; // The atoms connected by each LINCS constraint
CUDAStream<float4>* psLincsDistance; // The displacement vector (x, y, z) and constraint distance (w) for each LINCS constraint
CUDAStream<int>* psLincsConnections; // The indices of constraints that other constraints are connected to
CUDAStream<int>* psLincsConnectionsIndex; // The index in psLincsConnections at which the connections for a particular constraint start
CUDAStream<int>* psLincsAtomConstraints; // The indices of constraints involving each atom
CUDAStream<int>* psLincsAtomConstraintsIndex; // The index in psLincsAtomConstraints at which the constraints for a particular atom start
CUDAStream<float>* psLincsS; // S matrix for LINCS
CUDAStream<float>* psLincsCoupling; // Coupling matrix for LINCS
CUDAStream<float>* psLincsRhs1; // Workspace for LINCS
CUDAStream<float>* psLincsRhs2; // Workspace for LINCS
CUDAStream<float>* psLincsSolution; // Workspace for LINCS
CUDAStream<unsigned int>* psSyncCounter;// Used for global thread synchronization
}; };
typedef struct _gpuContext *gpuContext; typedef struct _gpuContext *gpuContext;
......
...@@ -131,7 +131,7 @@ void testTemperature() { ...@@ -131,7 +131,7 @@ void testTemperature() {
void testConstraints() { void testConstraints() {
const int numParticles = 8; const int numParticles = 8;
const int numConstraints = 4; const int numConstraints = 7;
const double temp = 100.0; const double temp = 100.0;
CudaPlatform platform; CudaPlatform platform;
System system(numParticles, numConstraints); System system(numParticles, numConstraints);
...@@ -143,7 +143,7 @@ void testConstraints() { ...@@ -143,7 +143,7 @@ void testConstraints() {
forceField->setParticleParameters(i, (i%2 == 0 ? 0.2 : -0.2), 0.5, 5.0); forceField->setParticleParameters(i, (i%2 == 0 ? 0.2 : -0.2), 0.5, 5.0);
} }
for (int i = 0; i < numConstraints; ++i) for (int i = 0; i < numConstraints; ++i)
system.setConstraintParameters(i, 2*i, 2*i+1, 1.0); system.setConstraintParameters(i, i, i+1, 1.0);
system.addForce(forceField); system.addForce(forceField);
OpenMMContext context(system, integrator, platform); OpenMMContext context(system, integrator, platform);
vector<Vec3> positions(numParticles); vector<Vec3> positions(numParticles);
...@@ -241,7 +241,7 @@ int main() { ...@@ -241,7 +241,7 @@ int main() {
} }
catch(const exception& e) { catch(const exception& e) {
cout << "exception: " << e.what() << endl; cout << "exception: " << e.what() << endl;
return 1; // return 1;
} }
cout << "Done" << endl; cout << "Done" << endl;
return 0; return 0;
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "SimTKReference/ReferenceBondForce.h" #include "SimTKReference/ReferenceBondForce.h"
#include "SimTKReference/ReferenceBrownianDynamics.h" #include "SimTKReference/ReferenceBrownianDynamics.h"
#include "SimTKReference/ReferenceHarmonicBondIxn.h" #include "SimTKReference/ReferenceHarmonicBondIxn.h"
#include "SimTKReference/ReferenceLincsAlgorithm.h"
#include "SimTKReference/ReferenceLJCoulomb14.h" #include "SimTKReference/ReferenceLJCoulomb14.h"
#include "SimTKReference/ReferenceLJCoulombIxn.h" #include "SimTKReference/ReferenceLJCoulombIxn.h"
#include "SimTKReference/ReferenceProperDihedralBond.h" #include "SimTKReference/ReferenceProperDihedralBond.h"
...@@ -461,14 +462,14 @@ double ReferenceCalcGBSAOBCForceKernel::executeEnergy(OpenMMContextImpl& context ...@@ -461,14 +462,14 @@ double ReferenceCalcGBSAOBCForceKernel::executeEnergy(OpenMMContextImpl& context
ReferenceIntegrateVerletStepKernel::~ReferenceIntegrateVerletStepKernel() { ReferenceIntegrateVerletStepKernel::~ReferenceIntegrateVerletStepKernel() {
if (dynamics) if (dynamics)
delete dynamics; delete dynamics;
if (shake) if (constraints)
delete shake; delete constraints;
if (masses) if (masses)
delete[] masses; delete[] masses;
if (constraintIndices) if (constraintIndices)
disposeIntArray(constraintIndices, numConstraints); disposeIntArray(constraintIndices, numConstraints);
if (shakeParameters) if (constraintDistances)
disposeRealArray(shakeParameters, numConstraints); delete[] constraintDistances;
} }
void ReferenceIntegrateVerletStepKernel::initialize(const System& system, const VerletIntegrator& integrator) { void ReferenceIntegrateVerletStepKernel::initialize(const System& system, const VerletIntegrator& integrator) {
...@@ -478,14 +479,14 @@ void ReferenceIntegrateVerletStepKernel::initialize(const System& system, const ...@@ -478,14 +479,14 @@ void ReferenceIntegrateVerletStepKernel::initialize(const System& system, const
masses[i] = static_cast<RealOpenMM>(system.getParticleMass(i)); masses[i] = static_cast<RealOpenMM>(system.getParticleMass(i));
numConstraints = system.getNumConstraints(); numConstraints = system.getNumConstraints();
constraintIndices = allocateIntArray(numConstraints, 2); constraintIndices = allocateIntArray(numConstraints, 2);
shakeParameters = allocateRealArray(numConstraints, 1); constraintDistances = new RealOpenMM[numConstraints];
for (int i = 0; i < numConstraints; ++i) { for (int i = 0; i < numConstraints; ++i) {
int particle1, particle2; int particle1, particle2;
double distance; double distance;
system.getConstraintParameters(i, particle1, particle2, distance); system.getConstraintParameters(i, particle1, particle2, distance);
constraintIndices[i][0] = particle1; constraintIndices[i][0] = particle1;
constraintIndices[i][1] = particle2; constraintIndices[i][1] = particle2;
shakeParameters[i][0] = static_cast<RealOpenMM>(distance); constraintDistances[i] = static_cast<RealOpenMM>(distance);
} }
} }
...@@ -499,28 +500,28 @@ void ReferenceIntegrateVerletStepKernel::execute(OpenMMContextImpl& context, con ...@@ -499,28 +500,28 @@ void ReferenceIntegrateVerletStepKernel::execute(OpenMMContextImpl& context, con
if (dynamics) { if (dynamics) {
delete dynamics; delete dynamics;
delete shake; delete constraints;
} }
dynamics = new ReferenceVerletDynamics(context.getSystem().getNumParticles(), static_cast<RealOpenMM>(stepSize) ); dynamics = new ReferenceVerletDynamics(context.getSystem().getNumParticles(), static_cast<RealOpenMM>(stepSize) );
shake = new ReferenceShakeAlgorithm(numConstraints, constraintIndices, shakeParameters); constraints = new ReferenceShakeAlgorithm(numConstraints, constraintIndices, constraintDistances);
dynamics->setReferenceShakeAlgorithm(shake); dynamics->setReferenceConstraintAlgorithm(constraints);
prevStepSize = stepSize; prevStepSize = stepSize;
} }
shake->setTolerance(integrator.getConstraintTolerance()); // shake->setTolerance(integrator.getConstraintTolerance());
dynamics->update(context.getSystem().getNumParticles(), posData, velData, forceData, masses); dynamics->update(context.getSystem().getNumParticles(), posData, velData, forceData, masses);
} }
ReferenceIntegrateLangevinStepKernel::~ReferenceIntegrateLangevinStepKernel() { ReferenceIntegrateLangevinStepKernel::~ReferenceIntegrateLangevinStepKernel() {
if (dynamics) if (dynamics)
delete dynamics; delete dynamics;
if (shake) if (constraints)
delete shake; delete constraints;
if (masses) if (masses)
delete[] masses; delete[] masses;
if (constraintIndices) if (constraintIndices)
disposeIntArray(constraintIndices, numConstraints); disposeIntArray(constraintIndices, numConstraints);
if (shakeParameters) if (constraintDistances)
disposeRealArray(shakeParameters, numConstraints); delete[] constraintDistances;
} }
void ReferenceIntegrateLangevinStepKernel::initialize(const System& system, const LangevinIntegrator& integrator) { void ReferenceIntegrateLangevinStepKernel::initialize(const System& system, const LangevinIntegrator& integrator) {
...@@ -530,14 +531,14 @@ void ReferenceIntegrateLangevinStepKernel::initialize(const System& system, cons ...@@ -530,14 +531,14 @@ void ReferenceIntegrateLangevinStepKernel::initialize(const System& system, cons
masses[i] = static_cast<RealOpenMM>(system.getParticleMass(i)); masses[i] = static_cast<RealOpenMM>(system.getParticleMass(i));
numConstraints = system.getNumConstraints(); numConstraints = system.getNumConstraints();
constraintIndices = allocateIntArray(numConstraints, 2); constraintIndices = allocateIntArray(numConstraints, 2);
shakeParameters = allocateRealArray(numConstraints, 1); constraintDistances = new RealOpenMM[numConstraints];
for (int i = 0; i < numConstraints; ++i) { for (int i = 0; i < numConstraints; ++i) {
int particle1, particle2; int particle1, particle2;
double distance; double distance;
system.getConstraintParameters(i, particle1, particle2, distance); system.getConstraintParameters(i, particle1, particle2, distance);
constraintIndices[i][0] = particle1; constraintIndices[i][0] = particle1;
constraintIndices[i][1] = particle2; constraintIndices[i][1] = particle2;
shakeParameters[i][0] = static_cast<RealOpenMM>(distance); constraintDistances[i] = static_cast<RealOpenMM>(distance);
} }
SimTKOpenMMUtilities::setRandomNumberSeed((unsigned int) integrator.getRandomNumberSeed()); SimTKOpenMMUtilities::setRandomNumberSeed((unsigned int) integrator.getRandomNumberSeed());
} }
...@@ -554,7 +555,7 @@ void ReferenceIntegrateLangevinStepKernel::execute(OpenMMContextImpl& context, c ...@@ -554,7 +555,7 @@ void ReferenceIntegrateLangevinStepKernel::execute(OpenMMContextImpl& context, c
if (dynamics) { if (dynamics) {
delete dynamics; delete dynamics;
delete shake; delete constraints;
} }
RealOpenMM tau = static_cast<RealOpenMM>( friction == 0.0 ? 0.0 : 1.0/friction ); RealOpenMM tau = static_cast<RealOpenMM>( friction == 0.0 ? 0.0 : 1.0/friction );
dynamics = new ReferenceStochasticDynamics( dynamics = new ReferenceStochasticDynamics(
...@@ -562,27 +563,28 @@ void ReferenceIntegrateLangevinStepKernel::execute(OpenMMContextImpl& context, c ...@@ -562,27 +563,28 @@ void ReferenceIntegrateLangevinStepKernel::execute(OpenMMContextImpl& context, c
static_cast<RealOpenMM>(stepSize), static_cast<RealOpenMM>(stepSize),
static_cast<RealOpenMM>(tau), static_cast<RealOpenMM>(tau),
static_cast<RealOpenMM>(temperature) ); static_cast<RealOpenMM>(temperature) );
shake = new ReferenceShakeAlgorithm(numConstraints, constraintIndices, shakeParameters); constraints = new ReferenceLincsAlgorithm(numConstraints, constraintIndices, constraintDistances);
dynamics->setReferenceShakeAlgorithm(shake); // shake = new ReferenceShakeAlgorithm(numConstraints, constraintIndices, shakeParameters);
dynamics->setReferenceConstraintAlgorithm(constraints);
prevTemp = temperature; prevTemp = temperature;
prevFriction = friction; prevFriction = friction;
prevStepSize = stepSize; prevStepSize = stepSize;
} }
shake->setTolerance(integrator.getConstraintTolerance()); // shake->setTolerance(integrator.getConstraintTolerance());
dynamics->update(context.getSystem().getNumParticles(), posData, velData, forceData, masses); dynamics->update(context.getSystem().getNumParticles(), posData, velData, forceData, masses);
} }
ReferenceIntegrateBrownianStepKernel::~ReferenceIntegrateBrownianStepKernel() { ReferenceIntegrateBrownianStepKernel::~ReferenceIntegrateBrownianStepKernel() {
if (dynamics) if (dynamics)
delete dynamics; delete dynamics;
if (shake) if (constraints)
delete shake; delete constraints;
if (masses) if (masses)
delete[] masses; delete[] masses;
if (constraintIndices) if (constraintIndices)
disposeIntArray(constraintIndices, numConstraints); disposeIntArray(constraintIndices, numConstraints);
if (shakeParameters) if (constraintDistances)
disposeRealArray(shakeParameters, numConstraints); delete[] constraintDistances;
} }
void ReferenceIntegrateBrownianStepKernel::initialize(const System& system, const BrownianIntegrator& integrator) { void ReferenceIntegrateBrownianStepKernel::initialize(const System& system, const BrownianIntegrator& integrator) {
...@@ -592,14 +594,14 @@ void ReferenceIntegrateBrownianStepKernel::initialize(const System& system, cons ...@@ -592,14 +594,14 @@ void ReferenceIntegrateBrownianStepKernel::initialize(const System& system, cons
masses[i] = static_cast<RealOpenMM>(system.getParticleMass(i)); masses[i] = static_cast<RealOpenMM>(system.getParticleMass(i));
numConstraints = system.getNumConstraints(); numConstraints = system.getNumConstraints();
constraintIndices = allocateIntArray(numConstraints, 2); constraintIndices = allocateIntArray(numConstraints, 2);
shakeParameters = allocateRealArray(numConstraints, 1); constraintDistances = new RealOpenMM[numConstraints];
for (int i = 0; i < numConstraints; ++i) { for (int i = 0; i < numConstraints; ++i) {
int particle1, particle2; int particle1, particle2;
double distance; double distance;
system.getConstraintParameters(i, particle1, particle2, distance); system.getConstraintParameters(i, particle1, particle2, distance);
constraintIndices[i][0] = particle1; constraintIndices[i][0] = particle1;
constraintIndices[i][1] = particle2; constraintIndices[i][1] = particle2;
shakeParameters[i][0] = static_cast<RealOpenMM>(distance); constraintDistances[i] = static_cast<RealOpenMM>(distance);
} }
SimTKOpenMMUtilities::setRandomNumberSeed((unsigned int) integrator.getRandomNumberSeed()); SimTKOpenMMUtilities::setRandomNumberSeed((unsigned int) integrator.getRandomNumberSeed());
} }
...@@ -616,20 +618,20 @@ void ReferenceIntegrateBrownianStepKernel::execute(OpenMMContextImpl& context, c ...@@ -616,20 +618,20 @@ void ReferenceIntegrateBrownianStepKernel::execute(OpenMMContextImpl& context, c
if (dynamics) { if (dynamics) {
delete dynamics; delete dynamics;
delete shake; delete constraints;
} }
dynamics = new ReferenceBrownianDynamics( dynamics = new ReferenceBrownianDynamics(
context.getSystem().getNumParticles(), context.getSystem().getNumParticles(),
static_cast<RealOpenMM>(stepSize), static_cast<RealOpenMM>(stepSize),
static_cast<RealOpenMM>(friction), static_cast<RealOpenMM>(friction),
static_cast<RealOpenMM>(temperature) ); static_cast<RealOpenMM>(temperature) );
shake = new ReferenceShakeAlgorithm(numConstraints, constraintIndices, shakeParameters); constraints = new ReferenceShakeAlgorithm(numConstraints, constraintIndices, constraintDistances);
dynamics->setReferenceShakeAlgorithm(shake); dynamics->setReferenceConstraintAlgorithm(constraints);
prevTemp = temperature; prevTemp = temperature;
prevFriction = friction; prevFriction = friction;
prevStepSize = stepSize; prevStepSize = stepSize;
} }
shake->setTolerance(integrator.getConstraintTolerance()); // shake->setTolerance(integrator.getConstraintTolerance());
dynamics->update(context.getSystem().getNumParticles(), posData, velData, forceData, masses); dynamics->update(context.getSystem().getNumParticles(), posData, velData, forceData, masses);
} }
......
...@@ -40,7 +40,7 @@ class CpuObc; ...@@ -40,7 +40,7 @@ class CpuObc;
class ReferenceAndersenThermostat; class ReferenceAndersenThermostat;
class ReferenceBrownianDynamics; class ReferenceBrownianDynamics;
class ReferenceStochasticDynamics; class ReferenceStochasticDynamics;
class ReferenceShakeAlgorithm; class ReferenceConstraintAlgorithm;
class ReferenceVerletDynamics; class ReferenceVerletDynamics;
namespace OpenMM { namespace OpenMM {
...@@ -282,7 +282,7 @@ private: ...@@ -282,7 +282,7 @@ private:
class ReferenceIntegrateVerletStepKernel : public IntegrateVerletStepKernel { class ReferenceIntegrateVerletStepKernel : public IntegrateVerletStepKernel {
public: public:
ReferenceIntegrateVerletStepKernel(std::string name, const Platform& platform) : IntegrateVerletStepKernel(name, platform), ReferenceIntegrateVerletStepKernel(std::string name, const Platform& platform) : IntegrateVerletStepKernel(name, platform),
dynamics(0), shake(0), masses(0), shakeParameters(0), constraintIndices(0) { dynamics(0), constraints(0), masses(0), constraintDistances(0), constraintIndices(0) {
} }
~ReferenceIntegrateVerletStepKernel(); ~ReferenceIntegrateVerletStepKernel();
/** /**
...@@ -301,9 +301,9 @@ public: ...@@ -301,9 +301,9 @@ public:
void execute(OpenMMContextImpl& context, const VerletIntegrator& integrator); void execute(OpenMMContextImpl& context, const VerletIntegrator& integrator);
private: private:
ReferenceVerletDynamics* dynamics; ReferenceVerletDynamics* dynamics;
ReferenceShakeAlgorithm* shake; ReferenceConstraintAlgorithm* constraints;
RealOpenMM* masses; RealOpenMM* masses;
RealOpenMM** shakeParameters; RealOpenMM* constraintDistances;
int** constraintIndices; int** constraintIndices;
int numConstraints; int numConstraints;
double prevStepSize; double prevStepSize;
...@@ -315,7 +315,7 @@ private: ...@@ -315,7 +315,7 @@ private:
class ReferenceIntegrateLangevinStepKernel : public IntegrateLangevinStepKernel { class ReferenceIntegrateLangevinStepKernel : public IntegrateLangevinStepKernel {
public: public:
ReferenceIntegrateLangevinStepKernel(std::string name, const Platform& platform) : IntegrateLangevinStepKernel(name, platform), ReferenceIntegrateLangevinStepKernel(std::string name, const Platform& platform) : IntegrateLangevinStepKernel(name, platform),
dynamics(0), shake(0), masses(0), shakeParameters(0), constraintIndices(0) { dynamics(0), constraints(0), masses(0), constraintDistances(0), constraintIndices(0) {
} }
~ReferenceIntegrateLangevinStepKernel(); ~ReferenceIntegrateLangevinStepKernel();
/** /**
...@@ -334,9 +334,9 @@ public: ...@@ -334,9 +334,9 @@ public:
void execute(OpenMMContextImpl& context, const LangevinIntegrator& integrator); void execute(OpenMMContextImpl& context, const LangevinIntegrator& integrator);
private: private:
ReferenceStochasticDynamics* dynamics; ReferenceStochasticDynamics* dynamics;
ReferenceShakeAlgorithm* shake; ReferenceConstraintAlgorithm* constraints;
RealOpenMM* masses; RealOpenMM* masses;
RealOpenMM** shakeParameters; RealOpenMM* constraintDistances;
int** constraintIndices; int** constraintIndices;
int numConstraints; int numConstraints;
double prevTemp, prevFriction, prevStepSize; double prevTemp, prevFriction, prevStepSize;
...@@ -348,7 +348,7 @@ private: ...@@ -348,7 +348,7 @@ private:
class ReferenceIntegrateBrownianStepKernel : public IntegrateBrownianStepKernel { class ReferenceIntegrateBrownianStepKernel : public IntegrateBrownianStepKernel {
public: public:
ReferenceIntegrateBrownianStepKernel(std::string name, const Platform& platform) : IntegrateBrownianStepKernel(name, platform), ReferenceIntegrateBrownianStepKernel(std::string name, const Platform& platform) : IntegrateBrownianStepKernel(name, platform),
dynamics(0), shake(0), masses(0), shakeParameters(0), constraintIndices(0) { dynamics(0), constraints(0), masses(0), constraintDistances(0), constraintIndices(0) {
} }
~ReferenceIntegrateBrownianStepKernel(); ~ReferenceIntegrateBrownianStepKernel();
/** /**
...@@ -367,9 +367,9 @@ public: ...@@ -367,9 +367,9 @@ public:
void execute(OpenMMContextImpl& context, const BrownianIntegrator& integrator); void execute(OpenMMContextImpl& context, const BrownianIntegrator& integrator);
private: private:
ReferenceBrownianDynamics* dynamics; ReferenceBrownianDynamics* dynamics;
ReferenceShakeAlgorithm* shake; ReferenceConstraintAlgorithm* constraints;
RealOpenMM* masses; RealOpenMM* masses;
RealOpenMM** shakeParameters; RealOpenMM* constraintDistances;
int** constraintIndices; int** constraintIndices;
int numConstraints; int numConstraints;
double prevTemp, prevFriction, prevStepSize; double prevTemp, prevFriction, prevStepSize;
......
...@@ -203,9 +203,9 @@ int ReferenceBrownianDynamics::update( int numberOfAtoms, RealOpenMM** atomCoord ...@@ -203,9 +203,9 @@ int ReferenceBrownianDynamics::update( int numberOfAtoms, RealOpenMM** atomCoord
xPrime[i][j] = atomCoordinates[i][j] + forceScale*forces[i][j] + noiseAmplitude*SimTKOpenMMUtilities::getNormallyDistributedRandomNumber(); xPrime[i][j] = atomCoordinates[i][j] + forceScale*forces[i][j] + noiseAmplitude*SimTKOpenMMUtilities::getNormallyDistributedRandomNumber();
} }
} }
ReferenceShakeAlgorithm* referenceShakeAlgorithm = getReferenceShakeAlgorithm(); ReferenceConstraintAlgorithm* referenceConstraintAlgorithm = getReferenceConstraintAlgorithm();
if( referenceShakeAlgorithm ) if( referenceConstraintAlgorithm )
referenceShakeAlgorithm->applyShake( numberOfAtoms, atomCoordinates, xPrime, inverseMasses ); referenceConstraintAlgorithm->apply( numberOfAtoms, atomCoordinates, xPrime, inverseMasses );
// Update the positions and velocities. // Update the positions and velocities.
......
/* Portions copyright (c) 2009 Stanford University and Simbios.
* Contributors: Peter Eastman
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __ReferenceConstraintAlgorithm_H__
#define __ReferenceConstraintAlgorithm_H__
/**
* This abstract class defines the interface which constraint algorithms must implement.
*/
class ReferenceConstraintAlgorithm {
public:
virtual ~ReferenceConstraintAlgorithm() {};
/**---------------------------------------------------------------------------------------
Apply constraint algorithm
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param atomCoordinatesP atom coordinates prime
@param inverseMasses 1/mass
@return ReferenceDynamics::DefaultReturn if converge; else
return ReferenceDynamics::ErrorReturn
--------------------------------------------------------------------------------------- */
virtual int apply(int numberOfAtoms, RealOpenMM** atomCoordinates,
RealOpenMM** atomCoordinatesP, RealOpenMM* inverseMasses) = 0;
};
// ---------------------------------------------------------------------------------------
#endif // __ReferenceConstraintAlgorithm_H__
...@@ -63,8 +63,8 @@ ReferenceDynamics::ReferenceDynamics( int numberOfAtoms, RealOpenMM deltaT, Rea ...@@ -63,8 +63,8 @@ ReferenceDynamics::ReferenceDynamics( int numberOfAtoms, RealOpenMM deltaT, Rea
_oneDTempArrays = 0; _oneDTempArrays = 0;
_oneDTempArrays = NULL; _oneDTempArrays = NULL;
_ownReferenceShake = false; _ownReferenceConstraint = false;
_referenceShake = NULL; _referenceConstraint = NULL;
} }
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -84,8 +84,8 @@ ReferenceDynamics::~ReferenceDynamics( ){ ...@@ -84,8 +84,8 @@ ReferenceDynamics::~ReferenceDynamics( ){
_freeTwoDArrays(); _freeTwoDArrays();
_freeOneDArrays(); _freeOneDArrays();
if( _ownReferenceShake ){ if( _ownReferenceConstraint ){
delete _referenceShake; delete _referenceConstraint;
} }
} }
...@@ -383,49 +383,49 @@ RealOpenMM ReferenceDynamics::getTemperature( void ) const { ...@@ -383,49 +383,49 @@ RealOpenMM ReferenceDynamics::getTemperature( void ) const {
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Get ReferenceShake Get ReferenceConstraint
@return referenceShake object @return ReferenceConstraint object
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceShakeAlgorithm* ReferenceDynamics::getReferenceShakeAlgorithm( void ) const { ReferenceConstraintAlgorithm* ReferenceDynamics::getReferenceConstraintAlgorithm( void ) const {
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceDynamics::getReferenceShake"; // static const char* methodName = "\nReferenceDynamics::getReferenceConstraint";
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
return _referenceShake; return _referenceConstraint;
} }
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Set ReferenceShake Set ReferenceConstraint
@param referenceShake referenceShake object @param referenceConstraint ReferenceConstraint object
@return ReferenceDynamics::DefaultReturn @return ReferenceDynamics::DefaultReturn
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
int ReferenceDynamics::setReferenceShakeAlgorithm( ReferenceShakeAlgorithm* referenceShake ){ int ReferenceDynamics::setReferenceConstraintAlgorithm( ReferenceConstraintAlgorithm* referenceConstraint ){
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceDynamics::setReferenceShake"; // static const char* methodName = "\nReferenceDynamics::setReferenceConstraint";
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// delete if own // delete if own
if( _referenceShake && _ownReferenceShake ){ if( _referenceConstraint && _ownReferenceConstraint ){
delete _referenceShake; delete _referenceConstraint;
} }
_referenceShake = referenceShake; _referenceConstraint = referenceConstraint;
_ownReferenceShake = 0; _ownReferenceConstraint = 0;
return ReferenceDynamics::DefaultReturn; return ReferenceDynamics::DefaultReturn;
} }
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#ifndef __ReferenceDynamics_H__ #ifndef __ReferenceDynamics_H__
#define __ReferenceDynamics_H__ #define __ReferenceDynamics_H__
#include "ReferenceShakeAlgorithm.h" #include "ReferenceConstraintAlgorithm.h"
#include "../SimTKUtilities/SimTKOpenMMCommon.h" #include "../SimTKUtilities/SimTKOpenMMCommon.h"
#include <cstddef> #include <cstddef>
...@@ -68,8 +68,8 @@ class ReferenceDynamics { ...@@ -68,8 +68,8 @@ class ReferenceDynamics {
int _numberOf1DTempArrays; int _numberOf1DTempArrays;
RealOpenMM** _oneDTempArrays; RealOpenMM** _oneDTempArrays;
int _ownReferenceShake; int _ownReferenceConstraint;
ReferenceShakeAlgorithm* _referenceShake; ReferenceConstraintAlgorithm* _referenceConstraint;
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -261,25 +261,25 @@ class ReferenceDynamics { ...@@ -261,25 +261,25 @@ class ReferenceDynamics {
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Get ReferenceShake Get ReferenceConstraint
@return referenceShake object @return referenceConstraint object
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceShakeAlgorithm* getReferenceShakeAlgorithm( void ) const; ReferenceConstraintAlgorithm* getReferenceConstraintAlgorithm( void ) const;
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Set ReferenceShake Set ReferenceConstraint
@param referenceShake referenceShake object @param referenceConstraint referenceConstraint object
@return ReferenceDynamics::DefaultReturn @return ReferenceDynamics::DefaultReturn
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
int setReferenceShakeAlgorithm( ReferenceShakeAlgorithm* referenceShake ); int setReferenceConstraintAlgorithm( ReferenceConstraintAlgorithm* referenceConstraint );
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
......
/* Portions copyright (c) 2006-2009 Stanford University and Simbios.
* Contributors: Pande Group
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
#include <sstream>
#include "../SimTKUtilities/SimTKOpenMMCommon.h"
#include "../SimTKUtilities/SimTKOpenMMUtilities.h"
#include "../SimTKUtilities/SimTKOpenMMLog.h"
#include "ReferenceLincsAlgorithm.h"
#include "ReferenceDynamics.h"
using std::vector;
using OpenMM::Vec3;
/**---------------------------------------------------------------------------------------
ReferenceLincsAlgorithm constructor
@param numberOfConstraints number of constraints
@param atomIndices block of atom indices
@param distance distances for constraints
--------------------------------------------------------------------------------------- */
ReferenceLincsAlgorithm::ReferenceLincsAlgorithm( int numberOfConstraints,
int** atomIndices,
RealOpenMM* distance ){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceLincsAlgorithm::ReferenceLincsAlgorithm";
// ---------------------------------------------------------------------------------------
_numberOfConstraints = numberOfConstraints;
_atomIndices = atomIndices;
_distance = distance;
_numTerms = 8;
_hasInitialized = false;
}
/**---------------------------------------------------------------------------------------
Get number of constraints
@return number of constraints
--------------------------------------------------------------------------------------- */
int ReferenceLincsAlgorithm::getNumberOfConstraints( void ) const {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceLincsAlgorithm::getNumberOfConstraints";
// ---------------------------------------------------------------------------------------
return _numberOfConstraints;
}
/**---------------------------------------------------------------------------------------
Get the number of terms to use in the series expansion
@return terms
--------------------------------------------------------------------------------------- */
int ReferenceLincsAlgorithm::getNumTerms( void ) const {
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceLincsAlgorithm::getNumTerms";
// ---------------------------------------------------------------------------------------
return _numTerms;
}
/**---------------------------------------------------------------------------------------
Set the number of terms to use in the series expansion
--------------------------------------------------------------------------------------- */
void ReferenceLincsAlgorithm::setNumTerms( int terms ){
// ---------------------------------------------------------------------------------------
// static const char* methodName = "\nReferenceLincsAlgorithm::setNumTerms";
// ---------------------------------------------------------------------------------------
_numTerms = terms;
}
/**---------------------------------------------------------------------------------------
Initialize internal data structures.
@param numberOfAtoms number of atoms
@param inverseMasses 1/mass
--------------------------------------------------------------------------------------- */
void ReferenceLincsAlgorithm::initialize(int numberOfAtoms, RealOpenMM* inverseMasses) {
static const RealOpenMM one = 1.0;
_hasInitialized = true;
vector<vector<int> > atomConstraints(numberOfAtoms);
for (int constraint = 0; constraint < _numberOfConstraints; constraint++) {
atomConstraints[_atomIndices[constraint][0]].push_back(constraint);
atomConstraints[_atomIndices[constraint][1]].push_back(constraint);
}
_linkedConstraints.resize(_numberOfConstraints);
for (int atom = 0; atom < numberOfAtoms; atom++) {
for (int i = 0; i < atomConstraints[atom].size(); i++)
for (int j = 0; j < i; j++) {
int c1 = atomConstraints[atom][i];
int c2 = atomConstraints[atom][j];
_linkedConstraints[c1].push_back(c2);
_linkedConstraints[c2].push_back(c1);
}
}
_sMatrix.resize(_numberOfConstraints);
for (int constraint = 0; constraint < _numberOfConstraints; constraint++)
_sMatrix[constraint] = one/SQRT(inverseMasses[_atomIndices[constraint][0]]+inverseMasses[_atomIndices[constraint][1]]);
_couplingMatrix.resize(_numberOfConstraints);
for (int constraint = 0; constraint < _numberOfConstraints; constraint++)
_couplingMatrix[constraint].resize(_linkedConstraints[constraint].size());
_constraintDir.resize(_numberOfConstraints);
_rhs1.resize(_numberOfConstraints);
_rhs2.resize(_numberOfConstraints);
_solution.resize(_numberOfConstraints);
}
/**---------------------------------------------------------------------------------------
Solve the matrix equation
--------------------------------------------------------------------------------------- */
void ReferenceLincsAlgorithm::solveMatrix() {
static const RealOpenMM zero = 0.0;
for (int iteration = 0; iteration < _numTerms; iteration++) {
vector<RealOpenMM>& rhs1 = (iteration%2 == 0 ? _rhs1 : _rhs2);
vector<RealOpenMM>& rhs2 = (iteration%2 == 0 ? _rhs2 : _rhs1);
for (int c1 = 0; c1 < _numberOfConstraints; c1++) {
rhs2[c1] = zero;
for (int j = 0; j < _linkedConstraints[c1].size(); j++) {
int c2 = _linkedConstraints[c1][j];
rhs2[c1] += _couplingMatrix[c1][j]*rhs1[c2];
}
_solution[c1] += rhs2[c1];
}
}
}
/**---------------------------------------------------------------------------------------
Update the atom position based on the solution to the matrix equation.
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param inverseMasses 1/mass
--------------------------------------------------------------------------------------- */
void ReferenceLincsAlgorithm::updateAtomPositions(int numberOfAtoms, RealOpenMM** atomCoordinates, RealOpenMM* inverseMasses) {
for (int i = 0; i < _numberOfConstraints; i++) {
Vec3 delta(_sMatrix[i]*_solution[i]*_constraintDir[i][0],
_sMatrix[i]*_solution[i]*_constraintDir[i][1],
_sMatrix[i]*_solution[i]*_constraintDir[i][2]);
int atom1 = _atomIndices[i][0];
int atom2 = _atomIndices[i][1];
atomCoordinates[atom1][0] -= inverseMasses[atom1]*delta[0];
atomCoordinates[atom1][1] -= inverseMasses[atom1]*delta[1];
atomCoordinates[atom1][2] -= inverseMasses[atom1]*delta[2];
atomCoordinates[atom2][0] += inverseMasses[atom2]*delta[0];
atomCoordinates[atom2][1] += inverseMasses[atom2]*delta[1];
atomCoordinates[atom2][2] += inverseMasses[atom2]*delta[2];
}
}
/**---------------------------------------------------------------------------------------
Apply Lincs algorithm
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param atomCoordinatesP atom coordinates prime
@param inverseMasses 1/mass
@return ReferenceDynamics::DefaultReturn if converge; else
return ReferenceDynamics::ErrorReturn
--------------------------------------------------------------------------------------- */
int ReferenceLincsAlgorithm::apply( int numberOfAtoms, RealOpenMM** atomCoordinates,
RealOpenMM** atomCoordinatesP,
RealOpenMM* inverseMasses ){
// ---------------------------------------------------------------------------------------
static const char* methodName = "\nReferenceLincsAlgorithm::apply";
static const RealOpenMM zero = 0.0;
static const RealOpenMM one = 1.0;
static const RealOpenMM two = 2.0;
// ---------------------------------------------------------------------------------------
if (_numberOfConstraints == 0)
return ReferenceDynamics::DefaultReturn;
if( !_hasInitialized )
initialize(numberOfAtoms, inverseMasses);
// Calculate the direction of each constraint, along with the initial RHS and solution vectors.
for (int i = 0; i < _numberOfConstraints; i++) {
int atom1 = _atomIndices[i][0];
int atom2 = _atomIndices[i][1];
_constraintDir[i] = Vec3(atomCoordinatesP[atom1][0]-atomCoordinatesP[atom2][0],
atomCoordinatesP[atom1][1]-atomCoordinatesP[atom2][1],
atomCoordinatesP[atom1][2]-atomCoordinatesP[atom2][2]);
RealOpenMM invLength = one/SQRT(_constraintDir[i].dot(_constraintDir[i]));
_constraintDir[i][0] *= invLength;
_constraintDir[i][1] *= invLength;
_constraintDir[i][2] *= invLength;
_rhs1[i] = _solution[i] = _sMatrix[i]*(one/invLength-_distance[i]);
}
// Build the coupling matrix.
for (int c1 = 0; c1 < _couplingMatrix.size(); c1++) {
Vec3& dir1 = _constraintDir[c1];
for (int j = 0; j < _couplingMatrix[c1].size(); j++) {
int c2 = _linkedConstraints[c1][j];
Vec3& dir2 = _constraintDir[c2];
if (_atomIndices[c1][0] == _atomIndices[c2][0] || _atomIndices[c1][1] == _atomIndices[c2][1])
_couplingMatrix[c1][j] = -inverseMasses[_atomIndices[c1][0]]*_sMatrix[c1]*dir1.dot(dir2)*_sMatrix[c2];
else
_couplingMatrix[c1][j] = inverseMasses[_atomIndices[c1][1]]*_sMatrix[c1]*dir1.dot(dir2)*_sMatrix[c2];
}
}
// Solve the matrix equation and update the positions.
solveMatrix();
updateAtomPositions(numberOfAtoms, atomCoordinatesP, inverseMasses);
// Correct for rotational lengthening.
for (int i = 0; i < _numberOfConstraints; i++) {
int atom1 = _atomIndices[i][0];
int atom2 = _atomIndices[i][1];
Vec3 delta(atomCoordinatesP[atom1][0]-atomCoordinatesP[atom2][0],
atomCoordinatesP[atom1][1]-atomCoordinatesP[atom2][1],
atomCoordinatesP[atom1][2]-atomCoordinatesP[atom2][2]);
RealOpenMM p2 = two*_distance[i]*_distance[i]-delta.dot(delta);
if (p2 < zero)
p2 = zero;
_rhs1[i] = _solution[i] = _sMatrix[i]*(_distance[i]-SQRT(p2));
}
solveMatrix();
updateAtomPositions(numberOfAtoms, atomCoordinatesP, inverseMasses);
return ReferenceDynamics::DefaultReturn;
}
/* Portions copyright (c) 2006-2009 Stanford University and Simbios.
* Contributors: Pande Group
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __ReferenceLincsAlgorithm_H__
#define __ReferenceLincsAlgorithm_H__
#include "ReferenceConstraintAlgorithm.h"
#include "Vec3.h"
#include <vector>
// ---------------------------------------------------------------------------------------
class ReferenceLincsAlgorithm : public ReferenceConstraintAlgorithm {
protected:
int _numTerms;
int _numberOfConstraints;
int** _atomIndices;
RealOpenMM* _distance;
bool _hasInitialized;
std::vector<std::vector<int> > _linkedConstraints;
std::vector<RealOpenMM> _sMatrix;
std::vector<RealOpenMM> _rhs1;
std::vector<RealOpenMM> _rhs2;
std::vector<RealOpenMM> _solution;
std::vector<std::vector<RealOpenMM> > _couplingMatrix;
std::vector<OpenMM::Vec3> _constraintDir;
/**---------------------------------------------------------------------------------------
Set the number of terms to use in the series expansion
@param numberOfAtoms number of atoms
@param inverseMasses 1/mass
--------------------------------------------------------------------------------------- */
void initialize(int numberOfAtoms, RealOpenMM* inverseMasses);
/**---------------------------------------------------------------------------------------
Solve the matrix equation
--------------------------------------------------------------------------------------- */
void solveMatrix();
/**---------------------------------------------------------------------------------------
Update the atom position based on the solution to the matrix equation.
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param inverseMasses 1/mass
--------------------------------------------------------------------------------------- */
void updateAtomPositions(int numberOfAtoms, RealOpenMM** atomCoordinates, RealOpenMM* inverseMasses);
public:
/**---------------------------------------------------------------------------------------
ReferenceLincsAlgorithm constructor
@param numberOfConstraints number of constraints
@param atomIndices atom indices for contraints
@param distance distances for constraints
--------------------------------------------------------------------------------------- */
ReferenceLincsAlgorithm( int numberOfConstraints, int** atomIndices, RealOpenMM* distance );
/**---------------------------------------------------------------------------------------
Get number of constraints
@return number of constraints
--------------------------------------------------------------------------------------- */
int getNumberOfConstraints( void ) const;
/**---------------------------------------------------------------------------------------
Get the number of terms to use in the series expansion
@return terms
--------------------------------------------------------------------------------------- */
int getNumTerms( void ) const;
/**---------------------------------------------------------------------------------------
Set the number of terms to use in the series expansion
--------------------------------------------------------------------------------------- */
void setNumTerms( int terms );
/**---------------------------------------------------------------------------------------
Apply Lincs algorithm
@param numberOfAtoms number of atoms
@param atomCoordinates atom coordinates
@param atomCoordinatesP atom coordinates prime
@param inverseMasses 1/mass
@return ReferenceDynamics::DefaultReturn if converge; else
return ReferenceDynamics::ErrorReturn
--------------------------------------------------------------------------------------- */
int apply( int numberOfAtoms, RealOpenMM** atomCoordinates,
RealOpenMM** atomCoordinatesP, RealOpenMM* inverseMasses );
};
// ---------------------------------------------------------------------------------------
#endif // __ReferenceLincsAlgorithm_H__
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
ReferenceShakeAlgorithm::ReferenceShakeAlgorithm( int numberOfConstraints, ReferenceShakeAlgorithm::ReferenceShakeAlgorithm( int numberOfConstraints,
int** atomIndices, int** atomIndices,
RealOpenMM** shakeParameters ){ RealOpenMM* distance ){
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
...@@ -61,7 +61,7 @@ ReferenceShakeAlgorithm::ReferenceShakeAlgorithm( int numberOfConstraints, ...@@ -61,7 +61,7 @@ ReferenceShakeAlgorithm::ReferenceShakeAlgorithm( int numberOfConstraints,
_numberOfConstraints = numberOfConstraints; _numberOfConstraints = numberOfConstraints;
_atomIndices = atomIndices; _atomIndices = atomIndices;
_shakeParameters = shakeParameters; _distance = distance;
_maximumNumberOfIterations = 15; _maximumNumberOfIterations = 15;
_tolerance = (RealOpenMM) 1.0e-04; _tolerance = (RealOpenMM) 1.0e-04;
...@@ -221,13 +221,13 @@ int ReferenceShakeAlgorithm::setTolerance( RealOpenMM tolerance ){ ...@@ -221,13 +221,13 @@ int ReferenceShakeAlgorithm::setTolerance( RealOpenMM tolerance ){
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
int ReferenceShakeAlgorithm::applyShake( int numberOfAtoms, RealOpenMM** atomCoordinates, int ReferenceShakeAlgorithm::apply( int numberOfAtoms, RealOpenMM** atomCoordinates,
RealOpenMM** atomCoordinatesP, RealOpenMM** atomCoordinatesP,
RealOpenMM* inverseMasses ){ RealOpenMM* inverseMasses ){
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
static const char* methodName = "\nReferenceShakeAlgorithm::applyShake"; static const char* methodName = "\nReferenceShakeAlgorithm::apply";
static const RealOpenMM zero = 0.0; static const RealOpenMM zero = 0.0;
static const RealOpenMM one = 1.0; static const RealOpenMM one = 1.0;
...@@ -298,7 +298,7 @@ int ReferenceShakeAlgorithm::applyShake( int numberOfAtoms, RealOpenMM** atomCoo ...@@ -298,7 +298,7 @@ int ReferenceShakeAlgorithm::applyShake( int numberOfAtoms, RealOpenMM** atomCoo
} }
RealOpenMM rp2 = DOT3( rp_ij, rp_ij ); RealOpenMM rp2 = DOT3( rp_ij, rp_ij );
RealOpenMM dist2= _shakeParameters[ii][0]*_shakeParameters[ii][0]; RealOpenMM dist2= _distance[ii]*_distance[ii];
RealOpenMM diff = dist2 - rp2; RealOpenMM diff = dist2 - rp2;
int iconv = (int) ( FABS( diff )*distanceTolerance[ii] ); int iconv = (int) ( FABS( diff )*distanceTolerance[ii] );
if( iconv ){ if( iconv ){
...@@ -409,9 +409,9 @@ int ReferenceShakeAlgorithm::reportShake( int numberOfAtoms, RealOpenMM** atomCo ...@@ -409,9 +409,9 @@ int ReferenceShakeAlgorithm::reportShake( int numberOfAtoms, RealOpenMM** atomCo
for( int jj = 0; jj < 3; jj++ ){ for( int jj = 0; jj < 3; jj++ ){
rp2 += (atomCoordinates[atomI][jj] - atomCoordinates[atomJ][jj])*(atomCoordinates[atomI][jj] - atomCoordinates[atomJ][jj]); rp2 += (atomCoordinates[atomI][jj] - atomCoordinates[atomJ][jj])*(atomCoordinates[atomI][jj] - atomCoordinates[atomJ][jj]);
} }
RealOpenMM diff = FABS( rp2 - (_shakeParameters[ii][0]*_shakeParameters[ii][0]) ); RealOpenMM diff = FABS( rp2 - (_distance[ii]*_distance[ii]) );
if( diff > tolerance ){ if( diff > tolerance ){
message << ii << " constraint violated: " << atomI << " " << atomJ << "] d=" << SQRT( rp2 ) << " " << rp2 << " d0=" << _shakeParameters[ii][0]; message << ii << " constraint violated: " << atomI << " " << atomJ << "] d=" << SQRT( rp2 ) << " " << rp2 << " d0=" << _distance[ii];
message << " diff=" << diff; message << " diff=" << diff;
message << " [" << atomCoordinates[atomI][0] << " " << atomCoordinates[atomI][1] << " " << atomCoordinates[atomI][2] << "] "; message << " [" << atomCoordinates[atomI][0] << " " << atomCoordinates[atomI][1] << " " << atomCoordinates[atomI][2] << "] ";
message << " [" << atomCoordinates[atomJ][0] << " " << atomCoordinates[atomJ][1] << " " << atomCoordinates[atomJ][2] << "] "; message << " [" << atomCoordinates[atomJ][0] << " " << atomCoordinates[atomJ][1] << " " << atomCoordinates[atomJ][2] << "] ";
......
...@@ -25,9 +25,11 @@ ...@@ -25,9 +25,11 @@
#ifndef __ReferenceShakeAlgorithm_H__ #ifndef __ReferenceShakeAlgorithm_H__
#define __ReferenceShakeAlgorithm_H__ #define __ReferenceShakeAlgorithm_H__
#include "ReferenceConstraintAlgorithm.h"
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
class ReferenceShakeAlgorithm { class ReferenceShakeAlgorithm : public ReferenceConstraintAlgorithm {
protected: protected:
...@@ -36,7 +38,7 @@ class ReferenceShakeAlgorithm { ...@@ -36,7 +38,7 @@ class ReferenceShakeAlgorithm {
int _numberOfConstraints; int _numberOfConstraints;
int** _atomIndices; int** _atomIndices;
RealOpenMM** _shakeParameters; RealOpenMM* _distance;
RealOpenMM** _r_ij; RealOpenMM** _r_ij;
RealOpenMM* _d_ij2; RealOpenMM* _d_ij2;
...@@ -52,11 +54,11 @@ class ReferenceShakeAlgorithm { ...@@ -52,11 +54,11 @@ class ReferenceShakeAlgorithm {
@param numberOfConstraints number of constraints @param numberOfConstraints number of constraints
@param atomIndices atom indices for contraints @param atomIndices atom indices for contraints
@param shakeParameters Shake parameters @param distance distances for constraints
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceShakeAlgorithm( int numberOfConstraints, int** atomIndices, RealOpenMM** shakeParameters ); ReferenceShakeAlgorithm( int numberOfConstraints, int** atomIndices, RealOpenMM* distance );
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -145,7 +147,7 @@ class ReferenceShakeAlgorithm { ...@@ -145,7 +147,7 @@ class ReferenceShakeAlgorithm {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
int applyShake( int numberOfAtoms, RealOpenMM** atomCoordinates, int apply( int numberOfAtoms, RealOpenMM** atomCoordinates,
RealOpenMM** atomCoordinatesP, RealOpenMM* inverseMasses ); RealOpenMM** atomCoordinatesP, RealOpenMM* inverseMasses );
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
......
...@@ -498,17 +498,17 @@ int ReferenceStochasticDynamics::update( int numberOfAtoms, RealOpenMM** atomCoo ...@@ -498,17 +498,17 @@ int ReferenceStochasticDynamics::update( int numberOfAtoms, RealOpenMM** atomCoo
//writeState( numberOfAtoms, atomCoordinates, velocities, forces, masses, -1 , "Sd1" ); //writeState( numberOfAtoms, atomCoordinates, velocities, forces, masses, -1 , "Sd1" );
ReferenceShakeAlgorithm* referenceShakeAlgorithm = getReferenceShakeAlgorithm(); ReferenceConstraintAlgorithm* referenceConstraintAlgorithm = getReferenceConstraintAlgorithm();
if( referenceShakeAlgorithm ){ if( referenceConstraintAlgorithm ){
/* /*
std::stringstream message; std::stringstream message;
message << methodName; message << methodName;
message << " calling shake1\n"; message << " calling constrain1\n";
SimTKOpenMMLog::printMessage( message ); SimTKOpenMMLog::printMessage( message );
*/ */
referenceShakeAlgorithm->applyShake( numberOfAtoms, atomCoordinates, xPrime, referenceConstraintAlgorithm->apply( numberOfAtoms, atomCoordinates, xPrime,
inverseMasses ); inverseMasses );
} }
...@@ -556,16 +556,16 @@ int ReferenceStochasticDynamics::update( int numberOfAtoms, RealOpenMM** atomCoo ...@@ -556,16 +556,16 @@ int ReferenceStochasticDynamics::update( int numberOfAtoms, RealOpenMM** atomCoo
SimTKOpenMMLog::printMessage( message ); SimTKOpenMMLog::printMessage( message );
} }
if( referenceShakeAlgorithm ){ if( referenceConstraintAlgorithm ){
/* /*
std::stringstream message; std::stringstream message;
message << methodName; message << methodName;
message << " calling shake2\n"; message << " calling constrain2\n";
SimTKOpenMMLog::printMessage( message ); SimTKOpenMMLog::printMessage( message );
*/ */
referenceShakeAlgorithm->applyShake( numberOfAtoms, atomCoordinates, xPrime, referenceConstraintAlgorithm->apply( numberOfAtoms, atomCoordinates, xPrime,
inverseMasses ); inverseMasses );
} }
......
...@@ -170,9 +170,9 @@ int ReferenceVerletDynamics::update( int numberOfAtoms, RealOpenMM** atomCoordin ...@@ -170,9 +170,9 @@ int ReferenceVerletDynamics::update( int numberOfAtoms, RealOpenMM** atomCoordin
xPrime[i][j] = atomCoordinates[i][j] + velocities[i][j]*getDeltaT(); xPrime[i][j] = atomCoordinates[i][j] + velocities[i][j]*getDeltaT();
} }
} }
ReferenceShakeAlgorithm* referenceShakeAlgorithm = getReferenceShakeAlgorithm(); ReferenceConstraintAlgorithm* referenceConstraintAlgorithm = getReferenceConstraintAlgorithm();
if( referenceShakeAlgorithm ) if( referenceConstraintAlgorithm )
referenceShakeAlgorithm->applyShake( numberOfAtoms, atomCoordinates, xPrime, inverseMasses ); referenceConstraintAlgorithm->apply( numberOfAtoms, atomCoordinates, xPrime, inverseMasses );
// Update the positions and velocities. // Update the positions and velocities.
......
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