29 #include "libmesh/boundary_info.h" 30 #include "libmesh/function_base.h" 31 #include "libmesh/cell_tet4.h" 32 #include "libmesh/cell_tet10.h" 33 #include "libmesh/cell_c0polyhedron.h" 34 #include "libmesh/cell_polyhedron.h" 35 #include "libmesh/elem_range.h" 36 #include "libmesh/face_c0polygon.h" 37 #include "libmesh/face_polygon.h" 38 #include "libmesh/face_tri3.h" 39 #include "libmesh/face_tri6.h" 40 #include "libmesh/libmesh_logging.h" 41 #include "libmesh/mesh_communication.h" 42 #include "libmesh/mesh_modification.h" 43 #include "libmesh/mesh_tools.h" 44 #include "libmesh/parallel.h" 45 #include "libmesh/remote_elem.h" 46 #include "libmesh/enum_to_string.h" 47 #include "libmesh/unstructured_mesh.h" 48 #include "libmesh/elem_side_builder.h" 49 #include "libmesh/tensor_value.h" 55 bool split_first_diagonal(
const Elem * elem,
56 unsigned int diag_1_node_1,
57 unsigned int diag_1_node_2,
58 unsigned int diag_2_node_1,
59 unsigned int diag_2_node_2)
61 return ((elem->
node_id(diag_1_node_1) > elem->
node_id(diag_2_node_1) &&
70 unsigned int highest_vertex_on(
const Elem * elem)
72 unsigned int highest_n = 0;
77 if (n_id > highest_n_id)
88 static const std::array<std::array<unsigned int, 3>, 8> opposing_nodes =
89 {{ {2,5,7},{3,4,6},{0,5,7},{1,4,6},{1,3,6},{0,2,7},{1,3,4},{0,2,5} }};
93 std::pair<unsigned int, unsigned int>
94 split_diagonal(
const Elem * elem,
95 const std::vector<unsigned int> & nodes_on_side)
97 libmesh_assert_equal_to(elem->
type(),
HEX8);
99 unsigned int highest_n = nodes_on_side.front();
101 for (
auto n : nodes_on_side)
104 if (n_id > highest_n_id)
111 for (
auto n : nodes_on_side)
113 for (
auto n2 : opposing_nodes[highest_n])
115 return std::make_pair(highest_n, n2);
125 template <
typename T>
126 struct reversion_wrapper { T& iterable; };
128 template <
typename T>
129 auto begin (reversion_wrapper<T> w) {
return std::rbegin(w.iterable);}
131 template <
typename T>
132 auto end (reversion_wrapper<T> w) {
return std::rend(w.iterable);}
134 template <
typename T>
135 reversion_wrapper<T> reverse(T&& iterable) {
return {iterable};}
148 const bool perturb_boundary)
154 LOG_SCOPE(
"distort()",
"MeshTools::Modification");
158 std::unordered_set<dof_id_type> boundary_node_ids;
159 if (!perturb_boundary)
166 std::numeric_limits<float>::max());
168 for (
const auto & elem :
mesh.active_element_ptr_range())
170 hmin[n.id()] = std::min(hmin[n.id()],
171 static_cast<float>(elem->
hmin()));
175 const unsigned int seed = 123456;
189 if ((perturb_boundary || !boundary_node_ids.count(n)) && hmin[n] < 1.e20)
192 Point dir (static_cast<Real>(std::rand())/static_cast<Real>(RAND_MAX),
193 (
mesh.
mesh_dimension() > 1) ? static_cast<Real>(std::rand())/static_cast<Real>(RAND_MAX) : 0.,
194 ((
mesh.
mesh_dimension() == 3) ? static_cast<Real>(std::rand())/static_cast<Real>(RAND_MAX) : 0.));
196 dir(0) = (dir(0)-.5)*2.;
199 dir(1) = (dir(1)-.5)*2.;
203 dir(2) = (dir(2)-.5)*2.;
212 (*node)(0) += dir(0)*factor*hmin[n];
215 (*node)(1) += dir(1)*factor*hmin[n];
219 (*node)(2) += dir(2)*factor*hmin[n];
233 LOG_SCOPE(
"permute_elements()",
"MeshTools::Modification");
242 const unsigned int seed = 123456;
253 int my_rand = std::rand();
261 if (!max_permutation)
264 const unsigned int perm = my_rand % max_permutation;
273 LOG_SCOPE(
"orient_elements()",
"MeshTools::Modification");
280 libmesh_not_implemented_msg(
"orient_elements() does not support refined meshes");
283 for (
auto elem :
mesh.element_ptr_range())
284 elem->
orient(&boundary_info);
295 LOG_SCOPE(
"redistribute()",
"MeshTools::Modification");
300 std::unique_ptr<FunctionBase<Real>> myfunc = mapfunc.
clone();
302 for (
auto & node :
mesh.node_ptr_range())
304 (*myfunc)(*node, output_vec);
306 (*node)(0) = output_vec(0);
308 (*node)(1) = output_vec(1);
311 (*node)(2) = output_vec(2);
327 const Point p(xt, yt, zt);
329 for (
auto & node :
mesh.node_ptr_range())
376 for (
auto & node :
mesh.node_ptr_range())
386 libmesh_error_msg(
"MeshTools::Modification::rotate() requires libMesh to be compiled with LIBMESH_DIM==3");
398 const Real x_scale = xs;
404 libmesh_assert_equal_to (zs, 0.);
406 y_scale = z_scale = x_scale;
410 for (
auto & node :
mesh.node_ptr_range())
411 (*node)(0) *= x_scale;
417 for (
auto & node :
mesh.node_ptr_range())
418 (*node)(1) *= y_scale;
424 for (
auto & node :
mesh.node_ptr_range())
425 (*node)(2) *= z_scale;
448 std::vector<std::unique_ptr<Elem>> new_elements;
450 unsigned int max_subelems = 1;
459 for (
const Elem * elem :
mesh.element_ptr_range())
461 if (
const Polygon * poly = dynamic_cast<const Polygon *>(elem))
462 max_subelems = std::max(max_subelems, poly->n_subtriangles());
463 else if (
const Polyhedron * polyhedron = dynamic_cast<const Polyhedron *>(elem))
464 max_subelems = std::max(max_subelems, polyhedron->n_subelements());
468 new_elements.reserve (max_subelems*n_orig_elem);
478 std::vector<Elem *> new_bndry_elements;
479 std::vector<unsigned short int> new_bndry_sides;
480 std::vector<boundary_id_type> new_bndry_ids;
485 bool added_new_ghost_point =
false;
500 #ifdef LIBMESH_ENABLE_UNIQUE_ID 505 std::unique_ptr<const Elem> elem_side, subside_elem;
507 for (
auto & elem :
mesh.element_ptr_range())
513 libmesh_not_implemented_msg(
"Cannot convert a refined element into simplices\n");
517 std::vector<std::unique_ptr<Elem>> subelem(max_subelems);
530 subelem[0]->set_node(0, elem->
node_ptr(0));
531 subelem[0]->set_node(1, elem->
node_ptr(1));
532 subelem[0]->set_node(2, elem->
node_ptr(2));
534 subelem[1]->set_node(0, elem->
node_ptr(0));
535 subelem[1]->set_node(1, elem->
node_ptr(2));
536 subelem[1]->set_node(2, elem->
node_ptr(3));
541 subelem[0]->set_node(0, elem->
node_ptr(0));
542 subelem[0]->set_node(1, elem->
node_ptr(1));
543 subelem[0]->set_node(2, elem->
node_ptr(3));
545 subelem[1]->set_node(0, elem->
node_ptr(1));
546 subelem[1]->set_node(1, elem->
node_ptr(2));
547 subelem[1]->set_node(2, elem->
node_ptr(3));
557 added_new_ghost_point =
true;
574 subelem[0]->set_node(0, elem->
node_ptr(0));
575 subelem[0]->set_node(1, elem->
node_ptr(1));
576 subelem[0]->set_node(2, elem->
node_ptr(2));
577 subelem[0]->set_node(3, elem->
node_ptr(4));
578 subelem[0]->set_node(4, elem->
node_ptr(5));
579 subelem[0]->set_node(5, new_node);
581 subelem[1]->set_node(0, elem->
node_ptr(0));
582 subelem[1]->set_node(1, elem->
node_ptr(2));
583 subelem[1]->set_node(2, elem->
node_ptr(3));
584 subelem[1]->set_node(3, new_node);
585 subelem[1]->set_node(4, elem->
node_ptr(6));
586 subelem[1]->set_node(5, elem->
node_ptr(7));
592 subelem[0]->set_node(0, elem->
node_ptr(3));
593 subelem[0]->set_node(1, elem->
node_ptr(0));
594 subelem[0]->set_node(2, elem->
node_ptr(1));
595 subelem[0]->set_node(3, elem->
node_ptr(7));
596 subelem[0]->set_node(4, elem->
node_ptr(4));
597 subelem[0]->set_node(5, new_node);
599 subelem[1]->set_node(0, elem->
node_ptr(1));
600 subelem[1]->set_node(1, elem->
node_ptr(2));
601 subelem[1]->set_node(2, elem->
node_ptr(3));
602 subelem[1]->set_node(3, elem->
node_ptr(5));
603 subelem[1]->set_node(4, elem->
node_ptr(6));
604 subelem[1]->set_node(5, new_node);
619 subelem[0]->set_node(0, elem->
node_ptr(0));
620 subelem[0]->set_node(1, elem->
node_ptr(1));
621 subelem[0]->set_node(2, elem->
node_ptr(2));
622 subelem[0]->set_node(3, elem->
node_ptr(4));
623 subelem[0]->set_node(4, elem->
node_ptr(5));
624 subelem[0]->set_node(5, elem->
node_ptr(8));
626 subelem[1]->set_node(0, elem->
node_ptr(0));
627 subelem[1]->set_node(1, elem->
node_ptr(2));
628 subelem[1]->set_node(2, elem->
node_ptr(3));
629 subelem[1]->set_node(3, elem->
node_ptr(8));
630 subelem[1]->set_node(4, elem->
node_ptr(6));
631 subelem[1]->set_node(5, elem->
node_ptr(7));
636 subelem[0]->set_node(0, elem->
node_ptr(0));
637 subelem[0]->set_node(1, elem->
node_ptr(1));
638 subelem[0]->set_node(2, elem->
node_ptr(3));
639 subelem[0]->set_node(3, elem->
node_ptr(4));
640 subelem[0]->set_node(4, elem->
node_ptr(8));
641 subelem[0]->set_node(5, elem->
node_ptr(7));
643 subelem[1]->set_node(0, elem->
node_ptr(1));
644 subelem[1]->set_node(1, elem->
node_ptr(2));
645 subelem[1]->set_node(2, elem->
node_ptr(3));
646 subelem[1]->set_node(3, elem->
node_ptr(5));
647 subelem[1]->set_node(4, elem->
node_ptr(6));
648 subelem[1]->set_node(5, elem->
node_ptr(8));
672 const unsigned int highest_n = highest_vertex_on(elem);
676 static const std::array<unsigned int, 8> opposing_node =
677 {6, 7, 4, 5, 2, 3, 0, 1};
679 static const std::vector<std::vector<unsigned int>> sides_opposing_highest =
680 {{2,3,5},{3,4,5},{1,4,5},{1,2,5},{0,2,3},{0,3,4},{0,1,4},{0,1,2}};
681 static const std::vector<std::vector<unsigned int>> nodes_neighboring_highest =
682 {{1,3,4},{0,2,5},{1,3,6},{0,2,7},{0,5,7},{1,4,6},{2,5,7},{3,4,6}};
693 unsigned int next_subelem = 0;
694 for (
auto side : sides_opposing_highest[highest_n])
696 const std::vector<unsigned int> nodes_on_side =
699 auto [dn, dn2] = split_diagonal(elem, nodes_on_side);
701 unsigned int split_on_neighbor =
false;
702 for (
auto n : nodes_neighboring_highest[highest_n])
703 if (dn == n || dn2 == n)
705 split_on_neighbor =
true;
713 if (split_on_neighbor)
715 subelem[next_subelem]->set_node(0, elem->
node_ptr(highest_n));
716 subelem[next_subelem]->set_node(1, elem->
node_ptr(dn));
717 subelem[next_subelem]->set_node(2, elem->
node_ptr(dn2));
718 for (
auto n : nodes_on_side)
719 if (n != dn && n != dn2)
721 subelem[next_subelem]->set_node(3, elem->
node_ptr(n));
724 subelem[next_subelem]->orient(&boundary_info);
727 subelem[next_subelem]->set_node(0, elem->
node_ptr(highest_n));
728 subelem[next_subelem]->set_node(1, elem->
node_ptr(dn));
729 subelem[next_subelem]->set_node(2, elem->
node_ptr(dn2));
730 for (
auto n : reverse(nodes_on_side))
731 if (n != dn && n != dn2)
733 subelem[next_subelem]->set_node(3, elem->
node_ptr(n));
736 subelem[next_subelem]->orient(&boundary_info);
741 subelem[next_subelem]->set_node(0, elem->
node_ptr(highest_n));
742 subelem[next_subelem]->set_node(1, elem->
node_ptr(dn));
743 subelem[next_subelem]->set_node(2, elem->
node_ptr(dn2));
744 for (
auto n : nodes_on_side)
745 for (
auto n2 : nodes_neighboring_highest[highest_n])
748 subelem[next_subelem]->set_node(3, elem->
node_ptr(n));
749 goto break_both_loops;
753 subelem[next_subelem]->orient(&boundary_info);
766 if (next_subelem == 3)
768 subelem[next_subelem]->set_node(0, elem->
node_ptr(opposing_nodes[highest_n][0]));
769 subelem[next_subelem]->set_node(1, elem->
node_ptr(opposing_nodes[highest_n][1]));
770 subelem[next_subelem]->set_node(2, elem->
node_ptr(opposing_nodes[highest_n][2]));
771 subelem[next_subelem]->set_node(3, elem->
node_ptr(opposing_node[highest_n]));
772 subelem[next_subelem]->orient(&boundary_info);
775 subelem[next_subelem]->set_node(0, elem->
node_ptr(opposing_nodes[highest_n][0]));
776 subelem[next_subelem]->set_node(1, elem->
node_ptr(opposing_nodes[highest_n][1]));
777 subelem[next_subelem]->set_node(2, elem->
node_ptr(opposing_nodes[highest_n][2]));
778 subelem[next_subelem]->set_node(3, elem->
node_ptr(highest_n));
779 subelem[next_subelem]->orient(&boundary_info);
783 subelem[next_subelem].reset();
790 if (next_subelem == 4 ||
793 for (
auto side : sides_opposing_highest[highest_n])
795 const std::vector<unsigned int> nodes_on_side =
798 auto [dn, dn2] = split_diagonal(elem, nodes_on_side);
800 unsigned int split_on_neighbor =
false;
801 for (
auto n : nodes_neighboring_highest[highest_n])
802 if (dn == n || dn2 == n)
804 split_on_neighbor =
true;
810 if (!split_on_neighbor)
812 subelem[next_subelem]->set_node(0, elem->
node_ptr(highest_n));
813 subelem[next_subelem]->set_node(1, elem->
node_ptr(dn));
814 subelem[next_subelem]->set_node(2, elem->
node_ptr(dn2));
815 subelem[next_subelem]->set_node(3, elem->
node_ptr(opposing_node[highest_n]));
816 subelem[next_subelem]->orient(&boundary_info);
854 if (split_first_diagonal(elem, 0,4, 1,3))
857 if (split_first_diagonal(elem, 0,5, 2,3))
860 if (split_first_diagonal(elem, 1,5, 2,4))
862 subelem[0]->set_node(0, elem->
node_ptr(0));
863 subelem[0]->set_node(1, elem->
node_ptr(4));
864 subelem[0]->set_node(2, elem->
node_ptr(5));
865 subelem[0]->set_node(3, elem->
node_ptr(3));
867 subelem[1]->set_node(0, elem->
node_ptr(0));
868 subelem[1]->set_node(1, elem->
node_ptr(4));
869 subelem[1]->set_node(2, elem->
node_ptr(1));
870 subelem[1]->set_node(3, elem->
node_ptr(5));
872 subelem[2]->set_node(0, elem->
node_ptr(0));
873 subelem[2]->set_node(1, elem->
node_ptr(1));
874 subelem[2]->set_node(2, elem->
node_ptr(2));
875 subelem[2]->set_node(3, elem->
node_ptr(5));
881 subelem[0]->set_node(0, elem->
node_ptr(0));
882 subelem[0]->set_node(1, elem->
node_ptr(4));
883 subelem[0]->set_node(2, elem->
node_ptr(5));
884 subelem[0]->set_node(3, elem->
node_ptr(3));
886 subelem[1]->set_node(0, elem->
node_ptr(0));
887 subelem[1]->set_node(1, elem->
node_ptr(4));
888 subelem[1]->set_node(2, elem->
node_ptr(2));
889 subelem[1]->set_node(3, elem->
node_ptr(5));
891 subelem[2]->set_node(0, elem->
node_ptr(0));
892 subelem[2]->set_node(1, elem->
node_ptr(1));
893 subelem[2]->set_node(2, elem->
node_ptr(2));
894 subelem[2]->set_node(3, elem->
node_ptr(4));
904 subelem[0]->set_node(0, elem->
node_ptr(0));
905 subelem[0]->set_node(1, elem->
node_ptr(4));
906 subelem[0]->set_node(2, elem->
node_ptr(2));
907 subelem[0]->set_node(3, elem->
node_ptr(3));
909 subelem[1]->set_node(0, elem->
node_ptr(3));
910 subelem[1]->set_node(1, elem->
node_ptr(4));
911 subelem[1]->set_node(2, elem->
node_ptr(2));
912 subelem[1]->set_node(3, elem->
node_ptr(5));
914 subelem[2]->set_node(0, elem->
node_ptr(0));
915 subelem[2]->set_node(1, elem->
node_ptr(1));
916 subelem[2]->set_node(2, elem->
node_ptr(2));
917 subelem[2]->set_node(3, elem->
node_ptr(4));
925 if (split_first_diagonal(elem, 0,5, 2,3))
930 subelem[0]->set_node(0, elem->
node_ptr(1));
931 subelem[0]->set_node(1, elem->
node_ptr(3));
932 subelem[0]->set_node(2, elem->
node_ptr(4));
933 subelem[0]->set_node(3, elem->
node_ptr(5));
935 subelem[1]->set_node(0, elem->
node_ptr(1));
936 subelem[1]->set_node(1, elem->
node_ptr(0));
937 subelem[1]->set_node(2, elem->
node_ptr(3));
938 subelem[1]->set_node(3, elem->
node_ptr(5));
940 subelem[2]->set_node(0, elem->
node_ptr(0));
941 subelem[2]->set_node(1, elem->
node_ptr(1));
942 subelem[2]->set_node(2, elem->
node_ptr(2));
943 subelem[2]->set_node(3, elem->
node_ptr(5));
950 if (split_first_diagonal(elem, 1,5, 2,4))
952 subelem[0]->set_node(0, elem->
node_ptr(0));
953 subelem[0]->set_node(1, elem->
node_ptr(1));
954 subelem[0]->set_node(2, elem->
node_ptr(2));
955 subelem[0]->set_node(3, elem->
node_ptr(3));
957 subelem[1]->set_node(0, elem->
node_ptr(3));
958 subelem[1]->set_node(1, elem->
node_ptr(1));
959 subelem[1]->set_node(2, elem->
node_ptr(2));
960 subelem[1]->set_node(3, elem->
node_ptr(5));
962 subelem[2]->set_node(0, elem->
node_ptr(1));
963 subelem[2]->set_node(1, elem->
node_ptr(3));
964 subelem[2]->set_node(2, elem->
node_ptr(4));
965 subelem[2]->set_node(3, elem->
node_ptr(5));
971 subelem[0]->set_node(0, elem->
node_ptr(0));
972 subelem[0]->set_node(1, elem->
node_ptr(1));
973 subelem[0]->set_node(2, elem->
node_ptr(2));
974 subelem[0]->set_node(3, elem->
node_ptr(3));
976 subelem[1]->set_node(0, elem->
node_ptr(2));
977 subelem[1]->set_node(1, elem->
node_ptr(3));
978 subelem[1]->set_node(2, elem->
node_ptr(4));
979 subelem[1]->set_node(3, elem->
node_ptr(5));
981 subelem[2]->set_node(0, elem->
node_ptr(3));
982 subelem[2]->set_node(1, elem->
node_ptr(1));
983 subelem[2]->set_node(2, elem->
node_ptr(2));
984 subelem[2]->set_node(3, elem->
node_ptr(4));
994 libmesh_experimental();
995 libmesh_fallthrough();
1003 if (split_first_diagonal(elem, 0,4, 1,3))
1006 if (split_first_diagonal(elem, 0,5, 2,3))
1009 if (split_first_diagonal(elem, 1,5, 2,4))
1011 subelem[0]->set_node(0, elem->
node_ptr(0));
1012 subelem[0]->set_node(1, elem->
node_ptr(4));
1013 subelem[0]->set_node(2, elem->
node_ptr(5));
1014 subelem[0]->set_node(3, elem->
node_ptr(3));
1016 subelem[0]->set_node(4, elem->
node_ptr(15));
1017 subelem[0]->set_node(5, elem->
node_ptr(13));
1018 subelem[0]->set_node(6, elem->
node_ptr(17));
1019 subelem[0]->set_node(7, elem->
node_ptr(9));
1020 subelem[0]->set_node(8, elem->
node_ptr(12));
1021 subelem[0]->set_node(9, elem->
node_ptr(14));
1023 subelem[1]->set_node(0, elem->
node_ptr(0));
1024 subelem[1]->set_node(1, elem->
node_ptr(4));
1025 subelem[1]->set_node(2, elem->
node_ptr(1));
1026 subelem[1]->set_node(3, elem->
node_ptr(5));
1028 subelem[1]->set_node(4, elem->
node_ptr(15));
1029 subelem[1]->set_node(5, elem->
node_ptr(10));
1030 subelem[1]->set_node(6, elem->
node_ptr(6));
1031 subelem[1]->set_node(7, elem->
node_ptr(17));
1032 subelem[1]->set_node(8, elem->
node_ptr(13));
1033 subelem[1]->set_node(9, elem->
node_ptr(16));
1035 subelem[2]->set_node(0, elem->
node_ptr(0));
1036 subelem[2]->set_node(1, elem->
node_ptr(1));
1037 subelem[2]->set_node(2, elem->
node_ptr(2));
1038 subelem[2]->set_node(3, elem->
node_ptr(5));
1040 subelem[2]->set_node(4, elem->
node_ptr(6));
1041 subelem[2]->set_node(5, elem->
node_ptr(7));
1042 subelem[2]->set_node(6, elem->
node_ptr(8));
1043 subelem[2]->set_node(7, elem->
node_ptr(17));
1044 subelem[2]->set_node(8, elem->
node_ptr(16));
1045 subelem[2]->set_node(9, elem->
node_ptr(11));
1051 subelem[0]->set_node(0, elem->
node_ptr(0));
1052 subelem[0]->set_node(1, elem->
node_ptr(4));
1053 subelem[0]->set_node(2, elem->
node_ptr(5));
1054 subelem[0]->set_node(3, elem->
node_ptr(3));
1056 subelem[0]->set_node(4, elem->
node_ptr(15));
1057 subelem[0]->set_node(5, elem->
node_ptr(13));
1058 subelem[0]->set_node(6, elem->
node_ptr(17));
1059 subelem[0]->set_node(7, elem->
node_ptr(9));
1060 subelem[0]->set_node(8, elem->
node_ptr(12));
1061 subelem[0]->set_node(9, elem->
node_ptr(14));
1063 subelem[1]->set_node(0, elem->
node_ptr(0));
1064 subelem[1]->set_node(1, elem->
node_ptr(4));
1065 subelem[1]->set_node(2, elem->
node_ptr(2));
1066 subelem[1]->set_node(3, elem->
node_ptr(5));
1068 subelem[1]->set_node(4, elem->
node_ptr(15));
1069 subelem[1]->set_node(5, elem->
node_ptr(16));
1070 subelem[1]->set_node(6, elem->
node_ptr(8));
1071 subelem[1]->set_node(7, elem->
node_ptr(17));
1072 subelem[1]->set_node(8, elem->
node_ptr(13));
1073 subelem[1]->set_node(9, elem->
node_ptr(11));
1075 subelem[2]->set_node(0, elem->
node_ptr(0));
1076 subelem[2]->set_node(1, elem->
node_ptr(1));
1077 subelem[2]->set_node(2, elem->
node_ptr(2));
1078 subelem[2]->set_node(3, elem->
node_ptr(4));
1080 subelem[2]->set_node(4, elem->
node_ptr(6));
1081 subelem[2]->set_node(5, elem->
node_ptr(7));
1082 subelem[2]->set_node(6, elem->
node_ptr(8));
1083 subelem[2]->set_node(7, elem->
node_ptr(15));
1084 subelem[2]->set_node(8, elem->
node_ptr(10));
1085 subelem[2]->set_node(9, elem->
node_ptr(16));
1095 subelem[0]->set_node(0, elem->
node_ptr(0));
1096 subelem[0]->set_node(1, elem->
node_ptr(4));
1097 subelem[0]->set_node(2, elem->
node_ptr(2));
1098 subelem[0]->set_node(3, elem->
node_ptr(3));
1100 subelem[0]->set_node(4, elem->
node_ptr(15));
1101 subelem[0]->set_node(5, elem->
node_ptr(16));
1102 subelem[0]->set_node(6, elem->
node_ptr(8));
1103 subelem[0]->set_node(7, elem->
node_ptr(9));
1104 subelem[0]->set_node(8, elem->
node_ptr(12));
1105 subelem[0]->set_node(9, elem->
node_ptr(17));
1107 subelem[1]->set_node(0, elem->
node_ptr(3));
1108 subelem[1]->set_node(1, elem->
node_ptr(4));
1109 subelem[1]->set_node(2, elem->
node_ptr(2));
1110 subelem[1]->set_node(3, elem->
node_ptr(5));
1112 subelem[1]->set_node(4, elem->
node_ptr(12));
1113 subelem[1]->set_node(5, elem->
node_ptr(16));
1114 subelem[1]->set_node(6, elem->
node_ptr(17));
1115 subelem[1]->set_node(7, elem->
node_ptr(14));
1116 subelem[1]->set_node(8, elem->
node_ptr(13));
1117 subelem[1]->set_node(9, elem->
node_ptr(11));
1119 subelem[2]->set_node(0, elem->
node_ptr(0));
1120 subelem[2]->set_node(1, elem->
node_ptr(1));
1121 subelem[2]->set_node(2, elem->
node_ptr(2));
1122 subelem[2]->set_node(3, elem->
node_ptr(4));
1124 subelem[2]->set_node(4, elem->
node_ptr(6));
1125 subelem[2]->set_node(5, elem->
node_ptr(7));
1126 subelem[2]->set_node(6, elem->
node_ptr(8));
1127 subelem[2]->set_node(7, elem->
node_ptr(15));
1128 subelem[2]->set_node(8, elem->
node_ptr(10));
1129 subelem[2]->set_node(9, elem->
node_ptr(16));
1137 if (split_first_diagonal(elem, 0,5, 2,3))
1142 subelem[0]->set_node(0, elem->
node_ptr(1));
1143 subelem[0]->set_node(1, elem->
node_ptr(3));
1144 subelem[0]->set_node(2, elem->
node_ptr(4));
1145 subelem[0]->set_node(3, elem->
node_ptr(5));
1147 subelem[0]->set_node(4, elem->
node_ptr(15));
1148 subelem[0]->set_node(5, elem->
node_ptr(12));
1149 subelem[0]->set_node(6, elem->
node_ptr(10));
1150 subelem[0]->set_node(7, elem->
node_ptr(16));
1151 subelem[0]->set_node(8, elem->
node_ptr(14));
1152 subelem[0]->set_node(9, elem->
node_ptr(13));
1154 subelem[1]->set_node(0, elem->
node_ptr(1));
1155 subelem[1]->set_node(1, elem->
node_ptr(0));
1156 subelem[1]->set_node(2, elem->
node_ptr(3));
1157 subelem[1]->set_node(3, elem->
node_ptr(5));
1159 subelem[1]->set_node(4, elem->
node_ptr(6));
1160 subelem[1]->set_node(5, elem->
node_ptr(9));
1161 subelem[1]->set_node(6, elem->
node_ptr(15));
1162 subelem[1]->set_node(7, elem->
node_ptr(16));
1163 subelem[1]->set_node(8, elem->
node_ptr(17));
1164 subelem[1]->set_node(9, elem->
node_ptr(14));
1166 subelem[2]->set_node(0, elem->
node_ptr(0));
1167 subelem[2]->set_node(1, elem->
node_ptr(1));
1168 subelem[2]->set_node(2, elem->
node_ptr(2));
1169 subelem[2]->set_node(3, elem->
node_ptr(5));
1171 subelem[2]->set_node(4, elem->
node_ptr(6));
1172 subelem[2]->set_node(5, elem->
node_ptr(7));
1173 subelem[2]->set_node(6, elem->
node_ptr(8));
1174 subelem[2]->set_node(7, elem->
node_ptr(17));
1175 subelem[2]->set_node(8, elem->
node_ptr(16));
1176 subelem[2]->set_node(9, elem->
node_ptr(11));
1183 if (split_first_diagonal(elem, 1,5, 2,4))
1185 subelem[0]->set_node(0, elem->
node_ptr(0));
1186 subelem[0]->set_node(1, elem->
node_ptr(1));
1187 subelem[0]->set_node(2, elem->
node_ptr(2));
1188 subelem[0]->set_node(3, elem->
node_ptr(3));
1190 subelem[0]->set_node(4, elem->
node_ptr(6));
1191 subelem[0]->set_node(5, elem->
node_ptr(7));
1192 subelem[0]->set_node(6, elem->
node_ptr(8));
1193 subelem[0]->set_node(7, elem->
node_ptr(9));
1194 subelem[0]->set_node(8, elem->
node_ptr(15));
1195 subelem[0]->set_node(9, elem->
node_ptr(17));
1197 subelem[1]->set_node(0, elem->
node_ptr(3));
1198 subelem[1]->set_node(1, elem->
node_ptr(1));
1199 subelem[1]->set_node(2, elem->
node_ptr(2));
1200 subelem[1]->set_node(3, elem->
node_ptr(5));
1202 subelem[1]->set_node(4, elem->
node_ptr(15));
1203 subelem[1]->set_node(5, elem->
node_ptr(7));
1204 subelem[1]->set_node(6, elem->
node_ptr(17));
1205 subelem[1]->set_node(7, elem->
node_ptr(14));
1206 subelem[1]->set_node(8, elem->
node_ptr(16));
1207 subelem[1]->set_node(9, elem->
node_ptr(11));
1209 subelem[2]->set_node(0, elem->
node_ptr(1));
1210 subelem[2]->set_node(1, elem->
node_ptr(3));
1211 subelem[2]->set_node(2, elem->
node_ptr(4));
1212 subelem[2]->set_node(3, elem->
node_ptr(5));
1214 subelem[2]->set_node(4, elem->
node_ptr(15));
1215 subelem[2]->set_node(5, elem->
node_ptr(12));
1216 subelem[2]->set_node(6, elem->
node_ptr(10));
1217 subelem[2]->set_node(7, elem->
node_ptr(16));
1218 subelem[2]->set_node(8, elem->
node_ptr(14));
1219 subelem[2]->set_node(9, elem->
node_ptr(13));
1225 subelem[0]->set_node(0, elem->
node_ptr(0));
1226 subelem[0]->set_node(1, elem->
node_ptr(1));
1227 subelem[0]->set_node(2, elem->
node_ptr(2));
1228 subelem[0]->set_node(3, elem->
node_ptr(3));
1230 subelem[0]->set_node(4, elem->
node_ptr(6));
1231 subelem[0]->set_node(5, elem->
node_ptr(7));
1232 subelem[0]->set_node(6, elem->
node_ptr(8));
1233 subelem[0]->set_node(7, elem->
node_ptr(9));
1234 subelem[0]->set_node(8, elem->
node_ptr(15));
1235 subelem[0]->set_node(9, elem->
node_ptr(17));
1237 subelem[1]->set_node(0, elem->
node_ptr(2));
1238 subelem[1]->set_node(1, elem->
node_ptr(3));
1239 subelem[1]->set_node(2, elem->
node_ptr(4));
1240 subelem[1]->set_node(3, elem->
node_ptr(5));
1242 subelem[1]->set_node(4, elem->
node_ptr(17));
1243 subelem[1]->set_node(5, elem->
node_ptr(12));
1244 subelem[1]->set_node(6, elem->
node_ptr(16));
1245 subelem[1]->set_node(7, elem->
node_ptr(11));
1246 subelem[1]->set_node(8, elem->
node_ptr(14));
1247 subelem[1]->set_node(9, elem->
node_ptr(13));
1249 subelem[2]->set_node(0, elem->
node_ptr(3));
1250 subelem[2]->set_node(1, elem->
node_ptr(1));
1251 subelem[2]->set_node(2, elem->
node_ptr(2));
1252 subelem[2]->set_node(3, elem->
node_ptr(4));
1254 subelem[2]->set_node(4, elem->
node_ptr(15));
1255 subelem[2]->set_node(5, elem->
node_ptr(7));
1256 subelem[2]->set_node(6, elem->
node_ptr(17));
1257 subelem[2]->set_node(7, elem->
node_ptr(12));
1258 subelem[2]->set_node(8, elem->
node_ptr(10));
1259 subelem[2]->set_node(9, elem->
node_ptr(16));
1274 const C0Polygon * polygon = cast_ptr<const C0Polygon *>(elem);
1276 for (
unsigned int t = 0; t != n_subtri; ++t)
1278 const std::array<int, 3> tri = polygon->
subtriangle(t);
1279 if (tri[0] < 0 || tri[1] < 0 || tri[2] < 0)
1280 libmesh_not_implemented_msg
1281 (
"Cannot convert a C0Polygon whose triangulation\n" 1282 "introduces special (non-vertex) points");
1284 subelem[t]->set_node(0, elem->
node_ptr(tri[0]));
1285 subelem[t]->set_node(1, elem->
node_ptr(tri[1]));
1286 subelem[t]->set_node(2, elem->
node_ptr(tri[2]));
1300 cast_ptr<const C0Polyhedron *>(elem);
1302 for (
unsigned int t = 0; t != n_sub; ++t)
1304 const std::array<int, 4> tet = polyhedron->
subelement(t);
1305 if (tet[0] < 0 || tet[1] < 0 || tet[2] < 0 || tet[3] < 0)
1306 libmesh_not_implemented_msg
1307 (
"Cannot convert a C0Polyhedron whose triangulation\n" 1308 "introduces special (non-vertex) points");
1310 subelem[t]->set_node(0, elem->
node_ptr(tet[0]));
1311 subelem[t]->set_node(1, elem->
node_ptr(tet[1]));
1312 subelem[t]->set_node(2, elem->
node_ptr(tet[2]));
1313 subelem[t]->set_node(3, elem->
node_ptr(tet[3]));
1347 libMesh::err <<
"Error, encountered unimplemented element " 1348 << Utility::enum_to_string<ElemType>(etype)
1349 <<
" in MeshTools::Modification::all_tri()..." 1351 libmesh_not_implemented();
1357 for (
unsigned int i=0; i != max_subelems; ++i)
1365 subelem[i]->add_extra_integers(nei);
1366 for (
unsigned int ei=0; ei != nei; ++ei)
1382 if (mesh_has_boundary_data || !mesh_is_serial)
1385 std::vector<boundary_id_type> bc_ids;
1396 std::vector<dof_id_type> elem_side_nodes(elem_side->n_nodes());
1397 for (
unsigned int esn=0,
1398 n_esn = cast_int<unsigned int>(elem_side_nodes.size());
1399 esn != n_esn; ++esn)
1400 elem_side_nodes[esn] = elem_side->node_id(esn);
1401 std::sort(elem_side_nodes.begin(), elem_side_nodes.end());
1403 for (
unsigned int i=0; i != max_subelems; ++i)
1406 for (
auto subside : subelem[i]->side_index_range())
1408 subelem[i]->build_side_ptr(subside_elem, subside);
1416 std::vector<dof_id_type> subside_nodes(subside_elem->n_vertices());
1417 for (
unsigned int ssn=0,
1418 n_ssn = cast_int<unsigned int>(subside_nodes.size());
1419 ssn != n_ssn; ++ssn)
1420 subside_nodes[ssn] = subside_elem->node_id(ssn);
1421 std::sort(subside_nodes.begin(), subside_nodes.end());
1425 if (std::includes(elem_side_nodes.begin(), elem_side_nodes.end(),
1426 subside_nodes.begin(), subside_nodes.end()))
1428 for (
const auto & b_id : bc_ids)
1431 new_bndry_ids.push_back(b_id);
1432 new_bndry_elements.push_back(subelem[i].
get());
1433 new_bndry_sides.push_back(subside);
1439 subelem[i]->set_neighbor(subside, const_cast<RemoteElem*>(
remote_elem));
1454 for (
unsigned int i=0; i != max_subelems; ++i)
1461 subelem[i]->set_id( max_orig_id + max_subelems*elem->
id() + i );
1463 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1464 subelem[i]->set_unique_id(max_unique_id + max_subelems*elem->
unique_id() + i);
1468 new_elements.push_back(std::move(subelem[i]));
1479 for (
auto & elem : new_elements)
1482 if (mesh_has_boundary_data)
1495 bool nbe_nonempty = new_bndry_elements.size();
1503 libmesh_assert_equal_to (new_bndry_elements.size(), new_bndry_sides.size());
1504 libmesh_assert_equal_to (new_bndry_sides.size(), new_bndry_ids.size());
1521 if (added_new_ghost_point)
1537 const Real default_weight = 1.0;
1539 const auto weight_index =
1547 std::unique_ptr<Elem> edge_ptr, face_ptr;
1549 for (
auto & elem :
mesh.element_ptr_range())
1552 libmesh_not_implemented_msg
1553 (
"all_rbb() currently only supports flat meshes with no refinement levels");
1555 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 1557 libmesh_not_implemented_msg
1558 (
"all_rbb() currently only supports finite geometric elements");
1580 auto make_edge_rbb = [default_weight, weight_index]
1588 const Real old_weight = n_center.get_extra_datum<
Real>(weight_index);
1589 if (old_weight != default_weight)
1592 Point & p2 = n_center;
1594 const Real w0 = n0.get_extra_datum<
Real>(weight_index);
1595 const Real w1 = n1.get_extra_datum<
Real>(weight_index);
1597 const Point e02 = p2-p0,
1599 const Real chord_02_len_sq = e02.norm_sq(),
1600 chord_21_len_sq = e21.norm_sq();
1608 const Real cos_phi = (e02*e21)/std::sqrt(chord_02_len_sq*chord_21_len_sq);
1615 libmesh_not_implemented_msg
1616 (
"all_rbb() is not recommended for extremely sharp curves on one edge");
1618 const Real w_center = cos_phi*std::sqrt(w0*w1);
1620 n_center.set_extra_datum<
Real>(weight_index, w_center);
1626 const Real w_mid = w0/4 + w1/4 + w_center/2;
1627 n_center *= 2*w_mid;
1628 n_center -= (w0 * p0 + w1 * p1)/2;
1629 n_center /= w_center;
1632 auto make_face_rbb = [weight_index] (
Elem & face)
1636 if (face.type() ==
TRI6)
1639 if (face.type() !=
QUAD9)
1640 libmesh_not_implemented_msg
1641 (
"all_rbb() currently only supports mid-face nodes on Quad9 faces");
1648 w[i] = face.node_ref(i).get_extra_datum<
Real>(weight_index);
1653 libmesh_assert_equal_to
1654 (face.node_ref(i).get_extra_datum<
Real>(weight_index), 1);
1674 const Point xi_avg = (face.point(7) + face.point(5))/2;
1675 const Point eta_avg = (face.point(4) + face.point(6))/2;
1676 const Point vertex_avg = (face.point(0) + face.point(1) +
1677 face.point(2) + face.point(3))/4;
1679 const Real w_xi = (w[7] + w[5])/2;
1680 const Real w_eta = (w[4] + w[6])/2;
1681 const Real w_mid = w_xi * w_eta;
1683 Node & midnode = face.node_ref(8);
1685 midnode = ((1+w_mid)/(w_xi+w_eta) * (w_xi*xi_avg + w_eta*eta_avg) - vertex_avg)/w_mid;
1691 Point midfacepts[6];
1694 midfacepts[i] = elem->
point(20+i);
1703 if (edge_ptr->type() !=
EDGE3)
1704 libmesh_not_implemented_msg
1705 (
"all_rbb() currently only supports meshes with 2- and/or 3-node edges");
1707 make_edge_rbb(edge_ptr->node_ref(0), edge_ptr->node_ref(1),
1708 edge_ptr->node_ref(2),
1709 edge_ptr->node_ref(0), edge_ptr->node_ref(1));
1717 bool check_face_points = (elem->
dim() > 2) &&
1720 if (check_face_points)
1730 make_face_rbb(*face_ptr);
1733 bool check_interior_points =
1736 if (check_interior_points)
1744 else if (elem->
dim() == 2)
1746 make_face_rbb(*elem);
1762 const int opposite_sides[3][2] = {{0,5}, {1,3}, {2,4}};
1765 const Point original_midpoint = midnode;
1768 Point sum_weighted_point = 0;
1769 Real sum_weight = 0;
1776 make_edge_rbb(n0, n1, midnode,
1777 midfacepts[opposite_sides[i][0]],
1778 midfacepts[opposite_sides[i][1]]);
1780 const Real midweight =
1782 sum_weight += midweight;
1783 sum_weighted_point += midweight * midnode;
1786 midnode = original_midpoint;
1787 midnode.set_extra_datum<
Real>(weight_index,
1792 const Real midweight = sum_weight/3;
1796 midnode = sum_weighted_point / 3 / midweight;
1799 libmesh_not_implemented_msg
1800 (
"all_rbb() doesn't yet support " << elem->
type());
1808 const unsigned int n_iterations,
1819 std::unordered_set<dof_id_type> boundary_node_ids =
1825 for (
unsigned int iter=0; iter<n_iterations; iter++)
1831 for (
unsigned int refinement_level=0; refinement_level !=
n_levels;
1835 std::vector<Point> new_positions;
1836 std::vector<Real>
weight;
1842 for (
const auto & elem :
as_range(
mesh.level_elements_begin(refinement_level),
1843 mesh.level_elements_end(refinement_level)))
1850 if (refinement_level == 0)
1863 const Elem & side = side_builder(*elem, s);
1867 Real node_weight = 1.;
1871 Point diff = node0-node1;
1876 new_positions[id0].add_scaled( node1, node_weight );
1877 new_positions[id1].add_scaled( node0, node_weight );
1878 weight[id0] += node_weight;
1879 weight[id1] += node_weight;
1883 #ifdef LIBMESH_ENABLE_AMR 1919 new_positions[id] = point;
1923 #endif // #ifdef LIBMESH_ENABLE_AMR 1931 if (!boundary_node_ids.count(nid) &&
weight[nid] > 0.)
1938 for (
auto & elem :
as_range(
mesh.level_elements_begin(refinement_level),
1939 mesh.level_elements_end(refinement_level)))
1941 const unsigned int son_begin = elem->
n_vertices();
1942 const unsigned int son_end = elem->
n_nodes();
1943 for (
unsigned int n=son_begin; n<son_end; n++)
1945 const unsigned int n_adjacent_vertices =
1949 for (
unsigned int v=0; v<n_adjacent_vertices; v++)
1966 #ifdef LIBMESH_ENABLE_AMR 1981 std::vector<std::unique_ptr<Elem>> new_elements;
1984 std::vector<Elem *> saved_boundary_elements;
1985 std::vector<boundary_id_type> saved_bc_ids;
1986 std::vector<unsigned short int> saved_bc_sides;
1989 std::vector<boundary_id_type> bc_ids;
1997 for (
auto & elem :
mesh.active_element_ptr_range())
2004 copy->set_node(n, elem->
node_ptr(n));
2012 copy->set_id( elem->
id() );
2013 #ifdef LIBMESH_ENABLE_UNIQUE_ID 2023 copy->set_neighbor(s, const_cast<RemoteElem *>(
remote_elem));
2026 for (
const auto & bc_id : bc_ids)
2029 saved_boundary_elements.push_back(copy.get());
2030 saved_bc_ids.push_back(bc_id);
2031 saved_bc_sides.push_back(s);
2038 copy->add_extra_integers(nei);
2039 for (
unsigned int i=0; i != nei; ++i)
2050 new_elements.push_back(std::move(copy));
2055 libmesh_assert_equal_to (saved_boundary_elements.size(), saved_bc_ids.size());
2056 libmesh_assert_equal_to (saved_bc_ids.size(), saved_bc_sides.size());
2059 for (
auto & elem :
mesh.element_ptr_range())
2063 for (
auto & new_elem : new_elements)
2074 libmesh_assert_equal_to (orig_id, added_elem->
id());
2081 for (
auto e :
index_range(saved_boundary_elements))
2089 #endif // #ifdef LIBMESH_ENABLE_AMR 2107 if (old_id == new_id)
2115 [old_id, new_id](
const ElemRange & range)
2117 for (
Elem * elem : range)
unsigned char mapping_data() const
void parallel_for(const Range &range, const Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided function object in parallel on the specified range.
std::size_t n_boundary_conds() const
ElemType
Defines an enum for geometric element types.
const Elem * parent() const
void add_scaled(const TypeVector< T2 > &, const T &)
Add a scaled value to this vector without creating a temporary.
virtual dof_id_type n_active_elem() const =0
A Node is like a Point, but with more information.
The Polyhedron is an element in 3D with an arbitrary number of polygonal faces.
virtual unique_id_type parallel_max_unique_id() const =0
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
void orient(BoundaryInfo *boundary_info)
Flips the element (by swapping node and neighbor pointers) to have a mapping Jacobian of opposite sig...
void set_mapping_type(const ElemMappingType type)
Sets the value of the mapping type for the element.
virtual ElemType side_type(const unsigned int s) const =0
unsigned int n_subtriangles() const
IntRange< unsigned short > side_index_range() const
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i)=0
void set_spatial_dimension(unsigned char d)
Sets the "spatial dimension" of the Mesh.
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly created (or read) mesh for use.
void remove(const Node *node)
Removes the boundary conditions associated with node node, if any exist.
This is the base class from which all geometric element types are derived.
unique_id_type unique_id() const
const Parallel::Communicator & comm() const
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.
The StoredRange class defines a contiguous, divisible set of objects.
The libMesh namespace provides an interface to certain functionality in the library.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
void renumber_id(boundary_id_type old_id, boundary_id_type new_id)
Changes all entities (nodes, sides, edges, shellfaces) with boundary id old_id to instead be labeled ...
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
Add a new Node at Point p to the end of the vertex array, with processor_id procid.
void unset_has_cached_elem_data()
Tells this we have done some operation (e.g.
This is the MeshBase class.
void add(const TypeVector< T2 > &)
Add to this vector without creating a temporary.
virtual std::array< int, 3 > subtriangle(unsigned int i) const
IntRange< unsigned short > edge_index_range() const
virtual Real embedding_matrix(const unsigned int child_num, const unsigned int child_node_num, const unsigned int parent_node_num) const =0
TensorValue< Real > RealTensorValue
Useful typedefs to allow transparent switching between Real and Complex data types.
virtual bool is_serial() const
TypeVector< T > unit() const
void libmesh_ignore(const Args &...)
static const boundary_id_type invalid_id
Number used for internal use.
virtual void delete_elem(Elem *e)=0
Removes element e from the mesh.
ElemMappingType mapping_type() const
This is the MeshCommunication class.
const Node & node_ref(const unsigned int i) const
virtual Real hmin() const
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
virtual unsigned int n_nodes() const =0
const ElemRange & element_stored_range()
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
unsigned int n_subelements() const
virtual std::array< int, 4 > subelement(unsigned int i) const
The Polygon is an element in 2D with an arbitrary (but fixed) number of sides.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
virtual const Node * query_node_ptr(const dof_id_type i) const =0
void set_mapping_data(const unsigned char data)
Sets the value of the mapping data for the element.
void set_default_mapping_type(const ElemMappingType type)
Set the default master space to physical space mapping basis functions to be used on newly added elem...
virtual dof_id_type max_elem_id() const =0
void clear_point_locator()
Releases the current PointLocator object.
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
static TensorValue< Real > intrinsic_rotation_matrix(Real phi, Real theta, Real psi)
Generate the intrinsic rotation matrix associated with the provided Euler angles. ...
void set_extra_datum(const unsigned int index, const T value)
Sets the value on this object of the extra datum associated with index, which should have been obtain...
Helper for building element sides that minimizes the construction of new elements.
virtual unsigned int n_edges() const =0
virtual unsigned int n_second_order_adjacent_vertices(const unsigned int n) const
unsigned int add_node_datum(const std::string &name, bool allocate_data=true, const T *default_value=nullptr)
Register a datum (of type T) to be added to each node in the mesh.
unsigned int which_child_am_i(const Elem *e) const
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
The C0Polygon is an element in 2D with an arbitrary (but fixed) number of first-order (EDGE2) sides...
const Elem * neighbor_ptr(unsigned int i) const
unsigned int level() const
virtual unsigned int n_vertices() const =0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
subdomain_id_type subdomain_id() const
void max(const T &r, T &o, Request &req) const
virtual unsigned short dim() const =0
const Node * node_ptr(const unsigned int i) const
void make_nodes_parallel_consistent(MeshBase &)
Copy processor_ids and ids on ghost nodes from their local processors.
virtual bool is_replicated() const
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
Add side side of element number elem with boundary id id to the boundary information data structure...
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const
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...
virtual void permute(unsigned int perm_num)=0
Permutes the element (by swapping node and neighbor pointers) according to the specified index...
unsigned int mesh_dimension() const
virtual std::unique_ptr< FunctionBase< Output > > clone() const =0
void set_default_mapping_data(const unsigned char data)
Set the default master space to physical space mapping basis functions to be used on newly added elem...
IntRange< unsigned short > node_index_range() const
unsigned int n_extra_integers() const
Returns how many extra integers are associated to the DofObject.
virtual const Node & node_ref(const dof_id_type i) const
virtual const Point & point(const dof_id_type i) const =0
Defines a dense vector for use in Finite Element-type computations.
virtual unsigned int n_faces() const =0
T get_extra_datum(const unsigned int index) const
Gets the value on this object of the extra datum associated with index, which should have been obtain...
virtual bool infinite() const =0
The C0Polyhedron is an element in 3D with an arbitrary (but fixed) number of polygonal first-order (C...
virtual dof_id_type max_node_id() const =0
virtual dof_id_type n_elem() const =0
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i)=0
processor_id_type processor_id() const
virtual Order default_order() const =0
processor_id_type processor_id() const
virtual ElemType type() const =0
A Point defines a location in LIBMESH_DIM dimensional Real space.
dof_id_type node_id(const unsigned int i) const
const Point & point(const unsigned int i) const
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
virtual unsigned int n_permutations() const =0
Returns the number of independent permutations of element nodes - e.g.
virtual dof_id_type n_nodes() const =0
virtual std::vector< unsigned int > nodes_on_side(const unsigned int) const =0
dof_id_type get_extra_integer(const unsigned int index) const
Gets the value on this object of the extra integer associated with index, which should have been obta...
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
const RemoteElem * remote_elem