395 if (triangulation.
n_levels() <= 1 ||
399 return !cell.is_artificial();
403 const unsigned int n_raw_lines = triangulation.
n_raw_lines();
404 this->line_to_cells.resize(n_raw_lines);
412 const unsigned int line_to_children[12][2] = {{0, 2},
426 boost::container::small_vector<std::array<unsigned int, 3>, 6>>
427 line_to_inactive_cells(n_raw_lines);
432 const unsigned int cell_level = cell->
level();
434 for (
unsigned int line = 0; line < GeometryInfo<3>::lines_per_cell;
437 const unsigned int line_idx = cell->
line_index(line);
442 line_to_inactive_cells[line_idx].push_back(
450 for (
unsigned int line_idx = 0; line_idx < n_raw_lines; ++line_idx)
452 if ((line_to_cells[line_idx].
size() > 0) &&
453 line_to_inactive_cells[line_idx].size() > 0)
459 line_to_inactive_cells[line_idx][0][0],
460 line_to_inactive_cells[line_idx][0][1]);
461 const unsigned int neighbor_line =
462 line_to_inactive_cells[line_idx][0][2];
464 for (
unsigned int c = 0; c < 2; ++c)
467 inactive_cell->child(line_to_children[neighbor_line][c]);
468 const unsigned int child_line_idx =
469 child->line_index(neighbor_line);
474 for (
const auto &cl : line_to_cells[line_idx])
475 line_to_cells[child_line_idx].
push_back(cl);
521 const CellIterator &cell)
const
524 if ((dim == 3 && line_to_cells.empty()) ||
525 (cell->reference_cell().is_hyper_cube() ==
false))
528 if (cell->level() == 0)
531 const std::uint16_t subcell =
532 cell->parent()->child_iterator_to_index(cell);
533 const std::uint16_t
subcell_x = (subcell >> 0) & 1;
534 const std::uint16_t
subcell_y = (subcell >> 1) & 1;
535 const std::uint16_t
subcell_z = (subcell >> 2) & 1;
537 std::uint16_t face = 0;
538 std::uint16_t edge = 0;
540 for (
unsigned int direction = 0; direction < dim; ++direction)
542 const auto side = (subcell >> direction) & 1U;
543 const auto face_no = direction * 2 + side;
546 if (cell->at_boundary(face_no))
549 const auto &neighbor = cell->neighbor(face_no);
553 if (neighbor->has_children() || neighbor->is_artificial() ||
554 neighbor->level() == cell->level())
558 if (neighbor->get_fe().n_dofs_per_cell() == 0)
561 face |= 1 << direction;
565 for (
unsigned int direction = 0; direction < dim; ++direction)
566 if (face == 0 || face == (1 << direction))
568 const unsigned int line_no =
575 const unsigned int line_index = cell->line_index(line_no);
577 const auto edge_neighbor =
578 std::find_if(line_to_cells[line_index].
begin(),
579 line_to_cells[line_index].
end(),
580 [&cell](
const auto &edge_neighbor) {
582 &cell->get_triangulation(),
585 &cell->get_dof_handler());
586 return dof_cell.is_artificial() ==
false &&
587 dof_cell.level() < cell->level() &&
588 dof_cell.
get_fe().n_dofs_per_cell() > 0;
591 if (edge_neighbor == line_to_cells[line_index].
end())
594 edge |= 1 << direction;
597 if ((face == 0) && (edge == 0))
600 const std::uint16_t inverted_subcell = (subcell ^ (dim == 2 ? 3 : 7));
603 inverted_subcell + (face << 3) + (edge << 6));
605 return refinement_configuration;
614 const CellIterator &cell,
615 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
616 const std::vector<std::vector<unsigned int>> &lexicographic_mapping,
617 const std::vector<std::vector<bool>> &supported_components,
619 std::vector<types::global_dof_index> &dof_indices)
const
621 if (std::find(supported_components[cell->active_fe_index()].begin(),
622 supported_components[cell->active_fe_index()].end(),
624 supported_components[cell->active_fe_index()].end())
627 const auto &fe = cell->get_fe();
630 std::vector<std::vector<unsigned int>>
631 component_to_system_index_face_array(fe.n_components());
633 for (
unsigned int i = 0; i < fe.n_dofs_per_face(0); ++i)
634 component_to_system_index_face_array
635 [fe.face_system_to_component_index(i, 0).first]
638 std::vector<unsigned int> idx_offset = {0};
640 for (
unsigned int base_element_index = 0;
641 base_element_index < fe.n_base_elements();
642 ++base_element_index)
643 for (
unsigned int c = 0;
644 c < fe.element_multiplicity(base_element_index);
646 idx_offset.push_back(
648 fe.base_element(base_element_index).n_dofs_per_cell());
650 std::vector<types::global_dof_index> neighbor_dofs_all(idx_offset.back());
651 std::vector<types::global_dof_index> neighbor_dofs_all_temp(
653 std::vector<types::global_dof_index> neighbor_dofs_face(
654 fe.n_dofs_per_face(0));
657 const auto get_face_idx = [](
const auto n_dofs_1d,
660 const auto j) ->
unsigned int {
661 const auto direction = face_no / 2;
662 const auto side = face_no % 2;
663 const auto offset = (side == 1) ? (n_dofs_1d - 1) : 0;
666 return (direction == 0) ? (n_dofs_1d * i + offset) :
667 (n_dofs_1d * offset + i);
672 return n_dofs_1d * n_dofs_1d * i + n_dofs_1d * j + offset;
674 return n_dofs_1d * n_dofs_1d * j + n_dofs_1d * offset + i;
676 return n_dofs_1d * n_dofs_1d * offset + n_dofs_1d * i + j;
686 const std::uint16_t kind =
687 static_cast<std::uint16_t
>(refinement_configuration);
688 const std::uint16_t subcell = (kind >> 0) & 7;
689 const std::uint16_t
subcell_x = (subcell >> 0) & 1;
690 const std::uint16_t
subcell_y = (subcell >> 1) & 1;
691 const std::uint16_t
subcell_z = (subcell >> 2) & 1;
692 const std::uint16_t face = (kind >> 3) & 7;
693 const std::uint16_t edge = (kind >> 6) & 7;
695 for (
unsigned int direction = 0; direction < dim; ++direction)
696 if ((face >> direction) & 1U)
698 const auto side = ((subcell >> direction) & 1U) == 0;
699 const auto face_no = direction * 2 + side;
702 cell->neighbor(face_no)
703 ->face(cell->neighbor_face_no(face_no))
704 ->get_dof_indices(neighbor_dofs_face,
705 cell->neighbor(face_no)->active_fe_index());
709 for (
auto &
index : neighbor_dofs_face)
712 for (
unsigned int base_element_index = 0, comp = 0;
713 base_element_index < fe.n_base_elements();
714 ++base_element_index)
715 for (
unsigned int c = 0;
716 c < fe.element_multiplicity(base_element_index);
719 if (supported_components[cell->active_fe_index()][comp] ==
723 const unsigned int n_dofs_1d =
725 .base_element(base_element_index)
728 const unsigned int dofs_per_face =
730 std::vector<types::global_dof_index> neighbor_dofs(
732 const auto lex_face_mapping =
737 for (
unsigned int i = 0; i < dofs_per_face; ++i)
738 neighbor_dofs[i] = neighbor_dofs_face
739 [component_to_system_index_face_array[comp][i]];
746 Assert(cell->combined_face_orientation(face_no) ==
752 orient_face(cell->combined_face_orientation(face_no),
762 for (
unsigned int i = 0, k = 0; i < n_dofs_1d; ++i)
763 for (
unsigned int j = 0; j < (dim == 2 ? 1 : n_dofs_1d);
765 dof_indices[get_face_idx(n_dofs_1d, face_no, i, j) +
767 neighbor_dofs[lex_face_mapping[k]];
772 for (
unsigned int direction = 0; direction < dim; ++direction)
773 if ((edge >> direction) & 1U)
775 const unsigned int line_no =
781 const unsigned int line_index = cell->line(line_no)->index();
783 const auto edge_neighbor =
784 std::find_if(line_to_cells[line_index].
begin(),
785 line_to_cells[line_index].
end(),
786 [&cell](
const auto &edge_array) {
788 edge_neighbor(&cell->get_triangulation(),
791 return edge_neighbor->is_artificial() ==
false &&
792 edge_neighbor->level() < cell->level();
795 if (edge_neighbor == line_to_cells[line_index].
end())
799 &cell->get_triangulation(),
802 &cell->get_dof_handler());
803 const auto local_line_neighbor = (*edge_neighbor)[2];
808 for (
auto &
index : neighbor_dofs_all)
811 for (
unsigned int i = 0; i < neighbor_dofs_all_temp.size(); ++i)
812 neighbor_dofs_all_temp[i] = neighbor_dofs_all
813 [lexicographic_mapping[cell->active_fe_index()][i]];
816 cell->line_orientation(line_no) !=
817 neighbor_cell.line_orientation(local_line_neighbor);
819 for (
unsigned int base_element_index = 0, comp = 0;
820 base_element_index < fe.n_base_elements();
821 ++base_element_index)
822 for (
unsigned int c = 0;
823 c < fe.element_multiplicity(base_element_index);
826 if (supported_components[cell->active_fe_index()][comp] ==
830 const unsigned int n_dofs_1d =
832 .base_element(base_element_index)
836 for (
unsigned int i = 0; i < n_dofs_1d; ++i)
837 dof_indices[line_dof_idx(line_no, i, n_dofs_1d) +
838 idx_offset[comp]] = neighbor_dofs_all_temp
839 [line_dof_idx(local_line_neighbor,
840 flipped ? (n_dofs_1d - 1 - i) : i,
853 const CellIterator &cell,
854 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
855 const std::vector<std::vector<unsigned int>> &lexicographic_mapping,
856 std::vector<types::global_dof_index> &dof_indices,
860 const auto supported_components = compute_supported_components(
861 cell->get_dof_handler().get_fe_collection());
863 if (std::none_of(supported_components.begin(),
864 supported_components.end(),
866 return *std::max_element(a.begin(), a.end());
871 const auto refinement_configuration =
872 compute_refinement_configuration(cell);
878 update_dof_indices(cell,
880 lexicographic_mapping,
881 supported_components,
882 refinement_configuration,
886 for (
unsigned int c = 0; c < supported_components[0].size(); ++c)
887 if (supported_components[cell->active_fe_index()][c])
888 masks[c] = refinement_configuration;
914 const unsigned int n_dofs_1d,
915 std::vector<types::global_dof_index> &dofs)
const
917 const auto [orientation, rotation, flip] =
919 const int n_rotations =
920 rotation || flip ? 4 -
int(rotation) - 2 *
int(flip) : 0;
922 const unsigned int rot_mapping[4] = {2, 0, 3, 1};
926 const unsigned int dofs_per_line = n_dofs_1d - 2;
929 std::vector<types::global_dof_index> copy(dofs.size());
930 for (
int t = 0; t < n_rotations; ++t)
932 std::swap(copy, dofs);
935 for (
unsigned int i = 0; i < 4; ++i)
936 dofs[rot_mapping[i]] = copy[i];
939 unsigned int offset = 4;
940 for (
unsigned int i = 0; i < dofs_per_line; ++i)
944 copy[offset + 2 * dofs_per_line + (dofs_per_line - 1 - i)];
946 dofs[offset + dofs_per_line + i] =
947 copy[offset + 3 * dofs_per_line + (dofs_per_line - 1 - i)];
949 dofs[offset + 2 * dofs_per_line + i] =
950 copy[offset + dofs_per_line + i];
952 dofs[offset + 3 * dofs_per_line + i] = copy[offset + i];
956 offset += 4 * dofs_per_line;
958 for (
unsigned int i = 0; i < dofs_per_line; ++i)
959 for (
unsigned int j = 0; j < dofs_per_line; ++j)
960 dofs[offset + i * dofs_per_line + j] =
961 copy[offset + j * dofs_per_line + (dofs_per_line - 1 - i)];
975 unsigned int offset = 4;
976 for (
unsigned int i = 0; i < dofs_per_line; ++i)
979 dofs[offset + i] = copy[offset + 2 * dofs_per_line + i];
981 dofs[offset + dofs_per_line + i] =
982 copy[offset + 3 * dofs_per_line + i];
984 dofs[offset + 2 * dofs_per_line + i] = copy[offset + i];
986 dofs[offset + 3 * dofs_per_line + i] =
987 copy[offset + dofs_per_line + i];
991 offset += 4 * dofs_per_line;
992 for (
unsigned int i = 0; i < dofs_per_line; ++i)
993 for (
unsigned int j = 0; j < dofs_per_line; ++j)
994 dofs[offset + i * dofs_per_line + j] =
995 copy[offset + j * dofs_per_line + i];