libMesh
contains_point.C
Go to the documentation of this file.
1 #include <libmesh/libmesh.h>
2 #include <libmesh/elem.h>
3 
4 #include "test_comm.h"
5 #include "libmesh_cppunit.h"
6 
7 
8 using namespace libMesh;
9 
10 class ContainsPointTest : public CppUnit::TestCase
11 {
17 public:
18  LIBMESH_CPPUNIT_TEST_SUITE( ContainsPointTest );
19 
20 #if LIBMESH_DIM > 2
21  CPPUNIT_TEST( testContainsPointNodeElem );
22  CPPUNIT_TEST( testContainsPointTri3 );
23  CPPUNIT_TEST( testContainsPointTet4 );
24 #endif
25 
26  CPPUNIT_TEST_SUITE_END();
27 
28 public:
29  void setUp() {}
30 
31  void tearDown() {}
32 
33  // NodeElem test
35  {
36  Node node (1., 1., 1., /*id=*/0);
37  std::unique_ptr<Elem> elem = Elem::build(NODEELEM);
38  elem->set_node(0, &node);
39 
40  Real epsilon = 1.e-4;
41  CPPUNIT_ASSERT(elem->contains_point(Point(1.+epsilon/2, 1.-epsilon/2, 1+epsilon/2), /*tol=*/epsilon));
42  CPPUNIT_ASSERT(!elem->contains_point(Point(1.+epsilon/2, 1.-epsilon/2, 1+epsilon/2), /*tol=*/epsilon/2));
43  }
44 
45  // TRI3 test
47  {
48  LOG_UNIT_TEST;
49 
50  Point a(3,1,2), b(1,2,3), c(2,3,1);
51  containsPointTri3Helper(a, b, c, a);
52 
53  // Ben's 1st "small triangle" test case.
54  containsPointTri3Helper(a/5000, b/5000, c/5000, c/5000);
55 
56  // Ben's 2nd "small triangle" test case.
57  containsPointTri3Helper(Point(0.000808805, 0.0047284, 0.),
58  Point(0.0011453, 0.00472831, 0.),
59  Point(0.000982249, 0.00508037, 0.),
60  Point(0.001, 0.005, 0.));
61  }
62 
63 
64 
65  // TET4 test
67  {
68  LOG_UNIT_TEST;
69 
70  // Construct unit Tet.
71  {
72  Node zero (0., 0., 0., 0);
73  Node one (1., 0., 0., 1);
74  Node two (0., 1., 0., 2);
75  Node three (0., 0., 1., 3);
76 
77  std::unique_ptr<Elem> elem = Elem::build(TET4);
78  elem->set_node(0, &zero);
79  elem->set_node(1, &one);
80  elem->set_node(2, &two);
81  elem->set_node(3, &three);
82 
83  // The centroid (equal to vertex average for Tet4) must be inside the element.
84  CPPUNIT_ASSERT (elem->contains_point(elem->vertex_average()));
85 
86  // The vertices must be contained in the element.
87  CPPUNIT_ASSERT (elem->contains_point(zero));
88  CPPUNIT_ASSERT (elem->contains_point(one));
89  CPPUNIT_ASSERT (elem->contains_point(two));
90  CPPUNIT_ASSERT (elem->contains_point(three));
91 
92  // Make sure that outside points are not contained.
93  CPPUNIT_ASSERT (!elem->contains_point(Point(.34, .34, .34)));
94  CPPUNIT_ASSERT (!elem->contains_point(Point(.33, .33, -.1)));
95  CPPUNIT_ASSERT (!elem->contains_point(Point(0., -.1, .5)));
96  }
97 
98 
99  // Construct a nearly degenerate (sliver) tet. A unit tet with
100  // nodes "one" and "two" moved to within a distance of epsilon
101  // from the origin.
102  {
103  Real epsilon = 1.e-4;
104 
105  Node zero (0., 0., 0., 0);
106  Node one (epsilon, 0., 0., 1);
107  Node two (0., epsilon, 0., 2);
108  Node three (0., 0., 1., 3);
109 
110  std::unique_ptr<Elem> elem = Elem::build(TET4);
111  elem->set_node(0, &zero);
112  elem->set_node(1, &one);
113  elem->set_node(2, &two);
114  elem->set_node(3, &three);
115 
116  // The centroid (equal to vertex average for Tet4) must be inside the element.
117  CPPUNIT_ASSERT (elem->contains_point(elem->vertex_average()));
118 
119  // The vertices must be contained in the element.
120  CPPUNIT_ASSERT (elem->contains_point(zero));
121  CPPUNIT_ASSERT (elem->contains_point(one));
122  CPPUNIT_ASSERT (elem->contains_point(two));
123  CPPUNIT_ASSERT (elem->contains_point(three));
124 
125  // Verify that a point which is on a mid-edge is contained in the element.
126  CPPUNIT_ASSERT (elem->contains_point(Point(epsilon/2, 0, 0.5)));
127 
128  // Make sure that "just barely" outside points are outside.
129  CPPUNIT_ASSERT (!elem->contains_point(Point(epsilon, epsilon, epsilon/2)));
130  CPPUNIT_ASSERT (!elem->contains_point(Point(epsilon/10, epsilon/10, 1.0)));
131  CPPUNIT_ASSERT (!elem->contains_point(Point(epsilon/2, -epsilon/10, 0.5)));
132  }
133  }
134 
135 protected:
136  // The first 3 arguments are the points of the triangle, the last argument is a
137  // custom point that should be inside the Tri.
138  void containsPointTri3Helper(Point a_in, Point b_in, Point c_in, Point p)
139  {
140  // vertices
141  Node a(a_in, 0);
142  Node b(b_in, 1);
143  Node c(c_in, 2);
144 
145  // Build the test Elem
146  std::unique_ptr<Elem> elem = Elem::build(TRI3);
147 
148  elem->set_node(0, &a);
149  elem->set_node(1, &b);
150  elem->set_node(2, &c);
151 
152  // helper vectors to span the tri and point out of plane
153  Point va(a-c);
154  Point vb(b-c);
155  Point oop(va.cross(vb));
156  Point oop_unit = oop.unit();
157 
158  // The centroid (equal to vertex average for Tri3) must be inside the element.
159  CPPUNIT_ASSERT (elem->contains_point(elem->vertex_average()));
160 
161  // triangle should contain all its vertices
162  CPPUNIT_ASSERT (elem->contains_point(a));
163  CPPUNIT_ASSERT (elem->contains_point(b));
164  CPPUNIT_ASSERT (elem->contains_point(c));
165 
166  // out of plane from the centroid, should *not* be in the element
167  CPPUNIT_ASSERT (!elem->contains_point(elem->vertex_average() + std::sqrt(TOLERANCE) * oop_unit));
168 
169  // These points should be outside the triangle
170  CPPUNIT_ASSERT (!elem->contains_point(a + va * TOLERANCE * 10));
171  CPPUNIT_ASSERT (!elem->contains_point(b + vb * TOLERANCE * 10));
172  CPPUNIT_ASSERT (!elem->contains_point(c - (va + vb) * TOLERANCE * 10));
173 
174  // Test the custom point
175  CPPUNIT_ASSERT (elem->contains_point(p));
176  }
177 };
178 
179 
void containsPointTri3Helper(Point a_in, Point b_in, Point c_in, Point p)
CPPUNIT_TEST_SUITE_REGISTRATION(ContainsPointTest)
A Node is like a Point, but with more information.
Definition: node.h:52
static constexpr Real TOLERANCE
The libMesh namespace provides an interface to certain functionality in the library.
const Number zero
.
Definition: libmesh.h:304
TypeVector< T > unit() const
Definition: type_vector.h:1104
void testContainsPointTet4()
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition: elem.C:444
TypeVector< typename CompareTypes< T, T2 >::supertype > cross(const TypeVector< T2 > &v) const
Definition: type_vector.h:884
void testContainsPointTri3()
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
void testContainsPointNodeElem()