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