libMesh
dof_map_test.C
Go to the documentation of this file.
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 
8 
9 #include "test_comm.h"
10 #include "libmesh_cppunit.h"
11 
12 #include <regex>
13 #include <string>
14 
15 using namespace libMesh;
16 
17 #ifdef LIBMESH_ENABLE_CONSTRAINTS
18 // This class is used by testConstraintLoopDetection
20 {
21 private:
22 
24 
25 public:
26 
27  MyConstraint( System & sys ) : Constraint(), _sys(sys) {}
28 
29  virtual ~MyConstraint() {}
30 
31  void constrain()
32  {
33  {
34  const dof_id_type constrained_dof_index = 0;
35  DofConstraintRow constraint_row;
36  constraint_row[1] = 1.0;
37  _sys.get_dof_map().add_constraint_row( constrained_dof_index, constraint_row, 0., true);
38  }
39  {
40  const dof_id_type constrained_dof_index = 1;
41  DofConstraintRow constraint_row;
42  constraint_row[0] = 1.0;
43  _sys.get_dof_map().add_constraint_row( constrained_dof_index, constraint_row, 0., true);
44  }
45  }
46 };
47 #endif
48 
49 
50 class DofMapTest : public CppUnit::TestCase {
51 public:
52  LIBMESH_CPPUNIT_TEST_SUITE( DofMapTest );
53 
54  CPPUNIT_TEST( testDofOwnerOnEdge3 );
55 #if LIBMESH_DIM > 1
56  CPPUNIT_TEST( testDofOwnerOnQuad9 );
57  CPPUNIT_TEST( testDofOwnerOnTri6 );
58 #endif
59 #if LIBMESH_DIM > 2
60  CPPUNIT_TEST( testDofOwnerOnHex27 );
61 #endif
62 
63 #if defined(LIBMESH_ENABLE_EXCEPTIONS)
64  CPPUNIT_TEST( testBadElemFECombo );
65 #endif
66 
67 #if defined(LIBMESH_ENABLE_CONSTRAINTS) && defined(LIBMESH_ENABLE_EXCEPTIONS) && LIBMESH_DIM > 1
68  CPPUNIT_TEST( testConstraintLoopDetection );
69 #endif
70 
71  CPPUNIT_TEST_SUITE_END();
72 
73 private:
74 
75 public:
76  void setUp()
77  {}
78 
79  void tearDown()
80  {}
81 
82  void testDofOwner(const ElemType elem_type)
83  {
85 
87  System &sys = es.add_system<System> ("SimpleSystem");
88  sys.add_variable("u", THIRD, HIERARCHIC);
89 
90  const unsigned int n_elem_per_side = 3;
91  const std::unique_ptr<Elem> test_elem = Elem::build(elem_type);
92  const unsigned int ymax = test_elem->dim() > 1;
93  const unsigned int zmax = test_elem->dim() > 2;
94  const unsigned int ny = ymax * n_elem_per_side;
95  const unsigned int nz = zmax * n_elem_per_side;
96 
98  n_elem_per_side,
99  ny,
100  nz,
101  0., 1.,
102  0., ymax,
103  0., zmax,
104  elem_type);
105 
106  es.init();
107 
108  DofMap & dof_map = sys.get_dof_map();
109  for (dof_id_type id = 0; id != dof_map.n_dofs(); ++id)
110  {
111  const processor_id_type pid = dof_map.dof_owner(id);
112  CPPUNIT_ASSERT(dof_map.first_dof(pid) <= id);
113  CPPUNIT_ASSERT(id < dof_map.end_dof(pid));
114  }
115  }
116 
117 
118 
119  void testDofOwnerOnEdge3() { LOG_UNIT_TEST; testDofOwner(EDGE3); }
120  void testDofOwnerOnQuad9() { LOG_UNIT_TEST; testDofOwner(QUAD9); }
121  void testDofOwnerOnTri6() { LOG_UNIT_TEST; testDofOwner(TRI6); }
122  void testDofOwnerOnHex27() { LOG_UNIT_TEST; testDofOwner(HEX27); }
123 
124 #if defined(LIBMESH_ENABLE_EXCEPTIONS)
126  {
127  LOG_UNIT_TEST;
128 
130 
131  EquationSystems es(mesh);
132  System & sys = es.add_system<System> ("SimpleSystem");
133  sys.add_variable("u", SECOND);
134 
135  MeshTools::Generation::build_square (mesh,4,4,-1., 1.,-1., 1., QUAD4);
136 
137  // We need at least one element per processor to make sure
138  // everyone throws and we don't get out of sync before going on to
139  // future tests.
140  dof_id_type min_local_elem = mesh.n_local_elem();
141  mesh.comm().min(min_local_elem);
142 
143  if (!min_local_elem)
144  return;
145 
146  // We can't just CPPUNIT_ASSERT_THROW, because we want to make
147  // sure we were thrown from the right place with the right error
148  // message!
149  bool threw_desired_exception = false;
150  try {
151  es.init();
152  }
153  catch (libMesh::LogicError & e) {
154  std::regex msg_regex("only supports FEInterface::max_order");
155  CPPUNIT_ASSERT(std::regex_search(e.what(), msg_regex));
156  threw_desired_exception = true;
157  }
158  catch (...) {
159  CPPUNIT_ASSERT_MESSAGE("Unexpected exception type thrown", false);
160  }
161 
162  // If we have more than 4*4 processors, or a poor partitioner, we
163  // might not get an exception on every processor
164  mesh.comm().max(threw_desired_exception);
165 
166  CPPUNIT_ASSERT(threw_desired_exception);
167  }
168 #endif
169 
170 #if defined(LIBMESH_ENABLE_CONSTRAINTS) && defined(LIBMESH_ENABLE_EXCEPTIONS)
172  {
173  LOG_UNIT_TEST;
175 
176  EquationSystems es(mesh);
177  System & sys = es.add_system<System> ("SimpleSystem");
178  sys.add_variable("u", FIRST);
179 
180  MyConstraint my_constraint(sys);
181  sys.attach_constraint_object(my_constraint);
182 
183  MeshTools::Generation::build_square (mesh,4,4,-1., 1.,-1., 1., QUAD4);
184 
185  // Tell the dof_map to check for constraint loops
186  DofMap & dof_map = sys.get_dof_map();
187  dof_map.set_error_on_constraint_loop(true);
188 
189  CPPUNIT_ASSERT_THROW_MESSAGE("Constraint loop not detected", es.init(), libMesh::LogicError);
190  }
191 #endif
192 
193 };
194 
ElemType
Defines an enum for geometric element types.
dof_id_type end_dof(const processor_id_type proc) const
Definition: dof_map_base.h:191
This is the EquationSystems class.
void testDofOwnerOnQuad9()
Definition: dof_map_test.C:120
processor_id_type dof_owner(const dof_id_type dof) const
Definition: dof_map.h:707
void testConstraintLoopDetection()
Definition: dof_map_test.C:171
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
MeshBase & mesh
const Parallel::Communicator & comm() const
void build_square(UnstructuredMesh &mesh, const unsigned int nx, const unsigned int ny, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 2D meshes.
dof_id_type n_dofs(const unsigned int vn) const
Definition: dof_map.h:668
The libMesh namespace provides an interface to certain functionality in the library.
void set_error_on_constraint_loop(bool error_on_constraint_loop)
Definition: dof_map.C:241
dof_id_type n_local_elem() const
Definition: mesh_base.h:548
void testDofOwnerOnEdge3()
Definition: dof_map_test.C:119
void attach_constraint_object(Constraint &constrain)
Register a user object for imposing constraints.
Definition: system.C:2209
void testDofOwner(const ElemType elem_type)
Definition: dof_map_test.C:82
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
uint8_t processor_id_type
void testDofOwnerOnTri6()
Definition: dof_map_test.C:121
void min(const T &r, T &o, Request &req) const
void add_constraint_row(const dof_id_type dof_number, const DofConstraintRow &constraint_row, const Number constraint_rhs, const bool forbid_constraint_overwrite)
Adds a copy of the user-defined row to the constraint matrix, using an inhomogeneous right-hand-side ...
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:96
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition: elem.C:444
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variable var to the list of variables for this system.
Definition: system.C:1357
System & _sys
Definition: dof_map_test.C:23
void tearDown()
Definition: dof_map_test.C:79
void max(const T &r, T &o, Request &req) const
A class to represent the internal "this should never happen" errors, to be thrown by "libmesh_error()...
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
A row of the Dof constraint matrix.
Definition: dof_map.h:100
void constrain()
Constraint function.
Definition: dof_map_test.C:31
Abstract base class to be used for system constraints.
Definition: system.h:179
void testBadElemFECombo()
Definition: dof_map_test.C:125
virtual void init()
Initialize all the systems.
dof_id_type first_dof(const processor_id_type proc) const
Definition: dof_map_base.h:185
virtual System & add_system(std::string_view system_type, std::string_view name)
Add the system of type system_type named name to the systems array.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
void testDofOwnerOnHex27()
Definition: dof_map_test.C:122
void setUp()
Definition: dof_map_test.C:76
const DofMap & get_dof_map() const
Definition: system.h:2374
CPPUNIT_TEST_SUITE_REGISTRATION(DofMapTest)
void build_cube(UnstructuredMesh &mesh, const unsigned int nx=0, const unsigned int ny=0, const unsigned int nz=0, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const Real zmin=0., const Real zmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
Builds a (elements) cube.
MyConstraint(System &sys)
Definition: dof_map_test.C:27
uint8_t dof_id_type
Definition: id_types.h:67
virtual ~MyConstraint()
Definition: dof_map_test.C:29