369 SPDLOG_LOGGER_DEBUG(
Logger(),
370 "Entering MeshHierarchy::PerformRefinement: {} levels",
390 size_type new_node_cnt = 0;
396 LF_VERIFY_MSG(node_index < pt_child_info.size(),
397 "Node index " << node_index <<
" out of range");
402 std::vector<std::unique_ptr<geometry::Geometry>> pt_child_geo_ptrs(
404 LF_VERIFY_MSG(pt_child_geo_ptrs.size() == 1,
405 "A point can only have one chile");
407 pt_child_info[node_index].child_point_idx =
412 SPDLOG_LOGGER_DEBUG(
Logger(),
"{} new nodes added", new_node_cnt);
422 size_type new_edge_cnt = 0;
428 auto ed_nodes = edge->SubEntities(1);
430 parent_mesh.
Index(*ed_nodes[0]);
432 parent_mesh.
Index(*ed_nodes[1]);
436 pt_child_info[ed_p0_coarse_idx].child_point_idx;
438 pt_child_info[ed_p1_coarse_idx].child_point_idx;
445 switch (edge_refpat) {
448 std::vector<std::unique_ptr<lf::geometry::Geometry>> ed_copy(
449 edge->Geometry()->ChildGeometry(rp, 0));
450 LF_VERIFY_MSG(ed_copy.size() == 1,
451 "Copy may create only a single child!");
453 SPDLOG_LOGGER_TRACE(
Logger(),
"Copy edge {} new edge [{},{}]",
454 edge_index, ed_p0_fine_idx, ed_p1_fine_idx);
459 std::array<lf::base::glb_idx_t, 2>{
460 {ed_p0_fine_idx, ed_p1_fine_idx}},
461 std::move(ed_copy[0])));
468 std::vector<std::unique_ptr<geometry::Geometry>> edge_nodes_geo_ptrs(
469 edge->Geometry()->ChildGeometry(rp, 1));
470 LF_VERIFY_MSG(edge_nodes_geo_ptrs.size() == 1,
471 "Split edge with " << edge_nodes_geo_ptrs.size()
478 std::vector<std::unique_ptr<geometry::Geometry>> edge_child_geo_ptrs(
479 edge->Geometry()->ChildGeometry(rp, 0));
481 edge_child_geo_ptrs.size() == 2,
482 "Split edge with " << edge_child_geo_ptrs.size() <<
" parts!");
488 SPDLOG_LOGGER_TRACE(
Logger(),
489 "Split Edge {} new edges [{},{}], [{},{}]",
490 edge_index, ed_p0_fine_idx, midpoint_fine_idx,
491 midpoint_fine_idx, ed_p1_fine_idx);
495 std::array<lf::base::glb_idx_t, 2>{
496 {ed_p0_fine_idx, midpoint_fine_idx}},
497 std::move(edge_child_geo_ptrs[0])));
500 std::array<lf::base::glb_idx_t, 2>{
501 {midpoint_fine_idx, ed_p1_fine_idx}},
502 std::move(edge_child_geo_ptrs[1])));
506 LF_VERIFY_MSG(
false,
"Refinement pattern "
507 <<
static_cast<int>(edge_refpat)
508 <<
" illegal for edge");
515 SPDLOG_LOGGER_DEBUG(Logger(),
"{} edges added", new_edge_cnt);
519 std::vector<CellChildInfo> &cell_child_info(cell_child_infos_.back());
523 LF_VERIFY_MSG(cell_child_info.size() == parent_mesh.NumEntities(0),
524 "Size mismatch for CellChildInfos");
525 for (
const mesh::Entity *cell : parent_mesh.Entities(0)) {
535 const RefPat cell_refpat(cell_ci.ref_pat_);
536 const sub_idx_t anchor = cell_ci.anchor_;
538 SPDLOG_LOGGER_TRACE(Logger(),
"Cell {} = {}, refpat = {}, anchor = {}",
539 cell_index, ref_el,
static_cast<int>(cell_refpat),
545 std::array<sub_idx_t, 4> mod{};
547 for (
int k = 0; k < num_vertices; k++) {
548 mod[k] = (k + anchor) % num_vertices;
553 std::array<std::vector<lf::base::glb_idx_t>, 3> cell_subent_idx;
554 cell_subent_idx[0].push_back(cell_index);
555 for (
int codim = 1; codim <= 2; codim++) {
556 auto subentities = cell->SubEntities(codim);
557 for (
const mesh::Entity *sub_ent : subentities) {
558 cell_subent_idx[codim].push_back(parent_mesh.Index(*sub_ent));
561 cell_subent_idx[codim].size() == ref_el.NumSubEntities(codim),
562 ref_el.ToString() <<
": only " << cell_subent_idx[codim].size()
563 <<
" subents of codim = " << codim);
565 SPDLOG_LOGGER_TRACE(Logger(),
" Subent({}) = [{}], ", codim,
566 cell_subent_idx[codim]);
570 std::array<lf::base::glb_idx_t, 4> vertex_child_idx{
573 LF_VERIFY_MSG(pt_child_info[cell_subent_idx[2][vt_lidx]].ref_pat ==
575 "Vertex must have been copied!");
576 vertex_child_idx[vt_lidx] =
577 pt_child_info[cell_subent_idx[2][vt_lidx]].child_point_idx;
581 std::array<lf::base::glb_idx_t, 4> edge_midpoint_idx{
584 const EdgeChildInfo &ed_ci(ed_child_info[cell_subent_idx[1][ed_lidx]]);
585 if (!ed_ci.child_point_idx.empty()) {
586 LF_VERIFY_MSG(ed_child_info[cell_subent_idx[1][ed_lidx]].ref_pat_ ==
588 "Edge with a midpoint must have been split");
589 edge_midpoint_idx[ed_lidx] = ed_ci.child_point_idx[0];
593 SPDLOG_LOGGER_TRACE(Logger(),
"vt_child_idx = {}, ed_mp_idx = {}",
594 std::span(vertex_child_idx.data(), num_vertices),
595 std::span(edge_midpoint_idx.data(), num_edges));
599 std::vector<std::vector<glb_idx_t>> child_cell_nodes;
600 std::vector<glb_idx_t> tria_ccn_tmp(3);
601 std::vector<glb_idx_t> quad_ccn_tmp(4);
603 std::vector<std::array<glb_idx_t, 2>> child_edge_nodes;
604 std::array<glb_idx_t, 2> cen_tmp{};
610 switch (cell_refpat) {
612 LF_VERIFY_MSG(
false,
"Every triangle must be refined");
617 child_cell_nodes.push_back({vertex_child_idx[0],
619 vertex_child_idx[2]});
625 "Anchor must be set for bisection refinement of triangle");
627 tria_ccn_tmp[0] = vertex_child_idx[mod[0]];
628 tria_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
629 tria_ccn_tmp[2] = vertex_child_idx[mod[2]];
631 "refpat = " << (
int)cell_refpat <<
": illegal index");
632 child_cell_nodes.push_back(tria_ccn_tmp);
634 tria_ccn_tmp[0] = vertex_child_idx[mod[1]];
635 tria_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
636 tria_ccn_tmp[2] = vertex_child_idx[mod[2]];
638 "refpat = " << (
int)cell_refpat <<
": illegal index");
639 child_cell_nodes.push_back(tria_ccn_tmp);
642 cen_tmp[0] = edge_midpoint_idx[mod[0]];
643 cen_tmp[1] = vertex_child_idx[mod[2]];
644 child_edge_nodes.push_back(cen_tmp);
650 "Anchor must be set for trisection refinement of triangle");
654 tria_ccn_tmp[0] = vertex_child_idx[mod[0]];
655 tria_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
656 tria_ccn_tmp[2] = vertex_child_idx[mod[2]];
658 "refpat = " << (
int)cell_refpat <<
": illegal index");
659 child_cell_nodes.push_back(tria_ccn_tmp);
661 tria_ccn_tmp[0] = vertex_child_idx[mod[1]];
662 tria_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
663 tria_ccn_tmp[2] = edge_midpoint_idx[mod[1]];
665 "refpat = " << (
int)cell_refpat <<
": illegal index");
666 child_cell_nodes.push_back(tria_ccn_tmp);
668 tria_ccn_tmp[0] = vertex_child_idx[mod[2]];
669 tria_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
670 tria_ccn_tmp[2] = edge_midpoint_idx[mod[1]];
672 "refpat = " << (
int)cell_refpat <<
": illegal index");
673 child_cell_nodes.push_back(tria_ccn_tmp);
676 cen_tmp[0] = edge_midpoint_idx[mod[0]];
677 cen_tmp[1] = vertex_child_idx[mod[2]];
678 child_edge_nodes.push_back(cen_tmp);
680 cen_tmp[0] = edge_midpoint_idx[mod[0]];
681 cen_tmp[1] = edge_midpoint_idx[mod[1]];
682 child_edge_nodes.push_back(cen_tmp);
688 "Anchor must be set for trisection refinement of triangle");
693 tria_ccn_tmp[0] = vertex_child_idx[mod[0]];
694 tria_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
695 tria_ccn_tmp[2] = edge_midpoint_idx[mod[2]];
697 "refpat = " << (
int)cell_refpat <<
": illegal index");
698 child_cell_nodes.push_back(tria_ccn_tmp);
700 tria_ccn_tmp[0] = vertex_child_idx[mod[1]];
701 tria_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
702 tria_ccn_tmp[2] = vertex_child_idx[mod[2]];
704 "refpat = " << (
int)cell_refpat <<
": illegal index");
705 child_cell_nodes.push_back(tria_ccn_tmp);
707 tria_ccn_tmp[0] = vertex_child_idx[mod[2]];
708 tria_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
709 tria_ccn_tmp[2] = edge_midpoint_idx[mod[2]];
711 "refpat = " << (
int)cell_refpat <<
": illegal index");
712 child_cell_nodes.push_back(tria_ccn_tmp);
715 cen_tmp[0] = edge_midpoint_idx[mod[0]];
716 cen_tmp[1] = vertex_child_idx[mod[2]];
717 child_edge_nodes.push_back(cen_tmp);
719 cen_tmp[0] = edge_midpoint_idx[mod[0]];
720 cen_tmp[1] = edge_midpoint_idx[mod[2]];
721 child_edge_nodes.push_back(cen_tmp);
727 "Anchor must be set for quadsection refinement of triangle");
731 tria_ccn_tmp[0] = vertex_child_idx[mod[0]];
732 tria_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
733 tria_ccn_tmp[2] = edge_midpoint_idx[mod[2]];
735 "refpat = " << (
int)cell_refpat <<
": illegal index");
736 child_cell_nodes.push_back(tria_ccn_tmp);
738 tria_ccn_tmp[0] = vertex_child_idx[mod[1]];
739 tria_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
740 tria_ccn_tmp[2] = edge_midpoint_idx[mod[1]];
742 "refpat = " << (
int)cell_refpat <<
": illegal index");
743 child_cell_nodes.push_back(tria_ccn_tmp);
745 tria_ccn_tmp[0] = vertex_child_idx[mod[2]];
746 tria_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
747 tria_ccn_tmp[2] = edge_midpoint_idx[mod[1]];
749 "refpat = " << (
int)cell_refpat <<
": illegal index");
750 child_cell_nodes.push_back(tria_ccn_tmp);
752 tria_ccn_tmp[0] = vertex_child_idx[mod[2]];
753 tria_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
754 tria_ccn_tmp[2] = edge_midpoint_idx[mod[2]];
756 "refpat = " << (
int)cell_refpat <<
": illegal index");
757 child_cell_nodes.push_back(tria_ccn_tmp);
760 cen_tmp[0] = edge_midpoint_idx[mod[0]];
761 cen_tmp[1] = vertex_child_idx[mod[2]];
762 child_edge_nodes.push_back(cen_tmp);
764 cen_tmp[0] = edge_midpoint_idx[mod[0]];
765 cen_tmp[1] = edge_midpoint_idx[mod[2]];
766 child_edge_nodes.push_back(cen_tmp);
768 cen_tmp[0] = edge_midpoint_idx[mod[0]];
769 cen_tmp[1] = edge_midpoint_idx[mod[1]];
770 child_edge_nodes.push_back(cen_tmp);
778 std::vector<std::unique_ptr<geometry::Geometry>>
779 cell_center_geo_ptrs(cell->Geometry()->ChildGeometry(
781 LF_VERIFY_MSG(cell_center_geo_ptrs.size() == 1,
782 "Barycentrically refined triangle with "
783 << cell_center_geo_ptrs.size()
784 <<
" interior child nodes ??");
786 const glb_idx_t center_fine_idx =
787 mesh_factory_->AddPoint(std::move(cell_center_geo_ptrs[0]));
788 cell_ci.child_point_idx.push_back(center_fine_idx);
790 tria_ccn_tmp[0] = vertex_child_idx[0];
791 tria_ccn_tmp[1] = edge_midpoint_idx[0];
792 tria_ccn_tmp[2] = center_fine_idx;
794 "refpat = " << (
int)cell_refpat <<
": illegal index");
795 child_cell_nodes.push_back(tria_ccn_tmp);
797 tria_ccn_tmp[0] = vertex_child_idx[1];
798 tria_ccn_tmp[1] = edge_midpoint_idx[0];
799 tria_ccn_tmp[2] = center_fine_idx;
801 "refpat = " << (
int)cell_refpat <<
": illegal index");
802 child_cell_nodes.push_back(tria_ccn_tmp);
804 tria_ccn_tmp[0] = vertex_child_idx[1];
805 tria_ccn_tmp[1] = edge_midpoint_idx[1];
806 tria_ccn_tmp[2] = center_fine_idx;
808 "refpat = " << (
int)cell_refpat <<
": illegal index");
809 child_cell_nodes.push_back(tria_ccn_tmp);
811 tria_ccn_tmp[0] = vertex_child_idx[2];
812 tria_ccn_tmp[1] = edge_midpoint_idx[1];
813 tria_ccn_tmp[2] = center_fine_idx;
815 "refpat = " << (
int)cell_refpat <<
": illegal index");
816 child_cell_nodes.push_back(tria_ccn_tmp);
818 tria_ccn_tmp[0] = vertex_child_idx[2];
819 tria_ccn_tmp[1] = edge_midpoint_idx[2];
820 tria_ccn_tmp[2] = center_fine_idx;
822 "refpat = " << (
int)cell_refpat <<
": illegal index");
823 child_cell_nodes.push_back(tria_ccn_tmp);
825 tria_ccn_tmp[0] = vertex_child_idx[0];
826 tria_ccn_tmp[1] = edge_midpoint_idx[2];
827 tria_ccn_tmp[2] = center_fine_idx;
829 "refpat = " << (
int)cell_refpat <<
": illegal index");
830 child_cell_nodes.push_back(tria_ccn_tmp);
833 cen_tmp[0] = vertex_child_idx[0];
834 cen_tmp[1] = center_fine_idx;
835 child_edge_nodes.push_back(cen_tmp);
837 cen_tmp[0] = vertex_child_idx[1];
838 cen_tmp[1] = center_fine_idx;
839 child_edge_nodes.push_back(cen_tmp);
841 cen_tmp[0] = vertex_child_idx[2];
842 cen_tmp[1] = center_fine_idx;
843 child_edge_nodes.push_back(cen_tmp);
845 cen_tmp[0] = edge_midpoint_idx[0];
846 cen_tmp[1] = center_fine_idx;
847 child_edge_nodes.push_back(cen_tmp);
849 cen_tmp[0] = edge_midpoint_idx[1];
850 cen_tmp[1] = center_fine_idx;
851 child_edge_nodes.push_back(cen_tmp);
853 cen_tmp[0] = edge_midpoint_idx[2];
854 cen_tmp[1] = center_fine_idx;
855 child_edge_nodes.push_back(cen_tmp);
861 tria_ccn_tmp[0] = vertex_child_idx[0];
862 tria_ccn_tmp[1] = edge_midpoint_idx[0];
863 tria_ccn_tmp[2] = edge_midpoint_idx[2];
865 "refpat = " << (
int)cell_refpat <<
": illegal index");
866 child_cell_nodes.push_back(tria_ccn_tmp);
868 tria_ccn_tmp[0] = vertex_child_idx[1];
869 tria_ccn_tmp[1] = edge_midpoint_idx[0];
870 tria_ccn_tmp[2] = edge_midpoint_idx[1];
872 "refpat = " << (
int)cell_refpat <<
": illegal index");
873 child_cell_nodes.push_back(tria_ccn_tmp);
875 tria_ccn_tmp[0] = vertex_child_idx[2];
876 tria_ccn_tmp[1] = edge_midpoint_idx[2];
877 tria_ccn_tmp[2] = edge_midpoint_idx[1];
879 "refpat = " << (
int)cell_refpat <<
": illegal index");
880 child_cell_nodes.push_back(tria_ccn_tmp);
882 tria_ccn_tmp[0] = edge_midpoint_idx[0];
883 tria_ccn_tmp[1] = edge_midpoint_idx[1];
884 tria_ccn_tmp[2] = edge_midpoint_idx[2];
886 "refpat = " << (
int)cell_refpat <<
": illegal index");
887 child_cell_nodes.push_back(tria_ccn_tmp);
890 cen_tmp[0] = edge_midpoint_idx[0];
891 cen_tmp[1] = edge_midpoint_idx[2];
892 child_edge_nodes.push_back(cen_tmp);
894 cen_tmp[0] = edge_midpoint_idx[0];
895 cen_tmp[1] = edge_midpoint_idx[1];
896 child_edge_nodes.push_back(cen_tmp);
898 cen_tmp[0] = edge_midpoint_idx[2];
899 cen_tmp[1] = edge_midpoint_idx[1];
900 child_edge_nodes.push_back(cen_tmp);
906 false,
"Refinement pattern not (yet) implemented for triangle");
912 switch (cell_refpat) {
914 LF_VERIFY_MSG(
false,
"Every quadrilateral must be refined");
919 child_cell_nodes.push_back(
920 {vertex_child_idx[0], vertex_child_idx[1], vertex_child_idx[2],
921 vertex_child_idx[3]});
927 "Anchor must be set for trisection refinement of quad");
931 tria_ccn_tmp[0] = edge_midpoint_idx[mod[0]];
932 tria_ccn_tmp[1] = vertex_child_idx[mod[2]];
933 tria_ccn_tmp[2] = vertex_child_idx[mod[3]];
935 "refpat = " << (
int)cell_refpat <<
": illegal index");
936 child_cell_nodes.push_back(tria_ccn_tmp);
938 tria_ccn_tmp[0] = edge_midpoint_idx[mod[0]];
939 tria_ccn_tmp[1] = vertex_child_idx[mod[0]];
940 tria_ccn_tmp[2] = vertex_child_idx[mod[3]];
942 "refpat = " << (
int)cell_refpat <<
": illegal index");
943 child_cell_nodes.push_back(tria_ccn_tmp);
945 tria_ccn_tmp[0] = edge_midpoint_idx[mod[0]];
946 tria_ccn_tmp[1] = vertex_child_idx[mod[1]];
947 tria_ccn_tmp[2] = vertex_child_idx[mod[2]];
949 "refpat = " << (
int)cell_refpat <<
": illegal index");
950 child_cell_nodes.push_back(tria_ccn_tmp);
953 cen_tmp[0] = edge_midpoint_idx[mod[0]];
954 cen_tmp[1] = vertex_child_idx[mod[2]];
955 child_edge_nodes.push_back(cen_tmp);
957 cen_tmp[0] = edge_midpoint_idx[mod[0]];
958 cen_tmp[1] = vertex_child_idx[mod[3]];
959 child_edge_nodes.push_back(cen_tmp);
965 "Anchor must be set for quadsection refinement of triangle");
969 tria_ccn_tmp[0] = vertex_child_idx[mod[0]];
970 tria_ccn_tmp[1] = vertex_child_idx[mod[3]];
971 tria_ccn_tmp[2] = edge_midpoint_idx[mod[0]];
973 "refpat = " << (
int)cell_refpat <<
": illegal index");
974 child_cell_nodes.push_back(tria_ccn_tmp);
976 tria_ccn_tmp[0] = vertex_child_idx[mod[1]];
977 tria_ccn_tmp[1] = edge_midpoint_idx[mod[1]];
978 tria_ccn_tmp[2] = edge_midpoint_idx[mod[0]];
980 "refpat = " << (
int)cell_refpat <<
": illegal index");
981 child_cell_nodes.push_back(tria_ccn_tmp);
983 tria_ccn_tmp[0] = vertex_child_idx[mod[2]];
984 tria_ccn_tmp[1] = vertex_child_idx[mod[3]];
985 tria_ccn_tmp[2] = edge_midpoint_idx[mod[1]];
987 "refpat = " << (
int)cell_refpat <<
": illegal index");
988 child_cell_nodes.push_back(tria_ccn_tmp);
990 tria_ccn_tmp[0] = edge_midpoint_idx[mod[0]];
991 tria_ccn_tmp[1] = edge_midpoint_idx[mod[1]];
992 tria_ccn_tmp[2] = vertex_child_idx[mod[3]];
994 "refpat = " << (
int)cell_refpat <<
": illegal index");
995 child_cell_nodes.push_back(tria_ccn_tmp);
998 cen_tmp[0] = vertex_child_idx[mod[3]];
999 cen_tmp[1] = edge_midpoint_idx[mod[0]];
1000 child_edge_nodes.push_back(cen_tmp);
1002 cen_tmp[0] = edge_midpoint_idx[mod[1]];
1003 cen_tmp[1] = edge_midpoint_idx[mod[0]];
1004 child_edge_nodes.push_back(cen_tmp);
1006 cen_tmp[0] = vertex_child_idx[mod[3]];
1007 cen_tmp[1] = edge_midpoint_idx[mod[1]];
1008 child_edge_nodes.push_back(cen_tmp);
1013 LF_VERIFY_MSG(anchor !=
idx_nil,
1014 "Anchor must be set for splitting of quad");
1017 quad_ccn_tmp[0] = vertex_child_idx[mod[0]];
1018 quad_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
1019 quad_ccn_tmp[2] = edge_midpoint_idx[mod[2]];
1020 quad_ccn_tmp[3] = vertex_child_idx[mod[3]];
1022 "refpat = " << (
int)cell_refpat <<
": illegal index");
1023 child_cell_nodes.push_back(quad_ccn_tmp);
1025 quad_ccn_tmp[0] = vertex_child_idx[mod[1]];
1026 quad_ccn_tmp[1] = vertex_child_idx[mod[2]];
1027 quad_ccn_tmp[2] = edge_midpoint_idx[mod[2]];
1028 quad_ccn_tmp[3] = edge_midpoint_idx[mod[0]];
1030 "refpat = " << (
int)cell_refpat <<
": illegal index");
1031 child_cell_nodes.push_back(quad_ccn_tmp);
1034 cen_tmp[0] = edge_midpoint_idx[mod[0]];
1035 cen_tmp[1] = edge_midpoint_idx[mod[2]];
1036 child_edge_nodes.push_back(cen_tmp);
1042 "Anchor must be set for three edge refinement of a quad");
1044 quad_ccn_tmp[0] = vertex_child_idx[mod[2]];
1045 quad_ccn_tmp[1] = vertex_child_idx[mod[3]];
1046 quad_ccn_tmp[2] = edge_midpoint_idx[mod[3]];
1047 quad_ccn_tmp[3] = edge_midpoint_idx[mod[1]];
1049 "refpat = " << (
int)cell_refpat <<
": illegal index");
1050 child_cell_nodes.push_back(quad_ccn_tmp);
1052 tria_ccn_tmp[0] = vertex_child_idx[mod[0]];
1053 tria_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
1054 tria_ccn_tmp[2] = edge_midpoint_idx[mod[3]];
1056 "refpat = " << (
int)cell_refpat <<
": illegal index");
1057 child_cell_nodes.push_back(tria_ccn_tmp);
1059 tria_ccn_tmp[0] = vertex_child_idx[mod[1]];
1060 tria_ccn_tmp[1] = edge_midpoint_idx[mod[0]];
1061 tria_ccn_tmp[2] = edge_midpoint_idx[mod[1]];
1063 "refpat = " << (
int)cell_refpat <<
": illegal index");
1064 child_cell_nodes.push_back(tria_ccn_tmp);
1066 tria_ccn_tmp[0] = edge_midpoint_idx[mod[0]];
1067 tria_ccn_tmp[1] = edge_midpoint_idx[mod[1]];
1068 tria_ccn_tmp[2] = edge_midpoint_idx[mod[3]];
1070 "refpat = " << (
int)cell_refpat <<
": illegal index");
1071 child_cell_nodes.push_back(tria_ccn_tmp);
1074 cen_tmp[0] = edge_midpoint_idx[mod[3]];
1075 cen_tmp[1] = edge_midpoint_idx[mod[1]];
1076 child_edge_nodes.push_back(cen_tmp);
1078 cen_tmp[0] = edge_midpoint_idx[mod[0]];
1079 cen_tmp[1] = edge_midpoint_idx[mod[3]];
1080 child_edge_nodes.push_back(cen_tmp);
1082 cen_tmp[0] = edge_midpoint_idx[mod[0]];
1083 cen_tmp[1] = edge_midpoint_idx[mod[1]];
1084 child_edge_nodes.push_back(cen_tmp);
1090 std::vector<std::unique_ptr<geometry::Geometry>>
1091 cell_center_geo_ptrs(cell->Geometry()->ChildGeometry(
1093 LF_VERIFY_MSG(cell_center_geo_ptrs.size() == 1,
1094 "Regularly refined quadrilateral with "
1095 << cell_center_geo_ptrs.size()
1096 <<
" interior child nodes!");
1098 const glb_idx_t center_fine_idx =
1099 mesh_factory_->AddPoint(std::move(cell_center_geo_ptrs[0]));
1100 cell_ci.child_point_idx.push_back(center_fine_idx);
1103 quad_ccn_tmp[0] = vertex_child_idx[0];
1104 quad_ccn_tmp[1] = edge_midpoint_idx[0];
1105 quad_ccn_tmp[2] = center_fine_idx;
1106 quad_ccn_tmp[3] = edge_midpoint_idx[3];
1108 "refpat = " << (
int)cell_refpat <<
": illegal index");
1109 child_cell_nodes.push_back(quad_ccn_tmp);
1111 quad_ccn_tmp[0] = vertex_child_idx[1];
1112 quad_ccn_tmp[1] = edge_midpoint_idx[1];
1113 quad_ccn_tmp[2] = center_fine_idx;
1114 quad_ccn_tmp[3] = edge_midpoint_idx[0];
1116 "refpat = " << (
int)cell_refpat <<
": illegal index");
1117 child_cell_nodes.push_back(quad_ccn_tmp);
1119 quad_ccn_tmp[0] = vertex_child_idx[2];
1120 quad_ccn_tmp[1] = edge_midpoint_idx[1];
1121 quad_ccn_tmp[2] = center_fine_idx;
1122 quad_ccn_tmp[3] = edge_midpoint_idx[2];
1124 "refpat = " << (
int)cell_refpat <<
": illegal index");
1125 child_cell_nodes.push_back(quad_ccn_tmp);
1127 quad_ccn_tmp[0] = vertex_child_idx[3];
1128 quad_ccn_tmp[1] = edge_midpoint_idx[2];
1129 quad_ccn_tmp[2] = center_fine_idx;
1130 quad_ccn_tmp[3] = edge_midpoint_idx[3];
1132 "refpat = " << (
int)cell_refpat <<
": illegal index");
1133 child_cell_nodes.push_back(quad_ccn_tmp);
1136 cen_tmp[0] = edge_midpoint_idx[0];
1137 cen_tmp[1] = center_fine_idx;
1138 child_edge_nodes.push_back(cen_tmp);
1140 cen_tmp[0] = edge_midpoint_idx[1];
1141 cen_tmp[1] = center_fine_idx;
1142 child_edge_nodes.push_back(cen_tmp);
1144 cen_tmp[0] = edge_midpoint_idx[2];
1145 cen_tmp[1] = center_fine_idx;
1146 child_edge_nodes.push_back(cen_tmp);
1148 cen_tmp[0] = edge_midpoint_idx[3];
1149 cen_tmp[1] = center_fine_idx;
1150 child_edge_nodes.push_back(cen_tmp);
1156 "Refinement pattern not (yet) implemented for quadrilateral");
1162 LF_VERIFY_MSG(
false,
"Unknown cell type" << ref_el.ToString());
1166 std::vector<std::unique_ptr<geometry::Geometry>> cell_edge_geo_ptrs(
1167 cell->Geometry()->ChildGeometry(rp, 1));
1168 const size_type num_new_edges = child_edge_nodes.size();
1169 LF_VERIFY_MSG(num_new_edges == rp.NumChildren(1),
1170 "num_new_edges = " << num_new_edges <<
" <-> "
1171 << rp.NumChildren(1));
1172 for (
int k = 0; k < num_new_edges; k++) {
1173 const std::array<glb_idx_t, 2> &cen(child_edge_nodes[k]);
1174 SPDLOG_LOGGER_TRACE(
1175 Logger(),
"{}({}), ref_pat = {}: new edge {}[{},{}]", ref_el,
1176 cell_index, (
int)cell_refpat, k, cen[0], cen[1]);
1178 const glb_idx_t new_edge_index = mesh_factory_->AddEntity(
1180 std::array<base::glb_idx_t, 2>{{cen[0], cen[1]}},
1181 std::move(cell_edge_geo_ptrs[k]));
1182 cell_ci.child_edge_idx.push_back(new_edge_index);
1187 std::vector<std::unique_ptr<geometry::Geometry>> childcell_geo_ptrs(
1188 cell->Geometry()->ChildGeometry(rp, 0));
1189 const size_type num_new_cells = child_cell_nodes.size();
1190 LF_VERIFY_MSG(num_new_cells == rp.NumChildren(0),
1191 "num_new_cells = " << num_new_cells <<
" <-> "
1192 << rp.NumChildren(0));
1193 for (
int k = 0; k < num_new_cells; k++) {
1194 const std::vector<glb_idx_t> &ccn(child_cell_nodes[k]);
1195 glb_idx_t new_cell_index;
1196 if (ccn.size() == 3) {
1198 SPDLOG_LOGGER_TRACE(
1199 Logger(),
"{}({}), ref_pat = {}: new triangle {}[{},{},{}]",
1200 ref_el, cell_index, (
int)cell_refpat, k, ccn[0], ccn[1],
1203 new_cell_index = mesh_factory_->AddEntity(
1205 std::array<base::glb_idx_t, 3>{ccn[0], ccn[1], ccn[2]},
1206 std::move(childcell_geo_ptrs[k]));
1207 }
else if (ccn.size() == 4) {
1209 SPDLOG_LOGGER_TRACE(
1210 Logger(),
"{}({}), ref_pat = {}: new quad {}[{},{},{},{}]",
1211 ref_el, cell_index, (
int)cell_refpat, k, ccn[0], ccn[1], ccn[2],
1216 std::array<base::glb_idx_t, 4>{
1217 {ccn[0], ccn[1], ccn[2], ccn[3]}},
1218 std::move(childcell_geo_ptrs[k]));
1220 LF_VERIFY_MSG(
false,
1221 "Child cells must be either triangles or quads");
1223 cell_ci.child_cell_idx.push_back(new_cell_index);
1230 meshes_.push_back(mesh_factory_->Build());
1231 const mesh::Mesh &child_mesh(*meshes_.back());
1233 SPDLOG_LOGGER_DEBUG(Logger(),
"Child mesh {} nodes, {} edges, {} cells.",
1234 child_mesh.NumEntities(2), child_mesh.NumEntities(1),
1235 child_mesh.NumEntities(0));
1241 parent_infos_.push_back(
1242 {std::move(std::vector<ParentInfo>(child_mesh.NumEntities(0))),
1243 std::move(std::vector<ParentInfo>(child_mesh.NumEntities(1))),
1244 std::move(std::vector<ParentInfo>(child_mesh.NumEntities(2)))});
1248 std::vector<CellChildInfo> fine_cell_child_info(child_mesh.NumEntities(0));
1249 std::vector<EdgeChildInfo> fine_edge_child_info(child_mesh.NumEntities(1));
1250 std::vector<PointChildInfo> fine_point_child_info(
1251 child_mesh.NumEntities(2));
1252 cell_child_infos_.push_back(std::move(fine_cell_child_info));
1253 edge_child_infos_.push_back(std::move(fine_edge_child_info));
1254 point_child_infos_.push_back(std::move(fine_point_child_info));
1257 refinement_edges_.push_back(
1258 std::move(std::vector<sub_idx_t>(child_mesh.NumEntities(0), idx_nil)));
1261 edge_marked_.emplace_back(child_mesh.NumEntities(1),
false);
1267 const size_type n_levels = meshes_.size();
1268 LF_VERIFY_MSG(n_levels > 1,
"A least two levels after refinement");
1270 std::vector<ParentInfo> &fine_node_parent_info(parent_infos_.back()[2]);
1271 std::vector<ParentInfo> &fine_edge_parent_info(parent_infos_.back()[1]);
1272 std::vector<ParentInfo> &fine_cell_parent_info(parent_infos_.back()[0]);
1274 LF_VERIFY_MSG(fine_node_parent_info.size() == child_mesh.NumEntities(2),
1275 "fine_node_parent_info size mismatch");
1276 LF_VERIFY_MSG(fine_edge_parent_info.size() == child_mesh.NumEntities(1),
1277 "fine_edge_parent_info size mismatch");
1278 LF_VERIFY_MSG(fine_cell_parent_info.size() == child_mesh.NumEntities(0),
1279 "fine_edge_parent_info size mismatch");
1282 std::vector<PointChildInfo> &pt_child_info(
1283 point_child_infos_.at(n_levels - 2));
1284 for (
const mesh::Entity *node : parent_mesh.Entities(2)) {
1286 const glb_idx_t node_index = parent_mesh.Index(*node);
1287 const glb_idx_t child_index = pt_child_info[node_index].child_point_idx;
1288 if (child_index != idx_nil) {
1289 LF_VERIFY_MSG(child_index < fine_node_parent_info.size(),
1290 "index " << child_index <<
" illegal for child vertex");
1291 fine_node_parent_info[child_index].child_number = 0;
1292 fine_node_parent_info[child_index].parent_ptr = node;
1293 fine_node_parent_info[child_index].parent_index = node_index;
1299 std::vector<EdgeChildInfo> &ed_child_info(
1300 edge_child_infos_.at(n_levels - 2));
1301 for (
const mesh::Entity *edge : parent_mesh.Entities(1)) {
1303 const glb_idx_t edge_index = parent_mesh.Index(*edge);
1304 const EdgeChildInfo &ci_edge(ed_child_info[edge_index]);
1307 const size_type num_child_edges = ci_edge.child_edge_idx.size();
1308 for (
int l = 0; l < num_child_edges; l++) {
1309 const glb_idx_t edge_child_idx = ci_edge.child_edge_idx[l];
1310 LF_VERIFY_MSG(edge_child_idx < fine_edge_parent_info.size(),
1311 "index " << edge_child_idx <<
" illegal for child edge");
1312 fine_edge_parent_info[edge_child_idx].child_number = l;
1313 fine_edge_parent_info[edge_child_idx].parent_ptr = edge;
1314 fine_edge_parent_info[edge_child_idx].parent_index = edge_index;
1318 const size_type num_child_nodes = ci_edge.child_point_idx.size();
1319 for (
int l = 0; l < num_child_nodes; l++) {
1320 const glb_idx_t node_child_idx = ci_edge.child_point_idx[l];
1321 LF_VERIFY_MSG(node_child_idx < fine_node_parent_info.size(),
1322 "index " << node_child_idx <<
" illegal for child point");
1323 fine_node_parent_info[node_child_idx].child_number = l;
1324 fine_node_parent_info[node_child_idx].parent_ptr = edge;
1325 fine_node_parent_info[node_child_idx].parent_index = edge_index;
1330 std::vector<CellChildInfo> &cell_child_info(
1331 cell_child_infos_.at(n_levels - 2));
1332 for (
const mesh::Entity *cell : parent_mesh.Entities(0)) {
1334 const glb_idx_t cell_index(parent_mesh.Index(*cell));
1336 CellChildInfo &cell_ci(cell_child_info[cell_index]);
1339 const size_type num_child_cells = cell_ci.child_cell_idx.size();
1340 for (
int l = 0; l < num_child_cells; l++) {
1341 const glb_idx_t child_cell_idx = cell_ci.child_cell_idx[l];
1342 LF_VERIFY_MSG(child_cell_idx < fine_cell_parent_info.size(),
1343 "index " << child_cell_idx <<
" illegal for child cell");
1344 fine_cell_parent_info[child_cell_idx].child_number = l;
1345 fine_cell_parent_info[child_cell_idx].parent_ptr = cell;
1346 fine_cell_parent_info[child_cell_idx].parent_index = cell_index;
1350 const size_type num_child_edges = cell_ci.child_edge_idx.size();
1351 for (
int l = 0; l < num_child_edges; l++) {
1352 const glb_idx_t edge_child_idx = cell_ci.child_edge_idx[l];
1353 LF_VERIFY_MSG(edge_child_idx < fine_edge_parent_info.size(),
1354 "index " << edge_child_idx <<
" illegal for child edge");
1355 fine_edge_parent_info[edge_child_idx].child_number = l;
1356 fine_edge_parent_info[edge_child_idx].parent_ptr = cell;
1357 fine_edge_parent_info[edge_child_idx].parent_index = cell_index;
1361 const size_type num_child_nodes = cell_ci.child_point_idx.size();
1362 for (
int l = 0; l < num_child_nodes; l++) {
1363 const glb_idx_t node_child_idx = cell_ci.child_point_idx[l];
1364 LF_VERIFY_MSG(node_child_idx < fine_node_parent_info.size(),
1365 "index " << node_child_idx <<
" illegal for child point");
1366 fine_node_parent_info[node_child_idx].child_number = l;
1367 fine_node_parent_info[node_child_idx].parent_ptr = cell;
1368 fine_node_parent_info[node_child_idx].parent_index = cell_index;
1375 const size_type n_levels = meshes_.size();
1376 LF_VERIFY_MSG(n_levels > 1,
"At least two levels after refinement!");
1377 std::vector<sub_idx_t> &child_ref_edges(refinement_edges_.at(n_levels - 1));
1378 std::vector<ParentInfo> &cell_parent_info(
1379 parent_infos_.at(n_levels - 1)[0]);
1380 std::vector<CellChildInfo> &parent_cell_ci(
1381 cell_child_infos_.at(n_levels - 2));
1382 std::vector<sub_idx_t> &parent_ref_edges(
1383 refinement_edges_.at(n_levels - 2));
1386 SPDLOG_LOGGER_DEBUG(Logger(),
"Setting refinement edges");
1388 for (
const mesh::Entity *fine_cell : child_mesh.Entities(0)) {
1389 const glb_idx_t cell_index = child_mesh.Index(*fine_cell);
1390 child_ref_edges[cell_index] =
idx_nil;
1394 const mesh::Entity *parent_ptr =
1395 cell_parent_info[cell_index].parent_ptr;
1396 LF_VERIFY_MSG(parent_ptr !=
nullptr,
1397 "Cell " << cell_index <<
" has no parent, paren_index = "
1398 << cell_parent_info[cell_index].parent_index);
1405 const sub_idx_t fine_cell_child_number =
1406 (parent_infos_.back())[0][cell_index].child_number;
1407 const glb_idx_t parent_index = parent_mesh.Index(*parent_ptr);
1408 LF_VERIFY_MSG(parent_index < parent_mesh.NumEntities(0),
1409 "parent_index = " << parent_index <<
" out of range");
1411 SPDLOG_LOGGER_TRACE(Logger(),
1412 "Cell {}: triangle child {} of parent {}",
1413 cell_index, fine_cell_child_number, parent_index);
1415 const CellChildInfo &parent_ci(parent_cell_ci[parent_index]);
1417 parent_ci.child_cell_idx[fine_cell_child_number] == cell_index,
1418 "Parent child index mismatch!");
1419 const RefPat parent_ref_pat = parent_ci.ref_pat_;
1421 switch (parent_ref_pat) {
1422 case RefPat::rp_nil: {
1423 LF_VERIFY_MSG(
false,
1424 "Parent cannot carry nil refinement pattern");
1427 case RefPat::rp_copy: {
1429 child_ref_edges[cell_index] = parent_ref_edges[parent_index];
1432 case RefPat::rp_bisect: {
1434 LF_VERIFY_MSG(fine_cell_child_number < 2,
1435 "Only 2 children for rp_bisect");
1436 child_ref_edges[cell_index] = 2;
1439 case RefPat::rp_trisect: {
1441 LF_VERIFY_MSG(fine_cell_child_number < 3,
1442 "Only 3 children for rp_trisect");
1443 switch (fine_cell_child_number) {
1445 child_ref_edges[cell_index] = 2;
1449 child_ref_edges[cell_index] = 1;
1453 child_ref_edges[cell_index] = 0;
1457 LF_VERIFY_MSG(
false,
1458 "invalid value for fine_cell_child_number");
1462 case RefPat::rp_trisect_left: {
1464 LF_VERIFY_MSG(fine_cell_child_number < 4,
1465 "Only 3 children for rp_quadsect");
1466 switch (fine_cell_child_number) {
1469 child_ref_edges[cell_index] = 2;
1473 child_ref_edges[cell_index] = 0;
1477 LF_VERIFY_MSG(
false,
1478 "invalid value for fine_cell_child_number");
1482 case RefPat::rp_quadsect: {
1484 switch (fine_cell_child_number) {
1486 child_ref_edges[cell_index] = 2;
1492 child_ref_edges[cell_index] = 0;
1496 LF_VERIFY_MSG(
false,
"Illegal child number");
1504 const sub_idx_t parent_ref_edge_idx =
1505 parent_ref_edges[parent_index];
1506 switch (parent_ref_edge_idx) {
1508 switch (fine_cell_child_number) {
1511 child_ref_edges[cell_index] = 0;
1516 child_ref_edges[cell_index] = 1;
1520 LF_VERIFY_MSG(
false,
"Illegal child number");
1527 switch (fine_cell_child_number) {
1529 child_ref_edges[cell_index] = 1;
1535 child_ref_edges[cell_index] = 2;
1539 LF_VERIFY_MSG(
false,
"Illegal child number");
1546 switch (fine_cell_child_number) {
1548 child_ref_edges[cell_index] = 2;
1552 child_ref_edges[cell_index] = 1;
1557 child_ref_edges[cell_index] = 0;
1561 LF_VERIFY_MSG(
false,
"Illegal child number");
1568 LF_VERIFY_MSG(
false,
"invalid parent_ref_edge_idx")
1575 child_ref_edges[cell_index] = LongestEdge(*fine_cell);
1579 LF_VERIFY_MSG(
false,
"Illegal refinement type for a triangle");
1584 SPDLOG_LOGGER_TRACE(Logger(),
"ref_pat = {}({}) ref edge = {}",
1585 (
int)parent_ref_pat, parent_ref_pat,
1586 child_ref_edges[cell_index]);
1592 child_ref_edges[cell_index] = LongestEdge(*fine_cell);
1594 LF_VERIFY_MSG(
false,
"Unknown parent cell type");