https://mooseframework.inl.gov
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  ,
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 }
Derived class for 2-node edge elements LineSegment is listed first so it is initialized before SBMBnd...
Definition: SBMBndEdge2.h:19

◆ TEST() [2/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 }
Derived class for 3-node triangular elements (Tri3) Triangle is listed first so it is initialized bef...
Definition: SBMBndTri3.h:19

◆ TEST() [3/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 }
Derived class for 2-node edge elements LineSegment is listed first so it is initialized before SBMBnd...
Definition: SBMBndEdge2.h:19

◆ TEST() [4/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 }
Derived class for 2-node edge elements LineSegment is listed first so it is initialized before SBMBnd...
Definition: SBMBndEdge2.h:19

◆ TEST() [5/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 }
Derived class for 3-node triangular elements (Tri3) Triangle is listed first so it is initialized bef...
Definition: SBMBndTri3.h:19

◆ 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 }
Derived class for 3-node triangular elements (Tri3) Triangle is listed first so it is initialized bef...
Definition: SBMBndTri3.h:19

◆ TEST() [7/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 }
Base class for SBM boundary elements.
Derived class for 3-node triangular elements (Tri3) Triangle is listed first so it is initialized bef...
Definition: SBMBndTri3.h:19
Ball computeBoundingBall() const override
Derived class for 2-node edge elements LineSegment is listed first so it is initialized before SBMBnd...
Definition: SBMBndEdge2.h:19

◆ TEST() [8/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 }
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)

◆ 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 }
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Base class for SBM boundary elements.