547 {
548 LOG_UNIT_TEST;
549
550#if LIBMESH_DIM > 1
551 Mesh
mesh(*TestCommWorld);
552 MeshTools::Generation::build_square(
mesh, 1, 1, 0., 1., 0., 1., QUAD9);
553
554 auto range =
mesh.active_local_element_ptr_range();
555 if (range.begin() == range.end())
556 return;
557
558 const Elem * elem = *range.begin();
559 CPPUNIT_ASSERT_EQUAL(static_cast<int>(QUAD9),
560 static_cast<int>(elem->type()));
561
562 const FEType fe_type(CONSTANT, SIDE_HIERARCHIC);
563 const std::vector<Number> elem_soln = {1, 3, 5, 7};
564
565 std::vector<Number> nodal_soln;
566 FEInterface::nodal_soln(2,
567 fe_type,
568 elem,
569 elem_soln,
570 nodal_soln,
571 false);
572
573 CPPUNIT_ASSERT_EQUAL(std::size_t(9), nodal_soln.size());
574
575 std::vector<Number> expected(nodal_soln.size(), 0);
576 std::vector<unsigned int> expected_count(nodal_soln.size(), 0);
577 for (const auto side : elem->side_index_range())
578 for (const auto n : elem->nodes_on_side(side))
579 {
580 expected[n] += elem_soln[side];
581 ++expected_count[n];
582 }
583
584 unsigned int n_nodes_without_side_value = 0;
586 {
587 if (expected_count[n])
588 expected[n] /= expected_count[n];
589 else
590 ++n_nodes_without_side_value;
591
592 LIBMESH_ASSERT_NUMBERS_EQUAL(expected[n],
593 nodal_soln[n],
594 TOLERANCE * TOLERANCE);
595 }
596
597 CPPUNIT_ASSERT_EQUAL(1u, n_nodes_without_side_value);
598#endif
599 }
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...