libMesh
Loading...
Searching...
No Matches
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
SlitMeshRefinedSystemTest Class Reference
Inheritance diagram for SlitMeshRefinedSystemTest:
[legend]

Public Member Functions

 LIBMESH_CPPUNIT_TEST_SUITE (SlitMeshRefinedSystemTest)
 The goal of this test is the same as the previous, but now we create a system and set dof values to make sure they are properly interpolated after refinement.
 
 CPPUNIT_TEST (testMesh)
 
 CPPUNIT_TEST (testSystem)
 
 CPPUNIT_TEST (testRestart)
 
 CPPUNIT_TEST_SUITE_END ()
 
void setUp ()
 
void tearDown ()
 
void testMesh ()
 
void testSystem ()
 
void testRestart ()
 
 LIBMESH_CPPUNIT_TEST_SUITE (SlitMeshTest)
 The goal of this test is to ensure that a 2D mesh with nodes overlapping on opposite sides of an internal, "slit" edge is usable.
 

Protected Member Functions

void build_mesh ()
 

Protected Attributes

System_sys
 
std::unique_ptr< EquationSystems_es
 
std::unique_ptr< Mesh_mesh
 

Detailed Description

Definition at line 268 of file slit_mesh_test.C.

Member Function Documentation

◆ build_mesh()

void SlitMeshTest::build_mesh ( )
inlineprotectedinherited

Definition at line 90 of file slit_mesh_test.C.

91 {
92 _mesh = std::make_unique<Mesh>(*TestCommWorld);
93
94 // (-1,1) (0,1) (1,1) (2,1) (3,1)
95 // o----------o----------o----------o----------o
96 // | | | | |
97 // | | | | |
98 // | | | | |
99 // | | | | |
100 // o----------o==========8==========o----------o
101 // (-1,0) (0,0) (1,0) (2,0) (3,0)
102 // | | | | |
103 // | | | | |
104 // | | | | |
105 // o----------o----------o----------o----------o
106 // (-1,-1) (0,-1) (1,-1) (2,-1) (3,-1)
107
108 _mesh->set_mesh_dimension(2);
109
110 _mesh->add_point( Point(0.0, 0.0), 0 );
111 _mesh->add_point( Point(1.0, 0.0), 1 );
112 _mesh->add_point( Point(1.0, 1.0), 2 );
113 _mesh->add_point( Point(0.0, 1.0), 3 );
114 _mesh->add_point( Point(0.0,-1.0), 4 );
115 _mesh->add_point( Point(1.0,-1.0), 5 );
116 _mesh->add_point( Point(1.0, 0.0), 6 ); // Doubled!
117 _mesh->add_point( Point(2.0, 0.0), 7 );
118 _mesh->add_point( Point(2.0, 1.0), 8 );
119 _mesh->add_point( Point(2.0,-1.0), 9 );
120 _mesh->add_point( Point(-1.0,-1.0), 10);
121 _mesh->add_point( Point(-1.0, 0.0), 11);
122 _mesh->add_point( Point(-1.0, 1.0), 12);
123 _mesh->add_point( Point(3.0,-1.0), 13);
124 _mesh->add_point( Point(3.0, 0.0), 14);
125 _mesh->add_point( Point(3.0, 1.0), 15);
126
127 {
128 Elem * elem_top_left = _mesh->add_elem(Elem::build_with_id(QUAD4, 0));
129 elem_top_left->set_node(0, _mesh->node_ptr(0));
130 elem_top_left->set_node(1, _mesh->node_ptr(1));
131 elem_top_left->set_node(2, _mesh->node_ptr(2));
132 elem_top_left->set_node(3, _mesh->node_ptr(3));
133
134 Elem * elem_bottom_left = _mesh->add_elem(Elem::build_with_id(QUAD4, 1));
135 elem_bottom_left->set_node(0, _mesh->node_ptr(4));
136 elem_bottom_left->set_node(1, _mesh->node_ptr(5));
137 elem_bottom_left->set_node(2, _mesh->node_ptr(6));
138 elem_bottom_left->set_node(3, _mesh->node_ptr(0));
139
140 Elem * elem_top_right = _mesh->add_elem(Elem::build_with_id(QUAD4, 2));
141 elem_top_right->set_node(0, _mesh->node_ptr(1));
142 elem_top_right->set_node(1, _mesh->node_ptr(7));
143 elem_top_right->set_node(2, _mesh->node_ptr(8));
144 elem_top_right->set_node(3, _mesh->node_ptr(2));
145
146 Elem * elem_bottom_right = _mesh->add_elem(Elem::build_with_id(QUAD4, 3));
147 elem_bottom_right->set_node(0, _mesh->node_ptr(5));
148 elem_bottom_right->set_node(1, _mesh->node_ptr(9));
149 elem_bottom_right->set_node(2, _mesh->node_ptr(7));
150 elem_bottom_right->set_node(3, _mesh->node_ptr(6));
151
152 Elem * elem_top_leftleft = _mesh->add_elem(Elem::build_with_id(QUAD4, 4));
153 elem_top_leftleft->set_node(0, _mesh->node_ptr(11));
154 elem_top_leftleft->set_node(1, _mesh->node_ptr(0));
155 elem_top_leftleft->set_node(2, _mesh->node_ptr(3));
156 elem_top_leftleft->set_node(3, _mesh->node_ptr(12));
157
158 Elem * elem_bottom_leftleft = _mesh->add_elem(Elem::build_with_id(QUAD4, 5));
159 elem_bottom_leftleft->set_node(0, _mesh->node_ptr(10));
160 elem_bottom_leftleft->set_node(1, _mesh->node_ptr(4));
161 elem_bottom_leftleft->set_node(2, _mesh->node_ptr(0));
162 elem_bottom_leftleft->set_node(3, _mesh->node_ptr(11));
163
164 Elem * elem_top_rightright = _mesh->add_elem(Elem::build_with_id(QUAD4, 6));
165 elem_top_rightright->set_node(0, _mesh->node_ptr(7));
166 elem_top_rightright->set_node(1, _mesh->node_ptr(14));
167 elem_top_rightright->set_node(2, _mesh->node_ptr(15));
168 elem_top_rightright->set_node(3, _mesh->node_ptr(8));
169
170 Elem * elem_bottom_rightright = _mesh->add_elem(Elem::build_with_id(QUAD4, 7));
171 elem_bottom_rightright->set_node(0, _mesh->node_ptr(9));
172 elem_bottom_rightright->set_node(1, _mesh->node_ptr(13));
173 elem_bottom_rightright->set_node(2, _mesh->node_ptr(14));
174 elem_bottom_rightright->set_node(3, _mesh->node_ptr(7));
175 }
176
177 // libMesh shouldn't renumber, or our based-on-initial-id
178 // assertions later may fail.
179 _mesh->allow_renumbering(false);
180
181 _mesh->prepare_for_use();
182 }
std::unique_ptr< Mesh > _mesh
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
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
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40

References SlitMeshTest::_mesh, libMesh::Elem::build_with_id(), libMesh::QUAD4, libMesh::Elem::set_node(), and TestCommWorld.

Referenced by SlitMeshTest::setUp(), SlitMeshRefinedMeshTest::setUp(), and setUp().

◆ CPPUNIT_TEST() [1/3]

SlitMeshRefinedSystemTest::CPPUNIT_TEST ( testMesh  )

◆ CPPUNIT_TEST() [2/3]

SlitMeshRefinedSystemTest::CPPUNIT_TEST ( testRestart  )

◆ CPPUNIT_TEST() [3/3]

SlitMeshRefinedSystemTest::CPPUNIT_TEST ( testSystem  )

◆ CPPUNIT_TEST_SUITE_END()

SlitMeshRefinedSystemTest::CPPUNIT_TEST_SUITE_END ( )

◆ LIBMESH_CPPUNIT_TEST_SUITE() [1/2]

SlitMeshRefinedSystemTest::LIBMESH_CPPUNIT_TEST_SUITE ( SlitMeshRefinedSystemTest  )

The goal of this test is the same as the previous, but now we create a system and set dof values to make sure they are properly interpolated after refinement.

◆ LIBMESH_CPPUNIT_TEST_SUITE() [2/2]

SlitMeshTest::LIBMESH_CPPUNIT_TEST_SUITE ( SlitMeshTest  )
inherited

The goal of this test is to ensure that a 2D mesh with nodes overlapping on opposite sides of an internal, "slit" edge is usable.

The mesh has to be connected at more than one node on each side of the slit, however, to ensure that we can find point neighbors of each node.

◆ setUp()

void SlitMeshRefinedSystemTest::setUp ( )
inline

Definition at line 296 of file slit_mesh_test.C.

297 {
298#if LIBMESH_DIM > 1
299 this->build_mesh();
300
301 // libMesh *should* renumber now, or a DistributedMesh might not
302 // have contiguous ids, which is a requirement to write xda files.
303 _mesh->allow_renumbering(true);
304
305 _es = std::make_unique<EquationSystems>(*_mesh);
306 _sys = &_es->add_system<System> ("SimpleSystem");
307 _sys->add_variable("u", FIRST);
308
309 // We're going to be integrating across the slit in the mesh, so
310 // let's make sure we can *see* elements and data across the slit.
311 _mesh->allgather();
313 (std::make_shared<OverlapCoupling>());
314 _mesh->delete_remote_elements();
315
316 _es->init();
317 SlitFunc slitfunc;
318 _sys->project_solution(&slitfunc);
319
320#ifdef LIBMESH_ENABLE_AMR
322 _es->reinit();
324 _es->reinit();
325#endif
326#endif
327 }
std::unique_ptr< EquationSystems > _es
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
Implements (adaptive) mesh refinement algorithms for a MeshBase.
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
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.
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

References _es, SlitMeshTest::_mesh, _sys, libMesh::DofMap::add_algebraic_ghosting_functor(), libMesh::System::add_variable(), SlitMeshTest::build_mesh(), libMesh::FIRST, libMesh::System::get_dof_map(), libMesh::System::project_solution(), and libMesh::MeshRefinement::uniformly_refine().

◆ tearDown()

void SlitMeshRefinedSystemTest::tearDown ( )
inline

Definition at line 329 of file slit_mesh_test.C.

329{}

◆ testMesh()

void SlitMeshRefinedSystemTest::testMesh ( )
inline

Definition at line 331 of file slit_mesh_test.C.

332 {
333 LOG_UNIT_TEST;
334
335#ifdef LIBMESH_ENABLE_AMR
336 // We should have 168 total and 128 active elements.
337 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(8+32+128), _mesh->n_elem());
338 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(128), _mesh->n_active_elem());
339
340 // We should have 160 nodes
341 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(160), _mesh->n_nodes());
342#endif
343 }
uint8_t dof_id_type
Definition id_types.h:67

References SlitMeshTest::_mesh.

◆ testRestart()

void SlitMeshRefinedSystemTest::testRestart ( )
inline

Definition at line 396 of file slit_mesh_test.C.

397 {
398 LOG_UNIT_TEST;
399
400 SlitFunc slitfunc;
401
402 _mesh->write("slit_mesh.xda");
403 _es->write("slit_solution.xda",
406
407 Mesh mesh2(*TestCommWorld);
408 mesh2.read("slit_mesh.xda");
409 EquationSystems es2(mesh2);
410 es2.read("slit_solution.xda");
411
412 System & sys2 = es2.get_system<System> ("SimpleSystem");
413
414 unsigned int dim = 2;
415
416 CPPUNIT_ASSERT_EQUAL( sys2.n_vars(), 1u );
417
418 FEMContext context(sys2);
419 FEBase * fe = NULL;
420 context.get_element_fe( 0, fe, dim );
421 const std::vector<Point> & xyz = fe->get_xyz();
422 fe->get_phi();
423
424 // While we're in the middle of a unique id based test case, let's
425 // make sure our unique ids were all read in correctly too.
426 std::unique_ptr<PointLocatorBase> locator = _mesh->sub_point_locator();
427
428 if (!_mesh->is_serial())
429 locator->enable_out_of_mesh_mode();
430
431 for (const auto & elem : mesh2.active_local_element_ptr_range())
432 {
433 const Elem * mesh1_elem = (*locator)(elem->vertex_average());
434 if (mesh1_elem)
435 {
436 CPPUNIT_ASSERT_EQUAL( elem->unique_id(),
437 mesh1_elem->unique_id() );
438
439 for (unsigned int n=0; n != elem->n_nodes(); ++n)
440 {
441 const Node & node = elem->node_ref(n);
442 const Node & mesh1_node = mesh1_elem->node_ref(n);
443 CPPUNIT_ASSERT_EQUAL( node.unique_id(),
444 mesh1_node.unique_id() );
445 }
446 }
447
448 context.pre_fe_reinit(sys2, elem);
449 context.elem_fe_reinit();
450
451 const unsigned int n_qp = xyz.size();
452
453 for (unsigned int qp=0; qp != n_qp; ++qp)
454 {
455 const Number exact_val = slitfunc(context, xyz[qp]);
456
457 const Number discrete_val = context.interior_value(0, qp);
458
459 LIBMESH_ASSERT_NUMBERS_EQUAL
460 (exact_val, discrete_val, TOLERANCE*TOLERANCE);
461 }
462 }
463 }
unsigned int dim
unique_id_type unique_id() const
Definition dof_object.h:835
const Node & node_ref(const unsigned int i) const
Definition elem.h:2538
This is the EquationSystems class.
virtual_for_inffe const std::vector< Point > & get_xyz() const
This class forms the foundation from which generic finite elements may be derived.
Definition fe_base.h:86
const std::vector< std::vector< OutputShape > > & get_phi() const
Definition fe_base.h:207
This class provides all data required for a physics package (e.g.
Definition fem_context.h:63
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition mesh.h:51
A Node is like a Point, but with more information.
Definition node.h:55
unsigned int n_vars() const
Definition system.C:2674
static constexpr Real TOLERANCE

References _es, SlitMeshTest::_mesh, dim, libMesh::FEMContext::elem_fe_reinit(), libMesh::FEMContext::get_element_fe(), libMesh::FEGenericBase< OutputType >::get_phi(), libMesh::EquationSystems::get_system(), libMesh::FEAbstract::get_xyz(), libMesh::FEMContext::interior_value(), libMesh::System::n_vars(), libMesh::Elem::node_ref(), libMesh::FEMContext::pre_fe_reinit(), libMesh::UnstructuredMesh::read(), libMesh::EquationSystems::read(), TestCommWorld, libMesh::TOLERANCE, libMesh::DofObject::unique_id(), libMesh::EquationSystems::WRITE_DATA, and libMesh::EquationSystems::WRITE_SERIAL_FILES.

◆ testSystem()

void SlitMeshRefinedSystemTest::testSystem ( )
inline

Definition at line 345 of file slit_mesh_test.C.

346 {
347 LOG_UNIT_TEST;
348
349 SlitFunc slitfunc;
350
351 unsigned int dim = 2;
352
353 CPPUNIT_ASSERT_EQUAL( _sys->n_vars(), 1u );
354
355 FEMContext context(*_sys);
356 FEBase * fe = NULL;
357 context.get_element_fe( 0, fe, dim );
358 const std::vector<Point> & xyz = fe->get_xyz();
359 fe->get_phi();
360
361 for (const auto & elem : _mesh->active_local_element_ptr_range())
362 {
363 context.pre_fe_reinit(*_sys, elem);
364 context.elem_fe_reinit();
365
366 const unsigned int n_qp = xyz.size();
367
368 for (unsigned int qp=0; qp != n_qp; ++qp)
369 {
370 const Number exact_val = slitfunc(context, xyz[qp]);
371
372 const Number discrete_val = context.interior_value(0, qp);
373
374 LIBMESH_ASSERT_NUMBERS_EQUAL
375 (exact_val, discrete_val, TOLERANCE*TOLERANCE);
376 }
377 }
378
379 // We should have no discontinuities (beyond floating-point error)
380 // between topologically connected elements
381 DiscontinuityMeasure connected_dm;
382 ErrorVector connected_err;
383 connected_dm.estimate_error(*_sys, connected_err);
384 const Real mean_connected_disc = connected_err.mean();
385 CPPUNIT_ASSERT_LESS(Real(1e-14), mean_connected_disc);
386
387 // We should be able to see the discontinuity along the slit
388 DiscontinuityMeasure slit_dm;
389 slit_dm.integrate_slits = true;
390 ErrorVector slit_disc;
391 slit_dm.estimate_error(*_sys, slit_disc);
392 const Real mean_slit_disc = slit_disc.mean();
393 CPPUNIT_ASSERT_GREATER(Real(1e-3), mean_slit_disc);
394 }
This class measures discontinuities between elements for debugging purposes.
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
virtual Real mean() const override
bool integrate_slits
A boolean flag, by default false, to be set to true if integrations should be performed on "slits" wh...
virtual void estimate_error(const System &system, ErrorVector &error_per_cell, const NumericVector< Number > *solution_vector=nullptr, bool estimate_parent_error=false) override
This function uses the derived class's jump error estimate formula to estimate the error on each cell...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

References SlitMeshTest::_mesh, _sys, dim, libMesh::FEMContext::elem_fe_reinit(), libMesh::JumpErrorEstimator::estimate_error(), libMesh::FEMContext::get_element_fe(), libMesh::FEGenericBase< OutputType >::get_phi(), libMesh::FEAbstract::get_xyz(), libMesh::JumpErrorEstimator::integrate_slits, libMesh::FEMContext::interior_value(), libMesh::ErrorVector::mean(), libMesh::System::n_vars(), libMesh::FEMContext::pre_fe_reinit(), libMesh::Real, and libMesh::TOLERANCE.

Member Data Documentation

◆ _es

std::unique_ptr<EquationSystems> SlitMeshRefinedSystemTest::_es
protected

Definition at line 292 of file slit_mesh_test.C.

Referenced by setUp(), and testRestart().

◆ _mesh

std::unique_ptr<Mesh> SlitMeshTest::_mesh
protectedinherited

◆ _sys

System* SlitMeshRefinedSystemTest::_sys
protected

Definition at line 291 of file slit_mesh_test.C.

Referenced by setUp(), and testSystem().


The documentation for this class was generated from the following file: