1 #include <libmesh/equation_systems.h>
2 #include <libmesh/mesh.h>
3 #include <libmesh/mesh_generation.h>
4 #include <libmesh/elem.h>
5 #include <libmesh/dof_map.h>
6 
7 #include "test_comm.h"
8 #include "libmesh_cppunit.h"
9 
10 
11 using namespace libMesh;
12 
13 #ifdef LIBMESH_ENABLE_CONSTRAINTS
14 // This class is used by testConstraintLoopDetection
15 class MyConstraint : public System::Constraint
16 {
17 private:
18 
19   System & _sys;
20 
21 public:
22 
MyConstraint(System & sys)23   MyConstraint( System & sys ) : Constraint(), _sys(sys) {}
24 
~MyConstraint()25   virtual ~MyConstraint() {}
26 
constrain()27   void constrain()
28   {
29     {
30       const dof_id_type constrained_dof_index = 0;
31       DofConstraintRow constraint_row;
32       constraint_row[1] = 1.0;
33       _sys.get_dof_map().add_constraint_row( constrained_dof_index, constraint_row, 0., true);
34     }
35     {
36       const dof_id_type constrained_dof_index = 1;
37       DofConstraintRow constraint_row;
38       constraint_row[0] = 1.0;
39       _sys.get_dof_map().add_constraint_row( constrained_dof_index, constraint_row, 0., true);
40     }
41   }
42 };
43 #endif
44 
45 
46 class DofMapTest : public CppUnit::TestCase {
47 public:
48   CPPUNIT_TEST_SUITE( DofMapTest );
49 
50   CPPUNIT_TEST( testDofOwnerOnEdge3 );
51 #if LIBMESH_DIM > 1
52   CPPUNIT_TEST( testDofOwnerOnQuad9 );
53   CPPUNIT_TEST( testDofOwnerOnTri6 );
54 #endif
55 #if LIBMESH_DIM > 2
56   CPPUNIT_TEST( testDofOwnerOnHex27 );
57 #endif
58 
59 #if defined(LIBMESH_ENABLE_CONSTRAINTS) && defined(LIBMESH_ENABLE_EXCEPTIONS) && LIBMESH_DIM > 1
60   CPPUNIT_TEST( testConstraintLoopDetection );
61 #endif
62 
63   CPPUNIT_TEST_SUITE_END();
64 
65 private:
66 
67 public:
setUp()68   void setUp()
69   {}
70 
tearDown()71   void tearDown()
72   {}
73 
testDofOwner(const ElemType elem_type)74   void testDofOwner(const ElemType elem_type)
75   {
76     Mesh mesh(*TestCommWorld);
77 
78     EquationSystems es(mesh);
79     System &sys = es.add_system<System> ("SimpleSystem");
80     sys.add_variable("u", THIRD, HIERARCHIC);
81 
82     const unsigned int n_elem_per_side = 3;
83     const std::unique_ptr<Elem> test_elem = Elem::build(elem_type);
84     const unsigned int ymax = test_elem->dim() > 1;
85     const unsigned int zmax = test_elem->dim() > 2;
86     const unsigned int ny = ymax * n_elem_per_side;
87     const unsigned int nz = zmax * n_elem_per_side;
88 
89     MeshTools::Generation::build_cube (mesh,
90                                        n_elem_per_side,
91                                        ny,
92                                        nz,
93                                        0., 1.,
94                                        0., ymax,
95                                        0., zmax,
96                                        elem_type);
97 
98     es.init();
99 
100     DofMap & dof_map = sys.get_dof_map();
101     for (dof_id_type id = 0; id != dof_map.n_dofs(); ++id)
102       {
103         const processor_id_type pid = dof_map.dof_owner(id);
104         CPPUNIT_ASSERT(dof_map.first_dof(pid) <= id);
105         CPPUNIT_ASSERT(id < dof_map.end_dof(pid));
106       }
107   }
108 
109 
110 
testDofOwnerOnEdge3()111   void testDofOwnerOnEdge3() { testDofOwner(EDGE3); }
testDofOwnerOnQuad9()112   void testDofOwnerOnQuad9() { testDofOwner(QUAD9); }
testDofOwnerOnTri6()113   void testDofOwnerOnTri6()  { testDofOwner(TRI6); }
testDofOwnerOnHex27()114   void testDofOwnerOnHex27() { testDofOwner(HEX27); }
115 
116 #if defined(LIBMESH_ENABLE_CONSTRAINTS) && defined(LIBMESH_ENABLE_EXCEPTIONS)
testConstraintLoopDetection()117   void testConstraintLoopDetection()
118   {
119     Mesh mesh(*TestCommWorld);
120 
121     EquationSystems es(mesh);
122     System & sys = es.add_system<System> ("SimpleSystem");
123     sys.add_variable("u", FIRST);
124 
125     MyConstraint my_constraint(sys);
126     sys.attach_constraint_object(my_constraint);
127 
128     MeshTools::Generation::build_square (mesh,4,4,-1., 1.,-1., 1., QUAD4);
129 
130     // Tell the dof_map to check for constraint loops
131     DofMap & dof_map = sys.get_dof_map();
132     dof_map.set_error_on_constraint_loop(true);
133 
134     CPPUNIT_ASSERT_THROW_MESSAGE("Constraint loop not detected", es.init(), libMesh::LogicError);
135   }
136 #endif
137 
138 };
139 
140 CPPUNIT_TEST_SUITE_REGISTRATION( DofMapTest );
141