Loading [MathJax]/extensions/tex2jax.js
libMesh
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
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. 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 509 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]

BoundaryRefinedMeshTest::CPPUNIT_TEST ( testMesh  )

◆ CPPUNIT_TEST() [2/2]

BoundaryRefinedMeshTest::CPPUNIT_TEST ( testBoundarySerialization  )

◆ 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 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 BoundaryRefinedMeshTest::setUp ( )
inline

Definition at line 529 of file boundary_mesh.C.

References libMesh::MeshRefinement::uniformly_refine().

530  {
531 #if LIBMESH_DIM > 1
532  this->build_mesh();
533  this->sync_and_test_meshes();
534 
535  // Need to refine interior mesh before separate boundary meshes,
536  // if we want to get interior_parent links right.
537  MeshRefinement(*_mesh).uniformly_refine(1);
538 
539  MeshRefinement(*_multi_boundary_mesh).uniformly_refine(1);
540  MeshRefinement(*_exterior_boundary_mesh).uniformly_refine(1);
541  MeshRefinement(*_left_boundary_mesh).uniformly_refine(1);
542  MeshRefinement(*_internal_boundary_mesh).uniformly_refine(1);
543 #endif
544  }
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 BoundaryRefinedMeshTest::testBoundarySerialization ( )
inline

Definition at line 619 of file boundary_mesh.C.

620  {
621  LOG_UNIT_TEST;
622 
623  MeshSerializer internal_serializer(*_internal_boundary_mesh);
624 
625  // There'd better be 2*4 active elements on the internal
626  // sideset mesh
627  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(8),
628  _internal_boundary_mesh->n_active_elem());
629 
630  // Plus the original 4 now-inactive elements
631  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(12),
632  _internal_boundary_mesh->n_elem());
633 
634  // There'd better be 2*2*4+1 nodes on the internal boundary
635  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(17),
636  _internal_boundary_mesh->n_nodes());
637 
638  this->sanityCheck();
639  }
std::unique_ptr< UnstructuredMesh > _internal_boundary_mesh
Temporarily serialize a DistributedMesh for non-distributed-mesh capable code paths.

◆ testMesh()

void BoundaryRefinedMeshTest::testMesh ( )
inline

Definition at line 546 of file boundary_mesh.C.

547  {
548  LOG_UNIT_TEST;
549 
550  // There'd better be 3*5*4 + 5*2 active elements in the interior
551  // plus right boundary
552  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(70),
553  _mesh->n_active_elem());
554 
555  // Plus the original 20 now-inactive elements
556  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(90),
557  _mesh->n_elem());
558 
559  // There'd better be 13*21 nodes in the interior
560  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(273),
561  _mesh->n_nodes());
562 
563  // There'd better be 2*2*(3+5) active elements on the exterior boundary
564  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(32),
565  _exterior_boundary_mesh->n_active_elem());
566 
567  // Plus the original 16 now-inactive elements
568  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(48),
569  _exterior_boundary_mesh->n_elem());
570 
571  // There'd better be 2*2*2*(3+5) nodes on the exterior boundary
572  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(64),
573  _exterior_boundary_mesh->n_nodes());
574 
575  // There'd better be 2*5 active elements on the left boundary
576  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(10),
577  _left_boundary_mesh->n_active_elem());
578 
579  // Plus the original 5 now-inactive elements
580  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(15),
581  _left_boundary_mesh->n_elem());
582 
583  // There'd better be 2*2*5+1 nodes on the left boundary
584  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(21),
585  _left_boundary_mesh->n_nodes());
586 
587  // There'd better be 2*4 active elements on the one-sided internal
588  // sideset mesh
589  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(8),
590  _internal_boundary_mesh->n_active_elem());
591 
592  // Plus the original 4 now-inactive elements
593  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(12),
594  _internal_boundary_mesh->n_elem());
595 
596  // There'd better be 2*2*4+1 nodes on the internal boundary
597  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(17),
598  _internal_boundary_mesh->n_nodes());
599 
600  // There'd better be 2*(3+5) + 2*4 active elements on the
601  // multi-boundary
602  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(24),
603  _multi_boundary_mesh->n_active_elem());
604 
605  // Plus the original 12 now-inactive elements
606  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(36),
607  _multi_boundary_mesh->n_elem());
608 
609  // There'd better be 2*2*(3+5)+1 + 2*2*4+1 nodes on the
610  // multi-boundary
611  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(50),
612  _multi_boundary_mesh->n_nodes());
613 
614 
615  this->sanityCheck();
616  }
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: