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

Public Member Functions

 LIBMESH_CPPUNIT_TEST_SUITE (BoundaryRefinedMeshTest)
 The goal of this test is the same as the previous, but now we do a uniform refinement and make sure the result mesh is consistent.
 
 CPPUNIT_TEST (testMesh)
 
 CPPUNIT_TEST (testBoundarySerialization)
 
 CPPUNIT_TEST_SUITE_END ()
 
void setUp ()
 
void testMesh ()
 
void testBoundarySerialization ()
 
 LIBMESH_CPPUNIT_TEST_SUITE (BoundaryMeshTest)
 The goal of this test is to ensure that a 2D mesh generates boundary meshes correctly.
 
void sanityCheck ()
 

Protected Member Functions

void build_mesh ()
 
void sync_and_test_meshes ()
 

Protected Attributes

std::unique_ptr< UnstructuredMesh_mesh
 
std::unique_ptr< UnstructuredMesh_multi_boundary_mesh
 
std::unique_ptr< UnstructuredMesh_exterior_boundary_mesh
 
std::unique_ptr< UnstructuredMesh_left_boundary_mesh
 
std::unique_ptr< UnstructuredMesh_internal_boundary_mesh
 

Static Protected Attributes

static constexpr boundary_id_type bid1 = 5
 
static constexpr boundary_id_type bid2 = 6
 

Detailed Description

Definition at line 633 of file boundary_mesh.C.

Member Function Documentation

◆ build_mesh()

void BoundaryMeshTest::build_mesh ( )
inlineprotectedinherited

Definition at line 271 of file boundary_mesh.C.

272 {
273 _mesh = std::make_unique<Mesh>(*TestCommWorld);
274 _multi_boundary_mesh = std::make_unique<Mesh>(*TestCommWorld);
275 _exterior_boundary_mesh = std::make_unique<Mesh>(*TestCommWorld);
276
277 // We want to test Distributed->Replicated sync; this does that in
278 // some builds
279 _left_boundary_mesh = std::make_unique<ReplicatedMesh>(*TestCommWorld);
280
281 // We want to test Replicated->Distributed sync; this does that in
282 // other builds
283 _internal_boundary_mesh = std::make_unique<DistributedMesh>(*TestCommWorld);
284
286 0.2, 0.8, 0.2, 0.7, QUAD9);
287
288 // We'll need to skip most repartitioning with DistributedMesh for
289 // now; otherwise the boundary meshes' interior parents might get
290 // shuffled off to different processors.
291 if (!_mesh->is_serial())
292 {
293 _mesh->skip_noncritical_partitioning(true);
294 _left_boundary_mesh->skip_noncritical_partitioning(true);
295 _multi_boundary_mesh->skip_noncritical_partitioning(true);
296 _exterior_boundary_mesh->skip_noncritical_partitioning(true);
297 _internal_boundary_mesh->skip_noncritical_partitioning(true);
298 }
299
300 // Set subdomain ids for specific elements. This allows us to later
301 // build an internal sideset with respect to a given
302 // subdomain. The element subdomains look like:
303 // ___________________
304 // | 2 | 2 | 2 |
305 // |_____|_____|_____|
306 // | 2 | 2 | 2 |
307 // |_____|_____|_____|
308 // | 2 | 2 | 2 |
309 // |_____|_____|_____|
310 // | 1 | 1 | 2 |
311 // |_____|_____|_____|
312 // | 1 | 1 | 2 |
313 // |_____|_____|_____|
314 //
315 // and we will create an internal sideset along the border between
316 // subdomains 1 and 2.
317
318 for (auto & elem : _mesh->active_element_ptr_range())
319 {
320 const Point c = elem->vertex_average();
321 if (c(0) < 0.6 && c(1) < 0.4)
322 elem->subdomain_id() = 1;
323 else
324 elem->subdomain_id() = 2;
325 }
326
327 // To test the "relative to" feature, we add the same sides to the
328 // same sideset twice, from elements in subdomain 2 the second
329 // time. These should not show up in the BoundaryMesh, i.e. there
330 // should not be overlapped elems in the BoundaryMesh.
331 BoundaryInfo & bi = _mesh->get_boundary_info();
332
333 for (auto & elem : _mesh->active_element_ptr_range())
334 {
335 const Point c = elem->vertex_average();
336 if (c(0) < 0.6 && c(1) < 0.4)
337 {
338 if (c(0) > 0.4)
339 bi.add_side(elem, 1, bid1);
340 if (c(1) > 0.3)
341 bi.add_side(elem, 2, bid1);
342 }
343 else
344 {
345 if (c(0) < 0.75 && c(1) < 0.4)
346 bi.add_side(elem, 3, bid2);
347 if (c(0) < 0.6 && c(1) < 0.5)
348 bi.add_side(elem, 0, bid2);
349 }
350 }
351 }
std::unique_ptr< UnstructuredMesh > _multi_boundary_mesh
std::unique_ptr< UnstructuredMesh > _exterior_boundary_mesh
std::unique_ptr< UnstructuredMesh > _internal_boundary_mesh
std::unique_ptr< UnstructuredMesh > _mesh
static constexpr boundary_id_type bid2
static constexpr boundary_id_type bid1
std::unique_ptr< UnstructuredMesh > _left_boundary_mesh
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
Add side side of element number elem with boundary id id to the boundary information data structure.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
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.

References BoundaryMeshTest::_exterior_boundary_mesh, BoundaryMeshTest::_internal_boundary_mesh, BoundaryMeshTest::_left_boundary_mesh, BoundaryMeshTest::_mesh, BoundaryMeshTest::_multi_boundary_mesh, libMesh::BoundaryInfo::add_side(), BoundaryMeshTest::bid1, BoundaryMeshTest::bid2, libMesh::MeshTools::Generation::build_square(), libMesh::QUAD9, and TestCommWorld.

Referenced by BoundaryMeshTest::setUp(), setUp(), and BoundaryOfRefinedMeshTest::setUp().

◆ CPPUNIT_TEST() [1/2]

BoundaryRefinedMeshTest::CPPUNIT_TEST ( testBoundarySerialization  )

◆ CPPUNIT_TEST() [2/2]

BoundaryRefinedMeshTest::CPPUNIT_TEST ( testMesh  )

◆ CPPUNIT_TEST_SUITE_END()

BoundaryRefinedMeshTest::CPPUNIT_TEST_SUITE_END ( )

◆ LIBMESH_CPPUNIT_TEST_SUITE() [1/2]

BoundaryMeshTest::LIBMESH_CPPUNIT_TEST_SUITE ( BoundaryMeshTest  )
inherited

The goal of this test is to ensure that a 2D mesh generates boundary meshes correctly.

◆ LIBMESH_CPPUNIT_TEST_SUITE() [2/2]

BoundaryRefinedMeshTest::LIBMESH_CPPUNIT_TEST_SUITE ( BoundaryRefinedMeshTest  )

The goal of this test is the same as the previous, but now we do a uniform refinement and make sure the result mesh is consistent.

i.e. the new node shared between the 1D elements is the same as the node shared on the underlying quads, and so on.

◆ sanityCheck()

void BoundaryMeshTest::sanityCheck ( )
inlineinherited

Definition at line 479 of file boundary_mesh.C.

480 {
481 sanity_check_mesh(*_mesh, EDGE3, QUAD9, true);
482 sanity_check_mesh(*_multi_boundary_mesh, EDGE3, QUAD9, false);
483 sanity_check_mesh(*_exterior_boundary_mesh, EDGE3, QUAD9, false);
484 sanity_check_mesh(*_left_boundary_mesh, EDGE3, QUAD9, false);
485 sanity_check_mesh(*_internal_boundary_mesh, EDGE3, QUAD9, false);
486
487 for (const auto & elem : _left_boundary_mesh->active_element_ptr_range())
488 {
489 // We only added left edges here
490 LIBMESH_ASSERT_FP_EQUAL(0.2, elem->vertex_average()(0),
492 }
493
494 // Sanity check for the internal sideset mesh.
495 for (const auto & elem : _internal_boundary_mesh->active_element_ptr_range())
496 {
497 // All of the elements in the internal sideset mesh should
498 // have the same subdomain id as the parent Elems (i.e. 1)
499 // they came from.
500 CPPUNIT_ASSERT_EQUAL(static_cast<subdomain_id_type>(1),
501 elem->subdomain_id());
502 }
503 }
static constexpr Real TOLERANCE

References BoundaryMeshTest::_exterior_boundary_mesh, BoundaryMeshTest::_internal_boundary_mesh, BoundaryMeshTest::_left_boundary_mesh, BoundaryMeshTest::_mesh, BoundaryMeshTest::_multi_boundary_mesh, libMesh::EDGE3, libMesh::QUAD9, and libMesh::TOLERANCE.

Referenced by BoundaryMeshTest::testBoundarySerialization(), testBoundarySerialization(), BoundaryOfRefinedMeshTest::testBoundarySerialization(), BoundaryMeshTest::testMesh(), testMesh(), and BoundaryOfRefinedMeshTest::testMesh().

◆ setUp()

void BoundaryRefinedMeshTest::setUp ( )
inline

Definition at line 653 of file boundary_mesh.C.

654 {
655#if LIBMESH_DIM > 1
656 this->build_mesh();
657 this->sync_and_test_meshes();
658
659 // Need to refine interior mesh before separate boundary meshes,
660 // if we want to get interior_parent links right.
662
663 MeshRefinement(*_multi_boundary_mesh).uniformly_refine(1);
664 MeshRefinement(*_exterior_boundary_mesh).uniformly_refine(1);
665 MeshRefinement(*_left_boundary_mesh).uniformly_refine(1);
666 MeshRefinement(*_internal_boundary_mesh).uniformly_refine(1);
667#endif
668 }
void sync_and_test_meshes()
Implements (adaptive) mesh refinement algorithms for a MeshBase.
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.

References BoundaryMeshTest::build_mesh(), BoundaryMeshTest::sync_and_test_meshes(), and libMesh::MeshRefinement::uniformly_refine().

◆ sync_and_test_meshes()

void BoundaryMeshTest::sync_and_test_meshes ( )
inlineprotectedinherited

Definition at line 353 of file boundary_mesh.C.

354 {
355 // Get the border of the square
356 const std::set<boundary_id_type> exterior_boundaries {0, 1, 2, 3};
357 _mesh->get_boundary_info().sync(exterior_boundaries,
359 check_parent_side_index_tag(*_exterior_boundary_mesh);
360
361 // The mesh of all boundaries is, because of the two nodes each
362 // joining three edges where the internal boundary meets the
363 // external boundary, not a manifold mesh. We still have work to
364 // do to properly support non-manifold meshes, and
365 // find_neighbors() when preparing such a mesh is likely to fail,
366 // so we'll just do the best test we can here, requesting a set of
367 // three different boundaries. We drop the left and bottom
368 // boundaries because they have any T intersections with the
369 // interior boundaries, and we drop one of the interior boundaries
370 // because with both together we'd have 4 edges meeting at every
371 // interior boundary vertex.
372 const std::set<boundary_id_type> multi_boundaries {1, 2, 5};
373 _mesh->get_boundary_info().sync(multi_boundaries,
375 check_parent_side_index_tag(*_multi_boundary_mesh);
376
377 std::set<boundary_id_type> left_id, right_id;
378 left_id.insert(3);
379 right_id.insert(1);
380
381 // Add the right side of the square to the square; this should
382 // make it a mixed dimension mesh. We skip storing the parent
383 // side ids (which is the default) since they are not needed
384 // in this particular test.
385 _mesh->get_boundary_info().add_elements
386 (right_id, *_mesh, /*store_parent_side_ids=*/false);
387 _mesh->prepare_for_use();
388
389 // Add the left side of the square to its own boundary mesh.
390 _mesh->get_boundary_info().sync(left_id, *_left_boundary_mesh);
391 check_parent_side_index_tag(*_left_boundary_mesh);
392
393 // Create a BoundaryMesh from the internal sidesets relative to subdomain 1.
394 {
395 std::set<boundary_id_type> requested_boundary_ids {bid1, bid2};
396 std::set<subdomain_id_type> subdomains_relative_to;
397 subdomains_relative_to.insert(1);
398 _mesh->get_boundary_info().sync(requested_boundary_ids,
400 subdomains_relative_to);
401 check_parent_side_index_tag(*_internal_boundary_mesh);
402 }
403 }
static const boundary_id_type left_id
static const boundary_id_type right_id

References BoundaryMeshTest::_exterior_boundary_mesh, BoundaryMeshTest::_internal_boundary_mesh, BoundaryMeshTest::_left_boundary_mesh, BoundaryMeshTest::_mesh, BoundaryMeshTest::_multi_boundary_mesh, BoundaryMeshTest::bid1, BoundaryMeshTest::bid2, left_id, and right_id.

Referenced by BoundaryMeshTest::setUp(), setUp(), and BoundaryOfRefinedMeshTest::setUp().

◆ testBoundarySerialization()

void BoundaryRefinedMeshTest::testBoundarySerialization ( )
inline

Definition at line 743 of file boundary_mesh.C.

744 {
745 LOG_UNIT_TEST;
746
747 MeshSerializer internal_serializer(*_internal_boundary_mesh);
748
749 // There'd better be 2*4 active elements on the internal
750 // sideset mesh
751 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(8),
752 _internal_boundary_mesh->n_active_elem());
753
754 // Plus the original 4 now-inactive elements
755 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(12),
756 _internal_boundary_mesh->n_elem());
757
758 // There'd better be 2*2*4+1 nodes on the internal boundary
759 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(17),
760 _internal_boundary_mesh->n_nodes());
761
762 this->sanityCheck();
763 }
Temporarily serialize a DistributedMesh for non-distributed-mesh capable code paths.
uint8_t dof_id_type
Definition id_types.h:67

References BoundaryMeshTest::_internal_boundary_mesh, and BoundaryMeshTest::sanityCheck().

◆ testMesh()

void BoundaryRefinedMeshTest::testMesh ( )
inline

Definition at line 670 of file boundary_mesh.C.

671 {
672 LOG_UNIT_TEST;
673
674 // There'd better be 3*5*4 + 5*2 active elements in the interior
675 // plus right boundary
676 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(70),
677 _mesh->n_active_elem());
678
679 // Plus the original 20 now-inactive elements
680 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(90),
681 _mesh->n_elem());
682
683 // There'd better be 13*21 nodes in the interior
684 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(273),
685 _mesh->n_nodes());
686
687 // There'd better be 2*2*(3+5) active elements on the exterior boundary
688 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(32),
689 _exterior_boundary_mesh->n_active_elem());
690
691 // Plus the original 16 now-inactive elements
692 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(48),
693 _exterior_boundary_mesh->n_elem());
694
695 // There'd better be 2*2*2*(3+5) nodes on the exterior boundary
696 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(64),
697 _exterior_boundary_mesh->n_nodes());
698
699 // There'd better be 2*5 active elements on the left boundary
700 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(10),
701 _left_boundary_mesh->n_active_elem());
702
703 // Plus the original 5 now-inactive elements
704 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(15),
705 _left_boundary_mesh->n_elem());
706
707 // There'd better be 2*2*5+1 nodes on the left boundary
708 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(21),
709 _left_boundary_mesh->n_nodes());
710
711 // There'd better be 2*4 active elements on the one-sided internal
712 // sideset mesh
713 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(8),
714 _internal_boundary_mesh->n_active_elem());
715
716 // Plus the original 4 now-inactive elements
717 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(12),
718 _internal_boundary_mesh->n_elem());
719
720 // There'd better be 2*2*4+1 nodes on the internal boundary
721 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(17),
722 _internal_boundary_mesh->n_nodes());
723
724 // There'd better be 2*(3+5) + 2*4 active elements on the
725 // multi-boundary
726 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(24),
727 _multi_boundary_mesh->n_active_elem());
728
729 // Plus the original 12 now-inactive elements
730 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(36),
731 _multi_boundary_mesh->n_elem());
732
733 // There'd better be 2*2*(3+5)+1 + 2*2*4+1 nodes on the
734 // multi-boundary
735 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(50),
736 _multi_boundary_mesh->n_nodes());
737
738
739 this->sanityCheck();
740 }

References BoundaryMeshTest::_exterior_boundary_mesh, BoundaryMeshTest::_internal_boundary_mesh, BoundaryMeshTest::_left_boundary_mesh, BoundaryMeshTest::_mesh, BoundaryMeshTest::_multi_boundary_mesh, and BoundaryMeshTest::sanityCheck().

Member Data Documentation

◆ _exterior_boundary_mesh

std::unique_ptr<UnstructuredMesh> BoundaryMeshTest::_exterior_boundary_mesh
protectedinherited

◆ _internal_boundary_mesh

std::unique_ptr<UnstructuredMesh> BoundaryMeshTest::_internal_boundary_mesh
protectedinherited

◆ _left_boundary_mesh

std::unique_ptr<UnstructuredMesh> BoundaryMeshTest::_left_boundary_mesh
protectedinherited

◆ _mesh

std::unique_ptr<UnstructuredMesh> BoundaryMeshTest::_mesh
protectedinherited

◆ _multi_boundary_mesh

std::unique_ptr<UnstructuredMesh> BoundaryMeshTest::_multi_boundary_mesh
protectedinherited

◆ bid1

constexpr boundary_id_type BoundaryMeshTest::bid1 = 5
staticconstexprprotectedinherited

◆ bid2

constexpr boundary_id_type BoundaryMeshTest::bid2 = 6
staticconstexprprotectedinherited

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