401 return !cell.is_artificial();
405 const unsigned int n_raw_lines =
triangulation.n_raw_lines();
406 this->line_to_cells.resize(n_raw_lines);
414 const unsigned int line_to_children[12][2] = {{0, 2},
427 std::vector<std::vector<
428 std::pair<typename Triangulation<3>::cell_iterator,
unsigned int>>>
429 line_to_inactive_cells(n_raw_lines);
434 for (
unsigned int line = 0; line < GeometryInfo<3>::lines_per_cell;
437 const unsigned int line_idx = cell->
line(line)->index();
439 line_to_cells[line_idx].emplace_back(cell, line);
441 line_to_inactive_cells[line_idx].emplace_back(cell, line);
448 for (
unsigned int line_idx = 0; line_idx < n_raw_lines; ++line_idx)
450 if ((line_to_cells[line_idx].size() > 0) &&
451 line_to_inactive_cells[line_idx].size() > 0)
455 const auto &inactive_cell =
456 line_to_inactive_cells[line_idx][0].first;
457 const unsigned int neighbor_line =
458 line_to_inactive_cells[line_idx][0].second;
460 for (
unsigned int c = 0; c < 2; ++c)
463 inactive_cell->child(line_to_children[neighbor_line][c]);
464 const unsigned int child_line_idx =
465 child->line(neighbor_line)->index();
468 for (
const auto &cl : line_to_cells[line_idx])
469 line_to_cells[child_line_idx].push_back(cl);
515 const CellIterator &cell)
const
518 if ((dim == 3 && line_to_cells.size() == 0) ||
519 (cell->reference_cell().is_hyper_cube() ==
false))
522 if (cell->level() == 0)
525 const std::uint16_t subcell =
526 cell->parent()->child_iterator_to_index(cell);
527 const std::uint16_t
subcell_x = (subcell >> 0) & 1;
528 const std::uint16_t
subcell_y = (subcell >> 1) & 1;
529 const std::uint16_t
subcell_z = (subcell >> 2) & 1;
531 std::uint16_t face = 0;
532 std::uint16_t edge = 0;
534 for (
unsigned int direction = 0; direction < dim; ++direction)
536 const auto side = (subcell >> direction) & 1U;
537 const auto face_no = direction * 2 + side;
540 if (cell->at_boundary(face_no))
543 const auto &neighbor = cell->neighbor(face_no);
547 if (neighbor->has_children() || neighbor->is_artificial() ||
548 neighbor->level() == cell->level())
552 if (neighbor->get_fe().n_dofs_per_cell() == 0)
555 face |= 1 << direction;
559 for (
unsigned int direction = 0; direction < dim; ++direction)
560 if (face == 0 || face == (1 << direction))
562 const unsigned int line_no =
569 const unsigned int line_index = cell->line(line_no)->index();
571 const auto edge_neighbor =
572 std::find_if(line_to_cells[line_index].begin(),
573 line_to_cells[line_index].end(),
574 [&cell](
const auto &edge_neighbor) {
576 &edge_neighbor.first->get_triangulation(),
577 edge_neighbor.first->level(),
578 edge_neighbor.first->index(),
579 &cell->get_dof_handler());
580 return edge_neighbor.first->is_artificial() ==
582 edge_neighbor.first->level() <
584 dof_cell.
get_fe().n_dofs_per_cell() > 0;
587 if (edge_neighbor == line_to_cells[line_index].end())
590 edge |= 1 << direction;
593 if ((face == 0) && (edge == 0))
596 const std::uint16_t inverted_subcell = (subcell ^ (dim == 2 ? 3 : 7));
599 inverted_subcell + (face << 3) + (edge << 6));
601 return refinement_configuration;
610 const CellIterator & cell,
611 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
612 const std::vector<std::vector<unsigned int>> &lexicographic_mapping,
613 const std::vector<std::vector<bool>> & supported_components,
615 std::vector<types::global_dof_index> & dof_indices)
const
617 if (std::find(supported_components[cell->active_fe_index()].begin(),
618 supported_components[cell->active_fe_index()].end(),
620 supported_components[cell->active_fe_index()].end())
623 const auto &fe = cell->get_fe();
627 std::vector<std::vector<unsigned int>>
628 component_to_system_index_face_array(fe.n_components());
630 for (
unsigned int i = 0; i < fe.n_dofs_per_face(0); ++i)
631 component_to_system_index_face_array
632 [fe.face_system_to_component_index(i, 0).first]
635 std::vector<unsigned int> idx_offset = {0};
637 for (
unsigned int base_element_index = 0;
638 base_element_index < cell->get_fe().n_base_elements();
639 ++base_element_index)
640 for (
unsigned int c = 0;
641 c < cell->get_fe().element_multiplicity(base_element_index);
643 idx_offset.push_back(
645 cell->get_fe().base_element(base_element_index).n_dofs_per_cell());
647 std::vector<types::global_dof_index> neighbor_dofs_all(idx_offset.back());
648 std::vector<types::global_dof_index> neighbor_dofs_all_temp(
650 std::vector<types::global_dof_index> neighbor_dofs_face(
651 fe.n_dofs_per_face(0));
654 const auto get_face_idx = [](
const auto n_dofs_1d,
657 const auto j) ->
unsigned int {
658 const auto direction = face_no / 2;
659 const auto side = face_no % 2;
660 const auto offset = (side == 1) ? (n_dofs_1d - 1) : 0;
663 return (direction == 0) ? (n_dofs_1d * i + offset) :
664 (n_dofs_1d * offset + i);
669 return n_dofs_1d * n_dofs_1d * i + n_dofs_1d * j + offset;
671 return n_dofs_1d * n_dofs_1d * j + n_dofs_1d * offset + i;
673 return n_dofs_1d * n_dofs_1d * offset + n_dofs_1d * i + j;
683 const std::uint16_t kind =
684 static_cast<std::uint16_t
>(refinement_configuration);
685 const std::uint16_t subcell = (kind >> 0) & 7;
686 const std::uint16_t
subcell_x = (subcell >> 0) & 1;
687 const std::uint16_t
subcell_y = (subcell >> 1) & 1;
688 const std::uint16_t
subcell_z = (subcell >> 2) & 1;
689 const std::uint16_t face = (kind >> 3) & 7;
690 const std::uint16_t edge = (kind >> 6) & 7;
692 for (
unsigned int direction = 0; direction < dim; ++direction)
693 if ((face >> direction) & 1U)
695 const auto side = ((subcell >> direction) & 1U) == 0;
696 const auto face_no = direction * 2 + side;
699 cell->neighbor(face_no)
700 ->face(cell->neighbor_face_no(face_no))
701 ->get_dof_indices(neighbor_dofs_face,
702 cell->neighbor(face_no)->active_fe_index());
706 for (
auto &
index : neighbor_dofs_face)
709 for (
unsigned int base_element_index = 0, comp = 0;
710 base_element_index < cell->get_fe().n_base_elements();
711 ++base_element_index)
712 for (
unsigned int c = 0;
713 c < cell->get_fe().element_multiplicity(base_element_index);
716 if (supported_components[cell->active_fe_index()][comp] ==
720 const unsigned int n_dofs_1d =
722 .base_element(base_element_index)
725 const unsigned int dofs_per_face =
727 std::vector<types::global_dof_index> neighbor_dofs(
729 const auto lex_face_mapping =
734 for (
unsigned int i = 0; i < dofs_per_face; ++i)
735 neighbor_dofs[i] = neighbor_dofs_face
736 [component_to_system_index_face_array[comp][i]];
743 Assert(cell->face_orientation(face_no),
749 if (cell->face_rotation(face_no))
751 if (cell->face_flip(face_no))
754 rotate_face(rotate, n_dofs_1d, neighbor_dofs);
756 if (cell->face_orientation(face_no) ==
false)
757 transpose_face(n_dofs_1d - 1, neighbor_dofs);
765 for (
unsigned int i = 0, k = 0; i < n_dofs_1d; ++i)
766 for (
unsigned int j = 0; j < (dim == 2 ? 1 : n_dofs_1d);
768 dof_indices[get_face_idx(n_dofs_1d, face_no, i, j) +
770 neighbor_dofs[lex_face_mapping[k]];
775 for (
unsigned int direction = 0; direction < dim; ++direction)
776 if ((edge >> direction) & 1U)
778 const unsigned int line_no =
784 const unsigned int line_index = cell->line(line_no)->index();
786 const auto edge_neighbor =
787 std::find_if(line_to_cells[line_index].begin(),
788 line_to_cells[line_index].end(),
789 [&cell](
const auto &edge_neighbor) {
790 return edge_neighbor.first->is_artificial() ==
792 edge_neighbor.first->level() <
796 if (edge_neighbor == line_to_cells[line_index].end())
799 const auto neighbor_cell = edge_neighbor->first;
800 const auto local_line_neighbor = edge_neighbor->second;
803 &neighbor_cell->get_triangulation(),
804 neighbor_cell->level(),
805 neighbor_cell->index(),
806 &cell->get_dof_handler())
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 < cell->get_fe().n_base_elements();
823 ++base_element_index)
824 for (
unsigned int c = 0;
826 cell->get_fe().element_multiplicity(base_element_index);
829 if (supported_components[cell->active_fe_index()][comp] ==
833 const unsigned int n_dofs_1d =
835 .base_element(base_element_index)
839 for (
unsigned int i = 0; i < n_dofs_1d; ++i)
840 dof_indices[line_dof_idx(line_no, i, n_dofs_1d) +
841 idx_offset[comp]] = neighbor_dofs_all_temp
842 [line_dof_idx(local_line_neighbor,
843 flipped ? (n_dofs_1d - 1 - i) : i,
856 const CellIterator & cell,
857 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
858 const std::vector<std::vector<unsigned int>> &lexicographic_mapping,
859 std::vector<types::global_dof_index> & dof_indices,
863 const auto supported_components = compute_supported_components(
864 cell->get_dof_handler().get_fe_collection());
866 if ([](
const auto &supported_components) {
867 return std::none_of(supported_components.begin(),
868 supported_components.end(),
870 return *std::max_element(a.begin(), a.end());
872 }(supported_components))
876 const auto refinement_configuration =
877 compute_refinement_configuration(cell);
883 update_dof_indices(cell,
885 lexicographic_mapping,
886 supported_components,
887 refinement_configuration,
891 for (
unsigned int c = 0; c < supported_components[0].size(); ++c)
892 if (supported_components[cell->active_fe_index()][c])
893 masks[c] = refinement_configuration;