404 return !cell.is_artificial();
408 const unsigned int n_raw_lines =
triangulation.n_raw_lines();
409 this->line_to_cells.resize(n_raw_lines);
417 const unsigned int line_to_children[12][2] = {{0, 2},
431 boost::container::small_vector<std::array<unsigned int, 3>, 6>>
432 line_to_inactive_cells(n_raw_lines);
437 const unsigned int cell_level = cell->
level();
439 for (
unsigned int line = 0; line < GeometryInfo<3>::lines_per_cell;
442 const unsigned int line_idx = cell->
line_index(line);
444 line_to_cells[line_idx].push_back(
447 line_to_inactive_cells[line_idx].push_back(
455 for (
unsigned int line_idx = 0; line_idx < n_raw_lines; ++line_idx)
457 if ((line_to_cells[line_idx].
size() > 0) &&
458 line_to_inactive_cells[line_idx].size() > 0)
464 line_to_inactive_cells[line_idx][0][0],
465 line_to_inactive_cells[line_idx][0][1]);
466 const unsigned int neighbor_line =
467 line_to_inactive_cells[line_idx][0][2];
469 for (
unsigned int c = 0; c < 2; ++c)
472 inactive_cell->child(line_to_children[neighbor_line][c]);
473 const unsigned int child_line_idx =
474 child->line_index(neighbor_line);
479 for (
const auto &cl : line_to_cells[line_idx])
480 line_to_cells[child_line_idx].push_back(cl);
526 const CellIterator &cell)
const
529 if ((dim == 3 && line_to_cells.empty()) ||
530 (cell->reference_cell().is_hyper_cube() ==
false))
533 if (cell->level() == 0)
536 const std::uint16_t subcell =
537 cell->parent()->child_iterator_to_index(cell);
538 const std::uint16_t
subcell_x = (subcell >> 0) & 1;
539 const std::uint16_t
subcell_y = (subcell >> 1) & 1;
540 const std::uint16_t
subcell_z = (subcell >> 2) & 1;
542 std::uint16_t face = 0;
543 std::uint16_t edge = 0;
545 for (
unsigned int direction = 0; direction < dim; ++direction)
547 const auto side = (subcell >> direction) & 1U;
548 const auto face_no = direction * 2 + side;
551 if (cell->at_boundary(face_no))
554 const auto &neighbor = cell->neighbor(face_no);
558 if (neighbor->has_children() || neighbor->is_artificial() ||
559 neighbor->level() == cell->level())
563 if (neighbor->get_fe().n_dofs_per_cell() == 0)
566 face |= 1 << direction;
570 for (
unsigned int direction = 0; direction < dim; ++direction)
571 if (face == 0 || face == (1 << direction))
573 const unsigned int line_no =
580 const unsigned int line_index = cell->line_index(line_no);
582 const auto edge_neighbor =
583 std::find_if(line_to_cells[line_index].begin(),
584 line_to_cells[line_index].end(),
585 [&cell](
const auto &edge_neighbor) {
587 &cell->get_triangulation(),
590 &cell->get_dof_handler());
591 return dof_cell.is_artificial() ==
false &&
592 dof_cell.level() < cell->level() &&
593 dof_cell.
get_fe().n_dofs_per_cell() > 0;
596 if (edge_neighbor == line_to_cells[line_index].end())
599 edge |= 1 << direction;
602 if ((face == 0) && (edge == 0))
605 const std::uint16_t inverted_subcell = (subcell ^ (dim == 2 ? 3 : 7));
608 inverted_subcell + (face << 3) + (edge << 6));
610 return refinement_configuration;
619 const CellIterator &cell,
620 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
621 const std::vector<std::vector<unsigned int>> &lexicographic_mapping,
622 const std::vector<std::vector<bool>> &supported_components,
624 std::vector<types::global_dof_index> &dof_indices)
const
626 if (std::find(supported_components[cell->active_fe_index()].begin(),
627 supported_components[cell->active_fe_index()].end(),
629 supported_components[cell->active_fe_index()].end())
632 const auto &fe = cell->get_fe();
636 std::vector<std::vector<unsigned int>>
637 component_to_system_index_face_array(fe.n_components());
639 for (
unsigned int i = 0; i < fe.n_dofs_per_face(0); ++i)
640 component_to_system_index_face_array
641 [fe.face_system_to_component_index(i, 0).first]
644 std::vector<unsigned int> idx_offset = {0};
646 for (
unsigned int base_element_index = 0;
647 base_element_index < cell->get_fe().n_base_elements();
648 ++base_element_index)
649 for (
unsigned int c = 0;
650 c < cell->get_fe().element_multiplicity(base_element_index);
652 idx_offset.push_back(
654 cell->get_fe().base_element(base_element_index).n_dofs_per_cell());
656 std::vector<types::global_dof_index> neighbor_dofs_all(idx_offset.back());
657 std::vector<types::global_dof_index> neighbor_dofs_all_temp(
659 std::vector<types::global_dof_index> neighbor_dofs_face(
660 fe.n_dofs_per_face(0));
663 const auto get_face_idx = [](
const auto n_dofs_1d,
666 const auto j) ->
unsigned int {
667 const auto direction = face_no / 2;
668 const auto side = face_no % 2;
669 const auto offset = (side == 1) ? (n_dofs_1d - 1) : 0;
672 return (direction == 0) ? (n_dofs_1d * i + offset) :
673 (n_dofs_1d * offset + i);
678 return n_dofs_1d * n_dofs_1d * i + n_dofs_1d * j + offset;
680 return n_dofs_1d * n_dofs_1d * j + n_dofs_1d * offset + i;
682 return n_dofs_1d * n_dofs_1d * offset + n_dofs_1d * i + j;
692 const std::uint16_t kind =
693 static_cast<std::uint16_t
>(refinement_configuration);
694 const std::uint16_t subcell = (kind >> 0) & 7;
695 const std::uint16_t
subcell_x = (subcell >> 0) & 1;
696 const std::uint16_t
subcell_y = (subcell >> 1) & 1;
697 const std::uint16_t
subcell_z = (subcell >> 2) & 1;
698 const std::uint16_t face = (kind >> 3) & 7;
699 const std::uint16_t edge = (kind >> 6) & 7;
701 for (
unsigned int direction = 0; direction < dim; ++direction)
702 if ((face >> direction) & 1U)
704 const auto side = ((subcell >> direction) & 1U) == 0;
705 const auto face_no = direction * 2 + side;
708 cell->neighbor(face_no)
709 ->face(cell->neighbor_face_no(face_no))
710 ->get_dof_indices(neighbor_dofs_face,
711 cell->neighbor(face_no)->active_fe_index());
715 for (
auto &
index : neighbor_dofs_face)
718 for (
unsigned int base_element_index = 0, comp = 0;
719 base_element_index < cell->get_fe().n_base_elements();
720 ++base_element_index)
721 for (
unsigned int c = 0;
722 c < cell->get_fe().element_multiplicity(base_element_index);
725 if (supported_components[cell->active_fe_index()][comp] ==
729 const unsigned int n_dofs_1d =
731 .base_element(base_element_index)
734 const unsigned int dofs_per_face =
736 std::vector<types::global_dof_index> neighbor_dofs(
738 const auto lex_face_mapping =
743 for (
unsigned int i = 0; i < dofs_per_face; ++i)
744 neighbor_dofs[i] = neighbor_dofs_face
745 [component_to_system_index_face_array[comp][i]];
752 Assert(cell->face_orientation(face_no),
758 if (cell->face_rotation(face_no))
760 if (cell->face_flip(face_no))
763 rotate_face(rotate, n_dofs_1d, neighbor_dofs);
765 if (cell->face_orientation(face_no) ==
false)
766 transpose_face(n_dofs_1d - 1, neighbor_dofs);
774 for (
unsigned int i = 0, k = 0; i < n_dofs_1d; ++i)
775 for (
unsigned int j = 0; j < (dim == 2 ? 1 : n_dofs_1d);
777 dof_indices[get_face_idx(n_dofs_1d, face_no, i, j) +
779 neighbor_dofs[lex_face_mapping[k]];
784 for (
unsigned int direction = 0; direction < dim; ++direction)
785 if ((edge >> direction) & 1U)
787 const unsigned int line_no =
793 const unsigned int line_index = cell->line(line_no)->index();
795 const auto edge_neighbor =
796 std::find_if(line_to_cells[line_index].begin(),
797 line_to_cells[line_index].end(),
798 [&cell](
const auto &edge_array) {
800 edge_neighbor(&cell->get_triangulation(),
803 return edge_neighbor->is_artificial() ==
false &&
804 edge_neighbor->level() < cell->level();
807 if (edge_neighbor == line_to_cells[line_index].end())
811 &cell->get_triangulation(),
814 &cell->get_dof_handler());
815 const auto local_line_neighbor = (*edge_neighbor)[2];
820 for (
auto &
index : neighbor_dofs_all)
823 for (
unsigned int i = 0; i < neighbor_dofs_all_temp.size(); ++i)
824 neighbor_dofs_all_temp[i] = neighbor_dofs_all
825 [lexicographic_mapping[cell->active_fe_index()][i]];
828 cell->line_orientation(line_no) !=
829 neighbor_cell.line_orientation(local_line_neighbor);
831 for (
unsigned int base_element_index = 0, comp = 0;
832 base_element_index < cell->get_fe().n_base_elements();
833 ++base_element_index)
834 for (
unsigned int c = 0;
836 cell->get_fe().element_multiplicity(base_element_index);
839 if (supported_components[cell->active_fe_index()][comp] ==
843 const unsigned int n_dofs_1d =
845 .base_element(base_element_index)
849 for (
unsigned int i = 0; i < n_dofs_1d; ++i)
850 dof_indices[line_dof_idx(line_no, i, n_dofs_1d) +
851 idx_offset[comp]] = neighbor_dofs_all_temp
852 [line_dof_idx(local_line_neighbor,
853 flipped ? (n_dofs_1d - 1 - i) : i,
866 const CellIterator &cell,
867 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
868 const std::vector<std::vector<unsigned int>> &lexicographic_mapping,
869 std::vector<types::global_dof_index> &dof_indices,
873 const auto supported_components = compute_supported_components(
874 cell->get_dof_handler().get_fe_collection());
876 if (std::none_of(supported_components.begin(),
877 supported_components.end(),
879 return *std::max_element(a.begin(), a.end());
884 const auto refinement_configuration =
885 compute_refinement_configuration(cell);
891 update_dof_indices(cell,
893 lexicographic_mapping,
894 supported_components,
895 refinement_configuration,
899 for (
unsigned int c = 0; c < supported_components[0].size(); ++c)
900 if (supported_components[cell->active_fe_index()][c])
901 masks[c] = refinement_configuration;