22#ifdef COLLISION_DETECTION
31#include "system/System.hpp"
40#include <boost/mpi/collectives.hpp>
41#include <boost/serialization/serialization.hpp>
58namespace serialization {
59template <
typename Archive>
80 throw std::runtime_error(
"Could not handle collision because particle " +
81 std::to_string(
id) +
" was not found.");
112 throw std::domain_error(
"Parameter 'distance' must be > 0");
119#ifndef VIRTUAL_SITES_RELATIVE
125 throw std::runtime_error(
"collision modes based on virtual sites require "
126 "the VIRTUAL_SITES_RELATIVE feature");
135 throw std::domain_error(
136 "Parameter 'vs_placement' must be between 0 and 1");
142 auto &nonbonded_ias = *system.nonbonded_ias;
147 throw std::runtime_error(
148 "Bond in parameter 'bond_centers' was not added to the system");
153 throw std::runtime_error(
154 "Bond in parameter 'bond_vs' was not added to the system");
161 throw std::runtime_error(
"The bond type to be used for binding particle "
162 "centers needs to be a pair bond");
169 throw std::runtime_error(
"The bond type to be used for binding virtual "
170 "sites needs to be a pair or three-particle bond");
177 throw std::runtime_error(
178 "Insufficient bonds defined for three particle binding");
186 throw std::runtime_error(
187 "The bonds for three particle binding need to be angle bonds.");
196 throw std::domain_error(
"Collision detection particle type for virtual "
197 "sites needs to be >=0");
204 throw std::domain_error(
"Collision detection particle type for virtual "
205 "sites needs to be >=0");
210 throw std::domain_error(
"Collision detection particle type to be glued "
213 nonbonded_ias.make_particle_type_exist(
217 throw std::domain_error(
"Collision detection particle type to attach "
218 "the virtual site to needs to be >=0");
220 nonbonded_ias.make_particle_type_exist(
224 throw std::domain_error(
"Collision detection particle type after gluing "
227 nonbonded_ias.make_particle_type_exist(
231 system.on_short_range_ia_change();
249 auto const dist = vec21.norm();
259 throw std::runtime_error(
"This should never be thrown. Bug.");
261 pos = p2.
pos() + vec21 * c;
298 auto is_collision_bond = [](
BondView const &bond) {
305 auto has_same_partners = [id1 = p1.
id(),
307 auto const partner_ids = bond.partner_ids();
309 return ((partner_ids[0] == id1) and (partner_ids[1] == id2)) or
310 ((partner_ids[0] == id2) and (partner_ids[1] == id1));
313 auto const &bonds = p.
bonds();
314 if (std::any_of(bonds.begin(), bonds.end(), [=](
auto const &bond) {
315 return is_collision_bond(bond) and has_same_partners(bond);
331 auto const phi = acos(cosine);
336 auto const bond_id =
static_cast<int>(
342 const std::array<int, 2> bondT = {{p1.
id(), p2.
id()}};
343 p.
bonds().insert({bond_id, bondT});
346#ifdef VIRTUAL_SITES_RELATIVE
349 double const min_global_cut,
350 int const current_vs_pid,
352 int const relate_to) {
354 new_part.id() = current_vs_pid;
355 new_part.pos() =
pos;
356 auto p_vs = cell_structure.
add_particle(std::move(new_part));
363 int const current_vs_pid,
368 const int bondG[] = {current_vs_pid - 2};
376 const int bondG[] = {c.
pp1, c.
pp2};
389 int const vs_pid_plus_one,
393 const int bondG[] = {vs_pid_plus_one - 1};
420 auto handle_cell = [&p1, &p2, &box_geo](
Cell *c) {
421 for (
auto &p : c->particles()) {
423 if ((p.id() == p1.
id()) or (p.id() == p2.
id())) {
447 handle_cell(basecell);
460 std::vector<CollisionPair>
const &gathered_queue) {
462 for (
auto &c : gathered_queue) {
474 if (cell2 and cell1 != cell2)
484 auto const &box_geo = *system.box_geo;
493 std::swap(c.pp1, c.pp2);
496 const int bondG[] = {c.pp2};
505#ifdef VIRTUAL_SITES_RELATIVE
506 auto const min_global_cut = system.get_min_global_cut();
516 auto const global_max_seen_particle = boost::mpi::all_reduce(
518 boost::mpi::maximum<int>());
520 int current_vs_pid = global_max_seen_particle + 1;
523 for (
auto &c : gathered_queue) {
571 min_global_cut, current_vs_pid,
582 handle_particle(p1, pos1);
586 handle_particle(p2, pos2);
615 const int bondG[] = {c.pp2};
632 min_global_cut, current_vs_pid,
pos,
647#ifdef ADDITIONAL_CHECKS
649 throw std::runtime_error(
"Nodes disagree about current_vs_pid");
654 if (!gathered_queue.empty()) {
659 system.update_used_propagations();
Vector implementation and trait types for boost qvm interoperability.
__shared__ int pos[MAXDEPTH *THREADS5/WARPSIZE]
BondedInteractionsMap bonded_ia_params
Field containing the parameters of the bonded ia types.
Data structures for bonded interactions.
int number_of_partners(Bonded_IA_Parameters const &iaparams)
Return the number of bonded partners for the specified bond.
Immutable view on a bond.
mapped_type at(key_type const &key) const
bool contains(key_type const &key) const
Utils::Vector< T, 3 > get_mi_vector(const Utils::Vector< T, 3 > &a, const Utils::Vector< T, 3 > &b) const
Get the minimum-image vector between two coordinates.
neighbors_type & neighbors()
All neighbors of the cell.
int part_type_after_glueing
Particle type to which the newly glued particle is converted.
void initialize()
Validates parameters and creates particle types if needed.
int part_type_to_be_glued
For mode "glue to surface": The particle type being glued.
double vs_placement
Placement of virtual sites for MODE_VS.
int bond_centers
bond type used between centers of colliding particles
CollisionModeType mode
collision protocol
int three_particle_angle_resolution
Number of angle bonds to use (angular resolution) different angle bonds with different equilibrium an...
int part_type_to_attach_vs_to
For mode "glue to surface": The particle type to which the virtual site is attached.
double dist_glued_part_to_vs
For mode "glue to surface": The distance from the particle which is to be glued to the new virtual si...
int bond_three_particles
First bond type (for zero degrees) used for the three-particle bond (angle potential)
double distance
distance at which particles are bound
int bond_vs
bond type used between virtual sites
int vs_particle_type
particle type for virtual sites created on collision
cell_range all()
All neighbors.
static void coldet_do_three_particle_bond(Particle &p, Particle const &p1, Particle const &p2, BoxGeometry const &box_geo)
static void place_vs_and_relate_to_particle(CellStructure &cell_structure, BoxGeometry const &box_geo, double const min_global_cut, int const current_vs_pid, Utils::Vector3d const &pos, int const relate_to)
void prepare_local_collision_queue()
void queue_collision(const int part1, const int part2)
Add the collision between the given particle ids to the collision queue.
static bool bind_centers()
Return true if a bond between the centers of the colliding particles needs to be placed.
static void three_particle_binding_domain_decomposition(CellStructure &cell_structure, BoxGeometry const &box_geo, std::vector< CollisionPair > const &gathered_queue)
static void three_particle_binding_do_search(Cell *basecell, Particle &p1, Particle &p2, BoxGeometry const &box_geo)
std::vector< CollisionPair > gather_global_collision_queue()
static std::vector< CollisionPair > local_collision_queue
During force calculation, colliding particles are recorded in the queue. The queue is processed after...
void handle_collisions(CellStructure &cell_structure)
Handle the collisions recorded in the queue.
static auto const & glue_to_surface_calc_vs_pos(Particle const &p1, Particle const &p2, BoxGeometry const &box_geo, Utils::Vector3d &pos)
Calculate position of vs for GLUE_TO_SURFACE mode.
static void glue_to_surface_bind_part_to_vs(Particle const *const p1, Particle const *const p2, int const vs_pid_plus_one, CollisionPair const &, CellStructure &cell_structure)
static int get_bond_num_partners(int bond_id)
Collision_parameters collision_params
Parameters for collision detection.
static void bind_at_poc_create_bond_between_vs(CellStructure &cell_structure, int const current_vs_pid, CollisionPair const &c)
static void bind_at_point_of_collision_calc_vs_pos(Particle const &p1, Particle const &p2, BoxGeometry const &box_geo, Utils::Vector3d &pos1, Utils::Vector3d &pos2)
@ BIND_CENTERS
Create bond between centers of colliding particles.
@ GLUE_TO_SURF
Glue a particle to a specific spot on another particle.
@ OFF
Deactivate collision detection.
@ BIND_THREE_PARTICLES
Three particle binding mode.
@ BIND_VS
Create a bond between the centers of the colliding particles, plus two virtual sites at the point of ...
Collision_parameters collision_params
Parameters for collision detection.
boost::mpi::communicator comm_cart
The communicator.
#define TINY_COS_VALUE
Tiny angle cutoff for cosine calculations.
This file contains the errorhandling code for severe errors, like a broken bond or illegal parameter ...
@ DATA_PART_PROPERTIES
Particle::p.
@ DATA_PART_BONDS
Particle::bonds.
bool all_compare(boost::mpi::communicator const &comm, T const &value)
Compare values on all nodes.
void gather_buffer(std::vector< T, Allocator > &buffer, boost::mpi::communicator const &comm, int root=0)
Gather buffer with different size on each node.
DEVICE_QUALIFIER constexpr T pi()
Ratio of diameter and circumference of a circle.
DEVICE_QUALIFIER constexpr T sqr(T x)
Calculates the SQuaRe of x.
Particle & get_part(CellStructure &cell_structure, int id)
void serialize(Archive &ar, std::tuple< T... > &pack, unsigned int const)
Serialize std::tuple.
Various procedures concerning interactions between particles.
Describes a cell structure / cell system.
Particle * get_local_particle(int id)
Get a local particle by id.
Cell * find_current_cell(const Particle &p)
Find cell a particle is stored in.
void update_ghosts_and_resort_particle(unsigned data_parts)
Update ghost particles, with particle resort if needed.
void set_resort_particles(Cells::Resort level)
Increase the local resort level at least to level.
Particle * add_particle(Particle &&p)
Add a particle.
int get_max_local_particle_id() const
Get the maximal particle id on this node.
Data type holding the info about a single collision.
Struct holding all information for one particle.
auto const & type() const
auto const & bonds() const
void set_can_rotate_all_axes()
void vs_relate_to(Particle &p_vs, Particle const &p_relate_to, BoxGeometry const &box_geo, double min_global_cut)
Setup a virtual site to track a real particle.