libMesh
mixed_dim_mesh_test.C
Go to the documentation of this file.
1 #include <libmesh/equation_systems.h>
2 #include <libmesh/replicated_mesh.h>
3 #include <libmesh/mesh_generation.h>
4 #include <libmesh/edge_edge2.h>
5 #include <libmesh/face_quad4.h>
6 #include <libmesh/face_tri3.h>
7 #include <libmesh/cell_hex8.h>
8 #include <libmesh/dof_map.h>
9 #include <libmesh/linear_implicit_system.h>
10 #include <libmesh/mesh_refinement.h>
11 
12 #include "test_comm.h"
13 #include "libmesh_cppunit.h"
14 
15 
16 using namespace libMesh;
17 
18 class MixedDimensionMeshTest : public CppUnit::TestCase {
24 public:
25  LIBMESH_CPPUNIT_TEST_SUITE( MixedDimensionMeshTest );
26 
27 #if LIBMESH_DIM > 1
28  CPPUNIT_TEST( testMesh );
29 #ifdef LIBMESH_HAVE_SOLVER
30  CPPUNIT_TEST( testDofOrdering );
31 #endif
32  CPPUNIT_TEST( testPointLocatorTree );
33 #endif
34 
35  CPPUNIT_TEST_SUITE_END();
36 
37 protected:
38 
39  std::unique_ptr<ReplicatedMesh> _mesh;
40 
41  void build_mesh()
42  {
43  _mesh = std::make_unique<ReplicatedMesh>(*TestCommWorld);
44 
45  // (0,1) (1,1)
46  // x---------------x
47  // | |
48  // | |
49  // | |
50  // | |
51  // | |
52  // x---------------x
53  // (0,0) (1,0)
54  // | |
55  // | |
56  // | |
57  // | |
58  // x---------------x
59  // (0,-1) (1,-1)
60 
61  _mesh->set_mesh_dimension(2);
62 
63  _mesh->add_point( Point(0.0,-1.0), 4 );
64  _mesh->add_point( Point(1.0,-1.0), 5 );
65  _mesh->add_point( Point(1.0, 0.0), 1 );
66  _mesh->add_point( Point(1.0, 1.0), 2 );
67  _mesh->add_point( Point(0.0, 1.0), 3 );
68  _mesh->add_point( Point(0.0, 0.0), 0 );
69 
70  {
71  Elem * elem_top = _mesh->add_elem(Elem::build(QUAD4));
72  elem_top->set_node(0, _mesh->node_ptr(0));
73  elem_top->set_node(1, _mesh->node_ptr(1));
74  elem_top->set_node(2, _mesh->node_ptr(2));
75  elem_top->set_node(3, _mesh->node_ptr(3));
76 
77  Elem * elem_bottom = _mesh->add_elem(Elem::build(QUAD4));
78  elem_bottom->set_node(0, _mesh->node_ptr(4));
79  elem_bottom->set_node(1, _mesh->node_ptr(5));
80  elem_bottom->set_node(2, _mesh->node_ptr(1));
81  elem_bottom->set_node(3, _mesh->node_ptr(0));
82 
83  Elem * edge = _mesh->add_elem(Elem::build(EDGE2));
84  edge->set_node(0, _mesh->node_ptr(0));
85  edge->set_node(1, _mesh->node_ptr(1));
86 
87  // 2D elements will have subdomain id 0, this one will have 1
88  edge->subdomain_id() = 1;
89  }
90 
91  _mesh->allow_renumbering(true);
92  _mesh->prepare_for_use();
93  }
94 
95 public:
96  void setUp()
97  {
98 #if LIBMESH_DIM > 1
99  this->build_mesh();
100 #endif
101  }
102 
103  void tearDown() {}
104 
105  void testMesh()
106  {
107  LOG_UNIT_TEST;
108 
109  // There'd better be 3 elements
110  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(3), _mesh->n_elem());
111 
112  // There'd better be only 6 nodes
113  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(6), _mesh->n_nodes());
114 
115  /* The nodes for the EDGE2 element should have the same global ids
116  as the bottom edge of the top QUAD4 element */
117  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(2).node_id(0), _mesh->elem_ref(0).node_id(0) );
118  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(2).node_id(1), _mesh->elem_ref(0).node_id(1) );
119 
120  /* The nodes for the EDGE2 element should have the same global ids
121  as the top edge of the bottom QUAD4 element */
122  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(2).node_id(0), _mesh->elem_ref(1).node_id(3) );
123  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(2).node_id(1), _mesh->elem_ref(1).node_id(2) );
124 
125  /* The nodes for the bottom edge of the top QUAD4 element should have
126  the same global ids as the top edge of the bottom QUAD4 element */
127  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(0).node_id(0), _mesh->elem_ref(1).node_id(3) );
128  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(0).node_id(1), _mesh->elem_ref(1).node_id(2) );
129 
130  // We didn't set an interior_parent on the edge element, so it
131  // should default to NULL
132  CPPUNIT_ASSERT( _mesh->elem_ref(2).interior_parent() );
133  }
134 
136  {
137  LOG_UNIT_TEST;
138 
139  EquationSystems es(*_mesh);
140  es.add_system<LinearImplicitSystem>("TestDofSystem");
141  es.get_system("TestDofSystem").add_variable("u",FIRST);
142  es.init();
143 
144  DofMap& dof_map = es.get_system("TestDofSystem").get_dof_map();
145 
146  std::vector<dof_id_type> top_quad_dof_indices, bottom_quad_dof_indices, edge_dof_indices;
147 
148  dof_map.dof_indices( _mesh->elem_ptr(0), top_quad_dof_indices );
149  dof_map.dof_indices( _mesh->elem_ptr(1), bottom_quad_dof_indices );
150  dof_map.dof_indices( _mesh->elem_ptr(2), edge_dof_indices );
151 
152  /* The dofs for the EDGE2 element should be the same
153  as the bottom edge of the top QUAD4 dofs */
154  CPPUNIT_ASSERT_EQUAL( edge_dof_indices[0], top_quad_dof_indices[0] );
155  CPPUNIT_ASSERT_EQUAL( edge_dof_indices[1], top_quad_dof_indices[1] );
156 
157  /* The dofs for the EDGE2 element should be the same
158  as the top edge of the bottom QUAD4 dofs */
159  CPPUNIT_ASSERT_EQUAL( edge_dof_indices[0], bottom_quad_dof_indices[3] );
160  CPPUNIT_ASSERT_EQUAL( edge_dof_indices[1], bottom_quad_dof_indices[2] );
161 
162  /* The nodes for the bottom edge of the top QUAD4 element should have
163  the same global ids as the top edge of the bottom QUAD4 element */
164  CPPUNIT_ASSERT_EQUAL( top_quad_dof_indices[0], bottom_quad_dof_indices[3] );
165  CPPUNIT_ASSERT_EQUAL( top_quad_dof_indices[1], bottom_quad_dof_indices[2] );
166  }
167 
169  {
170  LOG_UNIT_TEST;
171 
172  std::unique_ptr<PointLocatorBase> locator = _mesh->sub_point_locator();
173 
174  Point top_point(0.5, 0.5);
175  const Elem* top_elem = (*locator)(top_point);
176  CPPUNIT_ASSERT(top_elem);
177 
178  // We should have gotten back the top quad
179  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(0), top_elem->id());
180 
181  Point bottom_point(0.5, -0.5);
182  const Elem* bottom_elem = (*locator)(bottom_point);
183  CPPUNIT_ASSERT(bottom_elem);
184 
185  // We should have gotten back the bottom quad
186  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(1), bottom_elem->id());
187 
188  // Test getting back the edge
189  {
190  std::set<subdomain_id_type> subdomain_id; subdomain_id.insert(1);
191  Point interface_point( 0.5, 0.0 );
192  const Elem* interface_elem = (*locator)(interface_point, &subdomain_id);
193  CPPUNIT_ASSERT(interface_elem);
194 
195  // We should have gotten back the overlapping edge element
196  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(2), interface_elem->id());
197  }
198  }
199 
200 };
201 
209 public:
210  LIBMESH_CPPUNIT_TEST_SUITE( MixedDimensionRefinedMeshTest );
211 
212 #if LIBMESH_DIM > 1
213  CPPUNIT_TEST( testMesh );
214 #ifdef LIBMESH_HAVE_SOLVER
215  CPPUNIT_TEST( testDofOrdering );
216 #endif
217 #endif
218 
219  CPPUNIT_TEST_SUITE_END();
220 
221  // Yes, this is necessary. Somewhere in those macros is a protected/private
222 public:
223 
224  void setUp()
225  {
226  // 3-------10------2
227  // | | |
228  // | 5 | 6 |
229  // 8-------7-------9
230  // | | |
231  // | 3 | 4 |
232  // 0-------6-------1
233  // | | |
234  // | 9 | 10 |
235  // 13------12-------14
236  // | | |
237  // | 7 | 8 |
238  // 4-------11------5
239 #if LIBMESH_DIM > 1
240  this->build_mesh();
241 
242 #ifdef LIBMESH_ENABLE_AMR
243  MeshRefinement(*_mesh).uniformly_refine(1);
244 #endif
245 #endif
246  }
247 
248  void testMesh()
249  {
250 #ifdef LIBMESH_ENABLE_AMR
251  LOG_UNIT_TEST;
252 
253  // We should have 13 total and 10 active elements.
254  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(13), _mesh->n_elem());
255  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(10), _mesh->n_active_elem());
256 
257  // We should have 15 nodes
258  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(15), _mesh->n_nodes());
259 
260  // EDGE2,id=11 should have same nodes of bottom of QUAD4, id=3
261  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(11).node_id(0),
262  _mesh->elem_ref(3).node_id(0) );
263  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(11).node_id(1),
264  _mesh->elem_ref(3).node_id(1) );
265 
266  // EDGE2,id=12 should have same nodes of bottom of QUAD4, id=4
267  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(12).node_id(0),
268  _mesh->elem_ref(4).node_id(0) );
269  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(12).node_id(1),
270  _mesh->elem_ref(4).node_id(1) );
271 
272  // EDGE2,id=11 should have same nodes of top of QUAD4, id=9
273  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(11).node_id(0),
274  _mesh->elem_ref(9).node_id(3) );
275  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(11).node_id(1),
276  _mesh->elem_ref(9).node_id(2) );
277 
278  // EDGE2,id=12 should have same nodes of top of QUAD4, id=10
279  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(12).node_id(0),
280  _mesh->elem_ref(10).node_id(3) );
281  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(12).node_id(1),
282  _mesh->elem_ref(10).node_id(2) );
283 
284  // Shared node between the EDGE2 elements should have the same global id
285  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(11).node_id(1),
286  _mesh->elem_ref(12).node_id(0) );
287 
288  // EDGE2 child elements should have the correct parent
289  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(11).parent(),
290  _mesh->elem_ptr(2) );
291  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(12).parent(),
292  _mesh->elem_ptr(2) );
293 
294  // EDGE2 child elements should have the correct interior_parent
295  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(11).interior_parent(),
296  _mesh->elem_ptr(3) );
297  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(12).interior_parent(),
298  _mesh->elem_ptr(4) );
299 #endif
300  }
301 
303  {
304 #ifdef LIBMESH_ENABLE_AMR
305  LOG_UNIT_TEST;
306 
307  EquationSystems es(*_mesh);
308  es.add_system<LinearImplicitSystem>("TestDofSystem");
309  es.get_system("TestDofSystem").add_variable("u",FIRST);
310  es.init();
311 
312  DofMap& dof_map = es.get_system("TestDofSystem").get_dof_map();
313 
314  std::vector<dof_id_type> top_quad3_dof_indices, top_quad4_dof_indices;
315  std::vector<dof_id_type> bottom_quad9_dof_indices, bottom_quad10_dof_indices;
316  std::vector<dof_id_type> edge11_dof_indices, edge12_dof_indices;
317 
318  dof_map.dof_indices( _mesh->elem_ptr(3), top_quad3_dof_indices );
319  dof_map.dof_indices( _mesh->elem_ptr(4), top_quad4_dof_indices );
320  dof_map.dof_indices( _mesh->elem_ptr(9), bottom_quad9_dof_indices );
321  dof_map.dof_indices( _mesh->elem_ptr(10), bottom_quad10_dof_indices );
322  dof_map.dof_indices( _mesh->elem_ptr(11), edge11_dof_indices );
323  dof_map.dof_indices( _mesh->elem_ptr(12), edge12_dof_indices );
324 
325  // EDGE2,id=11 should have same dofs as of bottom of QUAD4, id=3
326  CPPUNIT_ASSERT_EQUAL( edge11_dof_indices[0], top_quad3_dof_indices[0] );
327  CPPUNIT_ASSERT_EQUAL( edge11_dof_indices[1], top_quad3_dof_indices[1] );
328 
329  // EDGE2,id=12 should have same dofs of bottom of QUAD4, id=4
330  CPPUNIT_ASSERT_EQUAL( edge12_dof_indices[0], top_quad4_dof_indices[0] );
331  CPPUNIT_ASSERT_EQUAL( edge12_dof_indices[1], top_quad4_dof_indices[1] );
332 
333  // EDGE2,id=11 should have same dofs of top of QUAD4, id=9
334  CPPUNIT_ASSERT_EQUAL( edge11_dof_indices[0], bottom_quad9_dof_indices[3] );
335  CPPUNIT_ASSERT_EQUAL( edge11_dof_indices[1], bottom_quad9_dof_indices[2] );
336 
337  // EDGE2,id=12 should have same dofs of top of QUAD4, id=10
338  CPPUNIT_ASSERT_EQUAL( edge12_dof_indices[0], bottom_quad10_dof_indices[3] );
339  CPPUNIT_ASSERT_EQUAL( edge12_dof_indices[1], bottom_quad10_dof_indices[2] );
340 
341  //EDGE2 elements should have same shared dof number
342  CPPUNIT_ASSERT_EQUAL( edge11_dof_indices[1], edge12_dof_indices[0] );
343 #endif
344  }
345 
346 };
347 
348 class MixedDimensionNonUniformRefinement : public CppUnit::TestCase {
356 public:
357  LIBMESH_CPPUNIT_TEST_SUITE( MixedDimensionNonUniformRefinement );
358 
359 #if LIBMESH_DIM > 1
360  CPPUNIT_TEST( testMesh );
361 #ifdef LIBMESH_HAVE_SOLVER
362  CPPUNIT_TEST( testDofOrdering );
363 #endif
364 #endif
365 
366  CPPUNIT_TEST_SUITE_END();
367 
368  // Yes, this is necessary. Somewhere in those macros is a protected/private
369 protected:
370 
371  std::unique_ptr<ReplicatedMesh> _mesh;
372 
373  void build_mesh()
374  {
375  _mesh = std::make_unique<ReplicatedMesh>(*TestCommWorld);
376  // We start with this
377  //
378  //
379  // (0,2) (1,2)
380  // 4---------------5
381  // | |
382  // | |
383  // | 1 |
384  // | |
385  // | |
386  // (0,1) (1,1)
387  // 3---------------2
388  // | |
389  // | |
390  // | 0 |
391  // | |
392  // | |
393  // 0---------------1
394  // (0,0) (1,0)
395  // | |
396  // | 2 |
397  // | |
398  // | |
399  // 6---------------7
400  // (0,-1) (1,-1)
401  // | |
402  // | 3 |
403  // | |
404  // | |
405  // 9---------------8
406  // (0,-2) (1,-2)
407  //
408  // But the single element refinement should result
409  // with this for the default max_mismatch = 0 case
410  //
411  // 4---------------5
412  // | |
413  // | |
414  // | 1 |
415  // | |
416  // | |
417  // 3------14-------2
418  // | | |
419  // | 7 | 8 |
420  // 12------11-------13
421  // | | |
422  // | 5 | 6 |
423  // 0------10-------1
424  // | | |
425  // | 11 | 12 |
426  // 17------16-------18
427  // | | |
428  // | 9 | 10 |
429  // 6------15-------7
430  // | |
431  // | |
432  // | 3 |
433  // | |
434  // | |
435  // 9---------------8
436 
437  _mesh->set_mesh_dimension(2);
438 
439  _mesh->add_point( Point(0.0,0.0), 0 );
440  _mesh->add_point( Point(1.0,0.0), 1 );
441  _mesh->add_point( Point(1.0,1.0), 2 );
442  _mesh->add_point( Point(0.0,1.0), 3 );
443  _mesh->add_point( Point(0.0,2.0), 4 );
444  _mesh->add_point( Point(1.0,2.0), 5 );
445  _mesh->add_point( Point(0.0,-1.0), 6 );
446  _mesh->add_point( Point(1.0,-1.0), 7 );
447  _mesh->add_point( Point(1.0,-2.0), 8 );
448  _mesh->add_point( Point(0.0,-2.0), 9 );
449 
450 
451  {
452  Elem * quad0 = _mesh->add_elem(Elem::build(QUAD4));
453  quad0->set_node(0, _mesh->node_ptr(0));
454  quad0->set_node(1, _mesh->node_ptr(1));
455  quad0->set_node(2, _mesh->node_ptr(2));
456  quad0->set_node(3, _mesh->node_ptr(3));
457 
458  Elem * quad1 = _mesh->add_elem(Elem::build(QUAD4));
459  quad1->set_node(0, _mesh->node_ptr(3));
460  quad1->set_node(1, _mesh->node_ptr(2));
461  quad1->set_node(2, _mesh->node_ptr(5));
462  quad1->set_node(3, _mesh->node_ptr(4));
463 
464  Elem * quad2 = _mesh->add_elem(Elem::build(QUAD4));
465  quad2->set_node(0, _mesh->node_ptr(6));
466  quad2->set_node(1, _mesh->node_ptr(7));
467  quad2->set_node(2, _mesh->node_ptr(1));
468  quad2->set_node(3, _mesh->node_ptr(0));
469 
470  Elem * quad3 = _mesh->add_elem(Elem::build(QUAD4));
471  quad3->set_node(0, _mesh->node_ptr(9));
472  quad3->set_node(1, _mesh->node_ptr(8));
473  quad3->set_node(2, _mesh->node_ptr(7));
474  quad3->set_node(3, _mesh->node_ptr(6));
475 
476  Elem * edge = _mesh->add_elem(Elem::build(EDGE2));
477  edge->set_node(0, _mesh->node_ptr(0));
478  edge->set_node(1, _mesh->node_ptr(1));
479 
480  // 2D elements will have subdomain id 0, this one will have 1
481  edge->subdomain_id() = 1;
482  }
483 
484  _mesh->allow_renumbering(true);
485  _mesh->prepare_for_use();
486 
487 
488 #ifdef LIBMESH_ENABLE_AMR
489  //Flag the bottom element for refinement
490  _mesh->elem_ref(0).set_refinement_flag(Elem::REFINE);
492 #endif
493 
494  }
495 
496 public:
497  void setUp()
498  {
499 #if LIBMESH_DIM > 1
500  this->build_mesh();
501 #endif
502  }
503 
504  void tearDown() {}
505 
506  void testMesh()
507  {
508 #ifdef LIBMESH_ENABLE_AMR
509  LOG_UNIT_TEST;
510 
511  // We should have 13 total and 10 active elements.
512  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(15), _mesh->n_elem());
513  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(12), _mesh->n_active_elem());
514 
515  // We should have 15 nodes
516  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(19), _mesh->n_nodes());
517 
518  // EDGE2,id=13 should have same nodes of bottom of QUAD4, id=5
519  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).node_id(0),
520  _mesh->elem_ref(5).node_id(0) );
521  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).node_id(1),
522  _mesh->elem_ref(5).node_id(1) );
523 
524  // EDGE2,id=14 should have same nodes of bottom of QUAD4, id=6
525  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(14).node_id(0),
526  _mesh->elem_ref(6).node_id(0) );
527  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(14).node_id(1),
528  _mesh->elem_ref(6).node_id(1) );
529 
530  // EDGE2,id=13 should have same nodes of top of QUAD4, id=11
531  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).node_id(0),
532  _mesh->elem_ref(11).node_id(3) );
533  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).node_id(1),
534  _mesh->elem_ref(11).node_id(2) );
535 
536  // EDGE2,id=14 should have same nodes of top of QUAD4, id=12
537  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(14).node_id(0),
538  _mesh->elem_ref(12).node_id(3) );
539  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(14).node_id(1),
540  _mesh->elem_ref(12).node_id(2) );
541 
542  // Shared node between the EDGE2 elements should have the same global id
543  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).node_id(1),
544  _mesh->elem_ref(14).node_id(0) );
545 
546  // EDGE2 child elements should have the correct parent
547  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).parent(),
548  _mesh->elem_ptr(4) );
549  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(14).parent(),
550  _mesh->elem_ptr(4) );
551 
552  // EDGE2 child elements should have the correct interior_parent
553  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).interior_parent(),
554  _mesh->elem_ptr(5) );
555  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(14).interior_parent(),
556  _mesh->elem_ptr(6) );
557 #endif
558  }
559 
561  {
562 #ifdef LIBMESH_ENABLE_AMR
563  LOG_UNIT_TEST;
564 
565  EquationSystems es(*_mesh);
566  es.add_system<LinearImplicitSystem>("TestDofSystem");
567  es.get_system("TestDofSystem").add_variable("u",FIRST);
568  es.init();
569 
570  DofMap& dof_map = es.get_system("TestDofSystem").get_dof_map();
571 
572  std::vector<dof_id_type> top_quad5_dof_indices, top_quad6_dof_indices;
573  std::vector<dof_id_type> bottom_quad11_dof_indices, bottom_quad12_dof_indices;
574  std::vector<dof_id_type> edge13_dof_indices, edge14_dof_indices;
575 
576  dof_map.dof_indices( _mesh->elem_ptr(5), top_quad5_dof_indices );
577  dof_map.dof_indices( _mesh->elem_ptr(6), top_quad6_dof_indices );
578  dof_map.dof_indices( _mesh->elem_ptr(11), bottom_quad11_dof_indices );
579  dof_map.dof_indices( _mesh->elem_ptr(12), bottom_quad12_dof_indices );
580  dof_map.dof_indices( _mesh->elem_ptr(13), edge13_dof_indices );
581  dof_map.dof_indices( _mesh->elem_ptr(14), edge14_dof_indices );
582 
583  // EDGE2,id=13 should have same dofs as of bottom of QUAD4, id=5
584  CPPUNIT_ASSERT_EQUAL( edge13_dof_indices[0], top_quad5_dof_indices[0] );
585  CPPUNIT_ASSERT_EQUAL( edge13_dof_indices[1], top_quad5_dof_indices[1] );
586 
587  // EDGE2,id=14 should have same dofs of bottom of QUAD4, id=6
588  CPPUNIT_ASSERT_EQUAL( edge14_dof_indices[0], top_quad6_dof_indices[0] );
589  CPPUNIT_ASSERT_EQUAL( edge14_dof_indices[1], top_quad6_dof_indices[1] );
590 
591  // EDGE2,id=13 should have same dofs of top of QUAD4, id=11
592  CPPUNIT_ASSERT_EQUAL( edge13_dof_indices[0], bottom_quad11_dof_indices[3] );
593  CPPUNIT_ASSERT_EQUAL( edge13_dof_indices[1], bottom_quad11_dof_indices[2] );
594 
595  // EDGE2,id=14 should have same dofs of top of QUAD4, id=12
596  CPPUNIT_ASSERT_EQUAL( edge14_dof_indices[0], bottom_quad12_dof_indices[3] );
597  CPPUNIT_ASSERT_EQUAL( edge14_dof_indices[1], bottom_quad12_dof_indices[2] );
598 
599  //EDGE2 elements should have same shared dof number
600  CPPUNIT_ASSERT_EQUAL( edge13_dof_indices[1], edge14_dof_indices[0] );
601 #endif
602  }
603 };
604 
605 class MixedDimensionNonUniformRefinementTriangle : public CppUnit::TestCase {
613 public:
614  LIBMESH_CPPUNIT_TEST_SUITE( MixedDimensionNonUniformRefinementTriangle );
615 
616 #if LIBMESH_DIM > 1
617  CPPUNIT_TEST( testMesh );
618 #ifdef LIBMESH_HAVE_SOLVER
619  CPPUNIT_TEST( testDofOrdering );
620 #endif
621 #endif
622 
623  CPPUNIT_TEST_SUITE_END();
624 
625 protected:
626 
627  std::unique_ptr<ReplicatedMesh> _mesh;
628 
629  void build_mesh()
630  {
631  _mesh = std::make_unique<ReplicatedMesh>(*TestCommWorld);
632 
673  _mesh->set_mesh_dimension(2);
674 
675  _mesh->add_point( Point(0.0,-1.0), 4 );
676  _mesh->add_point( Point(1.0,-1.0), 5 );
677  _mesh->add_point( Point(1.0, 0.0), 1 );
678  _mesh->add_point( Point(1.0, 1.0), 2 );
679  _mesh->add_point( Point(0.0, 1.0), 3 );
680  _mesh->add_point( Point(0.0, 0.0), 0 );
681 
682  {
683  Elem * elem0 = _mesh->add_elem(Elem::build(TRI3));
684  elem0->set_node(0, _mesh->node_ptr(0));
685  elem0->set_node(1, _mesh->node_ptr(1));
686  elem0->set_node(2, _mesh->node_ptr(2));
687 
688  Elem * elem1 = _mesh->add_elem(Elem::build(TRI3));
689  elem1->set_node(0, _mesh->node_ptr(2));
690  elem1->set_node(1, _mesh->node_ptr(3));
691  elem1->set_node(2, _mesh->node_ptr(0));
692 
693  Elem * elem2 = _mesh->add_elem(Elem::build(TRI3));
694  elem2->set_node(0, _mesh->node_ptr(1));
695  elem2->set_node(1, _mesh->node_ptr(0));
696  elem2->set_node(2, _mesh->node_ptr(4));
697 
698  Elem * elem3 = _mesh->add_elem(Elem::build(TRI3));
699  elem3->set_node(0, _mesh->node_ptr(4));
700  elem3->set_node(1, _mesh->node_ptr(5));
701  elem3->set_node(2, _mesh->node_ptr(1));
702 
703  Elem * edge = _mesh->add_elem(Elem::build(EDGE2));
704  edge->set_node(0, _mesh->node_ptr(0));
705  edge->set_node(1, _mesh->node_ptr(1));
706 
707  // 2D elements will have subdomain id 0, this one will have 1
708  edge->subdomain_id() = 1;
709 
710  }
711 
712  _mesh->allow_renumbering(true);
713  _mesh->prepare_for_use();
714 
715 #ifdef LIBMESH_ENABLE_AMR
716  //Flag the bottom element for refinement
717  _mesh->elem_ref(4).set_refinement_flag(Elem::REFINE);
719 #endif
720  }
721 
722 public:
723  void setUp()
724  {
725 #if LIBMESH_DIM > 1
726  this->build_mesh();
727 #endif
728  }
729 
730  void tearDown() {}
731 
732  void testMesh()
733  {
734 #ifdef LIBMESH_ENABLE_AMR
735  LOG_UNIT_TEST;
736 
737  // We should have 15 total and 12 active elements.
738  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(15), _mesh->n_elem());
739  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(12), _mesh->n_active_elem());
740 
741  // We should have 15 nodes
742  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(11), _mesh->n_nodes());
743 
744  // EDGE2,id=13 should have same nodes of the base of TRI3, id=5
745  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).node_id(0),
746  _mesh->elem_ref(5).node_id(0) );
747  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).node_id(1),
748  _mesh->elem_ref(5).node_id(1) );
749 
750  // EDGE2,id=13 should have same nodes of the base of TRI3, id=10
751  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).node_id(0),
752  _mesh->elem_ref(10).node_id(1) );
753  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).node_id(1),
754  _mesh->elem_ref(10).node_id(0) );
755 
756  // EDGE2,id=13 should have same node as the tip of TRI3, id=8 and id=12
757  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).node_id(1),
758  _mesh->elem_ref(8).node_id(0) );
759  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).node_id(1),
760  _mesh->elem_ref(12).node_id(0) );
761 
762  // EDGE2,id=14 should have same nodes of the base of TRI3, id=6
763  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(14).node_id(0),
764  _mesh->elem_ref(6).node_id(0) );
765  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(14).node_id(1),
766  _mesh->elem_ref(6).node_id(1) );
767 
768  // EDGE2,id=14 should have same nodes of the base of TRI3, id=9
769  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(14).node_id(0),
770  _mesh->elem_ref(9).node_id(1) );
771  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(14).node_id(1),
772  _mesh->elem_ref(9).node_id(0) );
773 
774  // EDGE2,id=14 should have same node as the tip of TRI3, id=8 and id=12
775  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(14).node_id(0),
776  _mesh->elem_ref(8).node_id(0) );
777  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(14).node_id(0),
778  _mesh->elem_ref(12).node_id(0) );
779 
780  // Shared node between the EDGE2 elements should have the same global id
781  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).node_id(1),
782  _mesh->elem_ref(14).node_id(0) );
783 
784  // EDGE2 child elements should have the correct parent
785  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).parent(),
786  _mesh->elem_ptr(4) );
787  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(14).parent(),
788  _mesh->elem_ptr(4) );
789 
790  // EDGE2 child elements should have the correct interior_parent
791  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(13).interior_parent(),
792  _mesh->elem_ptr(5) );
793  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(14).interior_parent(),
794  _mesh->elem_ptr(6) );
795 
796 #endif // LIBMESH_ENABLE_AMR
797  }
798 
800  {
801 #ifdef LIBMESH_ENABLE_AMR
802  LOG_UNIT_TEST;
803 
804  EquationSystems es(*_mesh);
805  es.add_system<LinearImplicitSystem>("TestDofSystem");
806  es.get_system("TestDofSystem").add_variable("u",FIRST);
807  es.init();
808 
809  DofMap& dof_map = es.get_system("TestDofSystem").get_dof_map();
810 
811  //Elements above the EDGE2 elements
812  std::vector<dof_id_type> elem5_dof_indices, elem6_dof_indices, elem8_dof_indices;
813 
814  //Elements below the EDGE2 elements
815  std::vector<dof_id_type> elem9_dof_indices, elem10_dof_indices, elem12_dof_indices;
816 
817  //EDGE2 Elements
818  std::vector<dof_id_type> elem13_dof_indices, elem14_dof_indices;
819 
820  dof_map.dof_indices( _mesh->elem_ptr(5), elem5_dof_indices );
821  dof_map.dof_indices( _mesh->elem_ptr(6), elem6_dof_indices );
822  dof_map.dof_indices( _mesh->elem_ptr(8), elem8_dof_indices );
823  dof_map.dof_indices( _mesh->elem_ptr(9), elem9_dof_indices );
824  dof_map.dof_indices( _mesh->elem_ptr(10), elem10_dof_indices );
825  dof_map.dof_indices( _mesh->elem_ptr(12), elem12_dof_indices );
826  dof_map.dof_indices( _mesh->elem_ptr(13), elem13_dof_indices );
827  dof_map.dof_indices( _mesh->elem_ptr(14), elem14_dof_indices );
828 
829  /* The dofs for the EDGE2 (id = 13 and id =14) element should be the same
830  as the bottom edge of the top TRI3 (id=5 and id=6) and the tip of
831  TRI3 id = 8 dofs */
832  CPPUNIT_ASSERT_EQUAL( elem13_dof_indices[0], elem5_dof_indices[0] );
833  CPPUNIT_ASSERT_EQUAL( elem13_dof_indices[1], elem5_dof_indices[1] );
834  CPPUNIT_ASSERT_EQUAL( elem13_dof_indices[1], elem6_dof_indices[0] );
835  CPPUNIT_ASSERT_EQUAL( elem13_dof_indices[1], elem8_dof_indices[0] );
836  CPPUNIT_ASSERT_EQUAL( elem14_dof_indices[0], elem6_dof_indices[0] );
837  CPPUNIT_ASSERT_EQUAL( elem14_dof_indices[1], elem6_dof_indices[1] );
838  CPPUNIT_ASSERT_EQUAL( elem14_dof_indices[0], elem5_dof_indices[1] );
839  CPPUNIT_ASSERT_EQUAL( elem14_dof_indices[0], elem8_dof_indices[0] );
840 
841  /* The dofs for the EDGE2 (id = 13 and id =14) element should be the same
842  as the top edge of the bottom TRI3 (id=9 and id=10) and the tip of
843  TRI3 id = 12 dofs */
844  CPPUNIT_ASSERT_EQUAL( elem13_dof_indices[0], elem10_dof_indices[1] );
845  CPPUNIT_ASSERT_EQUAL( elem13_dof_indices[1], elem10_dof_indices[0] );
846  CPPUNIT_ASSERT_EQUAL( elem13_dof_indices[1], elem9_dof_indices[1] );
847  CPPUNIT_ASSERT_EQUAL( elem13_dof_indices[1], elem12_dof_indices[0] );
848  CPPUNIT_ASSERT_EQUAL( elem14_dof_indices[0], elem9_dof_indices[1] );
849  CPPUNIT_ASSERT_EQUAL( elem14_dof_indices[1], elem9_dof_indices[0] );
850  CPPUNIT_ASSERT_EQUAL( elem14_dof_indices[0], elem10_dof_indices[0] );
851  CPPUNIT_ASSERT_EQUAL( elem14_dof_indices[0], elem12_dof_indices[0] );
852 
853  /* The nodes for the bottom edge of the top TRI3 elements should have
854  the same global ids as the top edge of the bottom TRI3 elements. */
855  CPPUNIT_ASSERT_EQUAL( elem5_dof_indices[0], elem10_dof_indices[1] );
856  CPPUNIT_ASSERT_EQUAL( elem5_dof_indices[1], elem10_dof_indices[0] );
857  CPPUNIT_ASSERT_EQUAL( elem6_dof_indices[0], elem9_dof_indices[1] );
858  CPPUNIT_ASSERT_EQUAL( elem6_dof_indices[1], elem9_dof_indices[0] );
859  CPPUNIT_ASSERT_EQUAL( elem8_dof_indices[0], elem12_dof_indices[0] );
860 #endif // LIBMESH_ENABLE_AMR
861  }
862 
863 };
864 
865 class MixedDimensionNonUniformRefinement3D : public CppUnit::TestCase {
873 public:
874  LIBMESH_CPPUNIT_TEST_SUITE( MixedDimensionNonUniformRefinement3D );
875 
876 #if LIBMESH_DIM > 2
877  CPPUNIT_TEST( testMesh );
878 #ifdef LIBMESH_HAVE_SOLVER
879  CPPUNIT_TEST( testDofOrdering );
880 #endif
881 #endif
882 
883  CPPUNIT_TEST_SUITE_END();
884 
885  // Yes, this is necessary. Somewhere in those macros is a protected/private
886 protected:
887 
888  std::unique_ptr<ReplicatedMesh> _mesh;
889 
890  void build_mesh()
891  {
892  _mesh = std::make_unique<ReplicatedMesh>(*TestCommWorld);
893 
894  _mesh->set_mesh_dimension(3);
895 
896  //Add the nodes
897  for (unsigned int z = 0; z < 5; z++)
898  {
899  for (unsigned int y = 0; y < 4; y++)
900  {
901  for (unsigned int x = 0; x < 4; x++)
902  {
903  _mesh->add_point( Point(Real(x),Real(y),Real(z)), 16*z+4*y+x);
904  }
905  }
906  }
907 
908  {
909  //Add the HEX8 elements
910  for (unsigned int z = 0; z < 4; z++)
911  {
912  for (unsigned int y = 0; y < 3; y++)
913  {
914  for (unsigned int x = 0; x < 3; x++)
915  {
916  Elem * hex = _mesh->add_elem(Elem::build(HEX8));
917  hex->set_node(0, _mesh->node_ptr(x+4*y +16*z ));
918  hex->set_node(1, _mesh->node_ptr(x+4*y +16*z + 1));
919  hex->set_node(2, _mesh->node_ptr(x+4*(y+1)+16*z + 1));
920  hex->set_node(3, _mesh->node_ptr(x+4*(y+1)+16*z ));
921  hex->set_node(4, _mesh->node_ptr(x+4*y +16*(z+1) ));
922  hex->set_node(5, _mesh->node_ptr(x+4*y +16*(z+1) + 1));
923  hex->set_node(6, _mesh->node_ptr(x+4*(y+1)+16*(z+1) + 1));
924  hex->set_node(7, _mesh->node_ptr(x+4*(y+1)+16*(z+1) ));
925  }
926  }
927  }
928  Elem * quad = _mesh->add_elem(Elem::build(QUAD4));
929  unsigned int x=1,y=1,z=2;
930  quad->set_node(0, _mesh->node_ptr(x+4*y +16*z ));
931  quad->set_node(1, _mesh->node_ptr(x+4*y +16*z + 1));
932  quad->set_node(2, _mesh->node_ptr(x+4*(y+1)+16*z + 1));
933  quad->set_node(3, _mesh->node_ptr(x+4*(y+1)+16*z ));
934 
935  // 2D elements will have subdomain id 0, this one will have 1
936  quad->subdomain_id() = 1;
937  }
938 
939  _mesh->allow_renumbering(true);
940  _mesh->prepare_for_use();
941 
942 #ifdef LIBMESH_ENABLE_AMR
943  //Flag the bottom element for refinement
944  _mesh->elem_ref(13).set_refinement_flag(Elem::REFINE);
946 #endif
947  }
948 
949 public:
950  void setUp()
951  {
952 #if LIBMESH_DIM > 2
953  this->build_mesh();
954 #endif
955  }
956 
957  void tearDown() {}
958 
959  void testMesh()
960  {
961 #ifdef LIBMESH_ENABLE_AMR
962  LOG_UNIT_TEST;
963 
964  // We should have 57 total and 54 active elements.
965  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(57), _mesh->n_elem() );
966  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(54), _mesh->n_active_elem() );
967 
968  // We should have 113 nodes
969  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(113), _mesh->n_nodes() );
970 
971  // QUAD4,id=53 should have same nodes as a face in HEX8, id=39
972  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(53).node_id(0),
973  _mesh->elem_ref(41).node_id(4) );
974  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(53).node_id(1),
975  _mesh->elem_ref(41).node_id(5) );
976  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(53).node_id(2),
977  _mesh->elem_ref(41).node_id(6) );
978  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(53).node_id(3),
979  _mesh->elem_ref(41).node_id(7) );
980 
981  // QUAD4,id=53 should have same nodes as a face in HEX8, id=45
982  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(53).node_id(0),
983  _mesh->elem_ref(45).node_id(0) );
984  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(53).node_id(1),
985  _mesh->elem_ref(45).node_id(1) );
986  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(53).node_id(2),
987  _mesh->elem_ref(45).node_id(2) );
988  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(53).node_id(3),
989  _mesh->elem_ref(45).node_id(3) );
990 
991  // QUAD4,id=54 should have same nodes as a face in HEX8, id=42
992  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(54).node_id(0),
993  _mesh->elem_ref(42).node_id(4) );
994  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(54).node_id(1),
995  _mesh->elem_ref(42).node_id(5) );
996  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(54).node_id(2),
997  _mesh->elem_ref(42).node_id(6) );
998  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(54).node_id(3),
999  _mesh->elem_ref(42).node_id(7) );
1000 
1001  // QUAD4,id=54 should have same nodes as a face in HEX8, id=46
1002  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(54).node_id(0),
1003  _mesh->elem_ref(46).node_id(0) );
1004  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(54).node_id(1),
1005  _mesh->elem_ref(46).node_id(1) );
1006  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(54).node_id(2),
1007  _mesh->elem_ref(46).node_id(2) );
1008  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(54).node_id(3),
1009  _mesh->elem_ref(46).node_id(3) );
1010 
1011  // QUAD4,id=55 should have same nodes as a face in HEX8, id=43
1012  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(55).node_id(0),
1013  _mesh->elem_ref(43).node_id(4) );
1014  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(55).node_id(1),
1015  _mesh->elem_ref(43).node_id(5) );
1016  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(55).node_id(2),
1017  _mesh->elem_ref(43).node_id(6) );
1018  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(55).node_id(3),
1019  _mesh->elem_ref(43).node_id(7) );
1020 
1021  // QUAD4,id=55 should have same nodes as a face in HEX8, id=47
1022  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(55).node_id(0),
1023  _mesh->elem_ref(47).node_id(0) );
1024  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(55).node_id(1),
1025  _mesh->elem_ref(47).node_id(1) );
1026  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(55).node_id(2),
1027  _mesh->elem_ref(47).node_id(2) );
1028  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(55).node_id(3),
1029  _mesh->elem_ref(47).node_id(3) );
1030 
1031  // QUAD4,id=56 should have same nodes as a face in HEX8, id=44
1032  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(56).node_id(0),
1033  _mesh->elem_ref(44).node_id(4) );
1034  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(56).node_id(1),
1035  _mesh->elem_ref(44).node_id(5) );
1036  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(56).node_id(2),
1037  _mesh->elem_ref(44).node_id(6) );
1038  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(56).node_id(3),
1039  _mesh->elem_ref(44).node_id(7) );
1040 
1041  // QUAD4,id=56 should have same nodes as a face in HEX8, id=48
1042  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(56).node_id(0),
1043  _mesh->elem_ref(48).node_id(0) );
1044  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(56).node_id(1),
1045  _mesh->elem_ref(48).node_id(1) );
1046  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(56).node_id(2),
1047  _mesh->elem_ref(48).node_id(2) );
1048  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(56).node_id(3),
1049  _mesh->elem_ref(48).node_id(3) );
1050 
1051  // Shared node between the QUAD4 elements should have the same global id
1052  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(53).node_id(1),
1053  _mesh->elem_ref(54).node_id(0) );
1054  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(53).node_id(2),
1055  _mesh->elem_ref(54).node_id(3) );
1056  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(53).node_id(3),
1057  _mesh->elem_ref(55).node_id(0) );
1058  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(53).node_id(2),
1059  _mesh->elem_ref(55).node_id(1) );
1060  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(54).node_id(3),
1061  _mesh->elem_ref(56).node_id(0) );
1062  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(54).node_id(2),
1063  _mesh->elem_ref(56).node_id(1) );
1064  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(55).node_id(1),
1065  _mesh->elem_ref(56).node_id(0) );
1066  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(55).node_id(2),
1067  _mesh->elem_ref(56).node_id(3) );
1068 
1069  // QUAD4 child elements should have the correct parent
1070  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(53).parent(),
1071  _mesh->elem_ptr(36) );
1072  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(54).parent(),
1073  _mesh->elem_ptr(36) );
1074  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(55).parent(),
1075  _mesh->elem_ptr(36) );
1076  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(56).parent(),
1077  _mesh->elem_ptr(36) );
1078 
1079  // QUAD4 child elements should have the correct interior_parent
1080  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(53).interior_parent(),
1081  _mesh->elem_ptr(41) );
1082  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(54).interior_parent(),
1083  _mesh->elem_ptr(42) );
1084  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(55).interior_parent(),
1085  _mesh->elem_ptr(43) );
1086  CPPUNIT_ASSERT_EQUAL( _mesh->elem_ref(56).interior_parent(),
1087  _mesh->elem_ptr(44) );
1088 
1089 #endif
1090  }
1091 
1093  {
1094 #ifdef LIBMESH_ENABLE_AMR
1095  LOG_UNIT_TEST;
1096 
1097  EquationSystems es(*_mesh);
1098  es.add_system<LinearImplicitSystem>("TestDofSystem");
1099  es.get_system("TestDofSystem").add_variable("u",FIRST);
1100  es.init();
1101 
1102  DofMap& dof_map = es.get_system("TestDofSystem").get_dof_map();
1103 
1104  //Elements to the left of the QUAD4 elements
1105  std::vector<dof_id_type> elem41_dof_indices, elem42_dof_indices, elem43_dof_indices, elem44_dof_indices;
1106  //Elements to the right of the QUAD4 elements
1107  std::vector<dof_id_type> elem45_dof_indices, elem46_dof_indices, elem47_dof_indices, elem48_dof_indices;
1108  //QUAD4 elements
1109  std::vector<dof_id_type> elem53_dof_indices, elem54_dof_indices, elem55_dof_indices, elem56_dof_indices;
1110 
1111  dof_map.dof_indices( _mesh->elem_ptr(41), elem41_dof_indices );
1112  dof_map.dof_indices( _mesh->elem_ptr(42), elem42_dof_indices );
1113  dof_map.dof_indices( _mesh->elem_ptr(43), elem43_dof_indices );
1114  dof_map.dof_indices( _mesh->elem_ptr(44), elem44_dof_indices );
1115  dof_map.dof_indices( _mesh->elem_ptr(45), elem45_dof_indices );
1116  dof_map.dof_indices( _mesh->elem_ptr(46), elem46_dof_indices );
1117  dof_map.dof_indices( _mesh->elem_ptr(47), elem47_dof_indices );
1118  dof_map.dof_indices( _mesh->elem_ptr(48), elem48_dof_indices );
1119  dof_map.dof_indices( _mesh->elem_ptr(53), elem53_dof_indices );
1120  dof_map.dof_indices( _mesh->elem_ptr(54), elem54_dof_indices );
1121  dof_map.dof_indices( _mesh->elem_ptr(55), elem55_dof_indices );
1122  dof_map.dof_indices( _mesh->elem_ptr(56), elem56_dof_indices );
1123 
1124  /* The dofs for the QUAD4 (ids = 53, 54, 55, and 56) element should be the same
1125  as the face of the HEX8 elements HEX8 (id=41, 42, 43, and 44) left of the
1126  QUAD4 elements. */
1127  CPPUNIT_ASSERT_EQUAL( elem53_dof_indices[0], elem41_dof_indices[4] );
1128  CPPUNIT_ASSERT_EQUAL( elem53_dof_indices[1], elem41_dof_indices[5] );
1129  CPPUNIT_ASSERT_EQUAL( elem53_dof_indices[2], elem41_dof_indices[6] );
1130  CPPUNIT_ASSERT_EQUAL( elem53_dof_indices[3], elem41_dof_indices[7] );
1131 
1132  CPPUNIT_ASSERT_EQUAL( elem54_dof_indices[0], elem42_dof_indices[4] );
1133  CPPUNIT_ASSERT_EQUAL( elem54_dof_indices[1], elem42_dof_indices[5] );
1134  CPPUNIT_ASSERT_EQUAL( elem54_dof_indices[2], elem42_dof_indices[6] );
1135  CPPUNIT_ASSERT_EQUAL( elem54_dof_indices[3], elem42_dof_indices[7] );
1136 
1137  CPPUNIT_ASSERT_EQUAL( elem55_dof_indices[0], elem43_dof_indices[4] );
1138  CPPUNIT_ASSERT_EQUAL( elem55_dof_indices[1], elem43_dof_indices[5] );
1139  CPPUNIT_ASSERT_EQUAL( elem55_dof_indices[2], elem43_dof_indices[6] );
1140  CPPUNIT_ASSERT_EQUAL( elem55_dof_indices[3], elem43_dof_indices[7] );
1141 
1142  CPPUNIT_ASSERT_EQUAL( elem56_dof_indices[0], elem44_dof_indices[4] );
1143  CPPUNIT_ASSERT_EQUAL( elem56_dof_indices[1], elem44_dof_indices[5] );
1144  CPPUNIT_ASSERT_EQUAL( elem56_dof_indices[2], elem44_dof_indices[6] );
1145  CPPUNIT_ASSERT_EQUAL( elem56_dof_indices[3], elem44_dof_indices[7] );
1146 
1147  /* The dofs for the QUAD4 (ids = 53, 54, 55, and 56) element should be the same
1148  as the face of the HEX8 elements HEX8 (id=45, 46, 47, and 49) left of the
1149  QUAD4 elements. */
1150  CPPUNIT_ASSERT_EQUAL( elem53_dof_indices[0], elem45_dof_indices[0] );
1151  CPPUNIT_ASSERT_EQUAL( elem53_dof_indices[1], elem45_dof_indices[1] );
1152  CPPUNIT_ASSERT_EQUAL( elem53_dof_indices[2], elem45_dof_indices[2] );
1153  CPPUNIT_ASSERT_EQUAL( elem53_dof_indices[3], elem45_dof_indices[3] );
1154 
1155  CPPUNIT_ASSERT_EQUAL( elem54_dof_indices[0], elem46_dof_indices[0] );
1156  CPPUNIT_ASSERT_EQUAL( elem54_dof_indices[1], elem46_dof_indices[1] );
1157  CPPUNIT_ASSERT_EQUAL( elem54_dof_indices[2], elem46_dof_indices[2] );
1158  CPPUNIT_ASSERT_EQUAL( elem54_dof_indices[3], elem46_dof_indices[3] );
1159 
1160  CPPUNIT_ASSERT_EQUAL( elem55_dof_indices[0], elem47_dof_indices[0] );
1161  CPPUNIT_ASSERT_EQUAL( elem55_dof_indices[1], elem47_dof_indices[1] );
1162  CPPUNIT_ASSERT_EQUAL( elem55_dof_indices[2], elem47_dof_indices[2] );
1163  CPPUNIT_ASSERT_EQUAL( elem55_dof_indices[3], elem47_dof_indices[3] );
1164 
1165  CPPUNIT_ASSERT_EQUAL( elem56_dof_indices[0], elem48_dof_indices[0] );
1166  CPPUNIT_ASSERT_EQUAL( elem56_dof_indices[1], elem48_dof_indices[1] );
1167  CPPUNIT_ASSERT_EQUAL( elem56_dof_indices[2], elem48_dof_indices[2] );
1168  CPPUNIT_ASSERT_EQUAL( elem56_dof_indices[3], elem48_dof_indices[3] );
1169 
1170  /* The dofs for the HEX8 elements (id=41, 42, 43, and 44) should be the same
1171  on the left side of the QUAD4 elements as the HEX8 elements (id=45, 46, 47, and 48)
1172  on the right as QUAD4 elements. */
1173  CPPUNIT_ASSERT_EQUAL( elem41_dof_indices[4], elem45_dof_indices[0] );
1174  CPPUNIT_ASSERT_EQUAL( elem41_dof_indices[5], elem45_dof_indices[1] );
1175  CPPUNIT_ASSERT_EQUAL( elem41_dof_indices[6], elem45_dof_indices[2] );
1176  CPPUNIT_ASSERT_EQUAL( elem41_dof_indices[7], elem45_dof_indices[3] );
1177 
1178  CPPUNIT_ASSERT_EQUAL( elem42_dof_indices[4], elem46_dof_indices[0] );
1179  CPPUNIT_ASSERT_EQUAL( elem42_dof_indices[5], elem46_dof_indices[1] );
1180  CPPUNIT_ASSERT_EQUAL( elem42_dof_indices[6], elem46_dof_indices[2] );
1181  CPPUNIT_ASSERT_EQUAL( elem42_dof_indices[7], elem46_dof_indices[3] );
1182 
1183  CPPUNIT_ASSERT_EQUAL( elem43_dof_indices[4], elem47_dof_indices[0] );
1184  CPPUNIT_ASSERT_EQUAL( elem43_dof_indices[5], elem47_dof_indices[1] );
1185  CPPUNIT_ASSERT_EQUAL( elem43_dof_indices[6], elem47_dof_indices[2] );
1186  CPPUNIT_ASSERT_EQUAL( elem43_dof_indices[7], elem47_dof_indices[3] );
1187 
1188  CPPUNIT_ASSERT_EQUAL( elem44_dof_indices[4], elem48_dof_indices[0] );
1189  CPPUNIT_ASSERT_EQUAL( elem44_dof_indices[5], elem48_dof_indices[1] );
1190  CPPUNIT_ASSERT_EQUAL( elem44_dof_indices[6], elem48_dof_indices[2] );
1191  CPPUNIT_ASSERT_EQUAL( elem44_dof_indices[7], elem48_dof_indices[3] );
1192 
1193  /* The dofs for the QUAD4 elements (ids = 53, 54, 55, and 56) should be the
1194  same for shared nodes. */
1195  CPPUNIT_ASSERT_EQUAL( elem53_dof_indices[1], elem54_dof_indices[0] );
1196  CPPUNIT_ASSERT_EQUAL( elem53_dof_indices[2], elem54_dof_indices[3] );
1197  CPPUNIT_ASSERT_EQUAL( elem53_dof_indices[3], elem55_dof_indices[0] );
1198  CPPUNIT_ASSERT_EQUAL( elem53_dof_indices[2], elem55_dof_indices[1] );
1199  CPPUNIT_ASSERT_EQUAL( elem53_dof_indices[2], elem56_dof_indices[0] );
1200  CPPUNIT_ASSERT_EQUAL( elem54_dof_indices[3], elem55_dof_indices[1] );
1201  CPPUNIT_ASSERT_EQUAL( elem54_dof_indices[3], elem56_dof_indices[0] );
1202  CPPUNIT_ASSERT_EQUAL( elem54_dof_indices[2], elem56_dof_indices[1] );
1203  CPPUNIT_ASSERT_EQUAL( elem55_dof_indices[1], elem56_dof_indices[0] );
1204  CPPUNIT_ASSERT_EQUAL( elem55_dof_indices[2], elem56_dof_indices[3] );
1205 
1206 
1207 #endif
1208  }
1209 };
1210 
1211 
CPPUNIT_TEST_SUITE_REGISTRATION(MixedDimensionMeshTest)
This is the EquationSystems class.
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2558
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2164
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
std::unique_ptr< ReplicatedMesh > _mesh
The libMesh namespace provides an interface to certain functionality in the library.
const T_sys & get_system(std::string_view name) const
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
Implements (adaptive) mesh refinement algorithms for a MeshBase.
dof_id_type id() const
Definition: dof_object.h:828
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition: elem.C:444
std::unique_ptr< ReplicatedMesh > _mesh
std::unique_ptr< ReplicatedMesh > _mesh
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
subdomain_id_type subdomain_id() const
Definition: elem.h:2582
bool refine_and_coarsen_elements()
Refines and coarsens user-requested elements.
std::unique_ptr< ReplicatedMesh > _mesh
virtual void init()
Initialize all the systems.
virtual System & add_system(std::string_view system_type, std::string_view name)
Add the system of type system_type named name to the systems array.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.