Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: Fixed find_current_cell #2410

Merged
merged 7 commits into from
Dec 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 5 additions & 34 deletions src/core/cells.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand Down Expand Up @@ -491,13 +464,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);
}
13 changes: 6 additions & 7 deletions src/core/cells.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,13 +298,12 @@ 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);

#endif
110 changes: 79 additions & 31 deletions src/core/particle_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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];
Expand All @@ -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];
Expand All @@ -322,6 +327,41 @@ 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.
*
* @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);

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);
Expand Down Expand Up @@ -803,42 +843,50 @@ 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;

/* 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;
namespace {
std::pair<Cell *, size_t> find_particle(Particle *p, Cell *c) {
for (int i = 0; i < c->n; ++i) {
if ((c->part + i) == p) {
return {c, i};
}
}
if (!pl) {
fprintf(stderr,
"%d: INTERNAL ERROR: could not find cell of particle %d, exiting\n",
this_node, part);
errexit();
}
return {nullptr, 0};
}

free_particle(p);
std::pair<Cell *, size_t> find_particle(Particle *p, CellPList cells) {
for (auto &c : cells) {
auto res = find_particle(p, c);
if (res.first) {
return res;
}
}

/* remove local_particles entry */
local_particles[p->p.identity] = nullptr;
return {nullptr, 0};
}
} // namespace

if (&pl->part[pl->n - 1] != p) {
/* move last particle to free position */
*p = pl->part[pl->n - 1];
void local_remove_particle(int part) {
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));
}

/* update the local_particles array for the moved particle */
local_particles[p->p.identity] = p;
if (not cell) {
std::tie(cell, n) = find_particle(p, local_cells);
}
pl->n--;

assert(cell && cell->part && (n < cell->n) && ((cell->part + n) == p));

Particle p_destroy = extract_indexed_particle(cell, n);
}

void local_place_particle(int part, const double p[3], int _new) {
Expand Down
2 changes: 2 additions & 0 deletions src/core/particle_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
/************************************************/

Expand Down