libMesh
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 
11 using namespace libMesh;
12 
13 
14 
15 class PointLocatorTest : public CppUnit::TestCase {
16 public:
17  LIBMESH_CPPUNIT_TEST_SUITE( PointLocatorTest );
18 
19  CPPUNIT_TEST( testLocatorOnEdge3 );
20 #if LIBMESH_DIM > 1
21  CPPUNIT_TEST( testLocatorOnQuad9 );
22  CPPUNIT_TEST( testLocatorOnTri6 );
23 #endif
24 #if LIBMESH_DIM > 2
25  CPPUNIT_TEST( testLocatorOnHex27 );
26  CPPUNIT_TEST( testPlanar );
27 #endif
28 
29  CPPUNIT_TEST_SUITE_END();
30 
31 private:
32 
33 public:
34  void setUp()
35  {}
36 
37  void tearDown()
38  {}
39 
40  void testLocator(const ElemType elem_type)
41  {
43 
44  const unsigned int n_elem_per_side = 5;
45  const unsigned int dim = Elem::type_to_dim_map[elem_type];
46  const unsigned int ymax = dim > 1;
47  const unsigned int zmax = dim > 2;
48  const unsigned int ny = ymax * n_elem_per_side;
49  const unsigned int nz = zmax * n_elem_per_side;
50 
52  n_elem_per_side,
53  ny,
54  nz,
55  0., 1.,
56  0., ymax,
57  0., zmax,
58  elem_type);
59 
60  std::unique_ptr<PointLocatorBase> locator = mesh.sub_point_locator();
61 
62  if (!mesh.is_serial())
63  locator->enable_out_of_mesh_mode();
64 
65  for (unsigned int i=0; i != n_elem_per_side+1; ++i)
66  {
67  for (unsigned int j=0; j != ny+1; ++j)
68  {
69  for (unsigned int k=0; k != nz+1; ++k)
70  {
71  const libMesh::Real h = libMesh::Real(1)/n_elem_per_side;
72  Point p(i*h, j*h, k*h);
73 
74  const Elem *elem = locator->operator()(p);
75 
76  bool found_elem = elem;
77  if (!mesh.is_serial())
78  mesh.comm().max(found_elem);
79 
80  CPPUNIT_ASSERT(found_elem);
81  if (elem)
82  {
83  CPPUNIT_ASSERT(elem->contains_point(p));
84  }
85 
86  const Node *node = locator->locate_node(p);
87 
88  bool found_node = node;
89  if (!mesh.is_serial())
90  mesh.comm().max(found_node);
91 
92  CPPUNIT_ASSERT(found_node);
93 
94  if (node)
95  {
96  LIBMESH_ASSERT_FP_EQUAL(i*h, (*node)(0),
98  if (LIBMESH_DIM > 1)
99  LIBMESH_ASSERT_FP_EQUAL(j*h, (*node)(1),
101  if (LIBMESH_DIM > 2)
102  LIBMESH_ASSERT_FP_EQUAL(k*h, (*node)(2),
104  }
105  }
106  }
107  }
108  }
109 
110  void testPlanar()
111  {
112  LOG_UNIT_TEST;
113 
114  // Here we test locating points in a Mesh which lies slightly above the z-axis
116 
118  /*nx=*/10, /*ny=*/10,
119  /*xmin=*/0., /*xmax=*/1.,
120  /*ymin=*/0., /*ymax=*/1.,
121  TRI3);
122 
123  // Move all nodes a small amount in the +z-direction
124  for (auto & node : mesh.node_ptr_range())
125  (*node)(2) += 3.1e-15;
126 
127  // Construct a PointLocator object
128  std::unique_ptr<PointLocatorBase> locator = mesh.sub_point_locator();
129 
130  // Turn on out-of-mesh-mode to handle parallel testing
131  if (!mesh.is_serial())
132  locator->enable_out_of_mesh_mode();
133 
134  // Test locating a Point which is in the z=0 plane, i.e. slightly
135  // below the plane of the Mesh, but which should otherwise be
136  // found within the Mesh.
137  Point p(0.53, 0.7, 0.0);
138  const Elem *elem = (*locator)(p);
139 
140  bool found_elem = elem;
141  if (!mesh.is_serial())
142  mesh.comm().max(found_elem);
143 
144  CPPUNIT_ASSERT(found_elem);
145 
146  // Note: Tri3::contains_point() returns true for points which are
147  // out-of-plane by less than TOLERANCE by default.
148  if (elem)
149  CPPUNIT_ASSERT(elem->contains_point(p));
150  }
151 
152  void testLocatorOnEdge3() { LOG_UNIT_TEST; testLocator(EDGE3); }
153  void testLocatorOnQuad9() { LOG_UNIT_TEST; testLocator(QUAD9); }
154  void testLocatorOnTri6() { LOG_UNIT_TEST; testLocator(TRI6); }
155  void testLocatorOnHex27() { LOG_UNIT_TEST; testLocator(HEX27); }
156 
157 };
158 
void testLocator(const ElemType elem_type)
ElemType
Defines an enum for geometric element types.
CPPUNIT_TEST_SUITE_REGISTRATION(PointLocatorTest)
A Node is like a Point, but with more information.
Definition: node.h:52
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:1638
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
static constexpr Real TOLERANCE
unsigned int dim
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:635
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
const Parallel::Communicator & comm() const
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.
The libMesh namespace provides an interface to certain functionality in the library.
virtual bool is_serial() const
Definition: mesh_base.h:211
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
Definition: elem.C:2751
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void max(const T &r, T &o, Request &req) const
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
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.