From d141dd6f5145491f62b5d9b74a85d8f500ed4f09 Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Fri, 13 Mar 2020 15:10:47 +0100 Subject: [PATCH 1/3] core: Put functions acting on the local particle index into separate file --- src/core/CMakeLists.txt | 1 + src/core/cells.cpp | 3 +- src/core/collision.cpp | 1 + src/core/debug.cpp | 2 +- src/core/domain_decomposition.cpp | 2 +- src/core/energy_inline.hpp | 1 + src/core/forces_inline.hpp | 1 + src/core/ghosts.cpp | 2 +- .../immersed_boundary/ImmersedBoundaries.cpp | 2 +- src/core/io/mpiio/mpiio.cpp | 3 +- src/core/nsquare.cpp | 2 +- .../object-in-fluid/oif_global_forces.cpp | 2 +- src/core/particle_data.cpp | 121 +----------------- src/core/particle_data.hpp | 104 --------------- src/core/particle_index.cpp | 93 ++++++++++++++ src/core/particle_index.hpp | 121 ++++++++++++++++++ src/core/rattle.cpp | 2 +- 17 files changed, 231 insertions(+), 232 deletions(-) create mode 100644 src/core/particle_index.cpp create mode 100644 src/core/particle_index.hpp diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index d88809d1acf..7d95f743a70 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -24,6 +24,7 @@ set(EspressoCore_SRC nsquare.cpp partCfg_global.cpp particle_data.cpp + particle_index.cpp polymer.cpp polynom.cpp pressure.cpp diff --git a/src/core/cells.cpp b/src/core/cells.cpp index 99ac6e1b41f..dc9c8650ed6 100644 --- a/src/core/cells.cpp +++ b/src/core/cells.cpp @@ -38,6 +38,7 @@ #include "nonbonded_interactions/nonbonded_interaction_data.hpp" #include "nsquare.hpp" #include "particle_data.hpp" +#include "particle_index.hpp" #include #include @@ -45,8 +46,6 @@ #include #include -#include -#include /** list of all cells. */ std::vector cells; diff --git a/src/core/collision.cpp b/src/core/collision.cpp index 7a107886955..9cf6d78597a 100644 --- a/src/core/collision.cpp +++ b/src/core/collision.cpp @@ -28,6 +28,7 @@ #include "grid.hpp" #include "nonbonded_interactions/nonbonded_interaction_data.hpp" #include "particle_data.hpp" +#include "particle_index.hpp" #include "rotation.hpp" #include "virtual_sites/VirtualSitesRelative.hpp" diff --git a/src/core/debug.cpp b/src/core/debug.cpp index 66f32321467..59055dc51db 100644 --- a/src/core/debug.cpp +++ b/src/core/debug.cpp @@ -25,7 +25,7 @@ #include "debug.hpp" #include "cells.hpp" -#include "particle_data.hpp" +#include "particle_index.hpp" #include diff --git a/src/core/domain_decomposition.cpp b/src/core/domain_decomposition.cpp index 68f87c146e5..3b52cead837 100644 --- a/src/core/domain_decomposition.cpp +++ b/src/core/domain_decomposition.cpp @@ -28,7 +28,7 @@ #include "communication.hpp" #include "errorhandling.hpp" #include "grid.hpp" -#include "particle_data.hpp" +#include "particle_index.hpp" #include "serialization/ParticleList.hpp" #include diff --git a/src/core/energy_inline.hpp b/src/core/energy_inline.hpp index 02d89a9cfe2..599e49be973 100644 --- a/src/core/energy_inline.hpp +++ b/src/core/energy_inline.hpp @@ -62,6 +62,7 @@ #include "electrostatics_magnetostatics/coulomb_inline.hpp" #endif #include "particle_data.hpp" +#include "particle_index.hpp" #include "statistics.hpp" #include "energy.hpp" diff --git a/src/core/forces_inline.hpp b/src/core/forces_inline.hpp index 20a1449199b..fca5b9d062e 100644 --- a/src/core/forces_inline.hpp +++ b/src/core/forces_inline.hpp @@ -60,6 +60,7 @@ #include "object-in-fluid/oif_global_forces.hpp" #include "object-in-fluid/oif_local_forces.hpp" #include "particle_data.hpp" +#include "particle_index.hpp" #include "rotation.hpp" #include "thermostat.hpp" diff --git a/src/core/ghosts.cpp b/src/core/ghosts.cpp index 74f3fe72a4c..466d61b721a 100644 --- a/src/core/ghosts.cpp +++ b/src/core/ghosts.cpp @@ -31,7 +31,7 @@ #include "ghosts.hpp" #include "Particle.hpp" #include "communication.hpp" -#include "particle_data.hpp" +#include "particle_index.hpp" #include #include diff --git a/src/core/immersed_boundary/ImmersedBoundaries.cpp b/src/core/immersed_boundary/ImmersedBoundaries.cpp index eaaecbdc0a1..edd2170574f 100644 --- a/src/core/immersed_boundary/ImmersedBoundaries.cpp +++ b/src/core/immersed_boundary/ImmersedBoundaries.cpp @@ -25,7 +25,7 @@ #include "communication.hpp" #include "errorhandling.hpp" #include "grid.hpp" -#include "particle_data.hpp" +#include "particle_index.hpp" #include diff --git a/src/core/io/mpiio/mpiio.cpp b/src/core/io/mpiio/mpiio.cpp index d066546b265..2c82af85420 100644 --- a/src/core/io/mpiio/mpiio.cpp +++ b/src/core/io/mpiio/mpiio.cpp @@ -55,9 +55,9 @@ #include "cells.hpp" #include "errorhandling.hpp" #include "event.hpp" -#include "integrate.hpp" #include "mpiio.hpp" #include "particle_data.hpp" +#include "particle_index.hpp" #include @@ -65,7 +65,6 @@ #include #include #include -#include #include namespace Mpiio { diff --git a/src/core/nsquare.cpp b/src/core/nsquare.cpp index 91a8a927fe3..4a67147eeaf 100644 --- a/src/core/nsquare.cpp +++ b/src/core/nsquare.cpp @@ -27,7 +27,7 @@ #include "communication.hpp" #include "constraints.hpp" #include "ghosts.hpp" -#include "particle_data.hpp" +#include "particle_index.hpp" #include diff --git a/src/core/object-in-fluid/oif_global_forces.cpp b/src/core/object-in-fluid/oif_global_forces.cpp index 43f7bbd0ab6..cc99b41b71e 100644 --- a/src/core/object-in-fluid/oif_global_forces.cpp +++ b/src/core/object-in-fluid/oif_global_forces.cpp @@ -25,7 +25,7 @@ #include "errorhandling.hpp" #include "grid.hpp" #include "grid_based_algorithms/lb_interface.hpp" -#include "particle_data.hpp" +#include "particle_index.hpp" #include using Utils::angle_btw_triangles; diff --git a/src/core/particle_data.cpp b/src/core/particle_data.cpp index 0a33e3090f2..d84b66d00a7 100644 --- a/src/core/particle_data.cpp +++ b/src/core/particle_data.cpp @@ -37,6 +37,7 @@ #include "integrate.hpp" #include "nonbonded_interactions/nonbonded_interaction_data.hpp" #include "partCfg_global.hpp" +#include "particle_index.hpp" #include "random.hpp" #include "rotation.hpp" #include "serialization/ParticleList.hpp" @@ -56,12 +57,6 @@ #include #include #include -/************************************************ - * defines - ************************************************/ - -/** my magic MPI code for send/recv_particles */ -#define REQ_SNDRCV_PART 0xaa namespace { /** @@ -390,8 +385,6 @@ void add_id_to_type_map(int part_id, int type); */ std::unordered_map particle_node; -std::vector local_particles; - /************************************************ * local functions ************************************************/ @@ -487,112 +480,6 @@ int get_particle_node(int id) { void clear_particle_node() { particle_node.clear(); } -/************************************************ - * organizational functions - ************************************************/ - -void update_local_particles(ParticleList *pl) { - Particle *p = pl->part; - int n = pl->n, i; - for (i = 0; i < n; i++) - set_local_particle_data(p[i].p.identity, &p[i]); -} - -void append_unindexed_particle(ParticleList *l, Particle &&part) { - l->resize(l->n + 1); - new (&(l->part[l->n - 1])) Particle(std::move(part)); -} - -Particle *append_indexed_particle(ParticleList *l, Particle &&part) { - auto const re = l->resize(l->n + 1); - auto p = new (&(l->part[l->n - 1])) Particle(std::move(part)); - - if (re) - update_local_particles(l); - else - set_local_particle_data(p->p.identity, p); - return p; -} - -Particle *move_unindexed_particle(ParticleList *dl, ParticleList *sl, int i) { - assert(sl->n > 0); - assert(i < sl->n); - - dl->resize(dl->n + 1); - auto dst = &dl->part[dl->n - 1]; - auto src = &sl->part[i]; - auto end = &sl->part[sl->n - 1]; - - new (dst) Particle(std::move(*src)); - if (src != end) { - new (src) Particle(std::move(*end)); - } - - sl->resize(sl->n - 1); - return dst; -} - -Particle *move_indexed_particle(ParticleList *dl, ParticleList *sl, int i) { - assert(sl->n > 0); - assert(i < sl->n); - int re = dl->resize(dl->n + 1); - Particle *dst = &dl->part[dl->n - 1]; - Particle *src = &sl->part[i]; - Particle *end = &sl->part[sl->n - 1]; - - new (dst) Particle(std::move(*src)); - - if (re) { - update_local_particles(dl); - } else { - set_local_particle_data(dst->p.identity, dst); - } - if (src != end) { - new (src) Particle(std::move(*end)); - } - - if (sl->resize(sl->n - 1)) { - update_local_particles(sl); - } else if (src != end) { - set_local_particle_data(src->p.identity, src); - } - return dst; -} - -/** - * @brief Extract an indexed particle from a list. - * - * Removes a particle from a particle list and - * from the particle index. - * - * @param i Index of particle to remove, - * needs to be valid. - * @param sl List to remove the particle from, - * needs to be non-empty. - * @return The extracted particle. - */ -Particle extract_indexed_particle(ParticleList *sl, int i) { - assert(sl->n > 0); - assert(i < sl->n); - Particle *src = &sl->part[i]; - Particle *end = &sl->part[sl->n - 1]; - - Particle p = std::move(*src); - - set_local_particle_data(p.p.identity, nullptr); - - if (src != end) { - new (src) Particle(std::move(*end)); - } - - if (sl->resize(sl->n - 1)) { - update_local_particles(sl); - } else if (src != end) { - set_local_particle_data(src->p.identity, src); - } - return p; -} - namespace { /* Limit cache to 100 MiB */ std::size_t const max_cache_size = (100ul * 1048576ul) / sizeof(Particle); @@ -1075,11 +962,11 @@ Particle *local_place_particle(int id, const Utils::Vector3d &pos, int _new) { } void local_remove_all_particles() { - local_particles.clear(); - for (auto c : cell_structure.local_cells()) { - for (auto &p : c->particles()) + for (auto &p : c->particles()) { + set_local_particle_data(p.identity(), nullptr); free_particle(&p); + } c->clear(); } diff --git a/src/core/particle_data.hpp b/src/core/particle_data.hpp index e3142ef4137..29ce66467b5 100644 --- a/src/core/particle_data.hpp +++ b/src/core/particle_data.hpp @@ -71,59 +71,6 @@ enum { #define COORD_FIXED(coord) (0) #endif -/** - * @brief Find local particles by id. - * - * If a particles is present on this mpi rank, either - * as a local particles or as a ghost, a pointer to it - * is returned, otherwise null. - * - * @param id of the particle to look up. - * - * @return Pointer to particle or nullptr. - **/ -inline Particle *get_local_particle_data(int id) { - extern std::vector local_particles; - - if (id >= local_particles.size()) - return nullptr; - - return local_particles[id]; -} - -/** - * @brief Update local particle index. - * - * Update the entry for a particle in the local particle - * index. - * - * @param id of the particle to up-date. - * @param p Pointer to the particle. - **/ -inline void set_local_particle_data(int id, Particle *p) { - extern std::vector local_particles; - - if (id >= local_particles.size()) - local_particles.resize(id + 1); - - local_particles[id] = p; -} - -/** - * @brief Get the maximal particle ever seen on this node. - * - * This returns the highest particle id ever encountered on - * this node, or -1 if there are no particles on this node. - */ -inline int get_local_max_seen_particle() { - extern std::vector local_particles; - - auto it = std::find_if(local_particles.rbegin(), local_particles.rend(), - [](const Particle *p) { return p != nullptr; }); - - return (it != local_particles.rend()) ? (*it)->identity() : -1; -} - /************************************************ * Functions ************************************************/ @@ -134,60 +81,9 @@ inline int get_local_max_seen_particle() { /** Deallocate the dynamic storage of a particle. */ void free_particle(Particle *part); -/* Functions acting on Particle Lists */ -/************************************************/ - -/** Append a particle at the end of a particle list. - * Reallocate particles if necessary! - * This procedure does not care for \ref local_particles. - * \param l List to append the particle to. - * \param part Particle to append. - */ -void append_unindexed_particle(ParticleList *l, Particle &&part); - -/** Append a particle at the end of a particle list. - * Reallocate particles if necessary! - * This procedure cares for \ref local_particles. - * \param plist List to append the particle to. - * \param part Particle to append. - * \return Pointer to new location of the particle. - */ -Particle *append_indexed_particle(ParticleList *plist, Particle &&part); - -/** Remove a particle from one particle list and append it to another. - * Refill the @p sourceList with last particle and update its entry in - * local_particles. Reallocate particles if necessary. This - * procedure does not care for \ref local_particles. - * \param destList List where the particle is appended. - * \param sourceList List where the particle will be removed. - * \param ind Index of the particle in the @p sourceList. - * \return Pointer to new location of the particle. - */ -Particle *move_unindexed_particle(ParticleList *destList, - ParticleList *sourceList, int ind); - -/** Remove a particle from one particle list and append it to another. - * Refill the @p sourceList with last particle and update its entry in - * local_particles. Reallocate particles if necessary. This - * procedure cares for \ref local_particles. - * \param destList List where the particle is appended. - * \param sourceList List where the particle will be removed. - * \param ind Index of the particle in the @p sourceList. - * \return Pointer to new location of the particle. - */ -Particle *move_indexed_particle(ParticleList *destList, - ParticleList *sourceList, int ind); - -Particle extract_indexed_particle(ParticleList *sl, int i); - /* Other Functions */ /************************************************/ -/** Update the entries in \ref local_particles for all particles in the list pl. - * @param pl the list to put in. - */ -void update_local_particles(ParticleList *pl); - /** Invalidate \ref particle_node. This has to be done * at the beginning of the integration. */ diff --git a/src/core/particle_index.cpp b/src/core/particle_index.cpp new file mode 100644 index 00000000000..6ed804af744 --- /dev/null +++ b/src/core/particle_index.cpp @@ -0,0 +1,93 @@ +#include "particle_index.hpp" + +std::vector local_particles; + +void update_local_particles(ParticleList *pl) { + Particle *p = pl->part; + int n = pl->n, i; + for (i = 0; i < n; i++) + set_local_particle_data(p[i].p.identity, &p[i]); +} + +void append_unindexed_particle(ParticleList *l, Particle &&part) { + l->resize(l->n + 1); + new (&(l->part[l->n - 1])) Particle(std::move(part)); +} + +Particle *append_indexed_particle(ParticleList *l, Particle &&part) { + auto const re = l->resize(l->n + 1); + auto p = new (&(l->part[l->n - 1])) Particle(std::move(part)); + + if (re) + update_local_particles(l); + else + set_local_particle_data(p->p.identity, p); + return p; +} + +Particle *move_unindexed_particle(ParticleList *dl, ParticleList *sl, int i) { + assert(sl->n > 0); + assert(i < sl->n); + + dl->resize(dl->n + 1); + auto dst = &dl->part[dl->n - 1]; + auto src = &sl->part[i]; + auto end = &sl->part[sl->n - 1]; + + new (dst) Particle(std::move(*src)); + if (src != end) { + new (src) Particle(std::move(*end)); + } + + sl->resize(sl->n - 1); + return dst; +} + +Particle *move_indexed_particle(ParticleList *dl, ParticleList *sl, int i) { + assert(sl->n > 0); + assert(i < sl->n); + int re = dl->resize(dl->n + 1); + Particle *dst = &dl->part[dl->n - 1]; + Particle *src = &sl->part[i]; + Particle *end = &sl->part[sl->n - 1]; + + new (dst) Particle(std::move(*src)); + + if (re) { + update_local_particles(dl); + } else { + set_local_particle_data(dst->p.identity, dst); + } + if (src != end) { + new (src) Particle(std::move(*end)); + } + + if (sl->resize(sl->n - 1)) { + update_local_particles(sl); + } else if (src != end) { + set_local_particle_data(src->p.identity, src); + } + return dst; +} + +Particle extract_indexed_particle(ParticleList *sl, int i) { + assert(sl->n > 0); + assert(i < sl->n); + Particle *src = &sl->part[i]; + Particle *end = &sl->part[sl->n - 1]; + + Particle p = std::move(*src); + + set_local_particle_data(p.p.identity, nullptr); + + if (src != end) { + new (src) Particle(std::move(*end)); + } + + if (sl->resize(sl->n - 1)) { + update_local_particles(sl); + } else if (src != end) { + set_local_particle_data(src->p.identity, src); + } + return p; +} diff --git a/src/core/particle_index.hpp b/src/core/particle_index.hpp new file mode 100644 index 00000000000..9d663f46810 --- /dev/null +++ b/src/core/particle_index.hpp @@ -0,0 +1,121 @@ +#ifndef ESPRESSO_PARTICLE_INDEX_HPP +#define ESPRESSO_PARTICLE_INDEX_HPP + +#include "ParticleList.hpp" + +#include + +/** + * @brief Find local particles by id. + * + * If a particles is present on this mpi rank, either + * as a local particles or as a ghost, a pointer to it + * is returned, otherwise null. + * + * @param id of the particle to look up. + * + * @return Pointer to particle or nullptr. + **/ +inline Particle *get_local_particle_data(int id) { + extern std::vector local_particles; + + if (id >= local_particles.size()) + return nullptr; + + return local_particles[id]; +} + +/** + * @brief Update local particle index. + * + * Update the entry for a particle in the local particle + * index. + * + * @param id of the particle to up-date. + * @param p Pointer to the particle. + **/ +inline void set_local_particle_data(int id, Particle *p) { + extern std::vector local_particles; + + if (id >= local_particles.size()) + local_particles.resize(id + 1); + + local_particles[id] = p; +} + +/** + * @brief Get the maximal particle ever seen on this node. + * + * This returns the highest particle id ever encountered on + * this node, or -1 if there are no particles on this node. + */ +inline int get_local_max_seen_particle() { + extern std::vector local_particles; + + auto it = std::find_if(local_particles.rbegin(), local_particles.rend(), + [](const Particle *p) { return p != nullptr; }); + + return (it != local_particles.rend()) ? (*it)->identity() : -1; +} + +/** Update the entries in \ref local_particles for all particles in the list pl. + * @param pl the list to put in. + */ +void update_local_particles(ParticleList *pl); + +/** Append a particle at the end of a particle list. + * Reallocate particles if necessary! + * This procedure does not care for \ref local_particles. + * \param l List to append the particle to. + * \param part Particle to append. + */ +void append_unindexed_particle(ParticleList *l, Particle &&part); + +/** Append a particle at the end of a particle list. + * Reallocate particles if necessary! + * This procedure cares for \ref local_particles. + * \param plist List to append the particle to. + * \param part Particle to append. + * \return Pointer to new location of the particle. + */ +Particle *append_indexed_particle(ParticleList *plist, Particle &&part); + +/** Remove a particle from one particle list and append it to another. + * Refill the @p sourceList with last particle and update its entry in + * local_particles. Reallocate particles if necessary. This + * procedure does not care for \ref local_particles. + * \param destList List where the particle is appended. + * \param sourceList List where the particle will be removed. + * \param ind Index of the particle in the @p sourceList. + * \return Pointer to new location of the particle. + */ +Particle *move_unindexed_particle(ParticleList *destList, + ParticleList *sourceList, int ind); + +/** Remove a particle from one particle list and append it to another. + * Refill the @p sourceList with last particle and update its entry in + * local_particles. Reallocate particles if necessary. This + * procedure cares for \ref local_particles. + * \param destList List where the particle is appended. + * \param sourceList List where the particle will be removed. + * \param ind Index of the particle in the @p sourceList. + * \return Pointer to new location of the particle. + */ +Particle *move_indexed_particle(ParticleList *destList, + ParticleList *sourceList, int ind); + +/** + * @brief Extract an indexed particle from a list. + * + * Removes a particle from a particle list and + * from the particle index. + * + * @param i Index of particle to remove, + * needs to be valid. + * @param sl List to remove the particle from, + * needs to be non-empty. + * @return The extracted particle. + */ +Particle extract_indexed_particle(ParticleList *sl, int i); + +#endif // ESPRESSO_PARTICLE_INDEX_HPP diff --git a/src/core/rattle.cpp b/src/core/rattle.cpp index 5d14d0e7d46..49b2ef81770 100644 --- a/src/core/rattle.cpp +++ b/src/core/rattle.cpp @@ -32,7 +32,7 @@ int n_rigidbonds = 0; #include "errorhandling.hpp" #include "global.hpp" #include "grid.hpp" -#include "particle_data.hpp" +#include "particle_index.hpp" #include From ca597e8522b779fb8ff7610b8f5c59c463bd491a Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Fri, 13 Mar 2020 15:41:53 +0100 Subject: [PATCH 2/3] core: Moved and renamed some bond management functions --- .../bonded_interaction_data.cpp | 17 +++++++ .../bonded_interaction_data.hpp | 25 +++++++++-- src/core/collision.cpp | 16 +++---- src/core/communication.cpp | 9 ++-- src/core/particle_data.cpp | 45 ++++--------------- src/core/particle_data.hpp | 15 ------- 6 files changed, 59 insertions(+), 68 deletions(-) diff --git a/src/core/bonded_interactions/bonded_interaction_data.cpp b/src/core/bonded_interactions/bonded_interaction_data.cpp index 2364002d9f6..352d5ddc074 100644 --- a/src/core/bonded_interactions/bonded_interaction_data.cpp +++ b/src/core/bonded_interactions/bonded_interaction_data.cpp @@ -129,3 +129,20 @@ int virtual_set_params(int bond_type) { return ES_OK; } + +void remove_all_bonds_to(Particle &p, int id) { + IntList *bl = &p.bl; + int i, j, partners; + + for (i = 0; i < bl->n;) { + partners = bonded_ia_params[bl->e[i]].num; + for (j = 1; j <= partners; j++) + if (bl->e[i + j] == id) + break; + if (j <= partners) { + bl->erase(bl->begin() + i, bl->begin() + i + 1 + partners); + } else + i += 1 + partners; + } + assert(i == bl->n); +} diff --git a/src/core/bonded_interactions/bonded_interaction_data.hpp b/src/core/bonded_interactions/bonded_interaction_data.hpp index 15717b8be9e..88b2a92f00a 100644 --- a/src/core/bonded_interactions/bonded_interaction_data.hpp +++ b/src/core/bonded_interactions/bonded_interaction_data.hpp @@ -19,11 +19,12 @@ #ifndef _BONDED_INTERACTION_DATA_HPP #define _BONDED_INTERACTION_DATA_HPP -#include - #include "Particle.hpp" #include "TabulatedPotential.hpp" -#include + +#include + +#include /** @file * Data structures for bonded interactions. @@ -476,6 +477,24 @@ inline bool pair_bond_enum_exists_between(Particle const &p1, (p2.bl.n > 0 && pair_bond_enum_exists_on(p2, p1, bond)); } +/** @brief Add bond to local particle. + * @param p identity of principal atom of the bond. + * @param bond field containing the bond type number and the identity + * of all bond partners (secondary atoms of the bond). + */ +void add_bond(Particle &p, Utils::Span bond); + +/** Remove bond from particle. */ +int delete_bond(Particle *part, const int *bond); + +/** + * @brief Remove all bonds on particle involving another particle. + * + * @param p Particle whose bond list is modified. + * @param id Bonds involving this id are removed. + */ +void remove_all_bonds_to(Particle &p, int id); + /** Calculate the maximal cutoff of bonded interactions, required to * determine the cell size for communication. * diff --git a/src/core/collision.cpp b/src/core/collision.cpp index 9cf6d78597a..4d4f427261c 100644 --- a/src/core/collision.cpp +++ b/src/core/collision.cpp @@ -363,7 +363,7 @@ void coldet_do_three_particle_bond(Particle &p, Particle &p1, Particle &p2) { // First, fill bond data structure const Utils::Vector3i bondT = {bond_id, p1.p.identity, p2.p.identity}; - local_add_particle_bond(p, bondT); + add_bond(p, bondT); } #ifdef VIRTUAL_SITES_RELATIVE @@ -390,7 +390,7 @@ void bind_at_poc_create_bond_between_vs(const int current_vs_pid, const int bondG[] = {collision_params.bond_vs, current_vs_pid - 2}; // Only add bond if vs was created on this node if (get_local_particle_data(current_vs_pid - 1)) - local_add_particle_bond(get_part(current_vs_pid - 1), bondG); + add_bond(get_part(current_vs_pid - 1), bondG); break; } case 2: { @@ -398,9 +398,9 @@ void bind_at_poc_create_bond_between_vs(const int current_vs_pid, const int bondG[] = {collision_params.bond_vs, c.pp1, c.pp2}; // Only add bond if vs was created on this node if (get_local_particle_data(current_vs_pid - 1)) - local_add_particle_bond(get_part(current_vs_pid - 1), bondG); + add_bond(get_part(current_vs_pid - 1), bondG); if (get_local_particle_data(current_vs_pid - 2)) - local_add_particle_bond(get_part(current_vs_pid - 2), bondG); + add_bond(get_part(current_vs_pid - 2), bondG); break; } } @@ -414,9 +414,9 @@ void glue_to_surface_bind_part_to_vs(const Particle *const p1, const int bondG[] = {collision_params.bond_vs, vs_pid_plus_one - 1}; if (p1->p.type == collision_params.part_type_after_glueing) { - local_add_particle_bond(get_part(p1->p.identity), bondG); + add_bond(get_part(p1->p.identity), bondG); } else { - local_add_particle_bond(get_part(p2->p.identity), bondG); + add_bond(get_part(p2->p.identity), bondG); } } @@ -515,7 +515,7 @@ void handle_collisions() { int bondG[2]; bondG[0] = collision_params.bond_centers; bondG[1] = c.pp2; - local_add_particle_bond(get_part(c.pp1), bondG); + add_bond(get_part(c.pp1), bondG); } } @@ -630,7 +630,7 @@ void handle_collisions() { int bondG[2]; bondG[0] = collision_params.bond_centers; bondG[1] = c.pp2; - local_add_particle_bond(get_part(c.pp1), bondG); + add_bond(get_part(c.pp1), bondG); } // Change type of particle being attached, to make it inert diff --git a/src/core/communication.cpp b/src/core/communication.cpp index a1b2844d49a..34886ec7942 100644 --- a/src/core/communication.cpp +++ b/src/core/communication.cpp @@ -276,13 +276,10 @@ void mpi_remove_particle(int pnode, int part) { void mpi_remove_particle_slave(int pnode, int part) { if (part != -1) { - if (pnode == this_node) { - local_remove_particle(part); - } else { - remove_all_bonds_to(part); - } - } else + local_remove_particle(part); + } else { local_remove_all_particles(); + } on_particle_change(); } diff --git a/src/core/particle_data.cpp b/src/core/particle_data.cpp index d84b66d00a7..0f9ef9b19a4 100644 --- a/src/core/particle_data.cpp +++ b/src/core/particle_data.cpp @@ -176,7 +176,7 @@ struct RemoveBond { std::vector bond; void operator()(Particle &p) const { - try_delete_bond(&p, bond.data()); + delete_bond(&p, bond.data()); } template @@ -203,7 +203,7 @@ struct AddBond { std::vector bond; void operator()(Particle &p) const { - local_add_particle_bond(p, bond); + add_bond(p, bond); } template @@ -389,7 +389,7 @@ std::unordered_map particle_node; * local functions ************************************************/ -int try_delete_bond(Particle *part, const int *bond); +int delete_bond(Particle *part, const int *bond); void try_delete_exclusion(Particle *part, int part2); @@ -883,35 +883,6 @@ int remove_particle(int p_id) { return ES_OK; } -/** - * @brief Remove all bonds on particle involving another particle. - * - * @param p Particle whose bond list is modified. - * @param id Bonds involving this id are removed. - */ -static void remove_all_bonds_to(Particle &p, int id) { - IntList *bl = &p.bl; - int i, j, partners; - - for (i = 0; i < bl->n;) { - partners = bonded_ia_params[bl->e[i]].num; - for (j = 1; j <= partners; j++) - if (bl->e[i + j] == id) - break; - if (j <= partners) { - bl->erase(bl->begin() + i, bl->begin() + i + 1 + partners); - } else - i += 1 + partners; - } - assert(i == bl->n); -} - -void remove_all_bonds_to(int identity) { - for (auto &p : cell_structure.local_cells().particles()) { - remove_all_bonds_to(p, identity); - } -} - void local_remove_particle(int part) { Cell *cell = nullptr; int position = -1; @@ -930,8 +901,10 @@ void local_remove_particle(int part) { } } - assert(cell && (position >= 0)); - extract_indexed_particle(cell, position); + /* If we found the particle, remove it. */ + if (cell && (position >= 0)) { + extract_indexed_particle(cell, position); + } } Particle *local_place_particle(int id, const Utils::Vector3d &pos, int _new) { @@ -982,11 +955,11 @@ void local_rescale_particles(int dir, double scale) { } } -void local_add_particle_bond(Particle &p, Utils::Span bond) { +void add_bond(Particle &p, Utils::Span bond) { boost::copy(bond, std::back_inserter(p.bl)); } -int try_delete_bond(Particle *part, const int *bond) { +int delete_bond(Particle *part, const int *bond) { IntList *bl = &part->bl; int i, j, type, partners; diff --git a/src/core/particle_data.hpp b/src/core/particle_data.hpp index 29ce66467b5..c2b33b42af3 100644 --- a/src/core/particle_data.hpp +++ b/src/core/particle_data.hpp @@ -346,11 +346,6 @@ int remove_particle(int part); /** Remove all particles. */ void remove_all_particles(); -/** For all local particles, remove bonds incorporating the specified particle. - * @param part identity of the particle to free from bonds - */ -void remove_all_bonds_to(int part); - /** Used by \ref mpi_place_particle, should not be used elsewhere. * Move a particle to a new position. If it does not exist, it is created. * The position must be on the local node! @@ -389,13 +384,6 @@ void local_remove_all_particles(); */ void local_rescale_particles(int dir, double scale); -/** @brief Add bond to local particle. - * @param p identity of principal atom of the bond. - * @param bond field containing the bond type number and the identity - * of all bond partners (secondary atoms of the bond). - */ -void local_add_particle_bond(Particle &p, Utils::Span bond); - #ifdef EXCLUSIONS /** Determine if the non-bonded interactions between @p p1 and @p p2 should be * calculated. @@ -408,9 +396,6 @@ inline bool do_nonbonded(Particle const &p1, Particle const &p2) { } #endif -/** Remove bond from particle if possible */ -int try_delete_bond(Particle *part, const int *bond); - /** Remove exclusion from particle if possible */ void try_delete_exclusion(Particle *part, int part2); From e3b2c01b9e05fe04b3a320e25e843efc29fe49ba Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Fri, 13 Mar 2020 16:11:51 +0100 Subject: [PATCH 3/3] core: Split of non-head-node exclusion code --- src/core/CMakeLists.txt | 2 +- .../bonded_interaction_data.cpp | 47 ++++++++++++ src/core/collision.cpp | 2 - .../magnetic_non_p3m_methods.cpp | 2 - src/core/energy_inline.hpp | 2 +- src/core/exclusions.cpp | 19 +++++ src/core/exclusions.hpp | 23 ++++++ src/core/forces_inline.hpp | 2 +- src/core/global.cpp | 1 - src/core/grid_based_algorithms/lbgpu.cpp | 1 - src/core/pair_criteria/pair_criteria.hpp | 2 + src/core/particle_data.cpp | 75 ++----------------- src/core/particle_data.hpp | 18 ----- src/core/pressure_inline.hpp | 1 + 14 files changed, 101 insertions(+), 96 deletions(-) create mode 100644 src/core/exclusions.cpp create mode 100644 src/core/exclusions.hpp diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 7d95f743a70..be39a6b1b29 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -42,7 +42,7 @@ set(EspressoCore_SRC thermostat.cpp tuning.cpp virtual_sites.cpp -) + exclusions.cpp) if(CUDA) set(EspressoCuda_SRC diff --git a/src/core/bonded_interactions/bonded_interaction_data.cpp b/src/core/bonded_interactions/bonded_interaction_data.cpp index 352d5ddc074..f9ff4f18ed7 100644 --- a/src/core/bonded_interactions/bonded_interaction_data.cpp +++ b/src/core/bonded_interactions/bonded_interaction_data.cpp @@ -19,7 +19,9 @@ #include "bonded_interaction_data.hpp" #include "communication.hpp" +#include #include + #include std::vector bonded_ia_params; @@ -146,3 +148,48 @@ void remove_all_bonds_to(Particle &p, int id) { } assert(i == bl->n); } + +void add_bond(Particle &p, Utils::Span bond) { + boost::copy(bond, std::back_inserter(p.bl)); +} + +int delete_bond(Particle *part, const int *bond) { + IntList *bl = &part->bl; + int i, j, type, partners; + + // Empty bond means: delete all bonds + if (!bond) { + bl->clear(); + + return ES_OK; + } + + // Go over the bond list to find the bond to delete + for (i = 0; i < bl->n;) { + type = bl->e[i]; + partners = bonded_ia_params[type].num; + + // If the bond type does not match the one, we want to delete, skip + if (type != bond[0]) + i += 1 + partners; + else { + // Go over the bond partners + for (j = 1; j <= partners; j++) { + // Leave the loop early, if the bond to delete and the bond with in the + // particle don't match + if (bond[j] != bl->e[i + j]) + break; + } + // If we did not exit from the loop early, all parameters matched + // and we go on with deleting + if (j > partners) { + // New length of bond list + bl->erase(bl->begin() + i, bl->begin() + i + 1 + partners); + + return ES_OK; + } + i += 1 + partners; + } + } + return ES_ERROR; +} diff --git a/src/core/collision.cpp b/src/core/collision.cpp index 4d4f427261c..78c9789f9f0 100644 --- a/src/core/collision.cpp +++ b/src/core/collision.cpp @@ -27,9 +27,7 @@ #include "event.hpp" #include "grid.hpp" #include "nonbonded_interactions/nonbonded_interaction_data.hpp" -#include "particle_data.hpp" #include "particle_index.hpp" -#include "rotation.hpp" #include "virtual_sites/VirtualSitesRelative.hpp" #include diff --git a/src/core/electrostatics_magnetostatics/magnetic_non_p3m_methods.cpp b/src/core/electrostatics_magnetostatics/magnetic_non_p3m_methods.cpp index c91e231ab50..321196110a5 100644 --- a/src/core/electrostatics_magnetostatics/magnetic_non_p3m_methods.cpp +++ b/src/core/electrostatics_magnetostatics/magnetic_non_p3m_methods.cpp @@ -28,8 +28,6 @@ #include "electrostatics_magnetostatics/dipole.hpp" #include "errorhandling.hpp" #include "grid.hpp" -#include "nonbonded_interactions/nonbonded_interaction_data.hpp" -#include "particle_data.hpp" #include diff --git a/src/core/energy_inline.hpp b/src/core/energy_inline.hpp index 599e49be973..bad4a2d5ddb 100644 --- a/src/core/energy_inline.hpp +++ b/src/core/energy_inline.hpp @@ -61,7 +61,7 @@ #include "bonded_interactions/bonded_coulomb_sr.hpp" #include "electrostatics_magnetostatics/coulomb_inline.hpp" #endif -#include "particle_data.hpp" +#include "exclusions.hpp" #include "particle_index.hpp" #include "statistics.hpp" diff --git a/src/core/exclusions.cpp b/src/core/exclusions.cpp new file mode 100644 index 00000000000..58ca4b39b1b --- /dev/null +++ b/src/core/exclusions.cpp @@ -0,0 +1,19 @@ +#include "exclusions.hpp" + +#ifdef EXCLUSIONS +void add_exclusion(Particle *part, int part2) { + for (int i = 0; i < part->el.n; i++) + if (part->el.e[i] == part2) + return; + + part->el.push_back(part2); +} + +void delete_exclusion(Particle *part, int part2) { + IntList &el = part->el; + + if (!el.empty()) { + el.erase(std::remove(el.begin(), el.end(), part2), el.end()); + }; +} +#endif \ No newline at end of file diff --git a/src/core/exclusions.hpp b/src/core/exclusions.hpp new file mode 100644 index 00000000000..671d770b9de --- /dev/null +++ b/src/core/exclusions.hpp @@ -0,0 +1,23 @@ +#ifndef ESPRESSO_EXCLUSIONS_HPP +#define ESPRESSO_EXCLUSIONS_HPP + +#include "Particle.hpp" + +#ifdef EXCLUSIONS +/** Determine if the non-bonded interactions between @p p1 and @p p2 should be + * calculated. + */ +inline bool do_nonbonded(Particle const &p1, Particle const &p2) { + /* check for particle 2 in particle 1's exclusion list. The exclusion list is + * symmetric, so this is sufficient. */ + return std::none_of(p1.el.begin(), p1.el.end(), + [&p2](int id) { return p2.p.identity == id; }); +} + +/** Remove exclusion from particle if possible */ +void delete_exclusion(Particle *part, int part2); + +/** Insert an exclusion if not already set */ +void add_exclusion(Particle *part, int part2); +#endif +#endif // ESPRESSO_EXCLUSIONS_HPP diff --git a/src/core/forces_inline.hpp b/src/core/forces_inline.hpp index fca5b9d062e..ef69fd3107f 100644 --- a/src/core/forces_inline.hpp +++ b/src/core/forces_inline.hpp @@ -36,6 +36,7 @@ #include "bonded_interactions/thermalized_bond.hpp" #include "bonded_interactions/umbrella.hpp" #include "errorhandling.hpp" +#include "exclusions.hpp" #include "forces.hpp" #include "immersed_boundary/ibm_tribend.hpp" #include "immersed_boundary/ibm_triel.hpp" @@ -59,7 +60,6 @@ #include "npt.hpp" #include "object-in-fluid/oif_global_forces.hpp" #include "object-in-fluid/oif_local_forces.hpp" -#include "particle_data.hpp" #include "particle_index.hpp" #include "rotation.hpp" #include "thermostat.hpp" diff --git a/src/core/global.cpp b/src/core/global.cpp index a2e2233cc77..7aadc9f190b 100644 --- a/src/core/global.cpp +++ b/src/core/global.cpp @@ -33,7 +33,6 @@ #include "nonbonded_interactions/nonbonded_interaction_data.hpp" #include "npt.hpp" #include "object-in-fluid/oif_global_forces.hpp" -#include "particle_data.hpp" #include "rattle.hpp" #include "thermostat.hpp" #include "tuning.hpp" diff --git a/src/core/grid_based_algorithms/lbgpu.cpp b/src/core/grid_based_algorithms/lbgpu.cpp index 685ccb4ed7b..c6aebde8c60 100644 --- a/src/core/grid_based_algorithms/lbgpu.cpp +++ b/src/core/grid_based_algorithms/lbgpu.cpp @@ -36,7 +36,6 @@ #include "grid_based_algorithms/lbgpu.hpp" #include "integrate.hpp" #include "nonbonded_interactions/nonbonded_interaction_data.hpp" -#include "particle_data.hpp" #include "statistics.hpp" #include diff --git a/src/core/pair_criteria/pair_criteria.hpp b/src/core/pair_criteria/pair_criteria.hpp index 66698782586..9dd4bbbc47b 100644 --- a/src/core/pair_criteria/pair_criteria.hpp +++ b/src/core/pair_criteria/pair_criteria.hpp @@ -21,6 +21,8 @@ #include "Particle.hpp" #include "energy_inline.hpp" +#include "particle_data.hpp" + #include namespace PairCriteria { diff --git a/src/core/particle_data.cpp b/src/core/particle_data.cpp index 0f9ef9b19a4..597905aa869 100644 --- a/src/core/particle_data.cpp +++ b/src/core/particle_data.cpp @@ -391,9 +391,9 @@ std::unordered_map particle_node; int delete_bond(Particle *part, const int *bond); -void try_delete_exclusion(Particle *part, int part2); +void delete_exclusion(Particle *part, int part2); -void try_add_exclusion(Particle *part, int part2); +void add_exclusion(Particle *part, int part2); void auto_exclusion(int distance); @@ -955,51 +955,6 @@ void local_rescale_particles(int dir, double scale) { } } -void add_bond(Particle &p, Utils::Span bond) { - boost::copy(bond, std::back_inserter(p.bl)); -} - -int delete_bond(Particle *part, const int *bond) { - IntList *bl = &part->bl; - int i, j, type, partners; - - // Empty bond means: delete all bonds - if (!bond) { - bl->clear(); - - return ES_OK; - } - - // Go over the bond list to find the bond to delete - for (i = 0; i < bl->n;) { - type = bl->e[i]; - partners = bonded_ia_params[type].num; - - // If the bond type does not match the one, we want to delete, skip - if (type != bond[0]) - i += 1 + partners; - else { - // Go over the bond partners - for (j = 1; j <= partners; j++) { - // Leave the loop early, if the bond to delete and the bond with in the - // particle don't match - if (bond[j] != bl->e[i + j]) - break; - } - // If we did not exit from the loop early, all parameters matched - // and we go on with deleting - if (j > partners) { - // New length of bond list - bl->erase(bl->begin() + i, bl->begin() + i + 1 + partners); - - return ES_OK; - } - i += 1 + partners; - } - } - return ES_ERROR; -} - #ifdef EXCLUSIONS void local_change_exclusion(int part1, int part2, int _delete) { if (part1 == -1 && part2 == -1) { @@ -1014,39 +969,21 @@ void local_change_exclusion(int part1, int part2, int _delete) { auto part = get_local_particle_data(part1); if (part) { if (_delete) - try_delete_exclusion(part, part2); + delete_exclusion(part, part2); else - try_add_exclusion(part, part2); + add_exclusion(part, part2); } /* part2, if here */ part = get_local_particle_data(part2); if (part) { if (_delete) - try_delete_exclusion(part, part1); + delete_exclusion(part, part1); else - try_add_exclusion(part, part1); + add_exclusion(part, part1); } } -void try_add_exclusion(Particle *part, int part2) { - for (int i = 0; i < part->el.n; i++) - if (part->el.e[i] == part2) - return; - - part->el.push_back(part2); -} - -void try_delete_exclusion(Particle *part, int part2) { - IntList &el = part->el; - - if (!el.empty()) { - el.erase(std::remove(el.begin(), el.end(), part2), el.end()); - }; -} -#endif - -#ifdef EXCLUSIONS namespace { /* keep a unique list for particle i. Particle j is only added if it is not i and not already in the list. */ diff --git a/src/core/particle_data.hpp b/src/core/particle_data.hpp index c2b33b42af3..3ef0b4253b3 100644 --- a/src/core/particle_data.hpp +++ b/src/core/particle_data.hpp @@ -384,24 +384,6 @@ void local_remove_all_particles(); */ void local_rescale_particles(int dir, double scale); -#ifdef EXCLUSIONS -/** Determine if the non-bonded interactions between @p p1 and @p p2 should be - * calculated. - */ -inline bool do_nonbonded(Particle const &p1, Particle const &p2) { - /* check for particle 2 in particle 1's exclusion list. The exclusion list is - * symmetric, so this is sufficient. */ - return std::none_of(p1.el.begin(), p1.el.end(), - [&p2](int id) { return p2.p.identity == id; }); -} -#endif - -/** Remove exclusion from particle if possible */ -void try_delete_exclusion(Particle *part, int part2); - -/** Insert an exclusion if not already set */ -void try_add_exclusion(Particle *part, int part2); - /** Automatically add the next \ neighbors in each molecule to the * exclusion list. * This uses the bond topology obtained directly from the particles. diff --git a/src/core/pressure_inline.hpp b/src/core/pressure_inline.hpp index fb4a8ee0a58..ffd27f4d5b4 100644 --- a/src/core/pressure_inline.hpp +++ b/src/core/pressure_inline.hpp @@ -25,6 +25,7 @@ #ifndef CORE_PRESSURE_INLINE_HPP #define CORE_PRESSURE_INLINE_HPP +#include "exclusions.hpp" #include "forces_inline.hpp" #include "integrate.hpp" #include "npt.hpp"