https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Classes | Functions
SBMBndElementTest.C File Reference

Go to the source code of this file.

Classes

class  SBMBndUnsupportedForTest
 

Functions

 TEST (SBMBndElementTest, Edge2Normal)
 
 TEST (SBMBndElementTest, Tri3Normal)
 
 TEST (SBMBndElementTest, Edge2NormalTilted)
 
 TEST (SBMBndElementTest, Edge2DistanceNodeFallback)
 
 TEST (SBMBndElementTest, Tri3NormalTilted)
 
 TEST (SBMBndElementTest, ProjectedBoundingBoxDiagonal)
 
 TEST (SBMBndElementTest, BaseDynamicDispatcherIntersectAndBoundingBall)
 
 TEST (SBMBndElementTest, ConstructionRejectsUnsupportedSideType)
 
 TEST (SBMBndElementTest, UnsupportedGeometryDispatchersThrow)
 

Function Documentation

◆ TEST() [1/9]

TEST ( SBMBndElementTest  ,
BaseDynamicDispatcherIntersectAndBoundingBall   
)

Definition at line 242 of file SBMBndElementTest.C.

243{
244 // Exercise SBMBndElementBase::intersect / computeBoundingBall through a
245 // base-class reference; the `using` declarations in the derived classes
246 // otherwise route direct calls to LineSegment/Triangle and bypass these
247 // dispatchers.
248 std::unique_ptr<Edge2> edge(new Edge2());
249 std::unique_ptr<Node> e0(new Node(Point(0.0, 0.0, 0.0), 0));
250 std::unique_ptr<Node> e1(new Node(Point(1.0, 0.0, 0.0), 1));
251 edge->set_node(0) = e0.get();
252 edge->set_node(1) = e1.get();
253 SBMBndEdge2 bnd_edge(edge.get());
254 const SBMBndElementBase & edge_base = bnd_edge;
255
256 LineSegment crossing(Point(0.5, -1.0, 0.0), Point(0.5, 1.0, 0.0));
257 LineSegment parallel(Point(0.0, 1.0, 0.0), Point(1.0, 1.0, 0.0));
258 EXPECT_TRUE(edge_base.intersect(crossing));
259 EXPECT_FALSE(edge_base.intersect(parallel));
260
261 const Ball edge_ball = edge_base.computeBoundingBall();
262 EXPECT_NEAR(edge_ball.center()(0), 0.5, 1e-12);
263 EXPECT_NEAR(edge_ball.radius(), 0.5, 1e-12);
264
265 std::unique_ptr<Tri3> tri(new Tri3());
266 std::unique_ptr<Node> t0(new Node(Point(0.0, 0.0, 0.0), 0));
267 std::unique_ptr<Node> t1(new Node(Point(1.0, 0.0, 0.0), 1));
268 std::unique_ptr<Node> t2(new Node(Point(0.0, 1.0, 0.0), 2));
269 tri->set_node(0) = t0.get();
270 tri->set_node(1) = t1.get();
271 tri->set_node(2) = t2.get();
272 SBMBndTri3 bnd_tri(tri.get());
273 const SBMBndElementBase & tri_base = bnd_tri;
274
275 LineSegment piercing(Point(0.3, 0.3, -1.0), Point(0.3, 0.3, 1.0));
276 LineSegment missing(Point(2.0, 2.0, -1.0), Point(2.0, 2.0, 1.0));
277 EXPECT_TRUE(tri_base.intersect(piercing));
278 EXPECT_FALSE(tri_base.intersect(missing));
279
280 const Ball tri_ball = tri_base.computeBoundingBall();
281 EXPECT_GT(tri_ball.radius(), 0.0);
282}
const libMesh::Point & center() const
libMesh::Real radius() const
Derived class for 2-node edge elements LineSegment is listed first so it is initialized before SBMBnd...
Definition SBMBndEdge2.h:20
Base class for SBM boundary elements.
Ball computeBoundingBall() const
Compute a bounding ball for this boundary element.
bool intersect(const LineSegment &line_segment) const
Check if the given line segment intersects this boundary element.
Derived class for 3-node triangular elements (Tri3) Triangle is listed first so it is initialized bef...
Definition SBMBndTri3.h:20

◆ TEST() [2/9]

TEST ( SBMBndElementTest  ,
ConstructionRejectsUnsupportedSideType   
)

Definition at line 284 of file SBMBndElementTest.C.

285{
286 // SBMBndElementBase validates side(0)->type() in its ctor so misconfigured
287 // SBMBnd* subclasses fail to construct rather than producing wrong answers
288 // later. Tet4 has Tri3 sides (neither EDGE2 nor NODEELEM) and must throw.
289 std::unique_ptr<Tet4> tet(new Tet4());
290 std::unique_ptr<Node> n0(new Node(Point(0.0, 0.0, 0.0), 0));
291 std::unique_ptr<Node> n1(new Node(Point(1.0, 0.0, 0.0), 1));
292 std::unique_ptr<Node> n2(new Node(Point(0.0, 1.0, 0.0), 2));
293 std::unique_ptr<Node> n3(new Node(Point(0.0, 0.0, 1.0), 3));
294 tet->set_node(0) = n0.get();
295 tet->set_node(1) = n1.get();
296 tet->set_node(2) = n2.get();
297 tet->set_node(3) = n3.get();
298
299 EXPECT_THROW(
300 {
301 try
302 {
303 SBMBndUnsupportedForTest bnd(tet.get(), Point(0.0, 0.0, 1.0));
304 }
305 catch (const std::exception & e)
306 {
307 EXPECT_NE(std::string(e.what()).find("unsupported side type"), std::string::npos);
308 throw;
309 }
310 },
311 std::exception);
312}

◆ TEST() [3/9]

TEST ( SBMBndElementTest  ,
Edge2DistanceNodeFallback   
)

Definition at line 145 of file SBMBndElementTest.C.

146{
147 // Edge from (0,0,0) to (1,0,0); query point lies far off the line axis so
148 // its projection onto the edge falls outside the segment, forcing the side
149 // loop in distanceFrom() to take the NODEELEM switch case.
150 std::unique_ptr<Edge2> edge(new Edge2());
151 std::unique_ptr<Node> n0(new Node(Point(0.0, 0.0, 0.0), 0));
152 std::unique_ptr<Node> n1(new Node(Point(1.0, 0.0, 0.0), 1));
153 edge->set_node(0) = n0.get();
154 edge->set_node(1) = n1.get();
155
156 SBMBndEdge2 bnd_edge(edge.get());
157
158 // Projection of (2, 1, 0) onto the line is (2, 0, 0) which is outside [0,1].
159 // Nearest entity is node (1, 0, 0).
160 Point pt(2.0, 1.0, 0.0);
161 Point dist = bnd_edge.distanceFrom(pt);
162 EXPECT_NEAR(dist(0), -1.0, 1e-12);
163 EXPECT_NEAR(dist(1), -1.0, 1e-12);
164 EXPECT_NEAR(dist(2), 0.0, 1e-12);
165}

◆ TEST() [4/9]

TEST ( SBMBndElementTest  ,
Edge2Normal   
)

Definition at line 34 of file SBMBndElementTest.C.

35{
36 std::unique_ptr<Edge2> edge(new Edge2());
37
38 std::unique_ptr<Node> n0(new Node(Point(0.0, 0.0, 0.0), 0));
39 std::unique_ptr<Node> n1(new Node(Point(1.0, 0.0, 0.0), 1));
40
41 edge->set_node(0) = n0.get();
42 edge->set_node(1) = n1.get();
43
44 SBMBndEdge2 bnd_edge(edge.get());
45 Point n = bnd_edge.normal();
46
47 EXPECT_NEAR(n(0), 0.0, 1e-12);
48 EXPECT_NEAR(n(2), 0.0, 1e-12);
49 EXPECT_NEAR(std::abs(n(1)), 1.0, 1e-12);
50
51 // Line crossing through (0.5, -1) to (0.5, 1)
52 Point a(0.5, -1.0, 0.0);
53 Point b(0.5, 1.0, 0.0);
54 LineSegment line_segment_ab(a, b);
55 EXPECT_TRUE(bnd_edge.intersect(line_segment_ab));
56
57 // Line parallel, no intercept
58 Point c(0.0, 1.0, 0.0);
59 Point d(1.0, 1.0, 0.0);
60 LineSegment line_segment_cd(c, d);
61 EXPECT_FALSE(bnd_edge.intersect(line_segment_cd));
62
63 // Check distance vector
64 Point pt(0.5, 1.0, 0.0);
65 Point dist = bnd_edge.distanceFrom(pt);
66 EXPECT_NEAR(dist(1), -1.0, 1e-12);
67}

◆ TEST() [5/9]

TEST ( SBMBndElementTest  ,
Edge2NormalTilted   
)

Definition at line 106 of file SBMBndElementTest.C.

107{
108 std::unique_ptr<Edge2> edge(new Edge2());
109
110 std::unique_ptr<Node> n0(new Node(Point(0.0, 0.0, 0.0), 0));
111 std::unique_ptr<Node> n1(new Node(Point(1.0, 1.0, 0.0), 1));
112
113 edge->set_node(0) = n0.get();
114 edge->set_node(1) = n1.get();
115
116 SBMBndEdge2 bnd_edge(edge.get());
117 Point n = bnd_edge.normal();
118
119 // Expected normal
120 const double inv_sqrt2 = 1.0 / std::sqrt(2.0);
121 EXPECT_NEAR(n(0), -inv_sqrt2, 1e-12);
122 EXPECT_NEAR(n(1), inv_sqrt2, 1e-12);
123 EXPECT_NEAR(n(2), 0.0, 1e-12);
124
125 // Line crossing
126 Point a(0.5, 0.0, 0.0);
127 Point b(0.5, 1.0, 0.0);
128 LineSegment line_segment_ab(a, b);
129 EXPECT_TRUE(bnd_edge.intersect(line_segment_ab));
130
131 // Line outside
132 Point c(1.5, 1.0, 0.0);
133 Point d(1.5, 2.0, 0.0);
134 LineSegment line_segment_cd(c, d);
135 EXPECT_FALSE(bnd_edge.intersect(line_segment_cd));
136
137 // Check distance vector direction
138 Point pt(0.5, 0.0, 0.0); // Point below edge
139 Point dist = bnd_edge.distanceFrom(pt);
140 // Should be mostly pointing along normal
141 double dot = dist(0) * n(0) + dist(1) * n(1);
142 EXPECT_GT(dot, 0.0); // Same direction
143}

◆ TEST() [6/9]

TEST ( SBMBndElementTest  ,
ProjectedBoundingBoxDiagonal   
)

Definition at line 214 of file SBMBndElementTest.C.

215{
216 // Tri3 spanning [0,1] x [0,1] in the z=0 plane. Bounding-box diagonal is
217 // (1,1,0); projected onto a plane orthogonal to z (i.e. removing the
218 // z-component, which is already zero) the tangential diagonal has norm
219 // sqrt(2). Projecting onto a plane orthogonal to the diagonal direction
220 // itself zeroes out the projection.
221 std::unique_ptr<Tri3> tri(new Tri3());
222 std::unique_ptr<Node> n0(new Node(Point(0.0, 0.0, 0.0), 0));
223 std::unique_ptr<Node> n1(new Node(Point(1.0, 0.0, 0.0), 1));
224 std::unique_ptr<Node> n2(new Node(Point(0.0, 1.0, 0.0), 2));
225 tri->set_node(0) = n0.get();
226 tri->set_node(1) = n1.get();
227 tri->set_node(2) = n2.get();
228
229 SBMBndTri3 bnd_tri(tri.get());
230
231 EXPECT_NEAR(bnd_tri.getProjectedBoundingBoxDiagonal(Point(0.0, 0.0, 1.0) /*normal_dir*/),
232 std::sqrt(2.0),
233 1e-12);
234
235 const double inv_sqrt2 = 1.0 / std::sqrt(2.0);
236 EXPECT_NEAR(
237 bnd_tri.getProjectedBoundingBoxDiagonal(Point(inv_sqrt2, inv_sqrt2, 0.0) /*normal_dir*/),
238 0.0,
239 1e-12);
240}

◆ TEST() [7/9]

TEST ( SBMBndElementTest  ,
Tri3Normal   
)

Definition at line 69 of file SBMBndElementTest.C.

70{
71 std::unique_ptr<Tri3> tri(new Tri3());
72
73 std::unique_ptr<Node> n0(new Node(Point(0.0, 0.0, 0.0), 0));
74 std::unique_ptr<Node> n1(new Node(Point(1.0, 0.0, 0.0), 1));
75 std::unique_ptr<Node> n2(new Node(Point(0.0, 1.0, 0.0), 2));
76
77 tri->set_node(0) = n0.get();
78 tri->set_node(1) = n1.get();
79 tri->set_node(2) = n2.get();
80
81 SBMBndTri3 bnd_tri(tri.get());
82 Point n = bnd_tri.normal();
83
84 EXPECT_NEAR(n(0), 0.0, 1e-12);
85 EXPECT_NEAR(n(1), 0.0, 1e-12);
86 EXPECT_NEAR(std::abs(n(2)), 1.0, 1e-12);
87
88 // Line from below passing through triangle center
89 Point a(0.3, 0.3, -1.0);
90 Point b(0.3, 0.3, 1.0);
91 LineSegment line_segment_ab(a, b);
92 EXPECT_TRUE(bnd_tri.intersect(line_segment_ab));
93
94 // Line away from triangle
95 Point c(2.0, 2.0, -1.0);
96 Point d(2.0, 2.0, 1.0);
97 LineSegment line_segment_cd(c, d);
98 EXPECT_FALSE(bnd_tri.intersect(line_segment_cd));
99
100 // Check distance vector roughly in +Z
101 Point pt(0.3, 0.3, 1.0);
102 Point dist = bnd_tri.distanceFrom(pt);
103 EXPECT_NEAR(dist(2), -1.0, 1e-12);
104}

◆ TEST() [8/9]

TEST ( SBMBndElementTest  ,
Tri3NormalTilted   
)

Definition at line 167 of file SBMBndElementTest.C.

168{
169 std::unique_ptr<Tri3> tri(new Tri3());
170
171 std::unique_ptr<Node> n0(new Node(Point(0.0, 0.0, 0.0), 0));
172 std::unique_ptr<Node> n1(new Node(Point(1.0, 0.0, 1.0), 1));
173 std::unique_ptr<Node> n2(new Node(Point(0.0, 1.0, 1.0), 2));
174
175 tri->set_node(0) = n0.get();
176 tri->set_node(1) = n1.get();
177 tri->set_node(2) = n2.get();
178
179 SBMBndTri3 bnd_tri(tri.get());
180 Point n = bnd_tri.normal();
181
182 // Expected normal
183 const double inv_sqrt3 = 1.0 / std::sqrt(3.0);
184 EXPECT_NEAR(n(0), -inv_sqrt3, 1e-12);
185 EXPECT_NEAR(n(1), -inv_sqrt3, 1e-12);
186 EXPECT_NEAR(n(2), inv_sqrt3, 1e-12);
187
188 // Line from below passing through triangle center
189 Point a(0.3, 0.3, -1.0);
190 Point b(0.3, 0.3, 2.0);
191 LineSegment line_segment_ab(a, b);
192 EXPECT_TRUE(bnd_tri.intersect(line_segment_ab));
193
194 // Line away from triangle
195 Point c(2.0, 2.0, -1.0);
196 Point d(2.0, 2.0, 2.0);
197 LineSegment line_segment_cd(c, d);
198 EXPECT_FALSE(bnd_tri.intersect(line_segment_cd));
199
200 // Check distance vector
201 Point pt(2.0, 0.0, 2.0);
202 Point dist = bnd_tri.distanceFrom(pt);
203 EXPECT_NEAR(dist(0), -1.0, 1e-12);
204 EXPECT_NEAR(dist(1), 0.0, 1e-12);
205 EXPECT_NEAR(dist(2), -1.0, 1e-12);
206
207 Point pt2(0.0, 0.0, 0.0);
208 Point dist2 = bnd_tri.distanceFrom(pt2);
209 EXPECT_NEAR(dist2(0), 0.0, 1e-12);
210 EXPECT_NEAR(dist2(1), 0.0, 1e-12);
211 EXPECT_NEAR(dist2(2), 0.0, 1e-12);
212}

◆ TEST() [9/9]

TEST ( SBMBndElementTest  ,
UnsupportedGeometryDispatchersThrow   
)

Definition at line 314 of file SBMBndElementTest.C.

315{
316 // Drive a SBMBndElementBase subclass that is neither LineSegment nor
317 // Triangle through the base-class dispatchers; both intersect() and
318 // computeBoundingBall() must mooseError on the unsupported geometry type.
319 std::unique_ptr<Edge2> edge(new Edge2());
320 std::unique_ptr<Node> n0(new Node(Point(0.0, 0.0, 0.0), 0));
321 std::unique_ptr<Node> n1(new Node(Point(1.0, 0.0, 0.0), 1));
322 edge->set_node(0) = n0.get();
323 edge->set_node(1) = n1.get();
324
325 // Placeholder unit normal; the dispatchers under test never consult it.
326 SBMBndUnsupportedForTest bnd(edge.get(), Point(0.0, 0.0, 1.0));
327 const SBMBndElementBase & base = bnd;
328
329 LineSegment line(Point(0.5, -1.0, 0.0), Point(0.5, 1.0, 0.0));
330 EXPECT_THROW(
331 {
332 try
333 {
334 base.intersect(line);
335 }
336 catch (const std::exception & e)
337 {
338 EXPECT_NE(std::string(e.what()).find("unsupported geometry type"), std::string::npos);
339 throw;
340 }
341 },
342 std::exception);
343
344 EXPECT_THROW(
345 {
346 try
347 {
348 base.computeBoundingBall();
349 }
350 catch (const std::exception & e)
351 {
352 EXPECT_NE(std::string(e.what()).find("unsupported geometry type"), std::string::npos);
353 throw;
354 }
355 },
356 std::exception);
357}