Skip to content

Neighbour List

Raul edited this page Jan 17, 2019 · 15 revisions

A neighbour list is an entity that has a cut off distance and is able to determine for each particle in the system the other particles that are closer to it than this cut off.

The core pseudocode of a neighbour list's duties can be summarized as follow:

total = initial_value()
for(all particles i)
  for(all neighbours j of particle i)
   quantity = do_something_with(particle i, particle j)
   accumulate(total, quantity)

This something can be anything from summing forces on particle i to filling matrix elements. Furthermore, accumulate can be anything, like just summing (i.e. to compute the total force acting on each particle or filling the elements of a matrix, using total for something else).


Using a neighbour list

A neighbour list will work with the position array in its ParticleData[9] and only on the particles in its ParticleGroup[8].

A neighbour list must be initialized providing the system:

auto nl = make_shared<CellList>(pd, pg, sys);

A neighbour list (nl) can be constructed/updated by calling

nl.updateNeighbourList(box, cutoffDistance, cudastream);

The list will be updated only if it is necessary. i.e the box or the rcut have changed in a way that invalids the previous list.

A neighbour list can be used by calling

nl.transverse(tr, cudaStream)

Where tr is a List Transverser. This entity contains information about what to do with each pair of neighbours in the system. See [6] more information.

This is just a base class, a prototype to construct neighbour lists. It is a virtual class and therefore cannot be used by itself, it must be inherited by new neighbour lists.

In general, a neighbour list built following this page's directives will be compatible with any module using a neighbour list. Except in cases were a particular list type is needed for some reason.

In order to make a new module general for any neighbour list, the NL type must be implemented as a template parameter. This applies whether the module has its own private NL or one is provided through the constructor or any other setter function. See technical restrictions[3].

To see about a particular list see its wiki page. i.e CellList [2]

Implementing a new Neighbour List

Any new Neighbour List must comply with the NeighbourList concept, it must:

  • Have an updateNeighbourList(Box box, real cutoffDistance, cudaStream st); method that ensures the list is valid with the passed arguments after the call.
  • Have a transverseList(Transverser &tr, cudaStream st); method that applies a Transverser[6] to the list.
  • Have a getNeighbourList(cudaStream st); method that returns a neighbour list in the format:
  //The data structure needed to use the list from outside
    struct NeighbourListData{
      int * neighbourList; // All neighbours of particle "i" are adjacent and start at particleStride[i]
      int *numberNeighbours; // particle i has numberNeighbours[i] neighbours
      StrideIterator particleStride; //An iterator that returns the index of the first neighbour of particle i in neighbourList
    };
  • Handle ParticleGroups[8]
  • Handle particle number changes and sortings (through ParticleData)
  • Allow the Transverser to use shared memory by allocating tr.getSharedMemorySize() bytes of dynamic shared memory if the method exists.

See CellList.h for an example of a NL implementation.[2]


[1]https://github.com/RaulPPelaez/UAMMD/wiki/Verlet-List
[2]https://github.com/RaulPPelaez/UAMMD/wiki/Cell-List
[4]https://github.com/RaulPPelaez/UAMMD/wiki/Pair-Forces
[6]https://github.com/RaulPPelaez/UAMMD/wiki/List-Transverser
[8]https://github.com/RaulPPelaez/UAMMD/wiki/ParticleGroup
[9]https://github.com/RaulPPelaez/UAMMD/wiki/ParticleData









Clone this wiki locally