libMesh
Loading...
Searching...
No Matches
point_locator_test.C
Go to the documentation of this file.
1#include <libmesh/mesh.h>
2#include <libmesh/mesh_generation.h>
3#include <libmesh/elem.h>
4#include <libmesh/node.h>
5#include <libmesh/parallel.h>
6
7#include "test_comm.h"
8#include "libmesh_cppunit.h"
9
10#include <regex>
11
12using namespace libMesh;
13
14
15
16class PointLocatorTest : public CppUnit::TestCase {
17public:
19
21#if LIBMESH_DIM > 1
24#endif
25#if LIBMESH_DIM > 2
28#endif
29
31
32private:
33
34public:
35 void setUp()
36 {}
37
38 void tearDown()
39 {}
40
41 void testLocator(const ElemType elem_type)
42 {
44
45 const unsigned int n_elem_per_side = 5;
46 const unsigned int dim = Elem::type_to_dim_map[elem_type];
47 const unsigned int ymax = dim > 1;
48 const unsigned int zmax = dim > 2;
49 const unsigned int ny = ymax * n_elem_per_side;
50 const unsigned int nz = zmax * n_elem_per_side;
51
53 n_elem_per_side,
54 ny,
55 nz,
56 0., 1.,
57 0., ymax,
58 0., zmax,
59 elem_type);
60
61 std::unique_ptr<PointLocatorBase> locator = mesh.sub_point_locator();
62
63 // Make sure we throw in default (not out-of-mesh) mode when
64 // debugging and querying a point out of the mesh
65 const Point p{2,0,0};
66#if defined(LIBMESH_ENABLE_EXCEPTIONS) && !defined(NDEBUG)
67 auto test_exception = [&locator, p]()
68 {
69 bool threw_desired_exception = false;
70 try {
71 locator->operator()(p);
72 }
73 catch (libMesh::LogicError & e) {
74 std::regex msg_regex("out_of_mesh_mode");
75 CPPUNIT_ASSERT(std::regex_search(e.what(), msg_regex));
76 threw_desired_exception = true;
77 }
78 catch (...) {
79 CPPUNIT_ASSERT_MESSAGE("Unexpected exception type thrown", false);
80 }
81 CPPUNIT_ASSERT(threw_desired_exception);
82 };
83 test_exception();
84#endif
85
86 if (!mesh.is_serial())
87 locator->enable_out_of_mesh_mode();
88
89 for (unsigned int i=0; i != n_elem_per_side+1; ++i)
90 {
91 for (unsigned int j=0; j != ny+1; ++j)
92 {
93 for (unsigned int k=0; k != nz+1; ++k)
94 {
95 const libMesh::Real h = libMesh::Real(1)/n_elem_per_side;
96 Point p(i*h, j*h, k*h);
97
98 const Elem *elem = locator->operator()(p);
99
100 bool found_elem = elem;
101 if (!mesh.is_serial())
102 mesh.comm().max(found_elem);
103
104 CPPUNIT_ASSERT(found_elem);
105 if (elem)
106 {
107 CPPUNIT_ASSERT(elem->contains_point(p));
108 }
109
110 const Node *node = locator->locate_node(p);
111
112 bool found_node = node;
113 if (!mesh.is_serial())
114 mesh.comm().max(found_node);
115
116 CPPUNIT_ASSERT(found_node);
117
118 if (node)
119 {
120 LIBMESH_ASSERT_FP_EQUAL(i*h, (*node)(0),
122 if (LIBMESH_DIM > 1)
123 LIBMESH_ASSERT_FP_EQUAL(j*h, (*node)(1),
125 if (LIBMESH_DIM > 2)
126 LIBMESH_ASSERT_FP_EQUAL(k*h, (*node)(2),
128 }
129 }
130 }
131 }
132
133 // Make sure we do not throw in out-of-mesh mode when looking for
134 // a point out of the mesh
135 locator->enable_out_of_mesh_mode();
136 const Elem *elem = locator->operator()(p);
137 CPPUNIT_ASSERT(!elem);
138
139 // Make sure we throw again after disabling out-of-mesh mode again.
140 locator->disable_out_of_mesh_mode();
141#if defined(LIBMESH_ENABLE_EXCEPTIONS) && !defined(NDEBUG)
142 test_exception();
143#endif // LIBMESH_ENABLE_EXCEPTIONS
144
145 locator->clear();
146 CPPUNIT_ASSERT(!locator->initialized());
147
148 locator->init();
149 CPPUNIT_ASSERT(locator->initialized());
150
151 locator->set_close_to_point_tol(1e-1);
152 Point p2{1.001,0,0};
153 const Elem *elem2 = locator->operator()(p2);
154 bool found_elem = elem2;
155 if (!mesh.is_serial())
156 mesh.comm().max(found_elem);
157
158 CPPUNIT_ASSERT(found_elem);
159 }
160
162 {
163 LOG_UNIT_TEST;
164
165 // Here we test locating points in a Mesh which lies slightly above the z-axis
167
169 /*nx=*/10, /*ny=*/10,
170 /*xmin=*/0., /*xmax=*/1.,
171 /*ymin=*/0., /*ymax=*/1.,
172 TRI3);
173
174 // Move all nodes a small amount in the +z-direction
175 for (auto & node : mesh.node_ptr_range())
176 (*node)(2) += 3.1e-15;
177
178 // Construct a PointLocator object
179 std::unique_ptr<PointLocatorBase> locator = mesh.sub_point_locator();
180
181 // Turn on out-of-mesh-mode to handle parallel testing
182 if (!mesh.is_serial())
183 locator->enable_out_of_mesh_mode();
184
185 // Test locating a Point which is in the z=0 plane, i.e. slightly
186 // below the plane of the Mesh, but which should otherwise be
187 // found within the Mesh.
188 Point p(0.53, 0.7, 0.0);
189 const Elem *elem = (*locator)(p);
190
191 bool found_elem = elem;
192 if (!mesh.is_serial())
193 mesh.comm().max(found_elem);
194
195 CPPUNIT_ASSERT(found_elem);
196
197 // Note: Tri3::contains_point() returns true for points which are
198 // out-of-plane by less than TOLERANCE by default.
199 if (elem)
200 CPPUNIT_ASSERT(elem->contains_point(p));
201 }
202
203 void testLocatorOnEdge3() { LOG_UNIT_TEST; testLocator(EDGE3); }
204 void testLocatorOnQuad9() { LOG_UNIT_TEST; testLocator(QUAD9); }
205 void testLocatorOnTri6() { LOG_UNIT_TEST; testLocator(TRI6); }
206 void testLocatorOnHex27() { LOG_UNIT_TEST; testLocator(HEX27); }
207
208};
209
unsigned int dim
LIBMESH_CPPUNIT_TEST_SUITE(PointLocatorTest)
CPPUNIT_TEST(testLocatorOnEdge3)
CPPUNIT_TEST(testLocatorOnQuad9)
void testLocator(const ElemType elem_type)
CPPUNIT_TEST(testLocatorOnTri6)
CPPUNIT_TEST(testLocatorOnHex27)
CPPUNIT_TEST(testPlanar)
void max(const T &r, T &o, Request &req) const
This is the base class from which all geometric element types are derived.
Definition elem.h:96
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
Definition elem.C:2784
static const unsigned int type_to_dim_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the geometric dimension of the ele...
Definition elem.h:628
A class to represent the internal "this should never happen" errors, to be thrown by "libmesh_error()...
virtual bool is_serial() const
Definition mesh_base.h:357
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition mesh_base.C:1833
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition mesh.h:51
A Node is like a Point, but with more information.
Definition node.h:55
const Parallel::Communicator & comm() const
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
Communicator * TestCommWorld
MeshBase & mesh
void build_square(UnstructuredMesh &mesh, const unsigned int nx, const unsigned int ny, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 2D meshes.
void build_cube(UnstructuredMesh &mesh, const unsigned int nx=0, const unsigned int ny=0, const unsigned int nz=0, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const Real zmin=0., const Real zmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
Builds a (elements) cube.
The libMesh namespace provides an interface to certain functionality in the library.
ElemType
Defines an enum for geometric element types.
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
CPPUNIT_TEST_SUITE_REGISTRATION(PointLocatorTest)