Skip to content

Commit 2eea0c0

Browse files
committed
Step 1: everything passes the testsuite
1 parent 8c90c3d commit 2eea0c0

File tree

6 files changed

+202
-129
lines changed

6 files changed

+202
-129
lines changed

src/core/collision.cpp

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ Particle &get_part(CellStructure &cell_structure, int id) {
7474
return *p;
7575
}
7676
} // namespace
77-
78-
void CollisionDetection::initialize() {
77+
namespace Collision {
78+
void MergedProtocol::initialize(BondedInteractionsMap &bonded_ias, InteractionsNonBonded &nonbonded_ias) {
7979
// If mode is OFF, no further checks
8080
if (mode == CollisionModeType::OFF) {
8181
return;
@@ -111,10 +111,6 @@ void CollisionDetection::initialize() {
111111
}
112112
#endif
113113

114-
auto &system = get_system();
115-
auto &bonded_ias = *system.bonded_ias;
116-
auto &nonbonded_ias = *system.nonbonded_ias;
117-
118114
// Check if bond exists
119115
assert(mode != CollisionModeType::BIND_CENTERS or
120116
bonded_ias.contains(bond_centers));
@@ -172,15 +168,14 @@ void CollisionDetection::initialize() {
172168
nonbonded_ias.make_particle_type_exist(part_type_after_glueing);
173169
}
174170

175-
system.on_short_range_ia_change();
176171
}
177-
172+
}
178173
/** @brief Calculate position of vs for GLUE_TO_SURFACE mode.
179174
* Returns id of particle to bind vs to.
180175
*/
181176
static auto const &glue_to_surface_calc_vs_pos(
182177
Particle const &p1, Particle const &p2, BoxGeometry const &box_geo,
183-
CollisionDetection const &collision_params, Utils::Vector3d &pos) {
178+
Collision::MergedProtocol const &collision_params, Utils::Vector3d &pos) {
184179
double ratio;
185180
auto const vec21 = box_geo.get_mi_vector(p1.pos(), p2.pos());
186181
auto const dist = vec21.norm();
@@ -204,7 +199,7 @@ static auto const &glue_to_surface_calc_vs_pos(
204199

205200
static void bind_at_point_of_collision_calc_vs_pos(
206201
Particle const &p1, Particle const &p2, BoxGeometry const &box_geo,
207-
CollisionDetection const &collision_params, Utils::Vector3d &pos1,
202+
Collision::MergedProtocol const &collision_params, Utils::Vector3d &pos1,
208203
Utils::Vector3d &pos2) {
209204
auto const vec21 = box_geo.get_mi_vector(p1.pos(), p2.pos());
210205
pos1 = p1.pos() - vec21 * collision_params.vs_placement;
@@ -214,7 +209,7 @@ static void bind_at_point_of_collision_calc_vs_pos(
214209
#ifdef VIRTUAL_SITES_RELATIVE
215210
static void place_vs_and_relate_to_particle(
216211
CellStructure &cell_structure, BoxGeometry const &box_geo,
217-
CollisionDetection const &collision_params, double const min_global_cut,
212+
Collision::MergedProtocol const &collision_params, double const min_global_cut,
218213
int const current_vs_pid, Utils::Vector3d const &pos, int const relate_to) {
219214
Particle new_part;
220215
new_part.id() = current_vs_pid;
@@ -227,7 +222,7 @@ static void place_vs_and_relate_to_particle(
227222

228223
static void bind_at_poc_create_bond_between_vs(
229224
CellStructure &cell_structure, BondedInteractionsMap const &bonded_ias,
230-
CollisionDetection const &collision_params, int const current_vs_pid,
225+
Collision::MergedProtocol const &collision_params, int const current_vs_pid,
231226
CollisionPair const &c) {
232227
switch (number_of_partners(*bonded_ias.at(collision_params.bond_vs))) {
233228
case 1: {
@@ -253,7 +248,7 @@ static void bind_at_poc_create_bond_between_vs(
253248

254249
static void glue_to_surface_bind_part_to_vs(
255250
Particle const *const p1, Particle const *const p2,
256-
int const vs_pid_plus_one, CollisionDetection const &collision_params,
251+
int const vs_pid_plus_one, Collision::MergedProtocol const &collision_params,
257252
CellStructure &cell_structure) {
258253
// Create bond between the virtual particles
259254
const int bondG[] = {vs_pid_plus_one - 1};
@@ -281,6 +276,17 @@ static auto gather_collision_queue(std::vector<CollisionPair> const &local) {
281276
}
282277

283278
void CollisionDetection::handle_collisions(CellStructure &cell_structure) {
279+
auto &system = get_system();
280+
auto const &box_geo = *system.box_geo;
281+
auto const min_global_cut = system.get_min_global_cut();
282+
auto update_propagations = m_protocol->handle_collisions(cell_structure, box_geo, min_global_cut, *system.bonded_ias, local_collision_queue);
283+
if (update_propagations) {
284+
system.update_used_propagations();
285+
}
286+
clear_queue();
287+
}
288+
289+
bool Collision::MergedProtocol::handle_collisions(CellStructure &cell_structure, BoxGeometry const &box_geo, double min_global_cut, BondedInteractionsMap const &bonded_ias, std::vector<CollisionPair> &local_collision_queue) {
284290
// Note that the glue to surface mode adds bonds between the centers
285291
// but does so later in the process. This is needed to guarantee that
286292
// a particle can only be glued once, even if queued twice in a single
@@ -301,9 +307,6 @@ void CollisionDetection::handle_collisions(CellStructure &cell_structure) {
301307
}
302308

303309
#ifdef VIRTUAL_SITES_RELATIVE
304-
auto &system = get_system();
305-
auto const &box_geo = *system.box_geo;
306-
auto const min_global_cut = system.get_min_global_cut();
307310
if ((mode == CollisionModeType::BIND_VS) ||
308311
(mode == CollisionModeType::GLUE_TO_SURF)) {
309312
// Gather the global collision queue, because only one node has a collision
@@ -387,7 +390,7 @@ void CollisionDetection::handle_collisions(CellStructure &cell_structure) {
387390
current_vs_pid++;
388391
// Create bonds between the vs.
389392

390-
bind_at_poc_create_bond_between_vs(cell_structure, *system.bonded_ias,
393+
bind_at_poc_create_bond_between_vs(cell_structure,bonded_ias,
391394
*this, current_vs_pid, c);
392395
} // mode VS
393396

@@ -455,11 +458,19 @@ void CollisionDetection::handle_collisions(CellStructure &cell_structure) {
455458
cell_structure.update_ghosts_and_resort_particle(
456459
Cells::DATA_PART_PROPERTIES | Cells::DATA_PART_BONDS);
457460
}
458-
system.update_used_propagations();
461+
return true;
459462
} // are we in one of the vs_based methods
460463
#endif // defined VIRTUAL_SITES_RELATIVE
461-
462-
clear_queue();
464+
return false;
463465
}
464466

467+
void CollisionDetection::initialize() {
468+
auto &system = get_system();
469+
auto &bonded_ias = *system.bonded_ias;
470+
auto &nonbonded_ias = *system.nonbonded_ias;
471+
m_protocol->initialize(bonded_ias, nonbonded_ias);
472+
system.on_short_range_ia_change();
473+
}
474+
475+
465476
#endif // COLLISION_DETECTION

src/core/collision.hpp

Lines changed: 13 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@
2020
#pragma once
2121

2222
#include "config/config.hpp"
23-
23+
#include "collision/protocols.hpp"
2424
#include "BondList.hpp"
2525
#include "Particle.hpp"
2626
#include "cell_system/CellStructure.hpp"
2727
#include "nonbonded_interactions/nonbonded_interaction_data.hpp"
2828
#include "system/Leaf.hpp"
2929

30+
#include <memory>
31+
3032
/** @brief Protocols for collision handling. */
3133
enum class CollisionModeType : int {
3234
/** @brief Deactivate collision detection. */
@@ -51,51 +53,19 @@ struct CollisionPair {
5153
};
5254

5355
class CollisionDetection : public System::Leaf<CollisionDetection> {
56+
public: //private: TODO make private again!
57+
std::shared_ptr<Collision::MergedProtocol> m_protocol;
58+
bool m_off;
5459
public:
55-
CollisionDetection()
56-
: mode(CollisionModeType::OFF), distance(0.), distance_sq(0.),
57-
bond_centers(-1), bond_vs(-1) {}
58-
59-
/// collision protocol
60-
CollisionModeType mode;
61-
/// distance at which particles are bound
62-
double distance;
63-
// Square of distance at which particle are bound
64-
double distance_sq;
65-
66-
/// bond type used between centers of colliding particles
67-
int bond_centers;
68-
/// bond type used between virtual sites
69-
int bond_vs;
70-
/// particle type for virtual sites created on collision
71-
int vs_particle_type;
72-
73-
/// For mode "glue to surface": The distance from the particle which is to be
74-
/// glued to the new virtual site
75-
double dist_glued_part_to_vs;
76-
/// For mode "glue to surface": The particle type being glued
77-
int part_type_to_be_glued;
78-
/// For mode "glue to surface": The particle type to which the virtual site is
79-
/// attached
80-
int part_type_to_attach_vs_to;
81-
/// Particle type to which the newly glued particle is converted
82-
int part_type_after_glueing;
83-
/** Placement of virtual sites for MODE_VS.
84-
* 0=on same particle as related to,
85-
* 1=on collision partner,
86-
* 0.5=in the middle between
87-
*/
88-
double vs_placement;
60+
61+
CollisionDetection():m_protocol{std::make_shared<Collision::MergedProtocol>()}{}
8962

9063
/** @brief Validates parameters and creates particle types if needed. */
9164
void initialize();
9265

93-
auto cutoff() const {
94-
if (mode != CollisionModeType::OFF) {
95-
return distance;
96-
}
97-
return INACTIVE_CUTOFF;
98-
}
66+
auto is_off() const { return m_off; }
67+
68+
auto cutoff() const { return m_protocol->cutoff(); }
9969

10070
/// Handle queued collisions
10171
void handle_collisions(CellStructure &cell_structure);
@@ -105,34 +75,8 @@ class CollisionDetection : public System::Leaf<CollisionDetection> {
10575
/** @brief Detect (and queue) a collision between the given particles. */
10676
void detect_collision(Particle const &p1, Particle const &p2,
10777
double const dist_sq) {
108-
if (dist_sq > distance_sq)
109-
return;
110-
111-
// If we are in the glue to surface mode, check that the particles
112-
// are of the right type
113-
if (mode == CollisionModeType::GLUE_TO_SURF)
114-
if (!glue_to_surface_criterion(p1, p2))
115-
return;
116-
117-
// Ignore virtual particles
118-
if (p1.is_virtual() or p2.is_virtual())
119-
return;
120-
121-
// Check, if there's already a bond between the particles
122-
if (pair_bond_exists_on(p1.bonds(), p2.id(), bond_centers))
123-
return;
124-
125-
if (pair_bond_exists_on(p2.bonds(), p1.id(), bond_centers))
126-
return;
127-
128-
/* If we're still here, there is no previous bond between the particles,
129-
we have a new collision */
130-
131-
// do not create bond between ghost particles
132-
if (p1.is_ghost() and p2.is_ghost()) {
133-
return;
134-
}
135-
local_collision_queue.push_back({p1.id(), p2.id()});
78+
if (m_protocol->detect_collision(p1, p2, dist_sq))
79+
local_collision_queue.push_back({p1.id(), p2.id()});
13680
}
13781

13882
// private:
@@ -141,11 +85,4 @@ class CollisionDetection : public System::Leaf<CollisionDetection> {
14185
/// particles.
14286
std::vector<CollisionPair> local_collision_queue;
14387

144-
/** @brief Check additional criteria for the glue_to_surface collision mode */
145-
bool glue_to_surface_criterion(Particle const &p1, Particle const &p2) const {
146-
return (((p1.type() == part_type_to_be_glued) and
147-
(p2.type() == part_type_to_attach_vs_to)) or
148-
((p2.type() == part_type_to_be_glued) and
149-
(p1.type() == part_type_to_attach_vs_to)));
150-
}
15188
};

src/core/collision/protocols.hpp

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#pragma once
2+
3+
#include <config/config.hpp>
4+
5+
#ifdef COLLISION_DETECTION
6+
7+
#include "nonbonded_interactions/nonbonded_interaction_data.hpp"
8+
#include "bonded_interactions/bonded_interaction_data.hpp"
9+
10+
11+
struct CollisionPair;
12+
13+
namespace Collision{
14+
enum class CollisionModeType : int {
15+
/** @brief Deactivate collision detection. */
16+
OFF = 0,
17+
/** @brief Create bond between centers of colliding particles. */
18+
BIND_CENTERS = 1,
19+
/**
20+
* @brief Create a bond between the centers of the colliding particles,
21+
* plus two virtual sites at the point of collision and bind them
22+
* together. This prevents the particles from sliding against each
23+
* other. Requires VIRTUAL_SITES_RELATIVE.
24+
*/
25+
BIND_VS = 2,
26+
/** @brief Glue a particle to a specific spot on another particle. */
27+
GLUE_TO_SURF = 3,
28+
};
29+
30+
class MergedProtocol {
31+
public:
32+
MergedProtocol()
33+
: mode(CollisionModeType::OFF), distance(0.), distance_sq(0.),
34+
bond_centers(-1), bond_vs(-1) {}
35+
36+
/// collision protocol
37+
CollisionModeType mode;
38+
/// distance at which particles are bound
39+
double distance;
40+
// Square of distance at which particle are bound
41+
double distance_sq;
42+
43+
/// bond type used between centers of colliding particles
44+
int bond_centers;
45+
/// bond type used between virtual sites
46+
int bond_vs;
47+
/// particle type for virtual sites created on collision
48+
int vs_particle_type;
49+
50+
/// For mode "glue to surface": The distance from the particle which is to be
51+
/// glued to the new virtual site
52+
double dist_glued_part_to_vs;
53+
/// For mode "glue to surface": The particle type being glued
54+
int part_type_to_be_glued;
55+
/// For mode "glue to surface": The particle type to which the virtual site is
56+
/// attached
57+
int part_type_to_attach_vs_to;
58+
/// Particle type to which the newly glued particle is converted
59+
int part_type_after_glueing;
60+
/** Placement of virtual sites for MODE_VS.
61+
* 0=on same particle as related to,
62+
* 1=on collision partner,
63+
* 0.5=in the middle between
64+
*/
65+
double vs_placement;
66+
/** @brief Validates parameters and creates particle types if needed. */
67+
void initialize(BondedInteractionsMap &bonded_ias, InteractionsNonBonded &nonbonded_ias);
68+
69+
auto cutoff() const {
70+
if (mode != CollisionModeType::OFF) {
71+
return distance;
72+
}
73+
return INACTIVE_CUTOFF;
74+
}
75+
76+
/// Handle queued collisions
77+
bool handle_collisions(CellStructure &cell_structure, BoxGeometry const &box_geo, double min_global_cut, BondedInteractionsMap const &bonded_ias, std::vector<CollisionPair> &local_collision_queue);
78+
79+
/** @brief Detect (and queue) a collision between the given particles. */
80+
bool detect_collision(Particle const &p1, Particle const &p2,
81+
double const dist_sq) {
82+
if (dist_sq > distance_sq)
83+
return false;
84+
85+
// If we are in the glue to surface mode, check that the particles
86+
// are of the right type
87+
if (mode == CollisionModeType::GLUE_TO_SURF)
88+
if (!glue_to_surface_criterion(p1, p2))
89+
return false;
90+
91+
// Ignore virtual particles
92+
if (p1.is_virtual() or p2.is_virtual())
93+
return false;
94+
95+
// Check, if there's already a bond between the particles
96+
if (pair_bond_exists_on(p1.bonds(), p2.id(), bond_centers))
97+
return false;
98+
99+
if (pair_bond_exists_on(p2.bonds(), p1.id(), bond_centers))
100+
return false;
101+
102+
/* If we're still here, there is no previous bond between the particles,
103+
we have a new collision */
104+
105+
// do not create bond between ghost particles
106+
if (p1.is_ghost() and p2.is_ghost()) {
107+
return false;
108+
}
109+
return true;
110+
}
111+
112+
/** @brief Check additional criteria for the glue_to_surface collision mode */
113+
bool glue_to_surface_criterion(Particle const &p1, Particle const &p2) const {
114+
return (((p1.type() == part_type_to_be_glued) and
115+
(p2.type() == part_type_to_attach_vs_to)) or
116+
((p2.type() == part_type_to_be_glued) and
117+
(p1.type() == part_type_to_attach_vs_to)));
118+
}
119+
120+
};
121+
}
122+
123+
#endif // COLLISION_DETECTION

src/core/forces.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ void System::System::calculate_forces() {
197197
coulomb_kernel_ptr, dipoles_kernel_ptr,
198198
elc_kernel_ptr);
199199
#ifdef COLLISION_DETECTION
200-
if (collision_detection.mode != CollisionModeType::OFF) {
200+
if (not collision_detection.is_off()) {
201201
collision_detection.detect_collision(p1, p2, d.dist2);
202202
}
203203
#endif

0 commit comments

Comments
 (0)