16#ifndef dealii_hanging_nodes_internal_h
17#define dealii_hanging_nodes_internal_h
36 namespace MatrixFreeFunctions
95 const std::uint16_t kind =
static_cast<std::uint16_t
>(
kind_in);
96 const std::uint16_t
subcell = (kind >> 0) & 7;
97 const std::uint16_t face = (kind >> 3) & 7;
98 const std::uint16_t
edge = (kind >> 6) & 7;
117 else if (0 < face &&
edge == 0)
119 else if (0 == face && 0 <
edge)
121 else if ((face ==
edge) && (face == 1 || face == 2 || face == 4))
145 const std::uint16_t kind =
static_cast<std::uint16_t
>(
kind_in);
146 const std::uint16_t
subcell = (kind >> 0) & 7;
147 const std::uint16_t face = (kind >> 3) & 7;
148 const std::uint16_t
edge = (kind >> 6) & 7;
150 return subcell + ((face > 0) << 3) + ((
edge > 0) << 4) +
206 static_cast<std::uint16_t
>(
f2));
230 return static_cast<std::uint16_t
>(
f1) !=
static_cast<std::uint16_t
>(
f2);
242 return static_cast<std::uint16_t
>(
f1) <
static_cast<std::uint16_t
>(
f2);
254 static_cast<std::uint16_t
>(
f2));
283 template <
typename CellIterator>
286 const CellIterator & cell,
287 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
289 std::vector<types::global_dof_index> & dof_indices,
296 static std::vector<std::vector<bool>>
302 template <
typename CellIterator>
310 template <
typename CellIterator>
313 const CellIterator & cell,
314 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
316 const std::vector<std::vector<bool>> & component_mask,
318 std::vector<types::global_dof_index> & dof_indices)
const;
333 std::vector<types::global_dof_index> &dofs)
const;
342 std::vector<types::global_dof_index> &dofs)
const;
347 std::vector<std::vector<
348 std::pair<typename Triangulation<dim>::cell_iterator,
unsigned int>>>
352 {{{{{7, 3}}, {{6, 2}}}},
353 {{{{5, 1}}, {{4, 0}}}},
354 {{{{11, 9}}, {{10, 8}}}}}};
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);
427 std::vector<std::vector<
428 std::pair<typename Triangulation<3>::cell_iterator,
unsigned int>>>
437 const unsigned int line_idx = cell->line(line)->index();
438 if (cell->is_active())
450 if ((line_to_cells[
line_idx].size() > 0) &&
460 for (
unsigned int c = 0; c < 2; ++c)
468 for (
const auto &
cl : line_to_cells[
line_idx])
478 inline std::vector<std::vector<bool>>
480 const ::hp::FECollection<dim> &fe_collection)
483 fe_collection.size(),
484 std::vector<bool>(fe_collection.n_components(),
false));
486 for (
unsigned int i = 0; i < fe_collection.size(); ++i)
491 for (
unsigned int c = 0;
512 template <
typename CellIterator>
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)
526 cell->parent()->child_iterator_to_index(cell);
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))
569 const unsigned int line_index = cell->line(
line_no)->index();
572 std::find_if(line_to_cells[line_index].begin(),
573 line_to_cells[line_index].end(),
579 &cell->get_dof_handler());
584 dof_cell.get_fe().n_dofs_per_cell() > 0;
590 edge |= 1 << direction;
593 if ((face == 0) && (
edge == 0))
607 template <
typename CellIterator>
610 const CellIterator & cell,
611 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
615 std::vector<types::global_dof_index> & dof_indices)
const
623 const auto &fe = cell->get_fe();
627 std::vector<std::vector<unsigned int>>
630 for (
unsigned int i = 0; i < fe.n_dofs_per_face(0); ++i)
632 [fe.face_system_to_component_index(i, 0).first]
640 for (
unsigned int c = 0;
651 fe.n_dofs_per_face(0));
657 const auto j) ->
unsigned int {
658 const auto direction =
face_no / 2;
660 const auto offset = (side == 1) ? (
n_dofs_1d - 1) : 0;
663 return (direction == 0) ? (
n_dofs_1d * i + offset) :
683 const std::uint16_t kind =
685 const std::uint16_t
subcell = (kind >> 0) & 7;
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;
700 ->face(cell->neighbor_face_no(
face_no))
702 cell->neighbor(
face_no)->active_fe_index());
712 for (
unsigned int c = 0;
725 const unsigned int dofs_per_face =
734 for (
unsigned int i = 0; i < dofs_per_face; ++i)
749 if (cell->face_rotation(
face_no))
756 if (cell->face_orientation(
face_no) ==
false)
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);
775 for (
unsigned int direction = 0; direction < dim; ++direction)
776 if ((
edge >> direction) & 1U)
784 const unsigned int line_index = cell->line(
line_no)->index();
787 std::find_if(line_to_cells[line_index].begin(),
788 line_to_cells[line_index].end(),
806 &cell->get_dof_handler())
818 cell->line_orientation(
line_no) !=
824 for (
unsigned int c = 0;
839 for (
unsigned int i = 0; i <
n_dofs_1d; ++i)
853 template <
typename CellIterator>
856 const CellIterator & cell,
857 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
859 std::vector<types::global_dof_index> & dof_indices,
864 cell->get_dof_handler().get_fe_collection());
870 return *std::max_element(a.begin(), a.end());
877 compute_refinement_configuration(cell);
883 update_dof_indices(cell,
903 unsigned int &subface_index)
const
909 for (
int t = 0; t <
times; ++t)
920 std::vector<types::global_dof_index> &dofs)
const
927 std::vector<types::global_dof_index> copy(dofs.size());
928 for (
int t = 0; t <
times; ++t)
930 std::swap(copy, dofs);
933 for (
unsigned int i = 0; i < 4; ++i)
938 unsigned int offset = 4;
939 for (
unsigned int i = 0; i <
n_int; ++i)
942 dofs[offset + i] = copy[offset + 2 *
n_int + (
n_int - 1 - i)];
944 dofs[offset +
n_int + i] =
947 dofs[offset + 2 *
n_int + i] = copy[offset +
n_int + i];
949 dofs[offset + 3 *
n_int + i] = copy[offset + i];
955 for (
unsigned int i = 0; i <
n_int; ++i)
956 for (
unsigned int j = 0;
j <
n_int; ++
j)
957 dofs[offset + i *
n_int +
j] =
970 unsigned int x,
y, z;
972 const unsigned int fe_degree =
n_dofs_1d - 1;
999 const unsigned int fe_degree,
1000 std::vector<types::global_dof_index> &dofs)
const
1002 const std::vector<types::global_dof_index> copy(dofs);
1009 const unsigned int n_int = fe_degree - 1;
1010 unsigned int offset = 4;
1011 for (
unsigned int i = 0; i <
n_int; ++i)
1014 dofs[offset + i] = copy[offset + 2 *
n_int + i];
1016 dofs[offset +
n_int + i] = copy[offset + 3 *
n_int + i];
1018 dofs[offset + 2 *
n_int + i] = copy[offset + i];
1020 dofs[offset + 3 *
n_int + i] = copy[offset +
n_int + i];
1024 offset += 4 *
n_int;
1025 for (
unsigned int i = 0; i <
n_int; ++i)
1026 for (
unsigned int j = 0;
j <
n_int; ++
j)
1027 dofs[offset + i *
n_int +
j] = copy[offset +
j *
n_int + i];
1038 else if (subface == 2)
ConstraintKinds compute_refinement_configuration(const CellIterator &cell) const
void setup_line_to_cell(const Triangulation< dim > &triangulation)
void transpose_face(const unsigned int fe_degree, std::vector< types::global_dof_index > &dofs) const
static std::vector< std::vector< bool > > compute_supported_components(const ::hp::FECollection< dim > &fe)
std::vector< std::vector< std::pair< typename Triangulation< dim >::cell_iterator, unsigned int > > > line_to_cells
HangingNodes(const Triangulation< dim > &triangualtion)
bool setup_constraints(const CellIterator &cell, const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner, const std::vector< std::vector< unsigned int > > &lexicographic_mapping, std::vector< types::global_dof_index > &dof_indices, const ArrayView< ConstraintKinds > &mask) const
void transpose_subface_index(unsigned int &subface) const
void rotate_face(int times, unsigned int n_dofs_1d, std::vector< types::global_dof_index > &dofs) const
std::size_t memory_consumption() const
unsigned int line_dof_idx(int local_line, unsigned int dof, unsigned int n_dofs_1d) const
void update_dof_indices(const CellIterator &cell, const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner, const std::vector< std::vector< unsigned int > > &lexicographic_mapping, const std::vector< std::vector< bool > > &component_mask, const ConstraintKinds &refinement_configuration, std::vector< types::global_dof_index > &dof_indices) const
const ::ndarray< unsigned int, 3, 2, 2 > local_lines
void rotate_subface_index(int times, unsigned int &subface_index) const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
std::enable_if_t< std::is_fundamental< T >::value, std::size_t > memory_consumption(const T &t)
constexpr T pow(const T base, const int iexp)
bool operator<(const ConstraintKinds f1, const ConstraintKinds f2)
ConstraintKinds decompress(const compressed_constraint_kind kind_in, const unsigned int dim)
bool check(const ConstraintKinds kind_in, const unsigned int dim)
compressed_constraint_kind compress(const ConstraintKinds kind_in, const unsigned int dim)
ConstraintKinds & operator|=(ConstraintKinds &f1, const ConstraintKinds f2)
std::size_t memory_consumption(const ConstraintKinds &)
std::uint8_t compressed_constraint_kind
ConstraintKinds operator&(const ConstraintKinds f1, const ConstraintKinds f2)
bool operator!=(const ConstraintKinds f1, const ConstraintKinds f2)
constexpr compressed_constraint_kind unconstrained_compressed_constraint_kind
ConstraintKinds operator|(const ConstraintKinds f1, const ConstraintKinds f2)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
#define DEAL_II_HOST_DEVICE
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation