47 namespace DoFHandlerImplementation
71 template <
int dim,
int spacedim>
73 update_all_active_cell_dof_indices_caches(
76 const auto worker = [](
const auto &cell,
void *,
void *) {
77 if (!cell->is_artificial())
78 cell->update_cell_dof_indices_cache();
90 std::function<
void(
void *)>(),
102 template <
int dim,
int spacedim>
104 update_all_level_cell_dof_indices_caches(
107 const auto worker = [](
const auto &cell,
void *,
void *) {
108 if (cell->has_children() || !cell->is_artificial())
109 cell->update_cell_dof_indices_cache();
121 std::function<
void(
void *)>(),
129 using DoFIdentities =
130 std::vector<std::pair<unsigned int, unsigned int>>;
143 template <
int structdim,
int dim,
int spacedim>
144 const std::unique_ptr<DoFIdentities> &
145 ensure_existence_and_return_dof_identities(
148 std::unique_ptr<DoFIdentities> & identities,
156 if (identities.get() ==
nullptr)
162 identities = std::make_unique<DoFIdentities>(
169 identities = std::make_unique<DoFIdentities>(
176 identities = std::make_unique<DoFIdentities>(
187 for (
unsigned int i = 0; i < identities->size(); ++i)
190 fe1.template n_dofs_per_object<structdim>(face_no),
193 fe2.template n_dofs_per_object<structdim>(face_no),
212 template <
int dim,
int spacedim>
213 static std::map<types::global_dof_index, types::global_dof_index>
221 std::map<types::global_dof_index, types::global_dof_index>
235 for (
unsigned int vertex_index = 0;
241 const unsigned int n_active_fe_indices =
242 ::internal::DoFAccessorImplementation::Implementation::
243 n_active_fe_indices(dof_handler,
246 std::integral_constant<int, 0>());
248 if (n_active_fe_indices > 1)
250 const std::set<unsigned int> fe_indices =
256 std::integral_constant<int, 0>());
260 unsigned int most_dominating_fe_index =
267 if (most_dominating_fe_index ==
269 most_dominating_fe_index =
270 ::internal::DoFAccessorImplementation::
271 Implementation::nth_active_fe_index(
276 std::integral_constant<int, 0>());
282 for (
const auto &other_fe_index : fe_indices)
283 if (other_fe_index != most_dominating_fe_index)
287 const auto &identities =
288 *ensure_existence_and_return_dof_identities<0>(
289 dof_handler.
get_fe(most_dominating_fe_index),
290 dof_handler.
get_fe(other_fe_index),
291 vertex_dof_identities[most_dominating_fe_index]
302 for (
const auto &
identity : identities)
305 ::internal::DoFAccessorImplementation::
306 Implementation::get_dof_index(
310 most_dominating_fe_index,
312 std::integral_constant<int, 0>());
314 dependent_dof_index =
315 ::internal::DoFAccessorImplementation::
316 Implementation::get_dof_index(
322 std::integral_constant<int, 0>());
337 if (dependent_dof_index !=
347 if (primary_dof_index !=
350 (dof_identities.find(primary_dof_index) ==
351 dof_identities.end()) ||
352 (dof_identities[dependent_dof_index] ==
356 dof_identities[dependent_dof_index] =
364 return dof_identities;
372 template <
int spacedim>
373 static std::map<types::global_dof_index, types::global_dof_index>
380 return std::map<types::global_dof_index, types::global_dof_index>();
384 template <
int dim,
int spacedim>
385 static std::map<types::global_dof_index, types::global_dof_index>
393 std::map<types::global_dof_index, types::global_dof_index>
398 std::vector<bool> user_flags;
402 .clear_user_flags_line();
427 for (
const auto l : cell->line_indices())
428 if (cell->line(
l)->user_flag_set() ==
false)
430 const auto line = cell->line(
l);
431 line->set_user_flag();
433 unsigned int unique_sets_of_dofs =
434 line->n_active_fe_indices();
438 const unsigned int n_active_fe_indices =
439 line->n_active_fe_indices();
440 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
441 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
443 const unsigned int fe_index_1 =
444 line->nth_active_fe_index(f),
446 line->nth_active_fe_index(g);
465 dof_handler.
get_fe(fe_index_2)
471 const unsigned int dofs_per_line =
474 const auto &identities =
475 *ensure_existence_and_return_dof_identities<1>(
476 dof_handler.
get_fe(fe_index_1),
477 dof_handler.
get_fe(fe_index_2),
478 line_dof_identities[fe_index_1][fe_index_2]);
482 if (identities.size() == dofs_per_line)
485 for (; i < dofs_per_line; ++i)
486 if ((identities[i].
first != i) &&
487 (identities[i].
second != i))
491 if (i == dofs_per_line)
500 --unique_sets_of_dofs;
504 const std::set<unsigned int> fe_indices{
505 fe_index_1, fe_index_2};
507 unsigned int dominating_fe_index =
511 unsigned int other_fe_index =
514 if (dominating_fe_index !=
517 (dominating_fe_index == fe_index_1) ?
525 dominating_fe_index = fe_index_1;
526 other_fe_index = fe_index_2;
529 for (
unsigned int j = 0; j < dofs_per_line;
533 primary_dof_index = line->dof_index(
534 j, dominating_fe_index);
536 dependent_dof_index =
537 line->dof_index(j, other_fe_index);
553 if (dependent_dof_index !=
556 if (primary_dof_index !=
563 if (dof_identities.find(
564 primary_dof_index) !=
565 dof_identities.end())
581 [primary_dof_index]) ==
582 dof_identities.end(),
586 [dependent_dof_index] =
596 (dof_identities.find(
597 primary_dof_index) ==
598 dof_identities.end()) ||
600 [dependent_dof_index] ==
605 [dependent_dof_index] =
615 [dependent_dof_index] =
635 if ((unique_sets_of_dofs == 2) && (dim == 2))
637 const std::set<unsigned int> fe_indices =
638 line->get_active_fe_indices();
642 const unsigned int most_dominating_fe_index =
652 if (most_dominating_fe_index !=
658 for (
const auto &other_fe_index : fe_indices)
659 if (other_fe_index != most_dominating_fe_index)
661 const auto &identities =
662 *ensure_existence_and_return_dof_identities<
664 most_dominating_fe_index),
665 dof_handler.
get_fe(other_fe_index),
667 [most_dominating_fe_index]
670 for (
const auto &
identity : identities)
673 primary_dof_index = line->dof_index(
675 most_dominating_fe_index);
677 dependent_dof_index =
694 if (dependent_dof_index !=
704 if (primary_dof_index !=
706 Assert((dof_identities.find(
707 primary_dof_index) ==
708 dof_identities.end()) ||
710 [dependent_dof_index] ==
714 dof_identities[dependent_dof_index] =
726 .load_user_flags_line(user_flags);
728 return dof_identities;
737 template <
int dim,
int spacedim>
738 static std::map<types::global_dof_index, types::global_dof_index>
752 return std::map<types::global_dof_index, types::global_dof_index>();
756 template <
int spacedim>
757 static std::map<types::global_dof_index, types::global_dof_index>
765 std::map<types::global_dof_index, types::global_dof_index>
772 std::vector<bool> user_flags;
776 .clear_user_flags_quad();
795 for (
const auto q : cell->face_indices())
796 if ((cell->quad(q)->user_flag_set() ==
false) &&
797 (cell->quad(q)->n_active_fe_indices() == 2))
799 const auto quad = cell->quad(q);
800 quad->set_user_flag();
802 const std::set<unsigned int> fe_indices =
803 quad->get_active_fe_indices();
807 const unsigned int most_dominating_fe_index =
812 const unsigned int most_dominating_fe_index_face_no =
813 cell->active_fe_index() == most_dominating_fe_index ?
815 cell->neighbor_face_no(q);
829 for (
const auto &other_fe_index : fe_indices)
830 if (other_fe_index != most_dominating_fe_index)
832 const auto &identities =
833 *ensure_existence_and_return_dof_identities<2>(
834 dof_handler.
get_fe(most_dominating_fe_index),
835 dof_handler.
get_fe(other_fe_index),
837 [most_dominating_fe_index][other_fe_index]
838 [cell->quad(q)->reference_cell() ==
840 most_dominating_fe_index_face_no);
842 for (
const auto &
identity : identities)
847 most_dominating_fe_index);
849 dependent_dof_index =
858 if (dependent_dof_index !=
868 if (primary_dof_index !=
870 Assert((dof_identities.find(
871 primary_dof_index) ==
872 dof_identities.end()) ||
874 [dependent_dof_index] ==
878 dof_identities[dependent_dof_index] =
889 .load_user_flags_quad(user_flags);
891 return dof_identities;
900 template <
int dim,
int spacedim>
904 &all_constrained_indices,
916 all_constrained_indices[i] =
924 all_constrained_indices[i] =
933 all_constrained_indices[i] =
962 template <
int dim,
int spacedim>
965 std::vector<types::global_dof_index> &new_dof_indices,
967 std::map<types::global_dof_index, types::global_dof_index>>
968 &all_constrained_indices,
974 for (
const auto &constrained_dof_indices : all_constrained_indices)
975 for (
const auto &p : constrained_dof_indices)
978 Assert(new_dof_indices[p.first] == enumeration_dof_index,
981 new_dof_indices[p.first] = p.second;
986 for (
auto &new_dof_index : new_dof_indices)
987 if (new_dof_index == enumeration_dof_index)
988 new_dof_index = next_free_dof++;
992 for (
const auto &constrained_dof_indices : all_constrained_indices)
993 for (
const auto &p : constrained_dof_indices)
996 Assert(new_dof_indices[p.first] != enumeration_dof_index,
1000 new_dof_indices[p.first] = new_dof_indices[p.second];
1005 (void)new_dof_index;
1006 Assert(new_dof_index != enumeration_dof_index,
1008 Assert(new_dof_index < next_free_dof ||
1013 return next_free_dof;
1026 template <
int dim,
int spacedim>
1029 const unsigned int n_dofs_before_identification,
1030 const bool check_validity)
1033 return n_dofs_before_identification;
1036 std::map<types::global_dof_index, types::global_dof_index>>
1037 all_constrained_indices(dim);
1040 std::vector<::types::global_dof_index> renumbering(
1041 n_dofs_before_identification, enumeration_dof_index);
1044 all_constrained_indices,
1049 update_all_active_cell_dof_indices_caches(dof_handler);
1060 template <
int dim,
int spacedim>
1080 std::vector<bool> include_vertex(
1082 if (
dynamic_cast<const ::parallel::
1083 DistributedTriangulationBase<dim, spacedim> *
>(
1086 if (cell->is_ghost())
1087 for (
const unsigned int v : cell->vertex_indices())
1088 include_vertex[cell->vertex_index(v)] =
true;
1091 for (
unsigned int vertex_index = 0;
1096 (include_vertex[vertex_index] ==
true))
1098 const unsigned int n_active_fe_indices =
1099 ::internal::DoFAccessorImplementation::Implementation::
1100 n_active_fe_indices(dof_handler,
1103 std::integral_constant<int, 0>());
1105 if (n_active_fe_indices > 1)
1107 const std::set<unsigned int> fe_indices =
1113 std::integral_constant<int, 0>());
1117 unsigned int most_dominating_fe_index =
1125 if (most_dominating_fe_index ==
1127 most_dominating_fe_index =
1128 ::internal::DoFAccessorImplementation::
1129 Implementation::nth_active_fe_index(
1134 std::integral_constant<int, 0>());
1140 for (
const auto &other_fe_index : fe_indices)
1141 if (other_fe_index != most_dominating_fe_index)
1145 const auto &identities =
1146 *ensure_existence_and_return_dof_identities<0>(
1147 dof_handler.
get_fe(most_dominating_fe_index),
1148 dof_handler.
get_fe(other_fe_index),
1149 vertex_dof_identities[most_dominating_fe_index]
1160 for (
const auto &
identity : identities)
1163 ::internal::DoFAccessorImplementation::
1164 Implementation::get_dof_index(
1168 most_dominating_fe_index,
1170 std::integral_constant<int, 0>());
1172 dependent_dof_index =
1173 ::internal::DoFAccessorImplementation::
1174 Implementation::get_dof_index(
1180 std::integral_constant<int, 0>());
1194 if ((dependent_dof_index ==
1196 (primary_dof_index !=
1198 ::internal::DoFAccessorImplementation::
1199 Implementation::set_dof_index(
1205 std::integral_constant<int, 0>(),
1219 template <
int spacedim>
1229 template <
int dim,
int spacedim>
1240 std::vector<bool> user_flags;
1244 .clear_user_flags_line();
1248 if (cell->is_ghost())
1249 for (
const auto l : cell->line_indices())
1250 cell->line(
l)->set_user_flag();
1275 for (
const auto l : cell->line_indices())
1276 if ((cell->is_locally_owned()) &&
1277 (cell->line(
l)->user_flag_set() ==
true))
1279 const auto line = cell->line(
l);
1280 line->clear_user_flag();
1282 unsigned int unique_sets_of_dofs =
1283 line->n_active_fe_indices();
1287 const unsigned int n_active_fe_indices =
1288 line->n_active_fe_indices();
1289 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1290 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
1292 const unsigned int fe_index_1 =
1293 line->nth_active_fe_index(f),
1295 line->nth_active_fe_index(g);
1298 dof_handler.
get_fe(fe_index_2)
1304 const unsigned int dofs_per_line =
1307 const auto &identities =
1308 *ensure_existence_and_return_dof_identities<1>(
1309 dof_handler.
get_fe(fe_index_1),
1310 dof_handler.
get_fe(fe_index_2),
1311 line_dof_identities[fe_index_1][fe_index_2]);
1315 if (identities.size() == dofs_per_line)
1318 for (; i < dofs_per_line; ++i)
1319 if ((identities[i].
first != i) &&
1320 (identities[i].
second != i))
1324 if (i == dofs_per_line)
1333 --unique_sets_of_dofs;
1337 const std::set<unsigned int> fe_indices{
1338 fe_index_1, fe_index_2};
1340 unsigned int dominating_fe_index =
1344 unsigned int other_fe_index =
1347 if (dominating_fe_index !=
1350 (dominating_fe_index == fe_index_1) ?
1358 dominating_fe_index = fe_index_1;
1359 other_fe_index = fe_index_2;
1362 for (
unsigned int j = 0; j < dofs_per_line;
1366 primary_dof_index = line->dof_index(
1367 j, dominating_fe_index);
1369 dependent_dof_index =
1370 line->dof_index(j, other_fe_index);
1385 if ((dependent_dof_index ==
1387 (primary_dof_index !=
1389 line->set_dof_index(j,
1408 if ((unique_sets_of_dofs == 2) && (dim == 2))
1410 const std::set<unsigned int> fe_indices =
1411 line->get_active_fe_indices();
1415 const unsigned int most_dominating_fe_index =
1425 if (most_dominating_fe_index !=
1431 for (
const auto &other_fe_index : fe_indices)
1432 if (other_fe_index != most_dominating_fe_index)
1434 const auto &identities =
1435 *ensure_existence_and_return_dof_identities<
1437 most_dominating_fe_index),
1438 dof_handler.
get_fe(other_fe_index),
1440 [most_dominating_fe_index]
1443 for (
const auto &
identity : identities)
1446 primary_dof_index = line->dof_index(
1448 most_dominating_fe_index);
1450 dependent_dof_index =
1466 if ((dependent_dof_index ==
1468 (primary_dof_index !=
1470 line->set_dof_index(
identity.second,
1482 .load_user_flags_line(user_flags);
1491 template <
int dim,
int spacedim>
1508 template <
int spacedim>
1520 std::vector<bool> user_flags;
1524 .clear_user_flags_quad();
1528 if (cell->is_ghost())
1529 for (
const auto q : cell->face_indices())
1530 cell->quad(q)->set_user_flag();
1549 for (
const auto q : cell->face_indices())
1550 if ((cell->is_locally_owned()) &&
1551 (cell->quad(q)->user_flag_set() ==
true) &&
1552 (cell->quad(q)->n_active_fe_indices() == 2))
1554 const auto quad = cell->quad(q);
1555 quad->clear_user_flag();
1557 const std::set<unsigned int> fe_indices =
1558 quad->get_active_fe_indices();
1562 const unsigned int most_dominating_fe_index =
1567 const unsigned int most_dominating_fe_index_face_no =
1568 cell->active_fe_index() == most_dominating_fe_index ?
1570 cell->neighbor_face_no(q);
1584 for (
const auto &other_fe_index : fe_indices)
1585 if (other_fe_index != most_dominating_fe_index)
1587 const auto &identities =
1588 *ensure_existence_and_return_dof_identities<2>(
1589 dof_handler.
get_fe(most_dominating_fe_index),
1590 dof_handler.
get_fe(other_fe_index),
1592 [most_dominating_fe_index][other_fe_index]
1593 [cell->quad(q)->reference_cell() ==
1595 most_dominating_fe_index_face_no);
1597 for (
const auto &
identity : identities)
1602 most_dominating_fe_index);
1604 dependent_dof_index =
1619 if ((dependent_dof_index ==
1621 (primary_dof_index !=
1623 quad->set_dof_index(
identity.second,
1634 .load_user_flags_quad(user_flags);
1651 template <
int dim,
int spacedim>
1683 update_all_active_cell_dof_indices_caches(dof_handler);
1694 template <
int dim,
int spacedim>
1706 std::vector<types::global_dof_index> dof_indices;
1709 if (!cell->is_artificial())
1713 dof_indices.resize(cell->get_fe().n_dofs_per_cell());
1716 internal::DoFAccessorImplementation::Implementation::
1717 get_dof_indices(*cell,
1719 cell->active_fe_index());
1721 for (
auto &dof_index : dof_indices)
1723 dof_index = next_free_dof++;
1725 cell->set_dof_indices(dof_indices);
1728 update_all_active_cell_dof_indices_caches(dof_handler);
1730 return next_free_dof;
1748 template <
int dim,
int spacedim>
1751 std::vector<types::global_dof_index> &renumbering,
1755 std::vector<types::global_dof_index> local_dof_indices;
1758 if (cell->is_ghost() && (cell->subdomain_id() <
subdomain_id))
1766 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
1767 cell->get_dof_indices(local_dof_indices);
1768 for (
const auto &local_dof_index : local_dof_indices)
1780 template <
int dim,
int spacedim>
1784 const unsigned int level)
1789 const ::Triangulation<dim, spacedim> &tria =
1792 if (
level >= tria.n_levels())
1797 std::vector<types::global_dof_index> dof_indices;
1801 (cell->level_subdomain_id() == level_subdomain_id))
1803 dof_indices.resize(cell->get_fe().n_dofs_per_cell());
1805 cell->get_mg_dof_indices(dof_indices);
1807 for (
auto &dof_index : dof_indices)
1809 dof_index = next_free_dof++;
1811 cell->set_mg_dof_indices(dof_indices);
1814 return next_free_dof;
1829 template <
int dim,
int spacedim>
1832 const std::vector<types::global_dof_index> &new_numbers,
1833 const IndexSet & indices_we_care_about,
1836 for (
unsigned int d = 1;
d < dim;
d++)
1839 i = ((indices_we_care_about.
size() == 0) ?
1846 template <
int dim,
int spacedim>
1849 const std::vector<types::global_dof_index> &new_numbers,
1850 const IndexSet & indices_we_care_about,
1852 const bool check_validity)
1862 for (std::vector<types::global_dof_index>::iterator i =
1868 (indices_we_care_about.
size() == 0) ?
1871 else if (check_validity)
1882 for (
unsigned int vertex_index = 0;
1886 const unsigned int n_active_fe_indices =
1887 ::internal::DoFAccessorImplementation::Implementation::
1888 n_active_fe_indices(dof_handler,
1891 std::integral_constant<int, 0>());
1905 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1907 const unsigned int fe_index =
1908 ::internal::DoFAccessorImplementation::
1909 Implementation::nth_active_fe_index(
1914 std::integral_constant<int, 0>());
1916 for (
unsigned int d = 0;
1917 d < dof_handler.
get_fe(fe_index).n_dofs_per_vertex();
1921 ::internal::DoFAccessorImplementation::
1922 Implementation::get_dof_index(
1928 std::integral_constant<int, 0>());
1959 if (indices_we_care_about.
size() == 0)
1960 ::internal::DoFAccessorImplementation::
1961 Implementation::set_dof_index(
1967 std::integral_constant<int, 0>(),
1968 new_numbers[old_dof_index]);
1973 ::internal::DoFAccessorImplementation::
1974 Implementation::set_dof_index(
1980 std::integral_constant<int, 0>(),
1981 new_numbers[indices_we_care_about
1985 ::internal::DoFAccessorImplementation::
1986 Implementation::set_dof_index(
1992 std::integral_constant<int, 0>(),
2003 template <
int dim,
int spacedim>
2006 const std::vector<types::global_dof_index> &new_numbers,
2007 const IndexSet & indices_we_care_about,
2012 for (
unsigned int level = 0;
2017 i = ((indices_we_care_about.
size() == 0) ?
2025 if (!cell->is_artificial())
2027 const unsigned int fe_index = cell->active_fe_index();
2029 for (
unsigned int d = 0;
2030 d < dof_handler.
get_fe(fe_index)
2031 .template n_dofs_per_object<dim>();
2035 cell->dof_index(
d, fe_index);
2052 if (indices_we_care_about.
size() == 0)
2053 cell->set_dof_index(
d,
2054 new_numbers[old_dof_index],
2058 if (indices_we_care_about.
is_element(old_dof_index))
2059 cell->set_dof_index(
2061 new_numbers[indices_we_care_about
2065 cell->set_dof_index(
d,
2076 template <
int spacedim>
2079 const std::vector<types::global_dof_index> & ,
2089 template <
int spacedim>
2092 const std::vector<types::global_dof_index> &new_numbers,
2093 const IndexSet & indices_we_care_about,
2096 const unsigned int dim = 2;
2100 for (
unsigned int d = 1;
d < dim;
d++)
2103 i = ((indices_we_care_about.
size() == 0) ?
2114 std::vector<bool> saved_line_user_flags;
2117 .save_user_flags_line(saved_line_user_flags);
2120 .clear_user_flags_line();
2123 if (!cell->is_artificial())
2124 for (
const auto l : cell->line_indices())
2125 if (cell->line(
l)->user_flag_set() ==
false)
2127 const auto line = cell->line(
l);
2128 line->set_user_flag();
2130 const unsigned int n_active_fe_indices =
2131 line->n_active_fe_indices();
2133 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2135 const unsigned int fe_index =
2136 line->nth_active_fe_index(f);
2138 for (
unsigned int d = 0;
2140 dof_handler.
get_fe(fe_index).n_dofs_per_line();
2144 line->dof_index(
d, fe_index);
2164 if (indices_we_care_about.
size() == 0)
2165 line->set_dof_index(
2166 d, new_numbers[old_dof_index], fe_index);
2171 line->set_dof_index(
2173 new_numbers[indices_we_care_about
2178 line->set_dof_index(
2192 .load_user_flags_line(saved_line_user_flags);
2198 template <
int spacedim>
2201 const std::vector<types::global_dof_index> &new_numbers,
2202 const IndexSet & indices_we_care_about,
2205 const unsigned int dim = 3;
2209 for (
unsigned int d = 1;
d < dim;
d++)
2212 i = ((indices_we_care_about.
size() == 0) ?
2223 std::vector<bool> saved_line_user_flags;
2226 .save_user_flags_line(saved_line_user_flags);
2229 .clear_user_flags_line();
2232 if (!cell->is_artificial())
2233 for (
const auto l : cell->line_indices())
2234 if (cell->line(
l)->user_flag_set() ==
false)
2236 const auto line = cell->line(
l);
2237 line->set_user_flag();
2239 const unsigned int n_active_fe_indices =
2240 line->n_active_fe_indices();
2242 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2244 const unsigned int fe_index =
2245 line->nth_active_fe_index(f);
2247 for (
unsigned int d = 0;
2249 dof_handler.
get_fe(fe_index).n_dofs_per_line();
2253 line->dof_index(
d, fe_index);
2273 if (indices_we_care_about.
size() == 0)
2274 line->set_dof_index(
2275 d, new_numbers[old_dof_index], fe_index);
2278 line->set_dof_index(
2280 new_numbers[indices_we_care_about
2285 line->set_dof_index(
2296 .load_user_flags_line(saved_line_user_flags);
2301 std::vector<bool> saved_quad_user_flags;
2304 .save_user_flags_quad(saved_quad_user_flags);
2307 .clear_user_flags_quad();
2310 if (!cell->is_artificial())
2311 for (
const auto q : cell->face_indices())
2312 if (cell->quad(q)->user_flag_set() ==
false)
2314 const auto quad = cell->quad(q);
2315 quad->set_user_flag();
2317 const unsigned int n_active_fe_indices =
2318 quad->n_active_fe_indices();
2320 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2322 const unsigned int fe_index =
2323 quad->nth_active_fe_index(f);
2325 for (
unsigned int d = 0;
2327 dof_handler.
get_fe(fe_index).n_dofs_per_quad(q);
2331 quad->dof_index(
d, fe_index);
2351 if (indices_we_care_about.
size() == 0)
2352 quad->set_dof_index(
2353 d, new_numbers[old_dof_index], fe_index);
2358 quad->set_dof_index(
2360 new_numbers[indices_we_care_about
2365 quad->set_dof_index(
2378 .load_user_flags_quad(saved_quad_user_flags);
2395 template <
int dim,
int space_dim>
2398 const IndexSet & indices_we_care_about,
2400 const bool check_validity)
2411 indices_we_care_about,
2418 indices_we_care_about,
2424 indices_we_care_about,
2431 update_all_active_cell_dof_indices_caches(
2447 template <
int dim,
int spacedim>
2450 const std::vector<::types::global_dof_index> &new_numbers,
2451 const IndexSet & indices_we_care_about,
2453 const unsigned int level,
2454 const bool check_validity)
2456 (void)check_validity;
2460 for (
typename std::vector<
2466 if ((i->get_coarsest_level() <=
level) &&
2467 (i->get_finest_level() >=
level))
2468 for (
unsigned int d = 0;
2469 d < dof_handler.
get_fe().n_dofs_per_vertex();
2479 Assert(check_validity ==
false ||
2480 (indices_we_care_about.
size() > 0 ?
2482 (idx < new_numbers.size())),
2487 (indices_we_care_about.
size() == 0) ?
2488 (new_numbers[idx]) :
2489 (new_numbers[indices_we_care_about
2504 template <
int dim,
int spacedim>
2507 const std::vector<::types::global_dof_index> &new_numbers,
2508 const IndexSet & indices_we_care_about,
2510 const unsigned int level)
2512 for (std::vector<types::global_dof_index>::iterator i =
2521 (*i < new_numbers.size())),
2524 (indices_we_care_about.
size() == 0) ?
2540 template <
int spacedim>
2543 const std::vector<types::global_dof_index> & ,
2546 const unsigned int ,
2554 template <
int spacedim>
2557 const std::vector<::types::global_dof_index> &new_numbers,
2558 const IndexSet & indices_we_care_about,
2560 const unsigned int level,
2561 const bool check_validity)
2566 std::vector<bool> user_flags;
2570 .clear_user_flags();
2576 for (
const auto &cell :
2578 if (cell->level_subdomain_id() !=
2580 for (
const unsigned int line : cell->face_indices())
2581 cell->face(line)->set_user_flag();
2583 for (
const auto &cell :
2585 for (
const auto l : cell->line_indices())
2586 if (cell->line(
l)->user_flag_set())
2588 for (
unsigned int d = 0;
2589 d < dof_handler.
get_fe().n_dofs_per_line();
2593 cell->line(
l)->mg_dof_index(
level,
d);
2599 cell->line(
l)->set_mg_dof_index(
2602 ((indices_we_care_about.
size() == 0) ?
2604 new_numbers[indices_we_care_about
2607 cell->line(
l)->clear_user_flag();
2612 .load_user_flags(user_flags);
2618 template <
int spacedim>
2621 const std::vector<::types::global_dof_index> &new_numbers,
2622 const IndexSet & indices_we_care_about,
2624 const unsigned int level,
2625 const bool check_validity)
2631 std::vector<bool> user_flags;
2635 .clear_user_flags();
2640 for (
const auto &cell :
2642 if (cell->level_subdomain_id() !=
2644 for (
const auto line : cell->line_indices())
2645 cell->line(line)->set_user_flag();
2647 for (
const auto &cell :
2649 for (
const auto l : cell->line_indices())
2650 if (cell->line(
l)->user_flag_set())
2652 for (
unsigned int d = 0;
2653 d < dof_handler.
get_fe().n_dofs_per_line();
2657 cell->line(
l)->mg_dof_index(
level,
d);
2663 cell->line(
l)->set_mg_dof_index(
2666 ((indices_we_care_about.
size() == 0) ?
2668 new_numbers[indices_we_care_about
2671 cell->line(
l)->clear_user_flag();
2677 for (
const auto &cell :
2679 if (cell->level_subdomain_id() !=
2681 for (
const auto quad : cell->face_indices())
2682 cell->quad(quad)->set_user_flag();
2685 for (
const auto l : cell->face_indices())
2686 if (cell->quad(
l)->user_flag_set())
2688 for (
unsigned int d = 0;
2689 d < dof_handler.
get_fe().n_dofs_per_quad(
l);
2693 cell->quad(
l)->mg_dof_index(
level,
d);
2699 cell->quad(
l)->set_mg_dof_index(
2702 ((indices_we_care_about.
size() == 0) ?
2704 new_numbers[indices_we_care_about
2707 cell->quad(
l)->clear_user_flag();
2713 .load_user_flags(user_flags);
2719 template <
int dim,
int spacedim>
2722 const std::vector<::types::global_dof_index> &new_numbers,
2723 const IndexSet & indices_we_care_about,
2725 const unsigned int level,
2726 const bool check_validity)
2741 indices_we_care_about,
2748 indices_we_care_about,
2755 indices_we_care_about,
2769 template <
int dim,
int spacedim>
2772 : dof_handler(&dof_handler)
2777 template <
int dim,
int spacedim>
2796 template <
int dim,
int spacedim>
2797 std::vector<NumberCache>
2800 std::vector<bool> user_flags;
2805 .clear_user_flags();
2807 std::vector<NumberCache> number_caches;
2809 for (
unsigned int level = 0;
2819 number_caches.emplace_back(n_level_dofs);
2824 .load_user_flags(user_flags);
2826 return number_caches;
2831 template <
int dim,
int spacedim>
2834 const std::vector<types::global_dof_index> &new_numbers)
const
2850 *std::max_element(new_numbers.begin(), new_numbers.end()) + 1);
2855 template <
int dim,
int spacedim>
2858 const unsigned int level,
2859 const std::vector<types::global_dof_index> &new_numbers)
const
2872 template <
int dim,
int spacedim>
2875 : dof_handler(&dof_handler)
2890 template <
int dim,
int spacedim>
2891 std::vector<types::subdomain_id>
2892 get_dof_subdomain_association(
2895 const unsigned int n_procs)
2898 std::vector<types::subdomain_id> subdomain_association(
2900 std::vector<types::global_dof_index> local_dof_indices;
2901 local_dof_indices.reserve(
2912 const unsigned int dofs_per_cell =
2913 cell->get_fe().n_dofs_per_cell();
2914 local_dof_indices.resize(dofs_per_cell);
2915 cell->get_dof_indices(local_dof_indices);
2920 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2921 if (subdomain_association[local_dof_indices[i]] ==
2923 subdomain_association[local_dof_indices[i]] =
subdomain_id;
2924 else if (subdomain_association[local_dof_indices[i]] >
2927 subdomain_association[local_dof_indices[i]] =
subdomain_id;
2931 Assert(std::find(subdomain_association.begin(),
2932 subdomain_association.end(),
2934 subdomain_association.end(),
2937 Assert(*std::max_element(subdomain_association.begin(),
2938 subdomain_association.end()) < n_procs,
2941 return subdomain_association;
2951 template <
int dim,
int spacedim>
2952 std::vector<types::subdomain_id>
2953 get_dof_level_subdomain_association(
2956 const unsigned int n_procs,
2957 const unsigned int level)
2960 std::vector<types::subdomain_id> level_subdomain_association(
2962 std::vector<types::global_dof_index> local_dof_indices;
2963 local_dof_indices.reserve(
2974 cell->level_subdomain_id();
2975 const unsigned int dofs_per_cell =
2976 cell->get_fe().n_dofs_per_cell();
2977 local_dof_indices.resize(dofs_per_cell);
2978 cell->get_mg_dof_indices(local_dof_indices);
2983 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2984 if (level_subdomain_association[local_dof_indices[i]] ==
2986 level_subdomain_association[local_dof_indices[i]] =
2988 else if (level_subdomain_association[local_dof_indices[i]] >
2991 level_subdomain_association[local_dof_indices[i]] =
2996 Assert(std::find(level_subdomain_association.begin(),
2997 level_subdomain_association.end(),
2999 level_subdomain_association.end(),
3002 Assert(*std::max_element(level_subdomain_association.begin(),
3003 level_subdomain_association.end()) < n_procs,
3006 return level_subdomain_association;
3012 template <
int dim,
int spacedim>
3016 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3018 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3022 const unsigned int n_procs =
3032 const internal::parallel::shared::
3033 TemporarilyRestoreSubdomainIds<dim, spacedim>
3034 subdomain_modifier(*tr);
3040 *this->dof_handler);
3056 std::vector<types::global_dof_index> new_dof_indices(
3057 n_dofs, enumeration_dof_index);
3061 const std::vector<types::subdomain_id> subdomain_association =
3062 get_dof_subdomain_association(*this->dof_handler, n_dofs, n_procs);
3073 if (subdomain_association[i] == subdomain)
3075 Assert(new_dof_indices[i] == enumeration_dof_index,
3077 new_dof_indices[i] = next_free_index;
3083 Assert(std::find(new_dof_indices.begin(),
3084 new_dof_indices.end(),
3085 enumeration_dof_index) == new_dof_indices.end(),
3106 const std::vector<types::subdomain_id> subdomain_association =
3107 get_dof_subdomain_association(*this->dof_handler, n_dofs, n_procs);
3109 for (
unsigned int i = 1; i < n_dofs; ++i)
3110 Assert(subdomain_association[i] >= subdomain_association[i - 1],
3113 std::vector<IndexSet> locally_owned_dofs_per_processor(
3124 unsigned int start_index = 0;
3125 unsigned int end_index = 0;
3126 while (start_index < n_dofs)
3128 while ((end_index) < n_dofs &&
3129 (subdomain_association[end_index] ==
3130 subdomain_association[start_index]))
3135 if (end_index > start_index)
3137 const unsigned int subdomain_owner =
3138 subdomain_association[start_index];
3139 locally_owned_dofs_per_processor[subdomain_owner].add_range(
3140 start_index, end_index);
3144 start_index = end_index;
3151 locally_owned_dofs_per_processor,
3157 template <
int dim,
int spacedim>
3158 std::vector<NumberCache>
3161 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3163 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3167 const unsigned int n_procs =
3169 const unsigned int n_levels = tr->n_global_levels();
3171 std::vector<NumberCache> number_caches;
3172 number_caches.reserve(n_levels);
3175 for (
unsigned int lvl = 0; lvl < n_levels; ++lvl)
3183 std::vector<types::subdomain_id> saved_level_subdomain_ids;
3184 saved_level_subdomain_ids.resize(tr->n_cells(lvl));
3186 typename ::parallel::shared::Triangulation<dim, spacedim>::
3187 cell_iterator cell =
3193 const std::vector<types::subdomain_id> &true_level_subdomain_ids =
3194 tr->get_true_level_subdomain_ids_of_cells(lvl);
3196 for (
unsigned int index = 0; cell != endc; ++cell, ++index)
3198 saved_level_subdomain_ids[index] = cell->level_subdomain_id();
3199 cell->set_level_subdomain_id(true_level_subdomain_ids[index]);
3218 std::vector<types::global_dof_index> new_dof_indices(
3223 const std::vector<types::subdomain_id>
3224 level_subdomain_association =
3225 get_dof_level_subdomain_association(*this->dof_handler,
3237 level_subdomain < n_procs;
3240 if (level_subdomain_association[i] == level_subdomain)
3244 new_dof_indices[i] = next_free_index;
3250 Assert(std::find(new_dof_indices.begin(),
3251 new_dof_indices.end(),
3253 new_dof_indices.end(),
3262 new_dof_indices,
IndexSet(0), *this->dof_handler, lvl,
true);
3274 const std::vector<types::subdomain_id> level_subdomain_association =
3275 get_dof_level_subdomain_association(*this->dof_handler,
3280 for (
unsigned int i = 1; i < n_dofs_on_level; ++i)
3281 Assert(level_subdomain_association[i] >=
3282 level_subdomain_association[i - 1],
3285 std::vector<IndexSet> locally_owned_dofs_per_processor(
3286 n_procs,
IndexSet(n_dofs_on_level));
3296 unsigned int start_index = 0;
3297 unsigned int end_index = 0;
3298 while (start_index < n_dofs_on_level)
3300 while ((end_index) < n_dofs_on_level &&
3301 (level_subdomain_association[end_index] ==
3302 level_subdomain_association[start_index]))
3307 if (end_index > start_index)
3309 const unsigned int level_subdomain_owner =
3310 level_subdomain_association[start_index];
3311 locally_owned_dofs_per_processor[level_subdomain_owner]
3312 .add_range(start_index, end_index);
3316 start_index = end_index;
3322 typename ::parallel::shared::Triangulation<dim, spacedim>::
3323 cell_iterator cell =
3329 for (
unsigned int index = 0; cell != endc; ++cell, ++index)
3330 cell->set_level_subdomain_id(saved_level_subdomain_ids[index]);
3333 number_caches.emplace_back(
3340 return number_caches;
3345 template <
int dim,
int spacedim>
3348 const std::vector<types::global_dof_index> &new_numbers)
const
3350#ifndef DEAL_II_WITH_MPI
3357 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3359 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3364 const internal::parallel::shared::
3365 TemporarilyRestoreSubdomainIds<dim, spacedim>
3366 subdomain_modifier(*tr);
3368 std::vector<types::global_dof_index> global_gathered_numbers(
3369 this->dof_handler->
n_dofs(), 0);
3374 if (new_numbers.size() == this->dof_handler->n_dofs())
3376 global_gathered_numbers = new_numbers;
3380 Assert(new_numbers.size() ==
3381 this->dof_handler->locally_owned_dofs().n_elements(),
3383 const unsigned int n_cpu =
3385 std::vector<types::global_dof_index> gathered_new_numbers(
3386 this->dof_handler->
n_dofs(), 0);
3388 this->dof_handler->get_triangulation()
3389 .locally_owned_subdomain(),
3394 std::vector<types::global_dof_index> new_numbers_copy(
3399 std::vector<int> rcounts(n_cpu);
3403 int cur_count = new_numbers_copy.size();
3404 int ierr = MPI_Allgather(&cur_count,
3410 tr->get_communicator());
3415 std::vector<int> displacements(n_cpu);
3416 for (
unsigned int i = 0; i < n_cpu; i++)
3418 displacements[i] =
shift;
3419 shift += rcounts[i];
3421 Assert(new_numbers_copy.size() ==
3422 static_cast<unsigned int>(
3424 tr->get_communicator())]),
3426 ierr = MPI_Allgatherv(new_numbers_copy.data(),
3427 new_numbers_copy.size(),
3429 gathered_new_numbers.data(),
3431 displacements.data(),
3433 tr->get_communicator());
3443 std::vector<unsigned int> flag_1(this->dof_handler->
n_dofs(), 0);
3444 std::vector<unsigned int> flag_2(this->dof_handler->
n_dofs(), 0);
3445 for (
unsigned int i = 0; i < n_cpu; i++)
3455 gathered_new_numbers[
shift + ind];
3460 global_gathered_numbers[target] =
value;
3467 Assert(*std::max_element(flag_1.begin(), flag_1.end()) == 1,
3469 Assert(*std::min_element(flag_1.begin(), flag_1.end()) == 1,
3471 Assert((*std::max_element(flag_2.begin(), flag_2.end())) == 1,
3473 Assert((*std::min_element(flag_2.begin(), flag_2.end())) == 1,
3489 return number_cache;
3495 template <
int dim,
int spacedim>
3498 const unsigned int ,
3499 const std::vector<types::global_dof_index> & )
const
3511#ifdef DEAL_II_WITH_MPI
3515 template <
int dim,
int spacedim>
3517 communicate_mg_ghost_cells(
3518 const typename ::parallel::
3519 DistributedTriangulationBase<dim, spacedim> &tria,
3523 const auto pack = [&](
const auto &cell) {
3525 Assert(cell->level_subdomain_id() == tria.locally_owned_subdomain(),
3528 std::vector<::types::global_dof_index> data(
3529 cell->get_fe().n_dofs_per_cell());
3530 cell->get_mg_dof_indices(data);
3535 const auto unpack = [](
const auto &cell,
const auto &dofs) {
3536 Assert(cell->get_fe().n_dofs_per_cell() == dofs.size(),
3539 Assert(cell->level_subdomain_id() !=
3543 std::vector<::types::global_dof_index> dof_indices(
3544 cell->get_fe().n_dofs_per_cell());
3545 cell->get_mg_dof_indices(dof_indices);
3547 bool complete =
true;
3548 for (
unsigned int i = 0; i < dof_indices.size(); ++i)
3552 (dof_indices[i] == dofs[i]),
3554 dof_indices[i] = dofs[i];
3566 ->clear_user_flag();
3570 ->set_mg_dof_indices(dof_indices);
3573 const auto filter = [](
const auto &cell) {
3574 return cell->user_flag_set();
3578 std::vector<types::global_dof_index>,
3584 template <
int spacedim>
3586 communicate_mg_ghost_cells(
const typename ::parallel::
3587 distributed::Triangulation<1, spacedim> &,
3613 template <
int dim,
int spacedim>
3615 communicate_dof_indices_on_marked_cells(
3618# ifndef DEAL_II_WITH_MPI
3626 const auto pack = [](
const auto &cell) {
3629 std::vector<::types::global_dof_index> data(
3630 cell->get_fe().n_dofs_per_cell());
3631 cell->get_dof_indices(data);
3636 const auto unpack = [](
const auto &cell,
const auto &dofs) {
3637 Assert(cell->get_fe().n_dofs_per_cell() == dofs.size(),
3642 std::vector<::types::global_dof_index> dof_indices(
3643 cell->get_fe().n_dofs_per_cell());
3644 cell->update_cell_dof_indices_cache();
3645 cell->get_dof_indices(dof_indices);
3647 bool complete =
true;
3648 for (
unsigned int i = 0; i < dof_indices.size(); ++i)
3652 (dof_indices[i] == dofs[i]),
3654 dof_indices[i] = dofs[i];
3668 ->clear_user_flag();
3672 ->set_dof_indices(dof_indices);
3675 const auto filter = [](
const auto &cell) {
3676 return cell->user_flag_set();
3680 std::vector<types::global_dof_index>,
3685 update_all_active_cell_dof_indices_caches(dof_handler);
3702 dynamic_cast<const ::parallel::
3703 DistributedTriangulationBase<dim, spacedim> *
>(
3704 &dof_handler.get_triangulation()))
3706 const int ierr = MPI_Barrier(
triangulation->get_communicator());
3713 "The function communicate_dof_indices_on_marked_cells() "
3714 "only works with parallel distributed triangulations."));
3727 template <
int dim,
int spacedim>
3730 : dof_handler(&dof_handler)
3735 template <
int dim,
int spacedim>
3739#ifndef DEAL_II_WITH_MPI
3749 &dof_handler->get_triangulation())));
3788 std::vector<::types::global_dof_index> renumbering(
3789 n_initial_local_dofs, enumeration_dof_index);
3800 std::vector<std::map<types::global_dof_index, types::global_dof_index>>
3801 all_constrained_indices(dim);
3817 renumbering, all_constrained_indices, *dof_handler);
3832 for (
auto &new_index : renumbering)
3834 new_index += my_shift;
3855 n_locally_owned_dofs);
3866 std::vector<bool> user_flags;
3873 for (
const auto &cell : dof_handler->active_cell_iterators())
3874 if (cell->is_ghost())
3875 cell->set_user_flag();
3883 communicate_dof_indices_on_marked_cells(*dof_handler);
3896 communicate_dof_indices_on_marked_cells(*dof_handler);
3901 for (
const auto &cell : dof_handler->active_cell_iterators())
3911 std::vector<::types::global_dof_index> local_dof_indices;
3913 for (
const auto &cell : dof_handler->active_cell_iterators())
3914 if (!cell->is_artificial())
3916 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
3917 cell->get_dof_indices(local_dof_indices);
3918 if (local_dof_indices.end() !=
3919 std::find(local_dof_indices.begin(),
3920 local_dof_indices.end(),
3923 if (cell->is_ghost())
3927 "A ghost cell ended up with incomplete "
3928 "DoF index information. This should not "
3936 "A locally owned cell ended up with incomplete "
3937 "DoF index information. This should not "
3944 return number_cache;
3950 template <
int dim,
int spacedim>
3951 std::vector<NumberCache>
3954#ifndef DEAL_II_WITH_MPI
3956 return std::vector<NumberCache>();
3964 &dof_handler->get_triangulation())));
3969 "Multigrid DoFs can only be distributed on a parallel "
3970 "Triangulation if the flag construct_multigrid_hierarchy "
3971 "is set in the constructor."));
3978 const unsigned int n_levels =
triangulation->n_global_levels();
3979 std::vector<NumberCache> number_caches;
3980 number_caches.reserve(n_levels);
3986 const unsigned int n_initial_local_dofs =
3992 std::vector<::types::global_dof_index> renumbering(
3993 n_initial_local_dofs);
3998 if (level < triangulation->n_levels())
4000 std::vector<::types::global_dof_index> local_dof_indices;
4002 for (
const auto &cell :
4003 dof_handler->cell_iterators_on_level(
level))
4004 if (cell->level_subdomain_id() !=
4006 (cell->level_subdomain_id() <
4016 local_dof_indices.resize(
4017 cell->get_fe().n_dofs_per_cell());
4018 cell->get_mg_dof_indices(local_dof_indices);
4019 for (
unsigned int i = 0;
4020 i < cell->get_fe().n_dofs_per_cell();
4023 renumbering[local_dof_indices[i]] =
4072 if (level < triangulation->n_levels())
4083 number_caches.emplace_back(level_number_cache);
4092 std::vector<bool> user_flags;
4098 for (
const auto &cell : dof_handler->cell_iterators())
4099 if (cell->level_subdomain_id() !=
4101 !cell->is_locally_owned_on_level())
4102 cell->set_user_flag();
4123 const int ierr = MPI_Barrier(
triangulation->get_communicator());
4133 for (
const auto &cell : dof_handler->cell_iterators())
4134 if (cell->level_subdomain_id() !=
4136 !cell->is_locally_owned_on_level())
4149 std::vector<::types::global_dof_index> local_dof_indices;
4150 for (
const auto &cell : dof_handler->cell_iterators())
4151 if (cell->level_subdomain_id() !=
4154 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
4155 cell->get_mg_dof_indices(local_dof_indices);
4156 if (local_dof_indices.end() !=
4157 std::find(local_dof_indices.begin(),
4158 local_dof_indices.end(),
4167 return number_caches;
4173 template <
int dim,
int spacedim>
4176 const std::vector<::types::global_dof_index> &new_numbers)
const
4180 Assert(new_numbers.size() == dof_handler->n_locally_owned_dofs(),
4183#ifndef DEAL_II_WITH_MPI
4193 &dof_handler->get_triangulation())));
4201 const bool locally_owned_set_changes =
4202 std::any_of(new_numbers.cbegin(),
4205 return dof_handler->locally_owned_dofs().is_element(
4210 locally_owned_set_changes),
4223 std::vector<types::global_dof_index> ghosted_new_numbers(
4227 dof_handler->locally_owned_dofs(),
4234 const unsigned int communication_channel = 19;
4235 std::vector<types::global_dof_index> temp_array(
4237 std::vector<MPI_Request> requests;
4239 communication_channel,
4243 ghosted_new_numbers.data() + new_numbers.size(),
4248 ghosted_new_numbers.data() + new_numbers.size(),
4257 unsigned int n_ghosts_on_smaller_ranks = 0;
4258 for (std::pair<unsigned int, unsigned int> t :
4263 n_ghosts_on_smaller_ranks += t.second;
4265 if (n_ghosts_on_smaller_ranks > 0)
4267 Assert(ghosted_new_numbers.data() !=
nullptr,
4269 std::memmove(ghosted_new_numbers.data(),
4270 ghosted_new_numbers.data() + new_numbers.size(),
4272 n_ghosts_on_smaller_ranks);
4274 if (new_numbers.size() > 0)
4277 std::memcpy(ghosted_new_numbers.data() +
4278 n_ghosts_on_smaller_ranks,
4281 new_numbers.size());
4300 return number_cache;
4314 IndexSet my_locally_owned_new_dof_indices(dof_handler->n_dofs());
4315 if (dof_handler->n_locally_owned_dofs() > 0)
4317 std::vector<::types::global_dof_index>
4318 new_numbers_sorted = new_numbers;
4319 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
4322 new_numbers_sorted.begin(), new_numbers_sorted.end());
4323 my_locally_owned_new_dof_indices.
compress();
4342 std::vector<::types::global_dof_index> local_dof_indices;
4344 for (
auto cell : dof_handler->active_cell_iterators())
4345 if (cell->is_ghost())
4347 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
4348 cell->get_dof_indices(local_dof_indices);
4350 for (
unsigned int i = 0;
4351 i < cell->get_fe().n_dofs_per_cell();
4356 if ((local_dof_indices[i] !=
4358 (!dof_handler->locally_owned_dofs().is_element(
4359 local_dof_indices[i])))
4362 cell->set_dof_indices(local_dof_indices);
4368 if (dof_handler->locally_owned_dofs().n_elements() > 0)
4370 dof_handler->locally_owned_dofs(),
4381 std::vector<bool> user_flags;
4386 for (
const auto &cell : dof_handler->active_cell_iterators())
4387 if (cell->is_ghost())
4388 cell->set_user_flag();
4397 communicate_dof_indices_on_marked_cells(*dof_handler);
4407 communicate_dof_indices_on_marked_cells(*dof_handler);
4417 return number_cache;
4424 template <
int dim,
int spacedim>
4427 const unsigned int level,
4428 const std::vector<types::global_dof_index> &new_numbers)
const
4433 const IndexSet index_set = dof_handler->locally_owned_mg_dofs(
level);
4435#ifdef DEAL_II_WITH_MPI
4437 const ::parallel::TriangulationBase<dim, spacedim> *tr =
4438 (
dynamic_cast<const ::parallel::TriangulationBase<dim, spacedim>
4439 *
>(&this->dof_handler->get_triangulation()));
4442 const unsigned int my_rank =
4450 "Renumberings that change the locally owned mg dofs "
4451 "partitioning are currently not implemented for "
4452 "the multigrid levels"));
4463 std::vector<types::global_dof_index> ghosted_new_numbers(
4468 tr->get_communicator());
4469 std::vector<types::global_dof_index> temp_array(
4471 const unsigned int communication_channel = 17;
4472 std::vector<MPI_Request> requests;
4474 communication_channel,
4491 unsigned int n_ghosts_on_smaller_ranks = 0;
4492 for (std::pair<unsigned int, unsigned int> t :
4495 if (t.first > my_rank)
4497 n_ghosts_on_smaller_ranks += t.second;
4499 if (n_ghosts_on_smaller_ranks > 0)
4502 std::memmove(ghosted_new_numbers.data(),
4503 ghosted_new_numbers.data() + new_numbers.size(),
4505 n_ghosts_on_smaller_ranks);
4507 if (new_numbers.size() > 0)
4510 std::memcpy(ghosted_new_numbers.data() +
4511 n_ghosts_on_smaller_ranks,
4519 if (level < this->dof_handler->get_triangulation().n_levels() &&
4522 ghosted_new_numbers, relevant_dofs, *dof_handler,
level,
true);
4533 return number_cache;
4542#include "dof_handler_policy.inst"
ArrayView< typename std::remove_reference< typename std::iterator_traits< Iterator >::reference >::type, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
cell_iterator end() const
std::vector< std::unique_ptr<::internal::DoFHandlerImplementation::DoFLevel< dim > > > mg_levels
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
hp::FECollection< dim, spacedim > fe_collection
const hp::FECollection< dim, spacedim > & get_fe_collection() const
std::vector< MGVertexDoFs > mg_vertex_dofs
const std::vector< IndexSet > & locally_owned_dofs_per_processor() const
std::vector< std::array< std::vector< types::global_dof_index >, dim+1 > > object_dof_indices
const Triangulation< dim, spacedim > & get_triangulation() const
active_cell_iterator begin_active(const unsigned int level=0) const
bool hp_capability_enabled
types::global_dof_index n_dofs() const
cell_iterator begin(const unsigned int level=0) const
unsigned int n_dofs_per_vertex() const
unsigned int n_dofs_per_line() const
unsigned int max_dofs_per_quad() const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other, const unsigned int face_no=0) const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
size_type index_within_set(const size_type global_index) const
size_type n_elements() const
bool is_element(const size_type index) const
void add_range(const size_type begin, const size_type end)
size_type nth_index_in_set(const size_type local_index) const
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
static unsigned int n_threads()
void save_user_flags_line(std::ostream &out) const
cell_iterator begin(const unsigned int level=0) const
virtual types::subdomain_id locally_owned_subdomain() const
void save_user_flags(std::ostream &out) const
unsigned int n_levels() const
cell_iterator end() const
bool vertex_used(const unsigned int index) const
virtual unsigned int n_global_levels() const
const std::vector< bool > & get_used_vertices() const
void save_user_flags_quad(std::ostream &out) const
unsigned int n_vertices() const
unsigned int n_ghost_indices() const
const std::vector< std::pair< unsigned int, unsigned int > > & ghost_targets() 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
unsigned int this_mpi_process() const
void export_to_ghosted_array_finish(const ArrayView< Number, MemorySpaceType > &ghost_array, std::vector< MPI_Request > &requests) const
unsigned int n_import_indices() const
unsigned int size() const
unsigned int find_dominating_fe(const std::set< unsigned int > &fes, const unsigned int codim=0) const
unsigned int max_dofs_per_cell() const
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const override
ParallelDistributed(DoFHandler< dim, spacedim > &dof_handler)
virtual std::vector< NumberCache > distribute_mg_dofs() const override
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const override
virtual NumberCache distribute_dofs() const override
virtual NumberCache distribute_dofs() const override
virtual std::vector< NumberCache > distribute_mg_dofs() const override
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const override
ParallelShared(DoFHandler< dim, spacedim > &dof_handler)
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const override
virtual std::vector< NumberCache > distribute_mg_dofs() const override
virtual NumberCache distribute_dofs() const override
Sequential(DoFHandler< dim, spacedim > &dof_handler)
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const override
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const override
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
IteratorRange< active_cell_iterator > active_cell_iterators() const
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
IteratorRange< cell_iterator > cell_iterators() const
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertThrowMPI(error_code)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
void exchange_cell_data_to_ghosts(const MeshType &mesh, const std::function< std_cxx17::optional< DataType >(const typename MeshType::active_cell_iterator &)> &pack, const std::function< void(const typename MeshType::active_cell_iterator &, const DataType &)> &unpack, const std::function< bool(const typename MeshType::active_cell_iterator &)> &cell_filter=always_return< typename MeshType::active_cell_iterator, bool >{true})
void exchange_cell_data_to_level_ghosts(const MeshType &mesh, const std::function< std_cxx17::optional< DataType >(const typename MeshType::level_cell_iterator &)> &pack, const std::function< void(const typename MeshType::level_cell_iterator &, const DataType &)> &unpack, const std::function< bool(const typename MeshType::level_cell_iterator &)> &cell_filter=always_return< typename MeshType::level_cell_iterator, bool >{ true})
Task< RT > new_task(const std::function< RT()> &function)
#define DEAL_II_MPI_CONST_CAST(expr)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
constexpr const ReferenceCell Quadrilateral
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
T sum(const T &t, const MPI_Comm &mpi_communicator)
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
T unpack(const std::vector< char > &buffer, const bool allow_compression=true)
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)
const types::subdomain_id artificial_subdomain_id
const types::subdomain_id invalid_subdomain_id
static const unsigned int invalid_unsigned_int
const types::global_dof_index invalid_dof_index
unsigned int global_dof_index
unsigned int subdomain_id
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
types::global_dof_index n_global_dofs
IndexSet locally_owned_dofs
types::global_dof_index n_locally_owned_dofs
static void renumber_face_dofs(const std::vector< types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< 3, spacedim > &dof_handler)
static std::map< types::global_dof_index, types::global_dof_index > compute_quad_dof_identities(const DoFHandler< dim, spacedim > &dof_handler)
static void merge_invalid_quad_dofs_on_ghost_interfaces(DoFHandler< 3, spacedim > &dof_handler)
static void renumber_dofs(const std::vector< types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, const DoFHandler< dim, space_dim > &dof_handler, const bool check_validity)
static void renumber_face_mg_dofs(const std::vector<::types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< 3, spacedim > &dof_handler, const unsigned int level, const bool check_validity)
static void renumber_face_mg_dofs(const std::vector<::types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< 2, spacedim > &dof_handler, const unsigned int level, const bool check_validity)
static std::map< types::global_dof_index, types::global_dof_index > compute_line_dof_identities(const DoFHandler< 1, spacedim > &dof_handler)
static void merge_invalid_line_dofs_on_ghost_interfaces(DoFHandler< dim, spacedim > &dof_handler)
static types::global_dof_index enumerate_dof_indices_for_renumbering(std::vector< types::global_dof_index > &new_dof_indices, const std::vector< std::map< types::global_dof_index, types::global_dof_index > > &all_constrained_indices, const DoFHandler< dim, spacedim > &)
static types::global_dof_index unify_dof_indices(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int n_dofs_before_identification, const bool check_validity)
static void merge_invalid_dof_indices_on_ghost_interfaces(DoFHandler< dim, spacedim > &dof_handler)
static void renumber_vertex_dofs(const std::vector< types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< dim, spacedim > &dof_handler, const bool check_validity)
static void merge_invalid_vertex_dofs_on_ghost_interfaces(DoFHandler< dim, spacedim > &dof_handler)
static void renumber_cell_mg_dofs(const std::vector<::types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< dim, spacedim > &dof_handler, const unsigned int level)
static std::map< types::global_dof_index, types::global_dof_index > compute_quad_dof_identities(const DoFHandler< 3, spacedim > &dof_handler)
static void renumber_mg_dofs(const std::vector<::types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< dim, spacedim > &dof_handler, const unsigned int level, const bool check_validity)
static std::map< types::global_dof_index, types::global_dof_index > compute_vertex_dof_identities(const DoFHandler< dim, spacedim > &dof_handler)
static void merge_invalid_line_dofs_on_ghost_interfaces(DoFHandler< 1, spacedim > &dof_handler)
static void renumber_face_dofs(const std::vector< types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< 2, spacedim > &dof_handler)
static void renumber_vertex_mg_dofs(const std::vector<::types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< dim, spacedim > &dof_handler, const unsigned int level, const bool check_validity)
static void renumber_face_dofs(const std::vector< types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< dim, spacedim > &dof_handler)
static void compute_dof_identities(std::vector< std::map< types::global_dof_index, types::global_dof_index > > &all_constrained_indices, const DoFHandler< dim, spacedim > &dof_handler)
static void renumber_cell_dofs(const std::vector< types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< dim, spacedim > &dof_handler)
static std::map< types::global_dof_index, types::global_dof_index > compute_line_dof_identities(const DoFHandler< dim, spacedim > &dof_handler)
static void invalidate_dof_indices_on_weaker_ghost_cells_for_renumbering(std::vector< types::global_dof_index > &renumbering, const types::subdomain_id subdomain_id, const DoFHandler< dim, spacedim > &dof_handler)
static types::global_dof_index distribute_dofs(const types::subdomain_id subdomain_id, DoFHandler< dim, spacedim > &dof_handler)
static void merge_invalid_quad_dofs_on_ghost_interfaces(DoFHandler< dim, spacedim > &dof_handler)
static void renumber_face_mg_dofs(const std::vector< types::global_dof_index > &, const IndexSet &, DoFHandler< 1, spacedim > &, const unsigned int, const bool)
static types::global_dof_index distribute_dofs_on_level(const types::subdomain_id level_subdomain_id, DoFHandler< dim, spacedim > &dof_handler, const unsigned int level)
static void renumber_face_dofs(const std::vector< types::global_dof_index > &, const IndexSet &, DoFHandler< 1, spacedim > &)
#define DEAL_II_DOF_INDEX_MPI_TYPE