48 namespace DoFHandlerImplementation
65 std::vector<std::pair<unsigned int, unsigned int>>;
78 template <
int structdim,
int dim,
int spacedim>
79 const std::unique_ptr<DoFIdentities> &
80 ensure_existence_and_return_dof_identities(
81 const ::hp::FECollection<dim, spacedim> &fes,
84 std::unique_ptr<DoFIdentities> &identities,
92 if (identities.get() ==
nullptr)
96 std::vector<std::map<unsigned int, unsigned int>>
104 complete_identities = fes.hp_vertex_dof_identities(
105 std::set<unsigned int>{fe_index_1, fe_index_2});
112 complete_identities = fes.hp_line_dof_identities(
113 std::set<unsigned int>{fe_index_1, fe_index_2});
120 complete_identities = fes.hp_quad_dof_identities(
121 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);
173 for (
const auto &
identity : reduced_identities)
177 fes[fe_index_1].template n_dofs_per_object<structdim>(
182 fes[fe_index_2].template n_dofs_per_object<structdim>(
189 std::make_unique<DoFIdentities>(std::move(reduced_identities));
206 template <
int dim,
int spacedim>
207 static std::map<types::global_dof_index, types::global_dof_index>
215 std::map<types::global_dof_index, types::global_dof_index>
229 for (
unsigned int vertex_index = 0;
235 const unsigned int n_active_fe_indices =
240 std::integral_constant<int, 0>());
242 if (n_active_fe_indices > 1)
244 const std::set<types::fe_index> fe_indices =
250 std::integral_constant<int, 0>());
257 {fe_indices.begin(), fe_indices.end()},
264 most_dominating_fe_index =
271 std::integral_constant<int, 0>());
277 for (
const auto &other_fe_index : fe_indices)
278 if (other_fe_index != most_dominating_fe_index)
282 const auto &identities =
283 *ensure_existence_and_return_dof_identities<0>(
285 most_dominating_fe_index,
287 vertex_dof_identities[most_dominating_fe_index]
298 for (
const auto &
identity : identities)
306 most_dominating_fe_index,
308 std::integral_constant<int, 0>());
310 dependent_dof_index =
318 std::integral_constant<int, 0>());
333 if (dependent_dof_index !=
343 if (primary_dof_index !=
346 (dof_identities.find(primary_dof_index) ==
347 dof_identities.end()) ||
348 (dof_identities[dependent_dof_index] ==
352 dof_identities[dependent_dof_index] =
360 return dof_identities;
368 template <
int spacedim>
369 static std::map<types::global_dof_index, types::global_dof_index>
376 return std::map<types::global_dof_index, types::global_dof_index>();
380 template <
int dim,
int spacedim>
381 static std::map<types::global_dof_index, types::global_dof_index>
389 std::map<types::global_dof_index, types::global_dof_index>
414 std::vector<bool> line_touched(
417 for (
const auto l : cell->line_indices())
418 if (!line_touched[cell->line(l)->index()])
420 const auto line = cell->line(l);
421 line_touched[line->index()] =
true;
423 unsigned int unique_sets_of_dofs =
424 line->n_active_fe_indices();
428 const unsigned int n_active_fe_indices =
429 line->n_active_fe_indices();
430 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
431 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
434 line->nth_active_fe_index(f),
436 line->nth_active_fe_index(g);
455 dof_handler.
get_fe(fe_index_2)
461 const unsigned int dofs_per_line =
464 const auto &identities =
465 *ensure_existence_and_return_dof_identities<1>(
469 line_dof_identities[fe_index_1][fe_index_2]);
473 if (identities.size() == dofs_per_line)
476 for (; i < dofs_per_line; ++i)
477 if ((identities[i].
first != i) &&
478 (identities[i].
second != i))
482 if (i == dofs_per_line)
491 --unique_sets_of_dofs;
495 const std::set<types::fe_index> fe_indices{
496 fe_index_1, fe_index_2};
507 if (dominating_fe_index !=
510 (dominating_fe_index == fe_index_1) ?
518 dominating_fe_index = fe_index_1;
519 other_fe_index = fe_index_2;
522 for (
unsigned int j = 0; j < dofs_per_line;
526 primary_dof_index = line->dof_index(
527 j, dominating_fe_index);
529 dependent_dof_index =
530 line->dof_index(j, other_fe_index);
546 if (dependent_dof_index !=
549 if (primary_dof_index !=
556 if (dof_identities.find(
557 primary_dof_index) !=
558 dof_identities.end())
574 [primary_dof_index]) ==
575 dof_identities.end(),
579 [dependent_dof_index] =
589 (dof_identities.find(
590 primary_dof_index) ==
591 dof_identities.end()) ||
593 [dependent_dof_index] ==
598 [dependent_dof_index] =
608 [dependent_dof_index] =
628 if ((unique_sets_of_dofs == 2) && (dim == 2))
630 const std::set<types::fe_index> fe_indices =
631 line->get_active_fe_indices();
638 {fe_indices.begin(), fe_indices.end()},
651 for (
const auto &other_fe_index : fe_indices)
652 if (other_fe_index != most_dominating_fe_index)
654 const auto &identities =
655 *ensure_existence_and_return_dof_identities<
657 most_dominating_fe_index,
660 [most_dominating_fe_index]
663 for (
const auto &
identity : identities)
666 primary_dof_index = line->dof_index(
668 most_dominating_fe_index);
670 dependent_dof_index =
687 if (dependent_dof_index !=
697 if (primary_dof_index !=
699 Assert((dof_identities.find(
700 primary_dof_index) ==
701 dof_identities.end()) ||
703 [dependent_dof_index] ==
707 dof_identities[dependent_dof_index] =
716 return dof_identities;
725 template <
int dim,
int spacedim>
726 static std::map<types::global_dof_index, types::global_dof_index>
740 return std::map<types::global_dof_index, types::global_dof_index>();
744 template <
int spacedim>
745 static std::map<types::global_dof_index, types::global_dof_index>
753 std::map<types::global_dof_index, types::global_dof_index>
772 std::vector<bool> quad_touched(
775 for (
const auto q : cell->face_indices())
776 if (!quad_touched[cell->quad(q)->index()] &&
777 (cell->quad(q)->n_active_fe_indices() == 2))
779 const auto quad = cell->quad(q);
780 quad_touched[quad->index()] =
true;
782 const std::set<types::fe_index> fe_indices =
783 quad->get_active_fe_indices();
790 {fe_indices.begin(), fe_indices.end()},
793 const unsigned int most_dominating_fe_index_face_no =
794 cell->active_fe_index() == most_dominating_fe_index ?
796 cell->neighbor_face_no(q);
810 for (
const auto &other_fe_index : fe_indices)
811 if (other_fe_index != most_dominating_fe_index)
813 const auto &identities =
814 *ensure_existence_and_return_dof_identities<2>(
816 most_dominating_fe_index,
819 [most_dominating_fe_index][other_fe_index]
820 [cell->quad(q)->reference_cell() ==
822 most_dominating_fe_index_face_no);
824 for (
const auto &
identity : identities)
829 most_dominating_fe_index);
831 dependent_dof_index =
840 if (dependent_dof_index !=
850 if (primary_dof_index !=
852 Assert((dof_identities.find(
853 primary_dof_index) ==
854 dof_identities.end()) ||
856 [dependent_dof_index] ==
860 dof_identities[dependent_dof_index] =
868 return dof_identities;
877 template <
int dim,
int spacedim>
881 &all_constrained_indices,
893 all_constrained_indices[i] =
901 all_constrained_indices[i] =
910 all_constrained_indices[i] =
941 std::vector<types::global_dof_index> &new_dof_indices,
943 std::map<types::global_dof_index, types::global_dof_index>>
944 &all_constrained_indices,
948 for (
const auto &constrained_dof_indices : all_constrained_indices)
949 for (
const auto &p : constrained_dof_indices)
952 Assert(new_dof_indices[p.first] == enumeration_dof_index,
955 new_dof_indices[p.first] = p.second;
960 for (
auto &new_dof_index : new_dof_indices)
961 if (new_dof_index == enumeration_dof_index)
962 new_dof_index = next_free_dof++;
966 for (
const auto &constrained_dof_indices : all_constrained_indices)
967 for (
const auto &p : constrained_dof_indices)
970 Assert(new_dof_indices[p.first] != enumeration_dof_index,
974 new_dof_indices[p.first] = new_dof_indices[p.second];
980 Assert(new_dof_index != enumeration_dof_index,
982 Assert(new_dof_index < next_free_dof ||
987 return next_free_dof;
1000 template <
int dim,
int spacedim>
1003 const unsigned int n_dofs_before_identification,
1004 const bool check_validity)
1007 return n_dofs_before_identification;
1010 std::map<types::global_dof_index, types::global_dof_index>>
1011 all_constrained_indices(dim);
1014 std::vector<::types::global_dof_index> renumbering(
1015 n_dofs_before_identification, enumeration_dof_index);
1018 all_constrained_indices,
1032 template <
int dim,
int spacedim>
1053 std::vector<bool> include_vertex(
1055 if (
dynamic_cast<const ::parallel::
1056 DistributedTriangulationBase<dim, spacedim> *
>(
1059 if (cell->is_ghost())
1060 for (
const unsigned int v : cell->vertex_indices())
1061 include_vertex[cell->vertex_index(v)] =
true;
1064 for (
unsigned int vertex_index = 0;
1069 (include_vertex[vertex_index] ==
true))
1071 const unsigned int n_active_fe_indices =
1076 std::integral_constant<int, 0>());
1078 if (n_active_fe_indices > 1)
1080 const std::set<types::fe_index> fe_indices =
1086 std::integral_constant<int, 0>());
1093 {fe_indices.begin(), fe_indices.end()},
1100 most_dominating_fe_index =
1107 std::integral_constant<int, 0>());
1113 for (
const auto &other_fe_index : fe_indices)
1114 if (other_fe_index != most_dominating_fe_index)
1118 const auto &identities =
1119 *ensure_existence_and_return_dof_identities<0>(
1121 most_dominating_fe_index,
1123 vertex_dof_identities[most_dominating_fe_index]
1134 for (
const auto &
identity : identities)
1142 most_dominating_fe_index,
1144 std::integral_constant<int, 0>());
1146 dependent_dof_index =
1154 std::integral_constant<int, 0>());
1168 if ((dependent_dof_index ==
1170 (primary_dof_index !=
1179 std::integral_constant<int, 0>(),
1193 template <
int spacedim>
1204 template <
int dim,
int spacedim>
1214 std::vector<bool> line_marked(
1217 if (cell->is_ghost())
1218 for (
const auto l : cell->line_indices())
1219 line_marked[cell->line(l)->index()] =
true;
1244 for (
const auto l : cell->line_indices())
1245 if ((cell->is_locally_owned()) &&
1246 line_marked[cell->line(l)->index()])
1248 const auto line = cell->line(l);
1249 line_marked[line->index()] =
false;
1251 unsigned int unique_sets_of_dofs =
1252 line->n_active_fe_indices();
1256 const unsigned int n_active_fe_indices =
1257 line->n_active_fe_indices();
1258 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1259 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
1262 line->nth_active_fe_index(f),
1264 line->nth_active_fe_index(g);
1267 dof_handler.
get_fe(fe_index_2)
1273 const unsigned int dofs_per_line =
1276 const auto &identities =
1277 *ensure_existence_and_return_dof_identities<1>(
1281 line_dof_identities[fe_index_1][fe_index_2]);
1285 if (identities.size() == dofs_per_line)
1288 for (; i < dofs_per_line; ++i)
1289 if ((identities[i].
first != i) &&
1290 (identities[i].
second != i))
1294 if (i == dofs_per_line)
1303 --unique_sets_of_dofs;
1307 const std::set<types::fe_index> fe_indices{
1308 fe_index_1, fe_index_2};
1319 if (dominating_fe_index !=
1322 (dominating_fe_index == fe_index_1) ?
1330 dominating_fe_index = fe_index_1;
1331 other_fe_index = fe_index_2;
1334 for (
unsigned int j = 0; j < dofs_per_line;
1338 primary_dof_index = line->dof_index(
1339 j, dominating_fe_index);
1341 dependent_dof_index =
1342 line->dof_index(j, other_fe_index);
1357 if ((dependent_dof_index ==
1359 (primary_dof_index !=
1361 line->set_dof_index(j,
1380 if ((unique_sets_of_dofs == 2) && (dim == 2))
1382 const std::set<types::fe_index> fe_indices =
1383 line->get_active_fe_indices();
1390 {fe_indices.begin(), fe_indices.end()},
1403 for (
const auto &other_fe_index : fe_indices)
1404 if (other_fe_index != most_dominating_fe_index)
1406 const auto &identities =
1407 *ensure_existence_and_return_dof_identities<
1409 most_dominating_fe_index,
1412 [most_dominating_fe_index]
1415 for (
const auto &
identity : identities)
1418 primary_dof_index = line->dof_index(
1420 most_dominating_fe_index);
1422 dependent_dof_index =
1438 if ((dependent_dof_index ==
1440 (primary_dof_index !=
1442 line->set_dof_index(
identity.second,
1458 template <
int dim,
int spacedim>
1475 template <
int spacedim>
1486 std::vector<bool> quad_marked(
1489 if (cell->is_ghost())
1490 for (
const auto q : cell->face_indices())
1491 quad_marked[cell->quad(q)->index()] =
true;
1510 for (
const auto q : cell->face_indices())
1511 if ((cell->is_locally_owned()) &&
1512 quad_marked[cell->quad(q)->index()] &&
1513 (cell->quad(q)->n_active_fe_indices() == 2))
1515 const auto quad = cell->quad(q);
1516 quad_marked[quad->index()] =
false;
1518 const std::set<types::fe_index> fe_indices =
1519 quad->get_active_fe_indices();
1526 {fe_indices.begin(), fe_indices.end()},
1530 cell->active_fe_index() == most_dominating_fe_index ?
1532 cell->neighbor_face_no(q);
1546 for (
const auto &other_fe_index : fe_indices)
1547 if (other_fe_index != most_dominating_fe_index)
1549 const auto &identities =
1550 *ensure_existence_and_return_dof_identities<2>(
1552 most_dominating_fe_index,
1555 [most_dominating_fe_index][other_fe_index]
1556 [cell->quad(q)->reference_cell() ==
1558 most_dominating_fe_index_face_no);
1560 for (
const auto &
identity : identities)
1565 most_dominating_fe_index);
1567 dependent_dof_index =
1582 if ((dependent_dof_index ==
1584 (primary_dof_index !=
1586 quad->set_dof_index(
identity.second,
1609 template <
int dim,
int spacedim>
1650 template <
int dim,
int spacedim>
1662 if (!cell->is_artificial() &&
1664 (cell->subdomain_id() == subdomain_id)))
1672 cell->active_fe_index(),
1674 DoFIndexProcessor<dim, spacedim>(),
1675 [&next_free_dof](
auto &stored_index,
auto) {
1678 stored_index = next_free_dof;
1681 std::numeric_limits<types::global_dof_index>::max(),
1683 "You have reached the maximal number of degrees of "
1684 "freedom that can be stored in the chosen data "
1685 "type. In practice, this can only happen if you "
1686 "are using 32-bit data types. You will have to "
1687 "re-compile deal.II with the "
1688 "`DEAL_II_WITH_64BIT_INDICES' flag set to `ON'."));
1695 return next_free_dof;
1713 template <
int dim,
int spacedim>
1716 std::vector<types::global_dof_index> &renumbering,
1720 std::vector<types::global_dof_index> local_dof_indices;
1723 if (cell->is_ghost() && (cell->subdomain_id() < subdomain_id))
1731 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
1735 cell->active_fe_index());
1736 for (
const auto &local_dof_index : local_dof_indices)
1748 template <
int dim,
int spacedim>
1752 const unsigned int level)
1757 const ::Triangulation<dim, spacedim> &tria =
1760 if (
level >= tria.n_levels())
1767 (cell->level_subdomain_id() == level_subdomain_id))
1774 MGDoFIndexProcessor<dim, spacedim>(
level),
1775 [&next_free_dof](
auto &stored_index,
auto) {
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;
1810 template <
int dim,
int spacedim>
1813 const std::vector<types::global_dof_index> &new_numbers,
1814 const IndexSet &indices_we_care_about,
1817 for (
unsigned int d = 1; d < dim; ++d)
1820 i = ((indices_we_care_about.
size() == 0) ?
1827 template <
int dim,
int spacedim>
1830 const std::vector<types::global_dof_index> &new_numbers,
1831 const IndexSet &indices_we_care_about,
1833 const bool check_validity)
1843 for (std::vector<types::global_dof_index>::iterator i =
1849 (indices_we_care_about.
size() == 0) ?
1852 else if (check_validity)
1863 for (
unsigned int vertex_index = 0;
1867 const unsigned int n_active_fe_indices =
1872 std::integral_constant<int, 0>());
1886 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1895 std::integral_constant<int, 0>());
1897 for (
unsigned int d = 0;
1898 d < dof_handler.
get_fe(fe_index).n_dofs_per_vertex();
1909 std::integral_constant<int, 0>());
1940 if (indices_we_care_about.
size() == 0)
1948 std::integral_constant<int, 0>(),
1949 new_numbers[old_dof_index]);
1961 std::integral_constant<int, 0>(),
1962 new_numbers[indices_we_care_about
1966 ::internal::DoFAccessorImplementation::
1967 Implementation::set_dof_index(
1973 std::integral_constant<int, 0>(),
1984 template <
int dim,
int spacedim>
1987 const std::vector<types::global_dof_index> &new_numbers,
1988 const IndexSet &indices_we_care_about,
1993 for (
unsigned int level = 0;
1998 i = ((indices_we_care_about.
size() == 0) ?
2006 if (!cell->is_artificial())
2010 for (
unsigned int d = 0;
2011 d < dof_handler.
get_fe(fe_index)
2012 .template n_dofs_per_object<dim>();
2016 cell->dof_index(d, fe_index);
2033 if (indices_we_care_about.
size() == 0)
2034 cell->set_dof_index(d,
2035 new_numbers[old_dof_index],
2039 if (indices_we_care_about.
is_element(old_dof_index))
2040 cell->set_dof_index(
2042 new_numbers[indices_we_care_about
2046 cell->set_dof_index(d,
2057 template <
int spacedim>
2060 const std::vector<types::global_dof_index> & ,
2070 template <
int spacedim>
2073 const std::vector<types::global_dof_index> &new_numbers,
2074 const IndexSet &indices_we_care_about,
2077 const unsigned int dim = 2;
2081 for (
unsigned int d = 1; d < dim; ++d)
2084 i = ((indices_we_care_about.
size() == 0) ?
2093 std::vector<bool> line_touched(
2096 if (!cell->is_artificial())
2097 for (
const auto l : cell->line_indices())
2098 if (!line_touched[cell->line(l)->index()])
2100 const auto line = cell->line(l);
2101 line_touched[line->index()] =
true;
2103 const unsigned int n_active_fe_indices =
2104 line->n_active_fe_indices();
2106 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2109 line->nth_active_fe_index(f);
2111 for (
unsigned int d = 0;
2117 line->dof_index(d, fe_index);
2137 if (indices_we_care_about.
size() == 0)
2138 line->set_dof_index(
2139 d, new_numbers[old_dof_index], fe_index);
2144 line->set_dof_index(
2146 new_numbers[indices_we_care_about
2151 line->set_dof_index(
2165 template <
int spacedim>
2168 const std::vector<types::global_dof_index> &new_numbers,
2169 const IndexSet &indices_we_care_about,
2172 const unsigned int dim = 3;
2176 for (
unsigned int d = 1; d < dim; ++d)
2179 i = ((indices_we_care_about.
size() == 0) ?
2188 std::vector<bool> line_touched(
2191 if (!cell->is_artificial())
2192 for (
const auto l : cell->line_indices())
2193 if (!line_touched[cell->line(l)->index()])
2195 const auto line = cell->line(l);
2196 line_touched[line->index()] =
true;
2198 const unsigned int n_active_fe_indices =
2199 line->n_active_fe_indices();
2201 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2204 line->nth_active_fe_index(f);
2206 for (
unsigned int d = 0;
2212 line->dof_index(d, fe_index);
2232 if (indices_we_care_about.
size() == 0)
2233 line->set_dof_index(
2234 d, new_numbers[old_dof_index], fe_index);
2237 line->set_dof_index(
2239 new_numbers[indices_we_care_about
2244 line->set_dof_index(
2254 std::vector<bool> quad_touched(
2257 if (!cell->is_artificial())
2258 for (
const auto q : cell->face_indices())
2259 if (!quad_touched[cell->quad(q)->index()])
2261 const auto quad = cell->quad(q);
2262 quad_touched[quad->index()] =
true;
2264 const unsigned int n_active_fe_indices =
2265 quad->n_active_fe_indices();
2267 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2270 quad->nth_active_fe_index(f);
2272 for (
unsigned int d = 0;
2278 quad->dof_index(d, fe_index);
2298 if (indices_we_care_about.
size() == 0)
2299 quad->set_dof_index(
2300 d, new_numbers[old_dof_index], fe_index);
2305 quad->set_dof_index(
2307 new_numbers[indices_we_care_about
2312 quad->set_dof_index(
2337 template <
int dim,
int space_dim>
2340 const IndexSet &indices_we_care_about,
2342 const bool check_validity)
2353 indices_we_care_about,
2360 indices_we_care_about,
2366 indices_we_care_about,
2385 template <
int dim,
int spacedim>
2388 const std::vector<::types::global_dof_index> &new_numbers,
2389 const IndexSet &indices_we_care_about,
2391 const unsigned int level)
2400 if ((i->get_coarsest_level() <=
level) &&
2401 (i->get_finest_level() >=
level))
2402 for (
unsigned int d = 0;
2406 const ::types::global_dof_index idx =
2407 i->access_index(
level,
2415 (idx < new_numbers.size()),
2419 (indices_we_care_about.
size() == 0) ?
2436 template <
int dim,
int spacedim>
2439 const std::vector<::types::global_dof_index> &new_numbers,
2440 const IndexSet &indices_we_care_about,
2442 const unsigned int level)
2444 for (std::vector<types::global_dof_index>::iterator i =
2453 (*i < new_numbers.size())),
2456 (indices_we_care_about.
size() == 0) ?
2472 template <
int spacedim>
2475 const std::vector<types::global_dof_index> & ,
2478 const unsigned int ,
2486 template <
int dim,
int spacedim>
2489 const std::vector<::types::global_dof_index> &new_numbers,
2490 const IndexSet &indices_we_care_about,
2492 const unsigned int level,
2493 const bool check_validity)
2495 const unsigned int dofs_per_line =
2497 if (dofs_per_line > 0 ||
2503 std::vector<bool> line_touched(
2505 std::vector<bool> quad_touched(
2507 for (
const auto &cell :
2509 if (cell->level_subdomain_id() !=
2513 if (dofs_per_line > 0)
2515 const auto line_indices =
2516 internal::TriaAccessorImplementation::Implementation::
2517 get_line_indices_of_cell(*cell);
2518 for (
const auto line : cell->line_indices())
2520 if (!line_touched[line_indices[line]])
2522 line_touched[line_indices[line]] =
true;
2532 std::integral_constant<int, 1>());
2533 for (
unsigned int d = 0; d < dofs_per_line; ++d)
2543 (indices_we_care_about.
size() == 0) ?
2544 new_numbers[indices[d]] :
2545 new_numbers[indices_we_care_about
2555 for (
const auto quad : cell->face_indices())
2556 if (!quad_touched[cell->quad(quad)->index()])
2558 quad_touched[cell->quad(quad)->index()] =
true;
2559 const unsigned int dofs_per_quad =
2561 if (dofs_per_quad > 0)
2569 cell->quad(quad)->index(),
2572 std::integral_constant<int, 2>());
2573 for (
unsigned int d = 0; d < dofs_per_quad; ++d)
2583 (indices_we_care_about.
size() == 0) ?
2584 new_numbers[indices[d]] :
2585 new_numbers[indices_we_care_about
2597 template <
int dim,
int spacedim>
2600 const std::vector<::types::global_dof_index> &new_numbers,
2601 const IndexSet &indices_we_care_about,
2603 const unsigned int level,
2604 const bool check_validity)
2619 indices_we_care_about,
2625 indices_we_care_about,
2632 indices_we_care_about,
2646 template <
int dim,
int spacedim>
2649 : dof_handler(&dof_handler)
2654 template <
int dim,
int spacedim>
2673 template <
int dim,
int spacedim>
2674 std::vector<NumberCache>
2677 std::vector<NumberCache> number_caches;
2678 number_caches.reserve(dof_handler->get_triangulation().n_levels());
2679 for (
unsigned int level = 0;
2680 level < dof_handler->get_triangulation().n_levels();
2689 number_caches.emplace_back(n_level_dofs);
2692 return number_caches;
2697 template <
int dim,
int spacedim>
2700 const std::vector<types::global_dof_index> &new_numbers)
const
2715 if (new_numbers.empty())
2719 *std::max_element(new_numbers.begin(), new_numbers.end()) + 1);
2724 template <
int dim,
int spacedim>
2727 const unsigned int level,
2728 const std::vector<types::global_dof_index> &new_numbers)
const
2741 template <
int dim,
int spacedim>
2744 : dof_handler(&dof_handler)
2759 template <
int dim,
int spacedim>
2760 std::vector<types::subdomain_id>
2761 get_dof_subdomain_association(
2767 std::vector<types::subdomain_id> subdomain_association(
2769 std::vector<types::global_dof_index> local_dof_indices;
2770 local_dof_indices.reserve(
2775 for (
const auto &cell : dof_handler.active_cell_iterators())
2782 const unsigned int dofs_per_cell =
2783 cell->get_fe().n_dofs_per_cell();
2784 local_dof_indices.resize(dofs_per_cell);
2788 cell->active_fe_index());
2793 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2794 if (subdomain_association[local_dof_indices[i]] ==
2796 subdomain_association[local_dof_indices[i]] = subdomain_id;
2797 else if (subdomain_association[local_dof_indices[i]] >
2800 subdomain_association[local_dof_indices[i]] = subdomain_id;
2804 Assert(std::find(subdomain_association.begin(),
2805 subdomain_association.end(),
2807 subdomain_association.end(),
2810 Assert(*std::max_element(subdomain_association.begin(),
2811 subdomain_association.end()) <
n_procs,
2814 return subdomain_association;
2824 template <
int dim,
int spacedim>
2825 std::vector<types::subdomain_id>
2826 get_dof_level_subdomain_association(
2830 const unsigned int level)
2833 std::vector<types::subdomain_id> level_subdomain_association(
2835 std::vector<types::global_dof_index> local_dof_indices;
2836 local_dof_indices.reserve(
2841 for (
const auto &cell : dof_handler.cell_iterators_on_level(
level))
2847 cell->level_subdomain_id();
2848 const unsigned int dofs_per_cell =
2849 cell->get_fe().n_dofs_per_cell();
2850 local_dof_indices.resize(dofs_per_cell);
2851 cell->get_mg_dof_indices(local_dof_indices);
2856 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2857 if (level_subdomain_association[local_dof_indices[i]] ==
2859 level_subdomain_association[local_dof_indices[i]] =
2861 else if (level_subdomain_association[local_dof_indices[i]] >
2864 level_subdomain_association[local_dof_indices[i]] =
2869 Assert(std::find(level_subdomain_association.begin(),
2870 level_subdomain_association.end(),
2872 level_subdomain_association.end(),
2875 Assert(*std::max_element(level_subdomain_association.begin(),
2876 level_subdomain_association.end()) <
n_procs,
2879 return level_subdomain_association;
2885 template <
int dim,
int spacedim>
2889 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
2891 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
2905 const internal::parallel::shared::
2906 TemporarilyRestoreSubdomainIds<dim, spacedim>
2907 subdomain_modifier(*tr);
2913 *this->dof_handler);
2929 std::vector<types::global_dof_index> new_dof_indices(
2930 n_dofs, enumeration_dof_index);
2934 const std::vector<types::subdomain_id> subdomain_association =
2935 get_dof_subdomain_association(*this->dof_handler, n_dofs,
n_procs);
2946 if (subdomain_association[i] == subdomain)
2948 Assert(new_dof_indices[i] == enumeration_dof_index,
2950 new_dof_indices[i] = next_free_index;
2956 Assert(std::find(new_dof_indices.begin(),
2957 new_dof_indices.end(),
2958 enumeration_dof_index) == new_dof_indices.end(),
2979 const std::vector<types::subdomain_id> subdomain_association =
2980 get_dof_subdomain_association(*this->dof_handler, n_dofs,
n_procs);
2982 for (
unsigned int i = 1; i < n_dofs; ++i)
2983 Assert(subdomain_association[i] >= subdomain_association[i - 1],
2986 std::vector<IndexSet> locally_owned_dofs_per_processor(
2997 unsigned int start_index = 0;
2998 unsigned int end_index = 0;
2999 while (start_index < n_dofs)
3001 while ((end_index < n_dofs) &&
3002 (subdomain_association[end_index] ==
3003 subdomain_association[start_index]))
3008 if (end_index > start_index)
3010 const unsigned int subdomain_owner =
3011 subdomain_association[start_index];
3012 locally_owned_dofs_per_processor[subdomain_owner].add_range(
3013 start_index, end_index);
3017 start_index = end_index;
3024 locally_owned_dofs_per_processor,
3030 template <
int dim,
int spacedim>
3031 std::vector<NumberCache>
3034 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3036 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3040 AssertThrow((tr->is_multilevel_hierarchy_constructed()),
3042 "Multigrid DoFs can only be distributed on a parallel "
3043 "Triangulation if the flag construct_multigrid_hierarchy "
3044 "is set in the constructor."));
3048 const unsigned int n_levels = tr->n_global_levels();
3050 std::vector<NumberCache> number_caches;
3051 number_caches.reserve(n_levels);
3054 for (
unsigned int lvl = 0; lvl < n_levels; ++lvl)
3062 std::vector<types::subdomain_id> saved_level_subdomain_ids;
3063 saved_level_subdomain_ids.resize(tr->n_cells(lvl));
3065 typename ::parallel::shared::Triangulation<dim, spacedim>::
3066 cell_iterator cell =
3072 const std::vector<types::subdomain_id> &true_level_subdomain_ids =
3073 tr->get_true_level_subdomain_ids_of_cells(lvl);
3075 for (
unsigned int index = 0; cell != endc; ++cell, ++
index)
3077 saved_level_subdomain_ids[
index] = cell->level_subdomain_id();
3078 cell->set_level_subdomain_id(true_level_subdomain_ids[
index]);
3097 std::vector<types::global_dof_index> new_dof_indices(
3102 const std::vector<types::subdomain_id>
3103 level_subdomain_association =
3104 get_dof_level_subdomain_association(*this->dof_handler,
3119 if (level_subdomain_association[i] == level_subdomain)
3123 new_dof_indices[i] = next_free_index;
3129 Assert(std::find(new_dof_indices.begin(),
3130 new_dof_indices.end(),
3132 new_dof_indices.end(),
3141 new_dof_indices,
IndexSet(0), *this->dof_handler, lvl,
true);
3153 const std::vector<types::subdomain_id> level_subdomain_association =
3154 get_dof_level_subdomain_association(*this->dof_handler,
3159 for (
unsigned int i = 1; i < n_dofs_on_level; ++i)
3160 Assert(level_subdomain_association[i] >=
3161 level_subdomain_association[i - 1],
3164 std::vector<IndexSet> locally_owned_dofs_per_processor(
3175 unsigned int start_index = 0;
3176 unsigned int end_index = 0;
3177 while (start_index < n_dofs_on_level)
3179 while ((end_index) < n_dofs_on_level &&
3180 (level_subdomain_association[end_index] ==
3181 level_subdomain_association[start_index]))
3186 if (end_index > start_index)
3188 const unsigned int level_subdomain_owner =
3189 level_subdomain_association[start_index];
3190 locally_owned_dofs_per_processor[level_subdomain_owner]
3191 .add_range(start_index, end_index);
3195 start_index = end_index;
3201 typename ::parallel::shared::Triangulation<dim, spacedim>::
3202 cell_iterator cell =
3208 for (
unsigned int index = 0; cell != endc; ++cell, ++
index)
3209 cell->set_level_subdomain_id(saved_level_subdomain_ids[
index]);
3212 number_caches.emplace_back(
3219 return number_caches;
3224 template <
int dim,
int spacedim>
3227 const std::vector<types::global_dof_index> &new_numbers)
const
3229#ifndef DEAL_II_WITH_MPI
3236 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3238 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3243 const internal::parallel::shared::
3244 TemporarilyRestoreSubdomainIds<dim, spacedim>
3245 subdomain_modifier(*tr);
3247 std::vector<types::global_dof_index> global_gathered_numbers(
3248 this->dof_handler->
n_dofs(), 0);
3253 const bool uses_sequential_numbering =
3254 new_numbers.size() == this->dof_handler->
n_dofs();
3255 bool all_use_sequential_numbering =
false;
3256 Utilities::MPI::internal::all_reduce<bool>(
3259 tr->get_mpi_communicator(),
3261 if (all_use_sequential_numbering)
3263 global_gathered_numbers = new_numbers;
3267 Assert(new_numbers.size() ==
3268 this->dof_handler->locally_owned_dofs().n_elements(),
3270 const unsigned int n_cpu =
3272 std::vector<types::global_dof_index> gathered_new_numbers(
3273 this->dof_handler->
n_dofs(), 0);
3275 tr->get_mpi_communicator()) ==
3276 this->dof_handler->get_triangulation()
3277 .locally_owned_subdomain(),
3282 std::vector<types::global_dof_index> new_numbers_copy(
3287 std::vector<int> rcounts(n_cpu);
3291 int cur_count = new_numbers_copy.size();
3292 int ierr = MPI_Allgather(&cur_count,
3298 tr->get_mpi_communicator());
3303 std::vector<int> displacements(n_cpu);
3304 for (
unsigned int i = 0; i < n_cpu; ++i)
3306 displacements[i] = shift;
3307 shift += rcounts[i];
3309 Assert(new_numbers_copy.size() ==
3310 static_cast<unsigned int>(
3312 tr->get_mpi_communicator())]),
3314 ierr = MPI_Allgatherv(new_numbers_copy.data(),
3315 new_numbers_copy.size(),
3317 gathered_new_numbers.data(),
3319 displacements.data(),
3321 tr->get_mpi_communicator());
3331 std::vector<unsigned int> flag_1(this->dof_handler->
n_dofs(), 0);
3332 std::vector<unsigned int> flag_2(this->dof_handler->
n_dofs(), 0);
3333 std::vector<IndexSet> locally_owned_dofs_per_processor =
3335 tr->get_mpi_communicator(),
3336 this->dof_handler->locally_owned_dofs());
3337 for (
unsigned int i = 0; i < n_cpu; ++i)
3339 const IndexSet &iset = locally_owned_dofs_per_processor[i];
3346 gathered_new_numbers[shift + ind];
3351 global_gathered_numbers[target] =
value;
3358 Assert(*std::max_element(flag_1.begin(), flag_1.end()) == 1,
3360 Assert(*std::min_element(flag_1.begin(), flag_1.end()) == 1,
3362 Assert((*std::max_element(flag_2.begin(), flag_2.end())) == 1,
3364 Assert((*std::min_element(flag_2.begin(), flag_2.end())) == 1,
3380 return number_cache;
3386 template <
int dim,
int spacedim>
3389 const unsigned int ,
3390 const std::vector<types::global_dof_index> & )
const
3402#ifdef DEAL_II_WITH_MPI
3406 template <
int dim,
int spacedim>
3409 std::vector<std::vector<bool>> &cell_marked)
3411 const auto pack = [](
const auto &cell) {
3415 std::vector<::types::global_dof_index>
data(
3416 cell->get_fe().n_dofs_per_cell());
3417 cell->get_mg_dof_indices(
data);
3422 const auto unpack = [&cell_marked](
const auto &cell,
3424 Assert(cell->get_fe().n_dofs_per_cell() == dofs.size(),
3427 Assert(cell->level_subdomain_id() !=
3431 bool complete =
true;
3437 MGDoFIndexProcessor<dim, spacedim>(cell->
level()),
3447 [&complete, invalid_dof_index =
numbers::invalid_dof_index](
3448 auto &stored_index, auto received_index) {
3449 if (*received_index != invalid_dof_index)
3451# if !defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1900
3452 Assert((stored_index == invalid_dof_index) ||
3453 (stored_index == *received_index),
3456 stored_index = *received_index;
3466 Assert(cell_marked[cell->level()][cell->index()],
3470 cell_marked[cell->level()][cell->index()] =
false;
3473 const auto filter = [&cell_marked](
const auto &cell) {
3474 return cell_marked[cell->level()][cell->index()];
3478 std::vector<types::global_dof_index>,
3502 template <
int dim,
int spacedim>
3504 communicate_dof_indices_on_marked_cells(
3506 std::vector<bool> &cell_marked)
3508# ifndef DEAL_II_WITH_MPI
3516 const auto pack = [](
const auto &cell) {
3519 std::vector<::types::global_dof_index>
data(
3520 cell->get_fe().n_dofs_per_cell());
3529 const auto unpack = [&cell_marked](
const auto &cell,
3531 Assert(cell->get_fe().n_dofs_per_cell() == dofs.size(),
3539 bool complete =
true;
3543 cell->active_fe_index(),
3544 DoFAccessorImplementation::Implementation::
3545 DoFIndexProcessor<dim, spacedim>(),
3556 auto &stored_index, const auto received_index) {
3557 if (*received_index != invalid_dof_index)
3559# if !defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1900
3560 Assert((stored_index == invalid_dof_index) ||
3561 (stored_index == *received_index),
3564 stored_index = *received_index;
3574 Assert(cell_marked[cell->active_cell_index()],
3578 cell_marked[cell->active_cell_index()] =
false;
3581 const auto filter = [&cell_marked](
const auto &cell) {
3582 return cell_marked[cell->active_cell_index()];
3586 std::vector<types::global_dof_index>,
3599 template <
int dim,
int spacedim>
3602 : dof_handler(&dof_handler)
3607 template <
int dim,
int spacedim>
3611#ifndef DEAL_II_WITH_MPI
3660 std::vector<::types::global_dof_index> renumbering(
3661 n_initial_local_dofs, enumeration_dof_index);
3668 renumbering, subdomain_id, *dof_handler);
3672 std::vector<std::map<types::global_dof_index, types::global_dof_index>>
3673 all_constrained_indices(dim);
3688 for (
const auto &constrained_indices : all_constrained_indices)
3689 for (
const auto &
index : constrained_indices)
3691 ++n_identity_constrained_indices;
3694 std::count(renumbering.begin(),
3696 enumeration_dof_index) -
3697 n_identity_constrained_indices;
3701 const auto [my_shift, n_global_dofs] =
3703 n_locally_owned_dofs,
triangulation->get_mpi_communicator());
3708 renumbering, all_constrained_indices, my_shift);
3724 n_locally_owned_dofs);
3738 std::vector<bool> cell_marked(
triangulation->n_active_cells());
3740 if (cell->is_ghost())
3741 cell_marked[cell->active_cell_index()] =
true;
3749 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
3762 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
3769 Assert(cell_marked[cell->active_cell_index()] ==
false,
3778 std::vector<::types::global_dof_index> local_dof_indices;
3781 if (!cell->is_artificial())
3783 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
3784 cell->get_dof_indices(local_dof_indices);
3785 if (local_dof_indices.end() !=
3786 std::find(local_dof_indices.begin(),
3787 local_dof_indices.end(),
3790 if (cell->is_ghost())
3794 "A ghost cell ended up with incomplete "
3795 "DoF index information. This should not "
3803 "A locally owned cell ended up with incomplete "
3804 "DoF index information. This should not "
3811 return number_cache;
3817 template <
int dim,
int spacedim>
3818 std::vector<NumberCache>
3821#ifndef DEAL_II_WITH_MPI
3823 return std::vector<NumberCache>();
3836 "Multigrid DoFs can only be distributed on a parallel "
3837 "Triangulation if the flag construct_multigrid_hierarchy "
3838 "is set in the constructor."));
3845 const unsigned int n_levels =
triangulation->n_global_levels();
3846 std::vector<NumberCache> number_caches;
3847 number_caches.reserve(n_levels);
3853 const unsigned int n_initial_local_dofs =
3859 std::vector<::types::global_dof_index> renumbering(
3860 n_initial_local_dofs, enumeration_dof_index);
3862 if (level < triangulation->n_levels())
3864 std::vector<::types::global_dof_index> local_dof_indices;
3866 for (
const auto &cell :
3868 if (cell->level_subdomain_id() !=
3870 (cell->level_subdomain_id() <
3880 local_dof_indices.resize(
3881 cell->get_fe().n_dofs_per_cell());
3882 cell->get_mg_dof_indices(local_dof_indices);
3883 for (
unsigned int i = 0;
3884 i < cell->get_fe().n_dofs_per_cell();
3887 renumbering[local_dof_indices[i]] =
3893 std::count(renumbering.begin(),
3895 enumeration_dof_index);
3899 const auto [my_shift, n_global_dofs] =
3908 if (
index == enumeration_dof_index)
3909 index = next_free_index++;
3919 if (level < triangulation->n_levels())
3931 number_caches.emplace_back(level_number_cache);
3940 std::vector<std::vector<bool>> cell_marked(
triangulation->n_levels());
3941 for (
unsigned int l = 0; l <
triangulation->n_levels(); ++l)
3944 if (cell->is_ghost_on_level())
3945 cell_marked[cell->level()][cell->index()] =
true;
3950 communicate_mg_ghost_cells(*dof_handler, cell_marked);
3954 communicate_mg_ghost_cells(*dof_handler, cell_marked);
3960 Assert(cell_marked[cell->level()][cell->index()] ==
false,
3971 std::vector<::types::global_dof_index> local_dof_indices;
3973 if (cell->level_subdomain_id() !=
3976 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
3977 cell->get_mg_dof_indices(local_dof_indices);
3978 if (local_dof_indices.end() !=
3979 std::find(local_dof_indices.begin(),
3980 local_dof_indices.end(),
3984 ExcMessage(
"not all DoFs got distributed!"));
3990 return number_caches;
3996 template <
int dim,
int spacedim>
3999 const std::vector<::types::global_dof_index> &new_numbers)
const
4006#ifndef DEAL_II_WITH_MPI
4024 const bool locally_owned_set_changes =
4025 std::any_of(new_numbers.cbegin(),
4028 return owned_dofs.is_element(i) == false;
4031 IndexSet my_locally_owned_new_dof_indices = owned_dofs;
4032 if (locally_owned_set_changes && owned_dofs.
n_elements() > 0)
4034 std::vector<::types::global_dof_index> new_numbers_sorted =
4036 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
4038 my_locally_owned_new_dof_indices =
IndexSet(dof_handler->
n_dofs());
4040 new_numbers_sorted.begin(), new_numbers_sorted.end());
4041 my_locally_owned_new_dof_indices.
compress();
4060 if (cell->is_ghost())
4065 cell->active_fe_index(),
4067 DoFIndexProcessor<dim, spacedim>(),
4068 [&owned_dofs](
auto &stored_index,
auto) {
4095 std::vector<bool> cell_marked(
triangulation->n_active_cells());
4097 if (cell->is_ghost())
4098 cell_marked[cell->active_cell_index()] =
true;
4106 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
4116 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
4124 return number_cache;
4130 template <
int dim,
int spacedim>
4133 const unsigned int level,
4134 const std::vector<types::global_dof_index> &new_numbers)
const
4136#ifndef DEAL_II_WITH_MPI
4159 const bool locally_owned_set_changes =
4160 std::any_of(new_numbers.cbegin(),
4163 return owned_dofs.is_element(i) == false;
4166 IndexSet my_locally_owned_new_dof_indices = owned_dofs;
4167 if (locally_owned_set_changes && owned_dofs.
n_elements() > 0)
4169 std::vector<::types::global_dof_index> new_numbers_sorted =
4171 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
4173 my_locally_owned_new_dof_indices =
4176 new_numbers_sorted.begin(), new_numbers_sorted.end());
4177 my_locally_owned_new_dof_indices.
compress();
4187 if (cell->is_ghost_on_level())
4194 MGDoFIndexProcessor<dim, spacedim>(cell->level()),
4195 [&owned_dofs](
auto &stored_index,
auto) {
4204 if (level < triangulation->n_levels() && owned_dofs.
n_elements() > 0)
4206 new_numbers, owned_dofs, *dof_handler,
level,
false);
4210 std::vector<std::vector<bool>> cell_marked(
triangulation->n_levels());
4211 for (
unsigned int l = 0; l <
triangulation->n_levels(); ++l)
4214 if (cell->is_ghost_on_level())
4215 cell_marked[cell->level()][cell->index()] =
true;
4217 communicate_mg_ghost_cells(*dof_handler, cell_marked);
4219 communicate_mg_ghost_cells(*dof_handler, cell_marked);
4227 return number_cache;
4237#include "dofs/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
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NOT_IMPLEMENTED()
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)
std::vector< index_type > data
const unsigned int n_procs
constexpr const ReferenceCell Quadrilateral
std::pair< T, T > partial_and_total_sum(const T &value, const MPI_Comm comm)
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)
std::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)
constexpr types::global_dof_index invalid_dof_index
constexpr unsigned int invalid_unsigned_int
constexpr types::subdomain_id artificial_subdomain_id
constexpr types::subdomain_id invalid_subdomain_id
constexpr types::fe_index invalid_fe_index
unsigned short int fe_index
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
static void process_dof_indices(const ::DoFAccessor< structdim, dim, spacedim, level_dof_access > &accessor, const DoFIndicesType &const_dof_indices, const types::fe_index fe_index_, const DoFOperation &dof_operation, const DoFProcessor &dof_processor, const bool count_level_dofs)
static void get_dof_indices(const ::DoFAccessor< structdim, dim, spacedim, level_dof_access > &accessor, std::vector< types::global_dof_index > &dof_indices, const types::fe_index fe_index)
static std::set< types::fe_index > get_active_fe_indices(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const std::integral_constant< int, structdim > &t)
static unsigned int n_active_fe_indices(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const std::integral_constant< int, structdim > &)
static void set_dof_index(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const types::fe_index fe_index, const unsigned int local_index, const std::integral_constant< int, structdim > &dd, const types::global_dof_index global_index)
static types::global_dof_index & get_mg_dof_index(const DoFHandler< dim, spacedim > &dof_handler, const std::unique_ptr< internal::DoFHandlerImplementation::DoFLevel< dim > > &mg_level, const std::unique_ptr< internal::DoFHandlerImplementation::DoFFaces< dim > > &, const unsigned int obj_index, const types::fe_index fe_index, const unsigned int local_index, const std::integral_constant< int, dim >)
static types::fe_index nth_active_fe_index(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const unsigned int local_index, const std::integral_constant< int, structdim > &)
static types::global_dof_index get_dof_index(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int obj_level, const unsigned int obj_index, const types::fe_index fe_index, const unsigned int local_index, const std::integral_constant< int, structdim > &dd)
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 > &)
#define DEAL_II_DOF_INDEX_MPI_TYPE