16 #include <deal.II/base/geometry_info.h> 17 #include <deal.II/base/memory_consumption.h> 18 #include <deal.II/base/std_cxx14/memory.h> 19 #include <deal.II/base/thread_management.h> 21 #include <deal.II/distributed/shared_tria.h> 22 #include <deal.II/distributed/tria.h> 24 #include <deal.II/dofs/dof_accessor.h> 25 #include <deal.II/dofs/dof_handler_policy.h> 27 #include <deal.II/fe/fe.h> 29 #include <deal.II/grid/grid_tools.h> 30 #include <deal.II/grid/tria.h> 31 #include <deal.II/grid/tria_accessor.h> 32 #include <deal.II/grid/tria_iterator.h> 33 #include <deal.II/grid/tria_levels.h> 35 #include <deal.II/hp/dof_faces.h> 36 #include <deal.II/hp/dof_handler.h> 37 #include <deal.II/hp/dof_level.h> 39 #include <boost/serialization/array.hpp> 45 DEAL_II_NAMESPACE_OPEN
50 #if defined(_MSC_VER) && (_MSC_VER >= 1800) 51 template <
int dim,
int spacedim>
55 # define HpDoFHandler DoFHandler 73 namespace DoFHandlerImplementation
77 using ::hp::DoFHandler;
90 template <
int dim,
int spacedim>
97 if (cell->is_locally_owned())
99 !cell->future_fe_index_set(),
101 "There shouldn't be any cells flagged for p-adaptation when partitioning."));
110 template <
int dim,
int spacedim>
117 std::vector<std::vector<DoFLevel::active_fe_index_type>>
118 active_fe_backup(dof_handler.
levels.size()),
119 future_fe_backup(dof_handler.
levels.size());
120 for (
unsigned int level = 0; level < dof_handler.
levels.size();
123 active_fe_backup[level] =
124 std::move(dof_handler.
levels[level]->active_fe_indices);
125 future_fe_backup[level] =
126 std::move(dof_handler.
levels[level]->future_fe_indices);
133 for (
unsigned int level = 0; level < dof_handler.
tria->n_levels();
138 dof_handler.
levels[level]->active_fe_indices =
139 std::move(active_fe_backup[level]);
140 dof_handler.
levels[level]->future_fe_indices =
141 std::move(future_fe_backup[level]);
146 std_cxx14::make_unique<internal::hp::DoFIndicesOnFaces<dim>>();
156 template <
int dim,
int spacedim>
172 std::vector<bool> locally_used_vertices(
173 dof_handler.
tria->n_vertices(),
false);
174 for (
typename HpDoFHandler<dim, spacedim>::active_cell_iterator cell =
176 cell != dof_handler.
end();
178 if (!cell->is_artificial())
179 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell;
181 locally_used_vertices[cell->vertex_index(v)] =
true;
183 std::vector<std::vector<bool>> vertex_fe_association(
185 std::vector<bool>(dof_handler.
tria->n_vertices(),
false));
187 for (
typename HpDoFHandler<dim, spacedim>::active_cell_iterator cell =
189 cell != dof_handler.
end();
191 if (!cell->is_artificial())
192 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell;
194 vertex_fe_association[cell->active_fe_index()]
195 [cell->vertex_index(v)] =
true;
203 for (
unsigned int v = 0; v < dof_handler.
tria->n_vertices(); ++v)
204 if (locally_used_vertices[v] ==
true)
205 if (dof_handler.
tria->vertex_used(v) ==
true)
209 if (vertex_fe_association[fe][v] ==
true)
221 dof_handler.vertex_dof_offsets.resize(dof_handler.
tria->n_vertices(),
224 unsigned int vertex_slots_needed = 0;
225 for (
unsigned int v = 0; v < dof_handler.
tria->n_vertices(); ++v)
226 if (dof_handler.
tria->vertex_used(v) ==
true)
227 if (locally_used_vertices[v] ==
true)
229 dof_handler.vertex_dof_offsets[v] = vertex_slots_needed;
231 for (
unsigned int fe = 0;
234 if (vertex_fe_association[fe][v] ==
true)
235 vertex_slots_needed +=
236 dof_handler.
get_fe(fe).dofs_per_vertex + 1;
239 ++vertex_slots_needed;
244 dof_handler.
vertex_dofs.resize(vertex_slots_needed,
246 for (
unsigned int v = 0; v < dof_handler.
tria->n_vertices(); ++v)
247 if (dof_handler.
tria->vertex_used(v) ==
true)
248 if (locally_used_vertices[v] ==
true)
250 unsigned int current_index =
251 dof_handler.vertex_dof_offsets[v];
252 for (
unsigned int fe = 0;
255 if (vertex_fe_association[fe][v] ==
true)
261 dof_handler.
get_fe(fe).dofs_per_vertex + 1;
275 template <
int dim,
int spacedim>
287 for (
unsigned int level = 0; level < dof_handler.
tria->n_levels();
290 dof_handler.
levels[level]->dof_offsets =
291 std::vector<DoFLevel::offset_type>(
292 dof_handler.
tria->n_raw_cells(level),
294 dof_handler.
levels[level]->cell_cache_offsets =
295 std::vector<DoFLevel::offset_type>(
296 dof_handler.
tria->n_raw_cells(level),
301 typename HpDoFHandler<dim, spacedim>::active_cell_iterator
304 for (; cell != endc; ++cell)
305 if (!cell->has_children() && !cell->is_artificial())
307 dof_handler.
levels[level]->dof_offsets[cell->index()] =
310 cell->get_fe().template n_dofs_per_object<dim>();
313 ->cell_cache_offsets[cell->index()] = cache_size;
314 cache_size += cell->get_fe().dofs_per_cell;
317 dof_handler.
levels[level]->dof_indices =
318 std::vector<types::global_dof_index>(
320 dof_handler.
levels[level]->cell_dof_indices_cache =
321 std::vector<types::global_dof_index>(
330 for (
unsigned int level = 0; level < dof_handler.
tria->n_levels();
334 typename HpDoFHandler<dim, spacedim>::active_cell_iterator
337 for (; cell != endc; ++cell)
338 if (!cell->has_children() && !cell->is_artificial())
339 counter += cell->get_fe().template n_dofs_per_object<dim>();
341 Assert(dof_handler.
levels[level]->dof_indices.size() == counter,
348 unsigned int n_active_non_artificial_cells = 0;
349 for (cell = dof_handler.
begin_active(level); cell != endc; ++cell)
350 if (!cell->has_children() && !cell->is_artificial())
351 ++n_active_non_artificial_cells;
353 Assert(static_cast<unsigned int>(std::count(
354 dof_handler.
levels[level]->dof_offsets.begin(),
355 dof_handler.
levels[level]->dof_offsets.end(),
357 dof_handler.
tria->n_raw_cells(level) -
358 n_active_non_artificial_cells,
370 template <
int dim,
int spacedim>
375 std::vector<unsigned int> &face_dof_offsets =
384 std::vector<types::global_dof_index> &face_dof_indices =
412 std::vector<bool> saved_face_user_flags;
419 .save_user_flags_line(saved_face_user_flags);
422 .clear_user_flags_line();
431 .save_user_flags_quad(saved_face_user_flags);
434 .clear_user_flags_quad();
445 unsigned int n_face_slots = 0;
448 if (!cell->is_artificial())
449 for (
unsigned int face = 0;
450 face < GeometryInfo<dim>::faces_per_cell;
452 if (cell->face(face)->user_flag_set() ==
false)
462 if (cell->at_boundary(face) ||
463 cell->face(face)->has_children() ||
464 cell->neighbor_is_coarser(face) ||
465 (!cell->at_boundary(face) &&
466 cell->neighbor(face)->is_artificial()) ||
467 (!cell->at_boundary(face) &&
468 !cell->neighbor(face)->is_artificial() &&
469 (cell->active_fe_index() ==
470 cell->neighbor(face)->active_fe_index())))
475 dof_handler.
get_fe(cell->active_fe_index())
476 .
template n_dofs_per_object<dim - 1>() +
485 dof_handler.
get_fe(cell->active_fe_index())
486 .
template n_dofs_per_object<
490 .
get_fe(cell->neighbor(face)->active_fe_index())
491 .
template n_dofs_per_object<
496 cell->face(face)->set_user_flag();
504 std::vector<unsigned int>(dof_handler.
tria->n_raw_faces(),
507 std::vector<types::global_dof_index>(n_face_slots,
519 .clear_user_flags_line();
528 .clear_user_flags_quad();
537 unsigned int next_free_face_slot = 0;
540 if (!cell->is_artificial())
541 for (
unsigned int face = 0;
542 face < GeometryInfo<dim>::faces_per_cell;
544 if (!cell->face(face)->user_flag_set())
547 if (cell->at_boundary(face) ||
548 cell->face(face)->has_children() ||
549 cell->neighbor_is_coarser(face) ||
550 (!cell->at_boundary(face) &&
551 cell->neighbor(face)->is_artificial()) ||
552 (!cell->at_boundary(face) &&
553 !cell->neighbor(face)->is_artificial() &&
554 (cell->active_fe_index() ==
555 cell->neighbor(face)->active_fe_index())))
559 face_dof_offsets[cell->face(face)->index()] =
564 face_dof_indices[next_free_face_slot] =
565 cell->active_fe_index();
574 next_free_face_slot +=
576 + dof_handler.
get_fe(cell->active_fe_index())
577 .
template n_dofs_per_object<
585 face_dof_offsets[cell->face(face)->index()] =
608 unsigned int active_fe_indices[2] = {
609 cell->active_fe_index(),
610 cell->neighbor(face)->active_fe_index()};
611 if (active_fe_indices[1] < active_fe_indices[0])
613 active_fe_indices[1]);
617 face_dof_indices[next_free_face_slot] =
618 active_fe_indices[0];
625 [next_free_face_slot + 1 +
626 dof_handler.
get_fe(active_fe_indices[0])
627 .template n_dofs_per_object<dim - 1>()] =
628 active_fe_indices[1];
637 next_free_face_slot +=
639 + dof_handler.
get_fe(active_fe_indices[0])
640 .template n_dofs_per_object<
643 + dof_handler.
get_fe(active_fe_indices[1])
644 .template n_dofs_per_object<
650 cell->face(face)->set_user_flag();
664 .load_user_flags_line(saved_face_user_flags);
673 .load_user_flags_quad(saved_face_user_flags);
692 template <
int spacedim>
698 ExcMessage(
"The current Triangulation must not be empty."));
714 template <
int spacedim>
720 ExcMessage(
"The current Triangulation must not be empty."));
738 template <
int spacedim>
741 const unsigned int dim = 3;
746 ExcMessage(
"The current Triangulation must not be empty."));
773 std::vector<std::vector<bool>> line_fe_association(
775 std::vector<bool>(dof_handler.
tria->n_raw_lines(),
false));
777 for (
typename HpDoFHandler<dim, spacedim>::active_cell_iterator
779 cell != dof_handler.
end();
781 if (!cell->is_artificial())
782 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell;
784 line_fe_association[cell->active_fe_index()]
785 [cell->line_index(l)] =
true;
791 std::vector<bool> line_is_used(dof_handler.
tria->n_raw_lines(),
793 for (
unsigned int line = 0; line < dof_handler.
tria->n_raw_lines();
795 for (
unsigned int fe = 0; fe < dof_handler.
fe_collection.size();
797 if (line_fe_association[fe][line] ==
true)
799 line_is_used[line] =
true;
808 dof_handler.
faces->lines.dof_offsets.resize(
811 unsigned int line_slots_needed = 0;
812 for (
unsigned int line = 0; line < dof_handler.
tria->n_raw_lines();
814 if (line_is_used[line] ==
true)
816 dof_handler.
faces->lines.dof_offsets[line] =
819 for (
unsigned int fe = 0;
822 if (line_fe_association[fe][line] ==
true)
824 dof_handler.
get_fe(fe).dofs_per_line + 1;
830 dof_handler.
faces->lines.dofs.resize(line_slots_needed,
832 for (
unsigned int line = 0; line < dof_handler.
tria->n_raw_lines();
834 if (line_is_used[line] ==
true)
836 unsigned int pointer =
837 dof_handler.
faces->lines.dof_offsets[line];
838 for (
unsigned int fe = 0;
841 if (line_fe_association[fe][line] ==
true)
845 dof_handler.
faces->lines.dofs[pointer] = fe;
846 pointer += dof_handler.
get_fe(fe).dofs_per_line + 1;
849 dof_handler.
faces->lines.dofs[pointer] =
863 template <
int spacedim>
867 return std::min(static_cast<types::global_dof_index>(
876 template <
int spacedim>
900 switch (dof_handler.
tria->max_adjacent_cells())
936 return std::min(max_couplings, dof_handler.
n_dofs());
941 template <
int spacedim>
954 const unsigned int max_adjacent_cells =
955 dof_handler.
tria->max_adjacent_cells();
958 if (max_adjacent_cells <= 8)
960 7 * 7 * 7 * dof_handler.
fe_collection.max_dofs_per_vertex() +
961 7 * 6 * 7 * 3 * dof_handler.
fe_collection.max_dofs_per_line() +
962 9 * 4 * 7 * 3 * dof_handler.
fe_collection.max_dofs_per_quad() +
970 return std::min(max_couplings, dof_handler.
n_dofs());
986 template <
int dim,
int spacedim>
1006 std::vector<unsigned int> active_fe_indices(tr->n_active_cells(),
1009 if (cell->is_locally_owned())
1010 active_fe_indices[cell->active_cell_index()] =
1011 cell->active_fe_index();
1014 tr->get_communicator(),
1024 if (!cell->is_locally_owned())
1025 dof_handler.
levels[cell->level()]->set_active_fe_index(
1027 active_fe_indices[cell->active_cell_index()]);
1041 [](
const typename ::hp::DoFHandler<dim, spacedim>::
1042 active_cell_iterator &cell) ->
unsigned int {
1043 return cell->active_fe_index();
1048 const typename ::hp::DoFHandler<dim, spacedim>::
1049 active_cell_iterator &cell,
1050 const unsigned int active_fe_index) ->
void {
1055 dof_handler.
levels[cell->level()]->set_active_fe_index(
1056 cell->index(), active_fe_index);
1096 template <
int dim,
int spacedim>
1104 if (cell->is_locally_owned())
1106 if (cell->refine_flag_set())
1111 fe_transfer->refined_cells_fe_index.insert(
1112 {cell, cell->future_fe_index()});
1114 else if (cell->coarsen_flag_set())
1121 const auto &parent = cell->parent();
1124 if (fe_transfer->coarsened_cells_fe_index.find(parent) ==
1125 fe_transfer->coarsened_cells_fe_index.end())
1131 std::set<unsigned int> fe_indices_children;
1132 for (
unsigned int child_index = 0;
1133 child_index < parent->n_children();
1136 Assert(parent->child(child_index)->active(),
1139 fe_indices_children.insert(
1140 parent->child(child_index)->future_fe_index());
1142 Assert(!fe_indices_children.empty(),
1145 const unsigned int fe_index =
1147 fe_indices_children,
1153 "No FiniteElement has been found in your FECollection " 1154 "that dominates all children of a cell you are trying " 1157 fe_transfer->coarsened_cells_fe_index.insert(
1158 {parent, fe_index});
1166 if (cell->future_fe_index_set() ==
true)
1167 fe_transfer->persisting_cells_fe_index.insert(
1168 {cell, cell->future_fe_index()});
1179 template <
int dim,
int spacedim>
1187 for (
const auto &pair : fe_transfer->persisting_cells_fe_index)
1189 const auto &cell = pair.first;
1191 if (cell->is_locally_owned())
1194 cell->set_active_fe_index(pair.second);
1200 for (
const auto &pair : fe_transfer->refined_cells_fe_index)
1202 const auto &parent = pair.first;
1204 for (
unsigned int child_index = 0;
1205 child_index < parent->n_children();
1208 const auto &child = parent->child(child_index);
1209 Assert(child->is_locally_owned() && child->active(),
1211 child->set_active_fe_index(pair.second);
1217 for (
const auto &pair : fe_transfer->coarsened_cells_fe_index)
1219 const auto &cell = pair.first;
1220 Assert(cell->is_locally_owned() && cell->active(),
1222 cell->set_active_fe_index(pair.second);
1234 template <
int dim,
int spacedim>
1237 template <
int dim,
int spacedim>
1240 template <
int dim,
int spacedim>
1245 template <
int dim,
int spacedim>
1247 : tria(nullptr, typeid(*this).name())
1253 template <
int dim,
int spacedim>
1256 : tria(&tria, typeid(*this).name())
1259 setup_policy_and_listeners();
1261 create_active_fe_table();
1266 template <
int dim,
int spacedim>
1271 for (
auto &connection : tria_listeners)
1272 connection.disconnect();
1273 tria_listeners.clear();
1287 template <
int dim,
int spacedim>
1291 return cell_iterator(*this->get_triangulation().begin(level),
this);
1296 template <
int dim,
int spacedim>
1304 while (i->has_children())
1312 template <
int dim,
int spacedim>
1316 return cell_iterator(&this->get_triangulation(), -1, -1,
this);
1321 template <
int dim,
int spacedim>
1325 return (level == this->get_triangulation().n_levels() - 1 ?
1332 template <
int dim,
int spacedim>
1336 return (level == this->get_triangulation().n_levels() - 1 ?
1338 begin_active(level + 1));
1343 template <
int dim,
int spacedim>
1353 template <
int dim,
int spacedim>
1364 template <
int dim,
int spacedim>
1367 const unsigned int level)
const 1370 begin(level), end(level));
1375 template <
int dim,
int spacedim>
1378 const unsigned int level)
const 1382 begin_active(level), end_active(level));
1390 template <
int dim,
int spacedim>
1396 std::set<types::global_dof_index> boundary_dofs;
1397 std::vector<types::global_dof_index> dofs_on_face;
1405 typename HpDoFHandler<dim, spacedim>::active_cell_iterator
1406 cell = this->begin_active(),
1408 for (; cell != endc; ++cell)
1409 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
1410 if (cell->at_boundary(f))
1412 const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
1413 dofs_on_face.resize(dofs_per_face);
1415 cell->face(f)->get_dof_indices(dofs_on_face,
1416 cell->active_fe_index());
1417 for (
unsigned int i = 0; i < dofs_per_face; ++i)
1418 boundary_dofs.insert(dofs_on_face[i]);
1420 return boundary_dofs.size();
1425 template <
int dim,
int spacedim>
1428 const std::set<types::boundary_id> &boundary_ids)
const 1437 std::set<types::global_dof_index> boundary_dofs;
1438 std::vector<types::global_dof_index> dofs_on_face;
1441 typename HpDoFHandler<dim, spacedim>::active_cell_iterator
1442 cell = this->begin_active(),
1444 for (; cell != endc; ++cell)
1445 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
1446 if (cell->at_boundary(f) &&
1447 (boundary_ids.find(cell->face(f)->boundary_id()) !=
1448 boundary_ids.end()))
1450 const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
1451 dofs_on_face.resize(dofs_per_face);
1453 cell->face(f)->get_dof_indices(dofs_on_face,
1454 cell->active_fe_index());
1455 for (
unsigned int i = 0; i < dofs_per_face; ++i)
1456 boundary_dofs.insert(dofs_on_face[i]);
1458 return boundary_dofs.size();
1474 template <
typename number>
1495 template <
int dim,
int spacedim>
1508 for (
unsigned int i = 0; i < levels.size(); ++i)
1517 template <
int dim,
int spacedim>
1520 const std::vector<unsigned int> &active_fe_indices)
1522 Assert(active_fe_indices.size() == get_triangulation().n_active_cells(),
1524 get_triangulation().n_active_cells()));
1526 create_active_fe_table();
1531 for (
const auto &cell : active_cell_iterators())
1532 if (cell->is_locally_owned())
1533 cell->set_active_fe_index(active_fe_indices[cell->active_cell_index()]);
1538 template <
int dim,
int spacedim>
1541 std::vector<unsigned int> &active_fe_indices)
const 1543 active_fe_indices.resize(get_triangulation().n_active_cells());
1548 for (
const auto &cell : active_cell_iterators())
1549 if (!cell->is_artificial())
1550 active_fe_indices[cell->active_cell_index()] = cell->active_fe_index();
1555 template <
int dim,
int spacedim>
1561 if (this->tria != &tria)
1563 for (
auto &connection : tria_listeners)
1564 connection.disconnect();
1565 tria_listeners.clear();
1569 setup_policy_and_listeners();
1572 create_active_fe_table();
1574 distribute_dofs(fe);
1579 template <
int dim,
int spacedim>
1586 "You need to set the Triangulation in the DoFHandler using initialize() or " 1587 "in the constructor before you can distribute DoFs."));
1588 Assert(tria->n_levels() > 0,
1589 ExcMessage(
"The Triangulation you are using is empty!"));
1593 if (fe_collection != ff)
1597 create_active_fe_table();
1606 for (
const auto &cell : active_cell_iterators())
1607 if (!cell->is_artificial())
1608 Assert(cell->active_fe_index() < fe_collection.size(),
1609 ExcInvalidFEIndex(cell->active_fe_index(),
1610 fe_collection.size()));
1615 template <
int dim,
int spacedim>
1627 std::vector<types::subdomain_id> saved_subdomain_ids;
1630 &get_triangulation()));
1635 const std::vector<types::subdomain_id> &true_subdomain_ids =
1640 const unsigned int index = cell->active_cell_index();
1641 saved_subdomain_ids[index] = cell->subdomain_id();
1642 cell->set_subdomain_id(true_subdomain_ids[index]);
1653 cell->set_subdomain_id(saved_subdomain_ids[cell->active_cell_index()]);
1660 std::vector<bool> user_flags;
1661 tria->save_user_flags(user_flags);
1668 number_cache = policy->distribute_dofs();
1675 for (
int level = levels.size() - 1; level >= 0; --level)
1677 &::internal::hp::DoFLevel::compress_data<dim, spacedim>,
1690 template <
int dim,
int spacedim>
1695 tria_listeners.push_back(this->tria->signals.pre_refinement.connect(
1698 tria_listeners.push_back(this->tria->signals.post_refinement.connect(
1701 tria_listeners.push_back(this->tria->signals.create.connect(std::bind(
1708 *
>(&this->get_triangulation()))
1710 policy = std_cxx14::make_unique<
1715 tria_listeners.push_back(
1716 this->tria->signals.pre_distributed_repartition.connect(
1718 ensure_absence_of_future_fe_indices<dim, spacedim>,
1720 tria_listeners.push_back(
1721 this->tria->signals.pre_distributed_repartition.connect(std::bind(
1723 spacedim>::pre_distributed_active_fe_index_transfer,
1725 tria_listeners.push_back(
1726 this->tria->signals.post_distributed_repartition.connect(std::bind(
1728 spacedim>::post_distributed_active_fe_index_transfer,
1732 tria_listeners.push_back(
1733 this->tria->signals.pre_distributed_refinement.connect(std::bind(
1735 spacedim>::pre_distributed_active_fe_index_transfer,
1737 tria_listeners.push_back(
1738 this->tria->signals.post_distributed_refinement.connect(std::bind(
1740 spacedim>::post_distributed_active_fe_index_transfer,
1744 tria_listeners.push_back(
1745 this->tria->signals.post_distributed_save.connect(
1747 post_distributed_serialization_of_active_fe_indices,
1751 *
>(&this->get_triangulation()) !=
nullptr)
1754 std_cxx14::make_unique<internal::DoFHandlerImplementation::Policy::
1755 ParallelShared<DoFHandler<dim, spacedim>>>(
1759 tria_listeners.push_back(this->tria->signals.pre_partition.connect(
1761 ensure_absence_of_future_fe_indices<dim, spacedim>,
1765 tria_listeners.push_back(this->tria->signals.pre_refinement.connect(
1768 tria_listeners.push_back(this->tria->signals.post_refinement.connect(
1775 std_cxx14::make_unique<internal::DoFHandlerImplementation::Policy::
1776 Sequential<DoFHandler<dim, spacedim>>>(
1780 tria_listeners.push_back(this->tria->signals.pre_refinement.connect(
1783 tria_listeners.push_back(this->tria->signals.post_refinement.connect(
1791 template <
int dim,
int spacedim>
1801 template <
int dim,
int spacedim>
1804 const std::vector<types::global_dof_index> &new_numbers)
1806 Assert(levels.size() > 0,
1808 "You need to distribute DoFs before you can renumber them."));
1822 if (n_locally_owned_dofs() == n_dofs())
1824 std::vector<types::global_dof_index> tmp(new_numbers);
1825 std::sort(tmp.begin(), tmp.end());
1826 std::vector<types::global_dof_index>::const_iterator p = tmp.begin();
1828 for (; p != tmp.end(); ++p, ++i)
1829 Assert(*p == i, ExcNewNumbersNotConsecutive(i));
1832 for (
const auto new_number : new_numbers)
1833 Assert(new_number < n_dofs(),
1835 "New DoF index is not less than the total number of dofs."));
1843 for (
int level = levels.size() - 1; level >= 0; --level)
1845 &::internal::hp::DoFLevel::uncompress_data<dim, spacedim>,
1852 number_cache = policy->renumber_dofs(new_numbers);
1857 for (
int level = levels.size() - 1; level >= 0; --level)
1859 &::internal::hp::DoFLevel::compress_data<dim, spacedim>,
1868 template <
int dim,
int spacedim>
1873 return ::internal::hp::DoFHandlerImplementation::Implementation::
1874 max_couplings_between_dofs(*
this);
1879 template <
int dim,
int spacedim>
1888 return fe_collection.max_dofs_per_vertex();
1890 return (3 * fe_collection.max_dofs_per_vertex() +
1891 2 * fe_collection.max_dofs_per_line());
1902 return (19 * fe_collection.max_dofs_per_vertex() +
1903 28 * fe_collection.max_dofs_per_line() +
1904 8 * fe_collection.max_dofs_per_quad());
1913 template <
int dim,
int spacedim>
1918 while (levels.size() < tria->n_levels())
1919 levels.emplace_back(new ::internal::hp::DoFLevel);
1923 for (
unsigned int level = 0; level < levels.size(); ++level)
1925 if (levels[level]->active_fe_indices.size() == 0 &&
1926 levels[level]->future_fe_indices.size() == 0)
1928 levels[level]->active_fe_indices.resize(tria->n_raw_cells(level),
1930 levels[level]->future_fe_indices.resize(
1931 tria->n_raw_cells(level),
1939 Assert(levels[level]->active_fe_indices.size() ==
1940 tria->n_raw_cells(level) &&
1941 levels[level]->future_fe_indices.size() ==
1942 tria->n_raw_cells(level),
1952 levels[level]->normalize_active_fe_indices();
1958 template <
int dim,
int spacedim>
1962 create_active_fe_table();
1967 template <
int dim,
int spacedim>
1973 while (levels.size() < tria->n_levels())
1974 levels.emplace_back(new ::internal::hp::DoFLevel);
1977 while (levels.size() > tria->n_levels())
1984 for (
unsigned int i = 0; i < levels.size(); ++i)
1987 levels[i]->active_fe_indices.resize(tria->n_raw_cells(i), 0);
1994 levels[i]->future_fe_indices.assign(
1995 tria->n_raw_cells(i),
2002 template <
int dim,
int spacedim>
2008 if (fe_collection.size() > 0)
2012 active_fe_index_transfer =
2013 std_cxx14::make_unique<ActiveFEIndexTransfer>();
2022 template <
int dim,
int spacedim>
2026 #ifndef DEAL_II_WITH_P4EST 2031 if (fe_collection.size() > 0)
2035 active_fe_index_transfer =
2036 std_cxx14::make_unique<ActiveFEIndexTransfer>();
2049 get_active_fe_indices(active_fe_index_transfer->active_fe_indices);
2053 for (
const auto &pair :
2054 active_fe_index_transfer->persisting_cells_fe_index)
2055 active_fe_index_transfer
2056 ->active_fe_indices[pair.first->active_cell_index()] = pair.second;
2058 for (
const auto &pair :
2059 active_fe_index_transfer->refined_cells_fe_index)
2060 active_fe_index_transfer
2061 ->active_fe_indices[pair.first->active_cell_index()] = pair.second;
2063 for (
const auto &pair :
2064 active_fe_index_transfer->coarsened_cells_fe_index)
2065 for (
unsigned int child_index = 0;
2066 child_index < pair.first->n_children();
2070 Assert(pair.first->child(child_index)->is_locally_owned(),
2073 active_fe_index_transfer
2074 ->active_fe_indices[pair.first->child(child_index)
2075 ->active_cell_index()] = pair.second;
2079 const auto *distributed_tria =
dynamic_cast< 2081 &this->get_triangulation());
2083 active_fe_index_transfer->cell_data_transfer = std_cxx14::make_unique<
2084 parallel::distributed::
2085 CellDataTransfer<dim, spacedim, std::vector<unsigned int>>>(
2091 std::vector<unsigned int>>::CoarseningStrategies::check_equality);
2093 active_fe_index_transfer->cell_data_transfer
2094 ->prepare_for_coarsening_and_refinement(
2095 active_fe_index_transfer->active_fe_indices);
2102 template <
int dim,
int spacedim>
2108 if (fe_collection.size() > 0)
2122 active_fe_index_transfer.reset();
2128 template <
int dim,
int spacedim>
2132 #ifndef DEAL_II_WITH_P4EST 2137 if (fe_collection.size() > 0)
2142 active_fe_index_transfer->active_fe_indices.resize(
2144 active_fe_index_transfer->cell_data_transfer->unpack(
2145 active_fe_index_transfer->active_fe_indices);
2148 set_active_fe_indices(active_fe_index_transfer->active_fe_indices);
2151 active_fe_index_transfer.reset();
2158 template <
int dim,
int spacedim>
2162 #ifndef DEAL_II_WITH_P4EST 2165 "You are attempting to use a functionality that is only available " 2166 "if deal.II was configured to use p4est, but cmake did not find a " 2167 "valid p4est library."));
2171 *
>(&this->get_triangulation()) !=
nullptr),
2173 "This functionality requires a parallel::distributed::Triangulation object."));
2177 if (fe_collection.size() > 0)
2181 active_fe_index_transfer =
2182 std_cxx14::make_unique<ActiveFEIndexTransfer>();
2185 const auto *distributed_tria =
dynamic_cast< 2187 &this->get_triangulation());
2189 active_fe_index_transfer->cell_data_transfer = std_cxx14::make_unique<
2190 parallel::distributed::
2191 CellDataTransfer<dim, spacedim, std::vector<unsigned int>>>(
2197 std::vector<unsigned int>>::CoarseningStrategies::check_equality);
2203 get_active_fe_indices(active_fe_index_transfer->active_fe_indices);
2206 active_fe_index_transfer->cell_data_transfer->prepare_for_serialization(
2207 active_fe_index_transfer->active_fe_indices);
2213 template <
int dim,
int spacedim>
2216 spacedim>::post_distributed_serialization_of_active_fe_indices()
2218 #ifndef DEAL_II_WITH_P4EST 2221 "You are attempting to use a functionality that is only available " 2222 "if deal.II was configured to use p4est, but cmake did not find a " 2223 "valid p4est library."));
2228 active_fe_index_transfer.reset();
2234 template <
int dim,
int spacedim>
2238 #ifndef DEAL_II_WITH_P4EST 2241 "You are attempting to use a functionality that is only available " 2242 "if deal.II was configured to use p4est, but cmake did not find a " 2243 "valid p4est library."));
2247 *
>(&this->get_triangulation()) !=
nullptr),
2249 "This functionality requires a parallel::distributed::Triangulation object."));
2253 if (fe_collection.size() > 0)
2257 active_fe_index_transfer =
2258 std_cxx14::make_unique<ActiveFEIndexTransfer>();
2261 const auto *distributed_tria =
dynamic_cast< 2263 &this->get_triangulation());
2265 active_fe_index_transfer->cell_data_transfer = std_cxx14::make_unique<
2266 parallel::distributed::
2267 CellDataTransfer<dim, spacedim, std::vector<unsigned int>>>(
2273 std::vector<unsigned int>>::CoarseningStrategies::check_equality);
2276 active_fe_index_transfer->active_fe_indices.resize(
2278 active_fe_index_transfer->cell_data_transfer->deserialize(
2279 active_fe_index_transfer->active_fe_indices);
2282 set_active_fe_indices(active_fe_index_transfer->active_fe_indices);
2285 active_fe_index_transfer.reset();
2292 template <
int dim,
int spacedim>
2293 template <
int structdim>
2298 const unsigned int)
const 2306 template <
int dim,
int spacedim>
2307 template <
int structdim>
2320 template <
int dim,
int spacedim>
2327 vertex_dofs = std::move(std::vector<types::global_dof_index>());
2328 vertex_dof_offsets = std::move(std::vector<unsigned int>());
2335 #include "dof_handler.inst" 2338 DEAL_II_NAMESPACE_CLOSE
IteratorRange< active_cell_iterator > active_cell_iterators_on_level(const unsigned int level) const
unsigned int max_couplings_between_dofs() const
unsigned int n_active_cells() const
static const unsigned int invalid_unsigned_int
#define AssertDimension(dim1, dim2)
cell_iterator begin(const unsigned int level=0) const
Task< RT > new_task(const std::function< RT()> &function)
static void distribute_fe_indices_on_refined_cells(::hp::DoFHandler< dim, spacedim > &dof_handler)
const std::vector< types::subdomain_id > & get_true_subdomain_ids_of_cells() const
IteratorRange< active_cell_iterator > active_cell_iterators() const
std::vector< std::unique_ptr<::internal::hp::DoFLevel > > levels
void load_user_flags(std::istream &in)
cell_iterator end() const
unsigned int max_dofs_per_face(const DoFHandler< dim, spacedim > &dh)
unsigned int size() const
virtual std::size_t memory_consumption() const
std::unique_ptr< ActiveFEIndexTransfer > active_fe_index_transfer
static void collect_fe_indices_on_cells_to_be_refined(::hp::DoFHandler< dim, spacedim > &dof_handler)
static void reserve_space_cells(DoFHandler< dim, spacedim > &dof_handler)
void initialize(const Triangulation< dim, spacedim > &tria, const FiniteElement< dim, spacedim > &fe)
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
typename ActiveSelector::active_cell_iterator active_cell_iterator
active_cell_iterator begin_active(const unsigned int level=0) const
static ::ExceptionBase & ExcMessage(std::string arg1)
typename ActiveSelector::cell_iterator cell_iterator
T sum(const T &t, const MPI_Comm &mpi_communicator)
#define Assert(cond, exc)
hp::FECollection< dim, spacedim > fe_collection
IteratorRange< active_cell_iterator > active_cell_iterators() const
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
std::vector< types::global_dof_index > dofs
active_cell_iterator end_active(const unsigned int level) const
types::global_dof_index n_boundary_dofs() const
static void reserve_space_release_space(DoFHandler< dim, spacedim > &dof_handler)
SmartPointer< const Triangulation< dim, spacedim >, DoFHandler< dim, spacedim > > tria
types::global_dof_index n_dofs() const
virtual void set_fe(const FiniteElement< dim, spacedim > &fe)
static unsigned int max_couplings_between_dofs(const DoFHandler< 1, spacedim > &dof_handler)
std::unique_ptr<::internal::DoFHandlerImplementation::DoFFaces< dim > > faces
std::vector< unsigned int > dof_offsets
std::vector< std::unique_ptr<::internal::DoFHandlerImplementation::DoFLevel< dim > > > levels
internal::hp::DoFIndicesOnFacesOrEdges< 2 > quads
void renumber_dofs(const std::vector< types::global_dof_index > &new_numbers)
void swap(Vector< Number > &u, Vector< Number > &v)
unsigned int global_dof_index
hp::FECollection< dim, spacedim > fe_collection
static void ensure_absence_of_future_fe_indices(DoFHandler< dim, spacedim > &dof_handler)
const Triangulation< dim, spacedim > & get_triangulation() const
virtual void distribute_dofs(const FiniteElement< dim, spacedim > &fe)
bool with_artificial_cells() const
static void reserve_space_vertices(DoFHandler< dim, spacedim > &dof_handler)
static const active_fe_index_type invalid_active_fe_index
static ::ExceptionBase & ExcInvalidBoundaryIndicator()
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
static ::ExceptionBase & ExcNotImplemented()
Iterator points to a valid object.
const types::boundary_id internal_face_boundary_id
unsigned int max_couplings_between_boundary_dofs() const
static void communicate_active_fe_indices(::hp::DoFHandler< dim, spacedim > &dof_handler)
static void reserve_space(DoFHandler< 1, spacedim > &dof_handler)
const types::global_dof_index invalid_dof_index
virtual ~DoFHandler() override
static ::ExceptionBase & ExcNoFESelected()
IteratorRange< cell_iterator > cell_iterators() const
static void reserve_space_faces(DoFHandler< dim, spacedim > &dof_handler)
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
std::vector< types::global_dof_index > vertex_dofs
static ::ExceptionBase & ExcInternalError()