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  LIBMESH_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 
28  std::unique_ptr<ReplicatedMesh> _mesh;
29 
30  void build_mesh()
31  {
32  _mesh = std::make_unique<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 = _mesh->add_elem(Elem::build_with_id(QUAD4, 0));
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  }
84  {
85  Elem * elem = _mesh->add_elem(Elem::build_with_id(QUAD4, 1));
86  elem->set_node(0, _mesh->node_ptr(4));
87  elem->set_node(1, _mesh->node_ptr(5));
88  elem->set_node(2, _mesh->node_ptr(1));
89  elem->set_node(3, _mesh->node_ptr(0));
90  }
91  {
92  Elem * elem = _mesh->add_elem(Elem::build_with_id(QUAD4, 2));
93  elem->set_node(0, _mesh->node_ptr(7));
94  elem->set_node(1, _mesh->node_ptr(2));
95  elem->set_node(2, _mesh->node_ptr(1));
96  elem->set_node(3, _mesh->node_ptr(6));
97  }
98  {
99  Elem * elem = _mesh->add_elem(Elem::build_with_id(QUAD4, 3));
100  elem->set_node(0, _mesh->node_ptr(5));
101  elem->set_node(1, _mesh->node_ptr(8));
102  elem->set_node(2, _mesh->node_ptr(6));
103  elem->set_node(3, _mesh->node_ptr(1));
104  }
105  {
106  Elem * elem = _mesh->add_elem(Elem::build_with_id(QUAD4, 4));
107  elem->set_node(0, _mesh->node_ptr(9));
108  elem->set_node(1, _mesh->node_ptr(13));
109  elem->set_node(2, _mesh->node_ptr(14));
110  elem->set_node(3, _mesh->node_ptr(10));
111  }
112  {
113  Elem * elem = _mesh->add_elem(Elem::build_with_id(QUAD4, 5));
114  elem->set_node(0, _mesh->node_ptr(10));
115  elem->set_node(1, _mesh->node_ptr(14));
116  elem->set_node(2, _mesh->node_ptr(15));
117  elem->set_node(3, _mesh->node_ptr(11));
118  }
119  {
120  Elem * elem = _mesh->add_elem(Elem::build_with_id(QUAD4, 6));
121  elem->set_node(0, _mesh->node_ptr(11));
122  elem->set_node(1, _mesh->node_ptr(15));
123  elem->set_node(2, _mesh->node_ptr(16));
124  elem->set_node(3, _mesh->node_ptr(12));
125  }
126  {
127  Elem * elem = _mesh->add_elem(Elem::build_with_id(QUAD4, 7));
128  elem->set_node(0, _mesh->node_ptr(13));
129  elem->set_node(1, _mesh->node_ptr(17));
130  elem->set_node(2, _mesh->node_ptr(18));
131  elem->set_node(3, _mesh->node_ptr(14));
132  }
133  // skip one element here
134  {
135  Elem * elem = _mesh->add_elem(Elem::build_with_id(QUAD4, 8));
136  elem->set_node(0, _mesh->node_ptr(15));
137  elem->set_node(1, _mesh->node_ptr(19));
138  elem->set_node(2, _mesh->node_ptr(20));
139  elem->set_node(3, _mesh->node_ptr(16));
140  }
141  {
142  Elem * elem = _mesh->add_elem(Elem::build_with_id(QUAD4, 9));
143  elem->set_node(0, _mesh->node_ptr(17));
144  elem->set_node(1, _mesh->node_ptr(21));
145  elem->set_node(2, _mesh->node_ptr(22));
146  elem->set_node(3, _mesh->node_ptr(18));
147  }
148  {
149  Elem * elem = _mesh->add_elem(Elem::build_with_id(QUAD4, 10));
150  elem->set_node(0, _mesh->node_ptr(18));
151  elem->set_node(1, _mesh->node_ptr(22));
152  elem->set_node(2, _mesh->node_ptr(23));
153  elem->set_node(3, _mesh->node_ptr(19));
154  }
155  {
156  Elem * elem = _mesh->add_elem(Elem::build_with_id(QUAD4, 11));
157  elem->set_node(0, _mesh->node_ptr(19));
158  elem->set_node(1, _mesh->node_ptr(23));
159  elem->set_node(2, _mesh->node_ptr(24));
160  elem->set_node(3, _mesh->node_ptr(20));
161  }
162 
163  // libMesh shouldn't renumber, or our based-on-initial-id
164  // assertions later may fail.
165  _mesh->allow_renumbering(false);
166 
167  _mesh->prepare_for_use();
168  }
169 
170 public:
171  void setUp()
172  {
173 #if LIBMESH_DIM > 1
174  this->build_mesh();
175 #endif
176  }
177 
178  void tearDown() {}
179 
180  void testMesh()
181  {
182  LOG_UNIT_TEST;
183 
184  const auto points = _mesh->get_boundary_points();
185 
186  // There'd better be two disconnected subdomains
187  CPPUNIT_ASSERT_EQUAL( (std::size_t)2, points.size() );
188 
189  // The first key should better be element 0
190  auto it = points.find(0);
191  CPPUNIT_ASSERT(it != points.end());
192 
193  // There'd better be one boundary in the first subdomain
194  CPPUNIT_ASSERT_EQUAL( (std::size_t)1, it->second.size() );
195 
196  // There'd better be eight points on the boundary of the first subdomain
197  CPPUNIT_ASSERT_EQUAL( (std::size_t)8, it->second[0].size() );
198 
199  // Boundary points should better start from (1,1)
200  CPPUNIT_ASSERT_EQUAL( Point(1,1), it->second[0][0] );
201 
202  // Boundary points should better end with (2,1)
203  CPPUNIT_ASSERT_EQUAL( Point(2,1), it->second[0][7] );
204 
205  // The second key should better be element 4
206  it = points.find(4);
207  CPPUNIT_ASSERT(it != points.end());
208 
209  // There'd better be two boundaries in the second subdomain due to the middle hole
210  CPPUNIT_ASSERT_EQUAL( (std::size_t)2, it->second.size() );
211 
212  // There'd better be 12 points on the first (outer) boundary of the second subdomain
213  CPPUNIT_ASSERT_EQUAL( (std::size_t)12, it->second[0].size() );
214 
215  // There'd better be 4 points on the first (inner) boundary of the second subdomain
216  CPPUNIT_ASSERT_EQUAL( (std::size_t)4, it->second[1].size() );
217 
218  // The first boundary points should better start from (3,-1)
219  CPPUNIT_ASSERT_EQUAL( Point(3,-1), it->second[0][0] );
220 
221  // The first boundary points should better end with (3,0)
222  CPPUNIT_ASSERT_EQUAL( Point(3,0), it->second[0][11] );
223 
224  // The second boundary points should better start from (4,0)
225  CPPUNIT_ASSERT_EQUAL( Point(4,0), it->second[1][0] );
226 
227  // The second boundary points should better end with (5,0)
228  CPPUNIT_ASSERT_EQUAL( Point(5,0), it->second[1][3] );
229  }
230 
231 };
232 
238 public:
239  LIBMESH_CPPUNIT_TEST_SUITE( GetBoundaryPointsSecondTest );
240 
241 #if LIBMESH_DIM > 1
242  CPPUNIT_TEST( testMesh );
243 #endif
244 
245  CPPUNIT_TEST_SUITE_END();
246 
247  // Yes, this is necessary. Somewhere in those macros is a protected/private
248 public:
249 
250  void setUp()
251  {
252 #if LIBMESH_DIM > 1
253  this->build_mesh();
254  _mesh->all_second_order(true);
255 #endif
256  }
257 
258  void testMesh()
259  {
260  LOG_UNIT_TEST;
261 
262  const auto points = _mesh->get_boundary_points();
263 
264  // There'd better be two disconnected subdomains
265  CPPUNIT_ASSERT_EQUAL( (std::size_t)2, points.size() );
266 
267  // The first key should better be element 0
268  auto it = points.find(0);
269  CPPUNIT_ASSERT(it != points.end());
270 
271  // There'd better be one boundary in the first subdomain
272  CPPUNIT_ASSERT_EQUAL( (std::size_t)1, it->second.size() );
273 
274  // There'd better be 16 points on the boundary of the first subdomain
275  CPPUNIT_ASSERT_EQUAL( (std::size_t)16, it->second[0].size() );
276 
277  // Boundary points should better start from (1,1)
278  CPPUNIT_ASSERT_EQUAL( Point(1,1), it->second[0][0] );
279 
280  // Boundary points should better include side middle points including (0.5,1)
281  CPPUNIT_ASSERT_EQUAL( Point(0.5,1), it->second[0][1] );
282 
283  // Boundary points should better end with (1.5,1)
284  CPPUNIT_ASSERT_EQUAL( Point(1.5,1), it->second[0][15] );
285 
286  // The second key should better be element 4
287  it = points.find(4);
288  CPPUNIT_ASSERT(it != points.end());
289 
290  // There'd better be two boundaries in the second subdomain due to the middle hole
291  CPPUNIT_ASSERT_EQUAL( (std::size_t)2, it->second.size() );
292 
293  // There'd better be 24 points on the first (outer) boundary of the second subdomain
294  CPPUNIT_ASSERT_EQUAL( (std::size_t)24, it->second[0].size() );
295 
296  // There'd better be 8 points on the first (inner) boundary of the second subdomain
297  CPPUNIT_ASSERT_EQUAL( (std::size_t)8, it->second[1].size() );
298 
299  // The first boundary points should better start from (3,-1)
300  CPPUNIT_ASSERT_EQUAL( Point(3,-1), it->second[0][0] );
301 
302  // The first boundary points should better include side middle points including (3.5,-1)
303  CPPUNIT_ASSERT_EQUAL( Point(3.5,-1), it->second[0][1] );
304 
305  // The first boundary points should better end with (3,-0.5)
306  CPPUNIT_ASSERT_EQUAL( Point(3,-0.5), it->second[0][23] );
307 
308  // The second boundary points should better start from (4,0)
309  CPPUNIT_ASSERT_EQUAL( Point(4,0), it->second[1][0] );
310 
311  // The second boundary points should better include side middle points including (4,0.25)
312  CPPUNIT_ASSERT_EQUAL( Point(4,0.25), it->second[1][1] );
313 
314  // The second boundary points should better end with (4.5,0)
315  CPPUNIT_ASSERT_EQUAL( Point(4.5,0), it->second[1][7] );
316  }
317 };
318 
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2558
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
std::unique_ptr< ReplicatedMesh > _mesh
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
The libMesh namespace provides an interface to certain functionality in the library.
static std::unique_ptr< Elem > build_with_id(const ElemType type, dof_id_type id)
Calls the build() method above with a nullptr parent, and additionally sets the newly-created Elem&#39;s ...
Definition: elem.C:558
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
CPPUNIT_TEST_SUITE_REGISTRATION(GetBoundaryPointsTest)