Skip to content

Commit f956256

Browse files
committed
Protect MeshRefinement from disconnected boundary meshes and add regression test.
- Added safety check in MeshRefinement::refine_elements() to prevent refinement when disconnected boundary interfaces are present. Refinement on such meshes can produce invalid neighbor relations (e.g., rev = invalid_uint). - Extended disconnected_neighbor_test with new testTempJumpLocalRefineFail() that verifies the exception is thrown.
1 parent 5301b91 commit f956256

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

src/mesh/mesh_refinement.C

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,25 @@ bool MeshRefinement::refine_elements ()
684684
// This function must be run on all processors at once
685685
parallel_object_only();
686686

687+
// Prevent refinement when the mesh has disconnected boundaries.
688+
//
689+
// Disconnected boundary interfaces violate the topological continuity
690+
// assumed by the refinement algorithm. Refinement on such meshes can
691+
// produce invalid neighbor relationships (for example reverse indices
692+
// equal to invalid_uint), which may trigger assertions like
693+
// `rev < neigh->n_neighbors()` or corrupt neighbor data.
694+
//
695+
// For safety, refinement is disabled while disconnected boundaries are
696+
// present.
697+
if (_mesh.get_disconnected_boundaries())
698+
{
699+
libmesh_error_msg(
700+
"Mesh contains disconnected boundary interfaces; refinement is disabled.\n"
701+
"MeshRefinement::refine_elements() cannot proceed because disconnected\n"
702+
"boundaries may produce invalid neighbor relations. Please remove or\n"
703+
"repair disconnected boundary interfaces before attempting refinement.");
704+
}
705+
687706
if (_face_level_mismatch_limit)
688707
libmesh_assert(test_level_one(true));
689708

tests/systems/disconnected_neighbor_test.C

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include "test_comm.h"
1616
#include "libmesh_cppunit.h"
1717

18+
#include "libmesh/mesh_refinement.h"
19+
1820
using namespace libMesh;
1921

2022
static const Real b = 1.0;
@@ -185,6 +187,10 @@ public:
185187
#if defined(LIBMESH_HAVE_SOLVER)
186188
CPPUNIT_TEST( testTempJump );
187189
CPPUNIT_TEST( testTempJumpRefine );
190+
// This test intentionally triggers find_neighbors() consistency check
191+
// failure after AMR refinement across disconnected interfaces.
192+
// Expected: libmesh_assert_valid_neighbors() fails.
193+
CPPUNIT_TEST_EXCEPTION(testTempJumpLocalRefineFail, std::exception);
188194
#endif
189195
CPPUNIT_TEST_SUITE_END();
190196

@@ -387,8 +393,22 @@ private:
387393
}
388394

389395

396+
void testTempJumpLocalRefineFail()
397+
{
398+
try
399+
{
400+
Mesh mesh(*TestCommWorld, 2);
401+
build_split_mesh_with_interface(mesh, true);
402+
}
403+
catch (const std::exception &e)
404+
{
405+
CPPUNIT_ASSERT(std::string(e.what()).find("Mesh contains disconnected boundary interfaces") != std::string::npos);
406+
throw;
407+
}
408+
}
409+
390410
// The interface is located at x = 0.5; nx must be even (split evenly into left and right subdomains)
391-
void build_split_mesh_with_interface(Mesh &mesh)
411+
void build_split_mesh_with_interface(Mesh &mesh, bool test_local_refinement = false)
392412
{
393413
// Ensure nx is even so the interface aligns with element boundaries
394414
libmesh_error_msg_if(nx % 2 != 0, "nx must be even!");
@@ -495,7 +515,25 @@ private:
495515
mesh.add_disconnected_boundaries(interface_left_id, interface_right_id, RealVectorValue(0.0, 0.0, 0.0));
496516

497517
mesh.prepare_for_use();
518+
519+
#if LIBMESH_ENABLE_AMR
520+
if (test_local_refinement)
521+
{
522+
// set refinement flags
523+
for (auto & elem : mesh.element_ptr_range())
524+
{
525+
const Real xmid = elem->vertex_average()(0);
526+
if ((xmid < 0.5 && xmid > 0.5 - dx) ||
527+
(xmid > 0.5 && xmid < 0.5 + dx))
528+
elem->set_refinement_flag(Elem::REFINE);
529+
}
530+
531+
// refine
532+
MeshRefinement(mesh).refine_elements();
533+
}
534+
#endif
498535
}
536+
499537
};
500538

501539
CPPUNIT_TEST_SUITE_REGISTRATION( DisconnectedNeighborTest );

0 commit comments

Comments
 (0)