preCICE v3.3.0
Loading...
Searching...
No Matches
ProvidedPartitionTest.cpp
Go to the documentation of this file.
1#ifndef PRECICE_NO_MPI
2#include <Eigen/Core>
3#include <algorithm>
4#include <deque>
5#include <map>
6#include <memory>
7#include <string>
8#include <vector>
9
10#include "com/Communication.hpp"
11#include "com/Extra.hpp"
12#include "com/SharedPointer.hpp"
13#include "m2n/M2N.hpp"
14#include "mapping/Mapping.hpp"
17#include "math/constants.hpp"
18#include "mesh/BoundingBox.hpp"
19#include "mesh/Data.hpp"
20#include "mesh/Mesh.hpp"
26#include "testing/Testing.hpp"
27#include "utils/assertion.hpp"
28
29namespace precice::mesh {
30class Edge;
31class Vertex;
32} // namespace precice::mesh
33
37
38BOOST_AUTO_TEST_SUITE(PartitionTests)
39BOOST_AUTO_TEST_SUITE(ProvidedPartitionTests)
40
41PRECICE_TEST_SETUP("NASTIN"_on(1_rank), "SOLIDZ"_on(3_ranks).setupIntraComm(), Require::Events)
42BOOST_AUTO_TEST_CASE(TestGatherAndCommunicate2D)
43{
44 using namespace precice;
46 auto m2n = context.connectPrimaryRanks("NASTIN", "SOLIDZ");
47
48 int dimensions = 2;
49
50 if (context.isNamed("NASTIN")) { // NASTIN
51 mesh::PtrMesh pSolidzMesh(new mesh::Mesh("SolidzMesh", dimensions, testing::nextMeshID()));
52
53 double safetyFactor = 0.1;
54
55 ReceivedPartition part(pSolidzMesh, ReceivedPartition::ON_SECONDARY_RANKS, safetyFactor);
56 part.addM2N(m2n);
57 part.communicate();
58
59 BOOST_TEST(pSolidzMesh->nVertices() == 6);
60 BOOST_TEST(pSolidzMesh->edges().size() == 4);
61
62 for (int i = 0; i < 6; i++) {
63 BOOST_TEST(pSolidzMesh->vertex(i).getGlobalIndex() == i);
64 }
65 } else { // SOLIDZ
66 mesh::PtrMesh pSolidzMesh(new mesh::Mesh("SolidzMesh", dimensions, testing::nextMeshID()));
67
68 if (context.isPrimary()) { // Primary
69 Eigen::VectorXd position(dimensions);
70 position << 0.0, 0.0;
71 mesh::Vertex &v1 = pSolidzMesh->createVertex(position);
72 position << 0.0, 1.5;
73 mesh::Vertex &v2 = pSolidzMesh->createVertex(position);
74 pSolidzMesh->createEdge(v1, v2);
75 } else if (context.isRank(1)) { // SecondaryRank1
76 } else if (context.isRank(2)) { // Secondary rank 2
77 Eigen::VectorXd position(dimensions);
78 position << 0.0, 3.5;
79 mesh::Vertex &v3 = pSolidzMesh->createVertex(position);
80 position << 0.0, 4.5;
81 mesh::Vertex &v4 = pSolidzMesh->createVertex(position);
82 position << 0.0, 5.5;
83 mesh::Vertex &v5 = pSolidzMesh->createVertex(position);
84 position << 0.0, 7.0;
85 mesh::Vertex &v6 = pSolidzMesh->createVertex(position);
86 pSolidzMesh->createEdge(v3, v4);
87 pSolidzMesh->createEdge(v4, v5);
88 pSolidzMesh->createEdge(v5, v6);
89 }
90 pSolidzMesh->computeBoundingBox();
91
92 ProvidedPartition part(pSolidzMesh);
93 part.addM2N(m2n);
94 part.communicate();
95 part.compute();
96
97 BOOST_REQUIRE(pSolidzMesh->getVertexOffsets().size() == 3);
98 if (context.isPrimary()) {
99 BOOST_TEST(pSolidzMesh->getVertexOffsets().at(0) == 2);
100 BOOST_TEST(pSolidzMesh->getVertexOffsets().at(1) == 2);
101 BOOST_TEST(pSolidzMesh->getVertexOffsets().at(2) == 6);
102 } else if (context.isRank(1)) { // SecondaryRank1
103 BOOST_TEST(pSolidzMesh->getVertexOffsets().at(0) == 2);
104 BOOST_TEST(pSolidzMesh->getVertexOffsets().at(1) == 2);
105 BOOST_TEST(pSolidzMesh->getVertexOffsets().at(2) == 6);
106 } else {
107 BOOST_TEST(pSolidzMesh->getVertexOffsets().at(0) == 2);
108 BOOST_TEST(pSolidzMesh->getVertexOffsets().at(1) == 2);
109 BOOST_TEST(pSolidzMesh->getVertexOffsets().at(2) == 6);
110 }
111 }
112}
113
114PRECICE_TEST_SETUP("NASTIN"_on(1_rank), "SOLIDZ"_on(3_ranks).setupIntraComm(), Require::Events)
115BOOST_AUTO_TEST_CASE(TestGatherAndCommunicate3D)
116{
117 using namespace precice;
118 PRECICE_TEST();
119 auto m2n = context.connectPrimaryRanks("NASTIN", "SOLIDZ");
120
121 int dimensions = 3;
122
123 if (context.isNamed("NASTIN")) { // NASTIN
124 mesh::PtrMesh pSolidzMesh(new mesh::Mesh("SolidzMesh", dimensions, testing::nextMeshID()));
125
126 double safetyFactor = 0.1;
127
128 ReceivedPartition part(pSolidzMesh, ReceivedPartition::ON_SECONDARY_RANKS, safetyFactor);
129 part.addM2N(m2n);
130 part.communicate();
131
132 BOOST_TEST(pSolidzMesh->nVertices() == 6);
133 BOOST_TEST(pSolidzMesh->edges().size() == 6);
134 BOOST_TEST(pSolidzMesh->triangles().size() == 2);
135
136 for (int i = 0; i < 6; i++) {
137 BOOST_TEST(pSolidzMesh->vertex(i).getGlobalIndex() == i);
138 }
139 } else { // SOLIDZ
140 mesh::PtrMesh pSolidzMesh(new mesh::Mesh("SolidzMesh", dimensions, testing::nextMeshID()));
141
142 if (context.isPrimary()) { // Primary
143 Eigen::VectorXd position(dimensions);
144 position << 0.0, 0.0, 0.0;
145 mesh::Vertex &v1 = pSolidzMesh->createVertex(position);
146 position << 0.0, 1.5, 1.0;
147 mesh::Vertex &v2 = pSolidzMesh->createVertex(position);
148 pSolidzMesh->createEdge(v1, v2);
149 } else if (context.isRank(1)) { // SecondaryRank1
150 } else if (context.isRank(2)) { // Secondary rank 2
151 Eigen::VectorXd position(dimensions);
152 position << 0.0, 3.5, 0.1;
153 mesh::Vertex &v3 = pSolidzMesh->createVertex(position);
154 position << 0.0, 4.5, 0.2;
155 mesh::Vertex &v4 = pSolidzMesh->createVertex(position);
156 position << 0.0, 5.5, 0.8;
157 mesh::Vertex &v5 = pSolidzMesh->createVertex(position);
158 position << 0.0, 7.0, 0.4;
159 mesh::Vertex &v6 = pSolidzMesh->createVertex(position);
160 mesh::Edge &e1 = pSolidzMesh->createEdge(v3, v4);
161 mesh::Edge &e2 = pSolidzMesh->createEdge(v4, v5);
162 mesh::Edge &e3 = pSolidzMesh->createEdge(v5, v3);
163 mesh::Edge &e4 = pSolidzMesh->createEdge(v3, v6);
164 mesh::Edge &e5 = pSolidzMesh->createEdge(v6, v5);
165
166 pSolidzMesh->createTriangle(e1, e2, e3);
167 pSolidzMesh->createTriangle(e4, e5, e3);
168 }
169 pSolidzMesh->computeBoundingBox();
170
171 ProvidedPartition part(pSolidzMesh);
172 part.addM2N(m2n);
173 part.communicate();
174 part.compute();
175
176 BOOST_TEST(pSolidzMesh->getGlobalNumberOfVertices() == 6);
177 const auto &vertices = pSolidzMesh->vertices();
178 const auto &vertexOffsets = pSolidzMesh->getVertexOffsets();
179 const auto &vertexDistribution = pSolidzMesh->getVertexDistribution();
180
181 if (context.isPrimary()) {
182 BOOST_REQUIRE(vertexOffsets.size() == 3);
183 BOOST_TEST(vertexOffsets.at(0) == 2);
184 BOOST_TEST(vertexOffsets.at(1) == 2);
185 BOOST_TEST(vertexOffsets.at(2) == 6);
186
187 BOOST_REQUIRE(vertices.size() == 2);
188 BOOST_TEST(vertices.at(0).getGlobalIndex() == 0);
189 BOOST_TEST(vertices.at(1).getGlobalIndex() == 1);
190 BOOST_TEST(vertices.at(0).isOwner() == true);
191 BOOST_TEST(vertices.at(1).isOwner() == true);
192
193 BOOST_REQUIRE((vertexDistribution.size()) == 3);
194 BOOST_TEST(vertexDistribution.at(0).size() == 2);
195 BOOST_TEST(vertexDistribution.at(1).size() == 0);
196 BOOST_TEST(vertexDistribution.at(2).size() == 4);
197 BOOST_TEST(vertexDistribution.at(0).at(0) == 0);
198 BOOST_TEST(vertexDistribution.at(0).at(1) == 1);
199 BOOST_TEST(vertexDistribution.at(2).at(0) == 2);
200 BOOST_TEST(vertexDistribution.at(2).at(1) == 3);
201 BOOST_TEST(vertexDistribution.at(2).at(2) == 4);
202 BOOST_TEST(vertexDistribution.at(2).at(3) == 5);
203 } else if (context.isRank(1)) { // SecondaryRank1
204 BOOST_REQUIRE(vertexOffsets.size() == 3);
205 BOOST_TEST(vertexOffsets.at(0) == 2);
206 BOOST_TEST(vertexOffsets.at(1) == 2);
207 BOOST_TEST(vertexOffsets.at(2) == 6);
208 } else if (context.isRank(2)) { // Secondary rank 2
209 BOOST_REQUIRE(vertexOffsets.size() == 3);
210 BOOST_TEST(vertexOffsets.at(0) == 2);
211 BOOST_TEST(vertexOffsets.at(1) == 2);
212 BOOST_TEST(vertexOffsets.at(2) == 6);
213
214 BOOST_REQUIRE(vertices.size() == 4);
215 BOOST_TEST(vertices.at(0).getGlobalIndex() == 2);
216 BOOST_TEST(vertices.at(1).getGlobalIndex() == 3);
217 BOOST_TEST(vertices.at(2).getGlobalIndex() == 4);
218 BOOST_TEST(vertices.at(3).getGlobalIndex() == 5);
219 BOOST_TEST(vertices.at(0).isOwner() == true);
220 BOOST_TEST(vertices.at(1).isOwner() == true);
221 BOOST_TEST(vertices.at(2).isOwner() == true);
222 BOOST_TEST(vertices.at(3).isOwner() == true);
223 }
224 }
225}
226
227PRECICE_TEST_SETUP("NASTIN"_on(4_ranks).setupIntraComm(), Require::Events)
228BOOST_AUTO_TEST_CASE(TestOnlyDistribution2D)
229{
230 using namespace precice;
231 PRECICE_TEST();
232 // Create mesh object
233 std::string meshName("MyMesh");
234 int dim = 2;
235 mesh::PtrMesh pMesh(new mesh::Mesh(meshName, dim, testing::nextMeshID()));
236
237 if (context.isPrimary()) { // Primary
238 Eigen::VectorXd position(dim);
239 position << 0.0, 0.0;
240 pMesh->createVertex(position);
241 position << 1.0, 0.0;
242 pMesh->createVertex(position);
243 } else if (context.isRank(1)) { // SecondaryRank1
244 Eigen::VectorXd position(dim);
245 position << 2.0, 0.0;
246 pMesh->createVertex(position);
247 } else if (context.isRank(2)) { // Secondary rank 2
248 } else if (context.isRank(3)) { // Secondary rank 3
249 Eigen::VectorXd position(dim);
250 position << 3.0, 0.0;
251 pMesh->createVertex(position);
252 position << 4.0, 0.0;
253 pMesh->createVertex(position);
254 }
255 pMesh->computeBoundingBox();
256
257 ProvidedPartition part(pMesh);
258 part.communicate();
259 part.compute();
260
261 BOOST_TEST_CONTEXT(*pMesh)
262 {
263 if (context.isPrimary()) { // Primary
264 BOOST_TEST(pMesh->getGlobalNumberOfVertices() == 5);
265 BOOST_TEST_REQUIRE(pMesh->getVertexOffsets().size() == 4);
266 BOOST_TEST(pMesh->getVertexOffsets().at(0) == 2);
267 BOOST_TEST(pMesh->getVertexOffsets().at(1) == 3);
268 BOOST_TEST(pMesh->getVertexOffsets().at(2) == 3);
269 BOOST_TEST(pMesh->getVertexOffsets().at(3) == 5);
270 BOOST_TEST(pMesh->vertex(0).getGlobalIndex() == 0);
271 BOOST_TEST(pMesh->vertex(1).getGlobalIndex() == 1);
272 BOOST_TEST(pMesh->vertex(0).isOwner() == true);
273 BOOST_TEST(pMesh->vertex(1).isOwner() == true);
274 } else if (context.isRank(1)) { // SecondaryRank1
275 BOOST_TEST(pMesh->getGlobalNumberOfVertices() == 5);
276 BOOST_TEST_REQUIRE(pMesh->getVertexOffsets().size() == 4);
277 BOOST_TEST(pMesh->getVertexOffsets().at(0) == 2);
278 BOOST_TEST(pMesh->getVertexOffsets().at(1) == 3);
279 BOOST_TEST(pMesh->getVertexOffsets().at(2) == 3);
280 BOOST_TEST(pMesh->getVertexOffsets().at(3) == 5);
281 BOOST_TEST(pMesh->vertex(0).getGlobalIndex() == 2);
282 BOOST_TEST(pMesh->vertex(0).isOwner() == true);
283 } else if (context.isRank(2)) { // Secondary rank 2
284 BOOST_TEST(pMesh->getGlobalNumberOfVertices() == 5);
285 BOOST_TEST_REQUIRE(pMesh->getVertexOffsets().size() == 4);
286 BOOST_TEST(pMesh->getVertexOffsets().at(0) == 2);
287 BOOST_TEST(pMesh->getVertexOffsets().at(1) == 3);
288 BOOST_TEST(pMesh->getVertexOffsets().at(2) == 3);
289 BOOST_TEST(pMesh->getVertexOffsets().at(3) == 5);
290 } else if (context.isRank(3)) { // Secondary rank 3
291 BOOST_TEST(pMesh->getGlobalNumberOfVertices() == 5);
292 BOOST_TEST_REQUIRE(pMesh->getVertexOffsets().size() == 4);
293 BOOST_TEST(pMesh->getVertexOffsets().at(0) == 2);
294 BOOST_TEST(pMesh->getVertexOffsets().at(1) == 3);
295 BOOST_TEST(pMesh->getVertexOffsets().at(2) == 3);
296 BOOST_TEST(pMesh->getVertexOffsets().at(3) == 5);
297 BOOST_TEST(pMesh->vertex(0).getGlobalIndex() == 3);
298 BOOST_TEST(pMesh->vertex(1).getGlobalIndex() == 4);
299 BOOST_TEST(pMesh->vertex(0).isOwner() == true);
300 BOOST_TEST(pMesh->vertex(1).isOwner() == true);
301 }
302 }
303}
304
305PRECICE_TEST_SETUP("SOLIDZ"_on(3_ranks).setupIntraComm(), "NASTIN"_on(1_rank), Require::Events)
306BOOST_AUTO_TEST_CASE(TestCompareBoundingBoxes2D)
307{
308 using namespace precice;
309 PRECICE_TEST();
311 options.useOnlyPrimaryCom = false;
312 options.useTwoLevelInit = true;
313 auto m2n = context.connectPrimaryRanks("NASTIN", "SOLIDZ", options);
314
315 int dimensions = 2;
316
317 if (context.isNamed("SOLIDZ")) { // SOLIDZ
318
319 mesh::PtrMesh pSolidzMesh(new mesh::Mesh("SolidzMesh", dimensions, testing::nextMeshID()));
320
321 if (context.isPrimary()) { // Primary
322 Eigen::VectorXd position(dimensions);
323 position << -1.0, 0.0;
324 mesh::Vertex &v0 = pSolidzMesh->createVertex(position);
325 position << 1.0, 2.0;
326 mesh::Vertex &v1 = pSolidzMesh->createVertex(position);
327 position << 5.0, 3.0;
328 mesh::Vertex &v2 = pSolidzMesh->createVertex(position);
329 pSolidzMesh->createEdge(v0, v1);
330 pSolidzMesh->createEdge(v1, v2);
331 }
332
333 else if (context.isRank(1)) { // SecondaryRank1
334 Eigen::VectorXd position(dimensions);
335 position << 1.0, 3.5;
336 mesh::Vertex &v3 = pSolidzMesh->createVertex(position);
337 position << 0.0, 4.5;
338 mesh::Vertex &v4 = pSolidzMesh->createVertex(position);
339 pSolidzMesh->createEdge(v3, v4);
340 } else if (context.isRank(2)) { // Secondary rank 2
341 Eigen::VectorXd position(dimensions);
342 position << 2.5, 5.5;
343 mesh::Vertex &v5 = pSolidzMesh->createVertex(position);
344 position << 4.5, 7.0;
345 mesh::Vertex &v6 = pSolidzMesh->createVertex(position);
346 pSolidzMesh->createEdge(v5, v6);
347 }
348 pSolidzMesh->computeBoundingBox();
349
350 ProvidedPartition part(pSolidzMesh);
351 part.addM2N(m2n);
353
354 if (context.isPrimary()) { // Primary
355 BOOST_TEST(pSolidzMesh->getConnectedRanks().size() == 2);
356 BOOST_TEST(pSolidzMesh->getConnectedRanks().at(0) == 1);
357 BOOST_TEST(pSolidzMesh->getConnectedRanks().at(1) == 2);
358 } else if (context.isRank(1)) { // SecondaryRank1
359 BOOST_TEST(pSolidzMesh->getConnectedRanks().size() == 2);
360 BOOST_TEST(pSolidzMesh->getConnectedRanks().at(0) == 0);
361 BOOST_TEST(pSolidzMesh->getConnectedRanks().at(1) == 2);
362 } else if (context.isRank(2)) { // Secondary rank 2
363 BOOST_TEST(pSolidzMesh->getConnectedRanks().size() == 2);
364 BOOST_TEST(pSolidzMesh->getConnectedRanks().at(0) == 0);
365 BOOST_TEST(pSolidzMesh->getConnectedRanks().at(1) == 1);
366 }
367
368 } else { // NASTIN
369 BOOST_TEST(context.isNamed("NASTIN"));
370
371 mesh::Mesh::BoundingBoxMap receivedGlobalBB;
372 mesh::BoundingBox localBB{dimensions};
373
375 compareBB.emplace(0, mesh::BoundingBox({-1, 5, 0, 3}));
376 compareBB.emplace(1, mesh::BoundingBox({0, 1, 3.5, 4.5}));
377 compareBB.emplace(2, mesh::BoundingBox({2.5, 4.5, 5.5, 7.0}));
378
379 // we receive other participants communicator size
380 int receivedFeedbackSize = 3;
381 m2n->getPrimaryRankCommunication()->receive(receivedFeedbackSize, 0);
382
383 for (int i = 0; i < receivedFeedbackSize; i++) {
384 receivedGlobalBB.emplace(i, localBB);
385 }
386
387 // we receive global bounding box from other participant!
388 com::receiveBoundingBoxMap(*m2n->getPrimaryRankCommunication(), 0, receivedGlobalBB);
389 // check whether we have received the correct com size
390 BOOST_TEST(receivedFeedbackSize == 3);
391
392 // check the validity of received global bounding box (globalBB)
393 BOOST_TEST(receivedGlobalBB.at(0) == compareBB.at(0));
394 BOOST_TEST(receivedGlobalBB.at(1) == compareBB.at(1));
395 BOOST_TEST(receivedGlobalBB.at(2) == compareBB.at(2));
396
397 std::vector<int> connectedRanks = {0, 1, 2};
398 m2n->getPrimaryRankCommunication()->sendRange(connectedRanks, 0);
399
400 // construct connection map
401 std::map<int, std::vector<int>> connectionMap;
402 connectionMap[0].push_back(1);
403 connectionMap[0].push_back(2);
404 connectionMap[1].push_back(0);
405 connectionMap[1].push_back(2);
406 connectionMap[2].push_back(0);
407 connectionMap[2].push_back(1);
408
409 com::sendConnectionMap(*m2n->getPrimaryRankCommunication(), 0, connectionMap);
410 }
411}
412
413PRECICE_TEST_SETUP("SOLIDZ"_on(3_ranks).setupIntraComm(), "NASTIN"_on(1_rank), Require::Events)
414BOOST_AUTO_TEST_CASE(TestSendBoundingBoxes3D)
415{
416 using namespace precice;
417 PRECICE_TEST();
419 options.useOnlyPrimaryCom = false;
420 options.useTwoLevelInit = true;
421 auto m2n = context.connectPrimaryRanks("NASTIN", "SOLIDZ", options);
422
423 int dimensions = 3;
424
425 if (context.isNamed("SOLIDZ")) { // SOLIDZ
426
427 mesh::PtrMesh pSolidzMesh(new mesh::Mesh("SolidzMesh", dimensions, testing::nextMeshID()));
428
429 if (context.isPrimary()) { // Primary
430 Eigen::VectorXd position(dimensions);
431 position << -1.0, 0.0, -1.0;
432 mesh::Vertex &v0 = pSolidzMesh->createVertex(position);
433 position << 1.0, 2.0, 1.0;
434 mesh::Vertex &v1 = pSolidzMesh->createVertex(position);
435 position << 5.0, 3.0, 5.0;
436 mesh::Vertex &v2 = pSolidzMesh->createVertex(position);
437 pSolidzMesh->createEdge(v0, v1);
438 pSolidzMesh->createEdge(v1, v2);
439 }
440
441 else if (context.isRank(1)) { // SecondaryRank1
442 Eigen::VectorXd position(dimensions);
443 position << 1.0, 3.5, 1.0;
444 mesh::Vertex &v3 = pSolidzMesh->createVertex(position);
445 position << 0.0, 4.5, 0.0;
446 mesh::Vertex &v4 = pSolidzMesh->createVertex(position);
447 pSolidzMesh->createEdge(v3, v4);
448 } else if (context.isRank(2)) { // Secondary rank 2
449 Eigen::VectorXd position(dimensions);
450 position << 2.5, 5.5, 2.5;
451 mesh::Vertex &v5 = pSolidzMesh->createVertex(position);
452 position << 4.5, 7.0, 4.5;
453 mesh::Vertex &v6 = pSolidzMesh->createVertex(position);
454 pSolidzMesh->createEdge(v5, v6);
455 }
456 pSolidzMesh->computeBoundingBox();
457
458 ProvidedPartition part(pSolidzMesh);
459 part.addM2N(m2n);
460 part.compareBoundingBoxes();
461
462 } else { // NASTIN
463 BOOST_TEST(context.isNamed("NASTIN"));
464
465 mesh::Mesh::BoundingBoxMap receivedGlobalBB;
466 mesh::BoundingBox localBB{dimensions};
467
469 compareBB.emplace(0, mesh::BoundingBox({-1, 5, 0, 3, -1, 5}));
470 compareBB.emplace(1, mesh::BoundingBox({0, 1, 3.5, 4.5, 0, 1}));
471 compareBB.emplace(2, mesh::BoundingBox({2.5, 4.5, 5.5, 7.0, 2.5, 4.5}));
472
473 // we receive other participants communicator size
474 int remoteParComSize = 3;
475 m2n->getPrimaryRankCommunication()->receive(remoteParComSize, 0);
476
477 for (int i = 0; i < remoteParComSize; i++) {
478 receivedGlobalBB.emplace(i, localBB);
479 }
480
481 // we receive global bounding box from other participant!
482 com::receiveBoundingBoxMap(*m2n->getPrimaryRankCommunication(), 0, receivedGlobalBB);
483
484 // check whether we have received the correct com size
485 BOOST_TEST(remoteParComSize == 3);
486
487 // check the validity of received global bounding box (globalBB)
488 BOOST_TEST(receivedGlobalBB.at(0) == compareBB.at(0));
489 BOOST_TEST(receivedGlobalBB.at(1) == compareBB.at(1));
490 BOOST_TEST(receivedGlobalBB.at(2) == compareBB.at(2));
491
492 // send empty dummy list of connected ranks as feedback
493 std::vector<int> connectedRanksList;
494 m2n->getPrimaryRankCommunication()->sendRange(connectedRanksList, 0);
495 }
496}
497
498PRECICE_TEST_SETUP("Solid"_on(2_ranks).setupIntraComm(), "Fluid"_on(2_ranks).setupIntraComm(), Require::Events)
499BOOST_AUTO_TEST_CASE(TestCommunicateLocalMeshPartitions)
500{
501 using namespace precice;
502 PRECICE_TEST();
503 // mesh creation
504 int dimensions = 2;
505 double safetyFactor = 0.1;
506 mesh::PtrMesh mesh(new mesh::Mesh("mesh", dimensions, testing::nextMeshID()));
507
509 options.useOnlyPrimaryCom = false;
510 options.useTwoLevelInit = true;
512 auto m2n = context.connectPrimaryRanks("Fluid", "Solid", options);
513
514 if (context.isNamed("Solid")) {
515 if (context.isPrimary()) {
516 Eigen::VectorXd position(dimensions);
517 position << 0.5, 0.0;
518 mesh::Vertex &v1 = mesh->createVertex(position);
519 position << 1.5, 0.0;
520 mesh::Vertex &v2 = mesh->createVertex(position);
521 position << 2.0, 1.0;
522 mesh::Vertex &v3 = mesh->createVertex(position);
523 position << 0.5, 1.0;
524 mesh::Vertex &v4 = mesh->createVertex(position);
525 mesh->createEdge(v1, v2);
526 mesh->createEdge(v2, v3);
527 mesh->createEdge(v3, v4);
528 mesh->createEdge(v4, v1);
529
530 mesh->setConnectedRanks({0});
531
532 } else {
533 Eigen::VectorXd position(dimensions);
534 position << 2.5, 0.0;
535 mesh::Vertex &v1 = mesh->createVertex(position);
536 position << 3.5, 0.0;
537 mesh::Vertex &v2 = mesh->createVertex(position);
538 position << 3.5, 1.0;
539 mesh::Vertex &v3 = mesh->createVertex(position);
540 position << 2.0, 1.0;
541 mesh::Vertex &v4 = mesh->createVertex(position);
542 mesh->createEdge(v1, v2);
543 mesh->createEdge(v2, v3);
544 mesh->createEdge(v3, v4);
545 mesh->createEdge(v4, v1);
546
547 mesh->setConnectedRanks({1});
548 }
549 } else {
550 BOOST_TEST(context.isNamed("Fluid"));
551 if (context.isPrimary()) {
552 mesh->setConnectedRanks({0});
553 } else {
554 mesh->setConnectedRanks({1});
555 }
556 }
557 mesh->computeBoundingBox();
558
559 if (context.isNamed("Solid")) {
560 m2n->createDistributedCommunication(mesh);
562 m2n->acceptSecondaryRanksPreConnection("SolidSecondaryRanks", "FluidSecondaryRanks");
563 part.addM2N(m2n);
564 part.communicate();
565 } else {
566 m2n->createDistributedCommunication(mesh);
568 m2n->requestSecondaryRanksPreConnection("SolidSecondaryRanks", "FluidSecondaryRanks");
569 part.addM2N(m2n);
570
571 part.communicate();
572
573 BOOST_TEST(mesh->nVertices() == 4);
574
575 if (context.isPrimary()) {
576 BOOST_TEST(mesh->vertex(0).coord(0) == 0.5);
577 BOOST_TEST(mesh->vertex(0).coord(1) == 0.0);
578 BOOST_TEST(mesh->vertex(1).coord(0) == 1.5);
579 BOOST_TEST(mesh->vertex(1).coord(1) == 0.0);
580 BOOST_TEST(mesh->vertex(2).coord(0) == 2.0);
581 BOOST_TEST(mesh->vertex(2).coord(1) == 1.0);
582 BOOST_TEST(mesh->vertex(3).coord(0) == 0.5);
583 BOOST_TEST(mesh->vertex(3).coord(1) == 1.0);
584 } else {
585 BOOST_TEST(mesh->vertex(0).coord(0) == 2.5);
586 BOOST_TEST(mesh->vertex(0).coord(1) == 0.0);
587 BOOST_TEST(mesh->vertex(1).coord(0) == 3.5);
588 BOOST_TEST(mesh->vertex(1).coord(1) == 0.0);
589 BOOST_TEST(mesh->vertex(2).coord(0) == 3.5);
590 BOOST_TEST(mesh->vertex(2).coord(1) == 1.0);
591 BOOST_TEST(mesh->vertex(3).coord(0) == 2.0);
592 BOOST_TEST(mesh->vertex(3).coord(1) == 1.0);
593 }
594 }
595}
596
597PRECICE_TEST_SETUP("Solid"_on(2_ranks).setupIntraComm(), "Fluid"_on(2_ranks).setupIntraComm(), Require::Events)
598BOOST_AUTO_TEST_CASE(TestTwoLevelRepartitioning2D)
599{
600 using namespace precice;
601 PRECICE_TEST();
602 // mesh creation
603 int dimensions = 2;
604 double safetyFactor = 0;
605 mesh::PtrMesh mesh(new mesh::Mesh("mesh", dimensions, testing::nextMeshID()));
606 mesh::PtrMesh receivedMesh(new mesh::Mesh("mesh", dimensions, testing::nextMeshID()));
607
609 options.useOnlyPrimaryCom = false;
610 options.useTwoLevelInit = true;
612 auto m2n = context.connectPrimaryRanks("Fluid", "Solid", options);
613
614 if (context.isNamed("Solid")) {
615 if (context.isPrimary()) {
616 Eigen::VectorXd position(dimensions);
617 position << -2.0, 0.0;
618 mesh->createVertex(position);
619 position << -1.0, 0.0;
620 mesh->createVertex(position);
621 position << 0.0, 1.0;
622 mesh->createVertex(position);
623 position << -1.0, 1.0;
624 mesh->createVertex(position);
625 position << -2.0, 1.0;
626 mesh->createVertex(position);
627 position << -2.0, 2.0;
628 mesh->createVertex(position);
629 position << -1.0, 2.0;
630 mesh->createVertex(position);
631 position << 0.0, 2.0;
632 mesh->createVertex(position);
633 } else {
634 Eigen::VectorXd position(dimensions);
635 position << -0.5, 0.0;
636 mesh->createVertex(position);
637 position << 1.0, 0.0;
638 mesh->createVertex(position);
639 position << 2.0, 0.0;
640 mesh->createVertex(position);
641 position << 2.0, 1.0;
642 mesh->createVertex(position);
643 position << 1.0, 1.0;
644 mesh->createVertex(position);
645 position << 1.0, 2.0;
646 mesh->createVertex(position);
647 position << 2.0, 2.0;
648 mesh->createVertex(position);
649 }
650 } else {
651 BOOST_TEST(context.isNamed("Fluid"));
652 if (context.isPrimary()) {
653 Eigen::VectorXd position(dimensions);
654 position << 0.0, 0.0;
655 mesh->createVertex(position);
656 position << 0.0, -1.0;
657 mesh->createVertex(position);
658 position << -1.0, 0.0;
659 mesh->createVertex(position);
660 position << -1.0, -1.0;
661 mesh->createVertex(position);
662 position << -2.0, -0.0;
663 mesh->createVertex(position);
664 position << -2.0, -1.0;
665 mesh->createVertex(position);
666 } else {
667 Eigen::VectorXd position(dimensions);
668 position << 0.0, 0.0;
669 mesh->createVertex(position);
670 position << 1.0, 0.0;
671 mesh->createVertex(position);
672 position << 0.0, -1.0;
673 mesh->createVertex(position);
674 position << 1.0, -1.0;
675 mesh->createVertex(position);
676 position << 2.0, 0.0;
677 mesh->createVertex(position);
678 position << 2.0, -1.0;
679 mesh->createVertex(position);
680 }
681 }
682 mesh->computeBoundingBox();
683
684 if (context.isNamed("Solid")) {
685 m2n->createDistributedCommunication(mesh);
687 part.addM2N(m2n);
688
689 part.compareBoundingBoxes();
690
691 if (context.isPrimary()) {
692 BOOST_TEST(mesh->getConnectedRanks().size() == 2);
693 BOOST_TEST(mesh->getConnectedRanks().at(0) == 0);
694 BOOST_TEST(mesh->getConnectedRanks().at(1) == 1);
695 } else {
696 BOOST_TEST(mesh->getConnectedRanks().size() == 2);
697 BOOST_TEST(mesh->getConnectedRanks().at(0) == 0);
698 BOOST_TEST(mesh->getConnectedRanks().at(1) == 1);
699 }
700
701 m2n->acceptSecondaryRanksPreConnection("FluidSecondaryRanks", "SolidSecondaryRanks");
702
703 part.communicate();
704 part.compute();
705
706 if (context.isPrimary()) {
707 BOOST_TEST(mesh->getCommunicationMap().at(0).at(0) == 0);
708 BOOST_TEST(mesh->getCommunicationMap().at(0).at(1) == 1);
709 } else {
710 BOOST_TEST(mesh->getCommunicationMap().at(0).at(0) == 0);
711 BOOST_TEST(mesh->getCommunicationMap().at(1).at(0) == 1);
712 BOOST_TEST(mesh->getCommunicationMap().at(1).at(1) == 2);
713 }
714 } else {
715 m2n->createDistributedCommunication(receivedMesh);
718 boundingFromMapping->setMeshes(receivedMesh, mesh);
719 boundingToMapping->setMeshes(mesh, receivedMesh);
720
721 ReceivedPartition part(receivedMesh, ReceivedPartition::ON_SECONDARY_RANKS, safetyFactor);
722
723 part.addM2N(m2n);
724
725 part.addFromMapping(boundingFromMapping);
726 part.addToMapping(boundingToMapping);
727
728 part.compareBoundingBoxes();
729
730 m2n->requestSecondaryRanksPreConnection("FluidSecondaryRanks", "SolidSecondaryRanks");
731
732 part.communicate();
733 part.compute();
734 }
735}
736
737PRECICE_TEST_SETUP("Solid"_on(2_ranks).setupIntraComm(), "Fluid"_on(2_ranks).setupIntraComm(), Require::Events)
738BOOST_AUTO_TEST_CASE(TestTwoLevelRepartitioning3D)
739{
740 using namespace precice;
741 PRECICE_TEST();
742
743 // mesh creation
744 int dimensions = 3;
745 double safetyFactor = 0.0;
746 mesh::PtrMesh mesh(new mesh::Mesh("mesh", dimensions, testing::nextMeshID()));
747 mesh::PtrMesh receivedMesh(new mesh::Mesh("mesh", dimensions, testing::nextMeshID()));
748
749 // create the communicator for m2n mesh and communication map exchange
751 options.useOnlyPrimaryCom = false;
752 options.useTwoLevelInit = true;
754 auto m2n = context.connectPrimaryRanks("Fluid", "Solid", options);
755
756 if (context.isNamed("Solid")) {
757 if (context.isPrimary()) {
758 Eigen::VectorXd position(dimensions);
759 position << -2.0, 0.0, 0.0;
760 mesh->createVertex(position);
761 position << -1.0, 0.0, 0.0;
762 mesh->createVertex(position);
763 position << 0.0, 1.0, 1.0;
764 mesh->createVertex(position);
765 position << -1.0, 1.0, 1.0;
766 mesh->createVertex(position);
767 position << -2.0, 1.0, 1.0;
768 mesh->createVertex(position);
769 } else {
770 Eigen::VectorXd position(dimensions);
771 position << -0.5, 0.0, 0.0;
772 mesh->createVertex(position);
773 position << 1.0, 0.0, 0.0;
774 mesh->createVertex(position);
775 position << 2.0, 0.0, 0.0;
776 mesh->createVertex(position);
777 position << 2.0, 1.0, 1.0;
778 mesh->createVertex(position);
779 position << 1.0, 1.0, 1.0;
780 mesh->createVertex(position);
781 }
782 } else {
783 if (context.isPrimary()) {
784 Eigen::VectorXd position(dimensions);
785 position << 0.0, 0.0, 0.0;
786 mesh->createVertex(position);
787 position << 0.0, -1.0, 1.0;
788 mesh->createVertex(position);
789 position << -1.0, 0.0, 0.0;
790 mesh->createVertex(position);
791 position << -1.0, -1.0, 1.0;
792 mesh->createVertex(position);
793 position << -2.0, -0.0, 0.0;
794 mesh->createVertex(position);
795 position << -2.0, -1.0, 1.0;
796 mesh->createVertex(position);
797 } else {
798 Eigen::VectorXd position(dimensions);
799 position << 0.0, 0.0, 0.0;
800 mesh->createVertex(position);
801 position << 1.0, 0.0, 0.0;
802 mesh->createVertex(position);
803 position << 0.0, -1.0, 1.0;
804 mesh->createVertex(position);
805 position << 1.0, -1.0, 1.0;
806 mesh->createVertex(position);
807 position << 2.0, 0.0, 0.0;
808 mesh->createVertex(position);
809 position << 2.0, -1.0, 0.0;
810 mesh->createVertex(position);
811 }
812 }
813 mesh->computeBoundingBox();
814
815 if (context.isNamed("Solid")) {
816 m2n->createDistributedCommunication(mesh);
818 part.addM2N(m2n);
819
820 part.compareBoundingBoxes();
821
822 if (context.isPrimary()) {
823 BOOST_TEST(mesh->getConnectedRanks().size() == 2);
824 BOOST_TEST(mesh->getConnectedRanks().at(0) == 0);
825 BOOST_TEST(mesh->getConnectedRanks().at(1) == 1);
826 } else {
827 BOOST_TEST(mesh->getConnectedRanks().size() == 2);
828 BOOST_TEST(mesh->getConnectedRanks().at(0) == 0);
829 BOOST_TEST(mesh->getConnectedRanks().at(1) == 1);
830 }
831
832 m2n->acceptSecondaryRanksPreConnection("FluidSecondaryRanks", "SolidSecondaryRanks");
833
834 part.communicate();
835 part.compute();
836
837 if (context.isPrimary()) {
838 BOOST_TEST(mesh->getCommunicationMap().at(0).at(0) == 0);
839 BOOST_TEST(mesh->getCommunicationMap().at(0).at(1) == 1);
840 } else {
841 BOOST_TEST(mesh->getCommunicationMap().at(0).at(0) == 0);
842 BOOST_TEST(mesh->getCommunicationMap().at(1).at(0) == 1);
843 BOOST_TEST(mesh->getCommunicationMap().at(1).at(1) == 2);
844 }
845 } else {
846 m2n->createDistributedCommunication(receivedMesh);
849 boundingFromMapping->setMeshes(receivedMesh, mesh);
850 boundingToMapping->setMeshes(mesh, receivedMesh);
851
852 ReceivedPartition part(receivedMesh, ReceivedPartition::ON_SECONDARY_RANKS, safetyFactor);
853 part.addM2N(m2n);
854
855 part.addFromMapping(boundingFromMapping);
856 part.addToMapping(boundingToMapping);
857
858 part.compareBoundingBoxes();
859
860 m2n->requestSecondaryRanksPreConnection("FluidSecondaryRanks", "SolidSecondaryRanks");
861
862 part.communicate();
863 part.compute();
864 }
865}
866
869
870#endif // PRECICE_NO_MPI
BOOST_AUTO_TEST_CASE(testIQNIMVJPPWithSubsteps)
BOOST_AUTO_TEST_SUITE(PreProcess)
BOOST_AUTO_TEST_SUITE_END()
#define PRECICE_TEST()
Definition Testing.hpp:39
#define PRECICE_TEST_SETUP(...)
Creates and attaches a TestSetup to a Boost test case.
Definition Testing.hpp:29
T at(T... args)
int getGlobalNumberOfVertices() const
Definition Mesh.hpp:265
std::size_t nVertices() const
Returns the number of vertices.
Definition Mesh.cpp:65
Vertex & vertex(VertexID id)
Mutable access to a vertex by VertexID.
Definition Mesh.cpp:43
const std::vector< Rank > & getConnectedRanks() const
Returns a vector of connected ranks.
Definition Mesh.hpp:282
const VertexOffsets & getVertexOffsets() const
Definition Mesh.hpp:251
void computeBoundingBox()
Computes the boundingBox for the vertices.
Definition Mesh.cpp:244
Edge & createEdge(Vertex &vertexOne, Vertex &vertexTwo)
Creates and initializes an Edge object.
Definition Mesh.cpp:113
Vertex & createVertex(const Eigen::Ref< const Eigen::VectorXd > &coords)
Creates and initializes a Vertex object.
Definition Mesh.cpp:105
EdgeContainer & edges()
Returns modifiable container holding all edges.
Definition Mesh.cpp:70
@ ON_SECONDARY_RANKS
Filter after communication on all secondary ranks.
Mapping using nearest neighboring vertices.
An axis-aligned bounding box around a (partition of a) mesh.
Linear edge of a mesh, defined by two Vertex objects.
Definition Edge.hpp:15
Container and creator for meshes.
Definition Mesh.hpp:38
std::map< int, BoundingBox > BoundingBoxMap
Definition Mesh.hpp:45
Vertex of a mesh.
Definition Vertex.hpp:16
bool isOwner() const
Definition Vertex.cpp:22
int getGlobalIndex() const
Globally unique index.
Definition Vertex.cpp:12
void addM2N(m2n::PtrM2N m2n)
Definition Partition.hpp:56
A partition that is provided by the participant.
void compute() override
All distribution data structures are set up.
void communicate() override
The mesh is gathered and sent to another participant (if required)
void compareBoundingBoxes() override
Intersections between bounding boxes around each rank are computed.
A partition that is computed from a mesh received from another participant.
void communicate() override
The mesh is communicated between both primary ranks (if required)
T emplace(T... args)
void receiveBoundingBoxMap(Communication &communication, int rankSender, mesh::Mesh::BoundingBoxMap &bbm)
Definition Extra.cpp:63
void sendConnectionMap(Communication &communication, int rankReceiver, const mesh::Mesh::ConnectionMap &cm)
Definition Extra.cpp:28
contains the logic of the parallel communication between participants.
Definition BoundM2N.cpp:12
std::shared_ptr< Mapping > PtrMapping
provides Mesh, Data and primitives.
std::shared_ptr< Mesh > PtrMesh
@ Events
Require to initialize Event.
Main namespace of the precice library.
T size(T... args)