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

Public Member Functions

 LIBMESH_CPPUNIT_TEST_SUITE (BoundaryMeshTest)
 The goal of this test is to ensure that a 2D mesh generates boundary meshes correctly.
 
 CPPUNIT_TEST (testMesh)
 
 CPPUNIT_TEST (testBoundarySerialization)
 
 CPPUNIT_TEST_SUITE_END ()
 
void setUp ()
 
void testMesh ()
 
void testBoundarySerialization ()
 
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 243 of file boundary_mesh.C.

Member Function Documentation

◆ build_mesh()

void BoundaryMeshTest::build_mesh ( )
inlineprotected

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 _exterior_boundary_mesh, _internal_boundary_mesh, _left_boundary_mesh, _mesh, _multi_boundary_mesh, libMesh::BoundaryInfo::add_side(), bid1, bid2, libMesh::MeshTools::Generation::build_square(), libMesh::QUAD9, and TestCommWorld.

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

◆ CPPUNIT_TEST() [1/2]

BoundaryMeshTest::CPPUNIT_TEST ( testBoundarySerialization  )

◆ CPPUNIT_TEST() [2/2]

BoundaryMeshTest::CPPUNIT_TEST ( testMesh  )

◆ CPPUNIT_TEST_SUITE_END()

BoundaryMeshTest::CPPUNIT_TEST_SUITE_END ( )

◆ LIBMESH_CPPUNIT_TEST_SUITE()

BoundaryMeshTest::LIBMESH_CPPUNIT_TEST_SUITE ( BoundaryMeshTest  )

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

◆ sanityCheck()

void BoundaryMeshTest::sanityCheck ( )
inline

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 _exterior_boundary_mesh, _internal_boundary_mesh, _left_boundary_mesh, _mesh, _multi_boundary_mesh, libMesh::EDGE3, libMesh::QUAD9, and libMesh::TOLERANCE.

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

◆ setUp()

void BoundaryMeshTest::setUp ( )
inline

Definition at line 406 of file boundary_mesh.C.

407 {
408#if LIBMESH_DIM > 1
409 this->build_mesh();
410 this->sync_and_test_meshes();
411#endif
412 }
void sync_and_test_meshes()

References build_mesh(), and sync_and_test_meshes().

◆ sync_and_test_meshes()

void BoundaryMeshTest::sync_and_test_meshes ( )
inlineprotected

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 _exterior_boundary_mesh, _internal_boundary_mesh, _left_boundary_mesh, _mesh, _multi_boundary_mesh, bid1, bid2, left_id, and right_id.

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

◆ testBoundarySerialization()

void BoundaryMeshTest::testBoundarySerialization ( )
inline

Definition at line 462 of file boundary_mesh.C.

463 {
464 LOG_UNIT_TEST;
465
466 MeshSerializer internal_serializer(*_internal_boundary_mesh);
467
468 // There are four elements in the internal sideset mesh.
469 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(4),
470 _internal_boundary_mesh->n_elem());
471
472 // There are 2*n_elem + 1 nodes in the internal sideset mesh.
473 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(9),
474 _internal_boundary_mesh->n_nodes());
475
476 this->sanityCheck();
477 }
Temporarily serialize a DistributedMesh for non-distributed-mesh capable code paths.
uint8_t dof_id_type
Definition id_types.h:67

References _internal_boundary_mesh, and sanityCheck().

◆ testMesh()

void BoundaryMeshTest::testMesh ( )
inline

Definition at line 414 of file boundary_mesh.C.

415 {
416 LOG_UNIT_TEST;
417
418 // There'd better be 3*5 + 5 elements in the interior plus right
419 // boundary
420 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(20),
421 _mesh->n_elem());
422
423 // There'd better be 7*11 nodes in the interior
424 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(77),
425 _mesh->n_nodes());
426
427 // There'd better be 2*(3+5) elements on the exterior boundary
428 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(16),
429 _exterior_boundary_mesh->n_elem());
430
431 // There'd better be 2*2*(3+5) nodes on the exterior boundary
432 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(32),
433 _exterior_boundary_mesh->n_nodes());
434
435 // There'd better be 5 elements on the left boundary
436 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(5),
437 _left_boundary_mesh->n_elem());
438
439 // There'd better be 2*5+1 nodes on the left boundary
440 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(11),
441 _left_boundary_mesh->n_nodes());
442
443 // There are four elements in the one-sided internal sideset mesh.
444 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(4),
445 _internal_boundary_mesh->n_elem());
446
447 // There are 2*n_elem + 1 nodes in the one-sided internal sideset mesh.
448 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(9),
449 _internal_boundary_mesh->n_nodes());
450
451 // There'd better be 3+5 + 4 elements on the multi-boundary
452 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(12),
453 _multi_boundary_mesh->n_elem());
454
455 // There'd better be (3+5)*2+1 + 4*2+1 nodes on the multi-boundary
456 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(26),
457 _multi_boundary_mesh->n_nodes());
458
459 this->sanityCheck();
460 }

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

Member Data Documentation

◆ _exterior_boundary_mesh

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

◆ _internal_boundary_mesh

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

◆ _left_boundary_mesh

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

◆ _mesh

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

◆ _multi_boundary_mesh

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

◆ bid1

constexpr boundary_id_type BoundaryMeshTest::bid1 = 5
staticconstexprprotected

Definition at line 268 of file boundary_mesh.C.

Referenced by build_mesh(), and sync_and_test_meshes().

◆ bid2

constexpr boundary_id_type BoundaryMeshTest::bid2 = 6
staticconstexprprotected

Definition at line 269 of file boundary_mesh.C.

Referenced by build_mesh(), and sync_and_test_meshes().


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