libMesh
Loading...
Searching...
No Matches
equation_systems_test.C
Go to the documentation of this file.
1#include <libmesh/dof_map.h>
2#include <libmesh/elem.h>
3#include <libmesh/equation_systems.h>
4#include <libmesh/ghost_point_neighbors.h>
5#include <libmesh/mesh.h>
6#include <libmesh/mesh_generation.h>
7#include <libmesh/mesh_refinement.h>
8#include <libmesh/remote_elem.h>
9#include <libmesh/replicated_mesh.h>
10#include <libmesh/node_elem.h>
11
12#include "test_comm.h"
13#include "libmesh_cppunit.h"
14
15
16using namespace libMesh;
17
18// Anonymous namespace to avoid linker conflicts
19namespace {
20
21Number bilinear_test (const Point& p,
22 const Parameters&,
23 const std::string&,
24 const std::string&)
25{
26 const Real & x = p(0);
27 const Real & y = p(1);
28
29 return 4*x*y - 3*x + 2*y - 1;
30}
31
32}
33
34class EquationSystemsTest : public CppUnit::TestCase {
35public:
37
45#if LIBMESH_DIM > 1
47#ifdef LIBMESH_ENABLE_AMR // needs project_solution, even for reordering
50#endif
51#endif
53
55
56private:
57
58public:
59 void setUp()
60 {}
61
62 void tearDown()
63 {}
64
65
66
68 {
69 LOG_UNIT_TEST;
70
73 }
74
76 {
77 LOG_UNIT_TEST;
78
81 /*System &sys = */es.add_system<System> ("SimpleSystem");
82 }
83
84 void testInit()
85 {
86 LOG_UNIT_TEST;
87
90 /*System &sys = */es.add_system<System> ("SimpleSystem");
92 es.init();
93 }
94
96 {
97 LOG_UNIT_TEST;
98
102 /*System &sys1 = */es.add_system<System> ("SimpleSystem");
103 es.init();
104 /*System &sys2 = */es.add_system<System> ("SecondSystem");
105 es.reinit();
106 }
107
109 {
110 LOG_UNIT_TEST;
111
115 System &sys1 = es.add_system<System> ("SimpleSystem");
116 sys1.add_variable("u1", FIRST);
117 es.init();
118 System &sys2 = es.add_system<System> ("SecondSystem");
119 sys2.add_variable("u2", FIRST);
120 es.reinit();
121 }
122
124 {
125 LOG_UNIT_TEST;
126
128
130 System &sys = es.add_system<System> ("SimpleSystem");
131 sys.add_variable("u", FIRST);
132
134 es.init();
135
137 e->processor_id() = 0;
138 e->set_node(0, mesh.node_ptr(2));
139 e->set_node(1, mesh.node_ptr(8));
141
142 es.reinit();
143 }
144
146 {
147#ifdef LIBMESH_ENABLE_EXCEPTIONS
148 LOG_UNIT_TEST;
149
153 System &sys1 = es.add_system<System> ("SimpleSystem");
154 sys1.add_variable("u", FIRST, MONOMIAL_VEC);
155 es.init();
156
157 const FEType & fe_type = sys1.variable_type ("u");
158 std::vector<std::string> var_names;
159 std::set<std::string> system_names = {"SimpleSystem"};
160 es.build_variable_names(var_names, &fe_type);
161
162 System &sys2 = es.add_system<System> ("SecondSystem");
163 sys2.add_variable("u_x", FIRST);
164 sys2.add_variable("u_y", FIRST);
165 sys2.add_variable("u_z", FIRST);
166 es.reinit();
167
168 var_names.clear();
169 CPPUNIT_ASSERT_THROW_MESSAGE("Duplicate var names not detected",
170 es.build_variable_names(var_names,
171 &fe_type),
173#endif // LIBMESH_ENABLE_EXCEPTIONS
174 }
175
177 {
178 LOG_UNIT_TEST;
179
181
183 auto node_elem = mesh.add_elem(Elem::build(NODEELEM));
184 node_elem->set_node(0, mesh.node_ptr(0));
186
188 System &sys = es.add_system<System> ("SimpleSystem");
189 sys.add_variable("u", CONSTANT, MONOMIAL);
190 es.init();
191 es.reinit();
192 }
193
195 {
196 // This test requires AMR support since it sets refinement flags.
197#ifdef LIBMESH_ENABLE_AMR
198 LOG_UNIT_TEST;
199
201 mesh.allow_renumbering(false);
203 System & sys = es.add_system<System> ("SimpleSystem");
204 sys.add_variable("u", FIRST);
206 es.init();
207
208 Elem * to_refine = mesh.query_elem_ptr(0);
209 if (to_refine)
211
213 mr.refine_elements();
215 es.reinit();
216
217 if (mesh.query_elem_ptr(1))
218 CPPUNIT_ASSERT( mesh.elem_ptr(1)->active() );
219
220 const Elem * elem = mesh.query_elem_ptr(0);
221 if (elem)
222 {
223 CPPUNIT_ASSERT_EQUAL( Elem::INACTIVE,elem->refinement_flag() );
224
225 for (unsigned int c=0; c<elem->n_children(); c++)
226 if (elem->child_ptr(c) != remote_elem)
227 CPPUNIT_ASSERT_EQUAL(Elem::JUST_REFINED,
228 elem->child_ptr(c)->refinement_flag());
229 }
230#endif
231 }
232
233
235 {
236 // This test requires AMR support since it sets refinement flags.
237#ifdef LIBMESH_ENABLE_AMR
238 LOG_UNIT_TEST;
239
242 System & sys = es.add_system<System> ("SimpleSystem");
243 const auto un = sys.add_variable("u", FIRST);
244 const auto vn = sys.add_variable("v", CONSTANT, MONOMIAL);
246 es.init();
247 auto & dof_map = sys.get_dof_map();
248 const auto ug = dof_map.var_group_from_var_number(un);
249 const auto vg = dof_map.var_group_from_var_number(vn);
250 dof_map.should_p_refine(ug, false);
251 dof_map.should_p_refine(vg, true);
252
253 Elem * to_refine = mesh.query_elem_ptr(0);
254 if (to_refine)
256
259 mr.refine_elements();
261 es.reinit();
262
263 CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), dof_id_type(1));
264 const Elem * elem = mesh.query_elem_ptr(0);
265 if (elem)
266 {
267 std::vector<dof_id_type> dof_indices;
268 dof_map.dof_indices(elem, dof_indices, un);
269 CPPUNIT_ASSERT_EQUAL(dof_indices.size(), std::size_t(2));
270 dof_map.dof_indices(elem, dof_indices, vn);
271 CPPUNIT_ASSERT_EQUAL(dof_indices.size(), std::size_t(2));
272 }
273#endif
274 }
275
276
278 {
279 LOG_UNIT_TEST;
280
282 mesh.allow_renumbering(false);
284 System & sys = es.add_system<System> ("SimpleSystem");
285 sys.add_variable("u", FIRST);
287 es.init();
288 sys.project_solution(bilinear_test, NULL, es.parameters);
289
290 // Force (in parallel) a different partitioning - we'll simply put
291 // everything on rank 0, which hopefully is not what our default
292 // partitioner did!
293 mesh.partition(1);
294
295 // Make sure the solution is still intact after reinit
296 es.reinit();
297
298 for (Real x = 0.1; x < 1; x += 0.2)
299 for (Real y = 0.1; y < 1; y += 0.2)
300 {
301 Point p(x,y);
302 LIBMESH_ASSERT_NUMBERS_EQUAL
303 (sys.point_value(0,p),
304 bilinear_test(p,es.parameters,"",""),
306 }
307 }
308
310 {
311 LOG_UNIT_TEST;
312
315
316 auto n_ghosts = [&mesh]() {
317 return int(std::distance(mesh.ghosting_functors_begin(),
319 };
320
321 auto n_evaluables = [](System &sys) {
322 return int(std::distance(sys.get_dof_map().algebraic_ghosting_functors_begin(),
323 sys.get_dof_map().algebraic_ghosting_functors_end()));
324 };
325
326 auto n_couplings = [](System &sys) {
327 return int(std::distance(sys.get_dof_map().coupling_functors_begin(),
328 sys.get_dof_map().coupling_functors_end()));
329 };
330
331 // One default ghosting functor on the mesh
332 CPPUNIT_ASSERT_EQUAL(n_ghosts(), 1);
333
334 // Add another functor, making two
335 auto gpn = std::make_shared<GhostPointNeighbors>(mesh);
337 CPPUNIT_ASSERT_EQUAL(n_ghosts(), 2);
338
339 // Remove the default, leaving just the user functor
340 es.enable_default_ghosting(false);
341 CPPUNIT_ASSERT_EQUAL(n_ghosts(), 1);
342
343 // Which can be removed too
345 CPPUNIT_ASSERT_EQUAL(n_ghosts(), 0);
346
347 // Adding a new system shouldn't add any default ghosting if the
348 // EquationSystems disabled it
349 System & sys1 = es.add_system<System>("System1");
350 CPPUNIT_ASSERT_EQUAL(n_ghosts(), 0);
351 CPPUNIT_ASSERT_EQUAL(n_evaluables(sys1), 0);
352 CPPUNIT_ASSERT_EQUAL(n_couplings(sys1), 0);
353
354 // But if we reenable it then now we should have three functors,
355 // with the default algebraic and coupling functors from sys1.
356 //
357 // We currently iterate over coupling functors manually even when
358 // using them for evaluability... this test will need to change
359 // eventually, when that does.
361 CPPUNIT_ASSERT_EQUAL(n_ghosts(), 3);
362 CPPUNIT_ASSERT_EQUAL(n_evaluables(sys1), 1);
363 CPPUNIT_ASSERT_EQUAL(n_couplings(sys1), 1);
364
365 // Adding a second system with default ghosting reenabled should
366 // give us 2 more functors.
367 System & sys2 = es.add_system<System>("System2");
368 CPPUNIT_ASSERT_EQUAL(n_ghosts(), 5);
369 CPPUNIT_ASSERT_EQUAL(n_evaluables(sys2), 1);
370 CPPUNIT_ASSERT_EQUAL(n_couplings(sys2), 1);
371
372 // Adding a user functor to evaluables and couplings should add it
373 // to the mesh
376 CPPUNIT_ASSERT_EQUAL(n_ghosts(), 6);
377 CPPUNIT_ASSERT_EQUAL(n_evaluables(sys1), 2);
378 CPPUNIT_ASSERT_EQUAL(n_couplings(sys1), 1);
379
380 // Unless we say not to.
381 auto gpn3 = std::make_shared<GhostPointNeighbors>(mesh);
382 sys1.get_dof_map().add_coupling_functor(gpn3, /*to_mesh=*/false);
383 CPPUNIT_ASSERT_EQUAL(n_ghosts(), 6);
384 CPPUNIT_ASSERT_EQUAL(n_evaluables(sys1), 2);
385 CPPUNIT_ASSERT_EQUAL(n_couplings(sys1), 2);
386
387 // Turning off default coupling again should get rid of everything
388 // except the user functors.
389 es.enable_default_ghosting(false);
390 CPPUNIT_ASSERT_EQUAL(n_ghosts(), 1);
391 CPPUNIT_ASSERT_EQUAL(n_evaluables(sys1), 1);
392 CPPUNIT_ASSERT_EQUAL(n_couplings(sys1), 1);
393 CPPUNIT_ASSERT_EQUAL(n_evaluables(sys2), 0);
394 CPPUNIT_ASSERT_EQUAL(n_couplings(sys2), 0);
395 }
396
397
398
399
400
401};
402
void ErrorVector unsigned int
CPPUNIT_TEST(testRepartitionThenReinit)
CPPUNIT_TEST(testSelectivePRefine)
CPPUNIT_TEST(testPostInitAddElem)
CPPUNIT_TEST(testDisableDefaultGhosting)
LIBMESH_CPPUNIT_TEST_SUITE(EquationSystemsTest)
CPPUNIT_TEST(testReinitWithNodeElem)
CPPUNIT_TEST(testAddSystem)
CPPUNIT_TEST(testRefineThenReinitPreserveFlags)
CPPUNIT_TEST(testInit)
CPPUNIT_TEST(testBadVarNames)
CPPUNIT_TEST(testPostInitAddSystem)
CPPUNIT_TEST(testConstruction)
unsigned int var_group_from_var_number(unsigned int var_num) const
Definition dof_map.h:2600
void add_algebraic_ghosting_functor(GhostingFunctor &evaluable_functor, bool to_mesh=true)
Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors.
Definition dof_map.C:2062
void add_coupling_functor(GhostingFunctor &coupling_functor, bool to_mesh=true)
Adds a functor which can specify coupling requirements for creation of sparse matrices.
Definition dof_map.C:2005
processor_id_type processor_id() const
Definition dof_object.h:881
This is the base class from which all geometric element types are derived.
Definition elem.h:96
virtual Node *& set_node(const unsigned int i)
Definition elem.h:2567
RefinementState refinement_flag() const
Definition elem.h:3227
bool active() const
Definition elem.h:2958
static std::unique_ptr< Elem > build_with_id(const ElemType type, dof_id_type id)
Calls the build() method above with a nullptr parent, and additionally sets the newly-created Elem's ...
Definition elem.C:556
const Elem * child_ptr(unsigned int i) const
Definition elem.h:3180
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition elem.C:442
virtual unsigned int n_children() const =0
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition elem.h:3235
This is the EquationSystems class.
virtual void reinit()
Handle any mesh changes and reinitialize all the systems on the updated mesh.
void build_variable_names(std::vector< std::string > &var_names, const FEType *type=nullptr, const std::set< std::string > *system_names=nullptr) const
Fill the input vector var_names with the names of the variables for each system.
Parameters parameters
Data structure holding arbitrary parameters.
virtual void init()
Initialize all the systems.
virtual System & add_system(std::string_view system_type, std::string_view name)
Add the system of type system_type named name to the systems array.
virtual void enable_default_ghosting(bool enable)
Enable or disable default ghosting functors on the Mesh and on all Systems.
void disable_refine_in_reinit()
Calls to reinit() will not try to coarsen or refine the mesh.
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition fe_type.h:197
This class implements the original default geometry ghosting requirements in libMesh: point neighbors...
A class to represent the internal "this should never happen" errors, to be thrown by "libmesh_error()...
virtual const Node * node_ptr(const dof_id_type i) const =0
virtual dof_id_type n_elem() const =0
void allow_renumbering(bool allow)
If false is passed in then this mesh will no longer be renumbered when being prepared for use.
Definition mesh_base.h:1355
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly created (or read) mesh for use.
Definition mesh_base.C:824
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition mesh_base.C:1100
GhostingFunctorIterator ghosting_functors_begin() const
Beginning of range of ghosting functors.
Definition mesh_base.h:1472
virtual const Elem * elem_ptr(const dof_id_type i) const =0
virtual dof_id_type max_elem_id() const =0
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
GhostingFunctorIterator ghosting_functors_end() const
End of range of ghosting functors.
Definition mesh_base.h:1478
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
Definition mesh_base.C:1078
virtual void partition(const unsigned int n_parts)
Call the default partitioner (currently metis_partition()).
Definition mesh_base.C:1769
Implements (adaptive) mesh refinement algorithms for a MeshBase.
void switch_h_to_p_refinement()
Takes a mesh whose elements are flagged for h refinement and coarsening, and switches those flags to ...
bool refine_elements()
Only refines the user-requested elements.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition mesh.h:51
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition parameters.h:75
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition system.h:100
void project_solution(FunctionBase< Number > *f, FunctionBase< Gradient > *g=nullptr, std::optional< ConstElemRange > active_local_range=std::nullopt, std::optional< std::vector< unsigned int > > variable_numbers=std::nullopt) const
Projects arbitrary functions onto the current solution.
Number point_value(unsigned int var, const Point &p, const bool insist_on_success=true, const NumericVector< Number > *sol=nullptr) const
Definition system.C:2219
const FEType & variable_type(const unsigned int i) const
Definition system.C:2721
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:1344
const DofMap & get_dof_map() const
Definition system.h:2417
Communicator * TestCommWorld
CPPUNIT_TEST_SUITE_REGISTRATION(EquationSystemsTest)
MeshBase & mesh
void build_point(UnstructuredMesh &mesh, const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 0D meshes.
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.
void build_line(UnstructuredMesh &mesh, const unsigned int nx, const Real xmin=0., const Real xmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 1D meshes.
The libMesh namespace provides an interface to certain functionality in the library.
const RemoteElem * remote_elem
Definition remote_elem.C:57
static constexpr Real TOLERANCE
uint8_t dof_id_type
Definition id_types.h:67
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real