Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Efficient search for interacting particles #4399

Closed
RudolfWeeber opened this issue Dec 6, 2021 · 2 comments · Fixed by #4401
Closed

Efficient search for interacting particles #4399

RudolfWeeber opened this issue Dec 6, 2021 · 2 comments · Fixed by #4401

Comments

@RudolfWeeber
Copy link
Contributor

RudolfWeeber commented Dec 6, 2021

Currently the search for (short-range) interacting particles, e.g., in the reaction ensemble, is n-square, as all other particles in the system are considered. This is not necessary when the cell system is a regular domain decomposition.

Objectives:

  • Provide a function template in CellStructure that can execute a given kernel function on all particles within the short-range interaction range of a given particle p.
  • Using that, implement a kernel that collects the ids of the particles in the neighborhood of p.
  • In the same way, implement a kernel calculating the short range energy contribution of a particle with its neighbors
  • Implement python interface functions for those two cases

Implement CellStructure::run_on_particle_short_range_neighbors

This should take a kernel and a particle, i.e.,

template <typename Kernel> 
bool run_on_particle_short_range_neighbors(const Particle& p) 

Steps:

  • Identify the cell in which the particle is stored using particle_to_cell (It might be necessary to use the position at the last resort, which is also in p.r).
  • If a nullptr is returned, the particle should not be on the mpi rank. Return false
  • For the returned cell:
    • iterate over the particles in the cell itself (cell.particles()
    • Iterate over neighboring cells, both in in red_neighbors and black_neighbors (see Cell.hpp). Iterate over the particles in those neighboring cells
    • For all these particles, except p itself (compare using addresses, not values), run kernel(p)
  • Return true

Implement get_short_range_neighbors(const Particle& p) in cells.cpp/hpp

  • Initialize a std::vector<int> to store the particle ids.
  • As kernel, to CellStrucutre.run_on_particle_short_range_neighbors(), use a lambda [&result_vector](const Particle& p) which appends the particle id to the result vector. See the get_pairs code in cells.cpp for inspiration

Implement particle_short_range_energy_contribution(const Particle& p) in energy.cpp/hpp

Same as above, but

  • use a double as result type
  • Capture the Particle p in the lambda [&result, &p](const Particle& q)
  • In the lamdba, add the pair energy provided by add_non_bonded_pair_energy() (energy_inline.hpp) to the result

Python interface

  • You need the head node function called from cython mpi_...
  • The callback function (which should return a boost::optional)
  • Register the callback via REGISTER_CALLBACK
  • The callbacks should be declares such that a result from exactly one mpi rank is expected.
    See get_particle_data_local, corresponding REGISTER_CALLBACK_ONE_RANK and the mpi call in get_particle_data() (below where it says "cache miss") FOR INSPIRATION
@RudolfWeeber
Copy link
Contributor Author

@stekajack @jhossbach @pm-blanco If you like, you can work on this, tomorrow.

@stekajack
Copy link
Contributor

I can tinker with this, but probably don't manage to get to it today.

@kodiakhq kodiakhq bot closed this as completed in #4401 May 19, 2022
kodiakhq bot added a commit that referenced this issue May 19, 2022
Fixes #4399, fixes #4438

Description of changes:
- `CellStructure.cpp`: Added the `CellStructure::run_on_particle_short_range_neighbors()` method which runs a kernel function over all particles inside the cell and its neighbors of a given particle
- `cells.hpp`: Added the `mpi_get_short_range_neighbors()` function to execute a parallel search
   - can be called from the Python interface via `system.cell_system.get_neighbors.get_neighbors(p, distance)`
- `energy.hpp`: Added the `compute_non_bonded_pair_energy()` function which returns both the short-range Coulomb interactions plus the non-bonded energy contributions  of two particles
   - can be called from the Python interface via `system.analysis.particle_energy(p)`
- Reaction methods can use the new neighbor search algorithm with constructor argument `search_algorithm="parallel"` (default is `search_algorithm="order_n"`); on 1 MPI rank the original order N algorithm is faster since the parallel algorithm introduces some overhead due to the ghost update (this overhead is negligible with 2 or more MPI ranks)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants