Loading [MathJax]/extensions/tex2jax.js
ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
AtomDecomposition.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010
4 * Max-Planck-Institute for Polymer Research, Theory Group
5 *
6 * This file is part of ESPResSo.
7 *
8 * ESPResSo is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * ESPResSo is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
23
24#include "cell_system/Cell.hpp"
25
26#include <utils/Vector.hpp>
27
28#include <boost/mpi/collectives/all_to_all.hpp>
29
30#include <cstddef>
31#include <limits>
32#include <utility>
33#include <vector>
34
35void AtomDecomposition::configure_neighbors() {
36 std::vector<Cell *> red_neighbors;
37 std::vector<Cell *> black_neighbors;
38
39 /* distribute force calculation work */
40 for (int n = 0; n < m_comm.size(); n++) {
41 if (m_comm.rank() == n) {
42 continue;
43 }
44
45 if (n < m_comm.rank()) {
46 red_neighbors.push_back(&cells.at(n));
47 } else {
48 black_neighbors.push_back(&cells.at(n));
49 }
50 }
51
52 local().m_neighbors = Neighbors<Cell *>(red_neighbors, black_neighbors);
53}
54
55GhostCommunicator AtomDecomposition::prepare_comm() {
56 /* no need for comm for only 1 node */
57 if (m_comm.size() == 1) {
58 return GhostCommunicator{m_comm, 0};
59 }
60
61 auto ghost_comm =
62 GhostCommunicator{m_comm, static_cast<std::size_t>(m_comm.size())};
63 /* every node has its dedicated comm step */
64 for (int n = 0; n < m_comm.size(); n++) {
65 ghost_comm.communications[n].part_lists.resize(1);
66 ghost_comm.communications[n].part_lists[0] = &(cells.at(n).particles());
67 ghost_comm.communications[n].node = n;
68 }
69
70 return ghost_comm;
71}
72
73void AtomDecomposition::configure_comms() {
74 m_exchange_ghosts_comm = prepare_comm();
75 m_collect_ghost_force_comm = prepare_comm();
76
77 if (m_comm.size() > 1) {
78 for (int n = 0; n < m_comm.size(); n++) {
79 /* use the prefetched send buffers. Node 0 transmits first and never
80 * prefetches. */
81 if (m_comm.rank() == 0 || m_comm.rank() != n) {
82 m_exchange_ghosts_comm.communications[n].type = GHOST_BCST;
83 } else {
84 m_exchange_ghosts_comm.communications[n].type =
86 }
87 m_collect_ghost_force_comm.communications[n].type = GHOST_RDCE;
88 }
89 /* first round: all nodes except the first one prefetch their send data */
90 if (m_comm.rank() != 0) {
91 m_exchange_ghosts_comm.communications[0].type |= GHOST_PREFETCH;
92 }
93 }
94}
95
96void AtomDecomposition::mark_cells() {
97 m_local_cells.resize(1, std::addressof(local()));
98 m_ghost_cells.clear();
99 for (int n = 0; n < m_comm.size(); n++) {
100 if (n != m_comm.rank()) {
101 m_ghost_cells.push_back(std::addressof(cells.at(n)));
102 }
103 }
104}
105
106void AtomDecomposition::resort(bool global_flag,
107 std::vector<ParticleChange> &diff) {
108 for (auto &p : local().particles()) {
109 m_box.fold_position(p.pos(), p.image_box());
110
111 p.pos_at_last_verlet_update() = p.pos();
112 }
113
114 /* Local updates are a NoOp for this decomposition. */
115 if (not global_flag) {
116 return;
117 }
118
119 /* Sort displaced particles by the node they belong to. */
120 std::vector<std::vector<Particle>> send_buf(m_comm.size());
121 for (auto it = local().particles().begin();
122 it != local().particles().end();) {
123 auto const target_node = id_to_rank(it->id());
124 if (target_node != m_comm.rank()) {
125 diff.emplace_back(RemovedParticle{it->id()});
126 send_buf.at(target_node).emplace_back(std::move(*it));
127 it = local().particles().erase(it);
128 } else {
129 ++it;
130 }
131 }
132
133 /* Exchange particles */
134 std::vector<std::vector<Particle>> recv_buf(m_comm.size());
135 boost::mpi::all_to_all(m_comm, send_buf, recv_buf);
136
137 diff.emplace_back(ModifiedList{local().particles()});
138
139 /* Add new particles belonging to this node */
140 for (auto &parts : recv_buf) {
141 for (auto &p : parts) {
142 local().particles().insert(std::move(p));
143 }
144 }
145}
146
148 : m_box(box_geo) {}
149
150AtomDecomposition::AtomDecomposition(boost::mpi::communicator comm,
151 BoxGeometry const &box_geo)
152 : m_comm(std::move(comm)), cells(m_comm.size()), m_box(box_geo) {
153 /* create communicators */
154 configure_comms();
155 /* configure neighbor relations */
156 configure_neighbors();
157 /* fill local and ghost cell lists */
158 mark_cells();
159}
160
162 return Utils::Vector3d::broadcast(std::numeric_limits<double>::infinity());
163}
164
Vector implementation and trait types for boost qvm interoperability.
Utils::Vector3d max_range() const override
AtomDecomposition(BoxGeometry const &m_box)
Utils::Vector3d max_cutoff() const override
void resort(bool global_flag, std::vector< ParticleChange > &diff) override
void fold_position(Utils::Vector3d &pos, Utils::Vector3i &image_box) const
Fold coordinates to primary simulation box in-place.
neighbors_type m_neighbors
Definition Cell.hpp:106
auto & particles()
Particles.
Definition Cell.hpp:103
static DEVICE_QUALIFIER constexpr Vector< T, N > broadcast(typename Base::value_type const &value) noexcept
Create a vector that has all entries set to the same value.
Definition Vector.hpp:111
#define GHOST_RDCE
reduce, the node entry gives the receiver
Definition ghosts.hpp:110
#define GHOST_BCST
broadcast, the node entry gives the sender
Definition ghosts.hpp:108
#define GHOST_PREFETCH
additional flag for prefetching
Definition ghosts.hpp:117
Properties for a ghost communication.
Definition ghosts.hpp:157
std::vector< GhostCommunication > communications
List of ghost communications.
Definition ghosts.hpp:166