21 #include <deal.II/distributed/cell_data_transfer.templates.h>
40 #include <boost/serialization/array.hpp>
45 #include <unordered_set>
52 #if defined(_MSC_VER) && (_MSC_VER >= 1800)
53 template <
int dim,
int spacedim>
57 # define HpDoFHandler DoFHandler
75 namespace DoFHandlerImplementation
79 using ::hp::DoFHandler;
92 template <
int dim,
int spacedim>
99 if (cell->is_locally_owned())
101 !cell->future_fe_index_set(),
103 "There shouldn't be any cells flagged for p-adaptation when partitioning."));
112 template <
int dim,
int spacedim>
119 std::vector<std::vector<DoFLevel::active_fe_index_type>>
120 active_fe_backup(dof_handler.
levels.size()),
121 future_fe_backup(dof_handler.
levels.size());
125 active_fe_backup[
level] =
126 std::move(dof_handler.
levels[
level]->active_fe_indices);
127 future_fe_backup[
level] =
128 std::move(dof_handler.
levels[
level]->future_fe_indices);
135 for (
unsigned int level = 0;
level < dof_handler.
tria->n_levels();
141 std::move(active_fe_backup[
level]);
143 std::move(future_fe_backup[
level]);
148 std_cxx14::make_unique<internal::hp::DoFIndicesOnFaces<dim>>();
158 template <
int dim,
int spacedim>
174 std::vector<bool> locally_used_vertices(
175 dof_handler.
tria->n_vertices(),
false);
177 if (!cell->is_artificial())
179 locally_used_vertices[cell->vertex_index(v)] =
true;
181 std::vector<std::vector<bool>> vertex_fe_association(
183 std::vector<bool>(dof_handler.
tria->n_vertices(),
false));
186 if (!cell->is_artificial())
188 vertex_fe_association[cell->active_fe_index()]
189 [cell->vertex_index(v)] =
true;
197 for (
unsigned int v = 0; v < dof_handler.
tria->n_vertices(); ++v)
198 if (locally_used_vertices[v] ==
true)
199 if (dof_handler.
tria->vertex_used(v) ==
true)
203 if (vertex_fe_association[fe][v] ==
true)
215 dof_handler.vertex_dof_offsets.resize(dof_handler.
tria->n_vertices(),
218 unsigned int vertex_slots_needed = 0;
219 for (
unsigned int v = 0; v < dof_handler.
tria->n_vertices(); ++v)
220 if (dof_handler.
tria->vertex_used(v) ==
true)
221 if (locally_used_vertices[v] ==
true)
223 dof_handler.vertex_dof_offsets[v] = vertex_slots_needed;
225 for (
unsigned int fe = 0;
228 if (vertex_fe_association[fe][v] ==
true)
229 vertex_slots_needed +=
230 dof_handler.
get_fe(fe).dofs_per_vertex + 1;
233 ++vertex_slots_needed;
238 dof_handler.
vertex_dofs.resize(vertex_slots_needed,
240 for (
unsigned int v = 0; v < dof_handler.
tria->n_vertices(); ++v)
241 if (dof_handler.
tria->vertex_used(v) ==
true)
242 if (locally_used_vertices[v] ==
true)
244 unsigned int current_index =
245 dof_handler.vertex_dof_offsets[v];
246 for (
unsigned int fe = 0;
249 if (vertex_fe_association[fe][v] ==
true)
255 dof_handler.
get_fe(fe).dofs_per_vertex + 1;
269 template <
int dim,
int spacedim>
281 for (
unsigned int level = 0;
level < dof_handler.
tria->n_levels();
285 std::vector<DoFLevel::offset_type>(
289 std::vector<DoFLevel::offset_type>(
295 typename HpDoFHandler<dim, spacedim>::active_cell_iterator
298 for (; cell != endc; ++cell)
299 if (cell->is_active() && !cell->is_artificial())
301 dof_handler.
levels[
level]->dof_offsets[cell->index()] =
304 cell->get_fe().template n_dofs_per_object<dim>();
307 ->cell_cache_offsets[cell->index()] = cache_size;
308 cache_size += cell->get_fe().dofs_per_cell;
312 std::vector<types::global_dof_index>(
314 dof_handler.
levels[
level]->cell_dof_indices_cache =
315 std::vector<types::global_dof_index>(
324 for (
unsigned int level = 0;
level < dof_handler.
tria->n_levels();
328 for (
const auto &cell :
330 if (cell->is_active() && !cell->is_artificial())
331 counter += cell->get_fe().template n_dofs_per_object<dim>();
340 unsigned int n_active_non_artificial_cells = 0;
341 for (
const auto &cell :
343 if (cell->is_active() && !cell->is_artificial())
344 ++n_active_non_artificial_cells;
346 Assert(
static_cast<unsigned int>(std::count(
351 n_active_non_artificial_cells,
363 template <
int dim,
int spacedim>
368 std::vector<unsigned int> &face_dof_offsets =
377 std::vector<types::global_dof_index> &face_dof_indices =
405 std::vector<bool> saved_face_user_flags;
412 .save_user_flags_line(saved_face_user_flags);
415 .clear_user_flags_line();
424 .save_user_flags_quad(saved_face_user_flags);
427 .clear_user_flags_quad();
438 unsigned int n_face_slots = 0;
441 if (!cell->is_artificial())
442 for (
const unsigned int face :
444 if (cell->face(face)->user_flag_set() ==
false)
454 if (cell->at_boundary(face) ||
455 cell->face(face)->has_children() ||
456 cell->neighbor_is_coarser(face) ||
457 (!cell->at_boundary(face) &&
458 cell->neighbor(face)->is_artificial()) ||
459 (!cell->at_boundary(face) &&
460 !cell->neighbor(face)->is_artificial() &&
461 (cell->active_fe_index() ==
462 cell->neighbor(face)->active_fe_index())))
467 dof_handler.
get_fe(cell->active_fe_index())
468 .template n_dofs_per_object<dim - 1>() +
477 dof_handler.
get_fe(cell->active_fe_index())
478 .
template n_dofs_per_object<
482 .
get_fe(cell->neighbor(face)->active_fe_index())
483 .
template n_dofs_per_object<
488 cell->face(face)->set_user_flag();
496 std::vector<unsigned int>(dof_handler.
tria->n_raw_faces(),
499 std::vector<types::global_dof_index>(n_face_slots,
511 .clear_user_flags_line();
520 .clear_user_flags_quad();
529 unsigned int next_free_face_slot = 0;
532 if (!cell->is_artificial())
533 for (
const unsigned int face :
535 if (!cell->face(face)->user_flag_set())
538 if (cell->at_boundary(face) ||
539 cell->face(face)->has_children() ||
540 cell->neighbor_is_coarser(face) ||
541 (!cell->at_boundary(face) &&
542 cell->neighbor(face)->is_artificial()) ||
543 (!cell->at_boundary(face) &&
544 !cell->neighbor(face)->is_artificial() &&
545 (cell->active_fe_index() ==
546 cell->neighbor(face)->active_fe_index())))
550 face_dof_offsets[cell->face(face)->index()] =
555 face_dof_indices[next_free_face_slot] =
556 cell->active_fe_index();
565 next_free_face_slot +=
567 + dof_handler.
get_fe(cell->active_fe_index())
568 .template n_dofs_per_object<
576 face_dof_offsets[cell->face(face)->index()] =
599 unsigned int active_fe_indices[2] = {
600 cell->active_fe_index(),
601 cell->neighbor(face)->active_fe_index()};
602 if (active_fe_indices[1] < active_fe_indices[0])
604 active_fe_indices[1]);
608 face_dof_indices[next_free_face_slot] =
609 active_fe_indices[0];
616 [next_free_face_slot + 1 +
617 dof_handler.
get_fe(active_fe_indices[0])
618 .template n_dofs_per_object<dim - 1>()] =
619 active_fe_indices[1];
628 next_free_face_slot +=
630 + dof_handler.
get_fe(active_fe_indices[0])
631 .template n_dofs_per_object<
634 + dof_handler.
get_fe(active_fe_indices[1])
635 .template n_dofs_per_object<
641 cell->face(face)->set_user_flag();
655 .load_user_flags_line(saved_face_user_flags);
664 .load_user_flags_quad(saved_face_user_flags);
683 template <
int spacedim>
689 ExcMessage(
"The current Triangulation must not be empty."));
705 template <
int spacedim>
711 ExcMessage(
"The current Triangulation must not be empty."));
729 template <
int spacedim>
732 const unsigned int dim = 3;
737 ExcMessage(
"The current Triangulation must not be empty."));
764 std::vector<std::vector<bool>> line_fe_association(
766 std::vector<bool>(dof_handler.
tria->n_raw_lines(),
false));
769 if (!cell->is_artificial())
770 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell;
772 line_fe_association[cell->active_fe_index()]
773 [cell->line_index(
l)] =
true;
779 std::vector<bool> line_is_used(dof_handler.
tria->n_raw_lines(),
781 for (
unsigned int line = 0; line < dof_handler.
tria->n_raw_lines();
783 for (
unsigned int fe = 0; fe < dof_handler.
fe_collection.size();
785 if (line_fe_association[fe][line] ==
true)
787 line_is_used[line] =
true;
796 dof_handler.
faces->lines.dof_offsets.resize(
799 unsigned int line_slots_needed = 0;
800 for (
unsigned int line = 0; line < dof_handler.
tria->n_raw_lines();
802 if (line_is_used[line] ==
true)
804 dof_handler.
faces->lines.dof_offsets[line] =
807 for (
unsigned int fe = 0;
810 if (line_fe_association[fe][line] ==
true)
812 dof_handler.
get_fe(fe).dofs_per_line + 1;
818 dof_handler.
faces->lines.dofs.resize(line_slots_needed,
820 for (
unsigned int line = 0; line < dof_handler.
tria->n_raw_lines();
822 if (line_is_used[line] ==
true)
824 unsigned int pointer =
825 dof_handler.
faces->lines.dof_offsets[line];
826 for (
unsigned int fe = 0;
829 if (line_fe_association[fe][line] ==
true)
833 dof_handler.
faces->lines.dofs[pointer] = fe;
834 pointer += dof_handler.
get_fe(fe).dofs_per_line + 1;
837 dof_handler.
faces->lines.dofs[pointer] =
851 template <
int spacedim>
864 template <
int spacedim>
888 switch (dof_handler.
tria->max_adjacent_cells())
929 template <
int spacedim>
942 const unsigned int max_adjacent_cells =
943 dof_handler.
tria->max_adjacent_cells();
946 if (max_adjacent_cells <= 8)
948 7 * 7 * 7 * dof_handler.
fe_collection.max_dofs_per_vertex() +
949 7 * 6 * 7 * 3 * dof_handler.
fe_collection.max_dofs_per_line() +
950 9 * 4 * 7 * 3 * dof_handler.
fe_collection.max_dofs_per_quad() +
974 template <
int dim,
int spacedim>
979 if (const ::parallel::shared::Triangulation<dim, spacedim> *tr =
981 const ::parallel::shared::Triangulation<dim, spacedim>
994 std::vector<unsigned int> active_fe_indices(tr->n_active_cells(),
997 if (cell->is_locally_owned())
998 active_fe_indices[cell->active_cell_index()] =
999 cell->active_fe_index();
1002 tr->get_communicator(),
1012 if (!cell->is_locally_owned())
1013 dof_handler.
levels[cell->level()]->set_active_fe_index(
1015 active_fe_indices[cell->active_cell_index()]);
1017 else if (const ::parallel::
1018 DistributedTriangulationBase<dim, spacedim> *tr =
1021 DistributedTriangulationBase<dim, spacedim> *
>(
1031 [](
const typename ::hp::DoFHandler<dim, spacedim>::
1032 active_cell_iterator &cell) ->
unsigned int {
1033 return cell->active_fe_index();
1038 const typename ::hp::DoFHandler<dim, spacedim>::
1039 active_cell_iterator &cell,
1040 const unsigned int active_fe_index) ->
void {
1045 dof_handler.
levels[cell->level()]->set_active_fe_index(
1046 cell->index(), active_fe_index);
1060 const ::parallel::TriangulationBase<dim, spacedim> *
>(
1088 template <
int dim,
int spacedim>
1096 if (cell->is_locally_owned())
1098 if (cell->refine_flag_set())
1103 fe_transfer->refined_cells_fe_index.insert(
1104 {cell, cell->future_fe_index()});
1106 else if (cell->coarsen_flag_set())
1113 const auto &parent = cell->parent();
1117 if (fe_transfer->coarsened_cells_fe_index.find(parent) ==
1118 fe_transfer->coarsened_cells_fe_index.end())
1124 std::set<unsigned int> fe_indices_children;
1125 for (
unsigned int child_index = 0;
1126 child_index < parent->n_children();
1129 const auto &sibling = parent->child(child_index);
1130 Assert(sibling->is_active() &&
1131 sibling->coarsen_flag_set(),
1133 dim>::ExcInconsistentCoarseningFlags());
1135 fe_indices_children.insert(
1136 sibling->future_fe_index());
1138 Assert(!fe_indices_children.empty(),
1141 const unsigned int fe_index =
1143 fe_indices_children, 0);
1146 typename ::hp::FECollection<dim>::
1147 ExcNoDominatedFiniteElementAmongstChildren());
1149 fe_transfer->coarsened_cells_fe_index.insert(
1150 {parent, fe_index});
1158 if (cell->future_fe_index_set() ==
true)
1159 fe_transfer->persisting_cells_fe_index.insert(
1160 {cell, cell->future_fe_index()});
1171 template <
int dim,
int spacedim>
1179 for (
const auto &persist : fe_transfer->persisting_cells_fe_index)
1181 const auto &cell = persist.first;
1183 if (cell->is_locally_owned())
1186 cell->set_active_fe_index(persist.second);
1192 for (
const auto &
refine : fe_transfer->refined_cells_fe_index)
1194 const auto &parent =
refine.first;
1196 for (
unsigned int child_index = 0;
1197 child_index < parent->n_children();
1200 const auto &child = parent->child(child_index);
1201 Assert(child->is_locally_owned() && child->is_active(),
1203 child->set_active_fe_index(
refine.second);
1209 for (
const auto &
coarsen : fe_transfer->coarsened_cells_fe_index)
1211 const auto &cell =
coarsen.first;
1212 Assert(cell->is_locally_owned() && cell->is_active(),
1214 cell->set_active_fe_index(
coarsen.second);
1229 template <
int dim,
int spacedim>
1233 const std::vector<unsigned int> & children_fe_indices,
1239 const std::set<unsigned int> children_fe_indices_set(
1240 children_fe_indices.begin(), children_fe_indices.end());
1242 const unsigned int dominated_fe_index =
1247 typename ::hp::FECollection<
1248 dim>::ExcNoDominatedFiniteElementAmongstChildren());
1250 return dominated_fe_index;
1261 template <
int dim,
int spacedim>
1264 template <
int dim,
int spacedim>
1269 template <
int dim,
int spacedim>
1271 : tria(nullptr, typeid(*this).name())
1277 template <
int dim,
int spacedim>
1280 : tria(&tria, typeid(*this).name())
1283 setup_policy_and_listeners();
1285 create_active_fe_table();
1290 template <
int dim,
int spacedim>
1295 for (
auto &connection : tria_listeners)
1296 connection.disconnect();
1297 tria_listeners.clear();
1311 template <
int dim,
int spacedim>
1320 template <
int dim,
int spacedim>
1328 while (i->has_children())
1336 template <
int dim,
int spacedim>
1340 return cell_iterator(&this->get_triangulation(), -1, -1,
this);
1345 template <
int dim,
int spacedim>
1349 return (
level == this->get_triangulation().n_levels() - 1 ?
1356 template <
int dim,
int spacedim>
1360 return (
level == this->get_triangulation().n_levels() - 1 ?
1362 begin_active(
level + 1));
1367 template <
int dim,
int spacedim>
1377 template <
int dim,
int spacedim>
1388 template <
int dim,
int spacedim>
1391 const unsigned int level)
const
1399 template <
int dim,
int spacedim>
1402 const unsigned int level)
const
1414 template <
int dim,
int spacedim>
1420 std::unordered_set<types::global_dof_index> boundary_dofs;
1421 std::vector<types::global_dof_index> dofs_on_face;
1424 const IndexSet &owned_dofs = locally_owned_dofs();
1431 typename HpDoFHandler<dim, spacedim>::active_cell_iterator
1432 cell = this->begin_active(),
1434 for (; cell != endc; ++cell)
1435 if (cell->is_locally_owned() && cell->at_boundary())
1438 if (cell->at_boundary(f))
1440 const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
1441 dofs_on_face.resize(dofs_per_face);
1443 cell->face(f)->get_dof_indices(dofs_on_face,
1444 cell->active_fe_index());
1445 for (
unsigned int i = 0; i < dofs_per_face; ++i)
1447 const unsigned int global_idof_index = dofs_on_face[i];
1448 if (owned_dofs.
is_element(global_idof_index))
1450 boundary_dofs.insert(global_idof_index);
1455 return boundary_dofs.size();
1460 template <
int dim,
int spacedim>
1463 const std::set<types::boundary_id> &boundary_ids)
const
1472 std::unordered_set<types::global_dof_index> boundary_dofs;
1473 std::vector<types::global_dof_index> dofs_on_face;
1476 const IndexSet &owned_dofs = locally_owned_dofs();
1478 typename HpDoFHandler<dim, spacedim>::active_cell_iterator
1479 cell = this->begin_active(),
1481 for (; cell != endc; ++cell)
1482 if (cell->is_locally_owned() && cell->at_boundary())
1485 if (cell->at_boundary(f) &&
1486 (boundary_ids.find(cell->face(f)->boundary_id()) !=
1487 boundary_ids.end()))
1489 const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
1490 dofs_on_face.resize(dofs_per_face);
1492 cell->face(f)->get_dof_indices(dofs_on_face,
1493 cell->active_fe_index());
1494 for (
unsigned int i = 0; i < dofs_per_face; ++i)
1496 const unsigned int global_idof_index = dofs_on_face[i];
1497 if (owned_dofs.
is_element(global_idof_index))
1499 boundary_dofs.insert(global_idof_index);
1504 return boundary_dofs.size();
1509 template <
int dim,
int spacedim>
1522 for (
const auto &
level : levels)
1531 template <
int dim,
int spacedim>
1534 const std::vector<unsigned int> &active_fe_indices)
1540 create_active_fe_table();
1545 for (
const auto &cell : active_cell_iterators())
1546 if (cell->is_locally_owned())
1547 cell->set_active_fe_index(active_fe_indices[cell->active_cell_index()]);
1552 template <
int dim,
int spacedim>
1555 std::vector<unsigned int> &active_fe_indices)
const
1562 for (
const auto &cell : active_cell_iterators())
1563 if (!cell->is_artificial())
1564 active_fe_indices[cell->active_cell_index()] = cell->active_fe_index();
1569 template <
int dim,
int spacedim>
1577 if (this->tria != &tria)
1579 for (
auto &connection : tria_listeners)
1580 connection.disconnect();
1581 tria_listeners.clear();
1585 setup_policy_and_listeners();
1588 create_active_fe_table();
1590 distribute_dofs(fe);
1595 template <
int dim,
int spacedim>
1602 "You need to set the Triangulation in the DoFHandler using initialize() or "
1603 "in the constructor before you can distribute DoFs."));
1604 Assert(tria->n_levels() > 0,
1605 ExcMessage(
"The Triangulation you are using is empty!"));
1609 if (fe_collection != ff)
1613 create_active_fe_table();
1622 for (
const auto &cell : active_cell_iterators())
1623 if (!cell->is_artificial())
1624 Assert(cell->active_fe_index() < fe_collection.size(),
1625 ExcInvalidFEIndex(cell->active_fe_index(),
1626 fe_collection.size()));
1631 template <
int dim,
int spacedim>
1643 std::vector<types::subdomain_id> saved_subdomain_ids;
1646 &get_triangulation()));
1651 const std::vector<types::subdomain_id> &true_subdomain_ids =
1656 const unsigned int index = cell->active_cell_index();
1657 saved_subdomain_ids[index] = cell->subdomain_id();
1658 cell->set_subdomain_id(true_subdomain_ids[index]);
1669 cell->set_subdomain_id(saved_subdomain_ids[cell->active_cell_index()]);
1676 std::vector<bool> user_flags;
1677 tria->save_user_flags(user_flags);
1684 number_cache = policy->distribute_dofs();
1693 &::internal::hp::DoFLevel::compress_data<dim, spacedim>,
1706 template <
int dim,
int spacedim>
1711 tria_listeners.push_back(this->tria->signals.pre_refinement.connect(
1712 [
this]() { this->pre_refinement_action(); }));
1713 tria_listeners.push_back(this->tria->signals.post_refinement.connect(
1714 [
this]() { this->post_refinement_action(); }));
1715 tria_listeners.push_back(this->tria->signals.create.connect(
1716 [
this]() { this->post_refinement_action(); }));
1722 *
>(&this->get_triangulation()))
1724 policy = std_cxx14::make_unique<
1729 tria_listeners.push_back(
1730 this->tria->signals.pre_distributed_repartition.connect([
this]() {
1731 internal::hp::DoFHandlerImplementation::Implementation::
1732 ensure_absence_of_future_fe_indices<dim, spacedim>(*this);
1734 tria_listeners.push_back(
1735 this->tria->signals.pre_distributed_repartition.connect(
1736 [
this]() { this->pre_distributed_active_fe_index_transfer(); }));
1737 tria_listeners.push_back(
1738 this->tria->signals.post_distributed_repartition.connect(
1739 [
this] { this->post_distributed_active_fe_index_transfer(); }));
1742 tria_listeners.push_back(
1743 this->tria->signals.pre_distributed_refinement.connect(
1744 [
this]() { this->pre_distributed_active_fe_index_transfer(); }));
1745 tria_listeners.push_back(
1746 this->tria->signals.post_distributed_refinement.connect(
1747 [
this]() { this->post_distributed_active_fe_index_transfer(); }));
1750 tria_listeners.push_back(
1751 this->tria->signals.post_distributed_save.connect([
this]() {
1752 this->post_distributed_serialization_of_active_fe_indices();
1756 *
>(&this->get_triangulation()) !=
nullptr)
1759 std_cxx14::make_unique<internal::DoFHandlerImplementation::Policy::
1760 ParallelShared<DoFHandler<dim, spacedim>>>(
1764 tria_listeners.push_back(
1765 this->tria->signals.pre_partition.connect([
this]() {
1766 internal::hp::DoFHandlerImplementation::Implementation::
1767 ensure_absence_of_future_fe_indices(*this);
1771 tria_listeners.push_back(this->tria->signals.pre_refinement.connect(
1772 [
this] { this->pre_active_fe_index_transfer(); }));
1773 tria_listeners.push_back(this->tria->signals.post_refinement.connect(
1774 [
this] { this->post_active_fe_index_transfer(); }));
1779 std_cxx14::make_unique<internal::DoFHandlerImplementation::Policy::
1780 Sequential<DoFHandler<dim, spacedim>>>(
1784 tria_listeners.push_back(this->tria->signals.pre_refinement.connect(
1785 [
this] { this->pre_active_fe_index_transfer(); }));
1786 tria_listeners.push_back(this->tria->signals.post_refinement.connect(
1787 [
this] { this->post_active_fe_index_transfer(); }));
1793 template <
int dim,
int spacedim>
1803 template <
int dim,
int spacedim>
1806 const std::vector<types::global_dof_index> &new_numbers)
1808 Assert(levels.size() > 0,
1810 "You need to distribute DoFs before you can renumber them."));
1824 if (n_locally_owned_dofs() == n_dofs())
1826 std::vector<types::global_dof_index> tmp(new_numbers);
1827 std::sort(tmp.begin(), tmp.end());
1828 std::vector<types::global_dof_index>::const_iterator p = tmp.begin();
1830 for (; p != tmp.end(); ++p, ++i)
1831 Assert(*p == i, ExcNewNumbersNotConsecutive(i));
1834 for (
const auto new_number : new_numbers)
1835 Assert(new_number < n_dofs(),
1837 "New DoF index is not less than the total number of dofs."));
1847 &::internal::hp::DoFLevel::uncompress_data<dim, spacedim>,
1854 number_cache = policy->renumber_dofs(new_numbers);
1861 &::internal::hp::DoFLevel::compress_data<dim, spacedim>,
1870 template <
int dim,
int spacedim>
1875 return ::internal::hp::DoFHandlerImplementation::Implementation::
1876 max_couplings_between_dofs(*
this);
1881 template <
int dim,
int spacedim>
1890 return fe_collection.max_dofs_per_vertex();
1892 return (3 * fe_collection.max_dofs_per_vertex() +
1893 2 * fe_collection.max_dofs_per_line());
1904 return (19 * fe_collection.max_dofs_per_vertex() +
1905 28 * fe_collection.max_dofs_per_line() +
1906 8 * fe_collection.max_dofs_per_quad());
1915 template <
int dim,
int spacedim>
1920 while (levels.size() < tria->n_levels())
1921 levels.emplace_back(new ::internal::hp::DoFLevel);
1927 if (levels[
level]->active_fe_indices.size() == 0 &&
1928 levels[
level]->future_fe_indices.size() == 0)
1930 levels[
level]->active_fe_indices.resize(tria->n_raw_cells(
level),
1932 levels[
level]->future_fe_indices.resize(
1933 tria->n_raw_cells(
level),
1942 tria->n_raw_cells(
level) &&
1943 levels[
level]->future_fe_indices.size() ==
1944 tria->n_raw_cells(
level),
1954 levels[
level]->normalize_active_fe_indices();
1960 template <
int dim,
int spacedim>
1964 create_active_fe_table();
1969 template <
int dim,
int spacedim>
1975 while (levels.size() < tria->n_levels())
1976 levels.emplace_back(new ::internal::hp::DoFLevel);
1979 while (levels.size() > tria->n_levels())
1986 for (
unsigned int i = 0; i < levels.size(); ++i)
1989 levels[i]->active_fe_indices.resize(tria->n_raw_cells(i), 0);
1996 levels[i]->future_fe_indices.assign(
1997 tria->n_raw_cells(i),
2004 template <
int dim,
int spacedim>
2010 if (fe_collection.size() > 0)
2014 active_fe_index_transfer =
2015 std_cxx14::make_unique<ActiveFEIndexTransfer>();
2024 template <
int dim,
int spacedim>
2028 #ifndef DEAL_II_WITH_P4EST
2031 "You are attempting to use a functionality that is only available "
2032 "if deal.II was configured to use p4est, but cmake did not find a "
2033 "valid p4est library."));
2038 &this->get_triangulation()) !=
nullptr),
2043 if (fe_collection.size() > 0)
2047 active_fe_index_transfer =
2048 std_cxx14::make_unique<ActiveFEIndexTransfer>();
2057 active_fe_index_transfer->active_fe_indices.resize(
2060 for (
const auto &cell : active_cell_iterators())
2061 if (cell->is_locally_owned())
2062 active_fe_index_transfer
2063 ->active_fe_indices[cell->active_cell_index()] =
2064 cell->future_fe_index();
2067 const auto *distributed_tria =
dynamic_cast<
2069 &this->get_triangulation());
2071 active_fe_index_transfer->cell_data_transfer = std_cxx14::make_unique<
2072 parallel::distributed::
2073 CellDataTransfer<dim, spacedim, std::vector<unsigned int>>>(
2077 &::AdaptationStrategies::Refinement::
2078 preserve<dim, spacedim, unsigned int>,
2082 const std::vector<unsigned int> &children_fe_indices)
2084 return ::internal::hp::DoFHandlerImplementation::
2085 Implementation::determine_fe_from_children<dim, spacedim>(
2086 parent, children_fe_indices, fe_collection);
2089 active_fe_index_transfer->cell_data_transfer
2090 ->prepare_for_coarsening_and_refinement(
2091 active_fe_index_transfer->active_fe_indices);
2098 template <
int dim,
int spacedim>
2104 if (fe_collection.size() > 0)
2118 active_fe_index_transfer.reset();
2124 template <
int dim,
int spacedim>
2128 #ifndef DEAL_II_WITH_P4EST
2131 "You are attempting to use a functionality that is only available "
2132 "if deal.II was configured to use p4est, but cmake did not find a "
2133 "valid p4est library."));
2138 &this->get_triangulation()) !=
nullptr),
2143 if (fe_collection.size() > 0)
2148 active_fe_index_transfer->active_fe_indices.resize(
2150 active_fe_index_transfer->cell_data_transfer->unpack(
2151 active_fe_index_transfer->active_fe_indices);
2154 set_active_fe_indices(active_fe_index_transfer->active_fe_indices);
2161 active_fe_index_transfer.reset();
2168 template <
int dim,
int spacedim>
2172 #ifndef DEAL_II_WITH_P4EST
2175 "You are attempting to use a functionality that is only available "
2176 "if deal.II was configured to use p4est, but cmake did not find a "
2177 "valid p4est library."));
2182 &this->get_triangulation()) !=
nullptr),
2187 if (fe_collection.size() > 0)
2191 active_fe_index_transfer =
2192 std_cxx14::make_unique<ActiveFEIndexTransfer>();
2195 const auto *distributed_tria =
dynamic_cast<
2197 &this->get_triangulation());
2199 active_fe_index_transfer->cell_data_transfer = std_cxx14::make_unique<
2200 parallel::distributed::
2201 CellDataTransfer<dim, spacedim, std::vector<unsigned int>>>(
2205 &::AdaptationStrategies::Refinement::
2206 preserve<dim, spacedim, unsigned int>,
2210 const std::vector<unsigned int> &children_fe_indices)
2212 return ::internal::hp::DoFHandlerImplementation::
2213 Implementation::determine_fe_from_children<dim, spacedim>(
2214 parent, children_fe_indices, fe_collection);
2224 active_fe_index_transfer->cell_data_transfer->prepare_for_serialization(
2225 active_fe_index_transfer->active_fe_indices);
2231 template <
int dim,
int spacedim>
2234 spacedim>::post_distributed_serialization_of_active_fe_indices()
2236 #ifndef DEAL_II_WITH_P4EST
2239 "You are attempting to use a functionality that is only available "
2240 "if deal.II was configured to use p4est, but cmake did not find a "
2241 "valid p4est library."));
2246 &this->get_triangulation()) !=
nullptr),
2249 if (fe_collection.size() > 0)
2254 active_fe_index_transfer.reset();
2261 template <
int dim,
int spacedim>
2265 #ifndef DEAL_II_WITH_P4EST
2268 "You are attempting to use a functionality that is only available "
2269 "if deal.II was configured to use p4est, but cmake did not find a "
2270 "valid p4est library."));
2275 &this->get_triangulation()) !=
nullptr),
2280 if (fe_collection.size() > 0)
2284 active_fe_index_transfer =
2285 std_cxx14::make_unique<ActiveFEIndexTransfer>();
2288 const auto *distributed_tria =
dynamic_cast<
2290 &this->get_triangulation());
2292 active_fe_index_transfer->cell_data_transfer = std_cxx14::make_unique<
2293 parallel::distributed::
2294 CellDataTransfer<dim, spacedim, std::vector<unsigned int>>>(
2298 &::AdaptationStrategies::Refinement::
2299 preserve<dim, spacedim, unsigned int>,
2303 const std::vector<unsigned int> &children_fe_indices)
2305 return ::internal::hp::DoFHandlerImplementation::
2306 Implementation::determine_fe_from_children<dim, spacedim>(
2307 parent, children_fe_indices, fe_collection);
2311 active_fe_index_transfer->active_fe_indices.resize(
2313 active_fe_index_transfer->cell_data_transfer->deserialize(
2314 active_fe_index_transfer->active_fe_indices);
2317 set_active_fe_indices(active_fe_index_transfer->active_fe_indices);
2324 active_fe_index_transfer.reset();
2331 template <
int dim,
int spacedim>
2332 template <
int structdim>
2337 const unsigned int)
const
2345 template <
int dim,
int spacedim>
2346 template <
int structdim>
2359 template <
int dim,
int spacedim>
2366 vertex_dofs = std::vector<types::global_dof_index>();
2367 vertex_dof_offsets = std::vector<unsigned int>();
2374 #include "dof_handler.inst"