Commit 4193a416 authored by peastman's avatar peastman
Browse files

CpuNeighborList correctly handles triclinic boxes

parent 34ddae96
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "AlignedArray.h" #include "AlignedArray.h"
#include "RealVec.h"
#include "windowsExportCpu.h" #include "windowsExportCpu.h"
#include "openmm/internal/ThreadPool.h" #include "openmm/internal/ThreadPool.h"
#include <set> #include <set>
...@@ -40,12 +41,14 @@ ...@@ -40,12 +41,14 @@
#include <vector> #include <vector>
namespace OpenMM { namespace OpenMM {
class OPENMM_EXPORT_CPU CpuNeighborList { class OPENMM_EXPORT_CPU CpuNeighborList {
public: public:
class ThreadTask; class ThreadTask;
class Voxels; class Voxels;
CpuNeighborList(int blockSize); CpuNeighborList(int blockSize);
void computeNeighborList(int numAtoms, const AlignedArray<float>& atomLocations, const std::vector<std::set<int> >& exclusions,
const RealVec* periodicBoxVectors, bool usePeriodic, float maxDistance, ThreadPool& threads);
void computeNeighborList(int numAtoms, const AlignedArray<float>& atomLocations, const std::vector<std::set<int> >& exclusions, void computeNeighborList(int numAtoms, const AlignedArray<float>& atomLocations, const std::vector<std::set<int> >& exclusions,
const float* periodicBoxSize, bool usePeriodic, float maxDistance, ThreadPool& threads); const float* periodicBoxSize, bool usePeriodic, float maxDistance, ThreadPool& threads);
int getNumBlocks() const; int getNumBlocks() const;
...@@ -68,7 +71,7 @@ private: ...@@ -68,7 +71,7 @@ private:
Voxels* voxels; Voxels* voxels;
const std::vector<std::set<int> >* exclusions; const std::vector<std::set<int> >* exclusions;
const float* atomLocations; const float* atomLocations;
const float* periodicBoxSize; RealVec periodicBoxVectors[3];
int numAtoms; int numAtoms;
bool usePeriodic; bool usePeriodic;
float maxDistance; float maxDistance;
......
This diff is collapsed.
...@@ -463,9 +463,9 @@ void CpuNonbondedForce::getDeltaR(const fvec4& posI, const fvec4& posJ, fvec4& d ...@@ -463,9 +463,9 @@ void CpuNonbondedForce::getDeltaR(const fvec4& posI, const fvec4& posJ, fvec4& d
deltaR = posJ-posI; deltaR = posJ-posI;
if (periodic) { if (periodic) {
if (triclinic) { if (triclinic) {
deltaR -= periodicBoxVec4[2]*floor(deltaR[2]*recipBoxSize[2]+0.5f); deltaR -= periodicBoxVec4[2]*floorf(deltaR[2]*recipBoxSize[2]+0.5f);
deltaR -= periodicBoxVec4[1]*floor(deltaR[1]*recipBoxSize[1]+0.5f); deltaR -= periodicBoxVec4[1]*floorf(deltaR[1]*recipBoxSize[1]+0.5f);
deltaR -= periodicBoxVec4[0]*floor(deltaR[0]*recipBoxSize[0]+0.5f); deltaR -= periodicBoxVec4[0]*floorf(deltaR[0]*recipBoxSize[0]+0.5f);
} }
else { else {
fvec4 base = round(deltaR*invBoxSize)*boxSize; fvec4 base = round(deltaR*invBoxSize)*boxSize;
......
...@@ -48,10 +48,21 @@ ...@@ -48,10 +48,21 @@
using namespace OpenMM; using namespace OpenMM;
using namespace std; using namespace std;
void testNeighborList(bool periodic) { void testNeighborList(bool periodic, bool triclinic) {
const int numParticles = 500; const int numParticles = 500;
const float cutoff = 2.0f; const float cutoff = 2.0f;
const float boxSize[3] = {20.0f, 15.0f, 22.0f}; RealVec boxVectors[3];
if (triclinic) {
boxVectors[0] = RealVec(20, 0, 0);
boxVectors[1] = RealVec(5, 15, 0);
boxVectors[2] = RealVec(-3, -7, 22);
}
else {
boxVectors[0] = RealVec(20, 0, 0);
boxVectors[1] = RealVec(0, 15, 0);
boxVectors[2] = RealVec(0, 0, 22);
}
const float boxSize[3] = {boxVectors[0][0], boxVectors[1][1], boxVectors[2][2]};
const int blockSize = 8; const int blockSize = 8;
OpenMM_SFMT::SFMT sfmt; OpenMM_SFMT::SFMT sfmt;
init_gen_rand(0, sfmt); init_gen_rand(0, sfmt);
...@@ -69,7 +80,7 @@ void testNeighborList(bool periodic) { ...@@ -69,7 +80,7 @@ void testNeighborList(bool periodic) {
} }
ThreadPool threads; ThreadPool threads;
CpuNeighborList neighborList(blockSize); CpuNeighborList neighborList(blockSize);
neighborList.computeNeighborList(numParticles, positions, exclusions, boxSize, periodic, cutoff, threads); neighborList.computeNeighborList(numParticles, positions, exclusions, boxVectors, periodic, cutoff, threads);
// Convert the neighbor list to a set for faster lookup. // Convert the neighbor list to a set for faster lookup.
...@@ -90,19 +101,17 @@ void testNeighborList(bool periodic) { ...@@ -90,19 +101,17 @@ void testNeighborList(bool periodic) {
} }
// Check each particle pair and figure out whether they should be in the neighbor list. // Check each particle pair and figure out whether they should be in the neighbor list.
for (int i = 0; i < numParticles; i++) for (int i = 0; i < numParticles; i++)
for (int j = 0; j <= i; j++) { for (int j = 0; j <= i; j++) {
bool shouldInclude = (exclusions[i].find(j) == exclusions[i].end()); bool shouldInclude = (exclusions[i].find(j) == exclusions[i].end());
float dx = positions[4*i]-positions[4*j]; Vec3 diff(positions[4*i]-positions[4*j], positions[4*i+1]-positions[4*j+1], positions[4*i+2]-positions[4*j+2]);
float dy = positions[4*i+1]-positions[4*j+1];
float dz = positions[4*i+2]-positions[4*j+2];
if (periodic) { if (periodic) {
dx -= floor(dx/boxSize[0]+0.5f)*boxSize[0]; diff -= boxVectors[2]*floor(diff[2]/boxSize[2]+0.5);
dy -= floor(dy/boxSize[1]+0.5f)*boxSize[1]; diff -= boxVectors[1]*floor(diff[1]/boxSize[1]+0.5);
dz -= floor(dz/boxSize[2]+0.5f)*boxSize[2]; diff -= boxVectors[0]*floor(diff[0]/boxSize[0]+0.5);
} }
if (dx*dx + dy*dy + dz*dz > cutoff*cutoff) if (diff.dot(diff) > cutoff*cutoff)
shouldInclude = false; shouldInclude = false;
bool isIncluded = (neighbors.find(make_pair(i, j)) != neighbors.end() || neighbors.find(make_pair(j, i)) != neighbors.end()); bool isIncluded = (neighbors.find(make_pair(i, j)) != neighbors.end() || neighbors.find(make_pair(j, i)) != neighbors.end());
if (shouldInclude) if (shouldInclude)
...@@ -116,8 +125,9 @@ int main() { ...@@ -116,8 +125,9 @@ int main() {
cout << "CPU is not supported. Exiting." << endl; cout << "CPU is not supported. Exiting." << endl;
return 0; return 0;
} }
testNeighborList(false); testNeighborList(false, false);
testNeighborList(true); testNeighborList(true, false);
testNeighborList(true, true);
} }
catch(const exception& e) { catch(const exception& e) {
cout << "exception: " << e.what() << endl; cout << "exception: " << e.what() << endl;
......
...@@ -157,9 +157,9 @@ public: ...@@ -157,9 +157,9 @@ public:
int miny = centerVoxelIndex.y-dIndexY; int miny = centerVoxelIndex.y-dIndexY;
int maxy = centerVoxelIndex.y+dIndexY; int maxy = centerVoxelIndex.y+dIndexY;
if (usePeriodic) { if (usePeriodic) {
int yoffset = (int) ceil(boxz*periodicBoxVectors[2][1]/voxelSizeY); double yoffset = boxz*periodicBoxVectors[2][1]/voxelSizeY;
miny -= yoffset; miny -= (int) ceil(yoffset);
maxy -= yoffset-1; maxy -= (int) floor(yoffset);
maxy = min(maxy, miny+ny-1); maxy = min(maxy, miny+ny-1);
} }
for (int y = miny; y <= maxy; ++y) for (int y = miny; y <= maxy; ++y)
...@@ -168,9 +168,9 @@ public: ...@@ -168,9 +168,9 @@ public:
int minx = centerVoxelIndex.x-dIndexX; int minx = centerVoxelIndex.x-dIndexX;
int maxx = centerVoxelIndex.x+dIndexX; int maxx = centerVoxelIndex.x+dIndexX;
if (usePeriodic) { if (usePeriodic) {
int xoffset = (int) ceil((boxy*periodicBoxVectors[1][0]+boxz*periodicBoxVectors[2][0])/voxelSizeX); double xoffset = (boxy*periodicBoxVectors[1][0]+boxz*periodicBoxVectors[2][0])/voxelSizeX;
minx -= xoffset; minx -= (int) ceil(xoffset);
maxx -= xoffset-1; maxx -= (int) floor(xoffset);
maxx = min(maxx, minx+nx-1); maxx = min(maxx, minx+nx-1);
} }
for (int x = minx; x <= maxx; ++x) for (int x = minx; x <= maxx; ++x)
......
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