17 #include <deal.II/base/geometry_info.h> 18 #include <deal.II/base/memory_consumption.h> 19 #include <deal.II/base/partitioner.h> 20 #include <deal.II/base/thread_management.h> 21 #include <deal.II/base/utilities.h> 22 #include <deal.II/base/work_stream.h> 24 #include <deal.II/distributed/shared_tria.h> 25 #include <deal.II/distributed/tria.h> 27 #include <deal.II/dofs/dof_accessor.h> 28 #include <deal.II/dofs/dof_handler.h> 29 #include <deal.II/dofs/dof_handler_policy.h> 31 #include <deal.II/fe/fe.h> 33 #include <deal.II/grid/grid_tools.h> 34 #include <deal.II/grid/tria.h> 35 #include <deal.II/grid/tria_iterator.h> 37 #include <boost/archive/binary_iarchive.hpp> 38 #include <boost/archive/binary_oarchive.hpp> 39 #ifdef DEAL_II_WITH_ZLIB 40 # include <boost/iostreams/device/back_inserter.hpp> 41 # include <boost/iostreams/filter/gzip.hpp> 42 # include <boost/iostreams/filtering_stream.hpp> 43 # include <boost/iostreams/stream.hpp> 44 # include <boost/serialization/array.hpp> 52 DEAL_II_NAMESPACE_OPEN
57 namespace DoFHandlerImplementation
68 using ::hp::DoFHandler;
87 template <
class DoFHandlerType>
89 update_all_active_cell_dof_indices_caches(
90 const DoFHandlerType &dof_handler)
92 typename DoFHandlerType::active_cell_iterator
93 beginc = dof_handler.begin_active(),
94 endc = dof_handler.end();
97 [](
const typename DoFHandlerType::active_cell_iterator &cell,
100 if (!cell->is_artificial())
101 cell->update_cell_dof_indices_cache();
113 std::function<
void(
void *)>(),
125 template <
class DoFHandlerType>
127 update_all_level_cell_dof_indices_caches(
128 const DoFHandlerType &dof_handler)
130 typename DoFHandlerType::level_cell_iterator beginc =
132 endc = dof_handler.end();
135 [](
const typename DoFHandlerType::level_cell_iterator &cell,
138 if (cell->has_children() || !cell->is_artificial())
139 cell->update_cell_dof_indices_cache();
151 std::function<
void(
void *)>(),
159 using DoFIdentities =
160 std::vector<std::pair<unsigned int, unsigned int>>;
173 template <
int structdim,
int dim,
int spacedim>
175 ensure_existence_of_dof_identities(
178 std::unique_ptr<DoFIdentities> & identities)
182 if (identities.get() ==
nullptr)
188 identities = std_cxx14::make_unique<DoFIdentities>(
195 identities = std_cxx14::make_unique<DoFIdentities>(
202 identities = std_cxx14::make_unique<DoFIdentities>(
213 for (
unsigned int i = 0; i < identities->size(); ++i)
215 Assert((*identities)[i].first <
216 fe1.template n_dofs_per_object<structdim>(),
218 Assert((*identities)[i].second <
219 fe2.template n_dofs_per_object<structdim>(),
228 struct Implementation
239 template <
int spacedim>
241 distribute_dofs_on_cell(
247 if (dof_handler.
get_fe().dofs_per_vertex > 0)
248 for (
unsigned int v = 0; v < GeometryInfo<1>::vertices_per_cell;
252 for (
unsigned int d = 0;
253 d < dof_handler.
get_fe().dofs_per_vertex;
256 Assert((cell->vertex_dof_index(v, d) ==
259 cell->set_vertex_dof_index(v, d, next_free_dof++);
262 for (
unsigned int d = 0;
263 d < dof_handler.
get_fe().dofs_per_vertex;
265 Assert((cell->vertex_dof_index(v, d) !=
271 for (
unsigned int d = 0;
d < dof_handler.
get_fe().dofs_per_line; ++
d)
272 cell->set_dof_index(d, next_free_dof++);
274 return next_free_dof;
279 template <
int spacedim>
281 distribute_dofs_on_cell(
286 if (dof_handler.
get_fe().dofs_per_vertex > 0)
288 for (
unsigned int vertex = 0;
289 vertex < GeometryInfo<2>::vertices_per_cell;
293 if (cell->vertex_dof_index(vertex, 0) ==
295 for (
unsigned int d = 0;
296 d < dof_handler.
get_fe().dofs_per_vertex;
298 cell->set_vertex_dof_index(vertex, d, next_free_dof++);
301 if (dof_handler.
get_fe().dofs_per_line > 0)
302 for (
unsigned int side = 0; side < GeometryInfo<2>::faces_per_cell;
313 for (
unsigned int d = 0;
314 d < dof_handler.
get_fe().dofs_per_line;
316 line->set_dof_index(d, next_free_dof++);
321 if (dof_handler.
get_fe().dofs_per_quad > 0)
322 for (
unsigned int d = 0;
d < dof_handler.
get_fe().dofs_per_quad;
324 cell->set_dof_index(d, next_free_dof++);
326 return next_free_dof;
331 template <
int spacedim>
333 distribute_dofs_on_cell(
338 if (dof_handler.
get_fe().dofs_per_vertex > 0)
340 for (
unsigned int vertex = 0;
341 vertex < GeometryInfo<3>::vertices_per_cell;
345 if (cell->vertex_dof_index(vertex, 0) ==
347 for (
unsigned int d = 0;
348 d < dof_handler.
get_fe().dofs_per_vertex;
350 cell->set_vertex_dof_index(vertex, d, next_free_dof++);
353 if (dof_handler.
get_fe().dofs_per_line > 0)
354 for (
unsigned int l = 0; l < GeometryInfo<3>::lines_per_cell; ++
l)
364 for (
unsigned int d = 0;
365 d < dof_handler.
get_fe().dofs_per_line;
367 line->set_dof_index(d, next_free_dof++);
371 if (dof_handler.
get_fe().dofs_per_quad > 0)
372 for (
unsigned int q = 0; q < GeometryInfo<3>::quads_per_cell; ++q)
382 for (
unsigned int d = 0;
383 d < dof_handler.
get_fe().dofs_per_quad;
385 quad->set_dof_index(d, next_free_dof++);
390 if (dof_handler.
get_fe().dofs_per_hex > 0)
391 for (
unsigned int d = 0;
d < dof_handler.
get_fe().dofs_per_hex; ++
d)
392 cell->set_dof_index(d, next_free_dof++);
394 return next_free_dof;
400 template <
int spacedim>
402 distribute_dofs_on_cell(
408 const unsigned int dim = 1;
411 const unsigned int fe_index = cell->active_fe_index();
418 for (
unsigned int vertex = 0;
419 vertex < GeometryInfo<1>::vertices_per_cell;
421 if (cell->vertex_dof_index(vertex, 0, fe_index) ==
424 ++
d, ++next_free_dof)
425 cell->set_vertex_dof_index(vertex,
433 Assert((cell->dof_index(0, fe_index) ==
438 ++
d, ++next_free_dof)
439 cell->set_dof_index(d, next_free_dof, fe_index);
443 cell->set_user_flag();
445 return next_free_dof;
450 template <
int spacedim>
452 distribute_dofs_on_cell(
458 const unsigned int dim = 2;
461 const unsigned int fe_index = cell->active_fe_index();
468 for (
unsigned int vertex = 0;
469 vertex < GeometryInfo<2>::vertices_per_cell;
471 if (cell->vertex_dof_index(vertex, 0, fe_index) ==
474 ++
d, ++next_free_dof)
475 cell->set_vertex_dof_index(vertex,
484 for (
unsigned int l = 0; l < GeometryInfo<2>::lines_per_cell; ++
l)
487 line = cell->line(l);
491 ++
d, ++next_free_dof)
492 line->set_dof_index(d, next_free_dof, fe_index);
499 Assert((cell->dof_index(0, fe_index) ==
504 ++
d, ++next_free_dof)
505 cell->set_dof_index(d, next_free_dof, fe_index);
509 cell->set_user_flag();
511 return next_free_dof;
516 template <
int spacedim>
518 distribute_dofs_on_cell(
524 const unsigned int dim = 3;
527 const unsigned int fe_index = cell->active_fe_index();
534 for (
unsigned int vertex = 0;
535 vertex < GeometryInfo<3>::vertices_per_cell;
537 if (cell->vertex_dof_index(vertex, 0, fe_index) ==
540 ++
d, ++next_free_dof)
541 cell->set_vertex_dof_index(vertex,
550 for (
unsigned int l = 0; l < GeometryInfo<3>::lines_per_cell; ++
l)
553 line = cell->line(l);
557 ++
d, ++next_free_dof)
558 line->set_dof_index(d, next_free_dof, fe_index);
563 for (
unsigned int q = 0; q < GeometryInfo<3>::quads_per_cell; ++q)
566 quad = cell->quad(q);
570 ++
d, ++next_free_dof)
571 quad->set_dof_index(d, next_free_dof, fe_index);
580 Assert((cell->dof_index(0, fe_index) ==
585 ++
d, ++next_free_dof)
586 cell->set_dof_index(d, next_free_dof, fe_index);
590 cell->set_user_flag();
592 return next_free_dof;
601 template <
int dim,
int spacedim>
602 static std::map<types::global_dof_index, types::global_dof_index>
603 compute_vertex_dof_identities(
606 std::map<types::global_dof_index, types::global_dof_index>
620 for (
unsigned int vertex_index = 0;
624 .get_used_vertices()[vertex_index] ==
true)
626 const unsigned int n_active_fe_indices =
627 ::internal::DoFAccessorImplementation::Implementation::
628 n_active_vertex_fe_indices(dof_handler, vertex_index);
630 if (n_active_fe_indices > 1)
632 const std::set<unsigned int> fe_indices =
633 ::internal::DoFAccessorImplementation::
634 Implementation::get_active_vertex_fe_indices(
635 dof_handler, vertex_index);
639 unsigned int most_dominating_fe_index =
646 if (most_dominating_fe_index ==
648 most_dominating_fe_index =
649 ::internal::DoFAccessorImplementation::
650 Implementation::nth_active_vertex_fe_index(
651 dof_handler, vertex_index, 0);
657 for (
const auto &other_fe_index : fe_indices)
658 if (other_fe_index != most_dominating_fe_index)
662 ensure_existence_of_dof_identities<0>(
663 dof_handler.
get_fe(most_dominating_fe_index),
664 dof_handler.
get_fe(other_fe_index),
665 vertex_dof_identities[most_dominating_fe_index]
676 DoFIdentities &identities =
677 *vertex_dof_identities[most_dominating_fe_index]
679 for (
const auto &
identity : identities)
682 ::internal::DoFAccessorImplementation::
683 Implementation::get_vertex_dof_index(
686 most_dominating_fe_index,
689 ::internal::DoFAccessorImplementation::
690 Implementation::get_vertex_dof_index(
718 if (master_dof_index !=
720 Assert((dof_identities.find(
722 dof_identities.end()) ||
723 (dof_identities[slave_dof_index] ==
727 dof_identities[slave_dof_index] =
735 return dof_identities;
743 template <
int spacedim>
744 static std::map<types::global_dof_index, types::global_dof_index>
747 return std::map<types::global_dof_index, types::global_dof_index>();
751 template <
int dim,
int spacedim>
752 static std::map<types::global_dof_index, types::global_dof_index>
753 compute_line_dof_identities(
756 std::map<types::global_dof_index, types::global_dof_index>
761 std::vector<bool> user_flags;
765 .clear_user_flags_line();
791 cell != dof_handler.
end();
793 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
794 if (cell->line(l)->user_flag_set() ==
false)
797 line = cell->line(l);
798 line->set_user_flag();
800 unsigned int unique_sets_of_dofs =
801 line->n_active_fe_indices();
805 const unsigned int n_active_fe_indices =
806 line->n_active_fe_indices();
807 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
808 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
810 const unsigned int fe_index_1 =
811 line->nth_active_fe_index(f),
813 line->nth_active_fe_index(g);
831 if ((dof_handler.
get_fe(fe_index_1).dofs_per_line ==
832 dof_handler.
get_fe(fe_index_2).dofs_per_line) &&
833 (dof_handler.
get_fe(fe_index_1).dofs_per_line > 0))
836 const unsigned int dofs_per_line =
837 dof_handler.
get_fe(fe_index_1).dofs_per_line;
839 ensure_existence_of_dof_identities<1>(
840 dof_handler.
get_fe(fe_index_1),
841 dof_handler.
get_fe(fe_index_2),
842 line_dof_identities[fe_index_1][fe_index_2]);
846 if (line_dof_identities[fe_index_1][fe_index_2]
847 ->size() == dofs_per_line)
850 for (; i < dofs_per_line; ++i)
851 if (((*(line_dof_identities[fe_index_1]
854 ((*(line_dof_identities[fe_index_1]
860 if (i == dofs_per_line)
869 --unique_sets_of_dofs;
873 const std::set<unsigned int> fe_indices{
874 fe_index_1, fe_index_2};
876 unsigned int dominating_fe_index =
878 .find_dominating_fe(fe_indices,
880 unsigned int other_fe_index =
883 if (dominating_fe_index !=
886 (dominating_fe_index == fe_index_1) ?
894 dominating_fe_index = fe_index_1;
895 other_fe_index = fe_index_2;
898 for (
unsigned int j = 0; j < dofs_per_line;
902 master_dof_index = line->dof_index(
903 j, dominating_fe_index);
906 line->dof_index(j, other_fe_index);
922 if (slave_dof_index !=
925 if (master_dof_index !=
932 if (dof_identities.find(
934 dof_identities.end())
950 [master_dof_index]) ==
951 dof_identities.end(),
965 (dof_identities.find(
967 dof_identities.end()) ||
1004 if ((unique_sets_of_dofs == 2) && (dim == 2))
1006 const std::set<unsigned int> fe_indices =
1011 const unsigned int most_dominating_fe_index =
1021 if (most_dominating_fe_index !=
1027 for (
const auto &other_fe_index : fe_indices)
1028 if (other_fe_index != most_dominating_fe_index)
1030 ensure_existence_of_dof_identities<1>(
1031 dof_handler.
get_fe(most_dominating_fe_index),
1032 dof_handler.
get_fe(other_fe_index),
1033 line_dof_identities[most_dominating_fe_index]
1036 DoFIdentities &identities =
1037 *line_dof_identities[most_dominating_fe_index]
1039 for (
const auto &
identity : identities)
1042 master_dof_index = line->dof_index(
1044 most_dominating_fe_index);
1063 if (slave_dof_index !=
1073 if (master_dof_index !=
1075 Assert((dof_identities.find(
1076 master_dof_index) ==
1077 dof_identities.end()) ||
1079 [slave_dof_index] ==
1083 dof_identities[slave_dof_index] =
1095 .load_user_flags_line(user_flags);
1097 return dof_identities;
1106 template <
int dim,
int spacedim>
1107 static std::map<types::global_dof_index, types::global_dof_index>
1115 return std::map<types::global_dof_index, types::global_dof_index>();
1119 template <
int spacedim>
1120 static std::map<types::global_dof_index, types::global_dof_index>
1121 compute_quad_dof_identities(
1126 std::map<types::global_dof_index, types::global_dof_index>
1133 std::vector<bool> user_flags;
1137 .clear_user_flags_quad();
1155 cell != dof_handler.
end();
1157 for (
unsigned int q = 0; q < GeometryInfo<dim>::quads_per_cell; ++q)
1158 if ((cell->quad(q)->user_flag_set() ==
false) &&
1159 (cell->quad(q)->n_active_fe_indices() == 2))
1162 quad = cell->quad(q);
1163 quad->set_user_flag();
1165 const std::set<unsigned int> fe_indices =
1170 const unsigned int most_dominating_fe_index =
1187 for (
const auto &other_fe_index : fe_indices)
1188 if (other_fe_index != most_dominating_fe_index)
1190 ensure_existence_of_dof_identities<2>(
1191 dof_handler.
get_fe(most_dominating_fe_index),
1192 dof_handler.
get_fe(other_fe_index),
1193 quad_dof_identities[most_dominating_fe_index]
1196 DoFIdentities &identities =
1197 *quad_dof_identities[most_dominating_fe_index]
1199 for (
const auto &
identity : identities)
1203 most_dominating_fe_index);
1213 if (slave_dof_index !=
1223 if (master_dof_index !=
1226 (dof_identities.find(
1227 master_dof_index) ==
1228 dof_identities.end()) ||
1229 (dof_identities[slave_dof_index] ==
1233 dof_identities[slave_dof_index] =
1244 .load_user_flags_quad(user_flags);
1246 return dof_identities;
1255 template <
int dim,
int spacedim>
1257 compute_dof_identities(
1259 std::map<types::global_dof_index, types::global_dof_index>> &,
1264 template <
int dim,
int spacedim>
1268 &all_constrained_indices,
1277 all_constrained_indices[i] =
1278 compute_vertex_dof_identities(dof_handler);
1285 all_constrained_indices[i] =
1286 compute_line_dof_identities(dof_handler);
1294 all_constrained_indices[i] =
1295 compute_quad_dof_identities(dof_handler);
1323 template <
class DoFHandlerType>
1325 enumerate_dof_indices_for_renumbering(
1326 std::vector<types::global_dof_index> &new_dof_indices,
1328 std::map<types::global_dof_index, types::global_dof_index>>
1329 &all_constrained_indices,
1330 const DoFHandlerType &)
1332 Assert(all_constrained_indices.size() == DoFHandlerType::dimension,
1336 for (
const auto &constrained_dof_indices : all_constrained_indices)
1337 for (
const auto &p : constrained_dof_indices)
1340 Assert(new_dof_indices[p.first] == enumeration_dof_index,
1343 new_dof_indices[p.first] = p.second;
1348 for (
auto &new_dof_index : new_dof_indices)
1349 if (new_dof_index == enumeration_dof_index)
1350 new_dof_index = next_free_dof++;
1354 for (
const auto &constrained_dof_indices : all_constrained_indices)
1355 for (
const auto &p : constrained_dof_indices)
1358 Assert(new_dof_indices[p.first] != enumeration_dof_index,
1362 new_dof_indices[p.first] = new_dof_indices[p.second];
1367 (void)new_dof_index;
1368 Assert(new_dof_index != enumeration_dof_index,
1370 Assert(new_dof_index < next_free_dof ||
1375 return next_free_dof;
1389 template <
int dim,
int spacedim>
1392 const unsigned int n_dofs_before_identification,
1395 return n_dofs_before_identification;
1399 template <
int dim,
int spacedim>
1402 const unsigned int n_dofs_before_identification,
1403 const bool check_validity)
1406 std::map<types::global_dof_index, types::global_dof_index>>
1407 all_constrained_indices(dim);
1408 compute_dof_identities(all_constrained_indices, dof_handler);
1410 std::vector<::types::global_dof_index> renumbering(
1411 n_dofs_before_identification, enumeration_dof_index);
1413 enumerate_dof_indices_for_renumbering(renumbering,
1414 all_constrained_indices,
1417 renumber_dofs(renumbering,
IndexSet(0), dof_handler, check_validity);
1419 update_all_active_cell_dof_indices_caches(dof_handler);
1430 template <
int dim,
int spacedim>
1432 merge_invalid_vertex_dofs_on_ghost_interfaces(
1446 std::vector<bool> include_vertex(
1452 if (cell->is_ghost())
1453 for (
unsigned int v = 0;
1454 v < GeometryInfo<dim>::vertices_per_cell;
1456 include_vertex[cell->vertex_index(v)] =
true;
1459 for (
unsigned int vertex_index = 0;
1463 .get_used_vertices()[vertex_index] ==
true) &&
1464 (include_vertex[vertex_index] ==
true))
1466 const unsigned int n_active_fe_indices =
1467 ::internal::DoFAccessorImplementation::Implementation::
1468 n_active_vertex_fe_indices(dof_handler, vertex_index);
1470 if (n_active_fe_indices > 1)
1472 const std::set<unsigned int> fe_indices =
1473 ::internal::DoFAccessorImplementation::
1474 Implementation::get_active_vertex_fe_indices(
1475 dof_handler, vertex_index);
1479 const unsigned int most_dominating_fe_index =
1490 if (most_dominating_fe_index !=
1497 for (
const auto &other_fe_index : fe_indices)
1498 if (other_fe_index != most_dominating_fe_index)
1502 ensure_existence_of_dof_identities<0>(
1503 dof_handler.
get_fe(most_dominating_fe_index),
1504 dof_handler.
get_fe(other_fe_index),
1505 vertex_dof_identities[most_dominating_fe_index]
1516 DoFIdentities &identities =
1517 *vertex_dof_identities[most_dominating_fe_index]
1519 for (
const auto &
identity : identities)
1522 master_dof_index = ::internal::
1523 DoFAccessorImplementation::
1524 Implementation::get_vertex_dof_index(
1527 most_dominating_fe_index,
1530 slave_dof_index = ::internal::
1531 DoFAccessorImplementation::
1532 Implementation::get_vertex_dof_index(
1550 if ((slave_dof_index ==
1552 (master_dof_index !=
1555 DoFAccessorImplementation::
1556 Implementation::set_vertex_dof_index(
1575 template <
int spacedim>
1576 static void merge_invalid_line_dofs_on_ghost_interfaces(
1581 template <
int dim,
int spacedim>
1583 merge_invalid_line_dofs_on_ghost_interfaces(
1588 std::vector<bool> user_flags;
1592 .clear_user_flags_line();
1596 if (cell->is_ghost())
1597 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell;
1599 cell->line(l)->set_user_flag();
1625 cell != dof_handler.
end();
1627 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
1628 if ((cell->is_locally_owned()) &&
1629 (cell->line(l)->user_flag_set() ==
true))
1632 line = cell->line(l);
1633 line->clear_user_flag();
1635 unsigned int unique_sets_of_dofs =
1636 line->n_active_fe_indices();
1640 const unsigned int n_active_fe_indices =
1641 line->n_active_fe_indices();
1642 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1643 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
1645 const unsigned int fe_index_1 =
1646 line->nth_active_fe_index(f),
1648 line->nth_active_fe_index(g);
1650 if ((dof_handler.
get_fe(fe_index_1).dofs_per_line ==
1651 dof_handler.
get_fe(fe_index_2).dofs_per_line) &&
1652 (dof_handler.
get_fe(fe_index_1).dofs_per_line > 0))
1655 const unsigned int dofs_per_line =
1656 dof_handler.
get_fe(fe_index_1).dofs_per_line;
1658 ensure_existence_of_dof_identities<1>(
1659 dof_handler.
get_fe(fe_index_1),
1660 dof_handler.
get_fe(fe_index_2),
1661 line_dof_identities[fe_index_1][fe_index_2]);
1665 if (line_dof_identities[fe_index_1][fe_index_2]
1666 ->size() == dofs_per_line)
1669 for (; i < dofs_per_line; ++i)
1670 if (((*(line_dof_identities[fe_index_1]
1673 ((*(line_dof_identities[fe_index_1]
1679 if (i == dofs_per_line)
1688 --unique_sets_of_dofs;
1692 const std::set<unsigned int> fe_indices{
1693 fe_index_1, fe_index_2};
1695 unsigned int dominating_fe_index =
1697 .find_dominating_fe(fe_indices,
1699 unsigned int other_fe_index =
1702 if (dominating_fe_index !=
1705 (dominating_fe_index == fe_index_1) ?
1713 dominating_fe_index = fe_index_1;
1714 other_fe_index = fe_index_2;
1717 for (
unsigned int j = 0; j < dofs_per_line;
1721 master_dof_index = line->dof_index(
1722 j, dominating_fe_index);
1725 line->dof_index(j, other_fe_index);
1740 if ((slave_dof_index ==
1742 (master_dof_index !=
1744 line->set_dof_index(j,
1763 if ((unique_sets_of_dofs == 2) && (dim == 2))
1765 const std::set<unsigned int> fe_indices =
1770 const unsigned int most_dominating_fe_index =
1780 if (most_dominating_fe_index !=
1786 for (
const auto &other_fe_index : fe_indices)
1787 if (other_fe_index != most_dominating_fe_index)
1789 ensure_existence_of_dof_identities<1>(
1790 dof_handler.
get_fe(most_dominating_fe_index),
1791 dof_handler.
get_fe(other_fe_index),
1792 line_dof_identities[most_dominating_fe_index]
1795 DoFIdentities &identities =
1796 *line_dof_identities[most_dominating_fe_index]
1798 for (
const auto &
identity : identities)
1801 master_dof_index = line->dof_index(
1803 most_dominating_fe_index);
1821 if ((slave_dof_index ==
1823 (master_dof_index !=
1825 line->set_dof_index(
identity.second,
1837 .load_user_flags_line(user_flags);
1846 template <
int dim,
int spacedim>
1848 merge_invalid_quad_dofs_on_ghost_interfaces(
1858 template <
int spacedim>
1859 static void merge_invalid_quad_dofs_on_ghost_interfaces(
1867 std::vector<bool> user_flags;
1871 .clear_user_flags_quad();
1875 if (cell->is_ghost())
1876 for (
unsigned int q = 0; q < GeometryInfo<dim>::quads_per_cell;
1878 cell->quad(q)->set_user_flag();
1896 cell != dof_handler.
end();
1898 for (
unsigned int q = 0; q < GeometryInfo<dim>::quads_per_cell; ++q)
1899 if ((cell->is_locally_owned()) &&
1900 (cell->quad(q)->user_flag_set() ==
true) &&
1901 (cell->quad(q)->n_active_fe_indices() == 2))
1904 quad = cell->quad(q);
1905 quad->clear_user_flag();
1907 const std::set<unsigned int> fe_indices =
1912 const unsigned int most_dominating_fe_index =
1929 for (
const auto &other_fe_index : fe_indices)
1930 if (other_fe_index != most_dominating_fe_index)
1932 ensure_existence_of_dof_identities<2>(
1933 dof_handler.
get_fe(most_dominating_fe_index),
1934 dof_handler.
get_fe(other_fe_index),
1935 quad_dof_identities[most_dominating_fe_index]
1938 DoFIdentities &identities =
1939 *quad_dof_identities[most_dominating_fe_index]
1941 for (
const auto &
identity : identities)
1945 most_dominating_fe_index);
1961 if ((slave_dof_index ==
1963 (master_dof_index !=
1965 quad->set_dof_index(
identity.second,
1976 .load_user_flags_quad(user_flags);
1993 template <
int dim,
int spacedim>
1995 merge_invalid_dof_indices_on_ghost_interfaces(
2000 template <
int dim,
int spacedim>
2002 merge_invalid_dof_indices_on_ghost_interfaces(
2009 merge_invalid_vertex_dofs_on_ghost_interfaces(dof_handler);
2015 merge_invalid_line_dofs_on_ghost_interfaces(dof_handler);
2022 merge_invalid_quad_dofs_on_ghost_interfaces(dof_handler);
2029 update_all_active_cell_dof_indices_caches(dof_handler);
2040 template <
class DoFHandlerType>
2043 DoFHandlerType & dof_handler)
2045 Assert(dof_handler.get_triangulation().n_levels() > 0,
2051 typename DoFHandlerType::active_cell_iterator
2053 endc = dof_handler.end();
2055 for (; cell != endc; ++cell)
2056 if (!cell->is_artificial())
2060 Implementation::distribute_dofs_on_cell(dof_handler,
2064 update_all_active_cell_dof_indices_caches(dof_handler);
2066 return next_free_dof;
2084 template <
class DoFHandlerType>
2086 invalidate_dof_indices_on_weaker_ghost_cells_for_renumbering(
2087 std::vector<types::global_dof_index> &renumbering,
2089 const DoFHandlerType & dof_handler)
2091 std::vector<types::global_dof_index> local_dof_indices;
2093 for (
const auto &cell : dof_handler.active_cell_iterators())
2094 if (cell->is_ghost() && (cell->subdomain_id() <
subdomain_id))
2102 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
2103 cell->get_dof_indices(local_dof_indices);
2104 for (
const auto &local_dof_index : local_dof_indices)
2122 template <
int dim,
int spacedim>
2124 distribute_mg_dofs_on_cell(
2125 const typename DoFHandler<dim, spacedim>::level_cell_iterator &cell,
2127 const std::integral_constant<int, 1> &)
2130 if (cell->
get_fe().dofs_per_vertex > 0)
2131 for (
unsigned int v = 0; v < GeometryInfo<1>::vertices_per_cell;
2134 typename DoFHandler<dim, spacedim>::level_cell_iterator
2135 neighbor = cell->neighbor(v);
2140 if (neighbor->user_flag_set() &&
2141 (neighbor->level() == cell->level()))
2146 for (
unsigned int d = 0;
2147 d < cell->
get_fe().dofs_per_vertex;
2149 cell->set_mg_vertex_dof_index(
2153 neighbor->mg_vertex_dof_index(cell->level(),
2157 for (
unsigned int d = 0;
2158 d < cell->
get_fe().dofs_per_vertex;
2160 cell->set_mg_vertex_dof_index(
2164 neighbor->mg_vertex_dof_index(cell->level(),
2174 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_vertex;
2176 cell->set_mg_vertex_dof_index(cell->level(),
2183 if (cell->
get_fe().dofs_per_line > 0)
2184 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_line; ++
d)
2185 cell->set_mg_dof_index(cell->level(),
d, next_free_dof++);
2188 cell->set_user_flag();
2190 return next_free_dof;
2195 template <
int dim,
int spacedim>
2197 distribute_mg_dofs_on_cell(
2198 const typename DoFHandler<dim, spacedim>::level_cell_iterator &cell,
2200 const std::integral_constant<int, 2> &)
2202 if (cell->
get_fe().dofs_per_vertex > 0)
2204 for (
unsigned int vertex = 0;
2205 vertex < GeometryInfo<2>::vertices_per_cell;
2210 if (cell->mg_vertex_dof_index(cell->level(), vertex, 0) ==
2212 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_vertex;
2214 cell->set_mg_vertex_dof_index(cell->level(),
2220 if (cell->
get_fe().dofs_per_line > 0)
2221 for (
unsigned int side = 0; side < GeometryInfo<2>::faces_per_cell;
2229 if (line->mg_dof_index(cell->level(), 0) ==
2232 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_line;
2234 line->set_mg_dof_index(cell->level(),
d, next_free_dof++);
2239 if (cell->
get_fe().dofs_per_quad > 0)
2240 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_quad; ++
d)
2241 cell->set_mg_dof_index(cell->level(),
d, next_free_dof++);
2245 cell->set_user_flag();
2247 return next_free_dof;
2252 template <
int dim,
int spacedim>
2254 distribute_mg_dofs_on_cell(
2255 const typename DoFHandler<dim, spacedim>::level_cell_iterator &cell,
2257 const std::integral_constant<int, 3> &)
2259 if (cell->
get_fe().dofs_per_vertex > 0)
2261 for (
unsigned int vertex = 0;
2262 vertex < GeometryInfo<3>::vertices_per_cell;
2266 if (cell->mg_vertex_dof_index(cell->level(), vertex, 0) ==
2268 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_vertex;
2270 cell->set_mg_vertex_dof_index(cell->level(),
2276 if (cell->
get_fe().dofs_per_line > 0)
2277 for (
unsigned int l = 0; l < GeometryInfo<3>::lines_per_cell; ++
l)
2285 if (line->mg_dof_index(cell->level(), 0) ==
2288 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_line;
2290 line->set_mg_dof_index(cell->level(),
d, next_free_dof++);
2294 if (cell->
get_fe().dofs_per_quad > 0)
2295 for (
unsigned int q = 0; q < GeometryInfo<3>::quads_per_cell; ++q)
2303 if (quad->mg_dof_index(cell->level(), 0) ==
2306 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_quad;
2308 quad->set_mg_dof_index(cell->level(),
d, next_free_dof++);
2313 if (cell->
get_fe().dofs_per_hex > 0)
2314 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_hex; ++
d)
2315 cell->set_mg_dof_index(cell->level(),
d, next_free_dof++);
2319 cell->set_user_flag();
2321 return next_free_dof;
2327 template <
int spacedim>
2329 distribute_mg_dofs_on_cell(
2337 (void)next_free_dof;
2343 template <
int spacedim>
2345 distribute_mg_dofs_on_cell(
2353 (void)next_free_dof;
2359 template <
int spacedim>
2361 distribute_mg_dofs_on_cell(
2369 (void)next_free_dof;
2375 template <
class DoFHandlerType>
2378 DoFHandlerType & dof_handler,
2379 const unsigned int level)
2381 const unsigned int dim = DoFHandlerType::dimension;
2382 const unsigned int spacedim = DoFHandlerType::space_dimension;
2384 const ::Triangulation<dim, spacedim> &tria =
2387 if (level >= tria.n_levels())
2394 std::vector<bool> user_flags;
2395 tria.save_user_flags(user_flags);
2397 .clear_user_flags();
2400 typename DoFHandler<dim, spacedim>::level_cell_iterator
2401 cell = dof_handler.
begin(level),
2402 endc = dof_handler.end(level);
2404 for (; cell != endc; ++cell)
2406 (cell->level_subdomain_id() == level_subdomain_id))
2408 Implementation::distribute_mg_dofs_on_cell<dim, spacedim>(
2409 cell, next_free_dof, std::integral_constant<int, dim>());
2413 .load_user_flags(user_flags);
2415 return next_free_dof;
2430 template <
int dim,
int spacedim>
2432 renumber_vertex_dofs(
2433 const std::vector<types::global_dof_index> &new_numbers,
2434 const IndexSet & indices_we_care_about,
2436 const bool check_validity)
2444 for (std::vector<types::global_dof_index>::iterator i =
2449 *i = (indices_we_care_about.
size() == 0) ?
2452 else if (check_validity)
2457 dof_handler.
get_fe().dofs_per_vertex) ==
false,
2470 template <
int dim,
int spacedim>
2473 const std::vector<types::global_dof_index> &new_numbers,
2474 const IndexSet & indices_we_care_about,
2477 for (
unsigned int level = 0; level < dof_handler.
levels.size();
2479 for (std::vector<types::global_dof_index>::iterator i =
2480 dof_handler.
levels[level]->dof_object.dofs.begin();
2481 i != dof_handler.
levels[level]->dof_object.dofs.end();
2485 ((indices_we_care_about.
size() == 0) ?
2499 template <
int spacedim>
2502 const std::vector<types::global_dof_index> & ,
2511 template <
int spacedim>
2514 const std::vector<types::global_dof_index> &new_numbers,
2515 const IndexSet & indices_we_care_about,
2519 for (std::vector<types::global_dof_index>::iterator i =
2520 dof_handler.
faces->lines.dofs.begin();
2521 i != dof_handler.
faces->lines.dofs.end();
2524 *i = ((indices_we_care_about.
size() == 0) ?
2531 template <
int spacedim>
2534 const std::vector<types::global_dof_index> &new_numbers,
2535 const IndexSet & indices_we_care_about,
2539 for (std::vector<types::global_dof_index>::iterator i =
2540 dof_handler.
faces->lines.dofs.begin();
2541 i != dof_handler.
faces->lines.dofs.end();
2544 *i = ((indices_we_care_about.
size() == 0) ?
2549 for (std::vector<types::global_dof_index>::iterator i =
2550 dof_handler.
faces->quads.dofs.begin();
2551 i != dof_handler.
faces->quads.dofs.end();
2554 *i = ((indices_we_care_about.
size() == 0) ?
2561 template <
int dim,
int spacedim>
2563 renumber_vertex_dofs(
2564 const std::vector<types::global_dof_index> &new_numbers,
2565 const IndexSet & indices_we_care_about,
2567 const bool check_validity)
2569 for (
unsigned int vertex_index = 0;
2573 const unsigned int n_active_fe_indices =
2574 ::internal::DoFAccessorImplementation::Implementation::
2575 n_active_vertex_fe_indices(dof_handler, vertex_index);
2589 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2591 const unsigned int fe_index =
2592 ::internal::DoFAccessorImplementation::
2593 Implementation::nth_active_vertex_fe_index(dof_handler,
2597 for (
unsigned int d = 0;
2598 d < dof_handler.
get_fe(fe_index).dofs_per_vertex;
2602 ::internal::DoFAccessorImplementation::
2603 Implementation::get_vertex_dof_index(dof_handler,
2637 if (indices_we_care_about.
size() == 0)
2639 Implementation::set_vertex_dof_index(
2644 new_numbers[old_dof_index]);
2650 Implementation::set_vertex_dof_index(
2655 new_numbers[indices_we_care_about
2659 ::internal::DoFAccessorImplementation::
2660 Implementation::set_vertex_dof_index(
2675 template <
int dim,
int spacedim>
2678 const std::vector<types::global_dof_index> &new_numbers,
2679 const IndexSet & indices_we_care_about,
2684 cell != dof_handler.
end();
2686 if (!cell->is_artificial())
2688 const unsigned int fe_index = cell->active_fe_index();
2690 for (
unsigned int d = 0;
2691 d < dof_handler.
get_fe(fe_index)
2692 .template n_dofs_per_object<dim>();
2696 cell->dof_index(d, fe_index);
2713 if (indices_we_care_about.
size() == 0)
2714 cell->set_dof_index(d,
2715 new_numbers[old_dof_index],
2719 if (indices_we_care_about.
is_element(old_dof_index))
2720 cell->set_dof_index(
2722 new_numbers[indices_we_care_about
2726 cell->set_dof_index(d,
2737 template <
int spacedim>
2740 const std::vector<types::global_dof_index> & ,
2750 template <
int spacedim>
2753 const std::vector<types::global_dof_index> &new_numbers,
2754 const IndexSet & indices_we_care_about,
2757 const unsigned int dim = 2;
2763 std::vector<bool> saved_line_user_flags;
2766 .save_user_flags_line(saved_line_user_flags);
2769 .clear_user_flags_line();
2773 cell != dof_handler.
end();
2775 if (!cell->is_artificial())
2776 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell;
2778 if (cell->line(l)->user_flag_set() ==
false)
2781 spacedim>::line_iterator
2782 line = cell->line(l);
2783 line->set_user_flag();
2785 const unsigned int n_active_fe_indices =
2786 line->n_active_fe_indices();
2788 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2790 const unsigned int fe_index =
2791 line->nth_active_fe_index(f);
2793 for (
unsigned int d = 0;
2794 d < dof_handler.
get_fe(fe_index).dofs_per_line;
2798 line->dof_index(d, fe_index);
2818 if (indices_we_care_about.
size() == 0)
2819 line->set_dof_index(
2820 d, new_numbers[old_dof_index], fe_index);
2825 line->set_dof_index(
2827 new_numbers[indices_we_care_about
2832 line->set_dof_index(
2846 .load_user_flags_line(saved_line_user_flags);
2852 template <
int spacedim>
2855 const std::vector<types::global_dof_index> &new_numbers,
2856 const IndexSet & indices_we_care_about,
2859 const unsigned int dim = 3;
2865 std::vector<bool> saved_line_user_flags;
2868 .save_user_flags_line(saved_line_user_flags);
2871 .clear_user_flags_line();
2875 cell != dof_handler.
end();
2877 if (!cell->is_artificial())
2878 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell;
2880 if (cell->line(l)->user_flag_set() ==
false)
2883 spacedim>::line_iterator
2884 line = cell->line(l);
2885 line->set_user_flag();
2887 const unsigned int n_active_fe_indices =
2888 line->n_active_fe_indices();
2890 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2892 const unsigned int fe_index =
2893 line->nth_active_fe_index(f);
2895 for (
unsigned int d = 0;
2896 d < dof_handler.
get_fe(fe_index).dofs_per_line;
2900 line->dof_index(d, fe_index);
2920 if (indices_we_care_about.
size() == 0)
2921 line->set_dof_index(
2922 d, new_numbers[old_dof_index], fe_index);
2925 line->set_dof_index(
2927 new_numbers[indices_we_care_about
2932 line->set_dof_index(
2943 .load_user_flags_line(saved_line_user_flags);
2948 std::vector<bool> saved_quad_user_flags;
2951 .save_user_flags_quad(saved_quad_user_flags);
2954 .clear_user_flags_quad();
2958 cell != dof_handler.
end();
2960 if (!cell->is_artificial())
2961 for (
unsigned int q = 0; q < GeometryInfo<dim>::quads_per_cell;
2963 if (cell->quad(q)->user_flag_set() ==
false)
2966 spacedim>::quad_iterator
2967 quad = cell->quad(q);
2968 quad->set_user_flag();
2970 const unsigned int n_active_fe_indices =
2971 quad->n_active_fe_indices();
2973 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2975 const unsigned int fe_index =
2976 quad->nth_active_fe_index(f);
2978 for (
unsigned int d = 0;
2979 d < dof_handler.
get_fe(fe_index).dofs_per_quad;
2983 quad->dof_index(d, fe_index);
3003 if (indices_we_care_about.
size() == 0)
3004 quad->set_dof_index(
3005 d, new_numbers[old_dof_index], fe_index);
3010 quad->set_dof_index(
3012 new_numbers[indices_we_care_about
3017 quad->set_dof_index(
3030 .load_user_flags_quad(saved_quad_user_flags);
3047 template <
class DoFHandlerType>
3049 renumber_dofs(
const std::vector<types::global_dof_index> &new_numbers,
3050 const IndexSet &indices_we_care_about,
3051 DoFHandlerType &dof_handler,
3052 const bool check_validity)
3054 if (DoFHandlerType::dimension == 1)
3062 renumber_vertex_dofs(new_numbers,
3063 indices_we_care_about,
3068 renumber_face_dofs(new_numbers, indices_we_care_about, dof_handler);
3071 renumber_cell_dofs(new_numbers, indices_we_care_about, dof_handler);
3076 update_all_active_cell_dof_indices_caches(dof_handler);
3091 template <
int dim,
int spacedim>
3093 renumber_vertex_mg_dofs(
3094 const std::vector<::types::global_dof_index> &new_numbers,
3095 const IndexSet & indices_we_care_about,
3097 const unsigned int level,
3098 const bool check_validity)
3100 (void)check_validity;
3104 for (
typename std::vector<
3110 if ((i->get_coarsest_level() <= level) &&
3111 (i->get_finest_level() >= level))
3112 for (
unsigned int d = 0;
d < dof_handler.
get_fe().dofs_per_vertex;
3115 const ::types::global_dof_index idx =
3118 dof_handler.
get_fe().dofs_per_vertex);
3122 Assert(check_validity ==
false ||
3123 (indices_we_care_about.
size() > 0 ?
3125 (idx < new_numbers.size())),
3129 dof_handler.
get_fe().dofs_per_vertex,
3130 (indices_we_care_about.
size() == 0) ?
3131 (new_numbers[idx]) :
3132 (new_numbers[indices_we_care_about
3147 template <
int dim,
int spacedim>
3149 renumber_cell_mg_dofs(
3150 const std::vector<::types::global_dof_index> &new_numbers,
3151 const IndexSet & indices_we_care_about,
3153 const unsigned int level)
3155 for (std::vector<types::global_dof_index>::iterator i =
3156 dof_handler.mg_levels[level]->dof_object.dofs.begin();
3157 i != dof_handler.mg_levels[level]->dof_object.dofs.end();
3164 (*i < new_numbers.size())),
3167 (indices_we_care_about.
size() == 0) ?
3183 template <
int spacedim>
3185 renumber_face_mg_dofs(
3186 const std::vector<types::global_dof_index> & ,
3189 const unsigned int ,
3197 template <
int spacedim>
3199 renumber_face_mg_dofs(
3200 const std::vector<::types::global_dof_index> &new_numbers,
3201 const IndexSet & indices_we_care_about,
3203 const unsigned int level,
3204 const bool check_validity)
3206 if (dof_handler.
get_fe().dofs_per_line > 0)
3209 std::vector<bool> user_flags;
3213 .clear_user_flags();
3219 typename DoFHandler<2, spacedim>::level_cell_iterator cell,
3220 endc = dof_handler.
end(level);
3221 for (cell = dof_handler.
begin(level); cell != endc; ++cell)
3222 if (cell->level_subdomain_id() !=
3224 for (
unsigned int line = 0;
3225 line < GeometryInfo<2>::faces_per_cell;
3227 cell->face(line)->set_user_flag();
3230 dof_handler.
begin();
3231 cell != dof_handler.
end();
3233 for (
unsigned int l = 0; l < GeometryInfo<2>::lines_per_cell;
3235 if (cell->line(l)->user_flag_set())
3237 for (
unsigned int d = 0;
3238 d < dof_handler.
get_fe().dofs_per_line;
3241 const ::types::global_dof_index idx =
3242 cell->line(l)->mg_dof_index(level, d);
3248 cell->line(l)->set_mg_dof_index(
3251 ((indices_we_care_about.
size() == 0) ?
3253 new_numbers[indices_we_care_about
3254 .index_within_set(idx)]));
3256 cell->line(l)->clear_user_flag();
3261 .load_user_flags(user_flags);
3267 template <
int spacedim>
3269 renumber_face_mg_dofs(
3270 const std::vector<::types::global_dof_index> &new_numbers,
3271 const IndexSet & indices_we_care_about,
3273 const unsigned int level,
3274 const bool check_validity)
3276 if (dof_handler.
get_fe().dofs_per_line > 0 ||
3277 dof_handler.
get_fe().dofs_per_quad > 0)
3280 std::vector<bool> user_flags;
3284 .clear_user_flags();
3289 typename DoFHandler<3, spacedim>::level_cell_iterator cell,
3290 endc = dof_handler.
end(level);
3291 for (cell = dof_handler.
begin(level); cell != endc; ++cell)
3292 if (cell->level_subdomain_id() !=
3294 for (
unsigned int line = 0;
3295 line < GeometryInfo<3>::lines_per_cell;
3297 cell->line(line)->set_user_flag();
3300 dof_handler.
begin();
3301 cell != dof_handler.
end();
3303 for (
unsigned int l = 0; l < GeometryInfo<3>::lines_per_cell;
3305 if (cell->line(l)->user_flag_set())
3307 for (
unsigned int d = 0;
3308 d < dof_handler.
get_fe().dofs_per_line;
3311 const ::types::global_dof_index idx =
3312 cell->line(l)->mg_dof_index(level, d);
3318 cell->line(l)->set_mg_dof_index(
3321 ((indices_we_care_about.
size() == 0) ?
3323 new_numbers[indices_we_care_about
3324 .index_within_set(idx)]));
3326 cell->line(l)->clear_user_flag();
3332 for (cell = dof_handler.
begin(level); cell != endc; ++cell)
3333 if (cell->level_subdomain_id() !=
3335 for (
unsigned int quad = 0;
3336 quad < GeometryInfo<3>::quads_per_cell;
3338 cell->quad(quad)->set_user_flag();
3341 dof_handler.
begin();
3342 cell != dof_handler.
end();
3344 for (
unsigned int l = 0; l < GeometryInfo<3>::quads_per_cell;
3346 if (cell->quad(l)->user_flag_set())
3348 for (
unsigned int d = 0;
3349 d < dof_handler.
get_fe().dofs_per_quad;
3352 const ::types::global_dof_index idx =
3353 cell->quad(l)->mg_dof_index(level, d);
3359 cell->quad(l)->set_mg_dof_index(
3362 ((indices_we_care_about.
size() == 0) ?
3364 new_numbers[indices_we_care_about
3365 .index_within_set(idx)]));
3367 cell->quad(l)->clear_user_flag();
3373 .load_user_flags(user_flags);
3379 template <
int dim,
int spacedim>
3382 const std::vector<::types::global_dof_index> &new_numbers,
3383 const IndexSet & indices_we_care_about,
3385 const unsigned int level,
3386 const bool check_validity)
3396 renumber_vertex_mg_dofs(new_numbers,
3397 indices_we_care_about,
3403 renumber_face_mg_dofs(new_numbers,
3404 indices_we_care_about,
3410 renumber_cell_mg_dofs(new_numbers,
3411 indices_we_care_about,
3420 template <
int dim,
int spacedim>
3423 const std::vector<::types::global_dof_index> & ,
3426 const unsigned int ,
3439 template <
class DoFHandlerType>
3441 : dof_handler(&dof_handler)
3446 template <
class DoFHandlerType>
3455 Implementation::unify_dof_indices(*dof_handler,
3465 template <
class DoFHandlerType>
3466 std::vector<NumberCache>
3469 std::vector<bool> user_flags;
3473 DoFHandlerType::space_dimension
> &>(
3475 .clear_user_flags();
3477 std::vector<NumberCache> number_caches;
3479 for (
unsigned int level = 0;
3485 Implementation::distribute_dofs_on_level(
3489 number_caches.emplace_back(
NumberCache(n_level_dofs));
3493 DoFHandlerType::space_dimension
> &>(
3495 .load_user_flags(user_flags);
3497 return number_caches;
3502 template <
class DoFHandlerType>
3505 const std::vector<types::global_dof_index> &new_numbers)
const 3507 Implementation::renumber_dofs(new_numbers,
3521 *std::max_element(new_numbers.begin(), new_numbers.end()) + 1);
3526 template <
class DoFHandlerType>
3529 const unsigned int level,
3530 const std::vector<types::global_dof_index> &new_numbers)
const 3532 Implementation::renumber_mg_dofs(
3533 new_numbers,
IndexSet(0), *dof_handler, level,
true);
3543 template <
class DoFHandlerType>
3545 DoFHandlerType &dof_handler)
3546 : dof_handler(&dof_handler)
3561 template <
class DoFHandlerType>
3562 std::vector<types::subdomain_id>
3563 get_dof_subdomain_association(
const DoFHandlerType & dof_handler,
3565 const unsigned int n_procs)
3568 std::vector<types::subdomain_id> subdomain_association(
3570 std::vector<types::global_dof_index> local_dof_indices;
3575 typename DoFHandlerType::active_cell_iterator
3577 endc = dof_handler.
end();
3578 for (; cell != endc; ++cell)
3584 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
3585 local_dof_indices.resize(dofs_per_cell);
3586 cell->get_dof_indices(local_dof_indices);
3591 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
3592 if (subdomain_association[local_dof_indices[i]] ==
3594 subdomain_association[local_dof_indices[i]] = subdomain_id;
3595 else if (subdomain_association[local_dof_indices[i]] >
3598 subdomain_association[local_dof_indices[i]] = subdomain_id;
3602 Assert(std::find(subdomain_association.begin(),
3603 subdomain_association.end(),
3605 subdomain_association.end(),
3608 Assert(*std::max_element(subdomain_association.begin(),
3609 subdomain_association.end()) < n_procs,
3612 return subdomain_association;
3622 template <
class DoFHandlerType>
3623 std::vector<types::subdomain_id>
3624 get_dof_level_subdomain_association(
3625 const DoFHandlerType & dof_handler,
3627 const unsigned int n_procs,
3628 const unsigned int level)
3631 std::vector<types::subdomain_id> level_subdomain_association(
3633 std::vector<types::global_dof_index> local_dof_indices;
3638 typename DoFHandlerType::cell_iterator cell =
3639 dof_handler.begin(level),
3640 endc = dof_handler.
end(level);
3641 for (; cell != endc; ++cell)
3647 cell->level_subdomain_id();
3648 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
3649 local_dof_indices.resize(dofs_per_cell);
3650 cell->get_mg_dof_indices(local_dof_indices);
3655 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
3656 if (level_subdomain_association[local_dof_indices[i]] ==
3658 level_subdomain_association[local_dof_indices[i]] =
3660 else if (level_subdomain_association[local_dof_indices[i]] >
3663 level_subdomain_association[local_dof_indices[i]] =
3668 Assert(std::find(level_subdomain_association.begin(),
3669 level_subdomain_association.end(),
3671 level_subdomain_association.end(),
3674 Assert(*std::max_element(level_subdomain_association.begin(),
3675 level_subdomain_association.end()) < n_procs,
3678 return level_subdomain_association;
3684 template <
class DoFHandlerType>
3688 const unsigned int dim = DoFHandlerType::dimension;
3689 const unsigned int spacedim = DoFHandlerType::space_dimension;
3693 &this->dof_handler->get_triangulation()));
3696 const unsigned int n_procs =
3703 std::vector<types::subdomain_id> saved_subdomain_ids;
3708 const std::vector<types::subdomain_id> &true_subdomain_ids =
3713 const unsigned int index = cell->active_cell_index();
3714 saved_subdomain_ids[index] = cell->subdomain_id();
3715 cell->set_subdomain_id(true_subdomain_ids[index]);
3723 *this->dof_handler);
3726 Implementation::unify_dof_indices(*this->dof_handler,
3739 std::vector<types::global_dof_index> new_dof_indices(
3740 n_dofs, enumeration_dof_index);
3744 const std::vector<types::subdomain_id> subdomain_association =
3745 get_dof_subdomain_association(*this->dof_handler, n_dofs, n_procs);
3756 if (subdomain_association[i] == subdomain)
3758 Assert(new_dof_indices[i] == enumeration_dof_index,
3760 new_dof_indices[i] = next_free_index;
3766 Assert(std::find(new_dof_indices.begin(),
3767 new_dof_indices.end(),
3768 enumeration_dof_index) == new_dof_indices.end(),
3775 Implementation::renumber_dofs(new_dof_indices,
3789 const std::vector<types::subdomain_id> subdomain_association =
3790 get_dof_subdomain_association(*this->dof_handler, n_dofs, n_procs);
3792 for (
unsigned int i = 1; i < n_dofs; ++i)
3793 Assert(subdomain_association[i] >= subdomain_association[i - 1],
3796 std::vector<IndexSet> locally_owned_dofs_per_processor(
3807 unsigned int start_index = 0;
3808 unsigned int end_index = 0;
3809 while (start_index < n_dofs)
3811 while ((end_index) < n_dofs &&
3812 (subdomain_association[end_index] ==
3813 subdomain_association[start_index]))
3818 if (end_index > start_index)
3820 const unsigned int subdomain_owner =
3821 subdomain_association[start_index];
3822 locally_owned_dofs_per_processor[subdomain_owner].add_range(
3823 start_index, end_index);
3827 start_index = end_index;
3834 cell->set_subdomain_id(
3835 saved_subdomain_ids[cell->active_cell_index()]);
3840 locally_owned_dofs_per_processor,
3841 this->dof_handler->get_triangulation().locally_owned_subdomain());
3846 template <
class DoFHandlerType>
3847 std::vector<NumberCache>
3850 const unsigned int dim = DoFHandlerType::dimension;
3851 const unsigned int spacedim = DoFHandlerType::space_dimension;
3855 &this->dof_handler->get_triangulation()));
3858 const unsigned int n_procs =
3862 std::vector<NumberCache> number_caches;
3863 number_caches.reserve(n_levels);
3866 for (
unsigned int lvl = 0; lvl < n_levels; ++lvl)
3874 std::vector<types::subdomain_id> saved_level_subdomain_ids;
3875 saved_level_subdomain_ids.resize(tr->
n_cells(lvl));
3878 spacedim>::cell_iterator
3882 const std::vector<types::subdomain_id> &true_level_subdomain_ids =
3885 for (
unsigned int index = 0; cell != endc; ++cell, ++index)
3887 saved_level_subdomain_ids[index] = cell->level_subdomain_id();
3888 cell->set_level_subdomain_id(true_level_subdomain_ids[index]);
3896 Implementation::distribute_dofs_on_level(
3907 std::vector<types::global_dof_index> new_dof_indices(
3912 const std::vector<types::subdomain_id>
3913 level_subdomain_association =
3914 get_dof_level_subdomain_association(*this->dof_handler,
3926 level_subdomain < n_procs;
3929 if (level_subdomain_association[i] == level_subdomain)
3933 new_dof_indices[i] = next_free_index;
3939 Assert(std::find(new_dof_indices.begin(),
3940 new_dof_indices.end(),
3942 new_dof_indices.end(),
3950 Implementation::renumber_mg_dofs(
3951 new_dof_indices,
IndexSet(0), *this->dof_handler, lvl,
true);
3963 const std::vector<types::subdomain_id> level_subdomain_association =
3964 get_dof_level_subdomain_association(*this->dof_handler,
3969 for (
unsigned int i = 1; i < n_dofs_on_level; ++i)
3970 Assert(level_subdomain_association[i] >=
3971 level_subdomain_association[i - 1],
3974 std::vector<IndexSet> locally_owned_dofs_per_processor(
3975 n_procs,
IndexSet(n_dofs_on_level));
3985 unsigned int start_index = 0;
3986 unsigned int end_index = 0;
3987 while (start_index < n_dofs_on_level)
3989 while ((end_index) < n_dofs_on_level &&
3990 (level_subdomain_association[end_index] ==
3991 level_subdomain_association[start_index]))
3996 if (end_index > start_index)
3998 const unsigned int level_subdomain_owner =
3999 level_subdomain_association[start_index];
4000 locally_owned_dofs_per_processor[level_subdomain_owner]
4001 .add_range(start_index, end_index);
4005 start_index = end_index;
4012 spacedim>::cell_iterator
4016 for (
unsigned int index = 0; cell != endc; ++cell, ++index)
4017 cell->set_level_subdomain_id(saved_level_subdomain_ids[index]);
4020 number_caches.emplace_back(
4022 this->dof_handler->get_triangulation()
4023 .locally_owned_subdomain()));
4027 return number_caches;
4032 template <
class DoFHandlerType>
4035 const std::vector<types::global_dof_index> &new_numbers)
const 4037 #ifndef DEAL_II_WITH_MPI 4042 const unsigned int dim = DoFHandlerType::dimension;
4043 const unsigned int spacedim = DoFHandlerType::space_dimension;
4049 &this->dof_handler->get_triangulation()));
4053 spacedim>::active_cell_iterator
4056 std::vector<types::subdomain_id> current_subdomain_ids(
4058 const std::vector<types::subdomain_id> &true_subdomain_ids =
4061 for (
unsigned int index = 0; cell != endc; cell++, index++)
4063 current_subdomain_ids[index] = cell->subdomain_id();
4064 cell->set_subdomain_id(true_subdomain_ids[index]);
4067 std::vector<types::global_dof_index> global_gathered_numbers(
4068 this->dof_handler->n_dofs(), 0);
4073 if (new_numbers.size() == this->dof_handler->n_dofs())
4075 global_gathered_numbers = new_numbers;
4079 Assert(new_numbers.size() ==
4080 this->dof_handler->locally_owned_dofs().n_elements(),
4082 const unsigned int n_cpu =
4084 std::vector<types::global_dof_index> gathered_new_numbers(
4085 this->dof_handler->n_dofs(), 0);
4087 this->dof_handler->get_triangulation()
4088 .locally_owned_subdomain(),
4093 std::vector<types::global_dof_index> new_numbers_copy(
4098 std::vector<int> rcounts(n_cpu);
4102 int cur_count = new_numbers_copy.size();
4103 int ierr = MPI_Allgather(&cur_count,
4114 std::vector<int> displacements(n_cpu);
4115 for (
unsigned int i = 0; i < n_cpu; i++)
4117 displacements[i] = shift;
4118 shift += rcounts[i];
4120 Assert(new_numbers_copy.size() ==
4121 static_cast<unsigned int>(
4125 ierr = MPI_Allgatherv(new_numbers_copy.data(),
4126 new_numbers_copy.size(),
4127 DEAL_II_DOF_INDEX_MPI_TYPE,
4128 gathered_new_numbers.data(),
4130 displacements.data(),
4131 DEAL_II_DOF_INDEX_MPI_TYPE,
4142 std::vector<unsigned int> flag_1(this->dof_handler->n_dofs(), 0);
4143 std::vector<unsigned int> flag_2(this->dof_handler->n_dofs(), 0);
4144 for (
unsigned int i = 0; i < n_cpu; i++)
4147 this->dof_handler->locally_owned_dofs_per_processor()[i];
4154 gathered_new_numbers[shift + ind];
4155 Assert(target < this->dof_handler->n_dofs(),
4157 Assert(value < this->dof_handler->n_dofs(),
4159 global_gathered_numbers[target] = value;
4166 Assert(*std::max_element(flag_1.begin(), flag_1.end()) == 1,
4168 Assert(*std::min_element(flag_1.begin(), flag_1.end()) == 1,
4170 Assert((*std::max_element(flag_2.begin(), flag_2.end())) == 1,
4172 Assert((*std::min_element(flag_2.begin(), flag_2.end())) == 1,
4179 Implementation::renumber_dofs(global_gathered_numbers,
4186 this->dof_handler->get_triangulation().locally_owned_subdomain());
4191 for (
unsigned int index = 0; cell != endc; cell++, index++)
4192 cell->set_subdomain_id(current_subdomain_ids[index]);
4194 return number_cache;
4200 template <
class DoFHandlerType>
4203 const unsigned int ,
4204 const std::vector<types::global_dof_index> & )
const 4216 #ifdef DEAL_II_WITH_P4EST 4236 struct CellDataTransferBuffer
4238 std::vector<unsigned int> tree_indices;
4239 std::vector<typename ::internal::p4est::types<dim>::quadrant>
4241 std::vector<::types::global_dof_index> dof_numbers_and_indices;
4248 template <
class Archive>
4250 save(Archive &ar,
const unsigned int )
const 4256 std::vector<char> quadrants_as_chars(
sizeof(quadrants[0]) *
4258 if (quadrants_as_chars.size() > 0)
4261 std::memcpy(quadrants_as_chars.data(),
4263 quadrants_as_chars.size());
4267 ar &quadrants_as_chars &tree_indices &dof_numbers_and_indices;
4274 template <
class Archive>
4276 load(Archive &ar,
const unsigned int )
4279 std::vector<char> quadrants_as_chars;
4280 ar &quadrants_as_chars &tree_indices &dof_numbers_and_indices;
4282 if (quadrants_as_chars.size() > 0)
4284 quadrants.resize(quadrants_as_chars.size() /
4285 sizeof(quadrants[0]));
4286 std::memcpy(quadrants.data(),
4287 quadrants_as_chars.data(),
4288 quadrants_as_chars.size());
4294 BOOST_SERIALIZATION_SPLIT_MEMBER()
4306 std::vector<char> buffer;
4308 # ifdef DEAL_II_WITH_ZLIB 4309 boost::iostreams::filtering_ostream out;
4311 boost::iostreams::gzip_compressor(boost::iostreams::gzip_params(
4312 boost::iostreams::gzip::best_compression)));
4313 out.push(boost::iostreams::back_inserter(buffer));
4315 boost::archive::binary_oarchive archive(out);
4320 std::ostringstream out;
4321 boost::archive::binary_oarchive archive(out);
4323 const std::string &s = out.str();
4324 buffer.reserve(s.size());
4325 buffer.assign(s.begin(), s.end());
4339 unpack_data(
const std::vector<char> &buffer)
4341 std::string decompressed_buffer;
4345 # ifdef DEAL_II_WITH_ZLIB 4346 boost::iostreams::filtering_ostream decompressing_stream;
4347 decompressing_stream.push(boost::iostreams::gzip_decompressor());
4348 decompressing_stream.push(
4349 boost::iostreams::back_inserter(decompressed_buffer));
4350 decompressing_stream.write(buffer.data(), buffer.size());
4352 decompressed_buffer.assign(buffer.begin(), buffer.end());
4357 std::istringstream in(decompressed_buffer);
4358 boost::archive::binary_iarchive archive(in);
4366 template <
int dim,
int spacedim>
4368 get_mg_dofindices_recursively(
4370 const typename ::internal::p4est::types<dim>::quadrant
4372 const typename DoFHandler<dim, spacedim>::level_cell_iterator
4374 const typename ::internal::p4est::types<dim>::quadrant
4376 CellDataTransferBuffer<dim> &cell_data_transfer_buffer)
4378 if (internal::p4est::quadrant_is_equal<dim>(p4est_cell, quadrant))
4381 Assert(dealii_cell->level_subdomain_id() ==
4386 std::vector<::types::global_dof_index> local_dof_indices(
4387 dealii_cell->
get_fe().dofs_per_cell);
4388 dealii_cell->get_mg_dof_indices(local_dof_indices);
4390 cell_data_transfer_buffer.dof_numbers_and_indices.push_back(
4391 dealii_cell->
get_fe().dofs_per_cell);
4392 cell_data_transfer_buffer.dof_numbers_and_indices.insert(
4393 cell_data_transfer_buffer.dof_numbers_and_indices.end(),
4394 local_dof_indices.begin(),
4395 local_dof_indices.end());
4399 if (!dealii_cell->has_children())
4402 if (!internal::p4est::quadrant_is_ancestor<dim>(p4est_cell, quadrant))
4405 typename ::internal::p4est::types<dim>::quadrant
4407 internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
4409 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
4411 get_mg_dofindices_recursively<dim, spacedim>(
4414 dealii_cell->child(c),
4416 cell_data_transfer_buffer);
4420 template <
int dim,
int spacedim>
4422 find_marked_mg_ghost_cells_recursively(
4425 const unsigned int tree_index,
4426 const typename DoFHandler<dim, spacedim>::level_cell_iterator
4428 const typename ::internal::p4est::types<dim>::quadrant
4431 &neighbor_cell_list)
4434 if (dealii_cell->has_children())
4436 typename ::internal::p4est::types<dim>::quadrant
4438 internal::p4est::init_quadrant_children<dim>(p4est_cell,
4442 for (
unsigned int c = 0;
4443 c < GeometryInfo<dim>::max_children_per_cell;
4445 find_marked_mg_ghost_cells_recursively<dim, spacedim>(
4448 dealii_cell->child(c),
4450 neighbor_cell_list);
4453 if (dealii_cell->user_flag_set() &&
4454 dealii_cell->level_subdomain_id() !=
4457 neighbor_cell_list[dealii_cell->level_subdomain_id()]
4458 .tree_indices.push_back(tree_index);
4459 neighbor_cell_list[dealii_cell->level_subdomain_id()]
4460 .quadrants.push_back(p4est_cell);
4465 template <
int dim,
int spacedim>
4467 set_mg_dofindices_recursively(
4469 const typename ::internal::p4est::types<dim>::quadrant
4471 const typename DoFHandler<dim, spacedim>::level_cell_iterator
4473 const typename ::internal::p4est::types<dim>::quadrant
4477 if (internal::p4est::quadrant_is_equal<dim>(p4est_cell, quadrant))
4479 Assert(dealii_cell->level_subdomain_id() !=
4480 ::numbers::artificial_subdomain_id,
4484 std::vector<::types::global_dof_index> dof_indices(
4485 dealii_cell->
get_fe().dofs_per_cell);
4486 dealii_cell->get_mg_dof_indices(dof_indices);
4488 bool complete =
true;
4489 for (
unsigned int i = 0; i < dof_indices.size(); ++i)
4493 (dof_indices[i] == dofs[i]),
4495 dof_indices[i] = dofs[i];
4502 typename DoFHandler<dim, spacedim>::level_cell_iterator &
>(
4507 typename DoFHandler<dim, spacedim>::level_cell_iterator &
>(
4509 ->clear_user_flag();
4512 typename DoFHandler<dim, spacedim>::level_cell_iterator &
>(
4514 ->set_mg_dof_indices(dof_indices);
4518 if (!dealii_cell->has_children())
4521 if (!internal::p4est::quadrant_is_ancestor<dim>(p4est_cell, quadrant))
4524 typename ::internal::p4est::types<dim>::quadrant
4526 internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
4528 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
4530 set_mg_dofindices_recursively<dim, spacedim>(
4531 tria, p4est_child[c], dealii_cell->child(c), quadrant, dofs);
4536 template <
int dim,
int spacedim,
class DoFHandlerType>
4538 communicate_mg_ghost_cells(
4541 DoFHandlerType &dof_handler,
4542 const std::vector<::types::global_dof_index>
4543 &coarse_cell_to_p4est_tree_permutation,
4544 const std::vector<::types::global_dof_index>
4545 &p4est_tree_to_coarse_cell_permutation)
4548 std::set<::types::subdomain_id> level_ghost_owners =
4551 std::map<::types::subdomain_id, CellDataTransferBuffer<dim>>;
4552 cellmap_t neighbor_cell_list;
4553 for (
const auto level_ghost_owner : level_ghost_owners)
4554 neighbor_cell_list.insert(
4555 std::make_pair(level_ghost_owner, CellDataTransferBuffer<dim>()));
4557 for (
typename DoFHandlerType::level_cell_iterator cell =
4558 dof_handler.begin(0);
4559 cell != dof_handler.end(0);
4562 typename ::internal::p4est::types<dim>::quadrant
4564 internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
4566 find_marked_mg_ghost_cells_recursively<dim, spacedim>(
4568 coarse_cell_to_p4est_tree_permutation[cell->index()],
4571 neighbor_cell_list);
4573 Assert(level_ghost_owners.size() == neighbor_cell_list.size(),
4577 std::vector<std::vector<char>> sendbuffers(level_ghost_owners.size());
4578 std::vector<MPI_Request> requests(level_ghost_owners.size());
4580 unsigned int idx = 0;
4581 for (
typename cellmap_t::iterator it = neighbor_cell_list.begin();
4582 it != neighbor_cell_list.end();
4588 sendbuffers[idx] = it->second.pack_data();
4589 const int ierr = MPI_Isend(sendbuffers[idx].data(),
4590 sendbuffers[idx].size(),
4594 tria.get_communicator(),
4600 std::vector<std::vector<char>> reply_buffers(
4601 level_ghost_owners.size());
4602 std::vector<MPI_Request> reply_requests(level_ghost_owners.size());
4604 for (
unsigned int idx = 0; idx < level_ghost_owners.size(); ++idx)
4606 std::vector<char> receive;
4607 CellDataTransferBuffer<dim> cell_data_transfer_buffer;
4611 int ierr = MPI_Probe(MPI_ANY_SOURCE,
4613 tria.get_communicator(),
4616 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
4618 receive.resize(len);
4620 char *ptr = receive.data();
4621 ierr = MPI_Recv(ptr,
4626 tria.get_communicator(),
4630 cell_data_transfer_buffer.unpack_data(receive);
4633 for (
unsigned int c = 0;
4634 c < cell_data_transfer_buffer.tree_indices.size();
4637 typename DoFHandlerType::level_cell_iterator cell(
4638 &dof_handler.get_triangulation(),
4640 p4est_tree_to_coarse_cell_permutation
4641 [cell_data_transfer_buffer.tree_indices[c]],
4644 typename ::internal::p4est::types<dim>::quadrant
4646 internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
4648 get_mg_dofindices_recursively<dim, spacedim>(
4652 cell_data_transfer_buffer.quadrants[c],
4653 cell_data_transfer_buffer);
4657 reply_buffers[idx] = cell_data_transfer_buffer.pack_data();
4658 ierr = MPI_Isend(reply_buffers[idx].data(),
4659 reply_buffers[idx].size(),
4663 tria.get_communicator(),
4664 &reply_requests[idx]);
4669 for (
unsigned int idx = 0; idx < level_ghost_owners.size(); ++idx)
4671 std::vector<char> receive;
4672 CellDataTransferBuffer<dim> cell_data_transfer_buffer;
4676 int ierr = MPI_Probe(MPI_ANY_SOURCE,
4678 tria.get_communicator(),
4681 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
4683 receive.resize(len);
4685 char *ptr = receive.data();
4686 ierr = MPI_Recv(ptr,
4691 tria.get_communicator(),
4695 cell_data_transfer_buffer.unpack_data(receive);
4696 if (cell_data_transfer_buffer.tree_indices.size() == 0)
4701 cell_data_transfer_buffer.dof_numbers_and_indices.data();
4702 for (
unsigned int c = 0;
4703 c < cell_data_transfer_buffer.tree_indices.size();
4704 ++c, dofs += 1 + dofs[0])
4706 typename DoFHandlerType::level_cell_iterator cell(
4709 p4est_tree_to_coarse_cell_permutation
4710 [cell_data_transfer_buffer.tree_indices[c]],
4713 typename ::internal::p4est::types<dim>::quadrant
4715 internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
4717 Assert(cell->get_fe().dofs_per_cell == dofs[0],
4720 set_mg_dofindices_recursively<dim, spacedim>(
4724 cell_data_transfer_buffer.quadrants[c],
4731 if (requests.size() > 0)
4733 const int ierr = MPI_Waitall(requests.size(),
4735 MPI_STATUSES_IGNORE);
4738 if (reply_requests.size() > 0)
4740 const int ierr = MPI_Waitall(reply_requests.size(),
4741 reply_requests.data(),
4742 MPI_STATUSES_IGNORE);
4749 template <
int spacedim>
4751 communicate_mg_ghost_cells(
4754 const std::vector<::types::global_dof_index> &,
4755 const std::vector<::types::global_dof_index> &)
4762 template <
int spacedim>
4764 communicate_mg_ghost_cells(
4767 const std::vector<::types::global_dof_index> &,
4768 const std::vector<::types::global_dof_index> &)
4793 template <
int spacedim>
4795 communicate_dof_indices_on_marked_cells(
4797 const std::map<
unsigned int, std::set<::types::subdomain_id>> &,
4798 const std::vector<::types::global_dof_index> &,
4799 const std::vector<::types::global_dof_index> &)
4806 template <
int spacedim>
4808 communicate_dof_indices_on_marked_cells(
4810 const std::map<
unsigned int, std::set<::types::subdomain_id>> &,
4811 const std::vector<::types::global_dof_index> &,
4812 const std::vector<::types::global_dof_index> &)
4819 template <
class DoFHandlerType>
4821 communicate_dof_indices_on_marked_cells(
4822 const DoFHandlerType &dof_handler,
4823 const std::map<
unsigned int, std::set<::types::subdomain_id>> &,
4824 const std::vector<::types::global_dof_index> &,
4825 const std::vector<::types::global_dof_index> &)
4827 # ifndef DEAL_II_WITH_MPI 4828 (void)vertices_with_ghost_neighbors;
4831 const unsigned int dim = DoFHandlerType::dimension;
4832 const unsigned int spacedim = DoFHandlerType::space_dimension;
4838 [](
const typename DoFHandlerType::active_cell_iterator &cell)
4839 -> boost::optional<std::vector<types::global_dof_index>> {
4846 if (cell->user_flag_set())
4849 std::vector<types::global_dof_index> local_dof_indices(
4850 cell->get_fe().dofs_per_cell);
4851 cell->get_dof_indices(local_dof_indices);
4860 if (std::find(local_dof_indices.begin(),
4861 local_dof_indices.end(),
4863 local_dof_indices.end())
4868 cell->clear_user_flag();
4870 return local_dof_indices;
4879 std::vector<types::global_dof_index> local_dof_indices(
4880 cell->get_fe().dofs_per_cell);
4881 cell->get_dof_indices(local_dof_indices);
4883 const bool is_complete =
4884 (std::find(local_dof_indices.begin(),
4885 local_dof_indices.end(),
4887 local_dof_indices.end());
4890 return boost::optional<std::vector<types::global_dof_index>>();
4895 [](
const typename DoFHandlerType::active_cell_iterator &cell,
4896 const std::vector<types::global_dof_index> &received_dof_indices)
4912 const bool is_complete = (std::find(received_dof_indices.begin(),
4913 received_dof_indices.end(),
4915 received_dof_indices.end());
4917 cell->clear_user_flag();
4931 std::vector<types::global_dof_index> local_dof_indices(
4932 cell->get_fe().dofs_per_cell);
4933 cell->update_cell_dof_indices_cache();
4934 cell->get_dof_indices(local_dof_indices);
4936 for (
unsigned int i = 0; i < local_dof_indices.size(); ++i)
4938 local_dof_indices[i] = received_dof_indices[i];
4942 Assert((received_dof_indices[i] ==
4944 (received_dof_indices[i] == local_dof_indices[i]),
4947 const_cast<typename DoFHandlerType::active_cell_iterator &
>(cell)
4948 ->set_dof_indices(local_dof_indices);
4952 std::vector<types::global_dof_index>,
4957 update_all_active_cell_dof_indices_caches(dof_handler);
4973 if (
const auto *triangulation =
dynamic_cast< 4975 &dof_handler.get_triangulation()))
4977 const int ierr = MPI_Barrier(triangulation->get_communicator());
4984 "The function communicate_dof_indices_on_marked_cells() " 4985 "only works with parallel distributed triangulations."));
4994 #endif // DEAL_II_WITH_P4EST 4998 template <
class DoFHandlerType>
5000 DoFHandlerType &dof_handler)
5001 : dof_handler(&dof_handler)
5006 template <
class DoFHandlerType>
5010 #ifndef DEAL_II_WITH_P4EST 5014 const unsigned int dim = DoFHandlerType::dimension;
5015 const unsigned int spacedim = DoFHandlerType::space_dimension;
5020 &dof_handler->get_triangulation())));
5023 const unsigned int n_cpus =
5027 triangulation->locally_owned_subdomain();
5056 Implementation::distribute_dofs(subdomain_id, *dof_handler);
5062 std::vector<::types::global_dof_index> renumbering(
5063 n_initial_local_dofs, enumeration_dof_index);
5069 invalidate_dof_indices_on_weaker_ghost_cells_for_renumbering(
5070 renumbering, subdomain_id, *dof_handler);
5073 std::vector<std::map<types::global_dof_index, types::global_dof_index>>
5074 all_constrained_indices(dim);
5075 Implementation::compute_dof_identities(all_constrained_indices,
5089 Implementation::enumerate_dof_indices_for_renumbering(
5090 renumbering, all_constrained_indices, *dof_handler);
5094 std::vector<::types::global_dof_index>
5095 n_locally_owned_dofs_per_processor(n_cpus);
5098 MPI_Allgather(DEAL_II_MPI_CONST_CAST(&n_locally_owned_dofs),
5100 DEAL_II_DOF_INDEX_MPI_TYPE,
5101 n_locally_owned_dofs_per_processor.data(),
5103 DEAL_II_DOF_INDEX_MPI_TYPE,
5104 triangulation->get_communicator());
5107 const ::types::global_dof_index my_shift =
5108 std::accumulate(n_locally_owned_dofs_per_processor.begin(),
5109 n_locally_owned_dofs_per_processor.begin() +
5114 for (
auto &new_index : renumbering)
5116 new_index += my_shift;
5121 Implementation::renumber_dofs(renumbering,
5127 const ::types::global_dof_index n_global_dofs =
5128 std::accumulate(n_locally_owned_dofs_per_processor.begin(),
5129 n_locally_owned_dofs_per_processor.end(),
5132 std::vector<IndexSet> locally_owned_dofs_per_processor(
5136 for (
unsigned int i = 0; i < n_cpus; ++i)
5138 locally_owned_dofs_per_processor[i].add_range(
5140 current_shift + n_locally_owned_dofs_per_processor[i]);
5141 current_shift += n_locally_owned_dofs_per_processor[i];
5144 NumberCache number_cache(locally_owned_dofs_per_processor,
5145 triangulation->locally_owned_subdomain());
5147 .locally_owned_dofs_per_processor
5148 [triangulation->locally_owned_subdomain()]
5149 .n_elements() == number_cache.n_locally_owned_dofs,
5153 .locally_owned_dofs_per_processor[triangulation
5154 ->locally_owned_subdomain()]
5157 .locally_owned_dofs_per_processor[triangulation
5158 ->locally_owned_subdomain()]
5159 .nth_index_in_set(0) == my_shift,
5170 std::vector<bool> user_flags;
5171 triangulation->save_user_flags(user_flags);
5172 triangulation->clear_user_flags();
5176 const std::map<unsigned int, std::set<::types::subdomain_id>>
5177 vertices_with_ghost_neighbors =
5178 triangulation->compute_vertices_with_ghost_neighbors();
5183 for (
const auto &cell : dof_handler->active_cell_iterators())
5184 if (cell->is_locally_owned())
5186 for (
unsigned int v = 0;
5187 v < GeometryInfo<dim>::vertices_per_cell;
5189 if (vertices_with_ghost_neighbors.find(cell->vertex_index(
5190 v)) != vertices_with_ghost_neighbors.end())
5192 cell->set_user_flag();
5196 else if (cell->is_ghost())
5197 cell->set_user_flag();
5207 communicate_dof_indices_on_marked_cells(
5209 vertices_with_ghost_neighbors,
5210 triangulation->coarse_cell_to_p4est_tree_permutation,
5211 triangulation->p4est_tree_to_coarse_cell_permutation);
5218 Implementation::merge_invalid_dof_indices_on_ghost_interfaces(
5225 communicate_dof_indices_on_marked_cells(
5227 vertices_with_ghost_neighbors,
5228 triangulation->coarse_cell_to_p4est_tree_permutation,
5229 triangulation->p4est_tree_to_coarse_cell_permutation);
5234 for (
const auto &cell : dof_handler->active_cell_iterators())
5238 triangulation->load_user_flags(user_flags);
5244 std::vector<::types::global_dof_index> local_dof_indices;
5246 for (
const auto &cell : dof_handler->active_cell_iterators())
5247 if (!cell->is_artificial())
5249 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
5250 cell->get_dof_indices(local_dof_indices);
5251 if (local_dof_indices.end() !=
5252 std::find(local_dof_indices.begin(),
5253 local_dof_indices.end(),
5256 if (cell->is_ghost())
5260 "A ghost cell ended up with incomplete " 5261 "DoF index information. This should not " 5269 "A locally owned cell ended up with incomplete " 5270 "DoF index information. This should not " 5277 return number_cache;
5278 #endif // DEAL_II_WITH_P4EST 5283 template <
class DoFHandlerType>
5284 std::vector<NumberCache>
5287 #ifndef DEAL_II_WITH_P4EST 5289 return std::vector<NumberCache>();
5291 const unsigned int dim = DoFHandlerType::dimension;
5292 const unsigned int spacedim = DoFHandlerType::space_dimension;
5297 &dof_handler->get_triangulation())));
5302 construct_multigrid_hierarchy),
5304 "Multigrid DoFs can only be distributed on a parallel " 5305 "Triangulation if the flag construct_multigrid_hierarchy " 5306 "is set in the constructor."));
5309 const unsigned int n_cpus =
5317 const unsigned int n_levels = triangulation->n_global_levels();
5318 std::vector<NumberCache> number_caches;
5319 number_caches.reserve(n_levels);
5320 for (
unsigned int level = 0; level < n_levels; ++level)
5325 const unsigned int n_initial_local_dofs =
5326 Implementation::distribute_dofs_on_level(
5327 triangulation->locally_owned_subdomain(), *dof_handler, level);
5331 std::vector<::types::global_dof_index> renumbering(
5332 n_initial_local_dofs);
5337 if (level < triangulation->n_levels())
5339 std::vector<::types::global_dof_index> local_dof_indices;
5341 typename DoFHandlerType::level_cell_iterator
5342 cell = dof_handler->begin(level),
5343 endc = dof_handler->
end(level);
5345 for (; cell != endc; ++cell)
5346 if (cell->level_subdomain_id() !=
5348 (cell->level_subdomain_id() <
5349 triangulation->locally_owned_subdomain()))
5358 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
5359 cell->get_mg_dof_indices(local_dof_indices);
5360 for (
unsigned int i = 0; i < cell->get_fe().dofs_per_cell;
5363 renumbering[local_dof_indices[i]] =
5380 int ierr = MPI_Allgather(
5383 DEAL_II_DOF_INDEX_MPI_TYPE,
5386 DEAL_II_DOF_INDEX_MPI_TYPE,
5387 triangulation->get_communicator());
5390 const ::types::global_dof_index shift = std::accumulate(
5393 triangulation->locally_owned_subdomain(),
5407 if (level < triangulation->n_levels())
5408 Implementation::renumber_mg_dofs(
5409 renumbering,
IndexSet(0), *dof_handler, level,
false);
5427 for (
unsigned int i = 0; i < n_cpus; ++i)
5432 .add_range(current_shift,
5435 .n_locally_owned_dofs_per_processor[i]);
5440 Assert(level_number_cache
5441 .locally_owned_dofs_per_processor
5442 [triangulation->locally_owned_subdomain()]
5445 Assert(!level_number_cache
5446 .locally_owned_dofs_per_processor
5447 [triangulation->locally_owned_subdomain()]
5451 [triangulation->locally_owned_subdomain()]
5452 .nth_index_in_set(0) == shift,
5455 number_caches.emplace_back(level_number_cache);
5464 std::vector<bool> user_flags;
5465 triangulation->save_user_flags(user_flags);
5466 triangulation->clear_user_flags();
5470 typename DoFHandlerType::level_cell_iterator cell,
5471 endc = dof_handler->
end();
5472 for (cell = dof_handler->begin(); cell != endc; ++cell)
5473 if (cell->level_subdomain_id() !=
5474 ::numbers::artificial_subdomain_id &&
5475 !cell->is_locally_owned_on_level())
5476 cell->set_user_flag();
5482 communicate_mg_ghost_cells(
5485 triangulation->coarse_cell_to_p4est_tree_permutation,
5486 triangulation->p4est_tree_to_coarse_cell_permutation);
5501 const int ierr = MPI_Barrier(triangulation->get_communicator());
5506 communicate_mg_ghost_cells(
5509 triangulation->coarse_cell_to_p4est_tree_permutation,
5510 triangulation->p4est_tree_to_coarse_cell_permutation);
5515 typename DoFHandlerType::level_cell_iterator cell,
5516 endc = dof_handler->
end();
5517 for (cell = dof_handler->begin(); cell != endc; ++cell)
5518 if (cell->level_subdomain_id() !=
5519 ::numbers::artificial_subdomain_id &&
5520 !cell->is_locally_owned_on_level())
5525 triangulation->load_user_flags(user_flags);
5533 std::vector<::types::global_dof_index> local_dof_indices;
5534 typename DoFHandlerType::level_cell_iterator cell,
5535 endc = dof_handler->
end();
5537 for (cell = dof_handler->begin(); cell != endc; ++cell)
5538 if (cell->level_subdomain_id() !=
5539 ::numbers::artificial_subdomain_id)
5541 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
5542 cell->get_mg_dof_indices(local_dof_indices);
5543 if (local_dof_indices.end() !=
5544 std::find(local_dof_indices.begin(),
5545 local_dof_indices.end(),
5554 return number_caches;
5556 #endif // DEAL_II_WITH_P4EST 5560 template <
class DoFHandlerType>
5563 const std::vector<::types::global_dof_index> &new_numbers)
const 5567 Assert(new_numbers.size() == dof_handler->n_locally_owned_dofs(),
5570 #ifndef DEAL_II_WITH_P4EST 5574 const unsigned int dim = DoFHandlerType::dimension;
5575 const unsigned int spacedim = DoFHandlerType::space_dimension;
5580 &dof_handler->get_triangulation())));
5588 bool locally_owned_set_changes =
false;
5590 if (dof_handler->locally_owned_dofs().is_element(i) ==
false)
5592 locally_owned_set_changes =
true;
5597 locally_owned_set_changes),
5598 triangulation->get_communicator()) == 0)
5610 std::vector<types::global_dof_index> ghosted_new_numbers(
5614 dof_handler->locally_owned_dofs(),
5616 triangulation->get_communicator());
5621 const unsigned int communication_channel = 19;
5622 std::vector<types::global_dof_index> temp_array(
5623 partitioner.n_import_indices());
5624 std::vector<MPI_Request> requests;
5626 communication_channel,
5627 make_array_view(new_numbers),
5628 make_array_view(temp_array),
5630 ghosted_new_numbers.data() + new_numbers.size(),
5631 partitioner.n_ghost_indices()),
5633 partitioner.export_to_ghosted_array_finish(
5635 ghosted_new_numbers.data() + new_numbers.size(),
5636 partitioner.n_ghost_indices()),
5644 unsigned int n_ghosts_on_smaller_ranks = 0;
5645 for (std::pair<unsigned int, unsigned int> t :
5646 partitioner.ghost_targets())
5648 if (t.first > partitioner.this_mpi_process())
5650 n_ghosts_on_smaller_ranks += t.second;
5652 if (n_ghosts_on_smaller_ranks > 0)
5654 Assert(ghosted_new_numbers.data() !=
nullptr,
5656 std::memmove(ghosted_new_numbers.data(),
5657 ghosted_new_numbers.data() + new_numbers.size(),
5659 n_ghosts_on_smaller_ranks);
5661 if (new_numbers.size() > 0)
5664 std::memcpy(ghosted_new_numbers.data() +
5665 n_ghosts_on_smaller_ranks,
5668 new_numbers.size());
5677 Implementation::renumber_dofs(ghosted_new_numbers,
5684 return NumberCache(dof_handler->locally_owned_dofs_per_processor(),
5686 triangulation->get_communicator()));
5700 IndexSet my_locally_owned_new_dof_indices(dof_handler->n_dofs());
5701 if (dof_handler->n_locally_owned_dofs() > 0)
5703 std::vector<::types::global_dof_index>
5704 new_numbers_sorted = new_numbers;
5705 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
5708 new_numbers_sorted.begin(), new_numbers_sorted.end());
5709 my_locally_owned_new_dof_indices.compress();
5711 Assert(my_locally_owned_new_dof_indices.n_elements() ==
5728 std::vector<::types::global_dof_index> local_dof_indices;
5730 for (
auto cell : dof_handler->active_cell_iterators())
5731 if (cell->is_ghost())
5733 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
5734 cell->get_dof_indices(local_dof_indices);
5736 for (
unsigned int i = 0; i < cell->get_fe().dofs_per_cell;
5741 if ((local_dof_indices[i] !=
5743 (!dof_handler->locally_owned_dofs().is_element(
5744 local_dof_indices[i])))
5747 cell->set_dof_indices(local_dof_indices);
5753 if (dof_handler->locally_owned_dofs().n_elements() > 0)
5754 Implementation::renumber_dofs(new_numbers,
5755 dof_handler->locally_owned_dofs(),
5766 std::vector<bool> user_flags;
5767 triangulation->save_user_flags(user_flags);
5768 triangulation->clear_user_flags();
5771 for (
const auto &cell : dof_handler->active_cell_iterators())
5772 if (!cell->is_artificial())
5773 cell->set_user_flag();
5777 const std::map<
unsigned int,
5778 std::set<::types::subdomain_id>>
5779 vertices_with_ghost_neighbors =
5780 triangulation->compute_vertices_with_ghost_neighbors();
5789 communicate_dof_indices_on_marked_cells(
5791 vertices_with_ghost_neighbors,
5792 triangulation->coarse_cell_to_p4est_tree_permutation,
5793 triangulation->p4est_tree_to_coarse_cell_permutation);
5800 Implementation::merge_invalid_dof_indices_on_ghost_interfaces(
5803 communicate_dof_indices_on_marked_cells(
5805 vertices_with_ghost_neighbors,
5806 triangulation->coarse_cell_to_p4est_tree_permutation,
5807 triangulation->p4est_tree_to_coarse_cell_permutation);
5809 triangulation->load_user_flags(user_flags);
5824 triangulation->get_communicator());
5825 std::vector<IndexSet> locally_owned_dofs_per_processor(
5826 n_cpus,
IndexSet(dof_handler->n_dofs()));
5828 std::vector<char> my_data;
5830 # ifdef DEAL_II_WITH_ZLIB 5832 boost::iostreams::filtering_ostream out;
5834 boost::iostreams::gzip_compressor(boost::iostreams::gzip_params(
5835 boost::iostreams::gzip::best_compression)));
5836 out.push(boost::iostreams::back_inserter(my_data));
5838 boost::archive::binary_oarchive archive(out);
5840 archive << my_locally_owned_new_dof_indices;
5843 std::ostringstream out;
5844 boost::archive::binary_oarchive archive(out);
5845 archive << my_locally_owned_new_dof_indices;
5846 const std::string &s = out.str();
5847 my_data.reserve(s.size());
5848 my_data.assign(s.begin(), s.end());
5853 const unsigned int max_size =
5855 triangulation->get_communicator());
5860 my_data.resize(max_size);
5862 std::vector<char> buffer(max_size * n_cpus);
5863 const int ierr = MPI_Allgather(my_data.data(),
5869 triangulation->get_communicator());
5872 for (
unsigned int i = 0; i < n_cpus; ++i)
5874 triangulation->get_communicator()))
5875 locally_owned_dofs_per_processor[i] =
5876 my_locally_owned_new_dof_indices;
5881 std::string decompressed_buffer;
5885 # ifdef DEAL_II_WITH_ZLIB 5887 boost::iostreams::filtering_ostream decompressing_stream;
5888 decompressing_stream.push(
5889 boost::iostreams::gzip_decompressor());
5890 decompressing_stream.push(
5891 boost::iostreams::back_inserter(decompressed_buffer));
5893 decompressing_stream.write(&buffer[i * max_size], max_size);
5895 decompressed_buffer.assign(&buffer[i * max_size], max_size);
5900 std::istringstream in(decompressed_buffer);
5901 boost::archive::binary_iarchive archive(in);
5903 archive >> locally_owned_dofs_per_processor[i];
5906 return NumberCache(locally_owned_dofs_per_processor,
5908 triangulation->get_communicator()));
5915 template <
class DoFHandlerType>
5918 const unsigned int level,
5919 const std::vector<types::global_dof_index> &new_numbers)
const 5924 const std::vector<IndexSet> &index_sets =
5925 dof_handler->locally_owned_mg_dofs_per_processor(level);
5927 constexpr
int dim = DoFHandlerType::dimension;
5928 constexpr
int spacedim = DoFHandlerType::space_dimension;
5931 &this->dof_handler->get_triangulation()));
5934 #ifdef DEAL_II_WITH_MPI 5935 const unsigned int my_rank =
5941 Assert(index_sets[my_rank].is_element(i),
5943 "Renumberings that change the locally owned mg dofs " 5944 "partitioning are currently not implemented for " 5945 "the multigrid levels"));
5956 std::vector<types::global_dof_index> ghosted_new_numbers(
5962 std::vector<types::global_dof_index> temp_array(
5963 partitioner.n_import_indices());
5964 const unsigned int communication_channel = 17;
5965 std::vector<MPI_Request> requests;
5967 communication_channel,
5968 make_array_view(new_numbers),
5969 make_array_view(temp_array),
5972 partitioner.n_ghost_indices()),
5974 partitioner.export_to_ghosted_array_finish(
5977 partitioner.n_ghost_indices()),
5984 unsigned int n_ghosts_on_smaller_ranks = 0;
5985 for (std::pair<unsigned int, unsigned int> t :
5986 partitioner.ghost_targets())
5988 if (t.first > my_rank)
5990 n_ghosts_on_smaller_ranks += t.second;
5992 if (n_ghosts_on_smaller_ranks > 0)
5995 std::memmove(ghosted_new_numbers.data(),
5996 ghosted_new_numbers.data() + new_numbers.size(),
5998 n_ghosts_on_smaller_ranks);
6000 if (new_numbers.size() > 0)
6003 std::memcpy(ghosted_new_numbers.data() +
6004 n_ghosts_on_smaller_ranks,
6012 if (level < this->dof_handler->get_triangulation().n_levels() &&
6014 Implementation::renumber_mg_dofs(
6015 ghosted_new_numbers, relevant_dofs, *dof_handler, level,
true);
6031 #include "dof_handler_policy.inst" 6034 DEAL_II_NAMESPACE_CLOSE
unsigned int n_active_cells() const
void get_active_fe_indices(std::vector< unsigned int > &active_fe_indices) const
std::vector< MGVertexDoFs > mg_vertex_dofs
const Triangulation< dim, spacedim > & get_triangulation() const
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const override
static const unsigned int invalid_unsigned_int
const types::subdomain_id invalid_subdomain_id
cell_iterator begin(const unsigned int level=0) const
types::subdomain_id locally_owned_subdomain() const override
typename ActiveSelector::quad_iterator quad_iterator
unsigned int n_cells() const
size_type nth_index_in_set(const unsigned int local_index) const
Task< RT > new_task(const std::function< RT()> &function)
virtual NumberCache distribute_dofs() const override
const std::vector< types::subdomain_id > & get_true_subdomain_ids_of_cells() const
IteratorRange< active_cell_iterator > active_cell_iterators() const
const hp::FECollection< dim, spacedim > & get_fe() const
cell_iterator end() const
IndexSet locally_owned_dofs
const unsigned int dofs_per_quad
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
active_cell_iterator begin_active(const unsigned int level=0) const
active_cell_iterator begin_active(const unsigned int level=0) const
#define AssertThrow(cond, exc)
const unsigned int dofs_per_line
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
const std::vector< types::subdomain_id > & get_true_level_subdomain_ids_of_cells(const unsigned int level) const
virtual std::vector< NumberCache > distribute_mg_dofs() const override
typename ActiveSelector::active_cell_iterator active_cell_iterator
active_cell_iterator begin_active(const unsigned int level=0) const
types::global_dof_index n_locally_owned_dofs
virtual std::vector< NumberCache > distribute_mg_dofs() const override
static ::ExceptionBase & ExcMessage(std::string arg1)
typename ActiveSelector::quad_iterator quad_iterator
ParallelDistributed(DoFHandlerType &dof_handler)
virtual std::vector< NumberCache > distribute_mg_dofs() const override
unsigned int subdomain_id
virtual NumberCache distribute_dofs() const override
virtual NumberCache distribute_dofs() const override
T sum(const T &t, const MPI_Comm &mpi_communicator)
const unsigned int dofs_per_hex
#define Assert(cond, exc)
IteratorRange< active_cell_iterator > active_cell_iterators() const
size_type index_within_set(const size_type global_index) const
Sequential(DoFHandlerType &dof_handler)
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const override
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const override
virtual MPI_Comm get_communicator() const
std::vector< types::global_dof_index > n_locally_owned_dofs_per_processor
virtual unsigned int n_global_levels() const override
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const override
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
std::unique_ptr<::internal::DoFHandlerImplementation::DoFFaces< dim > > faces
size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
const hp::FECollection< dim, spacedim > & get_fe_collection() const
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
std::vector< std::unique_ptr<::internal::DoFHandlerImplementation::DoFLevel< dim > > > levels
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
const std::set< types::subdomain_id > & level_ghost_owners() const
void add_range(const size_type begin, const size_type end)
unsigned int global_dof_index
const types::subdomain_id artificial_subdomain_id
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const override
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
#define AssertThrowMPI(error_code)
typename ActiveSelector::line_iterator line_iterator
hp::FECollection< dim, spacedim > fe_collection
const Triangulation< dim, spacedim > & get_triangulation() const
bool with_artificial_cells() const
void export_to_ghosted_array_start(const unsigned int communication_channel, const ArrayView< const Number, MemorySpaceType > &locally_owned_array, const ArrayView< Number, MemorySpaceType > &temporary_storage, const ArrayView< Number, MemorySpaceType > &ghost_array, std::vector< MPI_Request > &requests) const
T unpack(const std::vector< char > &buffer, const bool allow_compression=true)
std::vector< IndexSet > locally_owned_dofs_per_processor
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
static ::ExceptionBase & ExcNotImplemented()
Iterator points to a valid object.
const unsigned int dofs_per_vertex
void run(const std::vector< std::vector< Iterator >> &colored_iterators, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length=2 *MultithreadInfo::n_threads(), const unsigned int chunk_size=8)
static unsigned int n_threads()
ParallelShared(DoFHandlerType &dof_handler)
bool is_element(const size_type index) const
typename ActiveSelector::cell_iterator cell_iterator
types::global_dof_index n_global_dofs
typename ActiveSelector::active_cell_iterator active_cell_iterator
const types::global_dof_index invalid_dof_index
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const override
size_type n_elements() const
cell_iterator end() const
T max(const T &t, const MPI_Comm &mpi_communicator)
std::vector< types::global_dof_index > vertex_dofs
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
typename ActiveSelector::line_iterator line_iterator
static ::ExceptionBase & ExcInternalError()
Triangulation< dim, spacedim > & get_triangulation()