libMesh
Public Member Functions | Protected Member Functions | Protected Attributes | Static Protected Attributes | List of all members
BoundaryOfRefinedMeshTest Class Reference
Inheritance diagram for BoundaryOfRefinedMeshTest:
[legend]

Public Member Functions

 LIBMESH_CPPUNIT_TEST_SUITE (BoundaryOfRefinedMeshTest)
 The goal of this test is the same as the previous, but now we do a uniform refinement before synchronizing to the boundary mesh rather than after. More...
 
 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. More...
 
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 646 of file boundary_mesh.C.

Member Function Documentation

◆ build_mesh()

void BoundaryMeshTest::build_mesh ( )
inlineprotectedinherited

Definition at line 269 of file boundary_mesh.C.

References libMesh::BoundaryInfo::add_side(), libMesh::MeshTools::Generation::build_square(), and libMesh::QUAD9.

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

◆ CPPUNIT_TEST() [1/2]

BoundaryOfRefinedMeshTest::CPPUNIT_TEST ( testMesh  )

◆ CPPUNIT_TEST() [2/2]

BoundaryOfRefinedMeshTest::CPPUNIT_TEST ( testBoundarySerialization  )

◆ CPPUNIT_TEST_SUITE_END()

BoundaryOfRefinedMeshTest::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]

BoundaryOfRefinedMeshTest::LIBMESH_CPPUNIT_TEST_SUITE ( BoundaryOfRefinedMeshTest  )

The goal of this test is the same as the previous, but now we do a uniform refinement before synchronizing to the boundary mesh rather than after.

◆ sanityCheck()

void BoundaryMeshTest::sanityCheck ( )
inlineinherited

Definition at line 477 of file boundary_mesh.C.

References libMesh::EDGE3, libMesh::QUAD9, and libMesh::TOLERANCE.

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

◆ setUp()

void BoundaryOfRefinedMeshTest::setUp ( )
inline

Definition at line 665 of file boundary_mesh.C.

References libMesh::MeshRefinement::uniformly_refine().

666  {
667 #if LIBMESH_DIM > 1
668  this->build_mesh();
669 
670  // Refine interior mesh before creating boundary meshes
671  MeshRefinement(*_mesh).uniformly_refine(1);
672 
673  this->sync_and_test_meshes();
674 #endif
675  }
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.

◆ sync_and_test_meshes()

void BoundaryMeshTest::sync_and_test_meshes ( )
inlineprotectedinherited

Definition at line 351 of file boundary_mesh.C.

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

◆ testBoundarySerialization()

void BoundaryOfRefinedMeshTest::testBoundarySerialization ( )
inline

Definition at line 747 of file boundary_mesh.C.

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

◆ testMesh()

void BoundaryOfRefinedMeshTest::testMesh ( )
inline

Definition at line 677 of file boundary_mesh.C.

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

Member Data Documentation

◆ _exterior_boundary_mesh

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

Definition at line 260 of file boundary_mesh.C.

◆ _internal_boundary_mesh

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

Definition at line 262 of file boundary_mesh.C.

◆ _left_boundary_mesh

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

Definition at line 261 of file boundary_mesh.C.

◆ _mesh

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

Definition at line 258 of file boundary_mesh.C.

◆ _multi_boundary_mesh

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

Definition at line 259 of file boundary_mesh.C.

◆ bid1

constexpr boundary_id_type BoundaryMeshTest::bid1 = 5
staticprotectedinherited

Definition at line 266 of file boundary_mesh.C.

◆ bid2

constexpr boundary_id_type BoundaryMeshTest::bid2 = 6
staticprotectedinherited

Definition at line 267 of file boundary_mesh.C.


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