libMesh
boundary_points.C
Go to the documentation of this file.
1 #include <libmesh/replicated_mesh.h>
2 #include <libmesh/point.h>
3 #include <libmesh/elem.h>
4 #include <libmesh/face_quad4.h>
5 
6 #include "test_comm.h"
7 
8 #include "libmesh_cppunit.h"
9 
10 using namespace libMesh;
11 
12 class GetBoundaryPointsTest : public CppUnit::TestCase {
17 public:
18  CPPUNIT_TEST_SUITE( GetBoundaryPointsTest );
19 
20 #if LIBMESH_DIM > 1
21  CPPUNIT_TEST( testMesh );
22 #endif
23 
24  CPPUNIT_TEST_SUITE_END();
25 
26 protected:
27 
29 
30  void build_mesh()
31  {
32  _mesh = new ReplicatedMesh(*TestCommWorld, 2);
33 
34  // (0,1) (1,1) (2,1) (3,1) (4,1) (5,1) (6,1)
35  // x---------------x---------------x x-----------x-----------x-----------x
36  // | | | | | | |
37  // | | | | | | |
38  // | | | x-----------x-----------x-----------x
39  // | | | |(3,0.5) | void | |(6,0.5)
40  // | | | | | | |
41  // x---------------x---------------x x-----------x-----------x-----------x
42  // (0,0) (1,0) (2,0) | (3,0) | | |(6,0)
43  // | | | | | | |
44  // | | | | | | |
45  // | | | | | | |
46  // | | | | | | |
47  // x---------------x---------------x x-----------x-----------x-----------x
48  // (0,-1) (1,-1) (2,-1) (3,-1) (6,-1)
49 
50  _mesh->add_point( Point(0.0, 0.0), 0 );
51  _mesh->add_point( Point(1.0, 0.0), 1 );
52  _mesh->add_point( Point(1.0, 1.0), 2 );
53  _mesh->add_point( Point(0.0, 1.0), 3 );
54  _mesh->add_point( Point(0.0,-1.0), 4 );
55  _mesh->add_point( Point(1.0,-1.0), 5 );
56  _mesh->add_point( Point(2.0, 0.0), 6 );
57  _mesh->add_point( Point(2.0, 1.0), 7 );
58  _mesh->add_point( Point(2.0,-1.0), 8 );
59 
60  _mesh->add_point( Point(3.0,-1.0), 9 );
61  _mesh->add_point( Point(3.0, 0.0), 10 );
62  _mesh->add_point( Point(3.0, 0.5), 11 );
63  _mesh->add_point( Point(3.0, 1.0), 12 );
64  _mesh->add_point( Point(4.0,-1.0), 13 );
65  _mesh->add_point( Point(4.0, 0.0), 14 );
66  _mesh->add_point( Point(4.0, 0.5), 15 );
67  _mesh->add_point( Point(4.0, 1.0), 16 );
68  _mesh->add_point( Point(5.0,-1.0), 17 );
69  _mesh->add_point( Point(5.0, 0.0), 18 );
70  _mesh->add_point( Point(5.0, 0.5), 19 );
71  _mesh->add_point( Point(5.0, 1.0), 20 );
72  _mesh->add_point( Point(6.0,-1.0), 21 );
73  _mesh->add_point( Point(6.0, 0.0), 22 );
74  _mesh->add_point( Point(6.0, 0.5), 23 );
75  _mesh->add_point( Point(6.0, 1.0), 24 );
76 
77  {
78  Elem* elem = new Quad4;
79  elem->set_node(0) = _mesh->node_ptr(0);
80  elem->set_node(1) = _mesh->node_ptr(1);
81  elem->set_node(2) = _mesh->node_ptr(2);
82  elem->set_node(3) = _mesh->node_ptr(3);
83  elem->set_id() = 0;
84  _mesh->add_elem(elem);
85  }
86  {
87  Elem* elem = new Quad4;
88  elem->set_node(0) = _mesh->node_ptr(4);
89  elem->set_node(1) = _mesh->node_ptr(5);
90  elem->set_node(2) = _mesh->node_ptr(1);
91  elem->set_node(3) = _mesh->node_ptr(0);
92  elem->set_id() = 1;
93  _mesh->add_elem(elem);
94  }
95  {
96  Elem* elem = new Quad4;
97  elem->set_node(0) = _mesh->node_ptr(7);
98  elem->set_node(1) = _mesh->node_ptr(2);
99  elem->set_node(2) = _mesh->node_ptr(1);
100  elem->set_node(3) = _mesh->node_ptr(6);
101  elem->set_id() = 2;
102  _mesh->add_elem(elem);
103  }
104  {
105  Elem* elem = new Quad4;
106  elem->set_node(0) = _mesh->node_ptr(5);
107  elem->set_node(1) = _mesh->node_ptr(8);
108  elem->set_node(2) = _mesh->node_ptr(6);
109  elem->set_node(3) = _mesh->node_ptr(1);
110  elem->set_id() = 3;
111  _mesh->add_elem(elem);
112  }
113  {
114  Elem* elem = new Quad4;
115  elem->set_node(0) = _mesh->node_ptr(9);
116  elem->set_node(1) = _mesh->node_ptr(13);
117  elem->set_node(2) = _mesh->node_ptr(14);
118  elem->set_node(3) = _mesh->node_ptr(10);
119  elem->set_id() = 4;
120  _mesh->add_elem(elem);
121  }
122  {
123  Elem* elem = new Quad4;
124  elem->set_node(0) = _mesh->node_ptr(10);
125  elem->set_node(1) = _mesh->node_ptr(14);
126  elem->set_node(2) = _mesh->node_ptr(15);
127  elem->set_node(3) = _mesh->node_ptr(11);
128  elem->set_id() = 5;
129  _mesh->add_elem(elem);
130  }
131  {
132  Elem* elem = new Quad4;
133  elem->set_node(0) = _mesh->node_ptr(11);
134  elem->set_node(1) = _mesh->node_ptr(15);
135  elem->set_node(2) = _mesh->node_ptr(16);
136  elem->set_node(3) = _mesh->node_ptr(12);
137  elem->set_id() = 6;
138  _mesh->add_elem(elem);
139  }
140  {
141  Elem* elem = new Quad4;
142  elem->set_node(0) = _mesh->node_ptr(13);
143  elem->set_node(1) = _mesh->node_ptr(17);
144  elem->set_node(2) = _mesh->node_ptr(18);
145  elem->set_node(3) = _mesh->node_ptr(14);
146  elem->set_id() = 7;
147  _mesh->add_elem(elem);
148  }
149  // skip one element here
150  {
151  Elem* elem = new Quad4;
152  elem->set_node(0) = _mesh->node_ptr(15);
153  elem->set_node(1) = _mesh->node_ptr(19);
154  elem->set_node(2) = _mesh->node_ptr(20);
155  elem->set_node(3) = _mesh->node_ptr(16);
156  elem->set_id() = 8;
157  _mesh->add_elem(elem);
158  }
159  {
160  Elem* elem = new Quad4;
161  elem->set_node(0) = _mesh->node_ptr(17);
162  elem->set_node(1) = _mesh->node_ptr(21);
163  elem->set_node(2) = _mesh->node_ptr(22);
164  elem->set_node(3) = _mesh->node_ptr(18);
165  elem->set_id() = 9;
166  _mesh->add_elem(elem);
167  }
168  {
169  Elem* elem = new Quad4;
170  elem->set_node(0) = _mesh->node_ptr(18);
171  elem->set_node(1) = _mesh->node_ptr(22);
172  elem->set_node(2) = _mesh->node_ptr(23);
173  elem->set_node(3) = _mesh->node_ptr(19);
174  elem->set_id() = 10;
175  _mesh->add_elem(elem);
176  }
177  {
178  Elem* elem = new Quad4;
179  elem->set_node(0) = _mesh->node_ptr(19);
180  elem->set_node(1) = _mesh->node_ptr(23);
181  elem->set_node(2) = _mesh->node_ptr(24);
182  elem->set_node(3) = _mesh->node_ptr(20);
183  elem->set_id() = 11;
184  _mesh->add_elem(elem);
185  }
186 
187  // libMesh shouldn't renumber, or our based-on-initial-id
188  // assertions later may fail.
189  _mesh->allow_renumbering(false);
190 
191  _mesh->prepare_for_use();
192  }
193 
194 public:
195  void setUp()
196  {
197 #if LIBMESH_DIM > 1
198  this->build_mesh();
199 #endif
200  }
201 
202  void tearDown()
203  {
204  delete _mesh;
205  }
206 
207  void testMesh()
208  {
209  const auto points = _mesh->get_boundary_points();
210 
211  // There'd better be two disconnected subdomains
212  CPPUNIT_ASSERT_EQUAL( (std::size_t)2, points.size() );
213 
214  // The first key should better be element 0
215  auto it = points.find(0);
216  CPPUNIT_ASSERT(it != points.end());
217 
218  // There'd better be one boundary in the first subdomain
219  CPPUNIT_ASSERT_EQUAL( (std::size_t)1, it->second.size() );
220 
221  // There'd better be eight points on the boundary of the first subdomain
222  CPPUNIT_ASSERT_EQUAL( (std::size_t)8, it->second[0].size() );
223 
224  // Boundary points should better start from (1,1)
225  CPPUNIT_ASSERT_EQUAL( Point(1,1), it->second[0][0] );
226 
227  // Boundary points should better end with (2,1)
228  CPPUNIT_ASSERT_EQUAL( Point(2,1), it->second[0][7] );
229 
230  // The second key should better be element 4
231  it = points.find(4);
232  CPPUNIT_ASSERT(it != points.end());
233 
234  // There'd better be two boundaries in the second subdomain due to the middle hole
235  CPPUNIT_ASSERT_EQUAL( (std::size_t)2, it->second.size() );
236 
237  // There'd better be 12 points on the first (outer) boundary of the second subdomain
238  CPPUNIT_ASSERT_EQUAL( (std::size_t)12, it->second[0].size() );
239 
240  // There'd better be 4 points on the first (inner) boundary of the second subdomain
241  CPPUNIT_ASSERT_EQUAL( (std::size_t)4, it->second[1].size() );
242 
243  // The first boundary points should better start from (3,-1)
244  CPPUNIT_ASSERT_EQUAL( Point(3,-1), it->second[0][0] );
245 
246  // The first boundary points should better end with (3,0)
247  CPPUNIT_ASSERT_EQUAL( Point(3,0), it->second[0][11] );
248 
249  // The second boundary points should better start from (4,0)
250  CPPUNIT_ASSERT_EQUAL( Point(4,0), it->second[1][0] );
251 
252  // The second boundary points should better end with (5,0)
253  CPPUNIT_ASSERT_EQUAL( Point(5,0), it->second[1][3] );
254  }
255 
256 };
257 
263 public:
264  CPPUNIT_TEST_SUITE( GetBoundaryPointsSecondTest );
265 
266 #if LIBMESH_DIM > 1
267  CPPUNIT_TEST( testMesh );
268 #endif
269 
270  CPPUNIT_TEST_SUITE_END();
271 
272  // Yes, this is necessary. Somewhere in those macros is a protected/private
273 public:
274 
275  void setUp()
276  {
277 #if LIBMESH_DIM > 1
278  this->build_mesh();
279  _mesh->all_second_order(true);
280 #endif
281  }
282 
283  void testMesh()
284  {
285  const auto points = _mesh->get_boundary_points();
286 
287  // There'd better be two disconnected subdomains
288  CPPUNIT_ASSERT_EQUAL( (std::size_t)2, points.size() );
289 
290  // The first key should better be element 0
291  auto it = points.find(0);
292  CPPUNIT_ASSERT(it != points.end());
293 
294  // There'd better be one boundary in the first subdomain
295  CPPUNIT_ASSERT_EQUAL( (std::size_t)1, it->second.size() );
296 
297  // There'd better be 16 points on the boundary of the first subdomain
298  CPPUNIT_ASSERT_EQUAL( (std::size_t)16, it->second[0].size() );
299 
300  // Boundary points should better start from (1,1)
301  CPPUNIT_ASSERT_EQUAL( Point(1,1), it->second[0][0] );
302 
303  // Boundary points should better include side middle points including (0.5,1)
304  CPPUNIT_ASSERT_EQUAL( Point(0.5,1), it->second[0][1] );
305 
306  // Boundary points should better end with (1.5,1)
307  CPPUNIT_ASSERT_EQUAL( Point(1.5,1), it->second[0][15] );
308 
309  // The second key should better be element 4
310  it = points.find(4);
311  CPPUNIT_ASSERT(it != points.end());
312 
313  // There'd better be two boundaries in the second subdomain due to the middle hole
314  CPPUNIT_ASSERT_EQUAL( (std::size_t)2, it->second.size() );
315 
316  // There'd better be 24 points on the first (outer) boundary of the second subdomain
317  CPPUNIT_ASSERT_EQUAL( (std::size_t)24, it->second[0].size() );
318 
319  // There'd better be 8 points on the first (inner) boundary of the second subdomain
320  CPPUNIT_ASSERT_EQUAL( (std::size_t)8, it->second[1].size() );
321 
322  // The first boundary points should better start from (3,-1)
323  CPPUNIT_ASSERT_EQUAL( Point(3,-1), it->second[0][0] );
324 
325  // The first boundary points should better include side middle points including (3.5,-1)
326  CPPUNIT_ASSERT_EQUAL( Point(3.5,-1), it->second[0][1] );
327 
328  // The first boundary points should better end with (3,-0.5)
329  CPPUNIT_ASSERT_EQUAL( Point(3,-0.5), it->second[0][23] );
330 
331  // The second boundary points should better start from (4,0)
332  CPPUNIT_ASSERT_EQUAL( Point(4,0), it->second[1][0] );
333 
334  // The second boundary points should better include side middle points including (4,0.25)
335  CPPUNIT_ASSERT_EQUAL( Point(4,0.25), it->second[1][1] );
336 
337  // The second boundary points should better end with (4.5,0)
338  CPPUNIT_ASSERT_EQUAL( Point(4.5,0), it->second[1][7] );
339  }
340 };
341 
GetBoundaryPointsSecondTest
Definition: boundary_points.C:258
libMesh::ReplicatedMesh::node_ptr
virtual const Node * node_ptr(const dof_id_type i) const override
Definition: replicated_mesh.C:182
GetBoundaryPointsTest
Definition: boundary_points.C:12
libMesh::DofObject::set_id
dof_id_type & set_id()
Definition: dof_object.h:776
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
GetBoundaryPointsSecondTest::testMesh
void testMesh()
Definition: boundary_points.C:283
libMesh::ReplicatedMesh::add_elem
virtual Elem * add_elem(Elem *e) override
Add elem e to the end of the element array.
Definition: replicated_mesh.C:282
CPPUNIT_TEST_SUITE_REGISTRATION
CPPUNIT_TEST_SUITE_REGISTRATION(GetBoundaryPointsTest)
GetBoundaryPointsTest::_mesh
ReplicatedMesh * _mesh
Definition: boundary_points.C:28
GetBoundaryPointsSecondTest::setUp
void setUp()
Definition: boundary_points.C:275
GetBoundaryPointsTest::setUp
void setUp()
Definition: boundary_points.C:195
libMesh::ReplicatedMesh
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
Definition: replicated_mesh.h:47
GetBoundaryPointsTest::testMesh
void testMesh()
Definition: boundary_points.C:207
TestCommWorld
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:111
GetBoundaryPointsTest::build_mesh
void build_mesh()
Definition: boundary_points.C:30
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
libMesh::Quad4
The QUAD4 is an element in 2D composed of 4 nodes.
Definition: face_quad4.h:51
libMesh::Elem::set_node
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2059
libmesh_cppunit.h
GetBoundaryPointsTest::tearDown
void tearDown()
Definition: boundary_points.C:202
libMesh::Elem
This is the base class from which all geometric element types are derived.
Definition: elem.h:100
libMesh::MeshBase::allow_renumbering
void allow_renumbering(bool allow)
If false is passed in then this mesh will no longer be renumbered when being prepared for use.
Definition: mesh_base.h:1025
test_comm.h
libMesh::MeshBase::prepare_for_use
void prepare_for_use(const bool skip_renumber_nodes_and_elements=false, const bool skip_find_neighbors=false)
Prepare a newly ecreated (or read) mesh for use.
Definition: mesh_base.C:318
libMesh::ReplicatedMesh::add_point
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id) override
functions for adding /deleting nodes elements.
Definition: replicated_mesh.C:417
libMesh::ReplicatedMesh::get_boundary_points
std::unordered_map< dof_id_type, std::vector< std::vector< Point > > > get_boundary_points() const
Return all points on boundary.
Definition: replicated_mesh.C:1498