preCICE v3.2.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RTreeTests.cpp
Go to the documentation of this file.
1#include <Eigen/Core>
2#include <algorithm>
3#include <iterator>
4#include <limits>
5#include <list>
6#include <memory>
7#include <set>
8#include <utility>
9#include <vector>
10
11#include "logging/Logger.hpp"
12#include "math/geometry.hpp"
13#include "mesh/Data.hpp"
14#include "mesh/Edge.hpp"
15#include "mesh/Mesh.hpp"
17#include "mesh/Triangle.hpp"
18#include "mesh/Vertex.hpp"
19#include "query/Index.hpp"
21#include "testing/Testing.hpp"
22
23using namespace precice;
24using namespace precice::mesh;
25using namespace precice::query;
26
27namespace {
28PtrMesh fullMesh()
29{
30 PtrMesh ptr(new Mesh("MyMesh", 3, testing::nextMeshID()));
31 auto &mesh = *ptr;
32 auto &v1 = mesh.createVertex(Eigen::Vector3d(0, 2, 0));
33 auto &v2 = mesh.createVertex(Eigen::Vector3d(2, 1, 0));
34 auto &v3 = mesh.createVertex(Eigen::Vector3d(3, 0, 0));
35 auto &v4 = mesh.createVertex(Eigen::Vector3d(1, 0, 0));
36 // Quad Borders
37 auto &e1 = mesh.createEdge(v1, v2);
38 auto &e2 = mesh.createEdge(v2, v3);
39 auto &e3 = mesh.createEdge(v3, v4);
40 auto &e4 = mesh.createEdge(v4, v1);
41 // Diagonal
42 auto &e5 = mesh.createEdge(v2, v4);
43 // Triangles
44 mesh.createTriangle(e1, e5, e4);
45 mesh.createTriangle(e2, e3, e5);
46 return ptr;
47}
48
49PtrMesh edgeMesh3D()
50{
52 mesh->createVertex(Eigen::Vector3d(0, 0, 0));
53 mesh->createVertex(Eigen::Vector3d(0, 0, 1));
54 mesh->createVertex(Eigen::Vector3d(0, 1, 0));
55 mesh->createVertex(Eigen::Vector3d(0, 1, 1));
56 mesh->createVertex(Eigen::Vector3d(1, 0, 0));
57 mesh->createVertex(Eigen::Vector3d(1, 0, 1));
58 auto &v1 = mesh->createVertex(Eigen::Vector3d(1, 1, 0));
59 auto &v2 = mesh->createVertex(Eigen::Vector3d(1, 1, 1));
60 mesh->createEdge(v1, v2);
61 return mesh;
62}
63
64PtrMesh edgeMesh2D()
65{
66 PtrMesh mesh(new precice::mesh::Mesh("MyMesh", 2, testing::nextMeshID()));
67 mesh->createVertex(Eigen::Vector2d(0, 0));
68 mesh->createVertex(Eigen::Vector2d(0, 1));
69 auto &v1 = mesh->createVertex(Eigen::Vector2d(1, 0));
70 auto &v2 = mesh->createVertex(Eigen::Vector2d(1, 1));
71 mesh->createEdge(v1, v2);
72 return mesh;
73}
74
75PtrMesh vertexMesh3D()
76{
78 mesh->createVertex(Eigen::Vector3d(0, 0, 0));
79 mesh->createVertex(Eigen::Vector3d(0, 0, 1));
80 mesh->createVertex(Eigen::Vector3d(0, 1, 0));
81 mesh->createVertex(Eigen::Vector3d(0, 1, 1));
82 mesh->createVertex(Eigen::Vector3d(1, 0, 0));
83 mesh->createVertex(Eigen::Vector3d(1, 0, 1));
84 mesh->createVertex(Eigen::Vector3d(1, 1, 0));
85 mesh->createVertex(Eigen::Vector3d(1, 1, 1));
86 mesh->computeBoundingBox();
87 return mesh;
88}
89} // namespace
90
91BOOST_AUTO_TEST_SUITE(QueryTests)
92BOOST_AUTO_TEST_SUITE(MeshTests)
94
97{
99 auto mesh = edgeMesh2D();
100 Index indexTree(mesh);
101 Eigen::Vector2d location(0.2, 0.8);
102
103 auto result = indexTree.getClosestVertex(location);
104 BOOST_TEST(mesh->vertex(result.index).getCoords() == Eigen::Vector2d(0, 1));
105}
106
107PRECICE_TEST_SETUP(1_rank)
109{
110 PRECICE_TEST();
111 auto mesh = edgeMesh3D();
112 Index indexTree(mesh);
113 Eigen::Vector3d location(0.8, 0.0, 0.8);
114
115 auto result = indexTree.getClosestVertex(location);
116 BOOST_TEST(mesh->vertex(result.index).getCoords() == Eigen::Vector3d(1, 0, 1));
117}
118
119PRECICE_TEST_SETUP(1_rank)
120BOOST_AUTO_TEST_CASE(Query3DFullVertex)
121{
122 PRECICE_TEST();
124 const double z1 = 0.1;
125 const double z2 = -0.1;
126 auto &v00 = mesh->createVertex(Eigen::Vector3d(0, 0, 0));
127 auto &v01 = mesh->createVertex(Eigen::Vector3d(0, 1, 0));
128 auto &v10 = mesh->createVertex(Eigen::Vector3d(1, 0, z1));
129 auto &v11 = mesh->createVertex(Eigen::Vector3d(1, 1, z1));
130 auto &v20 = mesh->createVertex(Eigen::Vector3d(2, 0, z2));
131 auto &v21 = mesh->createVertex(Eigen::Vector3d(2, 1, z2));
132 auto &v30 = mesh->createVertex(Eigen::Vector3d(3, 0, z2));
133 auto &v31 = mesh->createVertex(Eigen::Vector3d(3, 1, z2));
134 auto &ell = mesh->createEdge(v00, v01);
135 auto &elt = mesh->createEdge(v01, v11);
136 auto &elr = mesh->createEdge(v11, v10);
137 auto &elb = mesh->createEdge(v10, v00);
138 auto &eld = mesh->createEdge(v00, v11);
139 auto &erl = elr;
140 auto &ert = mesh->createEdge(v11, v21);
141 auto &err = mesh->createEdge(v21, v20);
142 auto &erb = mesh->createEdge(v20, v10);
143 auto &erd = mesh->createEdge(v10, v21);
144 mesh->createTriangle(ell, elt, eld);
145 mesh->createTriangle(eld, elb, elr);
146 mesh->createTriangle(erl, ert, erd);
147 mesh->createTriangle(erd, erb, err);
148
149 Index indexTree(mesh);
150 {
151 Eigen::Vector3d location(0.8, 0.0, 0.8);
152 auto result = indexTree.getClosestVertex(location);
153
154 BOOST_TEST(mesh->vertex(result.index).getID() == v10.getID());
155 }
156 {
157 Eigen::Vector3d location(0.8, 0.0, 0.8);
158 int nVertices = 2;
159 std::vector<VertexID> expectedResult({v00.getID(), v10.getID()});
160 auto result = indexTree.getClosestVertices(location, nVertices);
161
162 BOOST_TEST(result.size() == nVertices);
163 BOOST_TEST(std::is_permutation(result.begin(), result.end(), expectedResult.begin()));
164 }
165 {
166 Eigen::Vector3d location(3.5, 3.5, 0.0);
167 int nVertices = 4;
168 std::vector<VertexID> expectedResult({v11.getID(), v30.getID(), v21.getID(), v31.getID()});
169 auto result = indexTree.getClosestVertices(location, nVertices);
170
171 BOOST_TEST(result.size() == nVertices);
172 BOOST_TEST(std::is_permutation(result.begin(), result.end(), expectedResult.begin()));
173 }
174}
175
177PRECICE_TEST_SETUP(1_rank)
178BOOST_AUTO_TEST_CASE(QueryWithBoxEmpty)
179{
180 PRECICE_TEST();
181 auto mesh = vertexMesh3D();
182 Index indexTree(mesh);
183 mesh::Vertex searchVertex(Eigen::Vector3d(0.8, 1, 0), 0);
184 double radius = 0.1; // No vertices in radius
185
186 auto results = indexTree.getVerticesInsideBox(searchVertex, radius);
187 BOOST_TEST(results.empty());
188}
189
191PRECICE_TEST_SETUP(1_rank)
192BOOST_AUTO_TEST_CASE(QueryWithBox2Matches)
193{
194 PRECICE_TEST();
195 auto mesh = vertexMesh3D();
196 Index indexTree(mesh);
197
198 mesh::Vertex searchVertex(Eigen::Vector3d(0.8, 1, 0), 0);
199 double radius = 0.81; // Two vertices in radius
200
201 auto results = indexTree.getVerticesInsideBox(searchVertex, radius);
202 BOOST_TEST(results.size() == 2);
203 BOOST_TEST(mesh->vertex(results.at(0)).getCoords() == Eigen::Vector3d(0, 1, 0));
204 BOOST_TEST(mesh->vertex(results.at(1)).getCoords() == Eigen::Vector3d(1, 1, 0));
205}
206
208PRECICE_TEST_SETUP(1_rank)
209BOOST_AUTO_TEST_CASE(QueryWithBoxEverything)
210{
211 PRECICE_TEST();
212 auto mesh = vertexMesh3D();
213 Index indexTree(mesh);
214
215 mesh::Vertex searchVertex(Eigen::Vector3d(0.8, 1, 0), 0);
216 double radius = std::numeric_limits<double>::max();
217
218 auto results = indexTree.getVerticesInsideBox(searchVertex, radius);
219 BOOST_TEST(results.size() == 8);
220}
221
222PRECICE_TEST_SETUP(1_rank)
223BOOST_AUTO_TEST_CASE(QueryRtreeBoundingBox2D)
224{
225 PRECICE_TEST();
226 auto mesh = edgeMesh2D();
227 auto result = mesh->index().getRtreeBounds();
228 mesh->computeBoundingBox();
229 auto comparison = mesh->getBoundingBox();
230
231 BOOST_TEST(result == comparison);
232 BOOST_TEST(result.minCorner() == Eigen::Vector2d(0, 0));
233 BOOST_TEST(result.maxCorner() == Eigen::Vector2d(1, 1));
234}
235
236PRECICE_TEST_SETUP(1_rank)
237BOOST_AUTO_TEST_CASE(QueryRtreeBoundingBox3D)
238{
239 PRECICE_TEST();
240 auto mesh = vertexMesh3D();
241 auto result = mesh->index().getRtreeBounds();
242 mesh->computeBoundingBox();
243 auto comparison = mesh->getBoundingBox();
244
245 BOOST_TEST(result == comparison);
246 BOOST_TEST(result.minCorner() == Eigen::Vector3d(0, 0, 0));
247 BOOST_TEST(result.maxCorner() == Eigen::Vector3d(1, 1, 1));
248}
249
250PRECICE_TEST_SETUP(1_rank)
251BOOST_AUTO_TEST_CASE(QueryRtreeBoundingBox3DComplex)
252{
253 PRECICE_TEST();
255 mesh->createVertex(Eigen::Vector3d(7, 4, 3.3));
256 mesh->createVertex(Eigen::Vector3d(26.4777, 5, 8));
257 mesh->createVertex(Eigen::Vector3d(-23.4, 100000.2, 7));
258 mesh->createVertex(Eigen::Vector3d(0.211, -21.37, 0.00003));
259 auto result = mesh->index().getRtreeBounds();
260 mesh->computeBoundingBox();
261 auto comparison = mesh->getBoundingBox();
262
263 BOOST_TEST(result == comparison);
264 BOOST_TEST(result.minCorner() == Eigen::Vector3d(-23.4, -21.37, 0.00003));
265 BOOST_TEST(result.maxCorner() == Eigen::Vector3d(26.4777, 100000.2, 8));
266}
267
269
271
272PRECICE_TEST_SETUP(1_rank)
274{
275 PRECICE_TEST();
276 auto mesh = edgeMesh2D();
277 Index indexTree(mesh);
278 Eigen::Vector2d location(0.2, 0.8);
279
280 auto results = indexTree.getClosestEdges(location, 1);
281 BOOST_TEST(results.size() == 1);
282 auto &edge = mesh->edges().at(results.front().index);
283
284 BOOST_TEST(edge.vertex(0).getCoords() == Eigen::Vector2d(1, 0));
285 BOOST_TEST(edge.vertex(1).getCoords() == Eigen::Vector2d(1, 1));
286}
287
288PRECICE_TEST_SETUP(1_rank)
290{
291 PRECICE_TEST();
292 auto mesh = edgeMesh3D();
293 Index indexTree(mesh);
294 Eigen::Vector3d location(1.8, 0.0, 0.8);
295
296 auto results = indexTree.getClosestEdges(location, 1);
297
298 BOOST_TEST(results.size() == 1);
299 auto match = results.front().index;
300
301 BOOST_TEST(match < mesh->edges().size());
302 auto &edge = mesh->edges().at(match);
303 Eigen::Vector3d p1(1, 1, 0);
304 Eigen::Vector3d p2(1, 1, 1);
305 BOOST_TEST((edge.vertex(0).getCoords() == p1 || edge.vertex(0).getCoords() == p2));
306 if (edge.vertex(0).getCoords() == p1) {
307 BOOST_TEST(edge.vertex(1).getCoords() == p2);
308 } else {
309 BOOST_TEST(edge.vertex(1).getCoords() == p1);
310 }
311}
312
313PRECICE_TEST_SETUP(1_rank)
314BOOST_AUTO_TEST_CASE(Query3DFullEdge)
315{
316 PRECICE_TEST();
318 const double z1 = 0.1;
319 const double z2 = -0.1;
320 auto &v00 = mesh->createVertex(Eigen::Vector3d(0, 0, 0));
321 auto &v01 = mesh->createVertex(Eigen::Vector3d(0, 1, 0));
322 auto &v10 = mesh->createVertex(Eigen::Vector3d(1, 0, z1));
323 auto &v11 = mesh->createVertex(Eigen::Vector3d(1, 1, z1));
324 auto &v20 = mesh->createVertex(Eigen::Vector3d(2, 0, z2));
325 auto &v21 = mesh->createVertex(Eigen::Vector3d(2, 1, z2));
326 auto &ell = mesh->createEdge(v00, v01);
327 auto &elt = mesh->createEdge(v01, v11);
328 auto &elr = mesh->createEdge(v11, v10);
329 auto &elb = mesh->createEdge(v10, v00);
330 auto &eld = mesh->createEdge(v00, v11);
331 auto &erl = elr;
332 auto &ert = mesh->createEdge(v11, v21);
333 auto &err = mesh->createEdge(v21, v20);
334 auto &erb = mesh->createEdge(v20, v10);
335 auto &erd = mesh->createEdge(v10, v21);
336 mesh->createTriangle(ell, elt, eld);
337 mesh->createTriangle(eld, elb, elr);
338 mesh->createTriangle(erl, ert, erd);
339 mesh->createTriangle(erd, erb, err);
340
341 Index indexTree(mesh);
342 Eigen::Vector3d location(0.8, 0.5, 0.0);
343 auto results = indexTree.getClosestEdges(location, 2);
344
346 &mesh->edges().at(results.at(0).index),
347 &mesh->edges().at(results.at(1).index),
348 };
349 std::set<mesh::Edge *> expected{&elr, &eld};
350
351 BOOST_TEST(matches.size() == 2);
352 BOOST_TEST(matches == expected, boost::test_tools::per_element());
353}
354
356
358
359PRECICE_TEST_SETUP(1_rank)
360BOOST_AUTO_TEST_CASE(Query3DFullTriangle)
361{
362 PRECICE_TEST();
363
365 const double z1 = 0.1;
366 const double z2 = -0.1;
367 auto &v00 = mesh->createVertex(Eigen::Vector3d(0, 0, 0));
368 auto &v01 = mesh->createVertex(Eigen::Vector3d(0, 1, 0));
369 auto &v10 = mesh->createVertex(Eigen::Vector3d(1, 0, z1));
370 auto &v11 = mesh->createVertex(Eigen::Vector3d(1, 1, z1));
371 auto &v20 = mesh->createVertex(Eigen::Vector3d(2, 0, z2));
372 auto &v21 = mesh->createVertex(Eigen::Vector3d(2, 1, z2));
373 auto &ell = mesh->createEdge(v00, v01);
374 auto &elt = mesh->createEdge(v01, v11);
375 auto &elr = mesh->createEdge(v11, v10);
376 auto &elb = mesh->createEdge(v10, v00);
377 auto &eld = mesh->createEdge(v00, v11);
378 auto &erl = elr;
379 auto &ert = mesh->createEdge(v11, v21);
380 auto &err = mesh->createEdge(v21, v20);
381 auto &erb = mesh->createEdge(v20, v10);
382 auto &erd = mesh->createEdge(v10, v21);
383 auto &tlt = mesh->createTriangle(ell, elt, eld);
384 auto &tlb = mesh->createTriangle(eld, elb, elr);
385 auto &trt = mesh->createTriangle(erl, ert, erd);
386 mesh->createTriangle(erd, erb, err);
387
388 Index indexTree(mesh);
389
390 Eigen::Vector3d location(0.7, 0.5, 0.0);
391
392 auto results = indexTree.getClosestTriangles(location, 3);
393 BOOST_TEST(results.size() == 3);
394
396 &mesh->triangles().at(results.at(0).index),
397 &mesh->triangles().at(results.at(1).index),
398 &mesh->triangles().at(results.at(2).index)};
399 std::set<mesh::Triangle *> expected{&tlb, &tlt, &trt};
400
401 BOOST_TEST(matches.size() == 3);
402 BOOST_TEST(matches == expected, boost::test_tools::per_element());
403}
404
405BOOST_AUTO_TEST_SUITE_END() // Triangle
406
407BOOST_AUTO_TEST_SUITE(Projection)
408
409PRECICE_TEST_SETUP(1_rank)
410BOOST_AUTO_TEST_CASE(ProjectionToVertex)
411{
412 PRECICE_TEST();
413 auto meshPtr = fullMesh();
414 Index indexTree(meshPtr);
415
416 Eigen::Vector3d location(4.0, 0.0, 0.0);
417 std::vector<int> expectedIndices = {2};
418 std::vector<double> expectedWeights = {1.0};
419
420 auto match = indexTree.findNearestProjection(location, 1);
421
422 BOOST_TEST(match.polation.getWeightedElements().size() == 1); // Check number of weights
423 BOOST_TEST(match.polation.distance() == 1.0); // Check the distance
424 BOOST_TEST(match.polation.isInterpolation());
425
426 for (int i = 0; i < static_cast<int>(match.polation.getWeightedElements().size()); ++i) {
427 BOOST_TEST(match.polation.getWeightedElements().at(i).vertexID == expectedIndices.at(i)); // Check index
428 BOOST_TEST(match.polation.getWeightedElements().at(i).weight == expectedWeights.at(i)); // Check the weight
429 }
430}
431
432PRECICE_TEST_SETUP(1_rank)
433BOOST_AUTO_TEST_CASE(ProjectionToEdge)
434{
435 PRECICE_TEST();
436 auto meshPtr = fullMesh();
437 Index indexTree(meshPtr);
438
439 Eigen::Vector3d location(2.0, -1.0, 0.0);
440 std::vector<int> expectedIndices = {2, 3};
441 std::vector<double> expectedWeights = {0.5, 0.5};
442
443 auto match = indexTree.findNearestProjection(location, 1);
444
445 BOOST_TEST(match.polation.getWeightedElements().size() == 2); // Check number of weights
446 BOOST_TEST(match.polation.distance() == 1.0); // Check the distance
447 BOOST_TEST(match.polation.isInterpolation());
448
449 for (int i = 0; i < static_cast<int>(match.polation.getWeightedElements().size()); ++i) {
450 BOOST_TEST(match.polation.getWeightedElements().at(i).vertexID == expectedIndices.at(i)); // Check index
451 BOOST_TEST(match.polation.getWeightedElements().at(i).weight == expectedWeights.at(i)); // Check the weight
452 }
453}
454
455PRECICE_TEST_SETUP(1_rank)
456BOOST_AUTO_TEST_CASE(ProjectionToTriangle)
457{
458 PRECICE_TEST();
459 auto meshPtr = fullMesh();
460 Index indexTree(meshPtr);
461
462 Eigen::Vector3d location(1.0, 1.0, 0.1);
463 std::vector<int> expectedIndices = {0, 1, 3};
464 std::vector<double> expectedWeights = {1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0};
465
466 auto match = indexTree.findNearestProjection(location, 1);
467
468 BOOST_TEST(match.polation.getWeightedElements().size() == 3); // Check number of weights
469 BOOST_TEST(match.polation.distance() == 0.1); // Check the distance
470 BOOST_TEST(match.polation.isInterpolation());
471
472 for (int i = 0; i < static_cast<int>(match.polation.getWeightedElements().size()); ++i) {
473 BOOST_TEST(match.polation.getWeightedElements().at(i).vertexID == expectedIndices.at(i)); // Check index
474 BOOST_TEST(match.polation.getWeightedElements().at(i).weight == expectedWeights.at(i)); // Check the weight
475 }
476}
477
478BOOST_AUTO_TEST_SUITE_END() // Projection
479
480BOOST_AUTO_TEST_SUITE(Tetrahedra)
481
482PRECICE_TEST_SETUP(1_rank)
483BOOST_AUTO_TEST_CASE(CubeBoundingBoxIndex)
484{
485 PRECICE_TEST();
486 PtrMesh ptr(new Mesh("MyMesh", 3, testing::nextMeshID()));
487 auto &mesh = *ptr;
488 Index indexTree(ptr);
489
490 Eigen::Vector3d location(0.5, 0.5, 0.5);
491 std::vector<int> expectedIndices = {0, 1};
492 // Set up 2 tetrahedra with the same bounding box
493 auto &v00 = mesh.createVertex(Eigen::Vector3d(0, 0, 0));
494 auto &v01 = mesh.createVertex(Eigen::Vector3d(1, 0, 0));
495 auto &v02 = mesh.createVertex(Eigen::Vector3d(0, 1, 0));
496 auto &v03 = mesh.createVertex(Eigen::Vector3d(1, 0, 1));
497 auto &v04 = mesh.createVertex(Eigen::Vector3d(1, 1, 1));
498
499 mesh.createTetrahedron(v00, v01, v02, v03);
500 mesh.createTetrahedron(v04, v01, v02, v03);
501
502 auto match = indexTree.getEnclosingTetrahedra(location);
503
504 BOOST_TEST(match.size() == 2);
505}
506
507PRECICE_TEST_SETUP(1_rank)
509{
510 PRECICE_TEST();
511 /*
512 For a location and 3 tetrahedra such that:
513 - First contains the location
514 - Second doesn't, but its Bounding Box does
515 - Third doesn't and neither does its AABB
516 Check that only 1st and 2nd are found by getEnclosingTetrahedra
517 */
518 PtrMesh ptr(new Mesh("MyMesh", 3, testing::nextMeshID()));
519 auto &mesh = *ptr;
520 Index indexTree(ptr);
521
522 Eigen::Vector3d location(0.2, 0.2, 0.2);
523 std::vector<int> expectedIndices = {0, 1};
524
525 // Set containing tetra
526 auto &v00 = mesh.createVertex(Eigen::Vector3d(0, 0, 0));
527 auto &v01 = mesh.createVertex(Eigen::Vector3d(1, 0, 0));
528 auto &v02 = mesh.createVertex(Eigen::Vector3d(0, 1, 0));
529 auto &v03 = mesh.createVertex(Eigen::Vector3d(0, 0, 1));
530 mesh.createTetrahedron(v00, v01, v02, v03);
531
532 // Set non-containing tetra with containing BB (from 0 to 1 in each direction)
533 auto &v10 = mesh.createVertex(Eigen::Vector3d(1, 1, 1));
534 auto &v11 = mesh.createVertex(Eigen::Vector3d(1, 0, 0));
535 auto &v12 = mesh.createVertex(Eigen::Vector3d(0, 1, 0));
536 auto &v13 = mesh.createVertex(Eigen::Vector3d(0, 0, 1));
537 mesh.createTetrahedron(v10, v11, v12, v13);
538
539 // Set tetra far away
540 auto &v20 = mesh.createVertex(Eigen::Vector3d(1, 1, 1));
541 auto &v21 = mesh.createVertex(Eigen::Vector3d(2, 1, 1));
542 auto &v22 = mesh.createVertex(Eigen::Vector3d(1, 2, 1));
543 auto &v23 = mesh.createVertex(Eigen::Vector3d(1, 1, 2));
544 mesh.createTetrahedron(v20, v21, v22, v23);
545
546 auto match = indexTree.getEnclosingTetrahedra(location);
547
548 BOOST_TEST(match.size() == 2);
549 BOOST_TEST(((match[0] == 0 && match[1] == 1) || (match[0] == 1 && match[1] == 0)));
550}
551
552PRECICE_TEST_SETUP(1_rank)
553BOOST_AUTO_TEST_CASE(TetraWorksOnBoundary)
554{
555 PRECICE_TEST();
556 /*
557 Check that the AABB safety factor is high enough. Do all the corners of a tetra fit inside its AABB?
558 */
559 PtrMesh ptr(new Mesh("MyMesh", 3, testing::nextMeshID()));
560 auto &mesh = *ptr;
561 Index indexTree(ptr);
562
564 locations.emplace_back(0, 0, 0);
565 locations.emplace_back(1, 0, 0);
566 locations.emplace_back(0, 1, 0);
567 locations.emplace_back(0, 0, 1);
568
569 // Set containing tetra
570 auto &v00 = mesh.createVertex(Eigen::Vector3d(0, 0, 0));
571 auto &v01 = mesh.createVertex(Eigen::Vector3d(1, 0, 0));
572 auto &v02 = mesh.createVertex(Eigen::Vector3d(0, 1, 0));
573 auto &v03 = mesh.createVertex(Eigen::Vector3d(0, 0, 1));
574 mesh.createTetrahedron(v00, v01, v02, v03);
575
576 for (const auto &vertex : locations) {
577 auto match = indexTree.getEnclosingTetrahedra(vertex);
578 BOOST_TEST(match.size() == 1);
579 }
580}
581
582BOOST_AUTO_TEST_SUITE_END() // Tetrahedra
583
double const * ptr
Definition ExportCSV.cpp:23
BOOST_AUTO_TEST_SUITE(PreProcess)
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(Query2DVertex)
#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)
T begin(T... args)
Linear edge of a mesh, defined by two Vertex objects.
Definition Edge.hpp:15
Container and creator for meshes.
Definition Mesh.hpp:38
Triangle & createTriangle(Edge &edgeOne, Edge &edgeTwo, Edge &edgeThree)
Creates and initializes a Triangle object.
Definition Mesh.cpp:121
Vertex & vertex(VertexID id)
Mutable access to a vertex by VertexID.
Definition Mesh.cpp:43
const query::Index & index() const
Call preprocess() before index() to ensure correct projection handling.
Definition Mesh.hpp:321
void computeBoundingBox()
Computes the boundingBox for the vertices.
Definition Mesh.cpp:244
TriangleContainer & triangles()
Returns modifiable container holding all triangles.
Definition Mesh.cpp:80
const BoundingBox & getBoundingBox() const
Returns the bounding box of the mesh.
Definition Mesh.cpp:388
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
Triangle of a mesh, defined by three vertices.
Definition Triangle.hpp:24
Vertex of a mesh.
Definition Vertex.hpp:16
VertexID getID() const
Returns the unique (among vertices of one mesh on one processor) ID of the vertex.
Definition Vertex.hpp:109
Class to query the index trees of the mesh.
Definition Index.hpp:64
mesh::BoundingBox getRtreeBounds()
Definition Index.cpp:367
std::vector< TetrahedronID > getEnclosingTetrahedra(const Eigen::VectorXd &location)
Return all the tetrahedra whose axis-aligned bounding box contains a vertex.
Definition Index.cpp:263
VertexMatch getClosestVertex(const Eigen::VectorXd &sourceCoord)
Get the closest vertex to the given vertex.
Definition Index.cpp:171
ProjectionMatch findNearestProjection(const Eigen::VectorXd &location, int n)
Find the closest interpolation element to the given location. If exists, triangle or edge projection ...
Definition Index.cpp:275
std::vector< TriangleMatch > getClosestTriangles(const Eigen::VectorXd &sourceCoord, int n)
Get n number of closest triangles to the given vertex.
Definition Index.cpp:210
std::vector< VertexID > getVerticesInsideBox(const mesh::Vertex &centerVertex, double radius)
Return all the vertices inside the box formed by vertex and radius (boundary exclusive)
Definition Index.cpp:223
std::vector< VertexID > getClosestVertices(const Eigen::VectorXd &sourceCoord, int n)
Get n number of closest vertices to the given vertex.
Definition Index.cpp:184
std::vector< EdgeMatch > getClosestEdges(const Eigen::VectorXd &sourceCoord, int n)
Get n number of closest edges to the given vertex.
Definition Index.cpp:197
T emplace_back(T... args)
T end(T... args)
T is_permutation(T... args)
T max(T... args)
provides Mesh, Data and primitives.
contains geometrical queries.
Main namespace of the precice library.
T size(T... args)