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