From 2a5886686e9d815d14172150edfb72159460c26c Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Tue, 18 Feb 2020 00:41:46 +0100 Subject: [PATCH 1/6] core: particle_data: Access local_particles via functions --- src/core/cells.cpp | 4 +- src/core/collision.cpp | 28 +++++++------- src/core/debug.cpp | 12 +++--- src/core/domain_decomposition.cpp | 4 +- src/core/energy_inline.hpp | 6 +-- src/core/forces_inline.hpp | 6 +-- src/core/ghosts.cpp | 4 +- .../immersed_boundary/ImmersedBoundaries.cpp | 8 ++-- src/core/io/mpiio/mpiio.cpp | 6 +-- .../object-in-fluid/oif_global_forces.cpp | 8 ++-- src/core/particle_data.cpp | 38 +++++++++---------- src/core/particle_data.hpp | 20 ++++++++-- src/core/pressure_inline.hpp | 6 +-- src/core/rattle.cpp | 4 +- .../virtual_sites/VirtualSitesRelative.cpp | 14 ++++--- 15 files changed, 93 insertions(+), 75 deletions(-) diff --git a/src/core/cells.cpp b/src/core/cells.cpp index 705ad28dfcb..af0f1a15136 100644 --- a/src/core/cells.cpp +++ b/src/core/cells.cpp @@ -228,8 +228,8 @@ unsigned topology_check_resort(int cs, unsigned local_resort) { local_particles. */ static void invalidate_ghosts() { for (auto const &p : cell_structure.ghost_cells().particles()) { - if (local_particles[p.identity()] == &p) { - local_particles[p.identity()] = {}; + if (get_local_particle_data(p.identity()) == &p) { + set_local_particle_data(p.identity(), nullptr); } } diff --git a/src/core/collision.cpp b/src/core/collision.cpp index 781c0f1ffac..d2eeaf88987 100644 --- a/src/core/collision.cpp +++ b/src/core/collision.cpp @@ -66,7 +66,7 @@ Collision_parameters collision_params; namespace { Particle &get_part(int id) { - return assert(local_particles[id]), *local_particles[id]; + return assert(get_local_particle_data(id)), *local_particles[id]; } } // namespace @@ -382,7 +382,7 @@ void bind_at_poc_create_bond_between_vs(const int current_vs_pid, // Create bond between the virtual particles const int bondG[] = {collision_params.bond_vs, current_vs_pid - 2}; // Only add bond if vs was created on this node - if (local_particles[current_vs_pid - 1]) + if (get_local_particle_data(current_vs_pid - 1)) local_add_particle_bond(get_part(current_vs_pid - 1), bondG); break; } @@ -390,9 +390,9 @@ void bind_at_poc_create_bond_between_vs(const int current_vs_pid, // Create 1st bond between the virtual particles const int bondG[] = {collision_params.bond_vs, c.pp1, c.pp2}; // Only add bond if vs was created on this node - if (local_particles[current_vs_pid - 1]) + if (get_local_particle_data(current_vs_pid - 1)) local_add_particle_bond(get_part(current_vs_pid - 1), bondG); - if (local_particles[current_vs_pid - 2]) + if (get_local_particle_data(current_vs_pid - 2)) local_add_particle_bond(get_part(current_vs_pid - 2), bondG); break; } @@ -471,9 +471,9 @@ void three_particle_binding_domain_decomposition( for (auto &c : gathered_queue) { // If we have both particles, at least as ghosts, Get the corresponding cell // indices - if ((local_particles[c.pp1]) && (local_particles[c.pp2])) { - Particle &p1 = *local_particles[c.pp1]; - Particle &p2 = *local_particles[c.pp2]; + if (get_local_particle_data(c.pp1) && get_local_particle_data(c.pp2)) { + Particle &p1 = *get_local_particle_data(c.pp1); + Particle &p2 = *get_local_particle_data(c.pp2); auto cell1 = find_current_cell(p1); auto cell2 = find_current_cell(p2); @@ -504,7 +504,7 @@ void handle_collisions() { if (bind_centers()) { for (auto &c : local_collision_queue) { // put the bond to the non-ghost particle; at least one partner always is - if (local_particles[c.pp1]->l.ghost) { + if (get_local_particle_data(c.pp1)->l.ghost) { std::swap(c.pp1, c.pp2); } int bondG[2]; @@ -537,8 +537,8 @@ void handle_collisions() { for (auto &c : gathered_queue) { // Get particle pointers - Particle *p1 = local_particles[c.pp1]; - Particle *p2 = local_particles[c.pp2]; + Particle *p1 = get_local_particle_data(c.pp1); + Particle *p2 = get_local_particle_data(c.pp2); // Only nodes take part in particle creation and binding // that see both particles @@ -587,8 +587,8 @@ void handle_collisions() { p->identity()); // Particle storage locations may have changed due to // added particle - p1 = local_particles[c.pp1]; - p2 = local_particles[c.pp2]; + p1 = get_local_particle_data(c.pp1); + p2 = get_local_particle_data(c.pp2); } else { added_particle(current_vs_pid); } @@ -651,8 +651,8 @@ void handle_collisions() { attach_vs_to.identity()); // Particle storage locations may have changed due to // added particle - p1 = local_particles[c.pp1]; - p2 = local_particles[c.pp2]; + p1 = get_local_particle_data(c.pp1); + p2 = get_local_particle_data(c.pp2); current_vs_pid++; } else { // Just update the books added_particle(current_vs_pid); diff --git a/src/core/debug.cpp b/src/core/debug.cpp index b4cdf3a77e6..025d4a454f6 100644 --- a/src/core/debug.cpp +++ b/src/core/debug.cpp @@ -61,12 +61,12 @@ void check_particle_consistency() { errexit(); } } - if (local_particles[p.p.identity] != &p) { + if (get_local_particle_data(p.p.identity) != &p) { fprintf(stderr, "%d: check_particle_consistency: ERROR: address " "mismatch for part id %d: local: %p cell: %p in cell %d\n", this_node, p.p.identity, - static_cast(local_particles[p.p.identity]), + static_cast(get_local_particle_data(p.p.identity)), static_cast(&p), c); errexit(); } @@ -86,13 +86,13 @@ void check_particle_consistency() { /* checks: local particle id */ for (n = 0; n < max_seen_particle + 1; n++) { - if (local_particles[n] != nullptr) { + if (get_local_particle_data(n) != nullptr) { local_part_cnt++; - if (local_particles[n]->p.identity != n) { + if (get_local_particle_data(n)->p.identity != n) { fprintf(stderr, "%d: check_particle_consistency: ERROR: " "local_particles part %d has corrupted id %d\n", - this_node, n, local_particles[n]->p.identity); + this_node, n, get_local_particle_data(n)->p.identity); errexit(); } } @@ -119,7 +119,7 @@ void check_particle_consistency() { } for (int p = 0; p < n_part; p++) - if (local_particles[p]) + if (get_local_particle_data(p)) fprintf(stderr, "%d: got particle %d in local_particles\n", this_node, p); diff --git a/src/core/domain_decomposition.cpp b/src/core/domain_decomposition.cpp index 1812bfc11dd..6195c9b28e9 100644 --- a/src/core/domain_decomposition.cpp +++ b/src/core/domain_decomposition.cpp @@ -651,7 +651,7 @@ void move_if_local(ParticleList &src, ParticleList &rest) { for (int i = 0; i < src.n; i++) { auto &part = src.part[i]; - assert(local_particles[src.part[i].p.identity] == nullptr); + assert(get_local_particle_data(src.part[i].p.identity) == nullptr); auto target_cell = dd_save_position_to_cell(part.r.p); @@ -684,7 +684,7 @@ void move_left_or_right(ParticleList &src, ParticleList &left, for (int i = 0; i < src.n; i++) { auto &part = src.part[i]; - assert(local_particles[src.part[i].p.identity] == nullptr); + assert(get_local_particle_data(src.part[i].p.identity) == nullptr); if (get_mi_coord(part.r.p[dir], local_geo.my_left()[dir], box_geo.length()[dir], box_geo.periodic(dir)) < 0.0) { diff --git a/src/core/energy_inline.hpp b/src/core/energy_inline.hpp index dac7a9d6dd6..18faa587d26 100644 --- a/src/core/energy_inline.hpp +++ b/src/core/energy_inline.hpp @@ -215,7 +215,7 @@ inline void add_bonded_energy(Particle const *const p1) { int n_partners = iaparams.num; /* fetch particle 2, which is always needed */ - Particle const *const p2 = local_particles[p1->bl.e[i++]]; + Particle const *const p2 = get_local_particle_data(p1->bl.e[i++]); if (!p2) { runtimeErrorMsg() << "bond broken between particles " << p1->p.identity << " and " << p1->bl.e[i - 1] @@ -225,7 +225,7 @@ inline void add_bonded_energy(Particle const *const p1) { /* fetch particle 3 eventually */ if (n_partners >= 2) { - p3 = local_particles[p1->bl.e[i++]]; + p3 = get_local_particle_data(p1->bl.e[i++]); if (!p3) { runtimeErrorMsg() << "bond broken between particles " << p1->p.identity << ", " << p1->bl.e[i - 2] << " and " @@ -237,7 +237,7 @@ inline void add_bonded_energy(Particle const *const p1) { /* fetch particle 4 eventually */ if (n_partners >= 3) { - p4 = local_particles[p1->bl.e[i++]]; + p4 = get_local_particle_data(p1->bl.e[i++]); if (!p4) { runtimeErrorMsg() << "bond broken between particles " << p1->p.identity << ", " << p1->bl.e[i - 3] << ", " << p1->bl.e[i - 2] diff --git a/src/core/forces_inline.hpp b/src/core/forces_inline.hpp index 14428930d17..56bed97c31c 100644 --- a/src/core/forces_inline.hpp +++ b/src/core/forces_inline.hpp @@ -412,7 +412,7 @@ inline void add_bonded_force(Particle *const p1) { bool bond_broken = true; if (n_partners) { - p2 = local_particles[p1->bl.e[i++]]; + p2 = get_local_particle_data(p1->bl.e[i++]); if (!p2) { runtimeErrorMsg() << "bond broken between particles " << p1->p.identity; return; @@ -420,7 +420,7 @@ inline void add_bonded_force(Particle *const p1) { /* fetch particle 3 eventually */ if (n_partners >= 2) { - p3 = local_particles[p1->bl.e[i++]]; + p3 = get_local_particle_data(p1->bl.e[i++]); if (!p3) { runtimeErrorMsg() << "bond broken between particles " << p1->p.identity << ", " @@ -432,7 +432,7 @@ inline void add_bonded_force(Particle *const p1) { /* fetch particle 4 eventually */ if (n_partners >= 3) { - p4 = local_particles[p1->bl.e[i++]]; + p4 = get_local_particle_data(p1->bl.e[i++]); if (!p4) { runtimeErrorMsg() << "bond broken between particles " << p1->p.identity << ", " diff --git a/src/core/ghosts.cpp b/src/core/ghosts.cpp index f1327532481..21cf4cad83c 100644 --- a/src/core/ghosts.cpp +++ b/src/core/ghosts.cpp @@ -212,8 +212,8 @@ static void put_recv_buffer(CommBuf &recv_buffer, for (Particle &part : part_list->particles()) { if (data_parts & GHOSTTRANS_PROPRTS) { archiver >> part.p; - if (local_particles[part.p.identity] == nullptr) { - local_particles[part.p.identity] = ∂ + if (get_local_particle_data(part.p.identity) == nullptr) { + set_local_particle_data(part.p.identity, &part); } } if (data_parts & GHOSTTRANS_POSITION) { diff --git a/src/core/immersed_boundary/ImmersedBoundaries.cpp b/src/core/immersed_boundary/ImmersedBoundaries.cpp index 90a70c89194..35e97e8459e 100644 --- a/src/core/immersed_boundary/ImmersedBoundaries.cpp +++ b/src/core/immersed_boundary/ImmersedBoundaries.cpp @@ -168,7 +168,7 @@ void ImmersedBoundaries::calc_volumes() { if (type == BONDED_IA_IBM_TRIEL) { // Our particle is the leading particle of a triel // Get second and third particle of the triangle - Particle const *const p2 = local_particles[p1.bl.e[j + 1]]; + Particle const *const p2 = get_local_particle_data(p1.bl.e[j + 1]); if (!p2) { runtimeErrorMsg() << "{IBM_calc_volumes: 078 bond broken between particles " @@ -176,7 +176,7 @@ void ImmersedBoundaries::calc_volumes() { << " (particles not stored on the same node)} "; return; } - Particle const *const p3 = local_particles[p1.bl.e[j + 2]]; + Particle const *const p3 = get_local_particle_data(p1.bl.e[j + 2]); if (!p3) { runtimeErrorMsg() << "{IBM_calc_volumes: 078 bond broken between particles " @@ -277,8 +277,8 @@ void ImmersedBoundaries::calc_volume_force() { if (type == BONDED_IA_IBM_TRIEL) { // Our particle is the leading particle of a triel // Get second and third particle of the triangle - Particle &p2 = *local_particles[p1.bl.e[j + 1]]; - Particle &p3 = *local_particles[p1.bl.e[j + 2]]; + Particle &p2 = *get_local_particle_data(p1.bl.e[j + 1]); + Particle &p3 = *get_local_particle_data(p1.bl.e[j + 2]); // Unfold position of first node. // This is to get a continuous trajectory with no jumps when box diff --git a/src/core/io/mpiio/mpiio.cpp b/src/core/io/mpiio/mpiio.cpp index 191f0d2c745..d97034b827c 100644 --- a/src/core/io/mpiio/mpiio.cpp +++ b/src/core/io/mpiio/mpiio.cpp @@ -410,7 +410,7 @@ void mpi_mpiio_common_read(const char *filename, unsigned fields) { MPI_INT); for (int i = 0; i < nlocalpart; ++i) - local_particles[id[i]]->p.type = type[i]; + get_local_particle_data(id[i])->p.type = type[i]; } if (fields & MPIIO_OUT_VEL) { @@ -422,7 +422,7 @@ void mpi_mpiio_common_read(const char *filename, unsigned fields) { for (int i = 0; i < nlocalpart; ++i) for (int k = 0; k < 3; ++k) - local_particles[id[i]]->m.v[k] = vel[3 * i + k]; + get_local_particle_data(id[i])->m.v[k] = vel[3 * i + k]; } if (fields & MPIIO_OUT_BND) { @@ -445,7 +445,7 @@ void mpi_mpiio_common_read(const char *filename, unsigned fields) { for (int i = 0; i < nlocalpart; ++i) { int blen = boff[i + 1] - boff[i]; - auto &bl = local_particles[id[i]]->bl; + auto &bl = get_local_particle_data(id[i])->bl; bl.resize(blen); std::copy_n(bond.begin() + boff[i], blen, bl.begin()); } diff --git a/src/core/object-in-fluid/oif_global_forces.cpp b/src/core/object-in-fluid/oif_global_forces.cpp index b3956b29d4a..43f7bbd0ab6 100644 --- a/src/core/object-in-fluid/oif_global_forces.cpp +++ b/src/core/object-in-fluid/oif_global_forces.cpp @@ -82,7 +82,7 @@ void calc_oif_global(double *area_volume, int molType, id == molType) { // BONDED_IA_OIF_GLOBAL_FORCES with correct molType test++; /* fetch particle 2 */ - auto const p2 = local_particles[p1->bl.e[j++]]; + auto const p2 = get_local_particle_data(p1->bl.e[j++]); if (!p2) { runtimeErrorMsg() << "oif global calc: bond broken between particles " << p1->p.identity << " and " << p1->bl.e[j - 1] @@ -92,7 +92,7 @@ void calc_oif_global(double *area_volume, int molType, return; } - auto const p3 = local_particles[p1->bl.e[j++]]; + auto const p3 = get_local_particle_data(p1->bl.e[j++]); if (!p3) { runtimeErrorMsg() << "oif global calc: bond broken between particles " << p1->p.identity << ", " << p1->bl.e[j - 2] @@ -150,7 +150,7 @@ void add_oif_global_forces(double const *area_volume, int molType, id == molType) { // BONDED_IA_OIF_GLOBAL_FORCES with correct molType test++; /* fetch particle 2 */ - auto p2 = local_particles[p1->bl.e[j++]]; + auto p2 = get_local_particle_data(p1->bl.e[j++]); if (!p2) { runtimeErrorMsg() << "add area: bond broken between particles " << p1->p.identity << " and " << p1->bl.e[j - 1] @@ -161,7 +161,7 @@ void add_oif_global_forces(double const *area_volume, int molType, } /* fetch particle 3 */ // if(n_partners>2){ - auto p3 = local_particles[p1->bl.e[j++]]; + auto p3 = get_local_particle_data(p1->bl.e[j++]); if (!p3) { runtimeErrorMsg() << "add area: bond broken between particles " << p1->p.identity diff --git a/src/core/particle_data.cpp b/src/core/particle_data.cpp index a5778045c74..b44196a647e 100644 --- a/src/core/particle_data.cpp +++ b/src/core/particle_data.cpp @@ -312,8 +312,8 @@ struct UpdateVisitor : public boost::static_visitor { } /* Plain messages are just called. */ template void operator()(const Message &msg) const { - assert(local_particles[id]); - msg(*local_particles[id]); + assert(get_local_particle_data(id)); + msg(*get_local_particle_data(id)); } }; } // namespace @@ -513,7 +513,7 @@ void update_local_particles(ParticleList *pl) { Particle *p = pl->part; int n = pl->n, i; for (i = 0; i < n; i++) - local_particles[p[i].p.identity] = &p[i]; + set_local_particle_data(p[i].p.identity, &p[i]); } void append_unindexed_particle(ParticleList *l, Particle &&part) { @@ -530,7 +530,7 @@ Particle *append_indexed_particle(ParticleList *l, Particle &&part) { if (re) update_local_particles(l); else - local_particles[p->p.identity] = p; + set_local_particle_data(p->p.identity, p); return p; } @@ -567,7 +567,7 @@ Particle *move_indexed_particle(ParticleList *dl, ParticleList *sl, int i) { if (re) { update_local_particles(dl); } else { - local_particles[dst->p.identity] = dst; + set_local_particle_data(dst->p.identity, dst); } if (src != end) { new (src) Particle(std::move(*end)); @@ -576,7 +576,7 @@ Particle *move_indexed_particle(ParticleList *dl, ParticleList *sl, int i) { if (sl->resize(sl->n - 1)) { update_local_particles(sl); } else if (src != end) { - local_particles[src->p.identity] = src; + set_local_particle_data(src->p.identity, src); } return dst; } @@ -602,7 +602,7 @@ Particle extract_indexed_particle(ParticleList *sl, int i) { Particle p = std::move(*src); assert(p.p.identity <= max_seen_particle); - local_particles[p.p.identity] = nullptr; + set_local_particle_data(p.p.identity, nullptr); if (src != end) { new (src) Particle(std::move(*end)); @@ -611,7 +611,7 @@ Particle extract_indexed_particle(ParticleList *sl, int i) { if (sl->resize(sl->n - 1)) { update_local_particles(sl); } else if (src != end) { - local_particles[src->p.identity] = src; + set_local_particle_data(src->p.identity, src); } return p; } @@ -625,7 +625,7 @@ Utils::Cache particle_fetch_cache(max_cache_size); void invalidate_fetch_cache() { particle_fetch_cache.invalidate(); } boost::optional get_particle_data_local(int id) { - auto p = local_particles[id]; + auto p = get_local_particle_data(id); if (p and (not p->l.ghost)) { return *p; @@ -640,8 +640,8 @@ const Particle &get_particle_data(int part) { auto const pnode = get_particle_node(part); if (pnode == this_node) { - assert(local_particles[part]); - return *local_particles[part]; + assert(get_local_particle_data(part)); + return *get_local_particle_data(part); } /* Query the cache */ @@ -664,8 +664,8 @@ void mpi_get_particles_slave(int, int) { std::vector parts(ids.size()); std::transform(ids.begin(), ids.end(), parts.begin(), [](int id) { - assert(local_particles[id]); - return *local_particles[id]; + assert(get_local_particle_data(id)); + return *get_local_particle_data(id); }); Utils::Mpi::gatherv(comm_cart, parts.data(), parts.size(), 0); @@ -702,8 +702,8 @@ std::vector mpi_get_particles(std::vector const &ids) { /* Copy local particles */ std::transform(node_ids[this_node].cbegin(), node_ids[this_node].cend(), parts.begin(), [](int id) { - assert(local_particles[id]); - return *local_particles[id]; + assert(get_local_particle_data(id)); + return *get_local_particle_data(id); }); std::vector node_sizes(comm_cart.size()); @@ -1093,7 +1093,7 @@ Particle *local_place_particle(int id, const Utils::Vector3d &pos, int _new) { return append_indexed_particle(cell, std::move(new_part)); } - auto pt = local_particles[id]; + auto pt = get_local_particle_data(id); pt->r.p = pp; pt->l.i = i; @@ -1195,7 +1195,7 @@ void local_change_exclusion(int part1, int part2, int _delete) { } /* part1, if here */ - auto part = local_particles[part1]; + auto part = get_local_particle_data(part1); if (part) { if (_delete) try_delete_exclusion(part, part2); @@ -1204,7 +1204,7 @@ void local_change_exclusion(int part1, int part2, int _delete) { } /* part2, if here */ - part = local_particles[part2]; + part = get_local_particle_data(part2); if (part) { if (_delete) try_delete_exclusion(part, part1); @@ -1236,7 +1236,7 @@ void send_particles(ParticleList *particles, int node) { /* remove particles from this nodes local list and free data */ for (int pc = 0; pc < particles->n; pc++) { - local_particles[particles->part[pc].p.identity] = nullptr; + set_local_particle_data(particles->part[pc].p.identity, nullptr); free_particle(&particles->part[pc]); } diff --git a/src/core/particle_data.hpp b/src/core/particle_data.hpp index d021bb13051..7229c3f82f5 100644 --- a/src/core/particle_data.hpp +++ b/src/core/particle_data.hpp @@ -87,11 +87,25 @@ extern int n_part; /** flag that active swimming particles exist */ extern bool swimming_particles_exist; -/** id->particle mapping on all nodes. This is used to find partners - * of bonded interactions. - */ extern std::vector local_particles; +/** + * @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) { return local_particles[id]; } + +inline void set_local_particle_data(int id, Particle *p) { + local_particles[id] = p; +} + /************************************************ * Functions ************************************************/ diff --git a/src/core/pressure_inline.hpp b/src/core/pressure_inline.hpp index 5c8fb62a8a9..4d6a3d9c1ba 100644 --- a/src/core/pressure_inline.hpp +++ b/src/core/pressure_inline.hpp @@ -150,7 +150,7 @@ inline void add_bonded_virials(Particle const &p1) { } /* fetch particle 2 */ - Particle const *const p2 = local_particles[p1.bl.e[i++]]; + Particle const *const p2 = get_local_particle_data(p1.bl.e[i++]); if (!p2) { // for harmonic spring: // if cutoff was defined and p2 is not there it is anyway outside the @@ -197,8 +197,8 @@ inline void add_three_body_bonded_stress(Particle const &p1) { i += 1 + iaparams.num; continue; } - Particle const &p2 = *local_particles[p1.bl.e[i + 1]]; - Particle const &p3 = *local_particles[p1.bl.e[i + 2]]; + Particle const &p2 = *get_local_particle_data(p1.bl.e[i + 1]); + Particle const &p3 = *get_local_particle_data(p1.bl.e[i + 2]); auto const dx21 = -get_mi_vector(p1.r.p, p2.r.p, box_geo); auto const dx31 = get_mi_vector(p3.r.p, p1.r.p, box_geo); diff --git a/src/core/rattle.cpp b/src/core/rattle.cpp index 976c4b3b434..5d14d0e7d46 100644 --- a/src/core/rattle.cpp +++ b/src/core/rattle.cpp @@ -114,7 +114,7 @@ void compute_pos_corr_vec(int *repeat_, const ParticleRange &particles) { while (k < p1.bl.n) { Bonded_ia_parameters const &ia_params = bonded_ia_params[p1.bl.e[k++]]; if (ia_params.type == BONDED_IA_RIGID_BOND) { - Particle *const pp2 = local_particles[p1.bl.e[k++]]; + Particle *const pp2 = get_local_particle_data(p1.bl.e[k++]); if (!pp2) { runtimeErrorMsg() << "rigid bond broken between particles " << p1.p.identity << " and " << p1.bl.e[k - 1] @@ -219,7 +219,7 @@ void compute_vel_corr_vec(int *repeat_, const ParticleRange &particles) { while (k < p1.bl.n) { Bonded_ia_parameters const &ia_params = bonded_ia_params[p1.bl.e[k++]]; if (ia_params.type == BONDED_IA_RIGID_BOND) { - Particle *const pp2 = local_particles[p1.bl.e[k++]]; + Particle *const pp2 = get_local_particle_data(p1.bl.e[k++]); if (!pp2) { runtimeErrorMsg() << "rigid bond broken between particles " << p1.p.identity << " and " << p1.bl.e[k - 1] diff --git a/src/core/virtual_sites/VirtualSitesRelative.cpp b/src/core/virtual_sites/VirtualSitesRelative.cpp index a9574fecc1c..5dc59824aa8 100644 --- a/src/core/virtual_sites/VirtualSitesRelative.cpp +++ b/src/core/virtual_sites/VirtualSitesRelative.cpp @@ -60,7 +60,8 @@ void VirtualSitesRelative::update(bool recalc_positions) const { void VirtualSitesRelative::update_virtual_particle_quaternion( Particle &p) const { - const Particle *p_real = local_particles[p.p.vs_relative.to_particle_id]; + const Particle *p_real = + get_local_particle_data(p.p.vs_relative.to_particle_id); if (!p_real) { throw std::runtime_error( "virtual_sites_relative.cpp - update_mol_pos_particle(): No real " @@ -73,7 +74,8 @@ void VirtualSitesRelative::update_pos(Particle &p) const { // First obtain the real particle responsible for this virtual particle: // Find the 1st real particle in the topology for the virtual particle's // mol_id - const Particle *p_real = local_particles[p.p.vs_relative.to_particle_id]; + const Particle *p_real = + get_local_particle_data(p.p.vs_relative.to_particle_id); // Check, if a real particle was found if (!p_real) { runtimeErrorMsg() @@ -106,7 +108,7 @@ void VirtualSitesRelative::update_pos(Particle &p) const { void VirtualSitesRelative::update_vel(Particle &p) const { // First obtain the real particle responsible for this virtual particle: - Particle *p_real = local_particles[p.p.vs_relative.to_particle_id]; + Particle *p_real = get_local_particle_data(p.p.vs_relative.to_particle_id); // Check, if a real particle was found if (!p_real) { runtimeErrorMsg() @@ -137,7 +139,8 @@ void VirtualSitesRelative::back_transfer_forces_and_torques() const { // We only care about virtual particles if (p.p.is_virtual) { // First obtain the real particle responsible for this virtual particle: - Particle *p_real = local_particles[p.p.vs_relative.to_particle_id]; + Particle *p_real = + get_local_particle_data(p.p.vs_relative.to_particle_id); // The rules for transferring forces are: // F_realParticle +=F_virtualParticle @@ -166,7 +169,8 @@ void VirtualSitesRelative::pressure_and_stress_tensor_contribution( update_pos(p); // First obtain the real particle responsible for this virtual particle: - const Particle *p_real = local_particles[p.p.vs_relative.to_particle_id]; + const Particle *p_real = + get_local_particle_data(p.p.vs_relative.to_particle_id); // Get distance vector pointing from real to virtual particle, respecting // periodic boundary i From 0452232c8b5adca46099046a8122299348b858f3 Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Tue, 18 Feb 2020 01:02:32 +0100 Subject: [PATCH 2/6] core: part_cfg: Directly get particles from cells, not thru local_particles --- src/core/PartCfg.hpp | 27 +-------------------------- src/core/collision.cpp | 2 +- src/core/particle_data.hpp | 8 +++++++- 3 files changed, 9 insertions(+), 28 deletions(-) diff --git a/src/core/PartCfg.hpp b/src/core/PartCfg.hpp index 766ca5503e5..11c8bff4f57 100644 --- a/src/core/PartCfg.hpp +++ b/src/core/PartCfg.hpp @@ -35,33 +35,8 @@ * @brief Proxy class that gets a particle range from #local_particles. */ class GetLocalParts { - class SkipIfNullOrGhost { - public: - bool operator()(Particle const *p_ptr) const { - return (p_ptr == nullptr) or (p_ptr->l.ghost); - } - }; - - using skip_it = Utils::SkipIterator; - using iterator = boost::indirect_iterator; - using Range = boost::iterator_range; - public: - Range operator()() const { - if (local_particles.empty()) { - auto begin = skip_it(nullptr, nullptr, SkipIfNullOrGhost()); - return {make_indirect_iterator(begin), make_indirect_iterator(begin)}; - } - - auto begin = skip_it(local_particles.data(), - local_particles.data() + max_seen_particle + 1, - SkipIfNullOrGhost()); - auto end = skip_it(local_particles.data() + max_seen_particle + 1, - local_particles.data() + max_seen_particle + 1, - SkipIfNullOrGhost()); - - return {make_indirect_iterator(begin), make_indirect_iterator(end)}; - } + auto operator()() const { return cell_structure.local_cells().particles(); } }; /** Unfold coordinates to physical position. */ diff --git a/src/core/collision.cpp b/src/core/collision.cpp index d2eeaf88987..2a499b912d1 100644 --- a/src/core/collision.cpp +++ b/src/core/collision.cpp @@ -66,7 +66,7 @@ Collision_parameters collision_params; namespace { Particle &get_part(int id) { - return assert(get_local_particle_data(id)), *local_particles[id]; + return assert(get_local_particle_data(id)), *get_local_particle_data(id); } } // namespace diff --git a/src/core/particle_data.hpp b/src/core/particle_data.hpp index 7229c3f82f5..6367be94252 100644 --- a/src/core/particle_data.hpp +++ b/src/core/particle_data.hpp @@ -100,9 +100,15 @@ extern std::vector local_particles; * * @return Pointer to particle or nullptr. **/ -inline Particle *get_local_particle_data(int id) { return local_particles[id]; } +inline Particle *get_local_particle_data(int id) { + extern std::vector local_particles; + + return local_particles[id]; +} inline void set_local_particle_data(int id, Particle *p) { + extern std::vector local_particles; + local_particles[id] = p; } From 49f36422f06c208f483de626a6a5c627cf7a6f16 Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Tue, 18 Feb 2020 01:14:34 +0100 Subject: [PATCH 3/6] core: Header cleanup --- src/core/PartCfg.hpp | 5 ----- src/core/communication.cpp | 1 + src/core/energy_inline.hpp | 1 + src/core/event.cpp | 1 + src/core/io/writer/h5md_core.cpp | 1 + src/core/layered.cpp | 1 + src/core/nsquare.cpp | 1 + src/core/reaction_ensemble.hpp | 2 ++ src/core/virtual_sites.cpp | 1 + 9 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/core/PartCfg.hpp b/src/core/PartCfg.hpp index 11c8bff4f57..e3f72725ccb 100644 --- a/src/core/PartCfg.hpp +++ b/src/core/PartCfg.hpp @@ -23,13 +23,8 @@ #include "ParticleCache.hpp" #include "cells.hpp" #include "grid.hpp" -#include "particle_data.hpp" #include "serialization/Particle.hpp" -#include - -#include -#include /** * @brief Proxy class that gets a particle range from #local_particles. diff --git a/src/core/communication.cpp b/src/core/communication.cpp index 620913beec1..0091b0b4908 100644 --- a/src/core/communication.cpp +++ b/src/core/communication.cpp @@ -54,6 +54,7 @@ #include "nonbonded_interactions/nonbonded_tab.hpp" #include "npt.hpp" #include "partCfg_global.hpp" +#include "particle_data.hpp" #include "pressure.hpp" #include "rotation.hpp" #include "statistics.hpp" diff --git a/src/core/energy_inline.hpp b/src/core/energy_inline.hpp index 18faa587d26..02d89a9cfe2 100644 --- a/src/core/energy_inline.hpp +++ b/src/core/energy_inline.hpp @@ -61,6 +61,7 @@ #include "bonded_interactions/bonded_coulomb_sr.hpp" #include "electrostatics_magnetostatics/coulomb_inline.hpp" #endif +#include "particle_data.hpp" #include "statistics.hpp" #include "energy.hpp" diff --git a/src/core/event.cpp b/src/core/event.cpp index 7408cf57559..723410fda4a 100644 --- a/src/core/event.cpp +++ b/src/core/event.cpp @@ -46,6 +46,7 @@ #include "npt.hpp" #include "nsquare.hpp" #include "partCfg_global.hpp" +#include "particle_data.hpp" #include "pressure.hpp" #include "random.hpp" #include "rattle.hpp" diff --git a/src/core/io/writer/h5md_core.cpp b/src/core/io/writer/h5md_core.cpp index 69294efcccf..c47b3365d8e 100644 --- a/src/core/io/writer/h5md_core.cpp +++ b/src/core/io/writer/h5md_core.cpp @@ -24,6 +24,7 @@ #include "communication.hpp" #include "grid.hpp" #include "integrate.hpp" +#include "particle_data.hpp" #include "version.hpp" #include diff --git a/src/core/layered.cpp b/src/core/layered.cpp index 98cb8018c8f..68f63dec62c 100644 --- a/src/core/layered.cpp +++ b/src/core/layered.cpp @@ -29,6 +29,7 @@ #include "errorhandling.hpp" #include "ghosts.hpp" #include "global.hpp" +#include "particle_data.hpp" #include diff --git a/src/core/nsquare.cpp b/src/core/nsquare.cpp index fa387ad8c2e..22cdffaf585 100644 --- a/src/core/nsquare.cpp +++ b/src/core/nsquare.cpp @@ -27,6 +27,7 @@ #include "communication.hpp" #include "constraints.hpp" #include "ghosts.hpp" +#include "particle_data.hpp" #include diff --git a/src/core/reaction_ensemble.hpp b/src/core/reaction_ensemble.hpp index 6a8ca2cd36f..a6a97ab7453 100644 --- a/src/core/reaction_ensemble.hpp +++ b/src/core/reaction_ensemble.hpp @@ -20,7 +20,9 @@ #define REACTION_ENSEMBLE_H #include "energy.hpp" +#include "particle_data.hpp" #include "random.hpp" + #include #include #include diff --git a/src/core/virtual_sites.cpp b/src/core/virtual_sites.cpp index 51d6ef85dc6..1e6c5a75ec9 100644 --- a/src/core/virtual_sites.cpp +++ b/src/core/virtual_sites.cpp @@ -27,6 +27,7 @@ #include "errorhandling.hpp" #include "event.hpp" #include "integrate.hpp" +#include "particle_data.hpp" #include "rotation.hpp" #include "statistics.hpp" From 6ae3a1f55878ac4ad25007ec58a37e9d03ee9dcc Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Tue, 18 Feb 2020 01:53:13 +0100 Subject: [PATCH 4/6] core: particle_data: Resize local_particles automatically. --- src/core/collision.cpp | 3 - src/core/io/mpiio/mpiio.cpp | 3 - src/core/particle_data.cpp | 16 ---- src/core/particle_data.hpp | 20 +++-- src/utils/include/utils/SkipIterator.hpp | 94 ------------------------ src/utils/tests/CMakeLists.txt | 1 - src/utils/tests/SkipIterator_test.cpp | 78 -------------------- 7 files changed, 15 insertions(+), 200 deletions(-) delete mode 100644 src/utils/include/utils/SkipIterator.hpp delete mode 100644 src/utils/tests/SkipIterator_test.cpp diff --git a/src/core/collision.cpp b/src/core/collision.cpp index 2a499b912d1..b2d96feff31 100644 --- a/src/core/collision.cpp +++ b/src/core/collision.cpp @@ -528,9 +528,6 @@ void handle_collisions() { MPI_Allreduce(MPI_IN_PLACE, &max_seen_particle, 1, MPI_INT, MPI_MAX, comm_cart); - // Make sure, the local_particles array is long enough - realloc_local_particles(max_seen_particle); - int current_vs_pid = max_seen_particle + 1; // Iterate over global collision queue diff --git a/src/core/io/mpiio/mpiio.cpp b/src/core/io/mpiio/mpiio.cpp index d97034b827c..cd4f34e9f5c 100644 --- a/src/core/io/mpiio/mpiio.cpp +++ b/src/core/io/mpiio/mpiio.cpp @@ -377,9 +377,6 @@ void mpi_mpiio_common_read(const char *filename, unsigned fields) { // Determine nlocalpart (prefix of rank+1 - own prefix) on every node. read_prefs(fnam + ".pref", rank, size, nglobalpart, &pref, &nlocalpart); - // Prepare ESPResSo data structures - local_particles.resize(nglobalpart); - std::fill(local_particles.begin(), local_particles.end(), nullptr); n_part = nglobalpart; max_seen_particle = nglobalpart; diff --git a/src/core/particle_data.cpp b/src/core/particle_data.cpp index b44196a647e..3c866e31630 100644 --- a/src/core/particle_data.cpp +++ b/src/core/particle_data.cpp @@ -495,20 +495,6 @@ void clear_particle_node() { particle_node.clear(); } * organizational functions ************************************************/ -/** resize \ref local_particles. - \param part the highest existing particle -*/ -void realloc_local_particles(int part) { - constexpr auto INCREMENT = 8; - - if (part >= local_particles.size()) { - /* increase vector size by round up part + 1 in granularity INCREMENT and - * set new memory to nullptr */ - local_particles.resize(INCREMENT * ((part + INCREMENT) / INCREMENT), - nullptr); - } -} - void update_local_particles(ParticleList *pl) { Particle *p = pl->part; int n = pl->n, i; @@ -1133,8 +1119,6 @@ void added_particle(int part) { n_part++; if (part > max_seen_particle) { - realloc_local_particles(part); - max_seen_particle = part; } } diff --git a/src/core/particle_data.hpp b/src/core/particle_data.hpp index 6367be94252..5e9977bec8a 100644 --- a/src/core/particle_data.hpp +++ b/src/core/particle_data.hpp @@ -87,8 +87,6 @@ extern int n_part; /** flag that active swimming particles exist */ extern bool swimming_particles_exist; -extern std::vector local_particles; - /** * @brief Find local particles by id. * @@ -103,12 +101,27 @@ extern std::vector local_particles; 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; } @@ -181,9 +194,6 @@ void update_local_particles(ParticleList *pl); */ void clear_particle_node(); -/** Realloc \ref local_particles. */ -void realloc_local_particles(int part); - /** * @brief Get particle data. * diff --git a/src/utils/include/utils/SkipIterator.hpp b/src/utils/include/utils/SkipIterator.hpp deleted file mode 100644 index 4f4cf2afd79..00000000000 --- a/src/utils/include/utils/SkipIterator.hpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2010-2019 The ESPResSo project - * - * This file is part of ESPResSo. - * - * ESPResSo is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ESPResSo is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef CORE_UTILS_SKIP_ITERATOR_HPP -#define CORE_UTILS_SKIP_ITERATOR_HPP - -#include -#include -#include - -namespace Utils { - -/** - * @brief Transform iterator that skips all elements - * in the underlying iterator if a predicate - * is true. - * - * Example: - * @code{.cpp} - * auto a = {1, 2, ,3 ,4 ,5}; - * it = make_skip_iterator(std::begin(a), std::end(a), - * [](int i) { return i % 2 != 0;}); - * @endcode - * Then the resulting range is {2, 4}. - */ -template ::value_type> -class SkipIterator : public boost::iterator_facade< - SkipIterator, - ValueType, boost::forward_traversal_tag> { - ForwardIterator m_it, m_end; - Predicate m_p; - -public: - SkipIterator(ForwardIterator const &it, ForwardIterator const &end, - Predicate const &pred) - : m_it(it), m_end(end), m_p(pred) { - /* increment until the first element that is not skipped. */ - if ((m_it != m_end) && m_p(*m_it)) - increment(); - } - -private: - friend class boost::iterator_core_access; - - void increment() { - /* Never increment past the end */ - if (m_it == m_end) - return; - - do { - ++m_it; - /* Order in the condition is important to - avoid dereferencing the end iterator. */ - } while ((m_it != m_end) && m_p(*m_it)); - } - - bool equal(SkipIterator const &other) const { return m_it == other.m_it; } - - ValueType &dereference() const { - assert((m_it != m_end) && (!m_p(*m_it))); - return *m_it; - } -}; - -/** - * @brief Use template type deduction to create a SkipIterator with - * the correct type. - */ -template > -SkipIter make_skip_iterator(ForwardIterator const &it, - ForwardIterator const &end, Predicate const &pred) { - return SkipIter(it, end, pred); -} -} // namespace Utils - -#endif diff --git a/src/utils/tests/CMakeLists.txt b/src/utils/tests/CMakeLists.txt index 797b838f931..8ae781891fd 100644 --- a/src/utils/tests/CMakeLists.txt +++ b/src/utils/tests/CMakeLists.txt @@ -6,7 +6,6 @@ unit_test(NAME Factory_test SRC Factory_test.cpp DEPENDS utils) unit_test(NAME NumeratedContainer_test SRC NumeratedContainer_test.cpp DEPENDS utils) unit_test(NAME make_function_test SRC make_function_test.cpp DEPENDS utils) unit_test(NAME List_test SRC List_test.cpp DEPENDS Boost::serialization utils) -unit_test(NAME SkipIterator_test SRC SkipIterator_test.cpp DEPENDS utils) unit_test(NAME keys_test SRC keys_test.cpp DEPENDS utils) unit_test(NAME Cache_test SRC Cache_test.cpp DEPENDS utils) unit_test(NAME histogram SRC histogram.cpp DEPENDS utils) diff --git a/src/utils/tests/SkipIterator_test.cpp b/src/utils/tests/SkipIterator_test.cpp deleted file mode 100644 index bc40da21b31..00000000000 --- a/src/utils/tests/SkipIterator_test.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2010-2019 The ESPResSo project - * - * This file is part of ESPResSo. - * - * ESPResSo is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ESPResSo is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include -#include -#include -#include - -#define BOOST_TEST_MODULE SkipIterator test -#define BOOST_TEST_DYN_LINK -#include - -#include "utils/SkipIterator.hpp" - -BOOST_AUTO_TEST_CASE(skip) { - using Utils::make_skip_iterator; - - std::vector data(50); - std::iota(data.begin(), data.end(), 1); - - auto multiple_of_3 = [](int i) -> bool { return (i % 3) == 0; }; - - auto begin = make_skip_iterator(data.begin(), data.end(), multiple_of_3); - auto end = make_skip_iterator(data.end(), data.end(), multiple_of_3); - - for (; begin != end; ++begin) { - BOOST_CHECK(!multiple_of_3(*begin)); - } -} - -BOOST_AUTO_TEST_CASE(empty) { - using Utils::make_skip_iterator; - - std::vector data(50); - std::iota(data.begin(), data.end(), 1); - - auto always_true = [](int) -> bool { return true; }; - - auto begin = make_skip_iterator(data.begin(), data.end(), always_true); - auto end = make_skip_iterator(data.end(), data.end(), always_true); - - BOOST_CHECK(begin == end); -} - -BOOST_AUTO_TEST_CASE(gap) { - using Utils::make_skip_iterator; - - std::vector values; - - for (int i = 1; i <= 10; i++) { - values.push_back(i); - for (int j = 0; j < i; j++) { - values.push_back(0); - } - } - - auto zero = [](int i) -> bool { return i == 0; }; - - auto begin = make_skip_iterator(values.begin(), values.end(), zero); - auto end = make_skip_iterator(values.end(), values.end(), zero); - - BOOST_CHECK(std::distance(begin, end) == 10); -} From 53e82b8e8e5b2de665671162d2f50a25784c7309 Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Tue, 18 Feb 2020 14:29:39 +0100 Subject: [PATCH 5/6] core: Fixed missing header --- src/core/grid_based_algorithms/lbgpu.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/grid_based_algorithms/lbgpu.cpp b/src/core/grid_based_algorithms/lbgpu.cpp index 7131ebc06d8..e1d118c3f6d 100644 --- a/src/core/grid_based_algorithms/lbgpu.cpp +++ b/src/core/grid_based_algorithms/lbgpu.cpp @@ -37,6 +37,7 @@ #include "integrate.hpp" #include "nonbonded_interactions/nonbonded_interaction_data.hpp" #include "statistics.hpp" +#include "particle_data.hpp" #include From 836d921c2f75ee9b9da89ba1c2fb0ed2ce37ebf2 Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Tue, 18 Feb 2020 14:40:58 +0100 Subject: [PATCH 6/6] core: coldet: Explicitly throw when particle is missing. --- src/core/collision.cpp | 9 ++++++++- src/core/grid_based_algorithms/lbgpu.cpp | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/collision.cpp b/src/core/collision.cpp index b2d96feff31..0992b481a4c 100644 --- a/src/core/collision.cpp +++ b/src/core/collision.cpp @@ -66,7 +66,14 @@ Collision_parameters collision_params; namespace { Particle &get_part(int id) { - return assert(get_local_particle_data(id)), *get_local_particle_data(id); + auto const p = get_local_particle_data(id); + + if (not p) { + throw std::runtime_error("Could not handle collision because particle " + + std::to_string(id) + " was not found."); + } + + return *p; } } // namespace diff --git a/src/core/grid_based_algorithms/lbgpu.cpp b/src/core/grid_based_algorithms/lbgpu.cpp index e1d118c3f6d..2034dff06f1 100644 --- a/src/core/grid_based_algorithms/lbgpu.cpp +++ b/src/core/grid_based_algorithms/lbgpu.cpp @@ -36,8 +36,8 @@ #include "grid_based_algorithms/lbgpu.hpp" #include "integrate.hpp" #include "nonbonded_interactions/nonbonded_interaction_data.hpp" -#include "statistics.hpp" #include "particle_data.hpp" +#include "statistics.hpp" #include