19#include <deal.II/base/mpi.templates.h>
22#include <deal.II/distributed/cell_data_transfer.templates.h>
40#include <unordered_set>
45template <
int dim,
int spacedim>
52 template <
int dim,
int spacedim>
55 PolicyBase<dim, spacedim> &
policy)
57 std::string policy_name;
58 if (
dynamic_cast<const typename ::internal::DoFHandlerImplementation::
59 Policy::Sequential<dim, spacedim> *
>(&
policy))
60 policy_name =
"Policy::Sequential<";
61 else if (
dynamic_cast<
62 const typename ::internal::DoFHandlerImplementation::
63 Policy::ParallelDistributed<dim, spacedim> *
>(&
policy))
64 policy_name =
"Policy::ParallelDistributed<";
65 else if (
dynamic_cast<
66 const typename ::internal::DoFHandlerImplementation::
67 Policy::ParallelShared<dim, spacedim> *
>(&
policy))
68 policy_name =
"Policy::ParallelShared<";
77 namespace DoFHandlerImplementation
89 template <
int spacedim>
94 3 * dof_handler.fe_collection.max_dofs_per_vertex() +
95 2 * dof_handler.fe_collection.max_dofs_per_line()),
96 dof_handler.n_dofs());
99 template <
int spacedim>
125 switch (dof_handler.tria->max_adjacent_cells())
129 19 * dof_handler.fe_collection.max_dofs_per_vertex() +
130 28 * dof_handler.fe_collection.max_dofs_per_line() +
131 8 * dof_handler.fe_collection.max_dofs_per_quad();
135 21 * dof_handler.fe_collection.max_dofs_per_vertex() +
136 31 * dof_handler.fe_collection.max_dofs_per_line() +
137 9 * dof_handler.fe_collection.max_dofs_per_quad();
141 28 * dof_handler.fe_collection.max_dofs_per_vertex() +
142 42 * dof_handler.fe_collection.max_dofs_per_line() +
143 12 * dof_handler.fe_collection.max_dofs_per_quad();
147 30 * dof_handler.fe_collection.max_dofs_per_vertex() +
148 45 * dof_handler.fe_collection.max_dofs_per_line() +
149 13 * dof_handler.fe_collection.max_dofs_per_quad();
153 37 * dof_handler.fe_collection.max_dofs_per_vertex() +
154 56 * dof_handler.fe_collection.max_dofs_per_line() +
155 16 * dof_handler.fe_collection.max_dofs_per_quad();
164 39 * dof_handler.fe_collection.max_dofs_per_vertex() +
165 59 * dof_handler.fe_collection.max_dofs_per_line() +
166 17 * dof_handler.fe_collection.max_dofs_per_quad();
170 46 * dof_handler.fe_collection.max_dofs_per_vertex() +
171 70 * dof_handler.fe_collection.max_dofs_per_line() +
172 20 * dof_handler.fe_collection.max_dofs_per_quad();
176 48 * dof_handler.fe_collection.max_dofs_per_vertex() +
177 73 * dof_handler.fe_collection.max_dofs_per_line() +
178 21 * dof_handler.fe_collection.max_dofs_per_quad();
182 55 * dof_handler.fe_collection.max_dofs_per_vertex() +
183 84 * dof_handler.fe_collection.max_dofs_per_line() +
184 24 * dof_handler.fe_collection.max_dofs_per_quad();
188 57 * dof_handler.fe_collection.max_dofs_per_vertex() +
189 87 * dof_handler.fe_collection.max_dofs_per_line() +
190 25 * dof_handler.fe_collection.max_dofs_per_quad();
194 63 * dof_handler.fe_collection.max_dofs_per_vertex() +
195 98 * dof_handler.fe_collection.max_dofs_per_line() +
196 28 * dof_handler.fe_collection.max_dofs_per_quad();
200 65 * dof_handler.fe_collection.max_dofs_per_vertex() +
201 103 * dof_handler.fe_collection.max_dofs_per_line() +
202 29 * dof_handler.fe_collection.max_dofs_per_quad();
206 72 * dof_handler.fe_collection.max_dofs_per_vertex() +
207 114 * dof_handler.fe_collection.max_dofs_per_line() +
208 32 * dof_handler.fe_collection.max_dofs_per_quad();
215 return std::min(max_couplings, dof_handler.n_dofs());
218 template <
int spacedim>
231 const unsigned int max_adjacent_cells =
232 dof_handler.tria->max_adjacent_cells();
235 if (max_adjacent_cells <= 8)
237 7 * 7 * 7 * dof_handler.fe_collection.max_dofs_per_vertex() +
238 7 * 6 * 7 * 3 * dof_handler.fe_collection.max_dofs_per_line() +
239 9 * 4 * 7 * 3 * dof_handler.fe_collection.max_dofs_per_quad() +
240 27 * dof_handler.fe_collection.max_dofs_per_hex();
247 return std::min(max_couplings, dof_handler.n_dofs());
254 template <
int dim,
int spacedim>
258 dof_handler.object_dof_indices.clear();
259 dof_handler.object_dof_indices.resize(dof_handler.tria->n_levels());
260 dof_handler.object_dof_indices.shrink_to_fit();
262 dof_handler.object_dof_ptr.clear();
263 dof_handler.object_dof_ptr.resize(dof_handler.tria->n_levels());
264 dof_handler.object_dof_ptr.shrink_to_fit();
270 template <
int dim,
int spacedim>
273 const unsigned int n_inner_dofs_per_cell)
275 for (
unsigned int i = 0; i < dof_handler.tria->n_levels(); ++i)
277 dof_handler.object_dof_ptr[i][dim].assign(
278 dof_handler.tria->n_raw_cells(i) + 1, 0);
280 for (
const auto &cell :
281 dof_handler.tria->cell_iterators_on_level(i))
282 if (cell->is_active() && !cell->is_artificial())
283 dof_handler.object_dof_ptr[i][dim][cell->index() + 1] =
284 n_inner_dofs_per_cell;
286 for (
unsigned int j = 0; j < dof_handler.tria->n_raw_cells(i); ++j)
287 dof_handler.object_dof_ptr[i][dim][j + 1] +=
288 dof_handler.object_dof_ptr[i][dim][j];
290 dof_handler.object_dof_indices[i][dim].resize(
291 dof_handler.object_dof_ptr[i][dim].back(),
300 template <
int dim,
int spacedim,
typename T>
303 const unsigned int structdim,
304 const unsigned int n_raw_entities,
305 const T &cell_process)
307 if (dof_handler.tria->n_cells() == 0)
310 dof_handler.object_dof_ptr[0][structdim].assign(n_raw_entities + 1, -1);
312 for (
const auto &cell : dof_handler.tria->cell_iterators())
313 if (cell->is_active() && !cell->is_artificial())
316 [&](
const unsigned int n_dofs_per_entity,
317 const unsigned int index) {
318 auto &n_dofs_per_entity_target =
319 dof_handler.object_dof_ptr[0][structdim][
index + 1];
323 Assert((n_dofs_per_entity_target ==
327 n_dofs_per_entity_target == n_dofs_per_entity),
330 n_dofs_per_entity_target = n_dofs_per_entity;
334 dof_handler.object_dof_ptr[0][structdim][0] = 0;
335 for (
unsigned int i = 1; i < n_raw_entities + 1; ++i)
337 if (dof_handler.object_dof_ptr[0][structdim][i] ==
340 dof_handler.object_dof_ptr[0][structdim][i] =
341 dof_handler.object_dof_ptr[0][structdim][i - 1];
343 dof_handler.object_dof_ptr[0][structdim][i] +=
344 dof_handler.object_dof_ptr[0][structdim][i - 1];
348 dof_handler.object_dof_indices[0][structdim].resize(
349 dof_handler.object_dof_ptr[0][structdim].back(),
359 template <
int dim,
int spacedim>
365 const auto &fe = dof_handler.get_fe();
369 dim == 1 ? fe.n_dofs_per_line() :
370 (dim == 2 ? fe.n_dofs_per_quad(0) :
371 fe.n_dofs_per_hex()));
376 dof_handler.tria->n_vertices(),
377 [&](
const auto &cell,
const auto &process) {
378 for (const auto vertex_index :
379 cell->vertex_indices())
380 process(fe.n_dofs_per_vertex(),
381 cell->vertex_index(vertex_index));
385 if (dim == 2 || dim == 3)
388 dof_handler.tria->n_raw_lines(),
389 [&](
const auto &cell,
const auto &process) {
390 for (const auto line_index :
391 cell->line_indices())
392 process(fe.n_dofs_per_line(),
393 cell->line(line_index)->index());
400 dof_handler.tria->n_raw_quads(),
401 [&](
const auto &cell,
const auto &process) {
402 for (const auto face_index :
403 cell->face_indices())
404 process(fe.n_dofs_per_quad(face_index),
405 cell->face(face_index)->index());
409 template <
int spacedim>
413 Assert(dof_handler.get_triangulation().n_levels() > 0,
415 dof_handler.clear_mg_space();
417 const ::Triangulation<1, spacedim> &
tria =
418 dof_handler.get_triangulation();
419 const unsigned int dofs_per_line =
420 dof_handler.get_fe().n_dofs_per_line();
421 const unsigned int n_levels =
tria.n_levels();
423 for (
unsigned int i = 0; i < n_levels; ++i)
425 dof_handler.mg_levels.emplace_back(
427 dof_handler.mg_levels.back()->dof_object.dofs =
428 std::vector<types::global_dof_index>(
tria.n_raw_lines(i) *
433 const unsigned int n_vertices =
tria.n_vertices();
435 dof_handler.mg_vertex_dofs.resize(n_vertices);
437 std::vector<unsigned int> max_level(n_vertices, 0);
438 std::vector<unsigned int> min_level(n_vertices, n_levels);
440 for (typename ::Triangulation<1, spacedim>::cell_iterator cell =
445 const unsigned int level = cell->level();
447 for (
const auto vertex : cell->vertex_indices())
449 const unsigned int vertex_index = cell->vertex_index(vertex);
451 if (min_level[vertex_index] > level)
452 min_level[vertex_index] = level;
454 if (max_level[vertex_index] < level)
455 max_level[vertex_index] = level;
459 for (
unsigned int vertex = 0; vertex < n_vertices; ++vertex)
460 if (
tria.vertex_used(vertex))
463 Assert(max_level[vertex] >= min_level[vertex],
465 dof_handler.mg_vertex_dofs[vertex].init(
468 dof_handler.get_fe().n_dofs_per_vertex());
475 dof_handler.mg_vertex_dofs[vertex].init(1, 0, 0);
479 template <
int spacedim>
483 Assert(dof_handler.get_triangulation().n_levels() > 0,
485 dof_handler.clear_mg_space();
487 const ::FiniteElement<2, spacedim> &fe = dof_handler.get_fe();
488 const ::Triangulation<2, spacedim> &
tria =
489 dof_handler.get_triangulation();
490 const unsigned int n_levels =
tria.n_levels();
492 for (
unsigned int i = 0; i < n_levels; ++i)
494 dof_handler.mg_levels.emplace_back(
497 dof_handler.mg_levels.back()->dof_object.dofs =
498 std::vector<types::global_dof_index>(
499 tria.n_raw_quads(i) *
500 fe.n_dofs_per_quad(0 ),
504 dof_handler.mg_faces =
505 std::make_unique<internal::DoFHandlerImplementation::DoFFaces<2>>();
506 dof_handler.mg_faces->lines.dofs =
507 std::vector<types::global_dof_index>(
tria.n_raw_lines() *
508 fe.n_dofs_per_line(),
511 const unsigned int n_vertices =
tria.n_vertices();
513 dof_handler.mg_vertex_dofs.resize(n_vertices);
515 std::vector<unsigned int> max_level(n_vertices, 0);
516 std::vector<unsigned int> min_level(n_vertices, n_levels);
518 for (typename ::Triangulation<2, spacedim>::cell_iterator cell =
523 const unsigned int level = cell->level();
525 for (
const auto vertex : cell->vertex_indices())
527 const unsigned int vertex_index = cell->vertex_index(vertex);
529 if (min_level[vertex_index] > level)
530 min_level[vertex_index] = level;
532 if (max_level[vertex_index] < level)
533 max_level[vertex_index] = level;
537 for (
unsigned int vertex = 0; vertex < n_vertices; ++vertex)
538 if (
tria.vertex_used(vertex))
541 Assert(max_level[vertex] >= min_level[vertex],
543 dof_handler.mg_vertex_dofs[vertex].init(min_level[vertex],
545 fe.n_dofs_per_vertex());
552 dof_handler.mg_vertex_dofs[vertex].init(1, 0, 0);
556 template <
int spacedim>
560 Assert(dof_handler.get_triangulation().n_levels() > 0,
562 dof_handler.clear_mg_space();
564 const ::FiniteElement<3, spacedim> &fe = dof_handler.get_fe();
565 const ::Triangulation<3, spacedim> &
tria =
566 dof_handler.get_triangulation();
567 const unsigned int n_levels =
tria.n_levels();
569 for (
unsigned int i = 0; i < n_levels; ++i)
571 dof_handler.mg_levels.emplace_back(
574 dof_handler.mg_levels.back()->dof_object.dofs =
575 std::vector<types::global_dof_index>(
tria.n_raw_hexs(i) *
580 dof_handler.mg_faces =
581 std::make_unique<internal::DoFHandlerImplementation::DoFFaces<3>>();
582 dof_handler.mg_faces->lines.dofs =
583 std::vector<types::global_dof_index>(
tria.n_raw_lines() *
584 fe.n_dofs_per_line(),
590 dof_handler.mg_faces->quads.dofs = std::vector<types::global_dof_index>(
591 tria.n_raw_quads() * fe.n_dofs_per_quad(0 ),
594 const unsigned int n_vertices =
tria.n_vertices();
596 dof_handler.mg_vertex_dofs.resize(n_vertices);
598 std::vector<unsigned int> max_level(n_vertices, 0);
599 std::vector<unsigned int> min_level(n_vertices, n_levels);
601 for (typename ::Triangulation<3, spacedim>::cell_iterator cell =
606 const unsigned int level = cell->level();
608 for (
const auto vertex : cell->vertex_indices())
610 const unsigned int vertex_index = cell->vertex_index(vertex);
612 if (min_level[vertex_index] > level)
613 min_level[vertex_index] = level;
615 if (max_level[vertex_index] < level)
616 max_level[vertex_index] = level;
620 for (
unsigned int vertex = 0; vertex < n_vertices; ++vertex)
621 if (
tria.vertex_used(vertex))
624 Assert(max_level[vertex] >= min_level[vertex],
626 dof_handler.mg_vertex_dofs[vertex].init(min_level[vertex],
628 fe.n_dofs_per_vertex());
635 dof_handler.mg_vertex_dofs[vertex].init(1, 0, 0);
645 namespace DoFHandlerImplementation
658 template <
int dim,
int spacedim>
664 for (
const auto &cell : dof_handler.active_cell_iterators())
665 if (cell->is_locally_owned())
667 !cell->future_fe_index_set(),
669 "There shouldn't be any cells flagged for p-adaptation when partitioning."));
678 template <
int dim,
int spacedim>
694 std::vector<bool> locally_used_vertices(
695 dof_handler.tria->n_vertices(),
false);
696 for (
const auto &cell : dof_handler.active_cell_iterators())
697 if (!cell->is_artificial())
698 for (
const auto v : cell->vertex_indices())
699 locally_used_vertices[cell->vertex_index(v)] =
true;
701 std::vector<std::vector<bool>> vertex_fe_association(
702 dof_handler.fe_collection.size(),
703 std::vector<bool>(dof_handler.tria->n_vertices(),
false));
705 for (
const auto &cell : dof_handler.active_cell_iterators())
706 if (!cell->is_artificial())
707 for (
const auto v : cell->vertex_indices())
708 vertex_fe_association[cell->active_fe_index()]
709 [cell->vertex_index(v)] =
true;
718 for (
unsigned int v = 0; v < dof_handler.tria->n_vertices(); ++v)
719 if (locally_used_vertices[v] ==
true)
720 if (dof_handler.tria->vertex_used(v) ==
true)
723 for (; fe < dof_handler.fe_collection.size(); ++fe)
724 if (vertex_fe_association[fe][v] ==
true)
726 Assert(fe != dof_handler.fe_collection.size(),
731 const unsigned int d = 0;
732 const unsigned int l = 0;
734 dof_handler.hp_object_fe_ptr[d].clear();
735 dof_handler.hp_object_fe_indices[d].clear();
736 dof_handler.object_dof_ptr[l][d].clear();
737 dof_handler.object_dof_indices[l][d].clear();
739 dof_handler.hp_object_fe_ptr[d].reserve(
740 dof_handler.tria->n_vertices() + 1);
742 unsigned int vertex_slots_needed = 0;
743 unsigned int fe_slots_needed = 0;
745 for (
unsigned int v = 0; v < dof_handler.tria->n_vertices(); ++v)
747 dof_handler.hp_object_fe_ptr[d].push_back(fe_slots_needed);
749 if (dof_handler.tria->vertex_used(v) && locally_used_vertices[v])
751 for (
unsigned int fe = 0;
752 fe < dof_handler.fe_collection.size();
754 if (vertex_fe_association[fe][v] ==
true)
757 vertex_slots_needed +=
758 dof_handler.get_fe(fe).n_dofs_per_vertex();
763 dof_handler.hp_object_fe_ptr[d].push_back(fe_slots_needed);
765 dof_handler.hp_object_fe_indices[d].reserve(fe_slots_needed);
766 dof_handler.object_dof_ptr[l][d].reserve(fe_slots_needed + 1);
768 dof_handler.object_dof_indices[l][d].reserve(vertex_slots_needed);
770 for (
unsigned int v = 0; v < dof_handler.tria->n_vertices(); ++v)
771 if (dof_handler.tria->vertex_used(v) && locally_used_vertices[v])
773 for (
unsigned int fe = 0; fe < dof_handler.fe_collection.size();
775 if (vertex_fe_association[fe][v] ==
true)
777 dof_handler.hp_object_fe_indices[d].push_back(fe);
778 dof_handler.object_dof_ptr[l][d].push_back(
779 dof_handler.object_dof_indices[l][d].size());
781 for (
unsigned int i = 0;
782 i < dof_handler.get_fe(fe).n_dofs_per_vertex();
784 dof_handler.object_dof_indices[l][d].push_back(
790 dof_handler.object_dof_ptr[l][d].push_back(
791 dof_handler.object_dof_indices[l][d].size());
794 dof_handler.object_dof_indices[l][d].size());
796 dof_handler.hp_object_fe_indices[d].size());
798 dof_handler.object_dof_ptr[l][d].size());
800 dof_handler.hp_object_fe_ptr[d].size());
802 dof_handler.object_dof_indices[l][d].assign(
812 template <
int dim,
int spacedim>
825 for (
unsigned int level = 0; level < dof_handler.tria->n_levels();
828 dof_handler.object_dof_ptr[level][dim] =
829 std::vector<typename DoFHandler<dim, spacedim>::offset_type>(
830 dof_handler.tria->n_raw_cells(level),
836 dof_handler.active_cell_iterators_on_level(level))
837 if (cell->is_active() && !cell->is_artificial())
839 dof_handler.object_dof_ptr[level][dim][cell->index()] =
842 cell->get_fe().template n_dofs_per_object<dim>();
845 dof_handler.object_dof_indices[level][dim] =
846 std::vector<types::global_dof_index>(
857 template <
int dim,
int spacedim>
878 std::vector<bool> face_touched(dim == 2 ?
879 dof_handler.tria->n_raw_lines() :
880 dof_handler.tria->n_raw_quads());
882 const unsigned int d = dim - 1;
883 const unsigned int l = 0;
885 dof_handler.hp_object_fe_ptr[d].clear();
886 dof_handler.hp_object_fe_indices[d].clear();
887 dof_handler.object_dof_ptr[l][d].clear();
888 dof_handler.object_dof_indices[l][d].clear();
890 dof_handler.hp_object_fe_ptr[d].resize(
891 dof_handler.tria->n_raw_faces() + 1);
895 unsigned int n_face_slots = 0;
897 for (
const auto &cell : dof_handler.active_cell_iterators())
898 if (!cell->is_artificial())
899 for (
const auto face : cell->face_indices())
900 if (!face_touched[cell->face(face)->index()])
902 unsigned int fe_slots_needed = 0;
904 if (cell->at_boundary(face) ||
905 cell->face(face)->has_children() ||
906 cell->neighbor_is_coarser(face) ||
907 (!cell->at_boundary(face) &&
908 cell->neighbor(face)->is_artificial()) ||
909 (!cell->at_boundary(face) &&
910 !cell->neighbor(face)->is_artificial() &&
911 (cell->active_fe_index() ==
912 cell->neighbor(face)->active_fe_index())))
916 dof_handler.get_fe(cell->active_fe_index())
917 .template n_dofs_per_object<dim - 1>(face);
923 dof_handler.get_fe(cell->active_fe_index())
924 .template n_dofs_per_object<dim - 1>(face) +
926 .
get_fe(cell->neighbor(face)->active_fe_index())
927 .template n_dofs_per_object<dim - 1>(
928 cell->neighbor_face_no(face));
932 face_touched[cell->face(face)->index()] =
true;
935 .hp_object_fe_ptr[d][cell->face(face)->index() + 1] =
939 for (
unsigned int i = 1; i < dof_handler.hp_object_fe_ptr[d].size();
941 dof_handler.hp_object_fe_ptr[d][i] +=
942 dof_handler.hp_object_fe_ptr[d][i - 1];
945 dof_handler.hp_object_fe_indices[d].resize(
946 dof_handler.hp_object_fe_ptr[d].back());
947 dof_handler.object_dof_ptr[l][d].resize(
948 dof_handler.hp_object_fe_ptr[d].back() + 1);
950 dof_handler.object_dof_indices[l][d].reserve(n_face_slots);
956 face_touched = std::vector<bool>(face_touched.size());
958 for (
const auto &cell : dof_handler.active_cell_iterators())
959 if (!cell->is_artificial())
960 for (
const auto face : cell->face_indices())
961 if (!face_touched[cell->face(face)->index()])
964 if (cell->at_boundary(face) ||
965 cell->face(face)->has_children() ||
966 cell->neighbor_is_coarser(face) ||
967 (!cell->at_boundary(face) &&
968 cell->neighbor(face)->is_artificial()) ||
969 (!cell->at_boundary(face) &&
970 !cell->neighbor(face)->is_artificial() &&
971 (cell->active_fe_index() ==
972 cell->neighbor(face)->active_fe_index())))
975 const unsigned int n_dofs =
976 dof_handler.get_fe(fe)
977 .template n_dofs_per_object<dim - 1>(face);
978 const unsigned int offset =
980 .hp_object_fe_ptr[d][cell->face(face)->index()];
982 dof_handler.hp_object_fe_indices[d][offset] = fe;
983 dof_handler.object_dof_ptr[l][d][offset + 1] =
n_dofs;
985 for (
unsigned int i = 0; i <
n_dofs; ++i)
986 dof_handler.object_dof_indices[l][d].push_back(
992 unsigned int face_no_1 = face;
994 cell->neighbor(face)->active_fe_index();
995 unsigned int face_no_2 = cell->neighbor_face_no(face);
999 std::swap(fe_1, fe_2);
1000 std::swap(face_no_1, face_no_2);
1003 const unsigned int n_dofs_1 =
1004 dof_handler.get_fe(fe_1)
1005 .template n_dofs_per_object<dim - 1>(face_no_1);
1007 const unsigned int n_dofs_2 =
1008 dof_handler.get_fe(fe_2)
1009 .template n_dofs_per_object<dim - 1>(face_no_2);
1011 const unsigned int offset =
1013 .hp_object_fe_ptr[d][cell->face(face)->index()];
1015 dof_handler.hp_object_fe_indices[d].push_back(
1016 cell->active_fe_index());
1017 dof_handler.object_dof_ptr[l][d].push_back(
1018 dof_handler.object_dof_indices[l][d].size());
1020 dof_handler.hp_object_fe_indices[d][offset + 0] =
1022 dof_handler.hp_object_fe_indices[d][offset + 1] =
1024 dof_handler.object_dof_ptr[l][d][offset + 1] =
1026 dof_handler.object_dof_ptr[l][d][offset + 2] =
1030 for (
unsigned int i = 0; i < n_dofs_1 + n_dofs_2; ++i)
1031 dof_handler.object_dof_indices[l][d].push_back(
1036 face_touched[cell->face(face)->index()] =
true;
1039 for (
unsigned int i = 1;
1040 i < dof_handler.object_dof_ptr[l][d].size();
1042 dof_handler.object_dof_ptr[l][d][i] +=
1043 dof_handler.object_dof_ptr[l][d][i - 1];
1055 template <
int spacedim>
1059 Assert(dof_handler.fe_collection.size() > 0,
1061 Assert(dof_handler.tria->n_levels() > 0,
1062 ExcMessage(
"The current Triangulation must not be empty."));
1063 Assert(dof_handler.tria->n_levels() ==
1064 dof_handler.hp_cell_future_fe_indices.size(),
1080 template <
int spacedim>
1084 Assert(dof_handler.fe_collection.size() > 0,
1086 Assert(dof_handler.tria->n_levels() > 0,
1087 ExcMessage(
"The current Triangulation must not be empty."));
1088 Assert(dof_handler.tria->n_levels() ==
1089 dof_handler.hp_cell_future_fe_indices.size(),
1107 template <
int spacedim>
1111 Assert(dof_handler.fe_collection.size() > 0,
1113 Assert(dof_handler.tria->n_levels() > 0,
1114 ExcMessage(
"The current Triangulation must not be empty."));
1115 Assert(dof_handler.tria->n_levels() ==
1116 dof_handler.hp_cell_future_fe_indices.size(),
1143 std::vector<std::vector<bool>> line_fe_association(
1144 dof_handler.fe_collection.size(),
1145 std::vector<bool>(dof_handler.tria->n_raw_lines(),
false));
1147 for (
const auto &cell : dof_handler.active_cell_iterators())
1148 if (!cell->is_artificial())
1149 for (
const auto l : cell->line_indices())
1150 line_fe_association[cell->active_fe_index()]
1151 [cell->line_index(l)] =
true;
1157 std::vector<bool> line_is_used(dof_handler.tria->n_raw_lines(),
1159 for (
unsigned int line = 0; line < dof_handler.tria->n_raw_lines();
1161 for (
unsigned int fe = 0; fe < dof_handler.fe_collection.size();
1163 if (line_fe_association[fe][line] ==
true)
1165 line_is_used[line] =
true;
1171 const unsigned int d = 1;
1172 const unsigned int l = 0;
1174 dof_handler.hp_object_fe_ptr[d].clear();
1175 dof_handler.hp_object_fe_indices[d].clear();
1176 dof_handler.object_dof_ptr[l][d].clear();
1177 dof_handler.object_dof_indices[l][d].clear();
1179 dof_handler.hp_object_fe_ptr[d].reserve(
1180 dof_handler.tria->n_raw_lines() + 1);
1182 unsigned int line_slots_needed = 0;
1183 unsigned int fe_slots_needed = 0;
1185 for (
unsigned int line = 0; line < dof_handler.tria->n_raw_lines();
1188 dof_handler.hp_object_fe_ptr[d].push_back(fe_slots_needed);
1190 if (line_is_used[line] ==
true)
1192 for (
unsigned int fe = 0;
1193 fe < dof_handler.fe_collection.size();
1195 if (line_fe_association[fe][line] ==
true)
1198 line_slots_needed +=
1199 dof_handler.get_fe(fe).n_dofs_per_line();
1204 dof_handler.hp_object_fe_ptr[d].push_back(fe_slots_needed);
1208 dof_handler.tria->n_raw_lines() + 1);
1210 dof_handler.hp_object_fe_indices[d].reserve(fe_slots_needed);
1211 dof_handler.object_dof_ptr[l][d].reserve(fe_slots_needed + 1);
1213 dof_handler.object_dof_indices[l][d].reserve(line_slots_needed);
1215 for (
unsigned int line = 0; line < dof_handler.tria->n_raw_lines();
1217 if (line_is_used[line] ==
true)
1219 for (
unsigned int fe = 0;
1220 fe < dof_handler.fe_collection.size();
1222 if (line_fe_association[fe][line] ==
true)
1224 dof_handler.hp_object_fe_indices[d].push_back(fe);
1225 dof_handler.object_dof_ptr[l][d].push_back(
1226 dof_handler.object_dof_indices[l][d].size());
1228 for (
unsigned int i = 0;
1229 i < dof_handler.get_fe(fe).n_dofs_per_line();
1231 dof_handler.object_dof_indices[l][d].push_back(
1236 dof_handler.object_dof_ptr[l][d].push_back(
1237 dof_handler.object_dof_indices[l][d].size());
1243 fe_slots_needed + 1);
1265 template <
int dim,
int spacedim>
1270 dof_handler.hp_capability_enabled ==
true,
1273 if (const ::parallel::shared::Triangulation<dim, spacedim> *tr =
1275 const ::parallel::shared::Triangulation<dim, spacedim>
1276 *
>(&dof_handler.get_triangulation()))
1288 std::vector<types::fe_index> active_fe_indices(
1289 tr->n_active_cells(), 0u);
1290 for (
const auto &cell : dof_handler.active_cell_iterators())
1291 if (cell->is_locally_owned())
1292 active_fe_indices[cell->active_cell_index()] =
1293 cell->active_fe_index();
1296 tr->get_mpi_communicator(),
1305 for (
const auto &cell : dof_handler.active_cell_iterators())
1306 if (!cell->is_locally_owned())
1308 .hp_cell_active_fe_indices[cell->level()][cell->index()] =
1309 active_fe_indices[cell->active_cell_index()];
1311 else if (const ::parallel::
1312 DistributedTriangulationBase<dim, spacedim> *tr =
1315 DistributedTriangulationBase<dim, spacedim> *
>(
1316 &dof_handler.get_triangulation()))
1328 return cell->active_fe_index();
1341 .hp_cell_active_fe_indices[cell->level()][cell->index()] =
1354 const ::parallel::TriangulationBase<dim, spacedim> *
>(
1355 &dof_handler.get_triangulation()) ==
nullptr),
1375 template <
int dim,
int spacedim>
1380 dof_handler.hp_capability_enabled ==
true,
1383 if (const ::parallel::shared::Triangulation<dim, spacedim> *tr =
1385 const ::parallel::shared::Triangulation<dim, spacedim>
1386 *
>(&dof_handler.get_triangulation()))
1388 std::vector<types::fe_index> future_fe_indices(
1389 tr->n_active_cells(), 0u);
1390 for (
const auto &cell : dof_handler.active_cell_iterators() |
1392 future_fe_indices[cell->active_cell_index()] =
1394 .hp_cell_future_fe_indices[cell->level()][cell->index()];
1397 tr->get_mpi_communicator(),
1400 for (
const auto &cell : dof_handler.active_cell_iterators())
1401 if (!cell->is_locally_owned())
1403 .hp_cell_future_fe_indices[cell->level()][cell->index()] =
1404 future_fe_indices[cell->active_cell_index()];
1406 else if (const ::parallel::
1407 DistributedTriangulationBase<dim, spacedim> *tr =
1410 DistributedTriangulationBase<dim, spacedim> *
>(
1411 &dof_handler.get_triangulation()))
1418 .hp_cell_future_fe_indices[cell->level()][cell->index()];
1427 .hp_cell_future_fe_indices[cell->level()][cell->index()] =
1439 const ::parallel::TriangulationBase<dim, spacedim> *
>(
1440 &dof_handler.get_triangulation()) ==
nullptr),
1467 template <
int dim,
int spacedim>
1472 const auto &fe_transfer = dof_handler.active_fe_index_transfer;
1474 for (
const auto &cell : dof_handler.active_cell_iterators())
1475 if (cell->is_locally_owned())
1477 if (cell->refine_flag_set())
1482 fe_transfer->refined_cells_fe_index.insert(
1483 {cell, cell->future_fe_index()});
1485 else if (cell->coarsen_flag_set())
1492 const auto &parent = cell->parent();
1496 if (fe_transfer->coarsened_cells_fe_index.find(parent) ==
1497 fe_transfer->coarsened_cells_fe_index.end())
1506 for (
const auto &child : parent->child_iterators())
1507 Assert(child->is_active() &&
1508 child->coarsen_flag_set(),
1509 typename ::Triangulation<
1510 dim>::ExcInconsistentCoarseningFlags());
1518 fe_transfer->coarsened_cells_fe_index.insert(
1519 {parent, fe_index});
1527 if (cell->future_fe_index_set() ==
true)
1528 fe_transfer->persisting_cells_fe_index.insert(
1529 {cell, cell->future_fe_index()});
1540 template <
int dim,
int spacedim>
1545 const auto &fe_transfer = dof_handler.active_fe_index_transfer;
1548 for (
const auto &persist : fe_transfer->persisting_cells_fe_index)
1550 const auto &cell = persist.first;
1552 if (cell->is_locally_owned())
1555 cell->set_active_fe_index(persist.second);
1561 for (
const auto &refine : fe_transfer->refined_cells_fe_index)
1563 const auto &parent = refine.first;
1565 for (
const auto &child : parent->child_iterators())
1566 if (child->is_locally_owned())
1569 child->set_active_fe_index(refine.second);
1575 for (
const auto &coarsen : fe_transfer->coarsened_cells_fe_index)
1577 const auto &cell = coarsen.first;
1579 if (cell->is_locally_owned())
1582 cell->set_active_fe_index(coarsen.second);
1598 template <
int dim,
int spacedim>
1602 const std::vector<types::fe_index> &children_fe_indices,
1609 const std::set<unsigned int> children_fe_indices_set(
1610 children_fe_indices.begin(), children_fe_indices.end());
1613 fe_collection.find_dominated_fe_extended(children_fe_indices_set,
1619 return dominated_fe_index;
1630 template <
int dim,
int spacedim>
1636 !parent->is_active(),
1638 "You ask for information on children of this cell which is only "
1639 "available for active cells. This cell has no children."));
1641 const auto &dof_handler = parent->get_dof_handler();
1643 dof_handler.has_hp_capabilities(),
1647 std::set<unsigned int> future_fe_indices_children;
1648 for (
const auto &child : parent->child_iterators())
1653 "You ask for information on children of this cell which is only "
1654 "available for active cells. One of its children is not active."));
1666 future_fe_indices_children.insert(future_fe_index_child);
1671 dof_handler.fe_collection.find_dominated_fe_extended(
1672 future_fe_indices_children,
1678 return future_fe_index;
1687 template <
int dim,
int spacedim>
1700 template <
int dim,
int spacedim>
1714template <
int dim,
int spacedim>
1718 ,
tria(nullptr, typeid(*this).name())
1724template <
int dim,
int spacedim>
1726DoFHandler<dim, spacedim>::DoFHandler(
const Triangulation<dim, spacedim> &
tria)
1734template <
int dim,
int spacedim>
1736DoFHandler<dim, spacedim>::~DoFHandler()
1740 connection.disconnect();
1744 connection.disconnect();
1751 DoFHandler<dim, spacedim>::clear();
1761template <
int dim,
int spacedim>
1763void DoFHandler<dim, spacedim>::reinit(
const Triangulation<dim, spacedim> &
tria)
1770 connection.disconnect();
1774 connection.disconnect();
1778 DoFHandler<dim, spacedim>::clear();
1800template <
int dim,
int spacedim>
1802typename DoFHandler<dim, spacedim>::cell_iterator
1803 DoFHandler<dim, spacedim>::begin(
const unsigned int level)
const
1814template <
int dim,
int spacedim>
1816typename DoFHandler<dim, spacedim>::active_cell_iterator
1817 DoFHandler<dim, spacedim>::begin_active(
const unsigned int level)
const
1823 while (i->has_children())
1831template <
int dim,
int spacedim>
1833typename DoFHandler<dim, spacedim>::cell_iterator
1834 DoFHandler<dim, spacedim>::end()
const
1841template <
int dim,
int spacedim>
1843typename DoFHandler<dim, spacedim>::cell_iterator
1844 DoFHandler<dim, spacedim>::end(
const unsigned int level)
const
1855template <
int dim,
int spacedim>
1857typename DoFHandler<dim, spacedim>::active_cell_iterator
1858 DoFHandler<dim, spacedim>::end_active(
const unsigned int level)
const
1869template <
int dim,
int spacedim>
1871typename DoFHandler<dim, spacedim>::level_cell_iterator
1872 DoFHandler<dim, spacedim>::begin_mg(
const unsigned int level)
const
1876 "levels if mg dofs got distributed."));
1886template <
int dim,
int spacedim>
1888typename DoFHandler<dim, spacedim>::level_cell_iterator
1889 DoFHandler<dim, spacedim>::end_mg(
const unsigned int level)
const
1893 "levels if mg dofs got distributed."));
1903template <
int dim,
int spacedim>
1905typename DoFHandler<dim, spacedim>::level_cell_iterator
1906 DoFHandler<dim, spacedim>::end_mg()
const
1913template <
int dim,
int spacedim>
1915IteratorRange<typename DoFHandler<dim, spacedim>::cell_iterator>
DoFHandler<
1919 return IteratorRange<typename DoFHandler<dim, spacedim>::cell_iterator>(
1925template <
int dim,
int spacedim>
1927IteratorRange<typename DoFHandler<dim, spacedim>::
1928 active_cell_iterator> DoFHandler<dim, spacedim>::
1929 active_cell_iterators()
const
1931 return IteratorRange<
1932 typename DoFHandler<dim, spacedim>::active_cell_iterator>(
begin_active(),
1938template <
int dim,
int spacedim>
1941 typename DoFHandler<dim, spacedim>::
1942 level_cell_iterator> DoFHandler<dim, spacedim>::mg_cell_iterators()
const
1944 return IteratorRange<typename DoFHandler<dim, spacedim>::level_cell_iterator>(
1950template <
int dim,
int spacedim>
1952IteratorRange<typename DoFHandler<dim, spacedim>::cell_iterator>
DoFHandler<
1956 return IteratorRange<typename DoFHandler<dim, spacedim>::cell_iterator>(
1962template <
int dim,
int spacedim>
1964IteratorRange<typename DoFHandler<dim, spacedim>::
1965 active_cell_iterator> DoFHandler<dim, spacedim>::
1966 active_cell_iterators_on_level(
const unsigned int level)
const
1968 return IteratorRange<
1969 typename DoFHandler<dim, spacedim>::active_cell_iterator>(
1975template <
int dim,
int spacedim>
1977IteratorRange<typename DoFHandler<dim, spacedim>::
1978 level_cell_iterator> DoFHandler<dim, spacedim>::
1979 mg_cell_iterators_on_level(
const unsigned int level)
const
1981 return IteratorRange<typename DoFHandler<dim, spacedim>::level_cell_iterator>(
1991template <
int dim,
int spacedim>
2000 std::unordered_set<types::global_dof_index> boundary_dofs;
2001 std::vector<types::global_dof_index> dofs_on_face;
2016 const auto face = cell->
face(iface);
2017 if (face->at_boundary())
2019 const unsigned int dofs_per_face =
2020 cell->get_fe().n_dofs_per_face(iface);
2021 dofs_on_face.resize(dofs_per_face);
2023 face->get_dof_indices(dofs_on_face, cell->active_fe_index());
2024 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2026 const unsigned int global_idof_index = dofs_on_face[i];
2027 if (owned_dofs.
is_element(global_idof_index))
2029 boundary_dofs.insert(global_idof_index);
2035 return boundary_dofs.size();
2040template <
int dim,
int spacedim>
2043 const std::set<types::boundary_id> &boundary_ids)
const
2055 std::unordered_set<types::global_dof_index> boundary_dofs;
2056 std::vector<types::global_dof_index> dofs_on_face;
2066 const auto face = cell->
face(iface);
2067 const unsigned int boundary_id = face->boundary_id();
2068 if (face->at_boundary() &&
2069 (boundary_ids.find(boundary_id) != boundary_ids.end()))
2071 const unsigned int dofs_per_face =
2072 cell->get_fe().n_dofs_per_face(iface);
2073 dofs_on_face.resize(dofs_per_face);
2075 face->get_dof_indices(dofs_on_face, cell->active_fe_index());
2076 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2078 const unsigned int global_idof_index = dofs_on_face[i];
2079 if (owned_dofs.
is_element(global_idof_index))
2081 boundary_dofs.insert(global_idof_index);
2087 return boundary_dofs.size();
2092template <
int dim,
int spacedim>
2094std::size_t DoFHandler<dim, spacedim>::memory_consumption()
const
2118 for (
unsigned int level = 0; level < this->
mg_levels.size(); ++level)
2125 mem +=
sizeof(MGVertexDoFs) +
2136template <
int dim,
int spacedim>
2138void DoFHandler<dim, spacedim>::distribute_dofs(
2139 const FiniteElement<dim, spacedim> &fe)
2146template <
int dim,
int spacedim>
2148void DoFHandler<dim, spacedim>::distribute_dofs(
2149 const hp::FECollection<dim, spacedim> &ff)
2153 "You need to set the Triangulation in the DoFHandler using reinit() "
2154 "or in the constructor before you can distribute DoFs."));
2156 ExcMessage(
"The Triangulation you are using is empty!"));
2160 Assert((ff.
size() <= std::numeric_limits<types::fe_index>::max()) &&
2162 ExcMessage(
"The given hp::FECollection contains more finite elements "
2163 "than the DoFHandler can cover with active FE indices."));
2175 IteratorFilters::LocallyOwnedCell())
2203 connection.disconnect();
2218 "You cannot re-enable hp-capabilities after you registered a single "
2219 "finite element. Please call reinit() or create a new DoFHandler "
2220 "object instead."));
2242 const internal::parallel::shared::TemporarilyRestoreSubdomainIds<dim,
2279 dynamic_cast<const parallel::DistributedTriangulationBase<dim, spacedim>
2280 *
>(&*this->
tria) ==
nullptr)
2286template <
int dim,
int spacedim>
2288void DoFHandler<dim, spacedim>::distribute_mg_dofs()
2295 "Distribute active DoFs using distribute_dofs() before calling distribute_mg_dofs()."));
2298 ((this->
tria->get_mesh_smoothing() &
2302 "The mesh smoothing requirement 'limit_level_difference_at_vertices' has to be set for using multigrid!"));
2311 if (
dynamic_cast<const parallel::TriangulationBase<dim, spacedim> *
>(
2312 &*this->
tria) ==
nullptr)
2318template <
int dim,
int spacedim>
2320void DoFHandler<dim, spacedim>::initialize_local_block_info()
2329template <
int dim,
int spacedim>
2331void DoFHandler<dim, spacedim>::setup_policy()
2334 if (
dynamic_cast<const ::parallel::shared::Triangulation<dim, spacedim>
2336 this->
policy = std::make_unique<internal::DoFHandlerImplementation::Policy::
2337 ParallelShared<dim, spacedim>>(*this);
2338 else if (
dynamic_cast<
2339 const ::parallel::DistributedTriangulationBase<dim, spacedim>
2341 this->
policy = std::make_unique<
2342 internal::DoFHandlerImplementation::Policy::Sequential<dim, spacedim>>(
2346 std::make_unique<internal::DoFHandlerImplementation::Policy::
2347 ParallelDistributed<dim, spacedim>>(*this);
2352template <
int dim,
int spacedim>
2354void DoFHandler<dim, spacedim>::clear()
2363template <
int dim,
int spacedim>
2365void DoFHandler<dim, spacedim>::clear_space()
2379template <
int dim,
int spacedim>
2381void DoFHandler<dim, spacedim>::clear_mg_space()
2386 std::vector<MGVertexDoFs> tmp;
2395template <
int dim,
int spacedim>
2397void DoFHandler<dim, spacedim>::renumber_dofs(
2398 const std::vector<types::global_dof_index> &new_numbers)
2404 "You need to distribute DoFs before you can renumber them."));
2416 std::vector<types::global_dof_index> tmp(new_numbers);
2417 std::sort(tmp.begin(), tmp.end());
2418 std::vector<types::global_dof_index>::const_iterator p =
2421 for (; p != tmp.end(); ++p, ++i)
2425 for (
const auto new_number : new_numbers)
2427 new_number < this->
n_dofs(),
2429 "New DoF index is not less than the total number of dofs."));
2463 "You need to distribute DoFs before you can renumber them."));
2467 if (
dynamic_cast<const parallel::shared::Triangulation<dim, spacedim>
2468 *
>(&*this->
tria) !=
nullptr)
2470 Assert(new_numbers.size() == this->n_dofs() ||
2471 new_numbers.size() == this->n_locally_owned_dofs(),
2472 ExcMessage(
"Incorrect size of the input array."));
2474 else if (
dynamic_cast<
2475 const parallel::DistributedTriangulationBase<dim, spacedim>
2476 *
>(&*this->
tria) !=
nullptr)
2491 std::vector<types::global_dof_index> tmp(new_numbers);
2492 std::sort(tmp.begin(), tmp.end());
2493 std::vector<types::global_dof_index>::const_iterator p =
2496 for (; p != tmp.end(); ++p, ++i)
2500 for (
const auto new_number : new_numbers)
2502 new_number < this->
n_dofs(),
2504 "New DoF index is not less than the total number of dofs."));
2513template <
int dim,
int spacedim>
2515void DoFHandler<dim, spacedim>::renumber_dofs(
2516 const unsigned int level,
2517 const std::vector<types::global_dof_index> &new_numbers)
2522 this->
mg_levels.size() > 0 && this->object_dof_indices.size() > 0,
2524 "You need to distribute active and level DoFs before you can renumber level DoFs."));
2527 this->locally_owned_mg_dofs(level).n_elements());
2537 std::vector<types::global_dof_index> tmp(new_numbers);
2538 std::sort(tmp.begin(), tmp.end());
2539 std::vector<types::global_dof_index>::const_iterator p = tmp.begin();
2541 for (; p != tmp.end(); ++p, ++i)
2545 for (
const auto new_number : new_numbers)
2548 "New DoF index is not less than the total number of dofs."));
2552 this->
policy->renumber_mg_dofs(level, new_numbers);
2557template <
int dim,
int spacedim>
2559unsigned int DoFHandler<dim, spacedim>::max_couplings_between_boundary_dofs()
2570 2 * this->fe_collection.max_dofs_per_line());
2582 28 * this->fe_collection.max_dofs_per_line() +
2583 8 * this->fe_collection.max_dofs_per_quad());
2592template <
int dim,
int spacedim>
2594unsigned int DoFHandler<dim, spacedim>::max_couplings_between_dofs()
const
2603template <
int dim,
int spacedim>
2605void DoFHandler<dim, spacedim>::set_active_fe_indices(
2606 const std::vector<types::fe_index> &active_fe_indices)
2608 Assert(active_fe_indices.size() == this->get_triangulation().n_active_cells(),
2610 this->get_triangulation().n_active_cells()));
2624template <
int dim,
int spacedim>
2626void DoFHandler<dim, spacedim>::set_active_fe_indices(
2627 const std::vector<unsigned int> &active_fe_indices)
2630 active_fe_indices.end()));
2635template <
int dim,
int spacedim>
2637std::vector<types::fe_index> DoFHandler<dim, spacedim>::get_active_fe_indices()
2640 std::vector<types::fe_index> active_fe_indices(
2650 return active_fe_indices;
2655template <
int dim,
int spacedim>
2657void DoFHandler<dim, spacedim>::get_active_fe_indices(
2658 std::vector<unsigned int> &active_fe_indices)
const
2662 active_fe_indices.assign(indices.begin(), indices.end());
2667template <
int dim,
int spacedim>
2669void DoFHandler<dim, spacedim>::set_future_fe_indices(
2670 const std::vector<types::fe_index> &future_fe_indices)
2672 Assert(future_fe_indices.size() == this->get_triangulation().n_active_cells(),
2674 this->get_triangulation().n_active_cells()));
2690template <
int dim,
int spacedim>
2692std::vector<types::fe_index> DoFHandler<dim, spacedim>::get_future_fe_indices()
2695 std::vector<types::fe_index> future_fe_indices(
2705 return future_fe_indices;
2710template <
int dim,
int spacedim>
2712void DoFHandler<dim, spacedim>::connect_to_triangulation_signals()
2719 [
this]() { this->reinit(*(this->tria)); }));
2721 this->
tria->signals.clear.connect([
this]() { this->clear(); }));
2726 const ::parallel::fullydistributed::Triangulation<dim, spacedim>
2731 else if (
dynamic_cast<
2732 const ::parallel::distributed::Triangulation<dim, spacedim>
2737 this->
tria->signals.pre_distributed_repartition.connect([
this]() {
2738 internal::hp::DoFHandlerImplementation::Implementation::
2739 ensure_absence_of_future_fe_indices<dim, spacedim>(*this);
2742 this->
tria->signals.pre_distributed_repartition.connect(
2743 [
this]() { this->pre_distributed_transfer_action(); }));
2745 this->
tria->signals.post_distributed_repartition.connect(
2746 [
this]() { this->post_distributed_transfer_action(); }));
2750 this->
tria->signals.post_p4est_refinement.connect(
2751 [
this]() { this->pre_distributed_transfer_action(); }));
2753 this->
tria->signals.post_distributed_refinement.connect(
2754 [
this]() { this->post_distributed_transfer_action(); }));
2758 this->
tria->signals.post_distributed_save.connect(
2759 [
this]() { this->active_fe_index_transfer.reset(); }));
2761 this->
tria->signals.post_distributed_load.connect(
2762 [
this]() { this->update_active_fe_table(); }));
2764 else if (
dynamic_cast<
2765 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
2770 this->
tria->signals.pre_partition.connect([
this]() {
2771 internal::hp::DoFHandlerImplementation::Implementation::
2772 ensure_absence_of_future_fe_indices(*this);
2777 this->
tria->signals.pre_refinement.connect(
2778 [
this]() { this->pre_transfer_action(); }));
2780 this->
tria->signals.post_refinement.connect(
2781 [
this]() { this->post_transfer_action(); }));
2787 this->
tria->signals.pre_refinement.connect(
2788 [
this]() { this->pre_transfer_action(); }));
2790 this->
tria->signals.post_refinement.connect(
2791 [
this]() { this->post_transfer_action(); }));
2797template <
int dim,
int spacedim>
2799void DoFHandler<dim, spacedim>::create_active_fe_table()
2820 this->
tria->n_raw_cells(level), 0);
2830 this->
tria->n_raw_cells(level) &&
2831 this->hp_cell_future_fe_indices[level].size() ==
2832 this->tria->n_raw_cells(level),
2848template <
int dim,
int spacedim>
2850void DoFHandler<dim, spacedim>::update_active_fe_table()
2886template <
int dim,
int spacedim>
2888void DoFHandler<dim, spacedim>::pre_transfer_action()
2903template <
int dim,
int spacedim>
2905void DoFHandler<dim, spacedim>::pre_distributed_transfer_action()
2907# ifndef DEAL_II_WITH_P4EST
2910 "You are attempting to use a functionality that is only available "
2911 "if deal.II was configured to use p4est, but cmake did not find a "
2912 "valid p4est library."));
2916 (
dynamic_cast<const parallel::distributed::Triangulation<dim, spacedim> *
>(
2948 const auto *distributed_tria =
2949 dynamic_cast<const parallel::distributed::Triangulation<dim, spacedim> *
>(
2953 parallel::distributed::
2954 CellDataTransfer<dim, spacedim, std::vector<types::fe_index>>>(
2958 &::AdaptationStrategies::Refinement::
2959 preserve<dim, spacedim, types::fe_index>,
2962 const std::vector<types::fe_index> &children_fe_indices)
2964 return ::internal::hp::DoFHandlerImplementation::Implementation::
2965 determine_fe_from_children<dim, spacedim>(parent,
2966 children_fe_indices,
2971 ->prepare_for_coarsening_and_refinement(
2978template <
int dim,
int spacedim>
2980void DoFHandler<dim, spacedim>::post_transfer_action()
3001template <
int dim,
int spacedim>
3003void DoFHandler<dim, spacedim>::post_distributed_transfer_action()
3005# ifndef DEAL_II_WITH_P4EST
3033template <
int dim,
int spacedim>
3035void DoFHandler<dim, spacedim>::prepare_for_serialization_of_active_fe_indices()
3037# ifndef DEAL_II_WITH_P4EST
3040 "You are attempting to use a functionality that is only available "
3041 "if deal.II was configured to use p4est, but cmake did not find a "
3042 "valid p4est library."));
3046 (
dynamic_cast<const parallel::distributed::Triangulation<dim, spacedim> *
>(
3055 const auto *distributed_tria =
3056 dynamic_cast<const parallel::distributed::Triangulation<dim, spacedim> *
>(
3060 parallel::distributed::
3061 CellDataTransfer<dim, spacedim, std::vector<types::fe_index>>>(
3065 &::AdaptationStrategies::Refinement::
3066 preserve<dim, spacedim, types::fe_index>,
3069 const std::vector<types::fe_index> &children_fe_indices)
3071 return ::internal::hp::DoFHandlerImplementation::Implementation::
3072 determine_fe_from_children<dim, spacedim>(parent,
3073 children_fe_indices,
3091template <
int dim,
int spacedim>
3093void DoFHandler<dim, spacedim>::deserialize_active_fe_indices()
3095# ifndef DEAL_II_WITH_P4EST
3098 "You are attempting to use a functionality that is only available "
3099 "if deal.II was configured to use p4est, but cmake did not find a "
3100 "valid p4est library."));
3104 (
dynamic_cast<const parallel::distributed::Triangulation<dim, spacedim> *
>(
3113 const auto *distributed_tria =
3114 dynamic_cast<const parallel::distributed::Triangulation<dim, spacedim> *
>(
3118 parallel::distributed::
3119 CellDataTransfer<dim, spacedim, std::vector<types::fe_index>>>(
3123 &::AdaptationStrategies::Refinement::
3124 preserve<dim, spacedim, types::fe_index>,
3127 const std::vector<types::fe_index> &children_fe_indices)
3129 return ::internal::hp::DoFHandlerImplementation::Implementation::
3130 determine_fe_from_children<dim, spacedim>(parent,
3131 children_fe_indices,
3155template <
int dim,
int spacedim>
3157DoFHandler<dim, spacedim>::MGVertexDoFs::MGVertexDoFs()
3164template <
int dim,
int spacedim>
3166void DoFHandler<dim, spacedim>::MGVertexDoFs::init(
3167 const unsigned int cl,
3168 const unsigned int fl,
3169 const unsigned int dofs_per_vertex)
3171 coarsest_level = cl;
3174 if (coarsest_level <= finest_level)
3176 const unsigned int n_levels = finest_level - coarsest_level + 1;
3177 const unsigned int n_indices = n_levels * dofs_per_vertex;
3179 indices = std::make_unique<types::global_dof_index[]>(n_indices);
3180 std::fill(indices.get(),
3181 indices.get() + n_indices,
3190template <
int dim,
int spacedim>
3192unsigned int DoFHandler<dim, spacedim>::MGVertexDoFs::get_coarsest_level()
const
3194 return coarsest_level;
3199template <
int dim,
int spacedim>
3201unsigned int DoFHandler<dim, spacedim>::MGVertexDoFs::get_finest_level()
const
3203 return finest_level;
3207#include "dofs/dof_handler.inst"
void initialize_local(const DoFHandler< dim, spacedim > &)
Initialize block structure on cells and compute renumbering between cell dofs and block cell dofs.
void initialize(const DoFHandler< dim, spacedim > &, bool levels_only=false, bool active_only=false)
Fill the object with values describing block structure of the DoFHandler.
bool at_boundary(const unsigned int i) const
TriaIterator< TriaAccessor< dim - 1, dim, spacedim > > face(const unsigned int i) const
bool is_locally_owned() const
unsigned int active_cell_index() const
bool is_artificial() const
bool is_element(const size_type index) const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > face_indices() const
IteratorState::IteratorStates state() const
@ limit_level_difference_at_vertices
cell_iterator begin(const unsigned int level=0) const
cell_iterator end() const
active_cell_iterator end_active(const unsigned int level) const
unsigned int size() const
unsigned int max_dofs_per_vertex() const
constexpr LibraryBuildMode library_build_mode
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_CXX20_REQUIRES(condition)
#define DEAL_II_NAMESPACE_CLOSE
void update_active_fe_table()
active_cell_iterator begin_active(const unsigned int level=0) const
const hp::FECollection< dim, spacedim > & get_fe_collection() const
const IndexSet & locally_owned_dofs() const
std::unique_ptr<::internal::DoFHandlerImplementation::Policy::PolicyBase< dim, spacedim > > policy
std::vector< types::fe_index > get_active_fe_indices() const
cell_iterator begin(const unsigned int level=0) const
cell_iterator end() const
const Triangulation< dim, spacedim > & get_triangulation() const
types::global_dof_index n_dofs() const
std::vector<::internal::DoFHandlerImplementation::NumberCache > mg_number_cache
std::vector< std::array< std::vector< offset_type >, dim+1 > > object_dof_ptr
types::global_dof_index n_locally_owned_dofs() const
std::vector< std::unique_ptr<::internal::DoFHandlerImplementation::DoFLevel< dim > > > mg_levels
std::vector< std::vector< types::fe_index > > hp_cell_active_fe_indices
std::array< std::vector< offset_type >, dim+1 > hp_object_fe_ptr
std::unique_ptr<::internal::DoFHandlerImplementation::DoFFaces< dim > > mg_faces
bool hp_capability_enabled
std::unique_ptr< ActiveFEIndexTransfer > active_fe_index_transfer
BlockInfo block_info_object
void distribute_dofs(const FiniteElement< dim, spacedim > &fe)
hp::FECollection< dim, spacedim > fe_collection
std::vector< boost::signals2::connection > tria_listeners_for_transfer
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
level_cell_iterator end_mg() const
std::vector< boost::signals2::connection > tria_listeners
typename LevelSelector::cell_iterator level_cell_iterator
bool has_level_dofs() const
level_cell_iterator begin_mg(const unsigned int level=0) const
std::vector< std::vector< types::fe_index > > hp_cell_future_fe_indices
std::array< std::vector< types::fe_index >, dim+1 > hp_object_fe_indices
std::vector< std::array< std::vector< types::global_dof_index >, dim+1 > > object_dof_indices
ObserverPointer< const Triangulation< dim, spacedim >, DoFHandler< dim, spacedim > > tria
void create_active_fe_table()
std::vector< MGVertexDoFs > mg_vertex_dofs
void set_active_fe_indices(const std::vector< types::fe_index > &active_fe_indices)
virtual std::size_t memory_consumption() const
void connect_to_triangulation_signals()
::internal::DoFHandlerImplementation::NumberCache number_cache
active_cell_iterator end_active(const unsigned int level) const
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
IteratorRange< cell_iterator > cell_iterators() const
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
IteratorRange< active_cell_iterator > active_cell_iterators() const
static ::ExceptionBase & ExcOnlyAvailableWithHP()
static ::ExceptionBase & ExcNoFESelected()
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcNewNumbersNotConsecutive(types::global_dof_index arg1)
static ::ExceptionBase & ExcNotImplementedWithHP()
static ::ExceptionBase & ExcInvalidFEIndex(int arg1, int arg2)
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcNoDominatedFiniteElementOnChildren()
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcInvalidBoundaryIndicator()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
typename ActiveSelector::active_cell_iterator active_cell_iterator
typename ActiveSelector::cell_iterator cell_iterator
TriaIterator< CellAccessor< dim, spacedim > > cell_iterator
Task< RT > new_task(const std::function< RT()> &function)
@ valid
Iterator points to a valid object.
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
T sum(const T &t, const MPI_Comm mpi_communicator)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
unsigned int n_active_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
unsigned int dominated_future_fe_on_children(const typename DoFHandler< dim, spacedim >::cell_iterator &parent)
void communicate_future_fe_indices(DoFHandler< dim, spacedim > &dof_handler)
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
std::string policy_to_string(const ::internal::DoFHandlerImplementation::Policy::PolicyBase< dim, spacedim > &policy)
constexpr types::global_dof_index invalid_dof_index
constexpr unsigned int invalid_unsigned_int
constexpr types::boundary_id internal_face_boundary_id
constexpr types::fe_index invalid_fe_index
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
unsigned short int fe_index
unsigned int global_dof_index
static types::fe_index future_fe_index(const DoFCellAccessor< dim, spacedim, level_dof_access > &accessor)
static void reserve_space_mg(DoFHandler< 3, spacedim > &dof_handler)
static void reserve_space(DoFHandler< dim, spacedim > &dof_handler)
static void reserve_subentities(DoFHandler< dim, spacedim > &dof_handler, const unsigned int structdim, const unsigned int n_raw_entities, const T &cell_process)
static unsigned int max_couplings_between_dofs(const DoFHandler< 2, spacedim > &dof_handler)
static void reset_to_empty_objects(DoFHandler< dim, spacedim > &dof_handler)
static unsigned int max_couplings_between_dofs(const DoFHandler< 3, spacedim > &dof_handler)
static void reserve_space_mg(DoFHandler< 1, spacedim > &dof_handler)
static unsigned int max_couplings_between_dofs(const DoFHandler< 1, spacedim > &dof_handler)
static void reserve_space_mg(DoFHandler< 2, spacedim > &dof_handler)
static void reserve_cells(DoFHandler< dim, spacedim > &dof_handler, const unsigned int n_inner_dofs_per_cell)
static void collect_fe_indices_on_cells_to_be_refined(DoFHandler< dim, spacedim > &dof_handler)
static void reserve_space(DoFHandler< 2, spacedim > &dof_handler)
static void reserve_space_cells(DoFHandler< dim, spacedim > &dof_handler)
static types::fe_index dominated_future_fe_on_children(const typename DoFHandler< dim, spacedim >::cell_iterator &parent)
static void distribute_fe_indices_on_refined_cells(DoFHandler< dim, spacedim > &dof_handler)
static void reserve_space(DoFHandler< 3, spacedim > &dof_handler)
static void ensure_absence_of_future_fe_indices(DoFHandler< dim, spacedim > &dof_handler)
static void reserve_space_faces(DoFHandler< dim, spacedim > &dof_handler)
static void communicate_future_fe_indices(DoFHandler< dim, spacedim > &dof_handler)
static void communicate_active_fe_indices(DoFHandler< dim, spacedim > &dof_handler)
static types::fe_index determine_fe_from_children(const typename Triangulation< dim, spacedim >::cell_iterator &, const std::vector< types::fe_index > &children_fe_indices, const ::hp::FECollection< dim, spacedim > &fe_collection)
static void reserve_space_vertices(DoFHandler< dim, spacedim > &dof_handler)
static void reserve_space(DoFHandler< 1, spacedim > &dof_handler)