Skip to content

Commit

Permalink
Step 1: everything passes the testsuite
Browse files Browse the repository at this point in the history
  • Loading branch information
1234somesh committed Aug 9, 2024
1 parent 8c90c3d commit 2eea0c0
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 129 deletions.
51 changes: 31 additions & 20 deletions src/core/collision.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ Particle &get_part(CellStructure &cell_structure, int id) {
return *p;
}
} // namespace

void CollisionDetection::initialize() {
namespace Collision {
void MergedProtocol::initialize(BondedInteractionsMap &bonded_ias, InteractionsNonBonded &nonbonded_ias) {
// If mode is OFF, no further checks
if (mode == CollisionModeType::OFF) {
return;
Expand Down Expand Up @@ -111,10 +111,6 @@ void CollisionDetection::initialize() {
}
#endif

auto &system = get_system();
auto &bonded_ias = *system.bonded_ias;
auto &nonbonded_ias = *system.nonbonded_ias;

// Check if bond exists
assert(mode != CollisionModeType::BIND_CENTERS or
bonded_ias.contains(bond_centers));
Expand Down Expand Up @@ -172,15 +168,14 @@ void CollisionDetection::initialize() {
nonbonded_ias.make_particle_type_exist(part_type_after_glueing);
}

system.on_short_range_ia_change();
}

}
/** @brief Calculate position of vs for GLUE_TO_SURFACE mode.
* Returns id of particle to bind vs to.
*/
static auto const &glue_to_surface_calc_vs_pos(
Particle const &p1, Particle const &p2, BoxGeometry const &box_geo,
CollisionDetection const &collision_params, Utils::Vector3d &pos) {
Collision::MergedProtocol const &collision_params, Utils::Vector3d &pos) {
double ratio;
auto const vec21 = box_geo.get_mi_vector(p1.pos(), p2.pos());
auto const dist = vec21.norm();
Expand All @@ -204,7 +199,7 @@ static auto const &glue_to_surface_calc_vs_pos(

static void bind_at_point_of_collision_calc_vs_pos(
Particle const &p1, Particle const &p2, BoxGeometry const &box_geo,
CollisionDetection const &collision_params, Utils::Vector3d &pos1,
Collision::MergedProtocol const &collision_params, Utils::Vector3d &pos1,
Utils::Vector3d &pos2) {
auto const vec21 = box_geo.get_mi_vector(p1.pos(), p2.pos());
pos1 = p1.pos() - vec21 * collision_params.vs_placement;
Expand All @@ -214,7 +209,7 @@ static void bind_at_point_of_collision_calc_vs_pos(
#ifdef VIRTUAL_SITES_RELATIVE
static void place_vs_and_relate_to_particle(
CellStructure &cell_structure, BoxGeometry const &box_geo,
CollisionDetection const &collision_params, double const min_global_cut,
Collision::MergedProtocol const &collision_params, double const min_global_cut,
int const current_vs_pid, Utils::Vector3d const &pos, int const relate_to) {
Particle new_part;
new_part.id() = current_vs_pid;
Expand All @@ -227,7 +222,7 @@ static void place_vs_and_relate_to_particle(

static void bind_at_poc_create_bond_between_vs(
CellStructure &cell_structure, BondedInteractionsMap const &bonded_ias,
CollisionDetection const &collision_params, int const current_vs_pid,
Collision::MergedProtocol const &collision_params, int const current_vs_pid,
CollisionPair const &c) {
switch (number_of_partners(*bonded_ias.at(collision_params.bond_vs))) {
case 1: {
Expand All @@ -253,7 +248,7 @@ static void bind_at_poc_create_bond_between_vs(

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

void CollisionDetection::handle_collisions(CellStructure &cell_structure) {
auto &system = get_system();
auto const &box_geo = *system.box_geo;
auto const min_global_cut = system.get_min_global_cut();
auto update_propagations = m_protocol->handle_collisions(cell_structure, box_geo, min_global_cut, *system.bonded_ias, local_collision_queue);
if (update_propagations) {
system.update_used_propagations();
}
clear_queue();
}

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) {
// Note that the glue to surface mode adds bonds between the centers
// but does so later in the process. This is needed to guarantee that
// a particle can only be glued once, even if queued twice in a single
Expand All @@ -301,9 +307,6 @@ void CollisionDetection::handle_collisions(CellStructure &cell_structure) {
}

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

bind_at_poc_create_bond_between_vs(cell_structure, *system.bonded_ias,
bind_at_poc_create_bond_between_vs(cell_structure,bonded_ias,
*this, current_vs_pid, c);
} // mode VS

Expand Down Expand Up @@ -455,11 +458,19 @@ void CollisionDetection::handle_collisions(CellStructure &cell_structure) {
cell_structure.update_ghosts_and_resort_particle(
Cells::DATA_PART_PROPERTIES | Cells::DATA_PART_BONDS);
}
system.update_used_propagations();
return true;
} // are we in one of the vs_based methods
#endif // defined VIRTUAL_SITES_RELATIVE

clear_queue();
return false;
}

void CollisionDetection::initialize() {
auto &system = get_system();
auto &bonded_ias = *system.bonded_ias;
auto &nonbonded_ias = *system.nonbonded_ias;
m_protocol->initialize(bonded_ias, nonbonded_ias);
system.on_short_range_ia_change();
}


#endif // COLLISION_DETECTION
89 changes: 13 additions & 76 deletions src/core/collision.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
#pragma once

#include "config/config.hpp"

#include "collision/protocols.hpp"
#include "BondList.hpp"
#include "Particle.hpp"
#include "cell_system/CellStructure.hpp"
#include "nonbonded_interactions/nonbonded_interaction_data.hpp"
#include "system/Leaf.hpp"

#include <memory>

/** @brief Protocols for collision handling. */
enum class CollisionModeType : int {
/** @brief Deactivate collision detection. */
Expand All @@ -51,51 +53,19 @@ struct CollisionPair {
};

class CollisionDetection : public System::Leaf<CollisionDetection> {
public: //private: TODO make private again!
std::shared_ptr<Collision::MergedProtocol> m_protocol;
bool m_off;
public:
CollisionDetection()
: mode(CollisionModeType::OFF), distance(0.), distance_sq(0.),
bond_centers(-1), bond_vs(-1) {}

/// collision protocol
CollisionModeType mode;
/// distance at which particles are bound
double distance;
// Square of distance at which particle are bound
double distance_sq;

/// bond type used between centers of colliding particles
int bond_centers;
/// bond type used between virtual sites
int bond_vs;
/// particle type for virtual sites created on collision
int vs_particle_type;

/// For mode "glue to surface": The distance from the particle which is to be
/// glued to the new virtual site
double dist_glued_part_to_vs;
/// For mode "glue to surface": The particle type being glued
int part_type_to_be_glued;
/// For mode "glue to surface": The particle type to which the virtual site is
/// attached
int part_type_to_attach_vs_to;
/// Particle type to which the newly glued particle is converted
int part_type_after_glueing;
/** Placement of virtual sites for MODE_VS.
* 0=on same particle as related to,
* 1=on collision partner,
* 0.5=in the middle between
*/
double vs_placement;

CollisionDetection():m_protocol{std::make_shared<Collision::MergedProtocol>()}{}

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

auto cutoff() const {
if (mode != CollisionModeType::OFF) {
return distance;
}
return INACTIVE_CUTOFF;
}
auto is_off() const { return m_off; }

auto cutoff() const { return m_protocol->cutoff(); }

/// Handle queued collisions
void handle_collisions(CellStructure &cell_structure);
Expand All @@ -105,34 +75,8 @@ class CollisionDetection : public System::Leaf<CollisionDetection> {
/** @brief Detect (and queue) a collision between the given particles. */
void detect_collision(Particle const &p1, Particle const &p2,
double const dist_sq) {
if (dist_sq > distance_sq)
return;

// If we are in the glue to surface mode, check that the particles
// are of the right type
if (mode == CollisionModeType::GLUE_TO_SURF)
if (!glue_to_surface_criterion(p1, p2))
return;

// Ignore virtual particles
if (p1.is_virtual() or p2.is_virtual())
return;

// Check, if there's already a bond between the particles
if (pair_bond_exists_on(p1.bonds(), p2.id(), bond_centers))
return;

if (pair_bond_exists_on(p2.bonds(), p1.id(), bond_centers))
return;

/* If we're still here, there is no previous bond between the particles,
we have a new collision */

// do not create bond between ghost particles
if (p1.is_ghost() and p2.is_ghost()) {
return;
}
local_collision_queue.push_back({p1.id(), p2.id()});
if (m_protocol->detect_collision(p1, p2, dist_sq))
local_collision_queue.push_back({p1.id(), p2.id()});
}

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

/** @brief Check additional criteria for the glue_to_surface collision mode */
bool glue_to_surface_criterion(Particle const &p1, Particle const &p2) const {
return (((p1.type() == part_type_to_be_glued) and
(p2.type() == part_type_to_attach_vs_to)) or
((p2.type() == part_type_to_be_glued) and
(p1.type() == part_type_to_attach_vs_to)));
}
};
123 changes: 123 additions & 0 deletions src/core/collision/protocols.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#pragma once

#include <config/config.hpp>

#ifdef COLLISION_DETECTION

#include "nonbonded_interactions/nonbonded_interaction_data.hpp"
#include "bonded_interactions/bonded_interaction_data.hpp"


struct CollisionPair;

namespace Collision{
enum class CollisionModeType : int {
/** @brief Deactivate collision detection. */
OFF = 0,
/** @brief Create bond between centers of colliding particles. */
BIND_CENTERS = 1,
/**
* @brief Create a bond between the centers of the colliding particles,
* plus two virtual sites at the point of collision and bind them
* together. This prevents the particles from sliding against each
* other. Requires VIRTUAL_SITES_RELATIVE.
*/
BIND_VS = 2,
/** @brief Glue a particle to a specific spot on another particle. */
GLUE_TO_SURF = 3,
};

class MergedProtocol {
public:
MergedProtocol()
: mode(CollisionModeType::OFF), distance(0.), distance_sq(0.),
bond_centers(-1), bond_vs(-1) {}

/// collision protocol
CollisionModeType mode;
/// distance at which particles are bound
double distance;
// Square of distance at which particle are bound
double distance_sq;

/// bond type used between centers of colliding particles
int bond_centers;
/// bond type used between virtual sites
int bond_vs;
/// particle type for virtual sites created on collision
int vs_particle_type;

/// For mode "glue to surface": The distance from the particle which is to be
/// glued to the new virtual site
double dist_glued_part_to_vs;
/// For mode "glue to surface": The particle type being glued
int part_type_to_be_glued;
/// For mode "glue to surface": The particle type to which the virtual site is
/// attached
int part_type_to_attach_vs_to;
/// Particle type to which the newly glued particle is converted
int part_type_after_glueing;
/** Placement of virtual sites for MODE_VS.
* 0=on same particle as related to,
* 1=on collision partner,
* 0.5=in the middle between
*/
double vs_placement;
/** @brief Validates parameters and creates particle types if needed. */
void initialize(BondedInteractionsMap &bonded_ias, InteractionsNonBonded &nonbonded_ias);

auto cutoff() const {
if (mode != CollisionModeType::OFF) {
return distance;
}
return INACTIVE_CUTOFF;
}

/// Handle queued collisions
bool handle_collisions(CellStructure &cell_structure, BoxGeometry const &box_geo, double min_global_cut, BondedInteractionsMap const &bonded_ias, std::vector<CollisionPair> &local_collision_queue);

/** @brief Detect (and queue) a collision between the given particles. */
bool detect_collision(Particle const &p1, Particle const &p2,
double const dist_sq) {
if (dist_sq > distance_sq)
return false;

// If we are in the glue to surface mode, check that the particles
// are of the right type
if (mode == CollisionModeType::GLUE_TO_SURF)
if (!glue_to_surface_criterion(p1, p2))
return false;

// Ignore virtual particles
if (p1.is_virtual() or p2.is_virtual())
return false;

// Check, if there's already a bond between the particles
if (pair_bond_exists_on(p1.bonds(), p2.id(), bond_centers))
return false;

if (pair_bond_exists_on(p2.bonds(), p1.id(), bond_centers))
return false;

/* If we're still here, there is no previous bond between the particles,
we have a new collision */

// do not create bond between ghost particles
if (p1.is_ghost() and p2.is_ghost()) {
return false;
}
return true;
}

/** @brief Check additional criteria for the glue_to_surface collision mode */
bool glue_to_surface_criterion(Particle const &p1, Particle const &p2) const {
return (((p1.type() == part_type_to_be_glued) and
(p2.type() == part_type_to_attach_vs_to)) or
((p2.type() == part_type_to_be_glued) and
(p1.type() == part_type_to_attach_vs_to)));
}

};
}

#endif // COLLISION_DETECTION
2 changes: 1 addition & 1 deletion src/core/forces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ void System::System::calculate_forces() {
coulomb_kernel_ptr, dipoles_kernel_ptr,
elc_kernel_ptr);
#ifdef COLLISION_DETECTION
if (collision_detection.mode != CollisionModeType::OFF) {
if (not collision_detection.is_off()) {
collision_detection.detect_collision(p1, p2, d.dist2);
}
#endif
Expand Down
Loading

0 comments on commit 2eea0c0

Please sign in to comment.