Commit d389e504 authored by peastman's avatar peastman
Browse files

Prevent segfaults when a simulation blows up

parent 79e2fb0e
...@@ -383,13 +383,15 @@ void CpuNonbondedForce::calculateDirectIxn(int numberOfAtoms, float* posq, const ...@@ -383,13 +383,15 @@ void CpuNonbondedForce::calculateDirectIxn(int numberOfAtoms, float* posq, const
float r = sqrtf(r2); float r = sqrtf(r2);
float inverseR = 1/r; float inverseR = 1/r;
float chargeProd = ONE_4PI_EPS0*posq[4*ii+3]*posq[4*jj+3]; float chargeProd = ONE_4PI_EPS0*posq[4*ii+3]*posq[4*jj+3];
float alphaR = alphaEwald*r;
float erfcAlphaR = erfcApprox(alphaR);
float dEdR = (float) (chargeProd * inverseR * inverseR * inverseR); float dEdR = (float) (chargeProd * inverseR * inverseR * inverseR);
dEdR = (float) (dEdR * (1.0f-ewaldScaleFunction(r))); dEdR = (float) (dEdR * (1.0f-erfcAlphaR-TWO_OVER_SQRT_PI*alphaR*exp(-alphaR*alphaR)));
__m128 result = _mm_mul_ps(deltaR, _mm_set1_ps(dEdR)); __m128 result = _mm_mul_ps(deltaR, _mm_set1_ps(dEdR));
_mm_storeu_ps(forces+4*ii, _mm_sub_ps(_mm_loadu_ps(forces+4*ii), result)); _mm_storeu_ps(forces+4*ii, _mm_sub_ps(_mm_loadu_ps(forces+4*ii), result));
_mm_storeu_ps(forces+4*jj, _mm_add_ps(_mm_loadu_ps(forces+4*jj), result)); _mm_storeu_ps(forces+4*jj, _mm_add_ps(_mm_loadu_ps(forces+4*jj), result));
if (includeEnergy) if (includeEnergy)
directEnergy -= chargeProd*inverseR*(1.0f-erfcApprox(alphaEwald*r)); directEnergy -= chargeProd*inverseR*(1.0f-erfcAlphaR);
} }
} }
} }
...@@ -505,8 +507,7 @@ void CpuNonbondedForce::calculateOneEwaldIxn(int ii, int jj, float* forces, doub ...@@ -505,8 +507,7 @@ void CpuNonbondedForce::calculateOneEwaldIxn(int ii, int jj, float* forces, doub
__m128 posJ = _mm_loadu_ps(posq+4*jj); __m128 posJ = _mm_loadu_ps(posq+4*jj);
float r2; float r2;
getDeltaR(posJ, posI, deltaR, r2, true); getDeltaR(posJ, posI, deltaR, r2, true);
if (r2 >= cutoffDistance*cutoffDistance) if (r2 < cutoffDistance*cutoffDistance) {
return;
float r = sqrtf(r2); float r = sqrtf(r2);
float inverseR = 1/r; float inverseR = 1/r;
float switchValue = 1, switchDeriv = 0; float switchValue = 1, switchDeriv = 0;
...@@ -542,6 +543,7 @@ void CpuNonbondedForce::calculateOneEwaldIxn(int ii, int jj, float* forces, doub ...@@ -542,6 +543,7 @@ void CpuNonbondedForce::calculateOneEwaldIxn(int ii, int jj, float* forces, doub
energy += (float) (chargeProd*inverseR*erfcApprox(alphaEwald*r)); energy += (float) (chargeProd*inverseR*erfcApprox(alphaEwald*r));
*totalEnergy += energy; *totalEnergy += energy;
} }
}
} }
void CpuNonbondedForce::getDeltaR(const __m128& posI, const __m128& posJ, __m128& deltaR, float& r2, bool periodic) const { void CpuNonbondedForce::getDeltaR(const __m128& posI, const __m128& posJ, __m128& deltaR, float& r2, bool periodic) const {
......
...@@ -93,6 +93,8 @@ static void spreadCharge(int start, int end, float* posq, float* grid, int gridx ...@@ -93,6 +93,8 @@ static void spreadCharge(int start, int end, float* posq, float* grid, int gridx
int gridIndexX = _mm_extract_epi32(gridIndex, 0); int gridIndexX = _mm_extract_epi32(gridIndex, 0);
int gridIndexY = _mm_extract_epi32(gridIndex, 1); int gridIndexY = _mm_extract_epi32(gridIndex, 1);
int gridIndexZ = _mm_extract_epi32(gridIndex, 2); int gridIndexZ = _mm_extract_epi32(gridIndex, 2);
if (gridIndexX < 0)
return; // This happens when a simulation blows up and coordinates become NaN.
int zindex[PME_ORDER]; int zindex[PME_ORDER];
for (int j = 0; j < PME_ORDER; j++) { for (int j = 0; j < PME_ORDER; j++) {
zindex[j] = gridIndexZ+j; zindex[j] = gridIndexZ+j;
...@@ -288,6 +290,8 @@ static void interpolateForces(int start, int end, float* posq, float* force, flo ...@@ -288,6 +290,8 @@ static void interpolateForces(int start, int end, float* posq, float* force, flo
int gridIndexX = _mm_extract_epi32(gridIndex, 0); int gridIndexX = _mm_extract_epi32(gridIndex, 0);
int gridIndexY = _mm_extract_epi32(gridIndex, 1); int gridIndexY = _mm_extract_epi32(gridIndex, 1);
int gridIndexZ = _mm_extract_epi32(gridIndex, 2); int gridIndexZ = _mm_extract_epi32(gridIndex, 2);
if (gridIndexX < 0)
return; // This happens when a simulation blows up and coordinates become NaN.
int zindex[PME_ORDER]; int zindex[PME_ORDER];
for (int j = 0; j < PME_ORDER; j++) { for (int j = 0; j < PME_ORDER; j++) {
zindex[j] = gridIndexZ+j; zindex[j] = gridIndexZ+j;
......
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