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