13
13
#include "test_comm.h"
14
14
#include "libmesh_cppunit.h"
15
15
16
+ #include <regex>
16
17
17
18
using namespace libMesh ;
18
19
@@ -29,6 +30,7 @@ public:
29
30
CPPUNIT_TEST ( testMesh );
30
31
CPPUNIT_TEST ( testRenumber );
31
32
#ifdef LIBMESH_ENABLE_AMR
33
+ CPPUNIT_TEST ( testBoundaryOnChildrenErrors );
32
34
CPPUNIT_TEST ( testBoundaryOnChildrenElementsRefineCoarsen );
33
35
CPPUNIT_TEST ( testBoundaryOnChildrenBoundaryIDs );
34
36
CPPUNIT_TEST ( testBoundaryOnChildrenBoundarySides );
@@ -481,6 +483,101 @@ public:
481
483
#endif // LIBMESH_ENABLE_DIRICHLET
482
484
483
485
#ifdef LIBMESH_ENABLE_AMR
486
+ void testBoundaryOnChildrenErrors ()
487
+ {
488
+ LOG_UNIT_TEST ;
489
+
490
+ // We create one cell only. The default boundaries of the cell are below.
491
+ // ___2___
492
+ // 3 | | 1
493
+ // |_____|
494
+ // 0
495
+
496
+ auto mesh = std ::make_unique < Mesh > (* TestCommWorld );
497
+ MeshTools ::Generation ::build_square (* mesh ,
498
+ 1 , 1 ,
499
+ 0. , 1. ,
500
+ 0. , 1. ,
501
+ QUAD4 );
502
+
503
+ BoundaryInfo & bi = mesh -> get_boundary_info ();
504
+
505
+ // We only have one element, but for easy access we use the iterator
506
+ for (auto & elem : mesh -> active_element_ptr_range ())
507
+ elem -> set_refinement_flag (Elem ::REFINE );
508
+ mesh -> prepare_for_use ();
509
+
510
+ MeshRefinement (* mesh ).refine_elements ();
511
+ mesh -> prepare_for_use ();
512
+
513
+ // Now we try to add boundary id 3 to a child on side 3. This should
514
+ // result in a "not implemented" error message
515
+ bool threw_desired_exception = false;
516
+ try {
517
+ for (auto & elem : mesh -> active_element_ptr_range ())
518
+ {
519
+ const Point c = elem -> vertex_average ();
520
+ if (c (0 ) < 0.5 && c (1 ) > 0.5 )
521
+ bi .add_side (elem , 3 , 3 );
522
+ }
523
+ }
524
+ catch (libMesh ::NotImplemented & e ) {
525
+ std ::regex msg_regex ("Trying to add boundary ID 3 which already exists on the ancestors" );
526
+ CPPUNIT_ASSERT (std ::regex_search (e .what (), msg_regex ));
527
+ threw_desired_exception = true;
528
+ }
529
+ // If we have more than 4 processors, or a poor partitioner, we
530
+ // might not get an exception on every processor
531
+ mesh -> comm ().max (threw_desired_exception );
532
+
533
+ CPPUNIT_ASSERT (threw_desired_exception );
534
+
535
+ threw_desired_exception = false;
536
+ try {
537
+ for (auto & elem : mesh -> active_element_ptr_range ())
538
+ {
539
+ const Point c = elem -> vertex_average ();
540
+ if (c (0 ) < 0.5 && c (1 ) > 0.5 )
541
+ bi .add_side (elem , 3 , {3 ,4 });
542
+ }
543
+ }
544
+ catch (libMesh ::NotImplemented & e ) {
545
+ std ::regex msg_regex ("Trying to add boundary ID 3 which already exists on the ancestors" );
546
+ CPPUNIT_ASSERT (std ::regex_search (e .what (), msg_regex ));
547
+ threw_desired_exception = true;
548
+ }
549
+
550
+ // If we have more than 4 processors, or a poor partitioner, we
551
+ // might not get an exception on every processor
552
+ mesh -> comm ().max (threw_desired_exception );
553
+
554
+ CPPUNIT_ASSERT (threw_desired_exception );
555
+
556
+ // We tested the side addition errors, now we move to the removal parts.
557
+ // We will attempt the removal of boundary 3 through the child
558
+ threw_desired_exception = false;
559
+ bi .allow_children_on_boundary_side (true);
560
+ try {
561
+ for (auto & elem : mesh -> active_element_ptr_range ())
562
+ {
563
+ const Point c = elem -> vertex_average ();
564
+ if (c (0 ) < 0.5 && c (1 ) > 0.5 )
565
+ bi .remove_side (elem , 3 , 3 );
566
+ }
567
+ }
568
+ catch (libMesh ::NotImplemented & e ) {
569
+ std ::regex msg_regex ("We cannot delete boundary ID 3 using a child because it is inherited from an ancestor" );
570
+ CPPUNIT_ASSERT (std ::regex_search (e .what (), msg_regex ));
571
+ threw_desired_exception = true;
572
+ }
573
+
574
+ // If we have more than 4 processors, or a poor partitioner, we
575
+ // might not get an exception on every processor
576
+ mesh -> comm ().max (threw_desired_exception );
577
+
578
+ CPPUNIT_ASSERT (threw_desired_exception );
579
+ }
580
+
484
581
void testBoundaryOnChildrenElementsRefineCoarsen ()
485
582
{
486
583
LOG_UNIT_TEST ;
@@ -618,8 +715,6 @@ public:
618
715
619
716
BoundaryInfo & bi = mesh -> get_boundary_info ();
620
717
621
- std ::ostringstream mystream ;
622
-
623
718
// We only have one element, but for easy access we use the iterator
624
719
for (auto & elem : mesh -> active_element_ptr_range ())
625
720
elem -> set_refinement_flag (Elem ::REFINE );
0 commit comments