Skip to content

Commit 1d1043a

Browse files
committed
Add proper out-of-mesh case to out-of-mesh test
ChatGPT added test coverage to the less important of the use cases here; let's test the more important too.
1 parent 15533c4 commit 1d1043a

1 file changed

Lines changed: 60 additions & 20 deletions

File tree

tests/mesh/mesh_function.C

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -191,52 +191,72 @@ public:
191191

192192
EquationSystems es(mesh);
193193
System & sys = es.add_system<System>("SimpleSystem");
194-
unsigned int u_var = sys.add_variable("u", FIRST, LAGRANGE);
194+
const unsigned int u_var = sys.add_variable("u", FIRST, LAGRANGE);
195+
const unsigned int v_var = sys.add_variable("v", CONSTANT, MONOMIAL);
195196

196197
es.init();
197198
sys.project_solution(bilinear_function, nullptr, es.parameters);
198199

199-
std::vector<unsigned int> variables {u_var, libMesh::invalid_uint};
200+
std::vector<unsigned int> variables {u_var, v_var, libMesh::invalid_uint};
200201
MeshFunction mesh_function(es,
201202
*sys.current_local_solution,
202203
sys.get_dof_map(),
203204
variables);
204205
mesh_function.init();
205206

206-
DenseVector<Number> out_of_mesh_value(2);
207+
DenseVector<Number> out_of_mesh_value(3);
207208
out_of_mesh_value(0) = -99.0;
208209
out_of_mesh_value(1) = 5.25;
210+
out_of_mesh_value(1) = 42;
209211
mesh_function.enable_out_of_mesh_mode(out_of_mesh_value);
210212

211-
std::vector<Gradient> gradients;
212-
const Point p(0.4, 0.6, 0.0);
213+
// Pick an element centroid so u and v agree
214+
const Point good_p(0.375, 0.625, 0.0);
213215

214216
// On a distributed mesh not every processor may have every
215217
// element
216-
const Elem * elem = (*mesh.sub_point_locator())(p);
218+
const Elem * elem = (*mesh.sub_point_locator())(good_p);
217219
bool someone_found_elem = elem;
218220
mesh.comm().max(someone_found_elem);
219221
CPPUNIT_ASSERT(someone_found_elem);
220222

221-
mesh_function.gradient(p, 0.0, gradients);
223+
std::vector<Gradient> gradients;
224+
mesh_function.gradient(good_p, 0.0, gradients);
225+
226+
CPPUNIT_ASSERT_EQUAL(std::size_t(3), gradients.size());
222227

223228
// Let's only test our evaluation where we know we can evaluate, in parallel
224229
if (!elem || elem->processor_id() != mesh.processor_id())
225230
return;
226231

227-
CPPUNIT_ASSERT_EQUAL(std::size_t(2), gradients.size());
228-
229232
LIBMESH_ASSERT_NUMBERS_EQUAL(8.0, gradients[0](0), TOLERANCE * TOLERANCE);
230233
LIBMESH_ASSERT_NUMBERS_EQUAL(80.0, gradients[0](1), TOLERANCE * TOLERANCE);
231234
if (LIBMESH_DIM > 2)
232235
LIBMESH_ASSERT_NUMBERS_EQUAL(0.0, gradients[0](2), TOLERANCE * TOLERANCE);
233236

234-
LIBMESH_ASSERT_NUMBERS_EQUAL(out_of_mesh_value(1),
235-
gradients[1](0),
237+
// Piecewise-constant functions have zero gradients
238+
for (unsigned int d = 0; d < LIBMESH_DIM; ++d)
239+
LIBMESH_ASSERT_NUMBERS_EQUAL(0, gradients[1](d), TOLERANCE * TOLERANCE);
240+
241+
LIBMESH_ASSERT_NUMBERS_EQUAL(out_of_mesh_value(2),
242+
gradients[2](0),
236243
TOLERANCE * TOLERANCE);
237244
for (unsigned int d = 1; d < LIBMESH_DIM; ++d)
238-
LIBMESH_ASSERT_NUMBERS_EQUAL(0, gradients[1](d),
245+
LIBMESH_ASSERT_NUMBERS_EQUAL(0, gradients[2](d),
239246
TOLERANCE * TOLERANCE);
247+
248+
const Point bad_p(1.375, 0.625, 0.0);
249+
mesh_function.gradient(bad_p, 0.0, gradients);
250+
251+
for (unsigned int vn = 0; vn != 3; ++vn)
252+
{
253+
LIBMESH_ASSERT_NUMBERS_EQUAL(out_of_mesh_value(vn),
254+
gradients[vn](0),
255+
TOLERANCE * TOLERANCE);
256+
for (unsigned int d = 1; d < LIBMESH_DIM; ++d)
257+
LIBMESH_ASSERT_NUMBERS_EQUAL(0, gradients[vn](d),
258+
TOLERANCE * TOLERANCE);
259+
}
240260
}
241261

242262
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
@@ -258,20 +278,22 @@ public:
258278
EquationSystems es(mesh);
259279
System & sys = es.add_system<System>("SimpleSystem");
260280
unsigned int u_var = sys.add_variable("u", SECOND, LAGRANGE);
281+
unsigned int v_var = sys.add_variable("v", CONSTANT, MONOMIAL);
261282

262283
es.init();
263284
sys.project_solution(biquadratic_function, nullptr, es.parameters);
264285

265-
std::vector<unsigned int> variables {u_var, libMesh::invalid_uint};
286+
std::vector<unsigned int> variables {u_var, v_var, libMesh::invalid_uint};
266287
MeshFunction mesh_function(es,
267288
*sys.current_local_solution,
268289
sys.get_dof_map(),
269290
variables);
270291
mesh_function.init();
271292

272-
DenseVector<Number> out_of_mesh_value(2);
293+
DenseVector<Number> out_of_mesh_value(3);
273294
out_of_mesh_value(0) = -99.0;
274295
out_of_mesh_value(1) = 5.25;
296+
out_of_mesh_value(2) = 42;
275297
mesh_function.enable_out_of_mesh_mode(out_of_mesh_value);
276298

277299
std::vector<Tensor> hessians;
@@ -286,12 +308,12 @@ public:
286308

287309
mesh_function.hessian(p, 0.0, hessians);
288310

311+
CPPUNIT_ASSERT_EQUAL(std::size_t(3), hessians.size());
312+
289313
// Let's only test our evaluation where we know we can evaluate, in parallel
290314
if (!elem || elem->processor_id() != mesh.processor_id())
291315
return;
292316

293-
CPPUNIT_ASSERT_EQUAL(std::size_t(2), hessians.size());
294-
295317
LIBMESH_ASSERT_NUMBERS_EQUAL(15.0, hessians[0](0,0), tol);
296318
LIBMESH_ASSERT_NUMBERS_EQUAL(0.75, hessians[0](0,1), tol);
297319
LIBMESH_ASSERT_NUMBERS_EQUAL(0.75, hessians[0](1,0), tol);
@@ -301,17 +323,35 @@ public:
301323
for (unsigned int d = 0; d < LIBMESH_DIM; ++d)
302324
for (unsigned int d2 = 0; d2 < LIBMESH_DIM; ++d2)
303325
if (d>1 || d2>1)
304-
LIBMESH_ASSERT_NUMBERS_EQUAL(0, hessians[1](d,d2),
326+
LIBMESH_ASSERT_NUMBERS_EQUAL(0, hessians[0](d,d2),
305327
tol);
306328

307-
LIBMESH_ASSERT_NUMBERS_EQUAL(out_of_mesh_value(1),
308-
hessians[1](0,0),
329+
// Piecewise-constant functions have zero Hessians
330+
for (unsigned int d = 0; d < LIBMESH_DIM; ++d)
331+
for (unsigned int d2 = 0; d2 < LIBMESH_DIM; ++d2)
332+
LIBMESH_ASSERT_NUMBERS_EQUAL(0, hessians[1](d,d2), tol);
333+
334+
LIBMESH_ASSERT_NUMBERS_EQUAL(out_of_mesh_value(2),
335+
hessians[2](0,0),
309336
tol);
310337
for (unsigned int d = 0; d < LIBMESH_DIM; ++d)
311338
for (unsigned int d2 = 0; d2 < LIBMESH_DIM; ++d2)
312339
if (d || d2)
313-
LIBMESH_ASSERT_NUMBERS_EQUAL(0, hessians[1](d,d2),
340+
LIBMESH_ASSERT_NUMBERS_EQUAL(0, hessians[2](d,d2),
314341
tol);
342+
343+
const Point bad_p(1.375, 0.625, 0.0);
344+
mesh_function.hessian(bad_p, 0.0, hessians);
345+
346+
for (unsigned int vn = 0; vn != 2; ++vn)
347+
{
348+
LIBMESH_ASSERT_NUMBERS_EQUAL(out_of_mesh_value(vn),
349+
hessians[vn](0,0), tol);
350+
for (unsigned int d = 0; d < LIBMESH_DIM; ++d)
351+
for (unsigned int d2 = 0; d2 < LIBMESH_DIM; ++d2)
352+
if (d || d2)
353+
LIBMESH_ASSERT_NUMBERS_EQUAL(0, hessians[vn](d,d2), tol);
354+
}
315355
}
316356
#endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
317357

0 commit comments

Comments
 (0)