49 namespace DoFHandlerImplementation
66 std::vector<std::pair<unsigned int, unsigned int>>;
79 template <
int structdim,
int dim,
int spacedim>
80 const std::unique_ptr<DoFIdentities> &
81 ensure_existence_and_return_dof_identities(
82 const ::hp::FECollection<dim, spacedim> &fes,
85 std::unique_ptr<DoFIdentities> & identities,
93 if (identities.get() ==
nullptr)
97 std::vector<std::map<unsigned int, unsigned int>>
105 complete_identities = fes.hp_vertex_dof_identities(
106 std::set<unsigned int>{fe_index_1, fe_index_2});
113 complete_identities = fes.hp_line_dof_identities(
114 std::set<unsigned int>{fe_index_1, fe_index_2});
121 complete_identities = fes.hp_quad_dof_identities(
122 std::set<unsigned int>{fe_index_1, fe_index_2},
139 for (
const auto &complete_identity : complete_identities)
142 Assert(complete_identity.find(fe_index_1) !=
143 complete_identity.end(),
145 Assert(complete_identity.find(fe_index_2) !=
146 complete_identity.end(),
158 DoFIdentities reduced_identities;
159 for (
const auto &complete_identity : complete_identities)
161 const unsigned int dof_index_1 =
162 complete_identity.at(fe_index_1);
163 const unsigned int dof_index_2 =
164 complete_identity.at(fe_index_2);
166 reduced_identities.emplace_back(dof_index_1, dof_index_2);
172 for (
const auto &
identity : reduced_identities)
176 .template n_dofs_per_object<structdim>(face_no),
180 .template n_dofs_per_object<structdim>(face_no),
186 std::make_unique<DoFIdentities>(std::move(reduced_identities));
203 template <
int dim,
int spacedim>
204 static std::map<types::global_dof_index, types::global_dof_index>
212 std::map<types::global_dof_index, types::global_dof_index>
226 for (
unsigned int vertex_index = 0;
232 const unsigned int n_active_fe_indices =
233 ::internal::DoFAccessorImplementation::Implementation::
234 n_active_fe_indices(dof_handler,
237 std::integral_constant<int, 0>());
239 if (n_active_fe_indices > 1)
241 const std::set<types::fe_index> fe_indices =
242 ::internal::DoFAccessorImplementation::
243 Implementation::get_active_fe_indices(
247 std::integral_constant<int, 0>());
254 {fe_indices.begin(), fe_indices.end()},
261 most_dominating_fe_index =
262 ::internal::DoFAccessorImplementation::
263 Implementation::nth_active_fe_index(
268 std::integral_constant<int, 0>());
274 for (
const auto &other_fe_index : fe_indices)
275 if (other_fe_index != most_dominating_fe_index)
279 const auto &identities =
280 *ensure_existence_and_return_dof_identities<0>(
282 most_dominating_fe_index,
284 vertex_dof_identities[most_dominating_fe_index]
295 for (
const auto &
identity : identities)
298 ::internal::DoFAccessorImplementation::
299 Implementation::get_dof_index(
303 most_dominating_fe_index,
305 std::integral_constant<int, 0>());
307 dependent_dof_index =
308 ::internal::DoFAccessorImplementation::
309 Implementation::get_dof_index(
315 std::integral_constant<int, 0>());
330 if (dependent_dof_index !=
340 if (primary_dof_index !=
343 (dof_identities.find(primary_dof_index) ==
344 dof_identities.end()) ||
345 (dof_identities[dependent_dof_index] ==
349 dof_identities[dependent_dof_index] =
357 return dof_identities;
365 template <
int spacedim>
366 static std::map<types::global_dof_index, types::global_dof_index>
373 return std::map<types::global_dof_index, types::global_dof_index>();
377 template <
int dim,
int spacedim>
378 static std::map<types::global_dof_index, types::global_dof_index>
386 std::map<types::global_dof_index, types::global_dof_index>
411 std::vector<bool> line_touched(
414 for (
const auto l : cell->line_indices())
415 if (!line_touched[cell->line(l)->index()])
417 const auto line = cell->line(l);
418 line_touched[line->index()] =
true;
420 unsigned int unique_sets_of_dofs =
421 line->n_active_fe_indices();
425 const unsigned int n_active_fe_indices =
426 line->n_active_fe_indices();
427 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
428 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
431 line->nth_active_fe_index(f),
433 line->nth_active_fe_index(g);
452 dof_handler.
get_fe(fe_index_2)
458 const unsigned int dofs_per_line =
461 const auto &identities =
462 *ensure_existence_and_return_dof_identities<1>(
466 line_dof_identities[fe_index_1][fe_index_2]);
470 if (identities.size() == dofs_per_line)
473 for (; i < dofs_per_line; ++i)
474 if ((identities[i].
first != i) &&
475 (identities[i].
second != i))
479 if (i == dofs_per_line)
488 --unique_sets_of_dofs;
492 const std::set<types::fe_index> fe_indices{
493 fe_index_1, fe_index_2};
504 if (dominating_fe_index !=
507 (dominating_fe_index == fe_index_1) ?
515 dominating_fe_index = fe_index_1;
516 other_fe_index = fe_index_2;
519 for (
unsigned int j = 0; j < dofs_per_line;
523 primary_dof_index = line->dof_index(
524 j, dominating_fe_index);
526 dependent_dof_index =
527 line->dof_index(j, other_fe_index);
543 if (dependent_dof_index !=
546 if (primary_dof_index !=
553 if (dof_identities.find(
554 primary_dof_index) !=
555 dof_identities.end())
571 [primary_dof_index]) ==
572 dof_identities.end(),
576 [dependent_dof_index] =
586 (dof_identities.find(
587 primary_dof_index) ==
588 dof_identities.end()) ||
590 [dependent_dof_index] ==
595 [dependent_dof_index] =
605 [dependent_dof_index] =
625 if ((unique_sets_of_dofs == 2) && (dim == 2))
627 const std::set<types::fe_index> fe_indices =
628 line->get_active_fe_indices();
635 {fe_indices.begin(), fe_indices.end()},
648 for (
const auto &other_fe_index : fe_indices)
649 if (other_fe_index != most_dominating_fe_index)
651 const auto &identities =
652 *ensure_existence_and_return_dof_identities<
654 most_dominating_fe_index,
657 [most_dominating_fe_index]
660 for (
const auto &
identity : identities)
663 primary_dof_index = line->dof_index(
665 most_dominating_fe_index);
667 dependent_dof_index =
684 if (dependent_dof_index !=
694 if (primary_dof_index !=
696 Assert((dof_identities.find(
697 primary_dof_index) ==
698 dof_identities.end()) ||
700 [dependent_dof_index] ==
704 dof_identities[dependent_dof_index] =
713 return dof_identities;
722 template <
int dim,
int spacedim>
723 static std::map<types::global_dof_index, types::global_dof_index>
737 return std::map<types::global_dof_index, types::global_dof_index>();
741 template <
int spacedim>
742 static std::map<types::global_dof_index, types::global_dof_index>
750 std::map<types::global_dof_index, types::global_dof_index>
769 std::vector<bool> quad_touched(
772 for (
const auto q : cell->face_indices())
773 if (!quad_touched[cell->quad(q)->index()] &&
774 (cell->quad(q)->n_active_fe_indices() == 2))
776 const auto quad = cell->quad(q);
777 quad_touched[quad->index()] =
true;
779 const std::set<types::fe_index> fe_indices =
780 quad->get_active_fe_indices();
787 {fe_indices.begin(), fe_indices.end()},
790 const unsigned int most_dominating_fe_index_face_no =
791 cell->active_fe_index() == most_dominating_fe_index ?
793 cell->neighbor_face_no(q);
807 for (
const auto &other_fe_index : fe_indices)
808 if (other_fe_index != most_dominating_fe_index)
810 const auto &identities =
811 *ensure_existence_and_return_dof_identities<2>(
813 most_dominating_fe_index,
816 [most_dominating_fe_index][other_fe_index]
817 [cell->quad(q)->reference_cell() ==
819 most_dominating_fe_index_face_no);
821 for (
const auto &
identity : identities)
826 most_dominating_fe_index);
828 dependent_dof_index =
837 if (dependent_dof_index !=
847 if (primary_dof_index !=
849 Assert((dof_identities.find(
850 primary_dof_index) ==
851 dof_identities.end()) ||
853 [dependent_dof_index] ==
857 dof_identities[dependent_dof_index] =
865 return dof_identities;
874 template <
int dim,
int spacedim>
878 &all_constrained_indices,
890 all_constrained_indices[i] =
898 all_constrained_indices[i] =
907 all_constrained_indices[i] =
938 std::vector<types::global_dof_index> &new_dof_indices,
940 std::map<types::global_dof_index, types::global_dof_index>>
941 & all_constrained_indices,
945 for (
const auto &constrained_dof_indices : all_constrained_indices)
946 for (
const auto &p : constrained_dof_indices)
949 Assert(new_dof_indices[p.first] == enumeration_dof_index,
952 new_dof_indices[p.first] = p.second;
957 for (
auto &new_dof_index : new_dof_indices)
958 if (new_dof_index == enumeration_dof_index)
959 new_dof_index = next_free_dof++;
963 for (
const auto &constrained_dof_indices : all_constrained_indices)
964 for (
const auto &p : constrained_dof_indices)
967 Assert(new_dof_indices[p.first] != enumeration_dof_index,
971 new_dof_indices[p.first] = new_dof_indices[p.second];
977 Assert(new_dof_index != enumeration_dof_index,
979 Assert(new_dof_index < next_free_dof ||
984 return next_free_dof;
997 template <
int dim,
int spacedim>
1000 const unsigned int n_dofs_before_identification,
1001 const bool check_validity)
1004 return n_dofs_before_identification;
1007 std::map<types::global_dof_index, types::global_dof_index>>
1008 all_constrained_indices(dim);
1011 std::vector<::types::global_dof_index> renumbering(
1012 n_dofs_before_identification, enumeration_dof_index);
1015 all_constrained_indices,
1029 template <
int dim,
int spacedim>
1050 std::vector<bool> include_vertex(
1052 if (
dynamic_cast<const ::parallel::
1053 DistributedTriangulationBase<dim, spacedim> *
>(
1056 if (cell->is_ghost())
1057 for (
const unsigned int v : cell->vertex_indices())
1058 include_vertex[cell->vertex_index(v)] =
true;
1061 for (
unsigned int vertex_index = 0;
1066 (include_vertex[vertex_index] ==
true))
1068 const unsigned int n_active_fe_indices =
1069 ::internal::DoFAccessorImplementation::Implementation::
1070 n_active_fe_indices(dof_handler,
1073 std::integral_constant<int, 0>());
1075 if (n_active_fe_indices > 1)
1077 const std::set<types::fe_index> fe_indices =
1078 ::internal::DoFAccessorImplementation::
1079 Implementation::get_active_fe_indices(
1083 std::integral_constant<int, 0>());
1090 {fe_indices.begin(), fe_indices.end()},
1097 most_dominating_fe_index =
1098 ::internal::DoFAccessorImplementation::
1099 Implementation::nth_active_fe_index(
1104 std::integral_constant<int, 0>());
1110 for (
const auto &other_fe_index : fe_indices)
1111 if (other_fe_index != most_dominating_fe_index)
1115 const auto &identities =
1116 *ensure_existence_and_return_dof_identities<0>(
1118 most_dominating_fe_index,
1120 vertex_dof_identities[most_dominating_fe_index]
1131 for (
const auto &
identity : identities)
1134 ::internal::DoFAccessorImplementation::
1135 Implementation::get_dof_index(
1139 most_dominating_fe_index,
1141 std::integral_constant<int, 0>());
1143 dependent_dof_index =
1144 ::internal::DoFAccessorImplementation::
1145 Implementation::get_dof_index(
1151 std::integral_constant<int, 0>());
1165 if ((dependent_dof_index ==
1167 (primary_dof_index !=
1169 ::internal::DoFAccessorImplementation::
1170 Implementation::set_dof_index(
1176 std::integral_constant<int, 0>(),
1190 template <
int spacedim>
1201 template <
int dim,
int spacedim>
1211 std::vector<bool> line_marked(
1214 if (cell->is_ghost())
1215 for (
const auto l : cell->line_indices())
1216 line_marked[cell->line(l)->index()] =
true;
1241 for (
const auto l : cell->line_indices())
1242 if ((cell->is_locally_owned()) &&
1243 line_marked[cell->line(l)->index()])
1245 const auto line = cell->line(l);
1246 line_marked[line->index()] =
false;
1248 unsigned int unique_sets_of_dofs =
1249 line->n_active_fe_indices();
1253 const unsigned int n_active_fe_indices =
1254 line->n_active_fe_indices();
1255 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1256 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
1259 line->nth_active_fe_index(f),
1261 line->nth_active_fe_index(g);
1264 dof_handler.
get_fe(fe_index_2)
1270 const unsigned int dofs_per_line =
1273 const auto &identities =
1274 *ensure_existence_and_return_dof_identities<1>(
1278 line_dof_identities[fe_index_1][fe_index_2]);
1282 if (identities.size() == dofs_per_line)
1285 for (; i < dofs_per_line; ++i)
1286 if ((identities[i].
first != i) &&
1287 (identities[i].
second != i))
1291 if (i == dofs_per_line)
1300 --unique_sets_of_dofs;
1304 const std::set<types::fe_index> fe_indices{
1305 fe_index_1, fe_index_2};
1316 if (dominating_fe_index !=
1319 (dominating_fe_index == fe_index_1) ?
1327 dominating_fe_index = fe_index_1;
1328 other_fe_index = fe_index_2;
1331 for (
unsigned int j = 0; j < dofs_per_line;
1335 primary_dof_index = line->dof_index(
1336 j, dominating_fe_index);
1338 dependent_dof_index =
1339 line->dof_index(j, other_fe_index);
1354 if ((dependent_dof_index ==
1356 (primary_dof_index !=
1358 line->set_dof_index(j,
1377 if ((unique_sets_of_dofs == 2) && (dim == 2))
1379 const std::set<types::fe_index> fe_indices =
1380 line->get_active_fe_indices();
1387 {fe_indices.begin(), fe_indices.end()},
1400 for (
const auto &other_fe_index : fe_indices)
1401 if (other_fe_index != most_dominating_fe_index)
1403 const auto &identities =
1404 *ensure_existence_and_return_dof_identities<
1406 most_dominating_fe_index,
1409 [most_dominating_fe_index]
1412 for (
const auto &
identity : identities)
1415 primary_dof_index = line->dof_index(
1417 most_dominating_fe_index);
1419 dependent_dof_index =
1435 if ((dependent_dof_index ==
1437 (primary_dof_index !=
1439 line->set_dof_index(
identity.second,
1455 template <
int dim,
int spacedim>
1472 template <
int spacedim>
1483 std::vector<bool> quad_marked(
1486 if (cell->is_ghost())
1487 for (
const auto q : cell->face_indices())
1488 quad_marked[cell->quad(q)->index()] =
true;
1507 for (
const auto q : cell->face_indices())
1508 if ((cell->is_locally_owned()) &&
1509 quad_marked[cell->quad(q)->index()] &&
1510 (cell->quad(q)->n_active_fe_indices() == 2))
1512 const auto quad = cell->quad(q);
1513 quad_marked[quad->index()] =
false;
1515 const std::set<types::fe_index> fe_indices =
1516 quad->get_active_fe_indices();
1523 {fe_indices.begin(), fe_indices.end()},
1527 cell->active_fe_index() == most_dominating_fe_index ?
1529 cell->neighbor_face_no(q);
1543 for (
const auto &other_fe_index : fe_indices)
1544 if (other_fe_index != most_dominating_fe_index)
1546 const auto &identities =
1547 *ensure_existence_and_return_dof_identities<2>(
1549 most_dominating_fe_index,
1552 [most_dominating_fe_index][other_fe_index]
1553 [cell->quad(q)->reference_cell() ==
1555 most_dominating_fe_index_face_no);
1557 for (
const auto &
identity : identities)
1562 most_dominating_fe_index);
1564 dependent_dof_index =
1579 if ((dependent_dof_index ==
1581 (primary_dof_index !=
1583 quad->set_dof_index(
identity.second,
1606 template <
int dim,
int spacedim>
1647 template <
int dim,
int spacedim>
1659 if (!cell->is_artificial() &&
1661 (cell->subdomain_id() == subdomain_id)))
1666 DoFAccessorImplementation::Implementation::process_dof_indices(
1669 cell->active_fe_index(),
1670 DoFAccessorImplementation::Implementation::
1671 DoFIndexProcessor<dim, spacedim>(),
1672 [&next_free_dof](
auto &stored_index,
auto) {
1675 stored_index = next_free_dof;
1678 std::numeric_limits<types::global_dof_index>::max(),
1680 "You have reached the maximal number of degrees of "
1681 "freedom that can be stored in the chosen data "
1682 "type. In practice, this can only happen if you "
1683 "are using 32-bit data types. You will have to "
1684 "re-compile deal.II with the "
1685 "`DEAL_II_WITH_64BIT_INDICES' flag set to `ON'."));
1692 return next_free_dof;
1710 template <
int dim,
int spacedim>
1713 std::vector<types::global_dof_index> &renumbering,
1717 std::vector<types::global_dof_index> local_dof_indices;
1720 if (cell->is_ghost() && (cell->subdomain_id() < subdomain_id))
1728 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
1729 internal::DoFAccessorImplementation::Implementation::
1730 get_dof_indices(*cell,
1732 cell->active_fe_index());
1733 for (
const auto &local_dof_index : local_dof_indices)
1745 template <
int dim,
int spacedim>
1749 const unsigned int level)
1754 const ::Triangulation<dim, spacedim> &
tria =
1764 (cell->level_subdomain_id() == level_subdomain_id))
1766 DoFAccessorImplementation::Implementation::process_dof_indices(
1770 DoFAccessorImplementation::Implementation::
1771 MGDoFIndexProcessor<dim, spacedim>(
level),
1772 [&next_free_dof](
auto &stored_index,
auto) {
1775 stored_index = next_free_dof;
1778 std::numeric_limits<types::global_dof_index>::max(),
1780 "You have reached the maximal number of degrees of "
1781 "freedom that can be stored in the chosen data "
1782 "type. In practice, this can only happen if you "
1783 "are using 32-bit data types. You will have to "
1784 "re-compile deal.II with the "
1785 "`DEAL_II_WITH_64BIT_INDICES' flag set to `ON'."));
1792 return next_free_dof;
1807 template <
int dim,
int spacedim>
1810 const std::vector<types::global_dof_index> &new_numbers,
1811 const IndexSet & indices_we_care_about,
1814 for (
unsigned int d = 1; d < dim; ++d)
1817 i = ((indices_we_care_about.
size() == 0) ?
1824 template <
int dim,
int spacedim>
1827 const std::vector<types::global_dof_index> &new_numbers,
1828 const IndexSet & indices_we_care_about,
1830 const bool check_validity)
1840 for (std::vector<types::global_dof_index>::iterator i =
1846 (indices_we_care_about.
size() == 0) ?
1849 else if (check_validity)
1860 for (
unsigned int vertex_index = 0;
1864 const unsigned int n_active_fe_indices =
1865 ::internal::DoFAccessorImplementation::Implementation::
1866 n_active_fe_indices(dof_handler,
1869 std::integral_constant<int, 0>());
1883 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1886 ::internal::DoFAccessorImplementation::
1887 Implementation::nth_active_fe_index(
1892 std::integral_constant<int, 0>());
1894 for (
unsigned int d = 0;
1895 d < dof_handler.
get_fe(fe_index).n_dofs_per_vertex();
1899 ::internal::DoFAccessorImplementation::
1900 Implementation::get_dof_index(
1906 std::integral_constant<int, 0>());
1937 if (indices_we_care_about.
size() == 0)
1938 ::internal::DoFAccessorImplementation::
1939 Implementation::set_dof_index(
1945 std::integral_constant<int, 0>(),
1946 new_numbers[old_dof_index]);
1951 ::internal::DoFAccessorImplementation::
1952 Implementation::set_dof_index(
1958 std::integral_constant<int, 0>(),
1959 new_numbers[indices_we_care_about
1963 ::internal::DoFAccessorImplementation::
1964 Implementation::set_dof_index(
1970 std::integral_constant<int, 0>(),
1981 template <
int dim,
int spacedim>
1984 const std::vector<types::global_dof_index> &new_numbers,
1985 const IndexSet & indices_we_care_about,
1990 for (
unsigned int level = 0;
1995 i = ((indices_we_care_about.
size() == 0) ?
2003 if (!cell->is_artificial())
2007 for (
unsigned int d = 0;
2008 d < dof_handler.
get_fe(fe_index)
2009 .template n_dofs_per_object<dim>();
2013 cell->dof_index(d, fe_index);
2030 if (indices_we_care_about.
size() == 0)
2031 cell->set_dof_index(d,
2032 new_numbers[old_dof_index],
2036 if (indices_we_care_about.
is_element(old_dof_index))
2037 cell->set_dof_index(
2039 new_numbers[indices_we_care_about
2043 cell->set_dof_index(d,
2054 template <
int spacedim>
2057 const std::vector<types::global_dof_index> & ,
2067 template <
int spacedim>
2070 const std::vector<types::global_dof_index> &new_numbers,
2071 const IndexSet & indices_we_care_about,
2074 const unsigned int dim = 2;
2078 for (
unsigned int d = 1; d < dim; ++d)
2081 i = ((indices_we_care_about.
size() == 0) ?
2090 std::vector<bool> line_touched(
2093 if (!cell->is_artificial())
2094 for (
const auto l : cell->line_indices())
2095 if (!line_touched[cell->line(l)->index()])
2097 const auto line = cell->line(l);
2098 line_touched[line->index()] =
true;
2100 const unsigned int n_active_fe_indices =
2101 line->n_active_fe_indices();
2103 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2106 line->nth_active_fe_index(f);
2108 for (
unsigned int d = 0;
2114 line->dof_index(d, fe_index);
2134 if (indices_we_care_about.
size() == 0)
2135 line->set_dof_index(
2136 d, new_numbers[old_dof_index], fe_index);
2141 line->set_dof_index(
2143 new_numbers[indices_we_care_about
2148 line->set_dof_index(
2162 template <
int spacedim>
2165 const std::vector<types::global_dof_index> &new_numbers,
2166 const IndexSet & indices_we_care_about,
2169 const unsigned int dim = 3;
2173 for (
unsigned int d = 1; d < dim; ++d)
2176 i = ((indices_we_care_about.
size() == 0) ?
2185 std::vector<bool> line_touched(
2188 if (!cell->is_artificial())
2189 for (
const auto l : cell->line_indices())
2190 if (!line_touched[cell->line(l)->index()])
2192 const auto line = cell->line(l);
2193 line_touched[line->index()] =
true;
2195 const unsigned int n_active_fe_indices =
2196 line->n_active_fe_indices();
2198 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2201 line->nth_active_fe_index(f);
2203 for (
unsigned int d = 0;
2209 line->dof_index(d, fe_index);
2229 if (indices_we_care_about.
size() == 0)
2230 line->set_dof_index(
2231 d, new_numbers[old_dof_index], fe_index);
2234 line->set_dof_index(
2236 new_numbers[indices_we_care_about
2241 line->set_dof_index(
2251 std::vector<bool> quad_touched(
2254 if (!cell->is_artificial())
2255 for (
const auto q : cell->face_indices())
2256 if (!quad_touched[cell->quad(q)->index()])
2258 const auto quad = cell->quad(q);
2259 quad_touched[quad->index()] =
true;
2261 const unsigned int n_active_fe_indices =
2262 quad->n_active_fe_indices();
2264 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2267 quad->nth_active_fe_index(f);
2269 for (
unsigned int d = 0;
2275 quad->dof_index(d, fe_index);
2295 if (indices_we_care_about.
size() == 0)
2296 quad->set_dof_index(
2297 d, new_numbers[old_dof_index], fe_index);
2302 quad->set_dof_index(
2304 new_numbers[indices_we_care_about
2309 quad->set_dof_index(
2334 template <
int dim,
int space_dim>
2337 const IndexSet & indices_we_care_about,
2339 const bool check_validity)
2350 indices_we_care_about,
2357 indices_we_care_about,
2363 indices_we_care_about,
2382 template <
int dim,
int spacedim>
2385 const std::vector<::types::global_dof_index> &new_numbers,
2386 const IndexSet & indices_we_care_about,
2388 const unsigned int level)
2397 if ((i->get_coarsest_level() <=
level) &&
2398 (i->get_finest_level() >=
level))
2399 for (
unsigned int d = 0;
2403 const ::types::global_dof_index idx =
2404 i->access_index(
level,
2412 (idx < new_numbers.size()),
2416 (indices_we_care_about.
size() == 0) ?
2433 template <
int dim,
int spacedim>
2436 const std::vector<::types::global_dof_index> &new_numbers,
2437 const IndexSet & indices_we_care_about,
2439 const unsigned int level)
2441 for (std::vector<types::global_dof_index>::iterator i =
2450 (*i < new_numbers.size())),
2453 (indices_we_care_about.
size() == 0) ?
2469 template <
int spacedim>
2472 const std::vector<types::global_dof_index> & ,
2475 const unsigned int ,
2483 template <
int dim,
int spacedim>
2486 const std::vector<::types::global_dof_index> &new_numbers,
2487 const IndexSet & indices_we_care_about,
2489 const unsigned int level,
2490 const bool check_validity)
2492 const unsigned int dofs_per_line =
2494 if (dofs_per_line > 0 ||
2500 std::vector<bool> line_touched(
2502 std::vector<bool> quad_touched(
2504 for (
const auto &cell :
2506 if (cell->level_subdomain_id() !=
2510 if (dofs_per_line > 0)
2512 const auto line_indices =
2513 internal::TriaAccessorImplementation::Implementation::
2514 get_line_indices_of_cell(*cell);
2515 for (
const auto line : cell->line_indices())
2517 if (!line_touched[line_indices[line]])
2519 line_touched[line_indices[line]] =
true;
2521 &internal::DoFAccessorImplementation::
2522 Implementation::get_mg_dof_index(
2529 std::integral_constant<int, 1>());
2530 for (
unsigned int d = 0; d < dofs_per_line; ++d)
2540 (indices_we_care_about.
size() == 0) ?
2541 new_numbers[indices[d]] :
2542 new_numbers[indices_we_care_about
2552 for (
const auto quad : cell->face_indices())
2553 if (!quad_touched[cell->quad(quad)->index()])
2555 quad_touched[cell->quad(quad)->index()] =
true;
2556 const unsigned int dofs_per_quad =
2558 if (dofs_per_quad > 0)
2561 &internal::DoFAccessorImplementation::
2562 Implementation::get_mg_dof_index(
2566 cell->quad(quad)->index(),
2569 std::integral_constant<int, 2>());
2570 for (
unsigned int d = 0; d < dofs_per_quad; ++d)
2580 (indices_we_care_about.
size() == 0) ?
2581 new_numbers[indices[d]] :
2582 new_numbers[indices_we_care_about
2594 template <
int dim,
int spacedim>
2597 const std::vector<::types::global_dof_index> &new_numbers,
2598 const IndexSet & indices_we_care_about,
2600 const unsigned int level,
2601 const bool check_validity)
2616 indices_we_care_about,
2622 indices_we_care_about,
2629 indices_we_care_about,
2643 template <
int dim,
int spacedim>
2646 : dof_handler(&dof_handler)
2651 template <
int dim,
int spacedim>
2670 template <
int dim,
int spacedim>
2671 std::vector<NumberCache>
2674 std::vector<NumberCache> number_caches;
2675 number_caches.reserve(dof_handler->get_triangulation().n_levels());
2676 for (
unsigned int level = 0;
2677 level < dof_handler->get_triangulation().n_levels();
2686 number_caches.emplace_back(n_level_dofs);
2689 return number_caches;
2694 template <
int dim,
int spacedim>
2697 const std::vector<types::global_dof_index> &new_numbers)
const
2712 if (new_numbers.size() == 0)
2716 *std::max_element(new_numbers.begin(), new_numbers.end()) + 1);
2721 template <
int dim,
int spacedim>
2724 const unsigned int level,
2725 const std::vector<types::global_dof_index> &new_numbers)
const
2738 template <
int dim,
int spacedim>
2741 : dof_handler(&dof_handler)
2756 template <
int dim,
int spacedim>
2757 std::vector<types::subdomain_id>
2758 get_dof_subdomain_association(
2761 const unsigned int n_procs)
2764 std::vector<types::subdomain_id> subdomain_association(
2766 std::vector<types::global_dof_index> local_dof_indices;
2767 local_dof_indices.reserve(
2772 for (
const auto &cell : dof_handler.active_cell_iterators())
2779 const unsigned int dofs_per_cell =
2780 cell->get_fe().n_dofs_per_cell();
2781 local_dof_indices.resize(dofs_per_cell);
2782 internal::DoFAccessorImplementation::Implementation::
2783 get_dof_indices(*cell,
2785 cell->active_fe_index());
2790 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2791 if (subdomain_association[local_dof_indices[i]] ==
2793 subdomain_association[local_dof_indices[i]] = subdomain_id;
2794 else if (subdomain_association[local_dof_indices[i]] >
2797 subdomain_association[local_dof_indices[i]] = subdomain_id;
2801 Assert(std::find(subdomain_association.begin(),
2802 subdomain_association.end(),
2804 subdomain_association.end(),
2807 Assert(*std::max_element(subdomain_association.begin(),
2808 subdomain_association.end()) < n_procs,
2811 return subdomain_association;
2821 template <
int dim,
int spacedim>
2822 std::vector<types::subdomain_id>
2823 get_dof_level_subdomain_association(
2826 const unsigned int n_procs,
2827 const unsigned int level)
2830 std::vector<types::subdomain_id> level_subdomain_association(
2832 std::vector<types::global_dof_index> local_dof_indices;
2833 local_dof_indices.reserve(
2838 for (
const auto &cell : dof_handler.cell_iterators_on_level(
level))
2844 cell->level_subdomain_id();
2845 const unsigned int dofs_per_cell =
2846 cell->get_fe().n_dofs_per_cell();
2847 local_dof_indices.resize(dofs_per_cell);
2848 cell->get_mg_dof_indices(local_dof_indices);
2853 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2854 if (level_subdomain_association[local_dof_indices[i]] ==
2856 level_subdomain_association[local_dof_indices[i]] =
2858 else if (level_subdomain_association[local_dof_indices[i]] >
2861 level_subdomain_association[local_dof_indices[i]] =
2866 Assert(std::find(level_subdomain_association.begin(),
2867 level_subdomain_association.end(),
2869 level_subdomain_association.end(),
2872 Assert(*std::max_element(level_subdomain_association.begin(),
2873 level_subdomain_association.end()) < n_procs,
2876 return level_subdomain_association;
2882 template <
int dim,
int spacedim>
2886 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
2888 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
2892 const unsigned int n_procs =
2902 const internal::parallel::shared::
2903 TemporarilyRestoreSubdomainIds<dim, spacedim>
2904 subdomain_modifier(*tr);
2910 *this->dof_handler);
2926 std::vector<types::global_dof_index> new_dof_indices(
2927 n_dofs, enumeration_dof_index);
2931 const std::vector<types::subdomain_id> subdomain_association =
2932 get_dof_subdomain_association(*this->dof_handler, n_dofs, n_procs);
2943 if (subdomain_association[i] == subdomain)
2945 Assert(new_dof_indices[i] == enumeration_dof_index,
2947 new_dof_indices[i] = next_free_index;
2953 Assert(std::find(new_dof_indices.begin(),
2954 new_dof_indices.end(),
2955 enumeration_dof_index) == new_dof_indices.end(),
2976 const std::vector<types::subdomain_id> subdomain_association =
2977 get_dof_subdomain_association(*this->dof_handler, n_dofs, n_procs);
2979 for (
unsigned int i = 1; i < n_dofs; ++i)
2980 Assert(subdomain_association[i] >= subdomain_association[i - 1],
2983 std::vector<IndexSet> locally_owned_dofs_per_processor(
2994 unsigned int start_index = 0;
2995 unsigned int end_index = 0;
2996 while (start_index < n_dofs)
2998 while ((end_index) < n_dofs &&
2999 (subdomain_association[end_index] ==
3000 subdomain_association[start_index]))
3005 if (end_index > start_index)
3007 const unsigned int subdomain_owner =
3008 subdomain_association[start_index];
3009 locally_owned_dofs_per_processor[subdomain_owner].add_range(
3010 start_index, end_index);
3014 start_index = end_index;
3021 locally_owned_dofs_per_processor,
3027 template <
int dim,
int spacedim>
3028 std::vector<NumberCache>
3031 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3033 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3037 AssertThrow((tr->is_multilevel_hierarchy_constructed()),
3039 "Multigrid DoFs can only be distributed on a parallel "
3040 "Triangulation if the flag construct_multigrid_hierarchy "
3041 "is set in the constructor."));
3043 const unsigned int n_procs =
3045 const unsigned int n_levels = tr->n_global_levels();
3047 std::vector<NumberCache> number_caches;
3048 number_caches.reserve(n_levels);
3051 for (
unsigned int lvl = 0; lvl < n_levels; ++lvl)
3059 std::vector<types::subdomain_id> saved_level_subdomain_ids;
3060 saved_level_subdomain_ids.resize(tr->n_cells(lvl));
3062 typename ::parallel::shared::Triangulation<dim, spacedim>::
3063 cell_iterator cell =
3069 const std::vector<types::subdomain_id> &true_level_subdomain_ids =
3070 tr->get_true_level_subdomain_ids_of_cells(lvl);
3072 for (
unsigned int index = 0; cell != endc; ++cell, ++
index)
3074 saved_level_subdomain_ids[
index] = cell->level_subdomain_id();
3075 cell->set_level_subdomain_id(true_level_subdomain_ids[
index]);
3094 std::vector<types::global_dof_index> new_dof_indices(
3099 const std::vector<types::subdomain_id>
3100 level_subdomain_association =
3101 get_dof_level_subdomain_association(*this->dof_handler,
3113 level_subdomain < n_procs;
3116 if (level_subdomain_association[i] == level_subdomain)
3120 new_dof_indices[i] = next_free_index;
3126 Assert(std::find(new_dof_indices.begin(),
3127 new_dof_indices.end(),
3129 new_dof_indices.end(),
3138 new_dof_indices,
IndexSet(0), *this->dof_handler, lvl,
true);
3150 const std::vector<types::subdomain_id> level_subdomain_association =
3151 get_dof_level_subdomain_association(*this->dof_handler,
3156 for (
unsigned int i = 1; i < n_dofs_on_level; ++i)
3157 Assert(level_subdomain_association[i] >=
3158 level_subdomain_association[i - 1],
3161 std::vector<IndexSet> locally_owned_dofs_per_processor(
3162 n_procs,
IndexSet(n_dofs_on_level));
3172 unsigned int start_index = 0;
3173 unsigned int end_index = 0;
3174 while (start_index < n_dofs_on_level)
3176 while ((end_index) < n_dofs_on_level &&
3177 (level_subdomain_association[end_index] ==
3178 level_subdomain_association[start_index]))
3183 if (end_index > start_index)
3185 const unsigned int level_subdomain_owner =
3186 level_subdomain_association[start_index];
3187 locally_owned_dofs_per_processor[level_subdomain_owner]
3188 .add_range(start_index, end_index);
3192 start_index = end_index;
3198 typename ::parallel::shared::Triangulation<dim, spacedim>::
3199 cell_iterator cell =
3205 for (
unsigned int index = 0; cell != endc; ++cell, ++
index)
3206 cell->set_level_subdomain_id(saved_level_subdomain_ids[
index]);
3209 number_caches.emplace_back(
3216 return number_caches;
3221 template <
int dim,
int spacedim>
3224 const std::vector<types::global_dof_index> &new_numbers)
const
3226#ifndef DEAL_II_WITH_MPI
3233 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3235 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3240 const internal::parallel::shared::
3241 TemporarilyRestoreSubdomainIds<dim, spacedim>
3242 subdomain_modifier(*tr);
3244 std::vector<types::global_dof_index> global_gathered_numbers(
3245 this->dof_handler->
n_dofs(), 0);
3250 const bool uses_sequential_numbering =
3251 new_numbers.size() == this->dof_handler->
n_dofs();
3252 bool all_use_sequential_numbering =
false;
3253 Utilities::MPI::internal::all_reduce<bool>(
3256 tr->get_communicator(),
3258 if (all_use_sequential_numbering)
3260 global_gathered_numbers = new_numbers;
3264 Assert(new_numbers.size() ==
3265 this->dof_handler->locally_owned_dofs().n_elements(),
3267 const unsigned int n_cpu =
3269 std::vector<types::global_dof_index> gathered_new_numbers(
3270 this->dof_handler->
n_dofs(), 0);
3272 this->dof_handler->get_triangulation()
3273 .locally_owned_subdomain(),
3278 std::vector<types::global_dof_index> new_numbers_copy(
3283 std::vector<int> rcounts(n_cpu);
3287 int cur_count = new_numbers_copy.size();
3288 int ierr = MPI_Allgather(&cur_count,
3294 tr->get_communicator());
3299 std::vector<int> displacements(n_cpu);
3300 for (
unsigned int i = 0; i < n_cpu; ++i)
3302 displacements[i] = shift;
3303 shift += rcounts[i];
3305 Assert(new_numbers_copy.size() ==
3306 static_cast<unsigned int>(
3308 tr->get_communicator())]),
3310 ierr = MPI_Allgatherv(new_numbers_copy.data(),
3311 new_numbers_copy.size(),
3313 gathered_new_numbers.data(),
3315 displacements.data(),
3317 tr->get_communicator());
3327 std::vector<unsigned int> flag_1(this->dof_handler->
n_dofs(), 0);
3328 std::vector<unsigned int> flag_2(this->dof_handler->
n_dofs(), 0);
3329 std::vector<IndexSet> locally_owned_dofs_per_processor =
3331 tr->get_communicator(),
3332 this->dof_handler->locally_owned_dofs());
3333 for (
unsigned int i = 0; i < n_cpu; ++i)
3335 const IndexSet iset = locally_owned_dofs_per_processor[i];
3342 gathered_new_numbers[shift + ind];
3347 global_gathered_numbers[target] =
value;
3354 Assert(*std::max_element(flag_1.begin(), flag_1.end()) == 1,
3356 Assert(*std::min_element(flag_1.begin(), flag_1.end()) == 1,
3358 Assert((*std::max_element(flag_2.begin(), flag_2.end())) == 1,
3360 Assert((*std::min_element(flag_2.begin(), flag_2.end())) == 1,
3376 return number_cache;
3382 template <
int dim,
int spacedim>
3385 const unsigned int ,
3386 const std::vector<types::global_dof_index> & )
const
3398#ifdef DEAL_II_WITH_MPI
3402 template <
int dim,
int spacedim>
3405 std::vector<std::vector<bool>> &cell_marked)
3407 const auto pack = [](
const auto &cell) {
3411 std::vector<::types::global_dof_index> data(
3412 cell->get_fe().n_dofs_per_cell());
3413 cell->get_mg_dof_indices(data);
3418 const auto unpack = [&cell_marked](
const auto &cell,
3420 Assert(cell->get_fe().n_dofs_per_cell() == dofs.size(),
3423 Assert(cell->level_subdomain_id() !=
3427 bool complete =
true;
3428 DoFAccessorImplementation::Implementation::process_dof_indices(
3432 DoFAccessorImplementation::Implementation::
3433 MGDoFIndexProcessor<dim, spacedim>(cell->
level()),
3443 [&complete, invalid_dof_index =
numbers::invalid_dof_index](
3444 auto &stored_index, auto received_index) {
3445 if (*received_index != invalid_dof_index)
3447# if !defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1900
3448 Assert((stored_index == invalid_dof_index) ||
3449 (stored_index == *received_index),
3452 stored_index = *received_index;
3462 Assert(cell_marked[cell->level()][cell->index()],
3466 cell_marked[cell->level()][cell->index()] =
false;
3469 const auto filter = [&cell_marked](
const auto &cell) {
3470 return cell_marked[cell->level()][cell->index()];
3474 std::vector<types::global_dof_index>,
3498 template <
int dim,
int spacedim>
3500 communicate_dof_indices_on_marked_cells(
3502 std::vector<bool> & cell_marked)
3504# ifndef DEAL_II_WITH_MPI
3512 const auto pack = [](
const auto &cell) {
3515 std::vector<::types::global_dof_index> data(
3516 cell->get_fe().n_dofs_per_cell());
3519 internal::DoFAccessorImplementation::Implementation::
3520 get_dof_indices(*cell, data, cell->active_fe_index());
3525 const auto unpack = [&cell_marked](
const auto &cell,
3527 Assert(cell->get_fe().n_dofs_per_cell() == dofs.size(),
3535 bool complete =
true;
3536 DoFAccessorImplementation::Implementation::process_dof_indices(
3539 cell->active_fe_index(),
3540 DoFAccessorImplementation::Implementation::
3541 DoFIndexProcessor<dim, spacedim>(),
3552 auto &stored_index, const auto received_index) {
3553 if (*received_index != invalid_dof_index)
3555# if !defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1900
3556 Assert((stored_index == invalid_dof_index) ||
3557 (stored_index == *received_index),
3560 stored_index = *received_index;
3570 Assert(cell_marked[cell->active_cell_index()],
3574 cell_marked[cell->active_cell_index()] =
false;
3577 const auto filter = [&cell_marked](
const auto &cell) {
3578 return cell_marked[cell->active_cell_index()];
3582 std::vector<types::global_dof_index>,
3595 template <
int dim,
int spacedim>
3598 : dof_handler(&dof_handler)
3603 template <
int dim,
int spacedim>
3607#ifndef DEAL_II_WITH_MPI
3656 std::vector<::types::global_dof_index> renumbering(
3657 n_initial_local_dofs, enumeration_dof_index);
3664 renumbering, subdomain_id, *dof_handler);
3668 std::vector<std::map<types::global_dof_index, types::global_dof_index>>
3669 all_constrained_indices(dim);
3684 for (
const auto &constrained_indices : all_constrained_indices)
3685 for (
const auto &
index : constrained_indices)
3687 ++n_identity_constrained_indices;
3690 std::count(renumbering.begin(),
3692 enumeration_dof_index) -
3693 n_identity_constrained_indices;
3698 const int ierr = MPI_Exscan(&n_locally_owned_dofs,
3708 renumbering, all_constrained_indices, my_shift);
3719 const ::types::global_dof_index n_global_dofs =
3729 n_locally_owned_dofs);
3743 std::vector<bool> cell_marked(
triangulation->n_active_cells());
3745 if (cell->is_ghost())
3746 cell_marked[cell->active_cell_index()] =
true;
3754 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
3767 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
3773 Assert(cell_marked[cell->active_cell_index()] ==
false,
3781 std::vector<::types::global_dof_index> local_dof_indices;
3784 if (!cell->is_artificial())
3786 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
3787 cell->get_dof_indices(local_dof_indices);
3788 if (local_dof_indices.end() !=
3789 std::find(local_dof_indices.begin(),
3790 local_dof_indices.end(),
3793 if (cell->is_ghost())
3797 "A ghost cell ended up with incomplete "
3798 "DoF index information. This should not "
3806 "A locally owned cell ended up with incomplete "
3807 "DoF index information. This should not "
3814 return number_cache;
3820 template <
int dim,
int spacedim>
3821 std::vector<NumberCache>
3824#ifndef DEAL_II_WITH_MPI
3826 return std::vector<NumberCache>();
3839 "Multigrid DoFs can only be distributed on a parallel "
3840 "Triangulation if the flag construct_multigrid_hierarchy "
3841 "is set in the constructor."));
3848 const unsigned int n_levels =
triangulation->n_global_levels();
3849 std::vector<NumberCache> number_caches;
3850 number_caches.reserve(n_levels);
3856 const unsigned int n_initial_local_dofs =
3862 std::vector<::types::global_dof_index> renumbering(
3863 n_initial_local_dofs, enumeration_dof_index);
3865 if (level < triangulation->n_levels())
3867 std::vector<::types::global_dof_index> local_dof_indices;
3869 for (
const auto &cell :
3871 if (cell->level_subdomain_id() !=
3873 (cell->level_subdomain_id() <
3883 local_dof_indices.resize(
3884 cell->get_fe().n_dofs_per_cell());
3885 cell->get_mg_dof_indices(local_dof_indices);
3886 for (
unsigned int i = 0;
3887 i < cell->get_fe().n_dofs_per_cell();
3890 renumbering[local_dof_indices[i]] =
3896 std::count(renumbering.begin(),
3898 enumeration_dof_index);
3927 if (
index == enumeration_dof_index)
3938 if (level < triangulation->n_levels())
3949 number_caches.emplace_back(level_number_cache);
3958 std::vector<std::vector<bool>> cell_marked(
triangulation->n_levels());
3959 for (
unsigned int l = 0; l <
triangulation->n_levels(); ++l)
3962 if (cell->is_ghost_on_level())
3963 cell_marked[cell->level()][cell->index()] =
true;
3968 communicate_mg_ghost_cells(*dof_handler, cell_marked);
3972 communicate_mg_ghost_cells(*dof_handler, cell_marked);
3977 Assert(cell_marked[cell->level()][cell->index()] ==
false,
3987 std::vector<::types::global_dof_index> local_dof_indices;
3989 if (cell->level_subdomain_id() !=
3992 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
3993 cell->get_mg_dof_indices(local_dof_indices);
3994 if (local_dof_indices.end() !=
3995 std::find(local_dof_indices.begin(),
3996 local_dof_indices.end(),
4005 return number_caches;
4011 template <
int dim,
int spacedim>
4014 const std::vector<::types::global_dof_index> &new_numbers)
const
4021#ifndef DEAL_II_WITH_MPI
4039 const bool locally_owned_set_changes =
4040 std::any_of(new_numbers.cbegin(),
4043 return owned_dofs.is_element(i) == false;
4046 IndexSet my_locally_owned_new_dof_indices = owned_dofs;
4047 if (locally_owned_set_changes && owned_dofs.
n_elements() > 0)
4049 std::vector<::types::global_dof_index> new_numbers_sorted =
4051 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
4053 my_locally_owned_new_dof_indices =
IndexSet(dof_handler->
n_dofs());
4055 new_numbers_sorted.begin(), new_numbers_sorted.end());
4056 my_locally_owned_new_dof_indices.
compress();
4075 if (cell->is_ghost())
4077 DoFAccessorImplementation::Implementation::process_dof_indices(
4080 cell->active_fe_index(),
4081 DoFAccessorImplementation::Implementation::
4082 DoFIndexProcessor<dim, spacedim>(),
4083 [&owned_dofs](
auto &stored_index,
auto) {
4110 std::vector<bool> cell_marked(
triangulation->n_active_cells());
4112 if (cell->is_ghost())
4113 cell_marked[cell->active_cell_index()] =
true;
4121 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
4131 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
4139 return number_cache;
4145 template <
int dim,
int spacedim>
4148 const unsigned int level,
4149 const std::vector<types::global_dof_index> &new_numbers)
const
4151#ifndef DEAL_II_WITH_MPI
4174 const bool locally_owned_set_changes =
4175 std::any_of(new_numbers.cbegin(),
4178 return owned_dofs.is_element(i) == false;
4181 IndexSet my_locally_owned_new_dof_indices = owned_dofs;
4182 if (locally_owned_set_changes && owned_dofs.
n_elements() > 0)
4184 std::vector<::types::global_dof_index> new_numbers_sorted =
4186 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
4188 my_locally_owned_new_dof_indices =
4191 new_numbers_sorted.begin(), new_numbers_sorted.end());
4192 my_locally_owned_new_dof_indices.
compress();
4202 if (cell->is_ghost_on_level())
4204 DoFAccessorImplementation::Implementation::process_dof_indices(
4208 DoFAccessorImplementation::Implementation::
4209 MGDoFIndexProcessor<dim, spacedim>(cell->level()),
4210 [&owned_dofs](
auto &stored_index,
auto) {
4219 if (level < triangulation->n_levels() && owned_dofs.
n_elements() > 0)
4221 new_numbers, owned_dofs, *dof_handler,
level,
false);
4225 std::vector<std::vector<bool>> cell_marked(
triangulation->n_levels());
4226 for (
unsigned int l = 0; l <
triangulation->n_levels(); ++l)
4229 if (cell->is_ghost_on_level())
4230 cell_marked[cell->level()][cell->index()] =
true;
4232 communicate_mg_ghost_cells(*dof_handler, cell_marked);
4234 communicate_mg_ghost_cells(*dof_handler, cell_marked);
4242 return number_cache;
4252#include "dof_handler_policy.inst"
std::vector< std::unique_ptr<::internal::DoFHandlerImplementation::DoFLevel< dim > > > mg_levels
hp::FECollection< dim, spacedim > fe_collection
const hp::FECollection< dim, spacedim > & get_fe_collection() const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
const IndexSet & locally_owned_mg_dofs(const unsigned int level) const
std::vector< MGVertexDoFs > mg_vertex_dofs
std::vector< std::array< std::vector< types::global_dof_index >, dim+1 > > object_dof_indices
const Triangulation< dim, spacedim > & get_triangulation() const
const IndexSet & locally_owned_dofs() const
std::unique_ptr<::internal::DoFHandlerImplementation::DoFFaces< dim > > mg_faces
bool hp_capability_enabled
types::global_dof_index n_dofs() const
types::global_dof_index n_locally_owned_dofs() const
unsigned int n_dofs_per_vertex() const
unsigned int n_dofs_per_line() const
unsigned int max_dofs_per_quad() const
unsigned int n_dofs_per_quad(unsigned int face_no=0) 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)
cell_iterator begin(const unsigned int level=0) const
unsigned int n_raw_lines() const
virtual types::subdomain_id locally_owned_subdomain() 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
unsigned int n_raw_quads() const
const std::vector< bool > & get_used_vertices() const
unsigned int n_vertices() 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 AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
Task< RT > new_task(const std::function< RT()> &function)
constexpr const ReferenceCell Quadrilateral
T sum(const T &t, const MPI_Comm mpi_communicator)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
std::vector< T > all_gather(const MPI_Comm comm, const T &object_to_send)
unsigned int this_mpi_process(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)
const types::fe_index invalid_fe_index
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 short int fe_index
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_face_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_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 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 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 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)
static std::map< types::global_dof_index, types::global_dof_index > compute_vertex_dof_identities(const 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 types::global_dof_index start_dof_index)
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_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 > &)
const ::Triangulation< dim, spacedim > & tria
#define DEAL_II_DOF_INDEX_MPI_TYPE