285 template <
typename CellIterator>
288 const CellIterator &cell,
289 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
290 const std::vector<std::vector<unsigned int>> &lexicographic_mapping,
291 std::vector<types::global_dof_index> &dof_indices,
298 static std::vector<std::vector<bool>>
304 template <
typename CellIterator>
312 template <
typename CellIterator>
315 const CellIterator &cell,
316 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
317 const std::vector<std::vector<unsigned int>> &lexicographic_mapping,
318 const std::vector<std::vector<bool>> &component_mask,
320 std::vector<types::global_dof_index> &dof_indices)
const;
334 const unsigned int n_dofs_1d,
335 std::vector<types::global_dof_index> &dofs)
const;
340 unsigned int n_dofs_1d)
const;
346 boost::container::small_vector<std::array<unsigned int, 3>, 6>>
350 {{{{{7, 3}}, {{6, 2}}}},
351 {{{{5, 1}}, {{4, 0}}}},
352 {{{{11, 9}}, {{10, 8}}}}}};
397 if (triangulation.
n_levels() <= 1 ||
401 return !cell.is_artificial();
405 const unsigned int n_raw_lines = triangulation.
n_raw_lines();
414 const unsigned int line_to_children[12][2] = {{0, 2},
428 boost::container::small_vector<std::array<unsigned int, 3>, 6>>
429 line_to_inactive_cells(n_raw_lines);
434 const unsigned int cell_level = cell->
level();
435 const unsigned int cell_index = cell->
index();
436 for (
unsigned int line = 0; line < GeometryInfo<3>::lines_per_cell;
439 const unsigned int line_idx = cell->
line_index(line);
442 {{cell_level, cell_index, line}});
444 line_to_inactive_cells[line_idx].push_back(
445 {{cell_level, cell_index, line}});
452 for (
unsigned int line_idx = 0; line_idx < n_raw_lines; ++line_idx)
455 line_to_inactive_cells[line_idx].size() > 0)
461 line_to_inactive_cells[line_idx][0][0],
462 line_to_inactive_cells[line_idx][0][1]);
463 const unsigned int neighbor_line =
464 line_to_inactive_cells[line_idx][0][2];
466 for (
unsigned int c = 0; c < 2; ++c)
469 inactive_cell->
child(line_to_children[neighbor_line][c]);
470 const unsigned int child_line_idx =
523 const CellIterator &cell)
const
527 (cell->reference_cell().is_hyper_cube() ==
false))
530 if (cell->level() == 0)
533 const std::uint16_t subcell =
534 cell->parent()->child_iterator_to_index(cell);
535 const std::uint16_t
subcell_x = (subcell >> 0) & 1;
536 const std::uint16_t
subcell_y = (subcell >> 1) & 1;
537 const std::uint16_t
subcell_z = (subcell >> 2) & 1;
539 std::uint16_t face = 0;
540 std::uint16_t edge = 0;
542 for (
unsigned int direction = 0; direction < dim; ++direction)
544 const auto side = (subcell >> direction) & 1U;
545 const auto face_no = direction * 2 + side;
548 if (cell->at_boundary(face_no))
551 const auto &neighbor = cell->neighbor(face_no);
555 if (neighbor->has_children() || neighbor->is_artificial() ||
556 neighbor->level() == cell->level())
560 if (neighbor->get_fe().n_dofs_per_cell() == 0)
563 face |= 1 << direction;
567 for (
unsigned int direction = 0; direction < dim; ++direction)
568 if (face == 0 || face == (1 << direction))
570 const unsigned int line_no =
577 const unsigned int line_index = cell->line_index(line_no);
579 const auto edge_neighbor =
582 [&cell](
const auto &edge_neighbor) {
584 &cell->get_triangulation(),
587 &cell->get_dof_handler());
588 return dof_cell.is_artificial() ==
false &&
589 dof_cell.level() < cell->level() &&
590 dof_cell.
get_fe().n_dofs_per_cell() > 0;
596 edge |= 1 << direction;
599 if ((face == 0) && (edge == 0))
602 const std::uint16_t inverted_subcell = (subcell ^ (dim == 2 ? 3 : 7));
605 inverted_subcell + (face << 3) + (edge << 6));
607 return refinement_configuration;
616 const CellIterator &cell,
617 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
618 const std::vector<std::vector<unsigned int>> &lexicographic_mapping,
619 const std::vector<std::vector<bool>> &supported_components,
621 std::vector<types::global_dof_index> &dof_indices)
const
623 if (std::find(supported_components[cell->active_fe_index()].begin(),
624 supported_components[cell->active_fe_index()].end(),
626 supported_components[cell->active_fe_index()].end())
629 const auto &fe = cell->get_fe();
632 std::vector<std::vector<unsigned int>>
633 component_to_system_index_face_array(fe.n_components());
635 for (
unsigned int i = 0; i < fe.n_dofs_per_face(0); ++i)
636 component_to_system_index_face_array
637 [fe.face_system_to_component_index(i, 0).first]
640 std::vector<unsigned int> idx_offset = {0};
642 for (
unsigned int base_element_index = 0;
643 base_element_index < fe.n_base_elements();
644 ++base_element_index)
645 for (
unsigned int c = 0;
646 c < fe.element_multiplicity(base_element_index);
648 idx_offset.push_back(
650 fe.base_element(base_element_index).n_dofs_per_cell());
652 std::vector<types::global_dof_index> neighbor_dofs_all(idx_offset.back());
653 std::vector<types::global_dof_index> neighbor_dofs_all_temp(
655 std::vector<types::global_dof_index> neighbor_dofs_face(
656 fe.n_dofs_per_face(0));
659 const auto get_face_idx = [](
const auto n_dofs_1d,
662 const auto j) ->
unsigned int {
663 const auto direction = face_no / 2;
664 const auto side = face_no % 2;
665 const auto offset = (side == 1) ? (n_dofs_1d - 1) : 0;
668 return (direction == 0) ? (n_dofs_1d * i + offset) :
669 (n_dofs_1d * offset + i);
674 return n_dofs_1d * n_dofs_1d * i + n_dofs_1d * j + offset;
676 return n_dofs_1d * n_dofs_1d * j + n_dofs_1d * offset + i;
678 return n_dofs_1d * n_dofs_1d * offset + n_dofs_1d * i + j;
688 const std::uint16_t kind =
689 static_cast<std::uint16_t
>(refinement_configuration);
690 const std::uint16_t subcell = (kind >> 0) & 7;
691 const std::uint16_t
subcell_x = (subcell >> 0) & 1;
692 const std::uint16_t
subcell_y = (subcell >> 1) & 1;
693 const std::uint16_t
subcell_z = (subcell >> 2) & 1;
694 const std::uint16_t face = (kind >> 3) & 7;
695 const std::uint16_t edge = (kind >> 6) & 7;
697 for (
unsigned int direction = 0; direction < dim; ++direction)
698 if ((face >> direction) & 1U)
700 const auto side = ((subcell >> direction) & 1U) == 0;
701 const auto face_no = direction * 2 + side;
704 cell->neighbor(face_no)
705 ->face(cell->neighbor_face_no(face_no))
706 ->get_dof_indices(neighbor_dofs_face,
707 cell->neighbor(face_no)->active_fe_index());
711 for (
auto &
index : neighbor_dofs_face)
714 for (
unsigned int base_element_index = 0, comp = 0;
715 base_element_index < fe.n_base_elements();
716 ++base_element_index)
717 for (
unsigned int c = 0;
718 c < fe.element_multiplicity(base_element_index);
721 if (supported_components[cell->active_fe_index()][comp] ==
725 const unsigned int n_dofs_1d =
727 .base_element(base_element_index)
730 const unsigned int dofs_per_face =
732 std::vector<types::global_dof_index> neighbor_dofs(
734 const auto lex_face_mapping =
739 for (
unsigned int i = 0; i < dofs_per_face; ++i)
740 neighbor_dofs[i] = neighbor_dofs_face
741 [component_to_system_index_face_array[comp][i]];
748 Assert(cell->combined_face_orientation(face_no) ==
754 orient_face(cell->combined_face_orientation(face_no),
764 for (
unsigned int i = 0, k = 0; i < n_dofs_1d; ++i)
765 for (
unsigned int j = 0; j < (dim == 2 ? 1 : n_dofs_1d);
767 dof_indices[get_face_idx(n_dofs_1d, face_no, i, j) +
769 neighbor_dofs[lex_face_mapping[k]];
774 for (
unsigned int direction = 0; direction < dim; ++direction)
775 if ((edge >> direction) & 1U)
777 const unsigned int line_no =
783 const unsigned int line_index = cell->line(line_no)->index();
785 const auto edge_neighbor =
788 [&cell](
const auto &edge_array) {
790 edge_neighbor(&cell->get_triangulation(),
794 edge_neighbor->
level() < cell->level();
801 &cell->get_triangulation(),
804 &cell->get_dof_handler());
805 const auto local_line_neighbor = (*edge_neighbor)[2];
810 for (
auto &
index : neighbor_dofs_all)
813 for (
unsigned int i = 0; i < neighbor_dofs_all_temp.size(); ++i)
814 neighbor_dofs_all_temp[i] = neighbor_dofs_all
815 [lexicographic_mapping[cell->active_fe_index()][i]];
818 cell->line_orientation(line_no) !=
819 neighbor_cell.line_orientation(local_line_neighbor);
821 for (
unsigned int base_element_index = 0, comp = 0;
822 base_element_index < fe.n_base_elements();
823 ++base_element_index)
824 for (
unsigned int c = 0;
825 c < fe.element_multiplicity(base_element_index);
828 if (supported_components[cell->active_fe_index()][comp] ==
832 const unsigned int n_dofs_1d =
834 .base_element(base_element_index)
838 for (
unsigned int i = 0; i < n_dofs_1d; ++i)
840 idx_offset[comp]] = neighbor_dofs_all_temp
842 flipped ? (n_dofs_1d - 1 - i) : i,
855 const CellIterator &cell,
856 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
857 const std::vector<std::vector<unsigned int>> &lexicographic_mapping,
858 std::vector<types::global_dof_index> &dof_indices,
863 cell->get_dof_handler().get_fe_collection());
865 if (std::none_of(supported_components.begin(),
866 supported_components.end(),
868 return *std::max_element(a.begin(), a.end());
873 const auto refinement_configuration =
882 lexicographic_mapping,
883 supported_components,
884 refinement_configuration,
888 for (
unsigned int c = 0; c < supported_components[0].size(); ++c)
889 if (supported_components[cell->active_fe_index()][c])
890 masks[c] = refinement_configuration;
916 const unsigned int n_dofs_1d,
917 std::vector<types::global_dof_index> &dofs)
const
919 const auto [orientation, rotation, flip] =
921 const int n_rotations =
922 rotation || flip ? 4 -
int(rotation) - 2 *
int(flip) : 0;
924 const unsigned int rot_mapping[4] = {2, 0, 3, 1};
928 const unsigned int dofs_per_line = n_dofs_1d - 2;
931 std::vector<types::global_dof_index> copy(dofs.size());
932 for (
int t = 0; t < n_rotations; ++t)
934 std::swap(copy, dofs);
937 for (
unsigned int i = 0; i < 4; ++i)
938 dofs[rot_mapping[i]] = copy[i];
941 unsigned int offset = 4;
942 for (
unsigned int i = 0; i < dofs_per_line; ++i)
946 copy[offset + 2 * dofs_per_line + (dofs_per_line - 1 - i)];
948 dofs[offset + dofs_per_line + i] =
949 copy[offset + 3 * dofs_per_line + (dofs_per_line - 1 - i)];
951 dofs[offset + 2 * dofs_per_line + i] =
952 copy[offset + dofs_per_line + i];
954 dofs[offset + 3 * dofs_per_line + i] = copy[offset + i];
958 offset += 4 * dofs_per_line;
960 for (
unsigned int i = 0; i < dofs_per_line; ++i)
961 for (
unsigned int j = 0; j < dofs_per_line; ++j)
962 dofs[offset + i * dofs_per_line + j] =
963 copy[offset + j * dofs_per_line + (dofs_per_line - 1 - i)];
977 unsigned int offset = 4;
978 for (
unsigned int i = 0; i < dofs_per_line; ++i)
981 dofs[offset + i] = copy[offset + 2 * dofs_per_line + i];
983 dofs[offset + dofs_per_line + i] =
984 copy[offset + 3 * dofs_per_line + i];
986 dofs[offset + 2 * dofs_per_line + i] = copy[offset + i];
988 dofs[offset + 3 * dofs_per_line + i] =
989 copy[offset + dofs_per_line + i];
993 offset += 4 * dofs_per_line;
994 for (
unsigned int i = 0; i < dofs_per_line; ++i)
995 for (
unsigned int j = 0; j < dofs_per_line; ++j)
996 dofs[offset + i * dofs_per_line + j] =
997 copy[offset + j * dofs_per_line + i];