Commit e06e0ea7 authored by Peter Eastman's avatar Peter Eastman
Browse files

Fixed bugs in AndersenThermostat and CMMotionRemover

parent dfd14586
...@@ -607,7 +607,7 @@ void CudaApplyAndersenThermostatKernel::execute(OpenMMContextImpl& context) { ...@@ -607,7 +607,7 @@ void CudaApplyAndersenThermostatKernel::execute(OpenMMContextImpl& context) {
if (temperature != prevTemp || frequency != prevFrequency || stepSize != prevStepSize) { if (temperature != prevTemp || frequency != prevFrequency || stepSize != prevStepSize) {
// Initialize the GPU parameters. // Initialize the GPU parameters.
gpuSetAndersenThermostatParameters(gpu, (float) temperature, (float) (frequency*stepSize)); gpuSetAndersenThermostatParameters(gpu, (float) temperature, frequency);
gpuSetConstants(gpu); gpuSetConstants(gpu);
kGenerateRandoms(gpu); kGenerateRandoms(gpu);
prevTemp = temperature; prevTemp = temperature;
......
...@@ -336,7 +336,7 @@ struct cudaGmxSimulation { ...@@ -336,7 +336,7 @@ struct cudaGmxSimulation {
float fix1; // Molecular dynamics fix1 constant float fix1; // Molecular dynamics fix1 constant
float oneOverFix1; // Molecular dynamics reciprocal of fix1 constant float oneOverFix1; // Molecular dynamics reciprocal of fix1 constant
float DOverTauC; // Molecular dynamics DOverTauC constant float DOverTauC; // Molecular dynamics DOverTauC constant
float collisionProbability; // Collision probability for Andersen thermostat float collisionFrequency; // Collision frequency for Andersen thermostat
float2* pObcData; // Pointer to fixed Born data float2* pObcData; // Pointer to fixed Born data
float2* pAttr; // Pointer to additional atom attributes (sig, eps) float2* pAttr; // Pointer to additional atom attributes (sig, eps)
float2* pEwaldCosSinSum; // Pointer to the cos/sin sums (ewald) float2* pEwaldCosSinSum; // Pointer to the cos/sin sums (ewald)
......
...@@ -1351,6 +1351,9 @@ void gpuSetIntegrationParameters(gpuContext gpu, float tau, float deltaT, float ...@@ -1351,6 +1351,9 @@ void gpuSetIntegrationParameters(gpuContext gpu, float tau, float deltaT, float
gpu->sim.X = gpu->sim.tau * sqrt(gpu->sim.kT * gpu->sim.C); gpu->sim.X = gpu->sim.tau * sqrt(gpu->sim.kT * gpu->sim.C);
gpu->sim.Yv = sqrt(gpu->sim.kT * gpu->sim.B / gpu->sim.C); gpu->sim.Yv = sqrt(gpu->sim.kT * gpu->sim.B / gpu->sim.C);
gpu->sim.Yx = gpu->sim.tau * sqrt(gpu->sim.kT * gpu->sim.B / (1.0f - gpu->sim.EM)); gpu->sim.Yx = gpu->sim.tau * sqrt(gpu->sim.kT * gpu->sim.B / (1.0f - gpu->sim.EM));
gpu->psStepSize->Download();
(*gpu->psStepSize)[0].y = deltaT;
gpu->psStepSize->Upload();
} }
extern "C" extern "C"
...@@ -1372,13 +1375,16 @@ void gpuSetBrownianIntegrationParameters(gpuContext gpu, float tau, float deltaT ...@@ -1372,13 +1375,16 @@ void gpuSetBrownianIntegrationParameters(gpuContext gpu, float tau, float deltaT
gpu->sim.T = temperature; gpu->sim.T = temperature;
gpu->sim.kT = BOLTZ * gpu->sim.T; gpu->sim.kT = BOLTZ * gpu->sim.T;
gpu->sim.Yv = gpu->sim.Yx = sqrt(2.0f*gpu->sim.kT*deltaT*tau); gpu->sim.Yv = gpu->sim.Yx = sqrt(2.0f*gpu->sim.kT*deltaT*tau);
gpu->psStepSize->Download();
(*gpu->psStepSize)[0].y = deltaT;
gpu->psStepSize->Upload();
} }
extern "C" extern "C"
void gpuSetAndersenThermostatParameters(gpuContext gpu, float temperature, float collisionProbability) { void gpuSetAndersenThermostatParameters(gpuContext gpu, float temperature, float collisionFrequency) {
gpu->sim.T = temperature; gpu->sim.T = temperature;
gpu->sim.kT = BOLTZ * gpu->sim.T; gpu->sim.kT = BOLTZ * gpu->sim.T;
gpu->sim.collisionProbability = collisionProbability; gpu->sim.collisionFrequency = collisionFrequency;
gpu->sim.Yv = gpu->sim.Yx = 1.0f; gpu->sim.Yv = gpu->sim.Yx = 1.0f;
gpu->sim.V = gpu->sim.X = 1.0f; gpu->sim.V = gpu->sim.X = 1.0f;
} }
......
...@@ -216,7 +216,7 @@ extern "C" ...@@ -216,7 +216,7 @@ extern "C"
void gpuSetBrownianIntegrationParameters(gpuContext gpu, float tau, float deltaT, float temperature); void gpuSetBrownianIntegrationParameters(gpuContext gpu, float tau, float deltaT, float temperature);
extern "C" extern "C"
void gpuSetAndersenThermostatParameters(gpuContext gpu, float temperature, float collisionProbability); void gpuSetAndersenThermostatParameters(gpuContext gpu, float temperature, float collisionFrequency);
extern "C" extern "C"
void gpuShutDown(gpuContext gpu); void gpuShutDown(gpuContext gpu);
......
...@@ -57,11 +57,12 @@ __global__ void kCalculateAndersenThermostat_kernel() ...@@ -57,11 +57,12 @@ __global__ void kCalculateAndersenThermostat_kernel()
unsigned int rpos = cSim.pRandomPosition[blockIdx.x]; unsigned int rpos = cSim.pRandomPosition[blockIdx.x];
__syncthreads(); __syncthreads();
float collisionProbability = 1.0f-exp(-cSim.collisionFrequency*cSim.pStepSize[0].y);
while (pos < cSim.atoms) while (pos < cSim.atoms)
{ {
float4 velocity = cSim.pVelm4[pos]; float4 velocity = cSim.pVelm4[pos];
float4 random4a = cSim.pRandom4a[rpos + pos]; float4 random4a = cSim.pRandom4a[rpos + pos];
float scale = (random4a.w < cSim.collisionProbability ? 0.0 : 1.0); float scale = (random4a.w < collisionProbability ? 0.0 : 1.0);
float add = (1.0-scale)*sqrt(cSim.kT*velocity.w); float add = (1.0-scale)*sqrt(cSim.kT*velocity.w);
velocity.x = scale*velocity.x + add*random4a.x; velocity.x = scale*velocity.x + add*random4a.x;
velocity.y = scale*velocity.y + add*random4a.y; velocity.y = scale*velocity.y + add*random4a.y;
......
...@@ -967,20 +967,22 @@ void ReferenceRemoveCMMotionKernel::execute(OpenMMContextImpl& context) { ...@@ -967,20 +967,22 @@ void ReferenceRemoveCMMotionKernel::execute(OpenMMContextImpl& context) {
// Calculate the center of mass momentum. // Calculate the center of mass momentum.
RealOpenMM momentum[] = {0.0, 0.0, 0.0}; RealOpenMM momentum[] = {0.0, 0.0, 0.0};
RealOpenMM mass = 0.0;
for (size_t i = 0; i < masses.size(); ++i) { for (size_t i = 0; i < masses.size(); ++i) {
momentum[0] += static_cast<RealOpenMM>( masses[i]*velData[i][0] ); momentum[0] += static_cast<RealOpenMM>( masses[i]*velData[i][0] );
momentum[1] += static_cast<RealOpenMM>( masses[i]*velData[i][1] ); momentum[1] += static_cast<RealOpenMM>( masses[i]*velData[i][1] );
momentum[2] += static_cast<RealOpenMM>( masses[i]*velData[i][2] ); momentum[2] += static_cast<RealOpenMM>( masses[i]*velData[i][2] );
mass += masses[i];
} }
// Adjust the particle velocities. // Adjust the particle velocities.
momentum[0] /= static_cast<RealOpenMM>( masses.size() ); momentum[0] /= mass;
momentum[1] /= static_cast<RealOpenMM>( masses.size() ); momentum[1] /= mass;
momentum[2] /= static_cast<RealOpenMM>( masses.size() ); momentum[2] /= mass;
for (size_t i = 0; i < masses.size(); ++i) { for (size_t i = 0; i < masses.size(); ++i) {
velData[i][0] -= static_cast<RealOpenMM>( momentum[0]/masses[i] ); velData[i][0] -= momentum[0];
velData[i][1] -= static_cast<RealOpenMM>( momentum[1]/masses[i] ); velData[i][1] -= momentum[1];
velData[i][2] -= static_cast<RealOpenMM>( momentum[2]/masses[i] ); velData[i][2] -= momentum[2];
} }
} }
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
void ReferenceAndersenThermostat::applyThermostat( int numberOfAtoms, RealOpenMM** atomVelocities, RealOpenMM* atomMasses, void ReferenceAndersenThermostat::applyThermostat( int numberOfAtoms, RealOpenMM** atomVelocities, RealOpenMM* atomMasses,
RealOpenMM temperature, RealOpenMM collisionFrequency, RealOpenMM stepSize ) const { RealOpenMM temperature, RealOpenMM collisionFrequency, RealOpenMM stepSize ) const {
const RealOpenMM collisionProbability = collisionFrequency*stepSize; const RealOpenMM collisionProbability = 1.0f - EXP(-collisionFrequency*stepSize);
for (int i = 0; i < numberOfAtoms; ++i) { for (int i = 0; i < numberOfAtoms; ++i) {
if (SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() < collisionProbability) { if (SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() < collisionProbability) {
......
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