From 7a03446e0014371df1e44f0da9d2dc28fbdab3bf Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Fri, 7 Dec 2018 20:28:22 +0100 Subject: [PATCH 1/7] core: Fixed find_current_cell --- src/core/cells.cpp | 12 +++++------- src/core/cells.hpp | 11 +++++------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/core/cells.cpp b/src/core/cells.cpp index ca21de4072b..cde7ba815a7 100644 --- a/src/core/cells.cpp +++ b/src/core/cells.cpp @@ -491,13 +491,11 @@ void cells_update_ghosts() { } Cell *find_current_cell(const Particle &p) { - auto c = cell_structure.position_to_cell(p.r.p); - if (c) { - return c; - } else if (!p.l.ghost) { - // Old pos must lie within the cell system - return cell_structure.position_to_cell(p.l.p_old); - } else { + assert(not resort_particles); + + if (p.l.ghost) { return nullptr; } + + return cell_structure.position_to_cell(p.l.p_old); } diff --git a/src/core/cells.hpp b/src/core/cells.hpp index 3487d57264e..9fb5b8f5ecd 100644 --- a/src/core/cells.hpp +++ b/src/core/cells.hpp @@ -298,12 +298,11 @@ void check_resort_particles(); /*@}*/ -/* @brief Finds the cell in which a particle is stored - - Uses position_to_cell on p.r.p. If this is not on the node's domain, - uses position at last Verlet list rebuild (p.l.p_old). - - @return pointer to the cell or nullptr if the particle is not on the node +/** + * @brief Finds the cell in which a particle is stored + * + * + * @return pointer to the cell or nullptr if the particle is not on the node */ Cell *find_current_cell(const Particle &p); From 8be0994df4a3862bf665507b0968b86946e3ebed Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Fri, 7 Dec 2018 20:44:22 +0100 Subject: [PATCH 2/7] Formatting --- src/core/cells.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/cells.hpp b/src/core/cells.hpp index 9fb5b8f5ecd..7ed2a331216 100644 --- a/src/core/cells.hpp +++ b/src/core/cells.hpp @@ -303,7 +303,7 @@ void check_resort_particles(); * * * @return pointer to the cell or nullptr if the particle is not on the node -*/ + */ Cell *find_current_cell(const Particle &p); #endif From 95257eef79bb626001adb60aa386ccde64ea7ef4 Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Fri, 7 Dec 2018 23:57:14 +0100 Subject: [PATCH 3/7] core: New version of local_remoe_particle based on find_current cell --- src/core/cells.cpp | 27 ----------- src/core/particle_data.cpp | 91 ++++++++++++++++++++++++++------------ src/core/particle_data.hpp | 2 + 3 files changed, 64 insertions(+), 56 deletions(-) diff --git a/src/core/cells.cpp b/src/core/cells.cpp index cde7ba815a7..9fe1ff2ba0c 100644 --- a/src/core/cells.cpp +++ b/src/core/cells.cpp @@ -306,33 +306,6 @@ void fold_and_reset(Particle &p) { p.l.p_old = p.r.p; } - -/** - * @brief Extract an indexed particle from a list. - * - * Removes a particle from a particle list and - * from the particle index. - */ -Particle extract_indexed_particle(ParticleList *sl, int i) { - Particle *src = &sl->part[i]; - Particle *end = &sl->part[sl->n - 1]; - - Particle p = std::move(*src); - - assert(p.p.identity <= max_seen_particle); - local_particles[p.p.identity] = nullptr; - - if (src != end) { - new (src) Particle(std::move(*end)); - } - - if (realloc_particlelist(sl, --sl->n)) { - update_local_particles(sl); - } else if (src != end) { - local_particles[src->p.identity] = src; - } - return p; -} } // namespace /** diff --git a/src/core/particle_data.cpp b/src/core/particle_data.cpp index c0016b96d1c..afa5f9d4371 100644 --- a/src/core/particle_data.cpp +++ b/src/core/particle_data.cpp @@ -322,6 +322,33 @@ Particle *move_indexed_particle(ParticleList *dl, ParticleList *sl, int i) { return dst; } +/** + * @brief Extract an indexed particle from a list. + * + * Removes a particle from a particle list and + * from the particle index. + */ +Particle extract_indexed_particle(ParticleList *sl, int i) { + Particle *src = &sl->part[i]; + Particle *end = &sl->part[sl->n - 1]; + + Particle p = std::move(*src); + + assert(p.p.identity <= max_seen_particle); + local_particles[p.p.identity] = nullptr; + + if (src != end) { + new (src) Particle(std::move(*end)); + } + + if (realloc_particlelist(sl, --sl->n)) { + update_local_particles(sl); + } else if (src != end) { + local_particles[src->p.identity] = src; + } + return p; +} + namespace { /* Limit cache to 100 MiB */ std::size_t const max_cache_size = (100ul * 1048576ul) / sizeof(Particle); @@ -803,42 +830,48 @@ int remove_particle(int p_id) { return ES_OK; } -void local_remove_particle(int part) { - int ind, c; - Particle *p = local_particles[part]; - ParticleList *pl = nullptr, *tmp; +namespace { +std::pair find_particle(const Particle *p, Cell *c) { + auto n = c->part - p; + if ((n > 0) && (n < c->n)) { + return {c, n}; + } else { + return {nullptr, 0}; + } +} - /* the tricky - say ugly - part: determine - the cell the particle is located in by checking - whether the particle address is inside the array */ - for (c = 0; c < local_cells.n; c++) { - tmp = local_cells.cell[c]; - ind = p - tmp->part; - if (ind >= 0 && ind < tmp->n) { - pl = tmp; - break; +std::pair find_particle(const Particle *p, CellPList cells) { + for (auto &c : cells) { + auto res = find_particle(p, c); + if (res.first) { + return res; } } - if (!pl) { - fprintf(stderr, - "%d: INTERNAL ERROR: could not find cell of particle %d, exiting\n", - this_node, part); - errexit(); - } - free_particle(p); + return {nullptr, 0}; +} +} // namespace - /* remove local_particles entry */ - local_particles[p->p.identity] = nullptr; +void local_remove_particle(int part) { + const Particle *p = local_particles[part]; + assert(p); + assert(not p->l.ghost); + + /* If the particles are sorted we can use the + * cell system to find the cell containing the + * particle. Otherwise we do a brute force search + * of the cells. */ + Cell *cell = nullptr; + size_t n = 0; + if (Cells::RESORT_NONE == get_resort_particles()) { + std::tie(cell, n) = find_particle(p, find_current_cell(*p)); + } else { + std::tie(cell, n) = find_particle(p, local_cells); + } - if (&pl->part[pl->n - 1] != p) { - /* move last particle to free position */ - *p = pl->part[pl->n - 1]; + assert(cell); - /* update the local_particles array for the moved particle */ - local_particles[p->p.identity] = p; - } - pl->n--; + Particle p_destroy = extract_indexed_particle(cell, n); } void local_place_particle(int part, const double p[3], int _new) { diff --git a/src/core/particle_data.hpp b/src/core/particle_data.hpp index fcf5b9b1bc1..3cc090c688a 100644 --- a/src/core/particle_data.hpp +++ b/src/core/particle_data.hpp @@ -562,6 +562,8 @@ Particle *move_unindexed_particle(ParticleList *destList, Particle *move_indexed_particle(ParticleList *destList, ParticleList *sourceList, int ind); +Particle extract_indexed_particle(ParticleList *sl, int i); + /* Other Functions */ /************************************************/ From 0e0a4ff7d92024a9a01cc564ab2c3c5edd02e1af Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Sat, 8 Dec 2018 02:47:07 +0100 Subject: [PATCH 4/7] core: Bounds check and fixed find_particle. --- src/core/particle_data.cpp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/core/particle_data.cpp b/src/core/particle_data.cpp index afa5f9d4371..db9e0a92bb6 100644 --- a/src/core/particle_data.cpp +++ b/src/core/particle_data.cpp @@ -220,6 +220,7 @@ void init_particlelist(ParticleList *pList) { } int realloc_particlelist(ParticleList *l, int size) { + assert(size >= 0); int old_max = l->max; Particle *old_start = l->part; @@ -280,6 +281,9 @@ Particle *append_indexed_particle(ParticleList *l, Particle &&part) { } Particle *move_unindexed_particle(ParticleList *dl, ParticleList *sl, int i) { + assert(sl->n > 0); + assert(i < sl->n); + realloc_particlelist(dl, ++dl->n); auto dst = &dl->part[dl->n - 1]; auto src = &sl->part[i]; @@ -290,12 +294,13 @@ Particle *move_unindexed_particle(ParticleList *dl, ParticleList *sl, int i) { new (src) Particle(std::move(*end)); } - sl->n -= 1; - realloc_particlelist(sl, sl->n); + realloc_particlelist(sl, --sl->n); return dst; } Particle *move_indexed_particle(ParticleList *dl, ParticleList *sl, int i) { + assert(sl->n > 0); + assert(i < sl->n); int re = realloc_particlelist(dl, ++dl->n); Particle *dst = &dl->part[dl->n - 1]; Particle *src = &sl->part[i]; @@ -327,8 +332,16 @@ Particle *move_indexed_particle(ParticleList *dl, ParticleList *sl, int i) { * * 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]; @@ -832,8 +845,8 @@ int remove_particle(int p_id) { namespace { std::pair find_particle(const Particle *p, Cell *c) { - auto n = c->part - p; - if ((n > 0) && (n < c->n)) { + const auto n = p - c->part; + if ((n >= 0) && (n < c->n)) { return {c, n}; } else { return {nullptr, 0}; @@ -865,10 +878,16 @@ void local_remove_particle(int part) { size_t n = 0; if (Cells::RESORT_NONE == get_resort_particles()) { std::tie(cell, n) = find_particle(p, find_current_cell(*p)); - } else { + } + + if (not cell) { std::tie(cell, n) = find_particle(p, local_cells); } + if (not cell) { + std::tie(cell, n) = find_particle(p, ghost_cells); + } + assert(cell); Particle p_destroy = extract_indexed_particle(cell, n); From 9619172eefb32f3a4ce614e9b580dd3e2662768a Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Sat, 8 Dec 2018 03:08:18 +0100 Subject: [PATCH 5/7] Cleanup --- src/core/particle_data.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/core/particle_data.cpp b/src/core/particle_data.cpp index db9e0a92bb6..71f8c750971 100644 --- a/src/core/particle_data.cpp +++ b/src/core/particle_data.cpp @@ -884,10 +884,6 @@ void local_remove_particle(int part) { std::tie(cell, n) = find_particle(p, local_cells); } - if (not cell) { - std::tie(cell, n) = find_particle(p, ghost_cells); - } - assert(cell); Particle p_destroy = extract_indexed_particle(cell, n); From 7ccd8eb76ea4d27e583b42a5836bcf4bf3a9e479 Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Sat, 8 Dec 2018 16:59:13 +0100 Subject: [PATCH 6/7] core: particle_data: Skip empty cells when searching for particle. --- src/core/particle_data.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/particle_data.cpp b/src/core/particle_data.cpp index 71f8c750971..9dc5d81475d 100644 --- a/src/core/particle_data.cpp +++ b/src/core/particle_data.cpp @@ -844,16 +844,16 @@ int remove_particle(int p_id) { } namespace { -std::pair find_particle(const Particle *p, Cell *c) { - const auto n = p - c->part; - if ((n >= 0) && (n < c->n)) { +std::pair find_particle(Particle *p, Cell *c) { + const auto n = (c->n > 0) ? std::distance(c->part, p) : -1; + if ((n >= 0) && (n < c->n) && ((c->part + n) == p)) { return {c, n}; } else { return {nullptr, 0}; } } -std::pair find_particle(const Particle *p, CellPList cells) { +std::pair find_particle(Particle *p, CellPList cells) { for (auto &c : cells) { auto res = find_particle(p, c); if (res.first) { @@ -866,7 +866,7 @@ std::pair find_particle(const Particle *p, CellPList cells) { } // namespace void local_remove_particle(int part) { - const Particle *p = local_particles[part]; + Particle *p = local_particles[part]; assert(p); assert(not p->l.ghost); @@ -884,7 +884,7 @@ void local_remove_particle(int part) { std::tie(cell, n) = find_particle(p, local_cells); } - assert(cell); + assert(cell && cell->part && (n < cell->n) && ((cell->part + n) == p)); Particle p_destroy = extract_indexed_particle(cell, n); } From 1262edc2b471fe1ad971c0c8378fe551816dc800 Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Sat, 8 Dec 2018 17:26:44 +0100 Subject: [PATCH 7/7] core: particle_data: Be less clever. --- src/core/particle_data.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/particle_data.cpp b/src/core/particle_data.cpp index 9dc5d81475d..a7b705499d2 100644 --- a/src/core/particle_data.cpp +++ b/src/core/particle_data.cpp @@ -845,12 +845,12 @@ int remove_particle(int p_id) { namespace { std::pair find_particle(Particle *p, Cell *c) { - const auto n = (c->n > 0) ? std::distance(c->part, p) : -1; - if ((n >= 0) && (n < c->n) && ((c->part + n) == p)) { - return {c, n}; - } else { - return {nullptr, 0}; + for (int i = 0; i < c->n; ++i) { + if ((c->part + i) == p) { + return {c, i}; + } } + return {nullptr, 0}; } std::pair find_particle(Particle *p, CellPList cells) {