Skip to content

Commit a3571d7

Browse files
committed
Add some unit tests for partial mesh preparation
This hits the easiest-to-set-up partially-unprepared cases, and even that was enough to expose a subtle bug or two.
1 parent a7258c0 commit a3571d7

1 file changed

Lines changed: 140 additions & 5 deletions

File tree

tests/mesh/mesh_base_test.C

Lines changed: 140 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ public:
2222

2323
/* Tests need a 2d mesh */
2424
#if LIBMESH_DIM > 1
25+
CPPUNIT_TEST( testDistributedMeshVerifyHasNeighborPtrs );
26+
CPPUNIT_TEST( testMeshVerifyHasNeighborPtrs );
27+
CPPUNIT_TEST( testReplicatedMeshVerifyHasNeighborPtrs );
28+
CPPUNIT_TEST( testDistributedMeshVerifyHasCachedElemData );
29+
CPPUNIT_TEST( testMeshVerifyHasCachedElemData );
30+
CPPUNIT_TEST( testReplicatedMeshVerifyHasCachedElemData );
31+
CPPUNIT_TEST( testDistributedMeshVerifyRemovalPreparation );
32+
CPPUNIT_TEST( testMeshVerifyRemovalPreparation );
33+
CPPUNIT_TEST( testReplicatedMeshVerifyRemovalPreparation );
2534
CPPUNIT_TEST( testDistributedMeshVerifyIsPrepared );
2635
CPPUNIT_TEST( testMeshVerifyIsPrepared );
2736
CPPUNIT_TEST( testReplicatedMeshVerifyIsPrepared );
@@ -35,7 +44,7 @@ public:
3544

3645
void tearDown() {}
3746

38-
void testMeshBaseVerifyIsPrepared(UnstructuredMesh & mesh)
47+
void BrokenNeighborMesh(UnstructuredMesh & mesh)
3948
{
4049
/**
4150
* Build a 2d 2x2 square mesh (mesh_one) covering [0.0, 1.0] x [0.0, 1.0]
@@ -47,10 +56,6 @@ public:
4756
0., 1.,
4857
QUAD9);
4958

50-
// build_square does its own prepare_for_use(), so we should be
51-
// prepared.
52-
CPPUNIT_ASSERT(MeshTools::valid_is_prepared(mesh));
53-
5459
// Break some neighbor links. Of course nobody would do this in
5560
// real life, right?
5661
Elem * elem0 = mesh.query_elem_ptr(0);
@@ -66,6 +71,136 @@ public:
6671
elem0->set_neighbor(n, nullptr);
6772
neigh->set_neighbor(n_neigh, nullptr);
6873
}
74+
}
75+
76+
void testMeshBaseVerifyHasNeighborPtrs(UnstructuredMesh & mesh)
77+
{
78+
this->BrokenNeighborMesh(mesh);
79+
mesh.unset_has_neighbor_ptrs();
80+
mesh.complete_preparation();
81+
CPPUNIT_ASSERT(mesh.is_prepared());
82+
CPPUNIT_ASSERT(MeshTools::valid_is_prepared(mesh));
83+
}
84+
85+
void testDistributedMeshVerifyHasNeighborPtrs ()
86+
{
87+
DistributedMesh mesh(*TestCommWorld);
88+
testMeshBaseVerifyHasNeighborPtrs(mesh);
89+
}
90+
91+
void testMeshVerifyHasNeighborPtrs ()
92+
{
93+
Mesh mesh(*TestCommWorld);
94+
testMeshBaseVerifyHasNeighborPtrs(mesh);
95+
}
96+
97+
void testReplicatedMeshVerifyHasNeighborPtrs ()
98+
{
99+
ReplicatedMesh mesh(*TestCommWorld);
100+
testMeshBaseVerifyHasNeighborPtrs(mesh);
101+
}
102+
103+
void testMeshBaseVerifyHasCachedElemData(UnstructuredMesh & mesh)
104+
{
105+
/**
106+
* Build a 2d 2x2 square mesh (mesh_one) covering [0.0, 1.0] x [0.0, 1.0]
107+
* with linear Quad elements.
108+
*/
109+
MeshTools::Generation::build_square(mesh,
110+
2, 2,
111+
0., 1.,
112+
0., 1.,
113+
QUAD9);
114+
115+
// Invalidate the subdomain ids cache
116+
Elem * elem0 = mesh.query_elem_ptr(0);
117+
if (elem0)
118+
elem0->subdomain_id() = 1;
119+
120+
// We're unprepared (prepare_for_use() will update that cache) but
121+
// we're not marked that way.
122+
CPPUNIT_ASSERT(!MeshTools::valid_is_prepared(mesh));
123+
124+
mesh.unset_has_cached_elem_data();
125+
mesh.complete_preparation();
126+
CPPUNIT_ASSERT(mesh.is_prepared());
127+
CPPUNIT_ASSERT(MeshTools::valid_is_prepared(mesh));
128+
}
129+
130+
void testDistributedMeshVerifyHasCachedElemData ()
131+
{
132+
DistributedMesh mesh(*TestCommWorld);
133+
testMeshBaseVerifyHasCachedElemData(mesh);
134+
}
135+
136+
void testMeshVerifyHasCachedElemData ()
137+
{
138+
Mesh mesh(*TestCommWorld);
139+
testMeshBaseVerifyHasCachedElemData(mesh);
140+
}
141+
142+
void testReplicatedMeshVerifyHasCachedElemData ()
143+
{
144+
ReplicatedMesh mesh(*TestCommWorld);
145+
testMeshBaseVerifyHasCachedElemData(mesh);
146+
}
147+
148+
void testMeshBaseVerifyRemovalPreparation(UnstructuredMesh & mesh)
149+
{
150+
/**
151+
* Build a 2d 2x2 square mesh (mesh_one) covering [0.0, 1.0] x [0.0, 1.0]
152+
* with linear Quad elements.
153+
*/
154+
MeshTools::Generation::build_square(mesh,
155+
2, 2,
156+
0., 1.,
157+
0., 1.,
158+
QUAD9);
159+
160+
// Remove elements on one side, orphaning 4 nodes and removing one
161+
// boundary condition. Remove dangling neighbor pointers too; we
162+
// can't even clone a mesh with dangling pointers.
163+
for (auto & elem : mesh.element_ptr_range())
164+
if (elem->vertex_average()(0) > 0.5)
165+
mesh.delete_elem(elem);
166+
else
167+
elem->set_neighbor(1, nullptr);
168+
169+
// We're unprepared (prepare_for_use() will remove those orphaned
170+
// nodes and fix the boundary id sets and fix the partitioning of
171+
// nodes that might need new owners) but we're not marked that
172+
// way.
173+
CPPUNIT_ASSERT(!MeshTools::valid_is_prepared(mesh));
174+
175+
mesh.unset_is_partitioned();
176+
mesh.unset_has_removed_orphaned_nodes();
177+
mesh.unset_has_boundary_id_sets();
178+
mesh.complete_preparation();
179+
CPPUNIT_ASSERT(mesh.is_prepared());
180+
CPPUNIT_ASSERT(MeshTools::valid_is_prepared(mesh));
181+
}
182+
183+
void testDistributedMeshVerifyRemovalPreparation ()
184+
{
185+
DistributedMesh mesh(*TestCommWorld);
186+
testMeshBaseVerifyRemovalPreparation(mesh);
187+
}
188+
189+
void testMeshVerifyRemovalPreparation ()
190+
{
191+
Mesh mesh(*TestCommWorld);
192+
testMeshBaseVerifyRemovalPreparation(mesh);
193+
}
194+
195+
void testReplicatedMeshVerifyRemovalPreparation ()
196+
{
197+
ReplicatedMesh mesh(*TestCommWorld);
198+
testMeshBaseVerifyRemovalPreparation(mesh);
199+
}
200+
201+
void testMeshBaseVerifyIsPrepared(UnstructuredMesh & mesh)
202+
{
203+
this->BrokenNeighborMesh(mesh);
69204

70205
// We're unprepared (prepare_for_use() will restitch those
71206
// neighbor pointers) but we're not marked that way.

0 commit comments

Comments
 (0)