3#include <libmesh/boundary_info.h>
4#include <libmesh/enum_elem_quality.h>
5#include <libmesh/elem_side_builder.h>
6#include <libmesh/mesh_modification.h>
7#include <libmesh/mesh_refinement.h>
8#include <libmesh/parallel_implementation.h>
9#include <libmesh/remote_elem.h>
10#include <libmesh/enum_to_string.h>
11#include <libmesh/elem_quality.h>
12#include <libmesh/node.h>
16template <ElemType elem_type>
23 for (
const auto & elem :
24 this->
_mesh->active_local_element_ptr_range())
26 const BoundingBox bbox = elem->loose_bounding_box();
32 BoundingBox wide_bbox(elem->point(0), elem->point(0));
34 for (
unsigned int n = 0; n != elem->n_nodes(); ++n)
36 const Point & p = elem->point(n);
38 if (!elem->infinite())
45 wide_bbox.
scale(1. / 3.);
47 if (!elem->infinite() && elem->dim())
59 for (
const auto & elem : this->
_mesh->active_local_element_ptr_range())
66 if (elem->runtime_topology())
71 for (
auto i : elem->node_index_range())
73 LIBMESH_ASSERT_REALVEC_EQUAL(elem->master_point(i),
87 for (
const auto & elem : this->
_mesh->active_local_element_ptr_range())
91 for (
const auto s : elem->side_index_range())
94 CPPUNIT_ASSERT_EQUAL(elem->side_type(s), side_type);
100 if (elem->runtime_topology() || elem->infinite())
103 const auto nodes = elem->nodes_on_side(s);
108 CPPUNIT_ASSERT_EQUAL(elem->local_side_node(s, n),
110 CPPUNIT_ASSERT_EQUAL(nodes[n],
118 if (elem->infinite() || elem->dim() < 2)
121 for (
const auto e : elem->edge_index_range())
126 CPPUNIT_ASSERT_EQUAL(elem->build_edge_ptr(e)->type(),
129 if (elem->runtime_topology())
132 const auto nodes = elem->nodes_on_edge(e);
137 CPPUNIT_ASSERT_EQUAL(elem->local_edge_node(e, n),
139 CPPUNIT_ASSERT_EQUAL(nodes[n],
155 for (
const auto & elem : this->
_mesh->active_local_element_ptr_range())
157 if (elem->infinite() || elem->runtime_topology())
162 for (
const auto i : elem->node_index_range())
164 if (elem->is_vertex(i))
170 LIBMESH_ASSERT_REALVEC_EQUAL(
Point(i == 2 ?
Real(-1)/3 :
Real(1)/3),
171 elem->master_point(i),
179 std::vector<unsigned int> subentity_vertices;
181 for (
const auto e : elem->edge_index_range())
183 const auto nodes = elem->nodes_on_edge(e);
184 if (std::find(nodes.begin(), nodes.end(), i) != nodes.end())
185 subentity_vertices = {nodes[0], nodes[1]};
187 if (subentity_vertices.empty())
188 for (
const auto s : elem->side_index_range())
190 const auto nodes = elem->nodes_on_side(s);
191 if (std::find(nodes.begin(), nodes.end(), i) != nodes.end())
193 if (elem->is_vertex(n))
194 subentity_vertices.push_back(n);
196 if (subentity_vertices.empty())
197 for (
const auto n : elem->node_index_range())
198 if (elem->is_vertex(n))
199 subentity_vertices.push_back(n);
202 for (
auto v : subentity_vertices)
203 centroid += elem->master_point(v);
204 centroid /=
Real(subentity_vertices.size());
206 LIBMESH_ASSERT_REALVEC_EQUAL(centroid, elem->master_point(i),
216 for (
const auto & elem : this->
_mesh->active_local_element_ptr_range())
223 CPPUNIT_ASSERT_LESSEQUAL(edge_length_ratio,
Real(1));
231 CPPUNIT_ASSERT_LESSEQUAL(
Real(2+
TOLERANCE), edge_length_ratio);
246 CPPUNIT_ASSERT_LESSEQUAL(135 +
TOLERANCE, max_angle);
248 const auto assert_quality =
250 const Real expected_value,
251 const Real expected_lower_bound,
252 const Real expected_upper_bound)
254 const auto bounds = elem->qual_bounds(quality);
255 LIBMESH_ASSERT_FP_EQUAL(expected_lower_bound, bounds.first,
TOLERANCE);
256 LIBMESH_ASSERT_FP_EQUAL(expected_upper_bound, bounds.second,
TOLERANCE);
257 LIBMESH_ASSERT_FP_EQUAL(expected_value, elem->quality(quality),
TOLERANCE);
262 const std::vector<ElemQuality> expected = {
271 CPPUNIT_ASSERT_EQUAL(
272 std::string(
"Edge Length Ratio"),
276 assert_quality(
JACOBIAN, 0.5, 0.5, 1.);
279 assert_quality(
MAX_ANGLE, 135., 108., 144.);
280 assert_quality(
MIN_ANGLE, 90., 54., 108.);
284 const std::vector<ElemQuality> expected = {
294 const Real min_polyhedron_angle =
295 std::acos(
Real(1) / std::sqrt(
Real(17))) *
300 assert_quality(
MIN_ANGLE, min_polyhedron_angle, 30., 180.);
333 CPPUNIT_ASSERT_LESSEQUAL (90 +
TOLERANCE, max_dihedral_angle);
340 CPPUNIT_ASSERT_GREATEREQUAL(45 -
TOLERANCE, min_dihedral_angle);
354 if (elem->infinite())
355 CPPUNIT_ASSERT_LESSEQUAL (64 +
TOLERANCE, jac);
357 CPPUNIT_ASSERT_LESSEQUAL (8 +
TOLERANCE, jac);
366 CPPUNIT_ASSERT_GREATEREQUAL(1 -
TOLERANCE, jac);
368 CPPUNIT_ASSERT_GREATEREQUAL(0.5 -
TOLERANCE, jac);
370 CPPUNIT_ASSERT_GREATEREQUAL(2 -
TOLERANCE, jac);
378 CPPUNIT_ASSERT_LESSEQUAL (1 +
TOLERANCE, scaled_jac);
379 CPPUNIT_ASSERT_GREATEREQUAL(
Real(0.4), scaled_jac);
397 for (
const auto & elem :
398 this->
_mesh->active_local_element_ptr_range())
401 if (elem->infinite())
406 const std::pair<Real, Real> bounds = elem->qual_bounds(q);
411 if (bounds.first == -1. && bounds.second == -1.)
424 const bool is_tet = (elem->type() ==
TET4 ||
425 elem->type() ==
TET10 ||
426 elem->type() ==
TET14);
430 std::ostringstream msg;
433 <<
" evaluated to " <<
value
434 <<
", outside its suggested bounds ["
435 << bounds.first <<
", " << bounds.second <<
"]";
437 CPPUNIT_ASSERT_MESSAGE(msg.str(),
438 value >= bounds.first - tol &&
439 value <= bounds.second + tol);
453 for (
const auto & elem :
454 this->
_mesh->active_local_element_ptr_range())
457 if (elem->infinite())
460 const std::vector<ElemQuality> valid_metrics =
463 if (valid_metrics.empty())
466 std::vector<Real> baseline(valid_metrics.size());
467 for (std::size_t i = 0; i != valid_metrics.size(); ++i)
468 baseline[i] = elem->quality(valid_metrics[i]);
474 for (std::size_t i = 0; i != valid_metrics.size(); ++i)
476 const Real permuted_value = elem->quality(valid_metrics[i]);
478 std::ostringstream msg;
481 <<
" changed from " << baseline[i]
482 <<
" to " << permuted_value
483 <<
" after applying permutation " << p;
485 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE
486 (msg.str(), baseline[i], permuted_value,
TOLERANCE);
496 for (
const auto & elem :
497 this->
_mesh->active_local_element_ptr_range())
499 for (
const auto edge : elem->edge_index_range())
500 for (
const auto side_on_edge : elem->sides_on_edge(edge))
501 for (
const auto node_on_edge : elem->nodes_on_edge(edge))
502 CPPUNIT_ASSERT(elem->is_node_on_side(node_on_edge, side_on_edge));
504 for (
const auto side : elem->side_index_range())
505 for (
const auto node_on_side : elem->nodes_on_side(side))
506 CPPUNIT_ASSERT(elem->is_node_on_side(node_on_side, side));
508 for (
const auto edge : elem->edge_index_range())
509 for (
const auto node_on_edge : elem->nodes_on_edge(edge))
510 CPPUNIT_ASSERT(elem->is_node_on_edge(node_on_edge, edge));
512 for (
const auto edge : elem->edge_index_range())
513 for (
const auto side_on_edge : elem->sides_on_edge(edge))
514 CPPUNIT_ASSERT(elem->is_edge_on_side(edge, side_on_edge));
522 for (
const auto & elem :
523 this->
_mesh->active_local_element_ptr_range())
527 const ElemType etype = elem->type();
529 CPPUNIT_ASSERT_EQUAL(
static_cast<unsigned int>(elem->dim()),
531 CPPUNIT_ASSERT_EQUAL(elem->default_order(),
537 if (!elem->runtime_topology())
556 for (
const auto & elem :
557 this->
_mesh->active_local_element_ptr_range())
559 if (elem->infinite())
562 for (
const auto n : elem->node_index_range())
563#ifndef LIBMESH_ENABLE_EXCEPTIONS
572 CPPUNIT_ASSERT(elem->contains_point(elem->point(n)));
580 for (
const auto & elem :
581 this->
_mesh->active_local_element_ptr_range())
583 if (elem->infinite())
586 const Point centroid = elem->true_centroid();
587 const Point vertex_avg = elem->vertex_average();
590 quasicc = elem->quasicircumcenter();
595 CPPUNIT_ASSERT(elem->has_invertible_map());
596 const Point new_centroid = elem->true_centroid();
597 const Point new_vertex_avg = elem->vertex_average();
600 new_quasicc = elem->quasicircumcenter();
604 LIBMESH_ASSERT_FP_EQUAL(centroid(d), new_centroid(d),
606 LIBMESH_ASSERT_FP_EQUAL(vertex_avg(d), new_vertex_avg(d),
608 LIBMESH_ASSERT_FP_EQUAL(quasicc(d), new_quasicc(d),
621 for (
const auto & elem :
622 this->
_mesh->active_local_element_ptr_range())
624 if (elem->infinite())
630 const Point vertex_avg = elem->vertex_average();
632 const unsigned int n_sides = elem->n_sides();
633 std::vector<std::set<Point*>> side_nodes(n_sides);
634 std::vector<Elem*> neighbors(n_sides);
635 std::vector<std::vector<boundary_id_type>> bcids(n_sides);
638 for (
auto n : elem->nodes_on_side(s))
639 side_nodes[s].insert(elem->node_ptr(n));
640 neighbors[s] = elem->neighbor_ptr(s);
644 elem->flip(&boundary_info);
650 if ((elem->dim() < 3 ||
651 elem->n_vertices() != 5) &&
653 CPPUNIT_ASSERT(elem->has_affine_map());
655 CPPUNIT_ASSERT(!elem->has_affine_map());
659 bool something_changed =
false;
662 std::set<Point*> new_side_nodes;
663 for (
auto n : elem->nodes_on_side(s))
664 new_side_nodes.insert(elem->node_ptr(n));
666 std::vector<boundary_id_type> new_bcids;
671 if (new_side_nodes == side_nodes[os])
675 something_changed =
true;
679 CPPUNIT_ASSERT(neighbors[old_side] ==
680 elem->neighbor_ptr(s));
682 CPPUNIT_ASSERT(bcids[old_side] == new_bcids);
684 CPPUNIT_ASSERT(!elem->dim() || something_changed);
686 const Point new_vertex_avg = elem->vertex_average();
688 LIBMESH_ASSERT_FP_EQUAL(vertex_avg(d), new_vertex_avg(d),
699 for (
const auto & elem :
700 this->
_mesh->active_local_element_ptr_range())
702 if (elem->infinite())
705 const Point vertex_avg = elem->vertex_average();
707 const unsigned int n_sides = elem->n_sides();
708 std::vector<std::set<Point*>> side_nodes(n_sides);
709 std::vector<Elem*> neighbors(n_sides);
710 std::vector<std::vector<boundary_id_type>> bcids(n_sides);
713 for (
auto n : elem->nodes_on_side(s))
714 side_nodes[s].insert(elem->node_ptr(n));
715 neighbors[s] = elem->neighbor_ptr(s);
719 CPPUNIT_ASSERT(!elem->is_flipped());
723 elem->flip(&boundary_info);
724 CPPUNIT_ASSERT(elem->is_flipped());
727 elem->orient(&boundary_info);
728 CPPUNIT_ASSERT(!elem->is_flipped());
735 if ((elem->dim() < 3 ||
736 elem->n_vertices() != 5) &&
739 CPPUNIT_ASSERT(elem->has_affine_map());
742 CPPUNIT_ASSERT(!elem->has_affine_map());
748 std::set<Point*> new_side_nodes;
749 for (
auto n : elem->nodes_on_side(s))
750 new_side_nodes.insert(elem->node_ptr(n));
752 std::vector<boundary_id_type> new_bcids;
755 CPPUNIT_ASSERT(side_nodes[s] ==
758 CPPUNIT_ASSERT(neighbors[s] ==
759 elem->neighbor_ptr(s));
761 CPPUNIT_ASSERT(bcids[s] == new_bcids);
764 const Point new_vertex_avg = elem->vertex_average();
766 LIBMESH_ASSERT_FP_EQUAL(vertex_avg(d), new_vertex_avg(d),
778 const BoundaryInfo & old_boundary_info = old_mesh.get_boundary_info();
779 CPPUNIT_ASSERT(&boundary_info != &old_boundary_info);
781 for (
const auto & elem :
782 this->
_mesh->active_local_element_ptr_range())
784 if (elem->infinite())
789 elem->flip(&boundary_info);
790 CPPUNIT_ASSERT(elem->is_flipped());
797 for (
const auto & elem :
798 this->
_mesh->active_local_element_ptr_range())
800 const Elem & old_elem = old_mesh.elem_ref(elem->id());
802 CPPUNIT_ASSERT(!elem->is_flipped());
805 CPPUNIT_ASSERT(*elem == old_elem);
807 const unsigned int n_sides = elem->n_sides();
810 std::vector<boundary_id_type> bcids, old_bcids;
812 old_boundary_info.
boundary_ids(&old_elem, s, old_bcids);
813 CPPUNIT_ASSERT(bcids == old_bcids);
815 if (elem->neighbor_ptr(s))
818 CPPUNIT_ASSERT_EQUAL(elem->neighbor_ptr(s)->id(),
830 std::vector<const Node *> sequence;
832 sequence.push_back(elem.
node_ptr(v));
841 for (
const auto & elem : this->
_mesh->active_local_element_ptr_range())
847 for (
const auto p :
make_range(elem->n_permutations()))
851 for (
const auto e :
make_range(elem->n_edges()))
853 const bool positive = elem->point(elem->local_edge_node(e, 0)) >
854 elem->point(elem->local_edge_node(e, 1));
856 CPPUNIT_ASSERT_EQUAL(positive, elem->positive_edge_orientation(e));
859 for (
const auto f :
make_range(elem->n_faces()))
861 const unsigned int n_vertices =
863 const std::vector<unsigned int> nodes = elem->nodes_on_side(f);
866 unsigned int least = 0;
867 for (
const auto v :
make_range(1u, n_vertices))
868 if (elem->point(nodes[v]) < elem->point(nodes[least]))
871 const bool positive =
872 elem->point(nodes[(least + n_vertices - 1) % n_vertices]) <
873 elem->point(nodes[(least + 1) % n_vertices]);
875 const unsigned int orientation = elem->face_orientation(f);
877 CPPUNIT_ASSERT_LESS(2 * n_vertices, orientation);
878 CPPUNIT_ASSERT_EQUAL(2 * least +
static_cast<unsigned int>(positive),
880 CPPUNIT_ASSERT_EQUAL(positive, elem->positive_face_orientation(f));
892 for (
const auto & elem : this->
_mesh->active_local_element_ptr_range())
897 for (
const auto f :
make_range(elem->n_faces()))
915 for (
const auto & elem :
916 this->
_mesh->active_local_element_ptr_range())
917 for (
const auto s : elem->side_index_range())
919 if (elem->type() ==
EDGE2 || elem->type() ==
EDGE3 || elem->type() ==
EDGE4)
920 CPPUNIT_ASSERT_EQUAL(
static_cast<unsigned int>(s), elem->center_node_on_side(s));
921 else if (elem->type() ==
TRI6 || elem->type() ==
TRI7)
922 CPPUNIT_ASSERT_EQUAL(
static_cast<unsigned int>(s + 3), elem->center_node_on_side(s));
923 else if (elem->type() ==
QUAD8 || elem->type() ==
QUAD9 ||
925 CPPUNIT_ASSERT_EQUAL(
static_cast<unsigned int>(s + 4), elem->center_node_on_side(s));
926 else if (elem->type() ==
HEX27)
927 CPPUNIT_ASSERT_EQUAL(
static_cast<unsigned int>(s + 20), elem->center_node_on_side(s));
928 else if (elem->type() ==
PRISM18 && s >= 1 && s <= 3)
929 CPPUNIT_ASSERT_EQUAL(
static_cast<unsigned int>(s + 14), elem->center_node_on_side(s));
930 else if ((elem->type() ==
PRISM20 ||
931 elem->type() ==
PRISM21) && s >= 1 && s <= 3)
932 CPPUNIT_ASSERT_EQUAL(
static_cast<unsigned int>(s + 14), elem->center_node_on_side(s));
933 else if (elem->type() ==
PRISM20 ||
935 CPPUNIT_ASSERT_EQUAL(
static_cast<unsigned int>(18 + (s == 4)), elem->center_node_on_side(s));
936 else if (elem->type() ==
PYRAMID14 && s == 4)
937 CPPUNIT_ASSERT_EQUAL(
static_cast<unsigned int>(13), elem->center_node_on_side(s));
941 CPPUNIT_ASSERT_EQUAL(
static_cast<unsigned int>(s + 14), elem->center_node_on_side(s));
943 CPPUNIT_ASSERT_EQUAL(
static_cast<unsigned int>(13), elem->center_node_on_side(s));
946 CPPUNIT_ASSERT_EQUAL(
invalid_uint, elem->center_node_on_side(s));
954 for (
const auto & elem :
955 this->
_mesh->active_local_element_ptr_range())
956 for (
const auto s : elem->side_index_range())
957 CPPUNIT_ASSERT_EQUAL(elem->build_side_ptr(s)->type(), elem->side_type(s));
964 for (
const auto & elem :
965 this->
_mesh->active_local_element_ptr_range())
967 std::unique_ptr<const Elem> side;
969 for (
const auto s : elem->side_index_range())
971 CPPUNIT_ASSERT_EQUAL(elem->build_side_ptr(s)->subdomain_id(), elem->subdomain_id());
973 elem->build_side_ptr(side, s);
974 CPPUNIT_ASSERT_EQUAL(side->subdomain_id(), elem->subdomain_id());
988 for (
auto & elem : this->
_mesh->active_local_element_ptr_range())
989 for (
const auto s : elem->side_index_range())
991 const auto side = elem->build_side_ptr(s);
993 auto & cached_side = cache(*elem, s);
994 CPPUNIT_ASSERT_EQUAL(side->type(), cached_side.type());
995 for (
const auto n : side->node_index_range())
996 CPPUNIT_ASSERT_EQUAL(side->node_ref(n), cached_side.node_ref(n));
998 const auto & const_cached_side = cache(
const_cast<const Elem &
>(*elem), s);
999 CPPUNIT_ASSERT_EQUAL(side->type(), const_cached_side.type());
1000 for (
const auto n : side->node_index_range())
1001 CPPUNIT_ASSERT_EQUAL(side->node_ref(n), const_cached_side.node_ref(n));
1007#ifdef LIBMESH_ENABLE_AMR
1009 if (elem_type ==
EDGE4 ||
1019 auto refining_mesh = this->
_mesh->clone();
1024 std::set<std::pair<dof_id_type, unsigned int>> parent_node_was_touched;
1025 std::set<std::pair<dof_id_type, unsigned int>> parent_child_was_touched;
1027 for (
const Elem * elem : refining_mesh->active_element_ptr_range())
1029 CPPUNIT_ASSERT_EQUAL(elem->level(), n);
1030 CPPUNIT_ASSERT(!elem->ancestor());
1031 CPPUNIT_ASSERT(elem->active());
1032 CPPUNIT_ASSERT(!elem->subactive());
1033 CPPUNIT_ASSERT(!elem->has_children());
1034 CPPUNIT_ASSERT(!elem->has_ancestor_children());
1035 CPPUNIT_ASSERT(!elem->interior_parent());
1038 CPPUNIT_ASSERT(parent);
1039 CPPUNIT_ASSERT(parent->
ancestor());
1040 CPPUNIT_ASSERT(!parent->
active());
1047 CPPUNIT_ASSERT_EQUAL(parent, elem->
top_parent());
1048 CPPUNIT_ASSERT_EQUAL(parent, parent->
top_parent());
1052 CPPUNIT_ASSERT(parent != elem->
top_parent());
1053 CPPUNIT_ASSERT(parent != parent->
top_parent());
1054 CPPUNIT_ASSERT_EQUAL(elem->top_parent(), parent->
top_parent());
1059 CPPUNIT_ASSERT(c < parent->n_children());
1060 CPPUNIT_ASSERT_EQUAL(elem, parent->
child_ptr(c));
1061 parent_child_was_touched.emplace(parent->
id(), c);
1069 CPPUNIT_ASSERT_EQUAL(pn, parent->
get_node_index(elem->node_ptr(n)));
1073 parent_node_was_touched.emplace(parent->
id(), pn);
1085 auto child_side = elem->build_side_ptr(s);
1088 if (!parent_side->infinite())
1089 for (
const Node & node : child_side->node_ref_range())
1090 CPPUNIT_ASSERT(parent_side->contains_point(node));
1096 bool shares_a_side_node =
false;
1097 bool shares_a_vertex =
false;
1098 for (
const Node & node : child_side->node_ref_range())
1099 if (parent_side->local_node(node.id()) !=
invalid_uint)
1100 shares_a_side_node =
true;
1101 for (
const Node & node : elem->node_ref_range())
1103 shares_a_vertex =
true;
1105 CPPUNIT_ASSERT(shares_a_side_node || !shares_a_vertex);
1107 if (elem->neighbor_ptr(s) && !elem->neighbor_ptr(s)->is_remote())
1108 CPPUNIT_ASSERT_EQUAL(parent->
child_neighbor(elem->neighbor_ptr(s)), elem);
1121 auto child_edge = elem->build_edge_ptr(e);
1124 if (!parent_edge->infinite())
1125 for (
const Node & node : child_edge->node_ref_range())
1126 CPPUNIT_ASSERT(parent_edge->contains_point(node));
1130 bool shares_an_edge_node =
false;
1131 for (
const Node & node : child_edge->node_ref_range())
1132 if (parent_edge->local_node(node.id()) !=
invalid_uint)
1133 shares_an_edge_node =
true;
1135 CPPUNIT_ASSERT(shares_an_edge_node);
1140 CPPUNIT_ASSERT(elem->has_affine_map());
1148 for (
const Elem * elem : refining_mesh->local_element_ptr_range())
1158 std::vector<const Elem *> family;
1159 elem->family_tree(family);
1160 CPPUNIT_ASSERT_EQUAL(family.size(),
1161 std::size_t(elem->n_children() + 1));
1164 elem->total_family_tree(family);
1165 CPPUNIT_ASSERT_EQUAL(family.size(),
1166 std::size_t(elem->n_children() + 1));
1169 elem->active_family_tree(family);
1170 CPPUNIT_ASSERT_EQUAL(family.size(),
1171 std::size_t(elem->n_children()));
1176 elem->active_family_tree_by_side(family,s);
1177 if (!elem->build_side_ptr(s)->infinite())
1178 CPPUNIT_ASSERT_EQUAL(
double(family.size()),
1179 std::pow(2.0,
int(elem->dim()-1)));
1181 CPPUNIT_ASSERT_EQUAL(
double(family.size()),
1182 std::pow(2.0,
int(elem->dim()-2)));
1183 for (
const Elem * child : family)
1185 if (child->is_remote())
1188 unsigned int c = elem->which_child_am_i(child);
1189 CPPUNIT_ASSERT(elem->is_child_on_side(c, s));
1194 if (elem->level() + 1 == n)
1196 for (
auto c :
make_range(elem->n_children()))
1198 auto it = parent_child_was_touched.find(std::make_pair(elem->id(), c));
1199 CPPUNIT_ASSERT(it != parent_child_was_touched.end());
1204 auto it = parent_node_was_touched.find(std::make_pair(elem->id(), n));
1205 CPPUNIT_ASSERT(it != parent_node_was_touched.end());
1230 for (
const auto & elem :
1231 this->
_mesh->active_local_element_ptr_range())
1232 for (
const auto nd : elem->node_index_range())
1234 if ((elem->type() ==
EDGE3 || elem->type() ==
EDGE4) && nd >= 2)
1235 CPPUNIT_ASSERT(elem->is_internal(nd));
1236 else if (elem->type() ==
HEX27 && nd == 26)
1237 CPPUNIT_ASSERT(elem->is_internal(nd));
1238 else if (elem->type() ==
PRISM21 && nd == 20)
1239 CPPUNIT_ASSERT(elem->is_internal(nd));
1240 else if ((elem->type() ==
QUAD9 || elem->type() ==
QUADSHELL9) && nd == 8)
1241 CPPUNIT_ASSERT(elem->is_internal(nd));
1242 else if (elem->type() ==
TRI7 && nd == 6)
1243 CPPUNIT_ASSERT(elem->is_internal(nd));
1244 else if (elem->type() ==
INFHEX18 && nd == 17)
1245 CPPUNIT_ASSERT(elem->is_internal(nd));
1246 else if (elem->type() ==
INFQUAD6 && nd == 5)
1247 CPPUNIT_ASSERT(elem->is_internal(nd));
1249 else if (elem->type() ==
C0POLYHEDRON && nd == elem->n_vertices())
1250 CPPUNIT_ASSERT(elem->is_internal(nd));
1252 CPPUNIT_ASSERT(!elem->is_internal(nd));
1260 for (
const auto & elem : this->
_mesh->active_local_element_ptr_range())
1262 for (
const auto nd : elem->node_index_range())
1264 auto adjacent_edge_ids = elem->edges_adjacent_to_node(nd);
1266 if (elem->dim() < 2)
1271 CPPUNIT_ASSERT(adjacent_edge_ids.empty());
1278 for (
const auto & edge_id : adjacent_edge_ids)
1280 auto node_ids_on_edge = elem->nodes_on_edge(edge_id);
1281 CPPUNIT_ASSERT(std::find(node_ids_on_edge.begin(), node_ids_on_edge.end(), nd) != node_ids_on_edge.end());
1291 CPPUNIT_TEST( test_bounding_box ); \
1292 CPPUNIT_TEST( test_ref_elem ); \
1293 CPPUNIT_TEST( test_static_topology ); \
1294 CPPUNIT_TEST( test_higher_order_node_placement ); \
1295 CPPUNIT_TEST( test_quality ); \
1296 CPPUNIT_TEST( test_quality_bounds ); \
1297 CPPUNIT_TEST( test_quality_permutation_invariance ); \
1298 CPPUNIT_TEST( test_node_edge_map_consistency ); \
1299 CPPUNIT_TEST( test_maps ); \
1300 CPPUNIT_TEST( test_static_data ); \
1301 CPPUNIT_TEST( test_permute ); \
1302 CPPUNIT_TEST( test_flip ); \
1303 CPPUNIT_TEST( test_orient ); \
1304 CPPUNIT_TEST( test_orient_elements ); \
1305 CPPUNIT_TEST( test_orientation ); \
1306 CPPUNIT_TEST( test_orientation_conformity ); \
1307 CPPUNIT_TEST( test_contains_point_node ); \
1308 CPPUNIT_TEST( test_center_node_on_side ); \
1309 CPPUNIT_TEST( test_side_type ); \
1310 CPPUNIT_TEST( test_side_subdomain ); \
1311 CPPUNIT_TEST( test_elem_side_builder ); \
1312 CPPUNIT_TEST( test_refinement ); \
1313 CPPUNIT_TEST( test_double_refinement ); \
1314 CPPUNIT_TEST( test_is_internal )
1316#define INSTANTIATE_ELEMTEST(elemtype) \
1317 class ElemTest_##elemtype : public ElemTest<elemtype> { \
1319 ElemTest_##elemtype() : \
1320 ElemTest<elemtype>() { \
1321 if (unitlog->summarized_logs_enabled()) \
1322 this->libmesh_suite_name = "ElemTest"; \
1324 this->libmesh_suite_name = "ElemTest_" #elemtype; \
1326 CPPUNIT_TEST_SUITE( ElemTest_##elemtype ); \
1328 CPPUNIT_TEST_SUITE_END(); \
1331 CPPUNIT_TEST_SUITE_REGISTRATION( ElemTest_##elemtype )
1358#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1382#ifdef LIBMESH_ENABLE_EXCEPTIONS
1389#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
void test_elem_side_builder()
void test_quality_permutation_invariance()
void test_contains_point_node()
void test_higher_order_node_placement()
void test_double_refinement()
void test_center_node_on_side()
void test_orientation_conformity()
void test_n_refinements(unsigned int n)
void test_side_subdomain()
void test_quality_bounds()
void test_static_topology()
std::vector< const Node * > oriented_face_nodes(const Elem &elem, const unsigned int face)
The nodes at the vertices of face, in the order Elem::oriented_face_vertices() gives.
void test_orient_elements()
void test_node_edge_map_consistency()
std::unique_ptr< Mesh > _mesh
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
Fills a user-provided std::vector with the boundary ids associated with Node node.
Defines a Cartesian bounding box by the two corner extremum.
const Point & max() const
void scale(const Real factor)
Scales each dimension of the bounding box by factor.
const Point & min() const
bool contains_point(const Point &) const
void union_with(const Point &p)
Enlarges this bounding box to include the given point.
Helper for building element sides that minimizes the construction of new elements.
This is the base class from which all geometric element types are derived.
bool has_ancestor_children() const
virtual unsigned int n_nodes_in_child(unsigned int) const
virtual bool is_child_on_side(const unsigned int c, const unsigned int s) const =0
bool is_ancestor_of(const Elem *descendant) const
virtual unsigned int n_vertices() const =0
Elem * child_neighbor(Elem *elem)
const Point & point(const unsigned int i) const
virtual unsigned int local_side_node(unsigned int side, unsigned int side_node) const =0
static const unsigned int type_to_n_edges_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of edges on the element...
virtual bool is_child_on_edge(const unsigned int c, const unsigned int e) const
bool has_children() const
static ElemType edge_type(const ElemType t)
const Elem * parent() const
const Elem * child_ptr(unsigned int i) const
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
virtual bool is_vertex_on_parent(unsigned int c, unsigned int n) const
unsigned int local_node(const dof_id_type i) const
unsigned int which_child_am_i(const Elem *e) const
virtual bool is_vertex_on_child(unsigned int, unsigned int n) const
virtual unsigned int local_edge_node(unsigned int edge, unsigned int edge_node) const =0
Similar to Elem::local_side_node(), but instead of a side id, takes an edge id and a node id on that ...
static const unsigned int type_to_dim_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the geometric dimension of the ele...
static const unsigned int type_to_n_sides_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of sides on the element...
static const unsigned int max_n_nodes
The maximum number of nodes any element can contain.
static constexpr unsigned int type_to_n_nodes_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of nodes in the element...
std::vector< unsigned int > oriented_face_vertices(const unsigned int i) const
const Node * node_ptr(const unsigned int i) const
virtual unsigned int as_parent_node(unsigned int c, unsigned int n) const
static const Order type_to_default_order_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the default approximation order of...
const Elem * reference_elem() const
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i)=0
virtual bool is_vertex(const unsigned int i) const =0
unsigned int get_node_index(const Node *node_ptr) const
const Elem * interior_parent() const
virtual unsigned int n_edges() const =0
virtual ElemType side_type(const unsigned int s) const =0
virtual unsigned int n_sides() const =0
virtual bool has_affine_map() const
const Elem * neighbor_ptr(unsigned int i) const
virtual bool infinite() const =0
const Elem * top_parent() const
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i)=0
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Implements (adaptive) mesh refinement algorithms for a MeshBase.
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
A Node is like a Point, but with more information.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Communicator * TestCommWorld
INSTANTIATE_ELEMTEST(NODEELEM)
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
std::vector< ElemQuality > valid(const ElemType t)
std::string enum_to_string(const T e)
The libMesh namespace provides an interface to certain functionality in the library.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
ElemType
Defines an enum for geometric element types.
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
const RemoteElem * remote_elem
ElemQuality
Defines an enum for element quality metrics.
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...