Skip to content

Commit 6f21dc9

Browse files
authored
Merge pull request #4391 from roystgnr/out_of_mesh_chatgpt
Test for out-of-mesh-value on bad MeshFunction variable indices
2 parents d9a8a89 + 5244b48 commit 6f21dc9

1 file changed

Lines changed: 161 additions & 0 deletions

File tree

tests/mesh/mesh_function.C

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,25 @@ Number trilinear_function (const Point & p,
3434
}
3535

3636

37+
Number bilinear_function (const Point & p,
38+
const Parameters &,
39+
const std::string &,
40+
const std::string &)
41+
{
42+
return 8*p(0) + 80*p(1);
43+
}
44+
45+
46+
Number biquadratic_function (const Point & p,
47+
const Parameters &,
48+
const std::string &,
49+
const std::string &)
50+
{
51+
return 7.5*p(0)*p(0) + 75*p(1)*p(1) + 0.75*p(1)*p(0);
52+
}
53+
54+
55+
3756
class MeshFunctionTest : public CppUnit::TestCase
3857
{
3958
/**
@@ -44,6 +63,10 @@ public:
4463

4564
#if LIBMESH_DIM > 1
4665
CPPUNIT_TEST( test_subdomain_id_sets );
66+
CPPUNIT_TEST( test_bad_gradient_var_with_out_of_mesh_value );
67+
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
68+
CPPUNIT_TEST( test_bad_hessian_var_with_out_of_mesh_value );
69+
#endif
4770
#ifdef LIBMESH_HAVE_PETSC
4871
CPPUNIT_TEST( vectorMeshFunctionLagrange );
4972
CPPUNIT_TEST( vectorMeshFunctionNedelec );
@@ -154,6 +177,144 @@ public:
154177
}
155178
}
156179

180+
void test_bad_gradient_var_with_out_of_mesh_value()
181+
{
182+
LOG_UNIT_TEST;
183+
184+
ReplicatedMesh mesh(*TestCommWorld);
185+
186+
MeshTools::Generation::build_square(mesh,
187+
4, 4,
188+
0., 1.,
189+
0., 1.,
190+
QUAD4);
191+
192+
EquationSystems es(mesh);
193+
System & sys = es.add_system<System>("SimpleSystem");
194+
unsigned int u_var = sys.add_variable("u", FIRST, LAGRANGE);
195+
196+
es.init();
197+
sys.project_solution(bilinear_function, nullptr, es.parameters);
198+
199+
std::vector<unsigned int> variables {u_var, libMesh::invalid_uint};
200+
MeshFunction mesh_function(es,
201+
*sys.current_local_solution,
202+
sys.get_dof_map(),
203+
variables);
204+
mesh_function.init();
205+
206+
DenseVector<Number> out_of_mesh_value(2);
207+
out_of_mesh_value(0) = -99.0;
208+
out_of_mesh_value(1) = 5.25;
209+
mesh_function.enable_out_of_mesh_mode(out_of_mesh_value);
210+
211+
std::vector<Gradient> gradients;
212+
const Point p(0.4, 0.6, 0.0);
213+
214+
// On a distributed mesh not every processor may have every
215+
// element
216+
const Elem * elem = (*mesh.sub_point_locator())(p);
217+
bool someone_found_elem = elem;
218+
mesh.comm().max(someone_found_elem);
219+
CPPUNIT_ASSERT(someone_found_elem);
220+
221+
mesh_function.gradient(p, 0.0, gradients);
222+
223+
// Let's only test our evaluation where we know we can evaluate, in parallel
224+
if (!elem || elem->processor_id() != mesh.processor_id())
225+
return;
226+
227+
CPPUNIT_ASSERT_EQUAL(std::size_t(2), gradients.size());
228+
229+
LIBMESH_ASSERT_NUMBERS_EQUAL(8.0, gradients[0](0), TOLERANCE * TOLERANCE);
230+
LIBMESH_ASSERT_NUMBERS_EQUAL(80.0, gradients[0](1), TOLERANCE * TOLERANCE);
231+
if (LIBMESH_DIM > 2)
232+
LIBMESH_ASSERT_NUMBERS_EQUAL(0.0, gradients[0](2), TOLERANCE * TOLERANCE);
233+
234+
LIBMESH_ASSERT_NUMBERS_EQUAL(out_of_mesh_value(1),
235+
gradients[1](0),
236+
TOLERANCE * TOLERANCE);
237+
for (unsigned int d = 1; d < LIBMESH_DIM; ++d)
238+
LIBMESH_ASSERT_NUMBERS_EQUAL(0, gradients[1](d),
239+
TOLERANCE * TOLERANCE);
240+
}
241+
242+
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
243+
void test_bad_hessian_var_with_out_of_mesh_value()
244+
{
245+
LOG_UNIT_TEST;
246+
247+
// Hessian calculations are a little weaker in FP on some systems
248+
const Real tol = TOLERANCE * std::sqrt(TOLERANCE);
249+
250+
ReplicatedMesh mesh(*TestCommWorld);
251+
252+
MeshTools::Generation::build_square(mesh,
253+
4, 4,
254+
0., 1.,
255+
0., 1.,
256+
QUAD9);
257+
258+
EquationSystems es(mesh);
259+
System & sys = es.add_system<System>("SimpleSystem");
260+
unsigned int u_var = sys.add_variable("u", SECOND, LAGRANGE);
261+
262+
es.init();
263+
sys.project_solution(biquadratic_function, nullptr, es.parameters);
264+
265+
std::vector<unsigned int> variables {u_var, libMesh::invalid_uint};
266+
MeshFunction mesh_function(es,
267+
*sys.current_local_solution,
268+
sys.get_dof_map(),
269+
variables);
270+
mesh_function.init();
271+
272+
DenseVector<Number> out_of_mesh_value(2);
273+
out_of_mesh_value(0) = -99.0;
274+
out_of_mesh_value(1) = 5.25;
275+
mesh_function.enable_out_of_mesh_mode(out_of_mesh_value);
276+
277+
std::vector<Tensor> hessians;
278+
const Point p(0.4, 0.6, 0.0);
279+
280+
// On a distributed mesh not every processor may have every
281+
// element
282+
const Elem * elem = (*mesh.sub_point_locator())(p);
283+
bool someone_found_elem = elem;
284+
mesh.comm().max(someone_found_elem);
285+
CPPUNIT_ASSERT(someone_found_elem);
286+
287+
mesh_function.hessian(p, 0.0, hessians);
288+
289+
// Let's only test our evaluation where we know we can evaluate, in parallel
290+
if (!elem || elem->processor_id() != mesh.processor_id())
291+
return;
292+
293+
CPPUNIT_ASSERT_EQUAL(std::size_t(2), hessians.size());
294+
295+
LIBMESH_ASSERT_NUMBERS_EQUAL(15.0, hessians[0](0,0), tol);
296+
LIBMESH_ASSERT_NUMBERS_EQUAL(0.75, hessians[0](0,1), tol);
297+
LIBMESH_ASSERT_NUMBERS_EQUAL(0.75, hessians[0](1,0), tol);
298+
LIBMESH_ASSERT_NUMBERS_EQUAL(150.0, hessians[0](1,1), tol);
299+
300+
if (LIBMESH_DIM > 2)
301+
for (unsigned int d = 0; d < LIBMESH_DIM; ++d)
302+
for (unsigned int d2 = 0; d2 < LIBMESH_DIM; ++d2)
303+
if (d>1 || d2>1)
304+
LIBMESH_ASSERT_NUMBERS_EQUAL(0, hessians[1](d,d2),
305+
tol);
306+
307+
LIBMESH_ASSERT_NUMBERS_EQUAL(out_of_mesh_value(1),
308+
hessians[1](0,0),
309+
tol);
310+
for (unsigned int d = 0; d < LIBMESH_DIM; ++d)
311+
for (unsigned int d2 = 0; d2 < LIBMESH_DIM; ++d2)
312+
if (d || d2)
313+
LIBMESH_ASSERT_NUMBERS_EQUAL(0, hessians[1](d,d2),
314+
tol);
315+
}
316+
#endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
317+
157318
// test that mesh function works correctly with non-zero
158319
// Elem::p_level() values.
159320
#ifdef LIBMESH_ENABLE_AMR

0 commit comments

Comments
 (0)