Neighbours#

Directory: libfly/neigh

The neigh folder contains a collection of data structures and algorithms for generating and manipulating neighbours. Neighbours of an atom are atoms withing some cut-off radius, r_cut. Everything is contained within the namespace fly::neigh.

Lists#

File: libfly/neigh/list.hpp

Classes to build and update neighbour lists.

class List#

A class to contain, build and manage neighbour lists in shared memory.

Neighbour-lists are used to find the atoms within some cut-off of all atoms efficiently. The cache efficiency of all List’s major operations can be enhances by pre-sorting the atoms according to their grid index, this can be done with the fly::neigh::sort() function.

Designed with the intention of being reused; List separates the building, updating and using of the neighbour-lists, performed by List::rebuild(), List::update() and List::for_neighbours() respectively.

List resolves periodicity using ghost atoms, these are stored and managed internally.

Implementation notes

Construction of a neighbour-list occurs as follows:

  1. Real atoms are mapped into the canonical cell.

  2. Ghost atoms are generated.

  3. All atoms are linked into lists of atoms in the same grid-cell.

  4. Iterating over all adjacent grid-cells the neighbour-lists or real atoms are built.

The neighbour-lists contain the indexes of the real or ghost atoms. Alongside each atom we store the index of the real atom it may be an image of, this allows us to map ghost atoms to real atoms.

Public Functions

inline List(system::Box const &box, double r_cut)#

Construct a new List object.

Parameters:
  • box – The description of the simulation space.

  • r_cut – The neighbour cut-off radius.

template<typename F>
inline auto for_neighbours(Eigen::Index i, double r_cut, F &&f) const -> void#

Call f(n, r, dr) for every neighbour of atom i within cut-off r_cut.

An example to count the average number of neighbours:

#include "libfly/neigh/list.hpp"

#include "libfly/system/property.hpp"
#include "libfly/system/supercell.hpp"
#include "libfly/system/typemap.hpp"
#include "libfly/utility/core.hpp"

#define MU [[maybe_unused]]  // Silence unused variable warning.

namespace fs = fly::system;

void example_list(fs::Supercell<fs::TypeMap<>, fly::Position> const& cell) {
  //
  constexpr double r_cut = 0.5;

  fly::neigh::List nl(cell.box(), r_cut);

  int sum = 0;

  for (int i = 0; i < nl.size(); i++) {
    nl.for_neighbours(i, r_cut, [&](MU auto n, MU auto r, MU auto const& dr) {
      // Here "n"  is the index of the neighbour,
      //      "r"  is the minimum-image (MI) distance to "n" and
      //      "dr" is the position vector connecting "i" to the MI of "n".

      sum += 1;
    });
  }

  // Average number of neighbours is sum / nl.size() //
}

Pre:

List::rebuild() must have be called.

Parameters:
  • i – The index of the atom whose neighbours will be iterated over.

  • r_cut – The neighbour cut-off.

  • f – The functor with signature f : Eigen::Index, double, fly::Vec -> void.

auto rebuild(system::SoA<Position const&> positions, int num_threads = 1) -> void#

Builds the internal neighbour-lists.

Parameters:
  • positions – The positions of the atoms.

  • num_threads – The number of (openMP) threads spawned to complete this operation.

inline auto size() const noexcept -> Eigen::Index#

Get the number of real atoms in this neighbour list.

Returns:

The number of real atoms in this List.

auto update(system::SoA<Delta const&> x) -> void#

Update the positions of the real + ghost atoms.

If the positions of the real atoms are stored in the \(3N \times 1\) vector \(r\) then after calling this function:

\[r \gets r - x\]

The ghost atoms are then updated accordingly.

Parameters:

x – The change in the positions of the real atoms.

Public Static Attributes

static constexpr Eigen::Index MAX_GHOST_RATIO = 26#

Control the maximum number of ghosts.

List supports up to MAX_GHOST_RATIO * List::size() ghost atoms.

Friends

friend class ::fly::potential::KIM_API

Sorting#

File: libfly/neigh/sort.hpp

Utility to enhance cache locality for fly::neigh::List.

template<typename ...T>
auto fly::neigh::sort(system::Box const &box, double r_cut, system::SoA<T...> const &soa) -> system::SoA<remove_cref_t<T>...>#

Order the atoms in a SoA according to their grid index.

This improves cache locality for neighbour reduction operations.

Parameters:
  • box – System box that will be used to build the grid.

  • r_cut – Cut of radius for atomic interactions.

  • soa – Input SoA to order.

Returns:

system::SoA<remove_cref_t<T>…> A SoA ordered according to their grid index.