preCICE v3.1.1
Loading...
Searching...
No Matches
SerializedPartitioning.cpp
Go to the documentation of this file.
1#include <cstddef>
2#include <iterator>
3#include <memory>
4#include <numeric>
5#include <utility>
6
9#include "utils/assertion.hpp"
10
12
13// SerializedConnectionMap
14
16{
18 auto & content = scm.content;
19
20 auto elements = std::transform_reduce(
21 cm.begin(), cm.end(),
22 1, // num entries
23 std::plus<size_t>{}, [](const auto &kv) {
24 // Rank, size, elements
25 return 2 + kv.second.size();
26 });
27 content.reserve(elements);
28
30 for (const auto &[rank, ids] : cm) {
31 content.push_back(rank);
32 content.push_back(ids.size());
33 content.insert(content.end(), ids.begin(), ids.end());
34 }
35 PRECICE_ASSERT(content.size() == static_cast<std::size_t>(elements));
36 scm.assertValid();
37 return scm;
38}
39
41{
42 auto begin = content.begin();
43 int numEntries = *begin;
44
45 if (numEntries == 0) {
46 return {};
47 }
48 std::advance(begin, 1);
49
51 for (int entry = 0; entry < numEntries; ++entry) {
52 // offset 0: rank
53 auto rank = *begin;
54 std::advance(begin, 1);
55 // offset 1: vertexid count
56 auto size = *begin;
57 std::advance(begin, 1);
58 // offset 2: n vertex ids
59 auto verticesStart = begin;
60 std::advance(begin, size);
61
62 cm.emplace(rank, std::vector<int>(verticesStart, begin));
63 }
64 return cm;
65}
66
68{
69 const size_t totalSize = content.size();
70 PRECICE_ASSERT(totalSize > 1);
71
72 const auto numEntries = content.front();
73 PRECICE_ASSERT(numEntries >= 0);
74
76 size_t consumed = 1;
77 for (int entry = 0; entry < numEntries; ++entry) {
78 // Minimal size is an empty entry: (rank, 0)
79 PRECICE_ASSERT(totalSize >= consumed + 2);
80 // offset 0: rank
81 auto rank = content[consumed++];
82 PRECICE_ASSERT(rank >= 0);
83 // offset 1: vertexid count
84 auto size = content[consumed++];
85 PRECICE_ASSERT(size >= 0);
86
87 // offset 2: n vertex ids
88 PRECICE_ASSERT(totalSize >= consumed + size, "size larger than remaining");
89 std::set<int> ids(content.begin() + consumed, content.begin() + consumed + size);
90 PRECICE_ASSERT(ids.size() == static_cast<std::size_t>(size), "Duplicate vertex IDs");
91 consumed += size;
92 }
93 PRECICE_ASSERT(consumed == totalSize, "Not everything consumed");
94}
95
96void SerializedConnectionMap::send(Communication &communication, int rankReceiver) const
97{
98 communication.sendRange(content, rankReceiver);
99}
100
102{
104 scm.content = communication.receiveRange(rankSender, AsVectorTag<int>{});
105 scm.assertValid();
106 return scm;
107}
108
110{
111 communication.broadcast(content);
112}
113
115{
117 communication.broadcast(scm.content, 0);
118 scm.assertValid();
119 return scm;
120}
121
122// SerializedBoundingBox
123
125{
127
128 // Entries, dimensions, ranks
129 const auto dims = bb.getDimension();
130 PRECICE_ASSERT(dims == 2 || dims == 3);
131
132 auto &coords = sbb.coords;
133 coords.reserve(1 + 2 * dims);
134 coords.push_back(dims);
135 // copy point coordinates
136 auto min = bb.minCorner();
137 std::copy_n(min.data(), dims, std::back_inserter(coords));
138 auto max = bb.maxCorner();
139 std::copy_n(max.data(), dims, std::back_inserter(coords));
140
141 sbb.assertValid();
142 return sbb;
143}
144
146{
147 auto dims = static_cast<int>(coords.at(0));
148
150 std::vector<double> buffer(dims * 2);
151
152 // Copy coords into buffer
153 // Input: minX, minY, minZ, maxX, maxY, maxZ
154 // Output: minX, maxX minY, maxY, minZ, maxZ
155 for (int d = 0; d < dims; ++d) {
156 auto offset = d * 2;
157 buffer[offset] = coords[1 + d]; // min
158 buffer[offset + 1] = coords[1 + d + dims]; // max
159 }
160 return mesh::BoundingBox(std::move(buffer));
161}
162
164{
166 auto dims = static_cast<size_t>(coords.front());
167 PRECICE_ASSERT(dims == 2 || dims == 3);
168 PRECICE_ASSERT(coords.size() == 1 + dims * 2);
169}
170
171void SerializedBoundingBox::send(Communication &communication, int rankReceiver)
172{
173 communication.sendRange(coords, rankReceiver);
174}
175
177{
179 sbb.coords = communication.receiveRange(rankSender, AsVectorTag<double>{});
180 sbb.assertValid();
181 return sbb;
182}
183
184// SerializedBoundingBoxMap
185
187{
188 if (bbm.empty()) {
190 sbbm.info = {0};
191 return sbbm;
192 }
193
195 auto & info = sbbm.info;
196 auto & coords = sbbm.coords;
197
198 // Entries, dimensions, ranks
199 auto size = bbm.size();
200 info.reserve(2 + size);
201 const auto dims = bbm.begin()->second.getDimension();
202 PRECICE_ASSERT(dims == 2 || dims == 3);
203 info.push_back(size);
204 info.push_back(dims);
205 coords.reserve(size * dims);
206
207 for (const auto &[rank, bb] : bbm) {
208 info.push_back(rank);
209 auto min = bb.minCorner();
210 std::copy_n(min.data(), dims, std::back_inserter(coords));
211 auto max = bb.maxCorner();
212 std::copy_n(max.data(), dims, std::back_inserter(coords));
213 }
214 sbbm.assertValid();
215 return sbbm;
216}
217
219{
220 if (info.size() == 1) {
221 return {};
222 }
223
224 auto size = info[0];
225 auto dims = info[1];
226
227 BoundingBoxMap bbm;
228
230 std::vector<double> buffer(dims * 2);
231
232 auto rankIter = std::next(info.begin(), 2);
233 auto coordIter = coords.begin();
234 for (int entry = 0; entry < size; ++entry) {
235 // Copy coords into buffer
236 // Input: minX, minY, minZ, maxX, maxY, maxZ
237 // Output: minX, maxX minY, maxY, minZ, maxZ
238 for (int d = 0; d < dims; ++d) {
239 auto offset = d * 2;
240 buffer[offset] = coordIter[d]; // min
241 buffer[offset + 1] = coordIter[d + dims]; // max
242 }
243 bbm.emplace(*rankIter, mesh::BoundingBox(buffer));
244
245 // advance the input iterators
246 std::advance(rankIter, 1);
247 std::advance(coordIter, dims * 2);
248 }
249 return bbm;
250}
251
253{
255 if (info.size() == 1) {
256 PRECICE_ASSERT(info.front() == 0);
258 return;
259 }
260
261 auto numEntries = info[0];
262 PRECICE_ASSERT(static_cast<size_t>(numEntries) + 2 == info.size());
263 auto dims = info[1];
264 PRECICE_ASSERT(dims == 2 || dims == 3);
265
266 PRECICE_ASSERT(coords.size() == static_cast<size_t>(numEntries * dims * 2));
267 for (int entry = 0; entry < numEntries; ++entry) {
268 PRECICE_ASSERT(info[2 + entry] >= 0);
269 }
270}
271
272void SerializedBoundingBoxMap::send(Communication &communication, int rankReceiver)
273{
274 communication.sendRange(info, rankReceiver);
275 if (info.size() > 1) {
276 communication.sendRange(coords, rankReceiver);
277 }
278}
279
281{
283 sbbm.info = communication.receiveRange(rankSender, AsVectorTag<int>{});
284 if (sbbm.info.size() > 1) {
285 sbbm.coords = communication.receiveRange(rankSender, AsVectorTag<double>{});
286 }
287 sbbm.assertValid();
288 return sbbm;
289}
290
292{
293 communication.broadcast(info);
294 if (info.size() > 1) {
295 communication.broadcast(coords);
296 }
297}
298
300{
302 communication.broadcast(sbbm.info, 0);
303 if (sbbm.info.size() > 1) {
304 communication.broadcast(sbbm.coords, 0);
305 }
306 sbbm.assertValid();
307 return sbbm;
308}
309} // namespace precice::com::serialize
T advance(T... args)
#define PRECICE_ASSERT(...)
Definition assertion.hpp:87
T at(T... args)
T back_inserter(T... args)
T begin(T... args)
Interface for all interprocess communication classes.
std::vector< int > receiveRange(Rank rankSender, AsVectorTag< int >)
Receives a range of ints as a vector<int>
void sendRange(precice::span< const double > itemsToSend, Rank rankReceiver)
Sends a range of doubles (size + content)
virtual void broadcast(precice::span< const int > itemsToSend)
serialized representation of a BoundingBoxMap
static SerializedBoundingBoxMap broadcastReceive(Communication &communication)
receives a SerializedBoundingBoxMap and calls assertValid before returning
static SerializedBoundingBoxMap receive(Communication &communication, int rankSender)
receives a SerializedBoundingBoxMap and calls assertValid before returning
BoundingBoxMap toBoundingBoxMap() const
Builds and returns the BoundingBoxMap represented by the serialized state.
void send(Communication &communication, int rankReceiver)
static SerializedBoundingBoxMap serialize(const BoundingBoxMap &bbm)
void assertValid() const
asserts the content for correctness
serialized representation of a mesh::BoundingBox
static SerializedBoundingBox receive(Communication &communication, int rankSender)
receives a SerializedBoundingBox and calls assertValid before returning
static SerializedBoundingBox serialize(const mesh::BoundingBox &bbm)
mesh::BoundingBox toBoundingBox() const
Builds and returns the BoundingBox represented by the serialized state.
void send(Communication &communication, int rankReceiver)
void assertValid() const
asserts the content for correctness
serialized representation of ConnectionMap
void broadcastSend(Communication &communication) const
static SerializedConnectionMap receive(Communication &communication, int rankSender)
receives a SerializedConnectionMap and calls assertValid before returning
ConnectionMap toConnectionMap() const
Builds and returns the connection map represented by the serialized state.
static SerializedConnectionMap serialize(const ConnectionMap &cm)
static SerializedConnectionMap broadcastReceive(Communication &communication)
receives a SerializedConnectionMap and calls assertValid before returning
void assertValid() const
asserts the content for correctness
void send(Communication &communication, int rankReceiver) const
An axis-aligned bounding box around a (partition of a) mesh.
Eigen::VectorXd maxCorner() const
the max corner of the bounding box
Eigen::VectorXd minCorner() const
the min corner of the bounding box
int getDimension() const
Getter dimension of the bounding box.
T copy_n(T... args)
T emplace(T... args)
T empty(T... args)
T end(T... args)
T front(T... args)
T insert(T... args)
contains serialization logic
T next(T... args)
T push_back(T... args)
T reserve(T... args)
T size(T... args)
T transform_reduce(T... args)