49 namespace DoFHandlerImplementation
73 template <
int dim,
int spacedim>
75 update_all_active_cell_dof_indices_caches(
78 const auto worker = [](
const auto &cell,
void *,
void *) {
79 if (!cell->is_artificial())
80 cell->update_cell_dof_indices_cache();
92 std::function<
void(
void *)>(),
104 template <
int dim,
int spacedim>
106 update_all_level_cell_dof_indices_caches(
109 const auto worker = [](
const auto &cell,
void *,
void *) {
110 if (cell->has_children() || !cell->is_artificial())
111 cell->update_cell_dof_indices_cache();
123 std::function<
void(
void *)>(),
131 using DoFIdentities =
132 std::vector<std::pair<unsigned int, unsigned int>>;
145 template <
int structdim,
int dim,
int spacedim>
146 const std::unique_ptr<DoFIdentities> &
147 ensure_existence_and_return_dof_identities(
148 const ::hp::FECollection<dim, spacedim> &fes,
149 const unsigned int fe_index_1,
150 const unsigned int fe_index_2,
151 std::unique_ptr<DoFIdentities> & identities,
159 if (identities.get() ==
nullptr)
161 std::vector<std::map<unsigned int, unsigned int>>
168 complete_identities =
169 fes.hp_vertex_dof_identities({fe_index_1, fe_index_2});
175 complete_identities =
176 fes.hp_line_dof_identities({fe_index_1, fe_index_2});
182 complete_identities =
183 fes.hp_quad_dof_identities({fe_index_1, fe_index_2},
200 for (
const auto &complete_identity : complete_identities)
203 Assert(complete_identity.find(fe_index_1) !=
204 complete_identity.end(),
206 Assert(complete_identity.find(fe_index_2) !=
207 complete_identity.end(),
219 DoFIdentities reduced_identities;
220 for (
const auto &complete_identity : complete_identities)
222 const unsigned int dof_index_1 =
223 complete_identity.at(fe_index_1);
224 const unsigned int dof_index_2 =
225 complete_identity.at(fe_index_2);
227 reduced_identities.emplace_back(dof_index_1, dof_index_2);
233 for (
const auto &
identity : reduced_identities)
237 .template n_dofs_per_object<structdim>(face_no),
241 .template n_dofs_per_object<structdim>(face_no),
247 std::make_unique<DoFIdentities>(std::move(reduced_identities));
264 template <
int dim,
int spacedim>
265 static std::map<types::global_dof_index, types::global_dof_index>
273 std::map<types::global_dof_index, types::global_dof_index>
287 for (
unsigned int vertex_index = 0;
293 const unsigned int n_active_fe_indices =
294 ::internal::DoFAccessorImplementation::Implementation::
295 n_active_fe_indices(dof_handler,
298 std::integral_constant<int, 0>());
300 if (n_active_fe_indices > 1)
302 const std::set<unsigned int> fe_indices =
303 ::internal::DoFAccessorImplementation::
304 Implementation::get_active_fe_indices(
308 std::integral_constant<int, 0>());
312 unsigned int most_dominating_fe_index =
319 if (most_dominating_fe_index ==
321 most_dominating_fe_index =
322 ::internal::DoFAccessorImplementation::
323 Implementation::nth_active_fe_index(
328 std::integral_constant<int, 0>());
334 for (
const auto &other_fe_index : fe_indices)
335 if (other_fe_index != most_dominating_fe_index)
339 const auto &identities =
340 *ensure_existence_and_return_dof_identities<0>(
342 most_dominating_fe_index,
344 vertex_dof_identities[most_dominating_fe_index]
355 for (
const auto &
identity : identities)
358 ::internal::DoFAccessorImplementation::
359 Implementation::get_dof_index(
363 most_dominating_fe_index,
365 std::integral_constant<int, 0>());
367 dependent_dof_index =
368 ::internal::DoFAccessorImplementation::
369 Implementation::get_dof_index(
375 std::integral_constant<int, 0>());
390 if (dependent_dof_index !=
400 if (primary_dof_index !=
403 (dof_identities.find(primary_dof_index) ==
404 dof_identities.end()) ||
405 (dof_identities[dependent_dof_index] ==
409 dof_identities[dependent_dof_index] =
417 return dof_identities;
425 template <
int spacedim>
426 static std::map<types::global_dof_index, types::global_dof_index>
433 return std::map<types::global_dof_index, types::global_dof_index>();
437 template <
int dim,
int spacedim>
438 static std::map<types::global_dof_index, types::global_dof_index>
446 std::map<types::global_dof_index, types::global_dof_index>
451 std::vector<bool> user_flags;
455 .clear_user_flags_line();
480 for (
const auto l : cell->line_indices())
481 if (cell->line(l)->user_flag_set() ==
false)
483 const auto line = cell->line(l);
484 line->set_user_flag();
486 unsigned int unique_sets_of_dofs =
487 line->n_active_fe_indices();
491 const unsigned int n_active_fe_indices =
492 line->n_active_fe_indices();
493 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
494 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
496 const unsigned int fe_index_1 =
497 line->nth_active_fe_index(f),
499 line->nth_active_fe_index(g);
518 dof_handler.
get_fe(fe_index_2)
524 const unsigned int dofs_per_line =
527 const auto &identities =
528 *ensure_existence_and_return_dof_identities<1>(
532 line_dof_identities[fe_index_1][fe_index_2]);
536 if (identities.size() == dofs_per_line)
539 for (; i < dofs_per_line; ++i)
540 if ((identities[i].
first != i) &&
541 (identities[i].
second != i))
545 if (i == dofs_per_line)
554 --unique_sets_of_dofs;
558 const std::set<unsigned int> fe_indices{
559 fe_index_1, fe_index_2};
561 unsigned int dominating_fe_index =
565 unsigned int other_fe_index =
568 if (dominating_fe_index !=
571 (dominating_fe_index == fe_index_1) ?
579 dominating_fe_index = fe_index_1;
580 other_fe_index = fe_index_2;
583 for (
unsigned int j = 0; j < dofs_per_line;
587 primary_dof_index = line->dof_index(
588 j, dominating_fe_index);
590 dependent_dof_index =
591 line->dof_index(j, other_fe_index);
607 if (dependent_dof_index !=
610 if (primary_dof_index !=
617 if (dof_identities.find(
618 primary_dof_index) !=
619 dof_identities.end())
635 [primary_dof_index]) ==
636 dof_identities.end(),
640 [dependent_dof_index] =
650 (dof_identities.find(
651 primary_dof_index) ==
652 dof_identities.end()) ||
654 [dependent_dof_index] ==
659 [dependent_dof_index] =
669 [dependent_dof_index] =
689 if ((unique_sets_of_dofs == 2) && (dim == 2))
691 const std::set<unsigned int> fe_indices =
692 line->get_active_fe_indices();
696 const unsigned int most_dominating_fe_index =
706 if (most_dominating_fe_index !=
712 for (
const auto &other_fe_index : fe_indices)
713 if (other_fe_index != most_dominating_fe_index)
715 const auto &identities =
716 *ensure_existence_and_return_dof_identities<
718 most_dominating_fe_index,
721 [most_dominating_fe_index]
724 for (
const auto &
identity : identities)
727 primary_dof_index = line->dof_index(
729 most_dominating_fe_index);
731 dependent_dof_index =
748 if (dependent_dof_index !=
758 if (primary_dof_index !=
760 Assert((dof_identities.find(
761 primary_dof_index) ==
762 dof_identities.end()) ||
764 [dependent_dof_index] ==
768 dof_identities[dependent_dof_index] =
780 .load_user_flags_line(user_flags);
782 return dof_identities;
791 template <
int dim,
int spacedim>
792 static std::map<types::global_dof_index, types::global_dof_index>
806 return std::map<types::global_dof_index, types::global_dof_index>();
810 template <
int spacedim>
811 static std::map<types::global_dof_index, types::global_dof_index>
819 std::map<types::global_dof_index, types::global_dof_index>
826 std::vector<bool> user_flags;
830 .clear_user_flags_quad();
849 for (
const auto q : cell->face_indices())
850 if ((cell->quad(q)->user_flag_set() ==
false) &&
851 (cell->quad(q)->n_active_fe_indices() == 2))
853 const auto quad = cell->quad(q);
854 quad->set_user_flag();
856 const std::set<unsigned int> fe_indices =
857 quad->get_active_fe_indices();
861 const unsigned int most_dominating_fe_index =
866 const unsigned int most_dominating_fe_index_face_no =
867 cell->active_fe_index() == most_dominating_fe_index ?
869 cell->neighbor_face_no(q);
883 for (
const auto &other_fe_index : fe_indices)
884 if (other_fe_index != most_dominating_fe_index)
886 const auto &identities =
887 *ensure_existence_and_return_dof_identities<2>(
889 most_dominating_fe_index,
892 [most_dominating_fe_index][other_fe_index]
893 [cell->quad(q)->reference_cell() ==
895 most_dominating_fe_index_face_no);
897 for (
const auto &
identity : identities)
902 most_dominating_fe_index);
904 dependent_dof_index =
913 if (dependent_dof_index !=
923 if (primary_dof_index !=
925 Assert((dof_identities.find(
926 primary_dof_index) ==
927 dof_identities.end()) ||
929 [dependent_dof_index] ==
933 dof_identities[dependent_dof_index] =
944 .load_user_flags_quad(user_flags);
946 return dof_identities;
955 template <
int dim,
int spacedim>
959 &all_constrained_indices,
971 all_constrained_indices[i] =
979 all_constrained_indices[i] =
988 all_constrained_indices[i] =
1017 template <
int dim,
int spacedim>
1020 std::vector<types::global_dof_index> &new_dof_indices,
1022 std::map<types::global_dof_index, types::global_dof_index>>
1023 &all_constrained_indices,
1029 for (
const auto &constrained_dof_indices : all_constrained_indices)
1030 for (
const auto &p : constrained_dof_indices)
1033 Assert(new_dof_indices[p.first] == enumeration_dof_index,
1036 new_dof_indices[p.first] = p.second;
1041 for (
auto &new_dof_index : new_dof_indices)
1042 if (new_dof_index == enumeration_dof_index)
1043 new_dof_index = next_free_dof++;
1047 for (
const auto &constrained_dof_indices : all_constrained_indices)
1048 for (
const auto &p : constrained_dof_indices)
1051 Assert(new_dof_indices[p.first] != enumeration_dof_index,
1055 new_dof_indices[p.first] = new_dof_indices[p.second];
1060 (void)new_dof_index;
1061 Assert(new_dof_index != enumeration_dof_index,
1063 Assert(new_dof_index < next_free_dof ||
1068 return next_free_dof;
1081 template <
int dim,
int spacedim>
1084 const unsigned int n_dofs_before_identification,
1085 const bool check_validity)
1088 return n_dofs_before_identification;
1091 std::map<types::global_dof_index, types::global_dof_index>>
1092 all_constrained_indices(dim);
1095 std::vector<::types::global_dof_index> renumbering(
1096 n_dofs_before_identification, enumeration_dof_index);
1099 all_constrained_indices,
1113 template <
int dim,
int spacedim>
1133 std::vector<bool> include_vertex(
1135 if (
dynamic_cast<const ::parallel::
1136 DistributedTriangulationBase<dim, spacedim> *
>(
1139 if (cell->is_ghost())
1140 for (
const unsigned int v : cell->vertex_indices())
1141 include_vertex[cell->vertex_index(v)] =
true;
1144 for (
unsigned int vertex_index = 0;
1149 (include_vertex[vertex_index] ==
true))
1151 const unsigned int n_active_fe_indices =
1152 ::internal::DoFAccessorImplementation::Implementation::
1153 n_active_fe_indices(dof_handler,
1156 std::integral_constant<int, 0>());
1158 if (n_active_fe_indices > 1)
1160 const std::set<unsigned int> fe_indices =
1161 ::internal::DoFAccessorImplementation::
1162 Implementation::get_active_fe_indices(
1166 std::integral_constant<int, 0>());
1170 unsigned int most_dominating_fe_index =
1178 if (most_dominating_fe_index ==
1180 most_dominating_fe_index =
1181 ::internal::DoFAccessorImplementation::
1182 Implementation::nth_active_fe_index(
1187 std::integral_constant<int, 0>());
1193 for (
const auto &other_fe_index : fe_indices)
1194 if (other_fe_index != most_dominating_fe_index)
1198 const auto &identities =
1199 *ensure_existence_and_return_dof_identities<0>(
1201 most_dominating_fe_index,
1203 vertex_dof_identities[most_dominating_fe_index]
1214 for (
const auto &
identity : identities)
1217 ::internal::DoFAccessorImplementation::
1218 Implementation::get_dof_index(
1222 most_dominating_fe_index,
1224 std::integral_constant<int, 0>());
1226 dependent_dof_index =
1227 ::internal::DoFAccessorImplementation::
1228 Implementation::get_dof_index(
1234 std::integral_constant<int, 0>());
1248 if ((dependent_dof_index ==
1250 (primary_dof_index !=
1252 ::internal::DoFAccessorImplementation::
1253 Implementation::set_dof_index(
1259 std::integral_constant<int, 0>(),
1273 template <
int spacedim>
1284 template <
int dim,
int spacedim>
1295 std::vector<bool> user_flags;
1299 .clear_user_flags_line();
1303 if (cell->is_ghost())
1304 for (
const auto l : cell->line_indices())
1305 cell->line(l)->set_user_flag();
1330 for (
const auto l : cell->line_indices())
1331 if ((cell->is_locally_owned()) &&
1332 (cell->line(l)->user_flag_set() ==
true))
1334 const auto line = cell->line(l);
1335 line->clear_user_flag();
1337 unsigned int unique_sets_of_dofs =
1338 line->n_active_fe_indices();
1342 const unsigned int n_active_fe_indices =
1343 line->n_active_fe_indices();
1344 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1345 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
1347 const unsigned int fe_index_1 =
1348 line->nth_active_fe_index(f),
1350 line->nth_active_fe_index(g);
1353 dof_handler.
get_fe(fe_index_2)
1359 const unsigned int dofs_per_line =
1362 const auto &identities =
1363 *ensure_existence_and_return_dof_identities<1>(
1367 line_dof_identities[fe_index_1][fe_index_2]);
1371 if (identities.size() == dofs_per_line)
1374 for (; i < dofs_per_line; ++i)
1375 if ((identities[i].
first != i) &&
1376 (identities[i].
second != i))
1380 if (i == dofs_per_line)
1389 --unique_sets_of_dofs;
1393 const std::set<unsigned int> fe_indices{
1394 fe_index_1, fe_index_2};
1396 unsigned int dominating_fe_index =
1400 unsigned int other_fe_index =
1403 if (dominating_fe_index !=
1406 (dominating_fe_index == fe_index_1) ?
1414 dominating_fe_index = fe_index_1;
1415 other_fe_index = fe_index_2;
1418 for (
unsigned int j = 0; j < dofs_per_line;
1422 primary_dof_index = line->dof_index(
1423 j, dominating_fe_index);
1425 dependent_dof_index =
1426 line->dof_index(j, other_fe_index);
1441 if ((dependent_dof_index ==
1443 (primary_dof_index !=
1445 line->set_dof_index(j,
1464 if ((unique_sets_of_dofs == 2) && (dim == 2))
1466 const std::set<unsigned int> fe_indices =
1467 line->get_active_fe_indices();
1471 const unsigned int most_dominating_fe_index =
1481 if (most_dominating_fe_index !=
1487 for (
const auto &other_fe_index : fe_indices)
1488 if (other_fe_index != most_dominating_fe_index)
1490 const auto &identities =
1491 *ensure_existence_and_return_dof_identities<
1493 most_dominating_fe_index,
1496 [most_dominating_fe_index]
1499 for (
const auto &
identity : identities)
1502 primary_dof_index = line->dof_index(
1504 most_dominating_fe_index);
1506 dependent_dof_index =
1522 if ((dependent_dof_index ==
1524 (primary_dof_index !=
1526 line->set_dof_index(
identity.second,
1538 .load_user_flags_line(user_flags);
1547 template <
int dim,
int spacedim>
1564 template <
int spacedim>
1577 std::vector<bool> user_flags;
1581 .clear_user_flags_quad();
1585 if (cell->is_ghost())
1586 for (
const auto q : cell->face_indices())
1587 cell->quad(q)->set_user_flag();
1606 for (
const auto q : cell->face_indices())
1607 if ((cell->is_locally_owned()) &&
1608 (cell->quad(q)->user_flag_set() ==
true) &&
1609 (cell->quad(q)->n_active_fe_indices() == 2))
1611 const auto quad = cell->quad(q);
1612 quad->clear_user_flag();
1614 const std::set<unsigned int> fe_indices =
1615 quad->get_active_fe_indices();
1619 const unsigned int most_dominating_fe_index =
1624 const unsigned int most_dominating_fe_index_face_no =
1625 cell->active_fe_index() == most_dominating_fe_index ?
1627 cell->neighbor_face_no(q);
1641 for (
const auto &other_fe_index : fe_indices)
1642 if (other_fe_index != most_dominating_fe_index)
1644 const auto &identities =
1645 *ensure_existence_and_return_dof_identities<2>(
1647 most_dominating_fe_index,
1650 [most_dominating_fe_index][other_fe_index]
1651 [cell->quad(q)->reference_cell() ==
1653 most_dominating_fe_index_face_no);
1655 for (
const auto &
identity : identities)
1660 most_dominating_fe_index);
1662 dependent_dof_index =
1677 if ((dependent_dof_index ==
1679 (primary_dof_index !=
1681 quad->set_dof_index(
identity.second,
1692 .load_user_flags_quad(user_flags);
1709 template <
int dim,
int spacedim>
1750 template <
int dim,
int spacedim>
1762 if (!cell->is_artificial() &&
1764 (cell->subdomain_id() == subdomain_id)))
1769 DoFAccessorImplementation::Implementation::process_dof_indices(
1772 cell->active_fe_index(),
1773 DoFAccessorImplementation::Implementation::
1774 DoFIndexProcessor<dim, spacedim, false>(),
1775 [&next_free_dof](
auto &stored_index,
auto) {
1776 if (stored_index == numbers::invalid_dof_index)
1778 stored_index = next_free_dof;
1781 std::numeric_limits<types::global_dof_index>::max(),
1783 "You have reached the maximal number of degrees of "
1784 "freedom that can be stored in the chosen data "
1785 "type. In practice, this can only happen if you "
1786 "are using 32-bit data types. You will have to "
1787 "re-compile deal.II with the "
1788 "`DEAL_II_WITH_64BIT_INDICES' flag set to `ON'."));
1795 return next_free_dof;
1813 template <
int dim,
int spacedim>
1816 std::vector<types::global_dof_index> &renumbering,
1820 std::vector<types::global_dof_index> local_dof_indices;
1823 if (cell->is_ghost() && (cell->subdomain_id() < subdomain_id))
1831 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
1832 internal::DoFAccessorImplementation::Implementation::
1833 get_dof_indices(*cell,
1835 cell->active_fe_index());
1836 for (
const auto &local_dof_index : local_dof_indices)
1848 template <
int dim,
int spacedim>
1852 const unsigned int level)
1857 const ::Triangulation<dim, spacedim> &
tria =
1867 (cell->level_subdomain_id() == level_subdomain_id))
1869 DoFAccessorImplementation::Implementation::process_dof_indices(
1873 DoFAccessorImplementation::Implementation::
1874 MGDoFIndexProcessor<dim, spacedim>(
level),
1875 [&next_free_dof](
auto &stored_index,
auto) {
1878 stored_index = next_free_dof;
1881 std::numeric_limits<types::global_dof_index>::max(),
1883 "You have reached the maximal number of degrees of "
1884 "freedom that can be stored in the chosen data "
1885 "type. In practice, this can only happen if you "
1886 "are using 32-bit data types. You will have to "
1887 "re-compile deal.II with the "
1888 "`DEAL_II_WITH_64BIT_INDICES' flag set to `ON'."));
1895 return next_free_dof;
1910 template <
int dim,
int spacedim>
1913 const std::vector<types::global_dof_index> &new_numbers,
1914 const IndexSet & indices_we_care_about,
1917 for (
unsigned int d = 1; d < dim; ++d)
1920 i = ((indices_we_care_about.
size() == 0) ?
1927 template <
int dim,
int spacedim>
1930 const std::vector<types::global_dof_index> &new_numbers,
1931 const IndexSet & indices_we_care_about,
1933 const bool check_validity)
1943 for (std::vector<types::global_dof_index>::iterator i =
1949 (indices_we_care_about.
size() == 0) ?
1952 else if (check_validity)
1963 for (
unsigned int vertex_index = 0;
1967 const unsigned int n_active_fe_indices =
1968 ::internal::DoFAccessorImplementation::Implementation::
1969 n_active_fe_indices(dof_handler,
1972 std::integral_constant<int, 0>());
1986 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1988 const unsigned int fe_index =
1989 ::internal::DoFAccessorImplementation::
1990 Implementation::nth_active_fe_index(
1995 std::integral_constant<int, 0>());
1997 for (
unsigned int d = 0;
1998 d < dof_handler.
get_fe(fe_index).n_dofs_per_vertex();
2002 ::internal::DoFAccessorImplementation::
2003 Implementation::get_dof_index(
2009 std::integral_constant<int, 0>());
2040 if (indices_we_care_about.
size() == 0)
2041 ::internal::DoFAccessorImplementation::
2042 Implementation::set_dof_index(
2048 std::integral_constant<int, 0>(),
2049 new_numbers[old_dof_index]);
2054 ::internal::DoFAccessorImplementation::
2055 Implementation::set_dof_index(
2061 std::integral_constant<int, 0>(),
2062 new_numbers[indices_we_care_about
2066 ::internal::DoFAccessorImplementation::
2067 Implementation::set_dof_index(
2073 std::integral_constant<int, 0>(),
2084 template <
int dim,
int spacedim>
2087 const std::vector<types::global_dof_index> &new_numbers,
2088 const IndexSet & indices_we_care_about,
2093 for (
unsigned int level = 0;
2098 i = ((indices_we_care_about.
size() == 0) ?
2106 if (!cell->is_artificial())
2108 const unsigned int fe_index = cell->active_fe_index();
2110 for (
unsigned int d = 0;
2111 d < dof_handler.
get_fe(fe_index)
2112 .template n_dofs_per_object<dim>();
2116 cell->dof_index(d, fe_index);
2133 if (indices_we_care_about.
size() == 0)
2134 cell->set_dof_index(d,
2135 new_numbers[old_dof_index],
2139 if (indices_we_care_about.
is_element(old_dof_index))
2140 cell->set_dof_index(
2142 new_numbers[indices_we_care_about
2146 cell->set_dof_index(d,
2157 template <
int spacedim>
2160 const std::vector<types::global_dof_index> & ,
2170 template <
int spacedim>
2173 const std::vector<types::global_dof_index> &new_numbers,
2174 const IndexSet & indices_we_care_about,
2177 const unsigned int dim = 2;
2181 for (
unsigned int d = 1; d < dim; ++d)
2184 i = ((indices_we_care_about.
size() == 0) ?
2195 std::vector<bool> saved_line_user_flags;
2198 .save_user_flags_line(saved_line_user_flags);
2201 .clear_user_flags_line();
2204 if (!cell->is_artificial())
2205 for (
const auto l : cell->line_indices())
2206 if (cell->line(l)->user_flag_set() ==
false)
2208 const auto line = cell->line(l);
2209 line->set_user_flag();
2211 const unsigned int n_active_fe_indices =
2212 line->n_active_fe_indices();
2214 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2216 const unsigned int fe_index =
2217 line->nth_active_fe_index(f);
2219 for (
unsigned int d = 0;
2221 dof_handler.
get_fe(fe_index).n_dofs_per_line();
2225 line->dof_index(d, fe_index);
2245 if (indices_we_care_about.
size() == 0)
2246 line->set_dof_index(
2247 d, new_numbers[old_dof_index], fe_index);
2252 line->set_dof_index(
2254 new_numbers[indices_we_care_about
2259 line->set_dof_index(
2273 .load_user_flags_line(saved_line_user_flags);
2279 template <
int spacedim>
2282 const std::vector<types::global_dof_index> &new_numbers,
2283 const IndexSet & indices_we_care_about,
2286 const unsigned int dim = 3;
2290 for (
unsigned int d = 1; d < dim; ++d)
2293 i = ((indices_we_care_about.
size() == 0) ?
2304 std::vector<bool> saved_line_user_flags;
2307 .save_user_flags_line(saved_line_user_flags);
2310 .clear_user_flags_line();
2313 if (!cell->is_artificial())
2314 for (
const auto l : cell->line_indices())
2315 if (cell->line(l)->user_flag_set() ==
false)
2317 const auto line = cell->line(l);
2318 line->set_user_flag();
2320 const unsigned int n_active_fe_indices =
2321 line->n_active_fe_indices();
2323 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2325 const unsigned int fe_index =
2326 line->nth_active_fe_index(f);
2328 for (
unsigned int d = 0;
2330 dof_handler.
get_fe(fe_index).n_dofs_per_line();
2334 line->dof_index(d, fe_index);
2354 if (indices_we_care_about.
size() == 0)
2355 line->set_dof_index(
2356 d, new_numbers[old_dof_index], fe_index);
2359 line->set_dof_index(
2361 new_numbers[indices_we_care_about
2366 line->set_dof_index(
2377 .load_user_flags_line(saved_line_user_flags);
2382 std::vector<bool> saved_quad_user_flags;
2385 .save_user_flags_quad(saved_quad_user_flags);
2388 .clear_user_flags_quad();
2391 if (!cell->is_artificial())
2392 for (
const auto q : cell->face_indices())
2393 if (cell->quad(q)->user_flag_set() ==
false)
2395 const auto quad = cell->quad(q);
2396 quad->set_user_flag();
2398 const unsigned int n_active_fe_indices =
2399 quad->n_active_fe_indices();
2401 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2403 const unsigned int fe_index =
2404 quad->nth_active_fe_index(f);
2406 for (
unsigned int d = 0;
2408 dof_handler.
get_fe(fe_index).n_dofs_per_quad(q);
2412 quad->dof_index(d, fe_index);
2432 if (indices_we_care_about.
size() == 0)
2433 quad->set_dof_index(
2434 d, new_numbers[old_dof_index], fe_index);
2439 quad->set_dof_index(
2441 new_numbers[indices_we_care_about
2446 quad->set_dof_index(
2459 .load_user_flags_quad(saved_quad_user_flags);
2476 template <
int dim,
int space_dim>
2479 const IndexSet & indices_we_care_about,
2481 const bool check_validity,
2482 const bool update_cache =
true)
2492 renumber_vertex_dofs(new_numbers,
2493 indices_we_care_about,
2499 renumber_face_dofs(new_numbers,
2500 indices_we_care_about,
2505 renumber_cell_dofs(new_numbers,
2506 indices_we_care_about,
2513 update_all_active_cell_dof_indices_caches(dof_handler);
2528 template <
int dim,
int spacedim>
2531 const std::vector<::types::global_dof_index> &new_numbers,
2532 const IndexSet & indices_we_care_about,
2534 const unsigned int level)
2543 if ((i->get_coarsest_level() <=
level) &&
2544 (i->get_finest_level() >=
level))
2545 for (
unsigned int d = 0;
2546 d < dof_handler.
get_fe().n_dofs_per_vertex();
2549 const ::types::global_dof_index idx =
2550 i->access_index(
level,
2558 (idx < new_numbers.size()),
2562 (indices_we_care_about.
size() == 0) ?
2579 template <
int dim,
int spacedim>
2582 const std::vector<::types::global_dof_index> &new_numbers,
2583 const IndexSet & indices_we_care_about,
2585 const unsigned int level)
2587 for (std::vector<types::global_dof_index>::iterator i =
2596 (*i < new_numbers.size())),
2599 (indices_we_care_about.
size() == 0) ?
2615 template <
int spacedim>
2618 const std::vector<types::global_dof_index> & ,
2621 const unsigned int ,
2629 template <
int spacedim>
2632 const std::vector<::types::global_dof_index> &new_numbers,
2633 const IndexSet & indices_we_care_about,
2635 const unsigned int level,
2636 const bool check_validity)
2641 std::vector<bool> user_flags;
2645 .clear_user_flags();
2651 for (
const auto &cell :
2653 if (cell->level_subdomain_id() !=
2655 for (
const unsigned int line : cell->face_indices())
2656 cell->face(line)->set_user_flag();
2658 for (
const auto &cell :
2660 for (
const auto l : cell->line_indices())
2661 if (cell->line(l)->user_flag_set())
2663 for (
unsigned int d = 0;
2664 d < dof_handler.
get_fe().n_dofs_per_line();
2667 const ::types::global_dof_index idx =
2668 cell->line(l)->mg_dof_index(
level, d);
2674 cell->line(l)->set_mg_dof_index(
2677 ((indices_we_care_about.
size() == 0) ?
2679 new_numbers[indices_we_care_about
2682 cell->line(l)->clear_user_flag();
2687 .load_user_flags(user_flags);
2693 template <
int spacedim>
2696 const std::vector<::types::global_dof_index> &new_numbers,
2697 const IndexSet & indices_we_care_about,
2699 const unsigned int level,
2700 const bool check_validity)
2706 std::vector<bool> user_flags;
2710 .clear_user_flags();
2715 for (
const auto &cell :
2717 if (cell->level_subdomain_id() !=
2719 for (
const auto line : cell->line_indices())
2720 cell->line(line)->set_user_flag();
2722 for (
const auto &cell :
2724 for (
const auto l : cell->line_indices())
2725 if (cell->line(l)->user_flag_set())
2727 for (
unsigned int d = 0;
2728 d < dof_handler.
get_fe().n_dofs_per_line();
2731 const ::types::global_dof_index idx =
2732 cell->line(l)->mg_dof_index(
level, d);
2738 cell->line(l)->set_mg_dof_index(
2741 ((indices_we_care_about.
size() == 0) ?
2743 new_numbers[indices_we_care_about
2746 cell->line(l)->clear_user_flag();
2752 for (
const auto &cell :
2754 if (cell->level_subdomain_id() !=
2756 for (
const auto quad : cell->face_indices())
2757 cell->quad(quad)->set_user_flag();
2760 for (
const auto l : cell->face_indices())
2761 if (cell->quad(l)->user_flag_set())
2763 for (
unsigned int d = 0;
2764 d < dof_handler.
get_fe().n_dofs_per_quad(l);
2767 const ::types::global_dof_index idx =
2768 cell->quad(l)->mg_dof_index(
level, d);
2774 cell->quad(l)->set_mg_dof_index(
2777 ((indices_we_care_about.
size() == 0) ?
2779 new_numbers[indices_we_care_about
2782 cell->quad(l)->clear_user_flag();
2788 .load_user_flags(user_flags);
2794 template <
int dim,
int spacedim>
2797 const std::vector<::types::global_dof_index> &new_numbers,
2798 const IndexSet & indices_we_care_about,
2800 const unsigned int level,
2801 const bool check_validity)
2815 renumber_vertex_mg_dofs(new_numbers,
2816 indices_we_care_about,
2821 renumber_face_mg_dofs(new_numbers,
2822 indices_we_care_about,
2828 renumber_cell_mg_dofs(new_numbers,
2829 indices_we_care_about,
2843 template <
int dim,
int spacedim>
2846 : dof_handler(&dof_handler)
2851 template <
int dim,
int spacedim>
2864 update_all_active_cell_dof_indices_caches(*dof_handler);
2872 template <
int dim,
int spacedim>
2873 std::vector<NumberCache>
2876 std::vector<bool> user_flags;
2881 .clear_user_flags();
2883 std::vector<NumberCache> number_caches;
2885 for (
unsigned int level = 0;
2895 number_caches.emplace_back(n_level_dofs);
2900 .load_user_flags(user_flags);
2902 return number_caches;
2907 template <
int dim,
int spacedim>
2910 const std::vector<types::global_dof_index> &new_numbers)
const
2925 if (new_numbers.size() == 0)
2929 *std::max_element(new_numbers.begin(), new_numbers.end()) + 1);
2934 template <
int dim,
int spacedim>
2937 const unsigned int level,
2938 const std::vector<types::global_dof_index> &new_numbers)
const
2951 template <
int dim,
int spacedim>
2954 : dof_handler(&dof_handler)
2969 template <
int dim,
int spacedim>
2970 std::vector<types::subdomain_id>
2971 get_dof_subdomain_association(
2974 const unsigned int n_procs)
2977 std::vector<types::subdomain_id> subdomain_association(
2979 std::vector<types::global_dof_index> local_dof_indices;
2980 local_dof_indices.reserve(
2992 const unsigned int dofs_per_cell =
2993 cell->get_fe().n_dofs_per_cell();
2994 local_dof_indices.resize(dofs_per_cell);
2995 internal::DoFAccessorImplementation::Implementation::
2996 get_dof_indices(*cell,
2998 cell->active_fe_index());
3003 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
3004 if (subdomain_association[local_dof_indices[i]] ==
3006 subdomain_association[local_dof_indices[i]] = subdomain_id;
3007 else if (subdomain_association[local_dof_indices[i]] >
3010 subdomain_association[local_dof_indices[i]] = subdomain_id;
3014 Assert(std::find(subdomain_association.begin(),
3015 subdomain_association.end(),
3017 subdomain_association.end(),
3020 Assert(*std::max_element(subdomain_association.begin(),
3021 subdomain_association.end()) < n_procs,
3024 return subdomain_association;
3034 template <
int dim,
int spacedim>
3035 std::vector<types::subdomain_id>
3036 get_dof_level_subdomain_association(
3039 const unsigned int n_procs,
3040 const unsigned int level)
3043 std::vector<types::subdomain_id> level_subdomain_association(
3045 std::vector<types::global_dof_index> local_dof_indices;
3046 local_dof_indices.reserve(
3057 cell->level_subdomain_id();
3058 const unsigned int dofs_per_cell =
3059 cell->get_fe().n_dofs_per_cell();
3060 local_dof_indices.resize(dofs_per_cell);
3061 cell->get_mg_dof_indices(local_dof_indices);
3066 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
3067 if (level_subdomain_association[local_dof_indices[i]] ==
3069 level_subdomain_association[local_dof_indices[i]] =
3071 else if (level_subdomain_association[local_dof_indices[i]] >
3074 level_subdomain_association[local_dof_indices[i]] =
3079 Assert(std::find(level_subdomain_association.begin(),
3080 level_subdomain_association.end(),
3082 level_subdomain_association.end(),
3085 Assert(*std::max_element(level_subdomain_association.begin(),
3086 level_subdomain_association.end()) < n_procs,
3089 return level_subdomain_association;
3095 template <
int dim,
int spacedim>
3099 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3101 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3105 const unsigned int n_procs =
3115 const internal::parallel::shared::
3116 TemporarilyRestoreSubdomainIds<dim, spacedim>
3117 subdomain_modifier(*tr);
3123 *this->dof_handler);
3139 std::vector<types::global_dof_index> new_dof_indices(
3140 n_dofs, enumeration_dof_index);
3144 const std::vector<types::subdomain_id> subdomain_association =
3145 get_dof_subdomain_association(*this->dof_handler, n_dofs, n_procs);
3156 if (subdomain_association[i] == subdomain)
3158 Assert(new_dof_indices[i] == enumeration_dof_index,
3160 new_dof_indices[i] = next_free_index;
3166 Assert(std::find(new_dof_indices.begin(),
3167 new_dof_indices.end(),
3168 enumeration_dof_index) == new_dof_indices.end(),
3189 const std::vector<types::subdomain_id> subdomain_association =
3190 get_dof_subdomain_association(*this->dof_handler, n_dofs, n_procs);
3192 for (
unsigned int i = 1; i < n_dofs; ++i)
3193 Assert(subdomain_association[i] >= subdomain_association[i - 1],
3196 std::vector<IndexSet> locally_owned_dofs_per_processor(
3207 unsigned int start_index = 0;
3208 unsigned int end_index = 0;
3209 while (start_index < n_dofs)
3211 while ((end_index) < n_dofs &&
3212 (subdomain_association[end_index] ==
3213 subdomain_association[start_index]))
3218 if (end_index > start_index)
3220 const unsigned int subdomain_owner =
3221 subdomain_association[start_index];
3222 locally_owned_dofs_per_processor[subdomain_owner].add_range(
3223 start_index, end_index);
3227 start_index = end_index;
3234 locally_owned_dofs_per_processor,
3240 template <
int dim,
int spacedim>
3241 std::vector<NumberCache>
3244 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3246 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3250 const unsigned int n_procs =
3252 const unsigned int n_levels = tr->n_global_levels();
3254 std::vector<NumberCache> number_caches;
3255 number_caches.reserve(n_levels);
3258 for (
unsigned int lvl = 0; lvl < n_levels; ++lvl)
3266 std::vector<types::subdomain_id> saved_level_subdomain_ids;
3267 saved_level_subdomain_ids.resize(tr->n_cells(lvl));
3269 typename ::parallel::shared::Triangulation<dim, spacedim>::
3270 cell_iterator cell =
3276 const std::vector<types::subdomain_id> &true_level_subdomain_ids =
3277 tr->get_true_level_subdomain_ids_of_cells(lvl);
3279 for (
unsigned int index = 0; cell != endc; ++cell, ++
index)
3281 saved_level_subdomain_ids[
index] = cell->level_subdomain_id();
3282 cell->set_level_subdomain_id(true_level_subdomain_ids[
index]);
3301 std::vector<types::global_dof_index> new_dof_indices(
3306 const std::vector<types::subdomain_id>
3307 level_subdomain_association =
3308 get_dof_level_subdomain_association(*this->dof_handler,
3320 level_subdomain < n_procs;
3323 if (level_subdomain_association[i] == level_subdomain)
3327 new_dof_indices[i] = next_free_index;
3333 Assert(std::find(new_dof_indices.begin(),
3334 new_dof_indices.end(),
3336 new_dof_indices.end(),
3345 new_dof_indices,
IndexSet(0), *this->dof_handler, lvl,
true);
3357 const std::vector<types::subdomain_id> level_subdomain_association =
3358 get_dof_level_subdomain_association(*this->dof_handler,
3363 for (
unsigned int i = 1; i < n_dofs_on_level; ++i)
3364 Assert(level_subdomain_association[i] >=
3365 level_subdomain_association[i - 1],
3368 std::vector<IndexSet> locally_owned_dofs_per_processor(
3369 n_procs,
IndexSet(n_dofs_on_level));
3379 unsigned int start_index = 0;
3380 unsigned int end_index = 0;
3381 while (start_index < n_dofs_on_level)
3383 while ((end_index) < n_dofs_on_level &&
3384 (level_subdomain_association[end_index] ==
3385 level_subdomain_association[start_index]))
3390 if (end_index > start_index)
3392 const unsigned int level_subdomain_owner =
3393 level_subdomain_association[start_index];
3394 locally_owned_dofs_per_processor[level_subdomain_owner]
3395 .add_range(start_index, end_index);
3399 start_index = end_index;
3405 typename ::parallel::shared::Triangulation<dim, spacedim>::
3406 cell_iterator cell =
3412 for (
unsigned int index = 0; cell != endc; ++cell, ++
index)
3413 cell->set_level_subdomain_id(saved_level_subdomain_ids[
index]);
3416 number_caches.emplace_back(
3423 return number_caches;
3428 template <
int dim,
int spacedim>
3431 const std::vector<types::global_dof_index> &new_numbers)
const
3433#ifndef DEAL_II_WITH_MPI
3440 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3442 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3447 const internal::parallel::shared::
3448 TemporarilyRestoreSubdomainIds<dim, spacedim>
3449 subdomain_modifier(*tr);
3451 std::vector<types::global_dof_index> global_gathered_numbers(
3452 this->dof_handler->
n_dofs(), 0);
3457 const bool uses_sequential_numbering =
3458 new_numbers.size() == this->dof_handler->
n_dofs();
3459 bool all_use_sequential_numbering =
false;
3460 Utilities::MPI::internal::all_reduce<bool>(
3463 tr->get_communicator(),
3465 if (all_use_sequential_numbering)
3467 global_gathered_numbers = new_numbers;
3471 Assert(new_numbers.size() ==
3472 this->dof_handler->locally_owned_dofs().n_elements(),
3474 const unsigned int n_cpu =
3476 std::vector<types::global_dof_index> gathered_new_numbers(
3477 this->dof_handler->
n_dofs(), 0);
3479 this->dof_handler->get_triangulation()
3480 .locally_owned_subdomain(),
3485 std::vector<types::global_dof_index> new_numbers_copy(
3490 std::vector<int> rcounts(n_cpu);
3494 int cur_count = new_numbers_copy.size();
3495 int ierr = MPI_Allgather(&cur_count,
3501 tr->get_communicator());
3506 std::vector<int> displacements(n_cpu);
3507 for (
unsigned int i = 0; i < n_cpu; ++i)
3509 displacements[i] = shift;
3510 shift += rcounts[i];
3512 Assert(new_numbers_copy.size() ==
3513 static_cast<unsigned int>(
3515 tr->get_communicator())]),
3517 ierr = MPI_Allgatherv(new_numbers_copy.data(),
3518 new_numbers_copy.size(),
3520 gathered_new_numbers.data(),
3522 displacements.data(),
3524 tr->get_communicator());
3534 std::vector<unsigned int> flag_1(this->dof_handler->
n_dofs(), 0);
3535 std::vector<unsigned int> flag_2(this->dof_handler->
n_dofs(), 0);
3536 std::vector<IndexSet> locally_owned_dofs_per_processor =
3538 tr->get_communicator(),
3539 this->dof_handler->locally_owned_dofs());
3540 for (
unsigned int i = 0; i < n_cpu; ++i)
3542 const IndexSet iset = locally_owned_dofs_per_processor[i];
3549 gathered_new_numbers[shift + ind];
3554 global_gathered_numbers[target] =
value;
3561 Assert(*std::max_element(flag_1.begin(), flag_1.end()) == 1,
3563 Assert(*std::min_element(flag_1.begin(), flag_1.end()) == 1,
3565 Assert((*std::max_element(flag_2.begin(), flag_2.end())) == 1,
3567 Assert((*std::min_element(flag_2.begin(), flag_2.end())) == 1,
3583 return number_cache;
3589 template <
int dim,
int spacedim>
3592 const unsigned int ,
3593 const std::vector<types::global_dof_index> & )
const
3605#ifdef DEAL_II_WITH_MPI
3609 template <
int dim,
int spacedim>
3613 const auto pack = [&](
const auto &cell) {
3615 Assert(cell->level_subdomain_id() ==
3619 std::vector<::types::global_dof_index> data(
3620 cell->get_fe().n_dofs_per_cell());
3621 cell->get_mg_dof_indices(data);
3626 const auto unpack = [](
const auto &cell,
const auto &dofs) {
3627 Assert(cell->get_fe().n_dofs_per_cell() == dofs.size(),
3630 Assert(cell->level_subdomain_id() !=
3634 bool complete =
true;
3635 DoFAccessorImplementation::Implementation::process_dof_indices(
3639 DoFAccessorImplementation::Implementation::
3640 MGDoFIndexProcessor<dim, spacedim>(cell->level()),
3641 [&complete](
auto &stored_index,
auto received_index) {
3642 if (received_index != numbers::invalid_dof_index)
3644# if !defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1900
3645 Assert((stored_index == (numbers::invalid_dof_index)) ||
3646 (stored_index == received_index),
3647 ExcInternalError());
3649 stored_index = received_index;
3663 ->clear_user_flag();
3666 const auto filter = [](
const auto &cell) {
3667 return cell->user_flag_set();
3671 std::vector<types::global_dof_index>,
3695 template <
int dim,
int spacedim>
3697 communicate_dof_indices_on_marked_cells(
3700# ifndef DEAL_II_WITH_MPI
3708 const auto pack = [](
const auto &cell) {
3711 std::vector<::types::global_dof_index> data(
3712 cell->get_fe().n_dofs_per_cell());
3715 internal::DoFAccessorImplementation::Implementation::
3716 get_dof_indices(*cell, data, cell->active_fe_index());
3721 const auto unpack = [](
const auto &cell,
const auto &dofs) {
3722 Assert(cell->get_fe().n_dofs_per_cell() == dofs.size(),
3730 bool complete =
true;
3731 DoFAccessorImplementation::Implementation::process_dof_indices(
3734 cell->active_fe_index(),
3735 DoFAccessorImplementation::Implementation::
3736 DoFIndexProcessor<dim, spacedim, false>(),
3737 [&complete](
auto &stored_index,
auto received_index) {
3738 if (received_index != numbers::invalid_dof_index)
3740# if !defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1900
3741 Assert((stored_index == (numbers::invalid_dof_index)) ||
3742 (stored_index == received_index),
3743 ExcInternalError());
3745 stored_index = received_index;
3761 ->clear_user_flag();
3764 const auto filter = [](
const auto &cell) {
3765 return cell->user_flag_set();
3769 std::vector<types::global_dof_index>,
3782 template <
int dim,
int spacedim>
3785 : dof_handler(&dof_handler)
3790 template <
int dim,
int spacedim>
3794#ifndef DEAL_II_WITH_MPI
3843 std::vector<::types::global_dof_index> renumbering(
3844 n_initial_local_dofs, enumeration_dof_index);
3851 renumbering, subdomain_id, *dof_handler);
3855 std::vector<std::map<types::global_dof_index, types::global_dof_index>>
3856 all_constrained_indices(dim);
3872 renumbering, all_constrained_indices, *dof_handler);
3877 const int ierr = MPI_Exscan(&n_locally_owned_dofs,
3886 for (
auto &new_index : renumbering)
3888 new_index += my_shift;
3900 const ::types::global_dof_index n_global_dofs =
3910 n_locally_owned_dofs);
3921 std::vector<bool> user_flags;
3929 if (cell->is_ghost())
3930 cell->set_user_flag();
3938 communicate_dof_indices_on_marked_cells(*dof_handler);
3951 communicate_dof_indices_on_marked_cells(*dof_handler);
3963 update_all_active_cell_dof_indices_caches(*this->dof_handler);
3968 std::vector<::types::global_dof_index> local_dof_indices;
3971 if (!cell->is_artificial())
3973 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
3974 cell->get_dof_indices(local_dof_indices);
3975 if (local_dof_indices.end() !=
3976 std::find(local_dof_indices.begin(),
3977 local_dof_indices.end(),
3980 if (cell->is_ghost())
3984 "A ghost cell ended up with incomplete "
3985 "DoF index information. This should not "
3993 "A locally owned cell ended up with incomplete "
3994 "DoF index information. This should not "
4001 return number_cache;
4007 template <
int dim,
int spacedim>
4008 std::vector<NumberCache>
4011#ifndef DEAL_II_WITH_MPI
4013 return std::vector<NumberCache>();
4026 "Multigrid DoFs can only be distributed on a parallel "
4027 "Triangulation if the flag construct_multigrid_hierarchy "
4028 "is set in the constructor."));
4035 const unsigned int n_levels =
triangulation->n_global_levels();
4036 std::vector<NumberCache> number_caches;
4037 number_caches.reserve(n_levels);
4043 const unsigned int n_initial_local_dofs =
4049 std::vector<::types::global_dof_index> renumbering(
4050 n_initial_local_dofs);
4055 if (level < triangulation->n_levels())
4057 std::vector<::types::global_dof_index> local_dof_indices;
4059 for (
const auto &cell :
4061 if (cell->level_subdomain_id() !=
4063 (cell->level_subdomain_id() <
4073 local_dof_indices.resize(
4074 cell->get_fe().n_dofs_per_cell());
4075 cell->get_mg_dof_indices(local_dof_indices);
4076 for (
unsigned int i = 0;
4077 i < cell->get_fe().n_dofs_per_cell();
4080 renumbering[local_dof_indices[i]] =
4128 if (level < triangulation->n_levels())
4139 number_caches.emplace_back(level_number_cache);
4148 std::vector<bool> user_flags;
4155 if (cell->is_ghost_on_level())
4156 cell->set_user_flag();
4162 communicate_mg_ghost_cells(*dof_handler);
4166 communicate_mg_ghost_cells(*dof_handler);
4172 if (cell->level_subdomain_id() !=
4174 !cell->is_locally_owned_on_level())
4187 std::vector<::types::global_dof_index> local_dof_indices;
4189 if (cell->level_subdomain_id() !=
4192 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
4193 cell->get_mg_dof_indices(local_dof_indices);
4194 if (local_dof_indices.end() !=
4195 std::find(local_dof_indices.begin(),
4196 local_dof_indices.end(),
4205 return number_caches;
4211 template <
int dim,
int spacedim>
4214 const std::vector<::types::global_dof_index> &new_numbers)
const
4221#ifndef DEAL_II_WITH_MPI
4239 const bool locally_owned_set_changes =
4240 std::any_of(new_numbers.cbegin(),
4243 return owned_dofs.is_element(i) == false;
4246 IndexSet my_locally_owned_new_dof_indices = owned_dofs;
4247 if (locally_owned_set_changes && owned_dofs.
n_elements() > 0)
4249 std::vector<::types::global_dof_index> new_numbers_sorted =
4251 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
4253 my_locally_owned_new_dof_indices =
IndexSet(dof_handler->
n_dofs());
4255 new_numbers_sorted.begin(), new_numbers_sorted.end());
4256 my_locally_owned_new_dof_indices.
compress();
4275 if (cell->is_ghost())
4277 DoFAccessorImplementation::Implementation::process_dof_indices(
4280 cell->active_fe_index(),
4281 DoFAccessorImplementation::Implementation::
4282 DoFIndexProcessor<dim, spacedim, false>(),
4283 [&owned_dofs](
auto &stored_index,
auto) {
4287 if (stored_index != numbers::invalid_dof_index &&
4288 (!owned_dofs.is_element(stored_index)))
4289 stored_index = numbers::invalid_dof_index;
4310 std::vector<bool> user_flags;
4316 if (cell->is_ghost())
4317 cell->set_user_flag();
4326 communicate_dof_indices_on_marked_cells(*dof_handler);
4336 communicate_dof_indices_on_marked_cells(*dof_handler);
4339 update_all_active_cell_dof_indices_caches(*this->dof_handler);
4347 return number_cache;
4353 template <
int dim,
int spacedim>
4356 const unsigned int level,
4357 const std::vector<types::global_dof_index> &new_numbers)
const
4359#ifndef DEAL_II_WITH_MPI
4382 const bool locally_owned_set_changes =
4383 std::any_of(new_numbers.cbegin(),
4386 return owned_dofs.is_element(i) == false;
4389 IndexSet my_locally_owned_new_dof_indices = owned_dofs;
4390 if (locally_owned_set_changes && owned_dofs.
n_elements() > 0)
4392 std::vector<::types::global_dof_index> new_numbers_sorted =
4394 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
4396 my_locally_owned_new_dof_indices =
4399 new_numbers_sorted.begin(), new_numbers_sorted.end());
4400 my_locally_owned_new_dof_indices.
compress();
4410 if (cell->is_ghost_on_level())
4412 DoFAccessorImplementation::Implementation::process_dof_indices(
4416 DoFAccessorImplementation::Implementation::
4417 MGDoFIndexProcessor<dim, spacedim>(cell->level()),
4418 [&owned_dofs](
auto &stored_index,
auto) {
4419 if ((stored_index != numbers::invalid_dof_index) &&
4420 (!owned_dofs.is_element(stored_index)))
4421 stored_index = numbers::invalid_dof_index;
4427 if (level < triangulation->n_levels() && owned_dofs.
n_elements() > 0)
4429 new_numbers, owned_dofs, *dof_handler,
level,
false);
4433 std::vector<bool> user_flags;
4439 if (cell->is_ghost_on_level())
4440 cell->set_user_flag();
4442 communicate_mg_ghost_cells(*dof_handler);
4444 communicate_mg_ghost_cells(*dof_handler);
4454 return number_cache;
4464#include "dof_handler_policy.inst"
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
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
active_cell_iterator begin_active(const unsigned int level=0) const
bool hp_capability_enabled
types::global_dof_index n_dofs() const
typename LevelSelector::cell_iterator level_cell_iterator
cell_iterator begin(const unsigned int level=0) 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
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 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
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
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)
typename ActiveSelector::active_cell_iterator active_cell_iterator
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)
constexpr const ReferenceCell Quadrilateral
std::vector< T > all_gather(const MPI_Comm &comm, const T &object_to_send)
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
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, const bool update_cache=true)
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 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 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