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/face_tri3.h" 34 #include "libmesh/face_tri6.h" 35 #include "libmesh/libmesh_logging.h" 36 #include "libmesh/mesh_communication.h" 37 #include "libmesh/mesh_modification.h" 38 #include "libmesh/mesh_tools.h" 39 #include "libmesh/parallel.h" 40 #include "libmesh/remote_elem.h" 41 #include "libmesh/enum_to_string.h" 42 #include "libmesh/unstructured_mesh.h" 43 #include "libmesh/elem_side_builder.h" 44 #include "libmesh/tensor_value.h" 50 bool split_first_diagonal(
const Elem * elem,
51 unsigned int diag_1_node_1,
52 unsigned int diag_1_node_2,
53 unsigned int diag_2_node_1,
54 unsigned int diag_2_node_2)
56 return ((elem->
node_id(diag_1_node_1) > elem->
node_id(diag_2_node_1) &&
65 unsigned int highest_vertex_on(
const Elem * elem)
67 unsigned int highest_n = 0;
72 if (n_id > highest_n_id)
83 static const std::array<std::array<unsigned int, 3>, 8> opposing_nodes =
84 {{ {2,5,7},{3,4,6},{0,5,7},{1,4,6},{1,3,6},{0,2,7},{1,3,4},{0,2,5} }};
88 std::pair<unsigned int, unsigned int>
89 split_diagonal(
const Elem * elem,
90 const std::vector<unsigned int> & nodes_on_side)
92 libmesh_assert_equal_to(elem->
type(),
HEX8);
94 unsigned int highest_n = nodes_on_side.front();
96 for (
auto n : nodes_on_side)
99 if (n_id > highest_n_id)
106 for (
auto n : nodes_on_side)
108 for (
auto n2 : opposing_nodes[highest_n])
110 return std::make_pair(highest_n, n2);
120 template <
typename T>
121 struct reversion_wrapper { T& iterable; };
123 template <
typename T>
124 auto begin (reversion_wrapper<T> w) {
return std::rbegin(w.iterable);}
126 template <
typename T>
127 auto end (reversion_wrapper<T> w) {
return std::rend(w.iterable);}
129 template <
typename T>
130 reversion_wrapper<T> reverse(T&& iterable) {
return {iterable};}
143 const bool perturb_boundary)
149 LOG_SCOPE(
"distort()",
"MeshTools::Modification");
153 std::unordered_set<dof_id_type> boundary_node_ids;
154 if (!perturb_boundary)
161 std::numeric_limits<float>::max());
163 for (
const auto & elem :
mesh.active_element_ptr_range())
165 hmin[n.id()] = std::min(hmin[n.id()],
166 static_cast<float>(elem->
hmin()));
170 const unsigned int seed = 123456;
184 if ((perturb_boundary || !boundary_node_ids.count(n)) && hmin[n] < 1.e20)
187 Point dir (static_cast<Real>(std::rand())/static_cast<Real>(RAND_MAX),
188 (
mesh.
mesh_dimension() > 1) ? static_cast<Real>(std::rand())/static_cast<Real>(RAND_MAX) : 0.,
189 ((
mesh.
mesh_dimension() == 3) ? static_cast<Real>(std::rand())/static_cast<Real>(RAND_MAX) : 0.));
191 dir(0) = (dir(0)-.5)*2.;
194 dir(1) = (dir(1)-.5)*2.;
198 dir(2) = (dir(2)-.5)*2.;
207 (*node)(0) += dir(0)*factor*hmin[n];
210 (*node)(1) += dir(1)*factor*hmin[n];
214 (*node)(2) += dir(2)*factor*hmin[n];
224 LOG_SCOPE(
"permute_elements()",
"MeshTools::Modification");
233 const unsigned int seed = 123456;
244 int my_rand = std::rand();
252 if (!max_permutation)
255 const unsigned int perm = my_rand % max_permutation;
264 LOG_SCOPE(
"orient_elements()",
"MeshTools::Modification");
271 libmesh_not_implemented_msg(
"orient_elements() does not support refined meshes");
274 for (
auto elem :
mesh.element_ptr_range())
275 elem->
orient(&boundary_info);
286 LOG_SCOPE(
"redistribute()",
"MeshTools::Modification");
291 std::unique_ptr<FunctionBase<Real>> myfunc = mapfunc.
clone();
293 for (
auto & node :
mesh.node_ptr_range())
295 (*myfunc)(*node, output_vec);
297 (*node)(0) = output_vec(0);
299 (*node)(1) = output_vec(1);
302 (*node)(2) = output_vec(2);
314 const Point p(xt, yt, zt);
316 for (
auto & node :
mesh.node_ptr_range())
355 for (
auto & node :
mesh.node_ptr_range())
365 libmesh_error_msg(
"MeshTools::Modification::rotate() requires libMesh to be compiled with LIBMESH_DIM==3");
377 const Real x_scale = xs;
383 libmesh_assert_equal_to (zs, 0.);
385 y_scale = z_scale = x_scale;
389 for (
auto & node :
mesh.node_ptr_range())
390 (*node)(0) *= x_scale;
396 for (
auto & node :
mesh.node_ptr_range())
397 (*node)(1) *= y_scale;
403 for (
auto & node :
mesh.node_ptr_range())
404 (*node)(2) *= z_scale;
423 std::vector<std::unique_ptr<Elem>> new_elements;
425 unsigned int max_subelems = 1;
431 new_elements.reserve (max_subelems*n_orig_elem);
441 std::vector<Elem *> new_bndry_elements;
442 std::vector<unsigned short int> new_bndry_sides;
443 std::vector<boundary_id_type> new_bndry_ids;
448 bool added_new_ghost_point =
false;
461 #ifdef LIBMESH_ENABLE_UNIQUE_ID 466 std::unique_ptr<const Elem> elem_side, subside_elem;
468 for (
auto & elem :
mesh.element_ptr_range())
474 libmesh_not_implemented_msg(
"Cannot convert a refined element into simplices\n");
478 std::array<std::unique_ptr<Elem>, 6> subelem {};
491 subelem[0]->set_node(0, elem->
node_ptr(0));
492 subelem[0]->set_node(1, elem->
node_ptr(1));
493 subelem[0]->set_node(2, elem->
node_ptr(2));
495 subelem[1]->set_node(0, elem->
node_ptr(0));
496 subelem[1]->set_node(1, elem->
node_ptr(2));
497 subelem[1]->set_node(2, elem->
node_ptr(3));
502 subelem[0]->set_node(0, elem->
node_ptr(0));
503 subelem[0]->set_node(1, elem->
node_ptr(1));
504 subelem[0]->set_node(2, elem->
node_ptr(3));
506 subelem[1]->set_node(0, elem->
node_ptr(1));
507 subelem[1]->set_node(1, elem->
node_ptr(2));
508 subelem[1]->set_node(2, elem->
node_ptr(3));
518 added_new_ghost_point =
true;
535 subelem[0]->set_node(0, elem->
node_ptr(0));
536 subelem[0]->set_node(1, elem->
node_ptr(1));
537 subelem[0]->set_node(2, elem->
node_ptr(2));
538 subelem[0]->set_node(3, elem->
node_ptr(4));
539 subelem[0]->set_node(4, elem->
node_ptr(5));
540 subelem[0]->set_node(5, new_node);
542 subelem[1]->set_node(0, elem->
node_ptr(0));
543 subelem[1]->set_node(1, elem->
node_ptr(2));
544 subelem[1]->set_node(2, elem->
node_ptr(3));
545 subelem[1]->set_node(3, new_node);
546 subelem[1]->set_node(4, elem->
node_ptr(6));
547 subelem[1]->set_node(5, elem->
node_ptr(7));
553 subelem[0]->set_node(0, elem->
node_ptr(3));
554 subelem[0]->set_node(1, elem->
node_ptr(0));
555 subelem[0]->set_node(2, elem->
node_ptr(1));
556 subelem[0]->set_node(3, elem->
node_ptr(7));
557 subelem[0]->set_node(4, elem->
node_ptr(4));
558 subelem[0]->set_node(5, new_node);
560 subelem[1]->set_node(0, elem->
node_ptr(1));
561 subelem[1]->set_node(1, elem->
node_ptr(2));
562 subelem[1]->set_node(2, elem->
node_ptr(3));
563 subelem[1]->set_node(3, elem->
node_ptr(5));
564 subelem[1]->set_node(4, elem->
node_ptr(6));
565 subelem[1]->set_node(5, new_node);
580 subelem[0]->set_node(0, elem->
node_ptr(0));
581 subelem[0]->set_node(1, elem->
node_ptr(1));
582 subelem[0]->set_node(2, elem->
node_ptr(2));
583 subelem[0]->set_node(3, elem->
node_ptr(4));
584 subelem[0]->set_node(4, elem->
node_ptr(5));
585 subelem[0]->set_node(5, elem->
node_ptr(8));
587 subelem[1]->set_node(0, elem->
node_ptr(0));
588 subelem[1]->set_node(1, elem->
node_ptr(2));
589 subelem[1]->set_node(2, elem->
node_ptr(3));
590 subelem[1]->set_node(3, elem->
node_ptr(8));
591 subelem[1]->set_node(4, elem->
node_ptr(6));
592 subelem[1]->set_node(5, elem->
node_ptr(7));
597 subelem[0]->set_node(0, elem->
node_ptr(0));
598 subelem[0]->set_node(1, elem->
node_ptr(1));
599 subelem[0]->set_node(2, elem->
node_ptr(3));
600 subelem[0]->set_node(3, elem->
node_ptr(4));
601 subelem[0]->set_node(4, elem->
node_ptr(8));
602 subelem[0]->set_node(5, elem->
node_ptr(7));
604 subelem[1]->set_node(0, elem->
node_ptr(1));
605 subelem[1]->set_node(1, elem->
node_ptr(2));
606 subelem[1]->set_node(2, elem->
node_ptr(3));
607 subelem[1]->set_node(3, elem->
node_ptr(5));
608 subelem[1]->set_node(4, elem->
node_ptr(6));
609 subelem[1]->set_node(5, elem->
node_ptr(8));
633 const unsigned int highest_n = highest_vertex_on(elem);
637 static const std::array<unsigned int, 8> opposing_node =
638 {6, 7, 4, 5, 2, 3, 0, 1};
640 static const std::vector<std::vector<unsigned int>> sides_opposing_highest =
641 {{2,3,5},{3,4,5},{1,4,5},{1,2,5},{0,2,3},{0,3,4},{0,1,4},{0,1,2}};
642 static const std::vector<std::vector<unsigned int>> nodes_neighboring_highest =
643 {{1,3,4},{0,2,5},{1,3,6},{0,2,7},{0,5,7},{1,4,6},{2,5,7},{3,4,6}};
654 unsigned int next_subelem = 0;
655 for (
auto side : sides_opposing_highest[highest_n])
657 const std::vector<unsigned int> nodes_on_side =
660 auto [dn, dn2] = split_diagonal(elem, nodes_on_side);
662 unsigned int split_on_neighbor =
false;
663 for (
auto n : nodes_neighboring_highest[highest_n])
664 if (dn == n || dn2 == n)
666 split_on_neighbor =
true;
674 if (split_on_neighbor)
676 subelem[next_subelem]->set_node(0, elem->
node_ptr(highest_n));
677 subelem[next_subelem]->set_node(1, elem->
node_ptr(dn));
678 subelem[next_subelem]->set_node(2, elem->
node_ptr(dn2));
679 for (
auto n : nodes_on_side)
680 if (n != dn && n != dn2)
682 subelem[next_subelem]->set_node(3, elem->
node_ptr(n));
685 subelem[next_subelem]->orient(&boundary_info);
688 subelem[next_subelem]->set_node(0, elem->
node_ptr(highest_n));
689 subelem[next_subelem]->set_node(1, elem->
node_ptr(dn));
690 subelem[next_subelem]->set_node(2, elem->
node_ptr(dn2));
691 for (
auto n : reverse(nodes_on_side))
692 if (n != dn && n != dn2)
694 subelem[next_subelem]->set_node(3, elem->
node_ptr(n));
697 subelem[next_subelem]->orient(&boundary_info);
702 subelem[next_subelem]->set_node(0, elem->
node_ptr(highest_n));
703 subelem[next_subelem]->set_node(1, elem->
node_ptr(dn));
704 subelem[next_subelem]->set_node(2, elem->
node_ptr(dn2));
705 for (
auto n : nodes_on_side)
706 for (
auto n2 : nodes_neighboring_highest[highest_n])
709 subelem[next_subelem]->set_node(3, elem->
node_ptr(n));
710 goto break_both_loops;
714 subelem[next_subelem]->orient(&boundary_info);
727 if (next_subelem == 3)
729 subelem[next_subelem]->set_node(0, elem->
node_ptr(opposing_nodes[highest_n][0]));
730 subelem[next_subelem]->set_node(1, elem->
node_ptr(opposing_nodes[highest_n][1]));
731 subelem[next_subelem]->set_node(2, elem->
node_ptr(opposing_nodes[highest_n][2]));
732 subelem[next_subelem]->set_node(3, elem->
node_ptr(opposing_node[highest_n]));
733 subelem[next_subelem]->orient(&boundary_info);
736 subelem[next_subelem]->set_node(0, elem->
node_ptr(opposing_nodes[highest_n][0]));
737 subelem[next_subelem]->set_node(1, elem->
node_ptr(opposing_nodes[highest_n][1]));
738 subelem[next_subelem]->set_node(2, elem->
node_ptr(opposing_nodes[highest_n][2]));
739 subelem[next_subelem]->set_node(3, elem->
node_ptr(highest_n));
740 subelem[next_subelem]->orient(&boundary_info);
744 subelem[next_subelem].reset();
751 if (next_subelem == 4 ||
754 for (
auto side : sides_opposing_highest[highest_n])
756 const std::vector<unsigned int> nodes_on_side =
759 auto [dn, dn2] = split_diagonal(elem, nodes_on_side);
761 unsigned int split_on_neighbor =
false;
762 for (
auto n : nodes_neighboring_highest[highest_n])
763 if (dn == n || dn2 == n)
765 split_on_neighbor =
true;
771 if (!split_on_neighbor)
773 subelem[next_subelem]->set_node(0, elem->
node_ptr(highest_n));
774 subelem[next_subelem]->set_node(1, elem->
node_ptr(dn));
775 subelem[next_subelem]->set_node(2, elem->
node_ptr(dn2));
776 subelem[next_subelem]->set_node(3, elem->
node_ptr(opposing_node[highest_n]));
777 subelem[next_subelem]->orient(&boundary_info);
815 if (split_first_diagonal(elem, 0,4, 1,3))
818 if (split_first_diagonal(elem, 0,5, 2,3))
821 if (split_first_diagonal(elem, 1,5, 2,4))
823 subelem[0]->set_node(0, elem->
node_ptr(0));
824 subelem[0]->set_node(1, elem->
node_ptr(4));
825 subelem[0]->set_node(2, elem->
node_ptr(5));
826 subelem[0]->set_node(3, elem->
node_ptr(3));
828 subelem[1]->set_node(0, elem->
node_ptr(0));
829 subelem[1]->set_node(1, elem->
node_ptr(4));
830 subelem[1]->set_node(2, elem->
node_ptr(1));
831 subelem[1]->set_node(3, elem->
node_ptr(5));
833 subelem[2]->set_node(0, elem->
node_ptr(0));
834 subelem[2]->set_node(1, elem->
node_ptr(1));
835 subelem[2]->set_node(2, elem->
node_ptr(2));
836 subelem[2]->set_node(3, elem->
node_ptr(5));
842 subelem[0]->set_node(0, elem->
node_ptr(0));
843 subelem[0]->set_node(1, elem->
node_ptr(4));
844 subelem[0]->set_node(2, elem->
node_ptr(5));
845 subelem[0]->set_node(3, elem->
node_ptr(3));
847 subelem[1]->set_node(0, elem->
node_ptr(0));
848 subelem[1]->set_node(1, elem->
node_ptr(4));
849 subelem[1]->set_node(2, elem->
node_ptr(2));
850 subelem[1]->set_node(3, elem->
node_ptr(5));
852 subelem[2]->set_node(0, elem->
node_ptr(0));
853 subelem[2]->set_node(1, elem->
node_ptr(1));
854 subelem[2]->set_node(2, elem->
node_ptr(2));
855 subelem[2]->set_node(3, elem->
node_ptr(4));
865 subelem[0]->set_node(0, elem->
node_ptr(0));
866 subelem[0]->set_node(1, elem->
node_ptr(4));
867 subelem[0]->set_node(2, elem->
node_ptr(2));
868 subelem[0]->set_node(3, elem->
node_ptr(3));
870 subelem[1]->set_node(0, elem->
node_ptr(3));
871 subelem[1]->set_node(1, elem->
node_ptr(4));
872 subelem[1]->set_node(2, elem->
node_ptr(2));
873 subelem[1]->set_node(3, elem->
node_ptr(5));
875 subelem[2]->set_node(0, elem->
node_ptr(0));
876 subelem[2]->set_node(1, elem->
node_ptr(1));
877 subelem[2]->set_node(2, elem->
node_ptr(2));
878 subelem[2]->set_node(3, elem->
node_ptr(4));
886 if (split_first_diagonal(elem, 0,5, 2,3))
891 subelem[0]->set_node(0, elem->
node_ptr(1));
892 subelem[0]->set_node(1, elem->
node_ptr(3));
893 subelem[0]->set_node(2, elem->
node_ptr(4));
894 subelem[0]->set_node(3, elem->
node_ptr(5));
896 subelem[1]->set_node(0, elem->
node_ptr(1));
897 subelem[1]->set_node(1, elem->
node_ptr(0));
898 subelem[1]->set_node(2, elem->
node_ptr(3));
899 subelem[1]->set_node(3, elem->
node_ptr(5));
901 subelem[2]->set_node(0, elem->
node_ptr(0));
902 subelem[2]->set_node(1, elem->
node_ptr(1));
903 subelem[2]->set_node(2, elem->
node_ptr(2));
904 subelem[2]->set_node(3, elem->
node_ptr(5));
911 if (split_first_diagonal(elem, 1,5, 2,4))
913 subelem[0]->set_node(0, elem->
node_ptr(0));
914 subelem[0]->set_node(1, elem->
node_ptr(1));
915 subelem[0]->set_node(2, elem->
node_ptr(2));
916 subelem[0]->set_node(3, elem->
node_ptr(3));
918 subelem[1]->set_node(0, elem->
node_ptr(3));
919 subelem[1]->set_node(1, elem->
node_ptr(1));
920 subelem[1]->set_node(2, elem->
node_ptr(2));
921 subelem[1]->set_node(3, elem->
node_ptr(5));
923 subelem[2]->set_node(0, elem->
node_ptr(1));
924 subelem[2]->set_node(1, elem->
node_ptr(3));
925 subelem[2]->set_node(2, elem->
node_ptr(4));
926 subelem[2]->set_node(3, elem->
node_ptr(5));
932 subelem[0]->set_node(0, elem->
node_ptr(0));
933 subelem[0]->set_node(1, elem->
node_ptr(1));
934 subelem[0]->set_node(2, elem->
node_ptr(2));
935 subelem[0]->set_node(3, elem->
node_ptr(3));
937 subelem[1]->set_node(0, elem->
node_ptr(2));
938 subelem[1]->set_node(1, elem->
node_ptr(3));
939 subelem[1]->set_node(2, elem->
node_ptr(4));
940 subelem[1]->set_node(3, elem->
node_ptr(5));
942 subelem[2]->set_node(0, elem->
node_ptr(3));
943 subelem[2]->set_node(1, elem->
node_ptr(1));
944 subelem[2]->set_node(2, elem->
node_ptr(2));
945 subelem[2]->set_node(3, elem->
node_ptr(4));
955 libmesh_experimental();
956 libmesh_fallthrough();
964 if (split_first_diagonal(elem, 0,4, 1,3))
967 if (split_first_diagonal(elem, 0,5, 2,3))
970 if (split_first_diagonal(elem, 1,5, 2,4))
972 subelem[0]->set_node(0, elem->
node_ptr(0));
973 subelem[0]->set_node(1, elem->
node_ptr(4));
974 subelem[0]->set_node(2, elem->
node_ptr(5));
975 subelem[0]->set_node(3, elem->
node_ptr(3));
977 subelem[0]->set_node(4, elem->
node_ptr(15));
978 subelem[0]->set_node(5, elem->
node_ptr(13));
979 subelem[0]->set_node(6, elem->
node_ptr(17));
980 subelem[0]->set_node(7, elem->
node_ptr(9));
981 subelem[0]->set_node(8, elem->
node_ptr(12));
982 subelem[0]->set_node(9, elem->
node_ptr(14));
984 subelem[1]->set_node(0, elem->
node_ptr(0));
985 subelem[1]->set_node(1, elem->
node_ptr(4));
986 subelem[1]->set_node(2, elem->
node_ptr(1));
987 subelem[1]->set_node(3, elem->
node_ptr(5));
989 subelem[1]->set_node(4, elem->
node_ptr(15));
990 subelem[1]->set_node(5, elem->
node_ptr(10));
991 subelem[1]->set_node(6, elem->
node_ptr(6));
992 subelem[1]->set_node(7, elem->
node_ptr(17));
993 subelem[1]->set_node(8, elem->
node_ptr(13));
994 subelem[1]->set_node(9, elem->
node_ptr(16));
996 subelem[2]->set_node(0, elem->
node_ptr(0));
997 subelem[2]->set_node(1, elem->
node_ptr(1));
998 subelem[2]->set_node(2, elem->
node_ptr(2));
999 subelem[2]->set_node(3, elem->
node_ptr(5));
1001 subelem[2]->set_node(4, elem->
node_ptr(6));
1002 subelem[2]->set_node(5, elem->
node_ptr(7));
1003 subelem[2]->set_node(6, elem->
node_ptr(8));
1004 subelem[2]->set_node(7, elem->
node_ptr(17));
1005 subelem[2]->set_node(8, elem->
node_ptr(16));
1006 subelem[2]->set_node(9, elem->
node_ptr(11));
1012 subelem[0]->set_node(0, elem->
node_ptr(0));
1013 subelem[0]->set_node(1, elem->
node_ptr(4));
1014 subelem[0]->set_node(2, elem->
node_ptr(5));
1015 subelem[0]->set_node(3, elem->
node_ptr(3));
1017 subelem[0]->set_node(4, elem->
node_ptr(15));
1018 subelem[0]->set_node(5, elem->
node_ptr(13));
1019 subelem[0]->set_node(6, elem->
node_ptr(17));
1020 subelem[0]->set_node(7, elem->
node_ptr(9));
1021 subelem[0]->set_node(8, elem->
node_ptr(12));
1022 subelem[0]->set_node(9, elem->
node_ptr(14));
1024 subelem[1]->set_node(0, elem->
node_ptr(0));
1025 subelem[1]->set_node(1, elem->
node_ptr(4));
1026 subelem[1]->set_node(2, elem->
node_ptr(2));
1027 subelem[1]->set_node(3, elem->
node_ptr(5));
1029 subelem[1]->set_node(4, elem->
node_ptr(15));
1030 subelem[1]->set_node(5, elem->
node_ptr(16));
1031 subelem[1]->set_node(6, elem->
node_ptr(8));
1032 subelem[1]->set_node(7, elem->
node_ptr(17));
1033 subelem[1]->set_node(8, elem->
node_ptr(13));
1034 subelem[1]->set_node(9, elem->
node_ptr(11));
1036 subelem[2]->set_node(0, elem->
node_ptr(0));
1037 subelem[2]->set_node(1, elem->
node_ptr(1));
1038 subelem[2]->set_node(2, elem->
node_ptr(2));
1039 subelem[2]->set_node(3, elem->
node_ptr(4));
1041 subelem[2]->set_node(4, elem->
node_ptr(6));
1042 subelem[2]->set_node(5, elem->
node_ptr(7));
1043 subelem[2]->set_node(6, elem->
node_ptr(8));
1044 subelem[2]->set_node(7, elem->
node_ptr(15));
1045 subelem[2]->set_node(8, elem->
node_ptr(10));
1046 subelem[2]->set_node(9, elem->
node_ptr(16));
1056 subelem[0]->set_node(0, elem->
node_ptr(0));
1057 subelem[0]->set_node(1, elem->
node_ptr(4));
1058 subelem[0]->set_node(2, elem->
node_ptr(2));
1059 subelem[0]->set_node(3, elem->
node_ptr(3));
1061 subelem[0]->set_node(4, elem->
node_ptr(15));
1062 subelem[0]->set_node(5, elem->
node_ptr(16));
1063 subelem[0]->set_node(6, elem->
node_ptr(8));
1064 subelem[0]->set_node(7, elem->
node_ptr(9));
1065 subelem[0]->set_node(8, elem->
node_ptr(12));
1066 subelem[0]->set_node(9, elem->
node_ptr(17));
1068 subelem[1]->set_node(0, elem->
node_ptr(3));
1069 subelem[1]->set_node(1, elem->
node_ptr(4));
1070 subelem[1]->set_node(2, elem->
node_ptr(2));
1071 subelem[1]->set_node(3, elem->
node_ptr(5));
1073 subelem[1]->set_node(4, elem->
node_ptr(12));
1074 subelem[1]->set_node(5, elem->
node_ptr(16));
1075 subelem[1]->set_node(6, elem->
node_ptr(17));
1076 subelem[1]->set_node(7, elem->
node_ptr(14));
1077 subelem[1]->set_node(8, elem->
node_ptr(13));
1078 subelem[1]->set_node(9, elem->
node_ptr(11));
1080 subelem[2]->set_node(0, elem->
node_ptr(0));
1081 subelem[2]->set_node(1, elem->
node_ptr(1));
1082 subelem[2]->set_node(2, elem->
node_ptr(2));
1083 subelem[2]->set_node(3, elem->
node_ptr(4));
1085 subelem[2]->set_node(4, elem->
node_ptr(6));
1086 subelem[2]->set_node(5, elem->
node_ptr(7));
1087 subelem[2]->set_node(6, elem->
node_ptr(8));
1088 subelem[2]->set_node(7, elem->
node_ptr(15));
1089 subelem[2]->set_node(8, elem->
node_ptr(10));
1090 subelem[2]->set_node(9, elem->
node_ptr(16));
1098 if (split_first_diagonal(elem, 0,5, 2,3))
1103 subelem[0]->set_node(0, elem->
node_ptr(1));
1104 subelem[0]->set_node(1, elem->
node_ptr(3));
1105 subelem[0]->set_node(2, elem->
node_ptr(4));
1106 subelem[0]->set_node(3, elem->
node_ptr(5));
1108 subelem[0]->set_node(4, elem->
node_ptr(15));
1109 subelem[0]->set_node(5, elem->
node_ptr(12));
1110 subelem[0]->set_node(6, elem->
node_ptr(10));
1111 subelem[0]->set_node(7, elem->
node_ptr(16));
1112 subelem[0]->set_node(8, elem->
node_ptr(14));
1113 subelem[0]->set_node(9, elem->
node_ptr(13));
1115 subelem[1]->set_node(0, elem->
node_ptr(1));
1116 subelem[1]->set_node(1, elem->
node_ptr(0));
1117 subelem[1]->set_node(2, elem->
node_ptr(3));
1118 subelem[1]->set_node(3, elem->
node_ptr(5));
1120 subelem[1]->set_node(4, elem->
node_ptr(6));
1121 subelem[1]->set_node(5, elem->
node_ptr(9));
1122 subelem[1]->set_node(6, elem->
node_ptr(15));
1123 subelem[1]->set_node(7, elem->
node_ptr(16));
1124 subelem[1]->set_node(8, elem->
node_ptr(17));
1125 subelem[1]->set_node(9, elem->
node_ptr(14));
1127 subelem[2]->set_node(0, elem->
node_ptr(0));
1128 subelem[2]->set_node(1, elem->
node_ptr(1));
1129 subelem[2]->set_node(2, elem->
node_ptr(2));
1130 subelem[2]->set_node(3, elem->
node_ptr(5));
1132 subelem[2]->set_node(4, elem->
node_ptr(6));
1133 subelem[2]->set_node(5, elem->
node_ptr(7));
1134 subelem[2]->set_node(6, elem->
node_ptr(8));
1135 subelem[2]->set_node(7, elem->
node_ptr(17));
1136 subelem[2]->set_node(8, elem->
node_ptr(16));
1137 subelem[2]->set_node(9, elem->
node_ptr(11));
1144 if (split_first_diagonal(elem, 1,5, 2,4))
1146 subelem[0]->set_node(0, elem->
node_ptr(0));
1147 subelem[0]->set_node(1, elem->
node_ptr(1));
1148 subelem[0]->set_node(2, elem->
node_ptr(2));
1149 subelem[0]->set_node(3, elem->
node_ptr(3));
1151 subelem[0]->set_node(4, elem->
node_ptr(6));
1152 subelem[0]->set_node(5, elem->
node_ptr(7));
1153 subelem[0]->set_node(6, elem->
node_ptr(8));
1154 subelem[0]->set_node(7, elem->
node_ptr(9));
1155 subelem[0]->set_node(8, elem->
node_ptr(15));
1156 subelem[0]->set_node(9, elem->
node_ptr(17));
1158 subelem[1]->set_node(0, elem->
node_ptr(3));
1159 subelem[1]->set_node(1, elem->
node_ptr(1));
1160 subelem[1]->set_node(2, elem->
node_ptr(2));
1161 subelem[1]->set_node(3, elem->
node_ptr(5));
1163 subelem[1]->set_node(4, elem->
node_ptr(15));
1164 subelem[1]->set_node(5, elem->
node_ptr(7));
1165 subelem[1]->set_node(6, elem->
node_ptr(17));
1166 subelem[1]->set_node(7, elem->
node_ptr(14));
1167 subelem[1]->set_node(8, elem->
node_ptr(16));
1168 subelem[1]->set_node(9, elem->
node_ptr(11));
1170 subelem[2]->set_node(0, elem->
node_ptr(1));
1171 subelem[2]->set_node(1, elem->
node_ptr(3));
1172 subelem[2]->set_node(2, elem->
node_ptr(4));
1173 subelem[2]->set_node(3, elem->
node_ptr(5));
1175 subelem[2]->set_node(4, elem->
node_ptr(15));
1176 subelem[2]->set_node(5, elem->
node_ptr(12));
1177 subelem[2]->set_node(6, elem->
node_ptr(10));
1178 subelem[2]->set_node(7, elem->
node_ptr(16));
1179 subelem[2]->set_node(8, elem->
node_ptr(14));
1180 subelem[2]->set_node(9, elem->
node_ptr(13));
1186 subelem[0]->set_node(0, elem->
node_ptr(0));
1187 subelem[0]->set_node(1, elem->
node_ptr(1));
1188 subelem[0]->set_node(2, elem->
node_ptr(2));
1189 subelem[0]->set_node(3, elem->
node_ptr(3));
1191 subelem[0]->set_node(4, elem->
node_ptr(6));
1192 subelem[0]->set_node(5, elem->
node_ptr(7));
1193 subelem[0]->set_node(6, elem->
node_ptr(8));
1194 subelem[0]->set_node(7, elem->
node_ptr(9));
1195 subelem[0]->set_node(8, elem->
node_ptr(15));
1196 subelem[0]->set_node(9, elem->
node_ptr(17));
1198 subelem[1]->set_node(0, elem->
node_ptr(2));
1199 subelem[1]->set_node(1, elem->
node_ptr(3));
1200 subelem[1]->set_node(2, elem->
node_ptr(4));
1201 subelem[1]->set_node(3, elem->
node_ptr(5));
1203 subelem[1]->set_node(4, elem->
node_ptr(17));
1204 subelem[1]->set_node(5, elem->
node_ptr(12));
1205 subelem[1]->set_node(6, elem->
node_ptr(16));
1206 subelem[1]->set_node(7, elem->
node_ptr(11));
1207 subelem[1]->set_node(8, elem->
node_ptr(14));
1208 subelem[1]->set_node(9, elem->
node_ptr(13));
1210 subelem[2]->set_node(0, elem->
node_ptr(3));
1211 subelem[2]->set_node(1, elem->
node_ptr(1));
1212 subelem[2]->set_node(2, elem->
node_ptr(2));
1213 subelem[2]->set_node(3, elem->
node_ptr(4));
1215 subelem[2]->set_node(4, elem->
node_ptr(15));
1216 subelem[2]->set_node(5, elem->
node_ptr(7));
1217 subelem[2]->set_node(6, elem->
node_ptr(17));
1218 subelem[2]->set_node(7, elem->
node_ptr(12));
1219 subelem[2]->set_node(8, elem->
node_ptr(10));
1220 subelem[2]->set_node(9, elem->
node_ptr(16));
1250 libMesh::err <<
"Error, encountered unimplemented element " 1251 << Utility::enum_to_string<ElemType>(etype)
1252 <<
" in MeshTools::Modification::all_tri()..." 1254 libmesh_not_implemented();
1260 for (
unsigned int i=0; i != max_subelems; ++i)
1268 subelem[i]->add_extra_integers(nei);
1269 for (
unsigned int ei=0; ei != nei; ++ei)
1285 if (mesh_has_boundary_data || !mesh_is_serial)
1288 std::vector<boundary_id_type> bc_ids;
1299 std::vector<dof_id_type> elem_side_nodes(elem_side->n_nodes());
1300 for (
unsigned int esn=0,
1301 n_esn = cast_int<unsigned int>(elem_side_nodes.size());
1302 esn != n_esn; ++esn)
1303 elem_side_nodes[esn] = elem_side->node_id(esn);
1304 std::sort(elem_side_nodes.begin(), elem_side_nodes.end());
1306 for (
unsigned int i=0; i != max_subelems; ++i)
1309 for (
auto subside : subelem[i]->side_index_range())
1311 subelem[i]->build_side_ptr(subside_elem, subside);
1319 std::vector<dof_id_type> subside_nodes(subside_elem->n_vertices());
1320 for (
unsigned int ssn=0,
1321 n_ssn = cast_int<unsigned int>(subside_nodes.size());
1322 ssn != n_ssn; ++ssn)
1323 subside_nodes[ssn] = subside_elem->node_id(ssn);
1324 std::sort(subside_nodes.begin(), subside_nodes.end());
1328 if (std::includes(elem_side_nodes.begin(), elem_side_nodes.end(),
1329 subside_nodes.begin(), subside_nodes.end()))
1331 for (
const auto & b_id : bc_ids)
1334 new_bndry_ids.push_back(b_id);
1335 new_bndry_elements.push_back(subelem[i].
get());
1336 new_bndry_sides.push_back(subside);
1342 subelem[i]->set_neighbor(subside, const_cast<RemoteElem*>(
remote_elem));
1357 for (
unsigned int i=0; i != max_subelems; ++i)
1364 subelem[i]->set_id( max_orig_id + 6*elem->
id() + i );
1366 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1367 subelem[i]->set_unique_id(max_unique_id + max_subelems*elem->
unique_id() + i);
1371 new_elements.push_back(std::move(subelem[i]));
1382 for (
auto & elem : new_elements)
1385 if (mesh_has_boundary_data)
1398 bool nbe_nonempty = new_bndry_elements.size();
1406 libmesh_assert_equal_to (new_bndry_elements.size(), new_bndry_sides.size());
1407 libmesh_assert_equal_to (new_bndry_sides.size(), new_bndry_ids.size());
1424 if (added_new_ghost_point)
1438 const unsigned int n_iterations,
1449 std::unordered_set<dof_id_type> boundary_node_ids =
1455 for (
unsigned int iter=0; iter<n_iterations; iter++)
1461 for (
unsigned int refinement_level=0; refinement_level !=
n_levels;
1465 std::vector<Point> new_positions;
1466 std::vector<Real>
weight;
1472 for (
const auto & elem :
as_range(
mesh.level_elements_begin(refinement_level),
1473 mesh.level_elements_end(refinement_level)))
1480 if (refinement_level == 0)
1493 const Elem & side = side_builder(*elem, s);
1497 Real node_weight = 1.;
1501 Point diff = node0-node1;
1506 new_positions[id0].add_scaled( node1, node_weight );
1507 new_positions[id1].add_scaled( node0, node_weight );
1508 weight[id0] += node_weight;
1509 weight[id1] += node_weight;
1513 #ifdef LIBMESH_ENABLE_AMR 1549 new_positions[id] = point;
1553 #endif // #ifdef LIBMESH_ENABLE_AMR 1561 if (!boundary_node_ids.count(nid) &&
weight[nid] > 0.)
1568 for (
auto & elem :
as_range(
mesh.level_elements_begin(refinement_level),
1569 mesh.level_elements_end(refinement_level)))
1571 const unsigned int son_begin = elem->
n_vertices();
1572 const unsigned int son_end = elem->
n_nodes();
1573 for (
unsigned int n=son_begin; n<son_end; n++)
1575 const unsigned int n_adjacent_vertices =
1579 for (
unsigned int v=0; v<n_adjacent_vertices; v++)
1592 #ifdef LIBMESH_ENABLE_AMR 1607 std::vector<std::unique_ptr<Elem>> new_elements;
1610 std::vector<Elem *> saved_boundary_elements;
1611 std::vector<boundary_id_type> saved_bc_ids;
1612 std::vector<unsigned short int> saved_bc_sides;
1615 std::vector<boundary_id_type> bc_ids;
1623 for (
auto & elem :
mesh.active_element_ptr_range())
1630 copy->set_node(n, elem->
node_ptr(n));
1638 copy->set_id( elem->
id() );
1639 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1649 copy->set_neighbor(s, const_cast<RemoteElem *>(
remote_elem));
1652 for (
const auto & bc_id : bc_ids)
1655 saved_boundary_elements.push_back(copy.get());
1656 saved_bc_ids.push_back(bc_id);
1657 saved_bc_sides.push_back(s);
1664 copy->add_extra_integers(nei);
1665 for (
unsigned int i=0; i != nei; ++i)
1676 new_elements.push_back(std::move(copy));
1681 libmesh_assert_equal_to (saved_boundary_elements.size(), saved_bc_ids.size());
1682 libmesh_assert_equal_to (saved_bc_ids.size(), saved_bc_sides.size());
1685 for (
auto & elem :
mesh.element_ptr_range())
1689 for (
auto & new_elem : new_elements)
1700 libmesh_assert_equal_to (orig_id, added_elem->
id());
1707 for (
auto e :
index_range(saved_boundary_elements))
1715 #endif // #ifdef LIBMESH_ENABLE_AMR 1733 if (old_id == new_id)
1739 for (
auto & elem :
mesh.element_ptr_range())
unsigned char mapping_data() const
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.
virtual unique_id_type parallel_max_unique_id() const =0
auto norm() const -> decltype(std::norm(T()))
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...
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 ecreated (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 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.
This is the MeshBase class.
void add(const TypeVector< T2 > &)
Add to this vector without creating a temporary.
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
virtual unsigned int n_nodes() const =0
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)
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
virtual dof_id_type max_elem_id() const =0
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
static TensorValue< Real > intrinsic_rotation_matrix(Real phi, Real theta, Real psi)
Generate the intrinsic rotation matrix associated with the provided Euler angles. ...
Helper for building element sides that minimizes the construction of new elements.
virtual unsigned int n_second_order_adjacent_vertices(const unsigned int n) const
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.
const Elem * neighbor_ptr(unsigned int i) 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
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
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 dof_id_type max_node_id() const =0
virtual dof_id_type n_elem() const =0
processor_id_type processor_id() const
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