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},
138 for (
const auto &complete_identity : complete_identities)
141 Assert(complete_identity.find(fe_index_1) !=
142 complete_identity.end(),
144 Assert(complete_identity.find(fe_index_2) !=
145 complete_identity.end(),
157 DoFIdentities reduced_identities;
158 for (
const auto &complete_identity : complete_identities)
160 const unsigned int dof_index_1 =
161 complete_identity.at(fe_index_1);
162 const unsigned int dof_index_2 =
163 complete_identity.at(fe_index_2);
165 reduced_identities.emplace_back(dof_index_1, dof_index_2);
171 for (
const auto &
identity : reduced_identities)
175 .template n_dofs_per_object<structdim>(face_no),
179 .template n_dofs_per_object<structdim>(face_no),
185 std::make_unique<DoFIdentities>(std::move(reduced_identities));
202 template <
int dim,
int spacedim>
203 static std::map<types::global_dof_index, types::global_dof_index>
211 std::map<types::global_dof_index, types::global_dof_index>
225 for (
unsigned int vertex_index = 0;
231 const unsigned int n_active_fe_indices =
232 ::internal::DoFAccessorImplementation::Implementation::
233 n_active_fe_indices(dof_handler,
236 std::integral_constant<int, 0>());
238 if (n_active_fe_indices > 1)
240 const std::set<types::fe_index> fe_indices =
241 ::internal::DoFAccessorImplementation::
242 Implementation::get_active_fe_indices(
246 std::integral_constant<int, 0>());
253 {fe_indices.begin(), fe_indices.end()},
260 most_dominating_fe_index =
261 ::internal::DoFAccessorImplementation::
262 Implementation::nth_active_fe_index(
267 std::integral_constant<int, 0>());
273 for (
const auto &other_fe_index : fe_indices)
274 if (other_fe_index != most_dominating_fe_index)
278 const auto &identities =
279 *ensure_existence_and_return_dof_identities<0>(
281 most_dominating_fe_index,
283 vertex_dof_identities[most_dominating_fe_index]
294 for (
const auto &
identity : identities)
297 ::internal::DoFAccessorImplementation::
298 Implementation::get_dof_index(
302 most_dominating_fe_index,
304 std::integral_constant<int, 0>());
306 dependent_dof_index =
307 ::internal::DoFAccessorImplementation::
308 Implementation::get_dof_index(
314 std::integral_constant<int, 0>());
329 if (dependent_dof_index !=
339 if (primary_dof_index !=
342 (dof_identities.find(primary_dof_index) ==
343 dof_identities.end()) ||
344 (dof_identities[dependent_dof_index] ==
348 dof_identities[dependent_dof_index] =
356 return dof_identities;
364 template <
int spacedim>
365 static std::map<types::global_dof_index, types::global_dof_index>
372 return std::map<types::global_dof_index, types::global_dof_index>();
376 template <
int dim,
int spacedim>
377 static std::map<types::global_dof_index, types::global_dof_index>
385 std::map<types::global_dof_index, types::global_dof_index>
410 std::vector<bool> line_touched(
413 for (
const auto l : cell->line_indices())
414 if (!line_touched[cell->line(l)->index()])
416 const auto line = cell->line(l);
417 line_touched[line->index()] =
true;
419 unsigned int unique_sets_of_dofs =
420 line->n_active_fe_indices();
424 const unsigned int n_active_fe_indices =
425 line->n_active_fe_indices();
426 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
427 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
430 line->nth_active_fe_index(f),
432 line->nth_active_fe_index(g);
451 dof_handler.
get_fe(fe_index_2)
457 const unsigned int dofs_per_line =
460 const auto &identities =
461 *ensure_existence_and_return_dof_identities<1>(
465 line_dof_identities[fe_index_1][fe_index_2]);
469 if (identities.size() == dofs_per_line)
472 for (; i < dofs_per_line; ++i)
473 if ((identities[i].
first != i) &&
474 (identities[i].
second != i))
478 if (i == dofs_per_line)
487 --unique_sets_of_dofs;
491 const std::set<types::fe_index> fe_indices{
492 fe_index_1, fe_index_2};
503 if (dominating_fe_index !=
506 (dominating_fe_index == fe_index_1) ?
514 dominating_fe_index = fe_index_1;
515 other_fe_index = fe_index_2;
518 for (
unsigned int j = 0; j < dofs_per_line;
522 primary_dof_index = line->dof_index(
523 j, dominating_fe_index);
525 dependent_dof_index =
526 line->dof_index(j, other_fe_index);
542 if (dependent_dof_index !=
545 if (primary_dof_index !=
552 if (dof_identities.find(
553 primary_dof_index) !=
554 dof_identities.end())
570 [primary_dof_index]) ==
571 dof_identities.end(),
575 [dependent_dof_index] =
585 (dof_identities.find(
586 primary_dof_index) ==
587 dof_identities.end()) ||
589 [dependent_dof_index] ==
594 [dependent_dof_index] =
604 [dependent_dof_index] =
624 if ((unique_sets_of_dofs == 2) && (dim == 2))
626 const std::set<types::fe_index> fe_indices =
627 line->get_active_fe_indices();
634 {fe_indices.begin(), fe_indices.end()},
647 for (
const auto &other_fe_index : fe_indices)
648 if (other_fe_index != most_dominating_fe_index)
650 const auto &identities =
651 *ensure_existence_and_return_dof_identities<
653 most_dominating_fe_index,
656 [most_dominating_fe_index]
659 for (
const auto &
identity : identities)
662 primary_dof_index = line->dof_index(
664 most_dominating_fe_index);
666 dependent_dof_index =
683 if (dependent_dof_index !=
693 if (primary_dof_index !=
695 Assert((dof_identities.find(
696 primary_dof_index) ==
697 dof_identities.end()) ||
699 [dependent_dof_index] ==
703 dof_identities[dependent_dof_index] =
712 return dof_identities;
721 template <
int dim,
int spacedim>
722 static std::map<types::global_dof_index, types::global_dof_index>
736 return std::map<types::global_dof_index, types::global_dof_index>();
740 template <
int spacedim>
741 static std::map<types::global_dof_index, types::global_dof_index>
749 std::map<types::global_dof_index, types::global_dof_index>
768 std::vector<bool> quad_touched(
771 for (
const auto q : cell->face_indices())
772 if (!quad_touched[cell->quad(q)->index()] &&
773 (cell->quad(q)->n_active_fe_indices() == 2))
775 const auto quad = cell->quad(q);
776 quad_touched[quad->index()] =
true;
778 const std::set<types::fe_index> fe_indices =
779 quad->get_active_fe_indices();
786 {fe_indices.begin(), fe_indices.end()},
789 const unsigned int most_dominating_fe_index_face_no =
790 cell->active_fe_index() == most_dominating_fe_index ?
792 cell->neighbor_face_no(q);
806 for (
const auto &other_fe_index : fe_indices)
807 if (other_fe_index != most_dominating_fe_index)
809 const auto &identities =
810 *ensure_existence_and_return_dof_identities<2>(
812 most_dominating_fe_index,
815 [most_dominating_fe_index][other_fe_index]
816 [cell->quad(q)->reference_cell() ==
818 most_dominating_fe_index_face_no);
820 for (
const auto &
identity : identities)
825 most_dominating_fe_index);
827 dependent_dof_index =
836 if (dependent_dof_index !=
846 if (primary_dof_index !=
848 Assert((dof_identities.find(
849 primary_dof_index) ==
850 dof_identities.end()) ||
852 [dependent_dof_index] ==
856 dof_identities[dependent_dof_index] =
864 return dof_identities;
873 template <
int dim,
int spacedim>
877 &all_constrained_indices,
889 all_constrained_indices[i] =
897 all_constrained_indices[i] =
906 all_constrained_indices[i] =
937 std::vector<types::global_dof_index> &new_dof_indices,
939 std::map<types::global_dof_index, types::global_dof_index>>
940 &all_constrained_indices,
944 for (
const auto &constrained_dof_indices : all_constrained_indices)
945 for (
const auto &p : constrained_dof_indices)
948 Assert(new_dof_indices[p.first] == enumeration_dof_index,
951 new_dof_indices[p.first] = p.second;
956 for (
auto &new_dof_index : new_dof_indices)
957 if (new_dof_index == enumeration_dof_index)
958 new_dof_index = next_free_dof++;
962 for (
const auto &constrained_dof_indices : all_constrained_indices)
963 for (
const auto &p : constrained_dof_indices)
966 Assert(new_dof_indices[p.first] != enumeration_dof_index,
970 new_dof_indices[p.first] = new_dof_indices[p.second];
976 Assert(new_dof_index != enumeration_dof_index,
978 Assert(new_dof_index < next_free_dof ||
983 return next_free_dof;
996 template <
int dim,
int spacedim>
999 const unsigned int n_dofs_before_identification,
1000 const bool check_validity)
1003 return n_dofs_before_identification;
1006 std::map<types::global_dof_index, types::global_dof_index>>
1007 all_constrained_indices(dim);
1010 std::vector<::types::global_dof_index> renumbering(
1011 n_dofs_before_identification, enumeration_dof_index);
1014 all_constrained_indices,
1028 template <
int dim,
int spacedim>
1049 std::vector<bool> include_vertex(
1051 if (
dynamic_cast<const ::parallel::
1052 DistributedTriangulationBase<dim, spacedim> *
>(
1055 if (cell->is_ghost())
1056 for (
const unsigned int v : cell->vertex_indices())
1057 include_vertex[cell->vertex_index(v)] =
true;
1060 for (
unsigned int vertex_index = 0;
1065 (include_vertex[vertex_index] ==
true))
1067 const unsigned int n_active_fe_indices =
1068 ::internal::DoFAccessorImplementation::Implementation::
1069 n_active_fe_indices(dof_handler,
1072 std::integral_constant<int, 0>());
1074 if (n_active_fe_indices > 1)
1076 const std::set<types::fe_index> fe_indices =
1077 ::internal::DoFAccessorImplementation::
1078 Implementation::get_active_fe_indices(
1082 std::integral_constant<int, 0>());
1089 {fe_indices.begin(), fe_indices.end()},
1096 most_dominating_fe_index =
1097 ::internal::DoFAccessorImplementation::
1098 Implementation::nth_active_fe_index(
1103 std::integral_constant<int, 0>());
1109 for (
const auto &other_fe_index : fe_indices)
1110 if (other_fe_index != most_dominating_fe_index)
1114 const auto &identities =
1115 *ensure_existence_and_return_dof_identities<0>(
1117 most_dominating_fe_index,
1119 vertex_dof_identities[most_dominating_fe_index]
1130 for (
const auto &
identity : identities)
1133 ::internal::DoFAccessorImplementation::
1134 Implementation::get_dof_index(
1138 most_dominating_fe_index,
1140 std::integral_constant<int, 0>());
1142 dependent_dof_index =
1143 ::internal::DoFAccessorImplementation::
1144 Implementation::get_dof_index(
1150 std::integral_constant<int, 0>());
1164 if ((dependent_dof_index ==
1166 (primary_dof_index !=
1168 ::internal::DoFAccessorImplementation::
1169 Implementation::set_dof_index(
1175 std::integral_constant<int, 0>(),
1189 template <
int spacedim>
1200 template <
int dim,
int spacedim>
1210 std::vector<bool> line_marked(
1213 if (cell->is_ghost())
1214 for (
const auto l : cell->line_indices())
1215 line_marked[cell->line(l)->index()] =
true;
1240 for (
const auto l : cell->line_indices())
1241 if ((cell->is_locally_owned()) &&
1242 line_marked[cell->line(l)->index()])
1244 const auto line = cell->line(l);
1245 line_marked[line->index()] =
false;
1247 unsigned int unique_sets_of_dofs =
1248 line->n_active_fe_indices();
1252 const unsigned int n_active_fe_indices =
1253 line->n_active_fe_indices();
1254 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1255 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
1258 line->nth_active_fe_index(f),
1260 line->nth_active_fe_index(g);
1263 dof_handler.
get_fe(fe_index_2)
1269 const unsigned int dofs_per_line =
1272 const auto &identities =
1273 *ensure_existence_and_return_dof_identities<1>(
1277 line_dof_identities[fe_index_1][fe_index_2]);
1281 if (identities.size() == dofs_per_line)
1284 for (; i < dofs_per_line; ++i)
1285 if ((identities[i].
first != i) &&
1286 (identities[i].
second != i))
1290 if (i == dofs_per_line)
1299 --unique_sets_of_dofs;
1303 const std::set<types::fe_index> fe_indices{
1304 fe_index_1, fe_index_2};
1315 if (dominating_fe_index !=
1318 (dominating_fe_index == fe_index_1) ?
1326 dominating_fe_index = fe_index_1;
1327 other_fe_index = fe_index_2;
1330 for (
unsigned int j = 0; j < dofs_per_line;
1334 primary_dof_index = line->dof_index(
1335 j, dominating_fe_index);
1337 dependent_dof_index =
1338 line->dof_index(j, other_fe_index);
1353 if ((dependent_dof_index ==
1355 (primary_dof_index !=
1357 line->set_dof_index(j,
1376 if ((unique_sets_of_dofs == 2) && (dim == 2))
1378 const std::set<types::fe_index> fe_indices =
1379 line->get_active_fe_indices();
1386 {fe_indices.begin(), fe_indices.end()},
1399 for (
const auto &other_fe_index : fe_indices)
1400 if (other_fe_index != most_dominating_fe_index)
1402 const auto &identities =
1403 *ensure_existence_and_return_dof_identities<
1405 most_dominating_fe_index,
1408 [most_dominating_fe_index]
1411 for (
const auto &
identity : identities)
1414 primary_dof_index = line->dof_index(
1416 most_dominating_fe_index);
1418 dependent_dof_index =
1434 if ((dependent_dof_index ==
1436 (primary_dof_index !=
1438 line->set_dof_index(
identity.second,
1454 template <
int dim,
int spacedim>
1471 template <
int spacedim>
1482 std::vector<bool> quad_marked(
1485 if (cell->is_ghost())
1486 for (
const auto q : cell->face_indices())
1487 quad_marked[cell->quad(q)->index()] =
true;
1506 for (
const auto q : cell->face_indices())
1507 if ((cell->is_locally_owned()) &&
1508 quad_marked[cell->quad(q)->index()] &&
1509 (cell->quad(q)->n_active_fe_indices() == 2))
1511 const auto quad = cell->quad(q);
1512 quad_marked[quad->index()] =
false;
1514 const std::set<types::fe_index> fe_indices =
1515 quad->get_active_fe_indices();
1522 {fe_indices.begin(), fe_indices.end()},
1526 cell->active_fe_index() == most_dominating_fe_index ?
1528 cell->neighbor_face_no(q);
1542 for (
const auto &other_fe_index : fe_indices)
1543 if (other_fe_index != most_dominating_fe_index)
1545 const auto &identities =
1546 *ensure_existence_and_return_dof_identities<2>(
1548 most_dominating_fe_index,
1551 [most_dominating_fe_index][other_fe_index]
1552 [cell->quad(q)->reference_cell() ==
1554 most_dominating_fe_index_face_no);
1556 for (
const auto &
identity : identities)
1561 most_dominating_fe_index);
1563 dependent_dof_index =
1578 if ((dependent_dof_index ==
1580 (primary_dof_index !=
1582 quad->set_dof_index(
identity.second,
1605 template <
int dim,
int spacedim>
1646 template <
int dim,
int spacedim>
1658 if (!cell->is_artificial() &&
1660 (cell->subdomain_id() == subdomain_id)))
1665 DoFAccessorImplementation::Implementation::process_dof_indices(
1668 cell->active_fe_index(),
1669 DoFAccessorImplementation::Implementation::
1670 DoFIndexProcessor<dim, spacedim>(),
1671 [&next_free_dof](
auto &stored_index,
auto) {
1674 stored_index = next_free_dof;
1677 std::numeric_limits<types::global_dof_index>::max(),
1679 "You have reached the maximal number of degrees of "
1680 "freedom that can be stored in the chosen data "
1681 "type. In practice, this can only happen if you "
1682 "are using 32-bit data types. You will have to "
1683 "re-compile deal.II with the "
1684 "`DEAL_II_WITH_64BIT_INDICES' flag set to `ON'."));
1691 return next_free_dof;
1709 template <
int dim,
int spacedim>
1712 std::vector<types::global_dof_index> &renumbering,
1716 std::vector<types::global_dof_index> local_dof_indices;
1719 if (cell->is_ghost() && (cell->subdomain_id() < subdomain_id))
1727 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
1728 internal::DoFAccessorImplementation::Implementation::
1729 get_dof_indices(*cell,
1731 cell->active_fe_index());
1732 for (
const auto &local_dof_index : local_dof_indices)
1744 template <
int dim,
int spacedim>
1748 const unsigned int level)
1753 const ::Triangulation<dim, spacedim> &tria =
1756 if (
level >= tria.n_levels())
1763 (cell->level_subdomain_id() == level_subdomain_id))
1765 DoFAccessorImplementation::Implementation::process_dof_indices(
1769 DoFAccessorImplementation::Implementation::
1770 MGDoFIndexProcessor<dim, spacedim>(
level),
1771 [&next_free_dof](
auto &stored_index,
auto) {
1774 stored_index = next_free_dof;
1777 std::numeric_limits<types::global_dof_index>::max(),
1779 "You have reached the maximal number of degrees of "
1780 "freedom that can be stored in the chosen data "
1781 "type. In practice, this can only happen if you "
1782 "are using 32-bit data types. You will have to "
1783 "re-compile deal.II with the "
1784 "`DEAL_II_WITH_64BIT_INDICES' flag set to `ON'."));
1791 return next_free_dof;
1806 template <
int dim,
int spacedim>
1809 const std::vector<types::global_dof_index> &new_numbers,
1810 const IndexSet &indices_we_care_about,
1813 for (
unsigned int d = 1; d < dim; ++d)
1816 i = ((indices_we_care_about.
size() == 0) ?
1823 template <
int dim,
int spacedim>
1826 const std::vector<types::global_dof_index> &new_numbers,
1827 const IndexSet &indices_we_care_about,
1829 const bool check_validity)
1839 for (std::vector<types::global_dof_index>::iterator i =
1845 (indices_we_care_about.
size() == 0) ?
1848 else if (check_validity)
1859 for (
unsigned int vertex_index = 0;
1863 const unsigned int n_active_fe_indices =
1864 ::internal::DoFAccessorImplementation::Implementation::
1865 n_active_fe_indices(dof_handler,
1868 std::integral_constant<int, 0>());
1882 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1885 ::internal::DoFAccessorImplementation::
1886 Implementation::nth_active_fe_index(
1891 std::integral_constant<int, 0>());
1893 for (
unsigned int d = 0;
1894 d < dof_handler.
get_fe(fe_index).n_dofs_per_vertex();
1898 ::internal::DoFAccessorImplementation::
1899 Implementation::get_dof_index(
1905 std::integral_constant<int, 0>());
1936 if (indices_we_care_about.
size() == 0)
1937 ::internal::DoFAccessorImplementation::
1938 Implementation::set_dof_index(
1944 std::integral_constant<int, 0>(),
1945 new_numbers[old_dof_index]);
1950 ::internal::DoFAccessorImplementation::
1951 Implementation::set_dof_index(
1957 std::integral_constant<int, 0>(),
1958 new_numbers[indices_we_care_about
1962 ::internal::DoFAccessorImplementation::
1963 Implementation::set_dof_index(
1969 std::integral_constant<int, 0>(),
1980 template <
int dim,
int spacedim>
1983 const std::vector<types::global_dof_index> &new_numbers,
1984 const IndexSet &indices_we_care_about,
1989 for (
unsigned int level = 0;
1994 i = ((indices_we_care_about.
size() == 0) ?
2002 if (!cell->is_artificial())
2006 for (
unsigned int d = 0;
2007 d < dof_handler.
get_fe(fe_index)
2008 .template n_dofs_per_object<dim>();
2012 cell->dof_index(d, fe_index);
2029 if (indices_we_care_about.
size() == 0)
2030 cell->set_dof_index(d,
2031 new_numbers[old_dof_index],
2035 if (indices_we_care_about.
is_element(old_dof_index))
2036 cell->set_dof_index(
2038 new_numbers[indices_we_care_about
2042 cell->set_dof_index(d,
2053 template <
int spacedim>
2056 const std::vector<types::global_dof_index> & ,
2066 template <
int spacedim>
2069 const std::vector<types::global_dof_index> &new_numbers,
2070 const IndexSet &indices_we_care_about,
2073 const unsigned int dim = 2;
2077 for (
unsigned int d = 1; d < dim; ++d)
2080 i = ((indices_we_care_about.
size() == 0) ?
2089 std::vector<bool> line_touched(
2092 if (!cell->is_artificial())
2093 for (
const auto l : cell->line_indices())
2094 if (!line_touched[cell->line(l)->index()])
2096 const auto line = cell->line(l);
2097 line_touched[line->index()] =
true;
2099 const unsigned int n_active_fe_indices =
2100 line->n_active_fe_indices();
2102 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2105 line->nth_active_fe_index(f);
2107 for (
unsigned int d = 0;
2113 line->dof_index(d, fe_index);
2133 if (indices_we_care_about.
size() == 0)
2134 line->set_dof_index(
2135 d, new_numbers[old_dof_index], fe_index);
2140 line->set_dof_index(
2142 new_numbers[indices_we_care_about
2147 line->set_dof_index(
2161 template <
int spacedim>
2164 const std::vector<types::global_dof_index> &new_numbers,
2165 const IndexSet &indices_we_care_about,
2168 const unsigned int dim = 3;
2172 for (
unsigned int d = 1; d < dim; ++d)
2175 i = ((indices_we_care_about.
size() == 0) ?
2184 std::vector<bool> line_touched(
2187 if (!cell->is_artificial())
2188 for (
const auto l : cell->line_indices())
2189 if (!line_touched[cell->line(l)->index()])
2191 const auto line = cell->line(l);
2192 line_touched[line->index()] =
true;
2194 const unsigned int n_active_fe_indices =
2195 line->n_active_fe_indices();
2197 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2200 line->nth_active_fe_index(f);
2202 for (
unsigned int d = 0;
2208 line->dof_index(d, fe_index);
2228 if (indices_we_care_about.
size() == 0)
2229 line->set_dof_index(
2230 d, new_numbers[old_dof_index], fe_index);
2233 line->set_dof_index(
2235 new_numbers[indices_we_care_about
2240 line->set_dof_index(
2250 std::vector<bool> quad_touched(
2253 if (!cell->is_artificial())
2254 for (
const auto q : cell->face_indices())
2255 if (!quad_touched[cell->quad(q)->index()])
2257 const auto quad = cell->quad(q);
2258 quad_touched[quad->index()] =
true;
2260 const unsigned int n_active_fe_indices =
2261 quad->n_active_fe_indices();
2263 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2266 quad->nth_active_fe_index(f);
2268 for (
unsigned int d = 0;
2274 quad->dof_index(d, fe_index);
2294 if (indices_we_care_about.
size() == 0)
2295 quad->set_dof_index(
2296 d, new_numbers[old_dof_index], fe_index);
2301 quad->set_dof_index(
2303 new_numbers[indices_we_care_about
2308 quad->set_dof_index(
2333 template <
int dim,
int space_dim>
2336 const IndexSet &indices_we_care_about,
2338 const bool check_validity)
2349 indices_we_care_about,
2356 indices_we_care_about,
2362 indices_we_care_about,
2381 template <
int dim,
int spacedim>
2384 const std::vector<::types::global_dof_index> &new_numbers,
2385 const IndexSet &indices_we_care_about,
2387 const unsigned int level)
2396 if ((i->get_coarsest_level() <=
level) &&
2397 (i->get_finest_level() >=
level))
2398 for (
unsigned int d = 0;
2402 const ::types::global_dof_index idx =
2403 i->access_index(
level,
2411 (idx < new_numbers.size()),
2415 (indices_we_care_about.
size() == 0) ?
2432 template <
int dim,
int spacedim>
2435 const std::vector<::types::global_dof_index> &new_numbers,
2436 const IndexSet &indices_we_care_about,
2438 const unsigned int level)
2440 for (std::vector<types::global_dof_index>::iterator i =
2449 (*i < new_numbers.size())),
2452 (indices_we_care_about.
size() == 0) ?
2468 template <
int spacedim>
2471 const std::vector<types::global_dof_index> & ,
2474 const unsigned int ,
2482 template <
int dim,
int spacedim>
2485 const std::vector<::types::global_dof_index> &new_numbers,
2486 const IndexSet &indices_we_care_about,
2488 const unsigned int level,
2489 const bool check_validity)
2491 const unsigned int dofs_per_line =
2493 if (dofs_per_line > 0 ||
2499 std::vector<bool> line_touched(
2501 std::vector<bool> quad_touched(
2503 for (
const auto &cell :
2505 if (cell->level_subdomain_id() !=
2509 if (dofs_per_line > 0)
2511 const auto line_indices =
2512 internal::TriaAccessorImplementation::Implementation::
2513 get_line_indices_of_cell(*cell);
2514 for (
const auto line : cell->line_indices())
2516 if (!line_touched[line_indices[line]])
2518 line_touched[line_indices[line]] =
true;
2520 &internal::DoFAccessorImplementation::
2521 Implementation::get_mg_dof_index(
2528 std::integral_constant<int, 1>());
2529 for (
unsigned int d = 0; d < dofs_per_line; ++d)
2539 (indices_we_care_about.
size() == 0) ?
2540 new_numbers[indices[d]] :
2541 new_numbers[indices_we_care_about
2551 for (
const auto quad : cell->face_indices())
2552 if (!quad_touched[cell->quad(quad)->index()])
2554 quad_touched[cell->quad(quad)->index()] =
true;
2555 const unsigned int dofs_per_quad =
2557 if (dofs_per_quad > 0)
2560 &internal::DoFAccessorImplementation::
2561 Implementation::get_mg_dof_index(
2565 cell->quad(quad)->index(),
2568 std::integral_constant<int, 2>());
2569 for (
unsigned int d = 0; d < dofs_per_quad; ++d)
2579 (indices_we_care_about.
size() == 0) ?
2580 new_numbers[indices[d]] :
2581 new_numbers[indices_we_care_about
2593 template <
int dim,
int spacedim>
2596 const std::vector<::types::global_dof_index> &new_numbers,
2597 const IndexSet &indices_we_care_about,
2599 const unsigned int level,
2600 const bool check_validity)
2615 indices_we_care_about,
2621 indices_we_care_about,
2628 indices_we_care_about,
2642 template <
int dim,
int spacedim>
2645 : dof_handler(&dof_handler)
2650 template <
int dim,
int spacedim>
2669 template <
int dim,
int spacedim>
2670 std::vector<NumberCache>
2673 std::vector<NumberCache> number_caches;
2674 number_caches.reserve(dof_handler->get_triangulation().n_levels());
2675 for (
unsigned int level = 0;
2676 level < dof_handler->get_triangulation().n_levels();
2685 number_caches.emplace_back(n_level_dofs);
2688 return number_caches;
2693 template <
int dim,
int spacedim>
2696 const std::vector<types::global_dof_index> &new_numbers)
const
2711 if (new_numbers.empty())
2715 *std::max_element(new_numbers.begin(), new_numbers.end()) + 1);
2720 template <
int dim,
int spacedim>
2723 const unsigned int level,
2724 const std::vector<types::global_dof_index> &new_numbers)
const
2737 template <
int dim,
int spacedim>
2740 : dof_handler(&dof_handler)
2755 template <
int dim,
int spacedim>
2756 std::vector<types::subdomain_id>
2757 get_dof_subdomain_association(
2763 std::vector<types::subdomain_id> subdomain_association(
2765 std::vector<types::global_dof_index> local_dof_indices;
2766 local_dof_indices.reserve(
2771 for (
const auto &cell : dof_handler.active_cell_iterators())
2778 const unsigned int dofs_per_cell =
2779 cell->get_fe().n_dofs_per_cell();
2780 local_dof_indices.resize(dofs_per_cell);
2781 internal::DoFAccessorImplementation::Implementation::
2782 get_dof_indices(*cell,
2784 cell->active_fe_index());
2789 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2790 if (subdomain_association[local_dof_indices[i]] ==
2792 subdomain_association[local_dof_indices[i]] = subdomain_id;
2793 else if (subdomain_association[local_dof_indices[i]] >
2796 subdomain_association[local_dof_indices[i]] = subdomain_id;
2800 Assert(std::find(subdomain_association.begin(),
2801 subdomain_association.end(),
2803 subdomain_association.end(),
2806 Assert(*std::max_element(subdomain_association.begin(),
2807 subdomain_association.end()) <
n_procs,
2810 return subdomain_association;
2820 template <
int dim,
int spacedim>
2821 std::vector<types::subdomain_id>
2822 get_dof_level_subdomain_association(
2826 const unsigned int level)
2829 std::vector<types::subdomain_id> level_subdomain_association(
2831 std::vector<types::global_dof_index> local_dof_indices;
2832 local_dof_indices.reserve(
2837 for (
const auto &cell : dof_handler.cell_iterators_on_level(
level))
2843 cell->level_subdomain_id();
2844 const unsigned int dofs_per_cell =
2845 cell->get_fe().n_dofs_per_cell();
2846 local_dof_indices.resize(dofs_per_cell);
2847 cell->get_mg_dof_indices(local_dof_indices);
2852 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2853 if (level_subdomain_association[local_dof_indices[i]] ==
2855 level_subdomain_association[local_dof_indices[i]] =
2857 else if (level_subdomain_association[local_dof_indices[i]] >
2860 level_subdomain_association[local_dof_indices[i]] =
2865 Assert(std::find(level_subdomain_association.begin(),
2866 level_subdomain_association.end(),
2868 level_subdomain_association.end(),
2871 Assert(*std::max_element(level_subdomain_association.begin(),
2872 level_subdomain_association.end()) <
n_procs,
2875 return level_subdomain_association;
2881 template <
int dim,
int spacedim>
2885 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
2887 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
2901 const internal::parallel::shared::
2902 TemporarilyRestoreSubdomainIds<dim, spacedim>
2903 subdomain_modifier(*tr);
2909 *this->dof_handler);
2925 std::vector<types::global_dof_index> new_dof_indices(
2926 n_dofs, enumeration_dof_index);
2930 const std::vector<types::subdomain_id> subdomain_association =
2931 get_dof_subdomain_association(*this->dof_handler, n_dofs,
n_procs);
2942 if (subdomain_association[i] == subdomain)
2944 Assert(new_dof_indices[i] == enumeration_dof_index,
2946 new_dof_indices[i] = next_free_index;
2952 Assert(std::find(new_dof_indices.begin(),
2953 new_dof_indices.end(),
2954 enumeration_dof_index) == new_dof_indices.end(),
2975 const std::vector<types::subdomain_id> subdomain_association =
2976 get_dof_subdomain_association(*this->dof_handler, n_dofs,
n_procs);
2978 for (
unsigned int i = 1; i < n_dofs; ++i)
2979 Assert(subdomain_association[i] >= subdomain_association[i - 1],
2982 std::vector<IndexSet> locally_owned_dofs_per_processor(
2993 unsigned int start_index = 0;
2994 unsigned int end_index = 0;
2995 while (start_index < n_dofs)
2997 while ((end_index < n_dofs) &&
2998 (subdomain_association[end_index] ==
2999 subdomain_association[start_index]))
3004 if (end_index > start_index)
3006 const unsigned int subdomain_owner =
3007 subdomain_association[start_index];
3008 locally_owned_dofs_per_processor[subdomain_owner].add_range(
3009 start_index, end_index);
3013 start_index = end_index;
3020 locally_owned_dofs_per_processor,
3026 template <
int dim,
int spacedim>
3027 std::vector<NumberCache>
3030 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3032 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3036 AssertThrow((tr->is_multilevel_hierarchy_constructed()),
3038 "Multigrid DoFs can only be distributed on a parallel "
3039 "Triangulation if the flag construct_multigrid_hierarchy "
3040 "is set in the constructor."));
3044 const unsigned int n_levels = tr->n_global_levels();
3046 std::vector<NumberCache> number_caches;
3047 number_caches.reserve(n_levels);
3050 for (
unsigned int lvl = 0; lvl < n_levels; ++lvl)
3058 std::vector<types::subdomain_id> saved_level_subdomain_ids;
3059 saved_level_subdomain_ids.resize(tr->n_cells(lvl));
3061 typename ::parallel::shared::Triangulation<dim, spacedim>::
3062 cell_iterator cell =
3068 const std::vector<types::subdomain_id> &true_level_subdomain_ids =
3069 tr->get_true_level_subdomain_ids_of_cells(lvl);
3071 for (
unsigned int index = 0; cell != endc; ++cell, ++
index)
3073 saved_level_subdomain_ids[
index] = cell->level_subdomain_id();
3074 cell->set_level_subdomain_id(true_level_subdomain_ids[
index]);
3093 std::vector<types::global_dof_index> new_dof_indices(
3098 const std::vector<types::subdomain_id>
3099 level_subdomain_association =
3100 get_dof_level_subdomain_association(*this->dof_handler,
3115 if (level_subdomain_association[i] == level_subdomain)
3119 new_dof_indices[i] = next_free_index;
3125 Assert(std::find(new_dof_indices.begin(),
3126 new_dof_indices.end(),
3128 new_dof_indices.end(),
3137 new_dof_indices,
IndexSet(0), *this->dof_handler, lvl,
true);
3149 const std::vector<types::subdomain_id> level_subdomain_association =
3150 get_dof_level_subdomain_association(*this->dof_handler,
3155 for (
unsigned int i = 1; i < n_dofs_on_level; ++i)
3156 Assert(level_subdomain_association[i] >=
3157 level_subdomain_association[i - 1],
3160 std::vector<IndexSet> locally_owned_dofs_per_processor(
3171 unsigned int start_index = 0;
3172 unsigned int end_index = 0;
3173 while (start_index < n_dofs_on_level)
3175 while ((end_index) < n_dofs_on_level &&
3176 (level_subdomain_association[end_index] ==
3177 level_subdomain_association[start_index]))
3182 if (end_index > start_index)
3184 const unsigned int level_subdomain_owner =
3185 level_subdomain_association[start_index];
3186 locally_owned_dofs_per_processor[level_subdomain_owner]
3187 .add_range(start_index, end_index);
3191 start_index = end_index;
3197 typename ::parallel::shared::Triangulation<dim, spacedim>::
3198 cell_iterator cell =
3204 for (
unsigned int index = 0; cell != endc; ++cell, ++
index)
3205 cell->set_level_subdomain_id(saved_level_subdomain_ids[
index]);
3208 number_caches.emplace_back(
3215 return number_caches;
3220 template <
int dim,
int spacedim>
3223 const std::vector<types::global_dof_index> &new_numbers)
const
3225#ifndef DEAL_II_WITH_MPI
3232 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3234 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3239 const internal::parallel::shared::
3240 TemporarilyRestoreSubdomainIds<dim, spacedim>
3241 subdomain_modifier(*tr);
3243 std::vector<types::global_dof_index> global_gathered_numbers(
3244 this->dof_handler->
n_dofs(), 0);
3249 const bool uses_sequential_numbering =
3250 new_numbers.size() == this->dof_handler->
n_dofs();
3251 bool all_use_sequential_numbering =
false;
3252 Utilities::MPI::internal::all_reduce<bool>(
3255 tr->get_mpi_communicator(),
3257 if (all_use_sequential_numbering)
3259 global_gathered_numbers = new_numbers;
3263 Assert(new_numbers.size() ==
3264 this->dof_handler->locally_owned_dofs().n_elements(),
3266 const unsigned int n_cpu =
3268 std::vector<types::global_dof_index> gathered_new_numbers(
3269 this->dof_handler->
n_dofs(), 0);
3271 tr->get_mpi_communicator()) ==
3272 this->dof_handler->get_triangulation()
3273 .locally_owned_subdomain(),
3278 std::vector<types::global_dof_index> new_numbers_copy(
3283 std::vector<int> rcounts(n_cpu);
3287 int cur_count = new_numbers_copy.size();
3288 int ierr = MPI_Allgather(&cur_count,
3294 tr->get_mpi_communicator());
3299 std::vector<int> displacements(n_cpu);
3300 for (
unsigned int i = 0; i < n_cpu; ++i)
3302 displacements[i] = shift;
3303 shift += rcounts[i];
3305 Assert(new_numbers_copy.size() ==
3306 static_cast<unsigned int>(
3308 tr->get_mpi_communicator())]),
3310 ierr = MPI_Allgatherv(new_numbers_copy.data(),
3311 new_numbers_copy.size(),
3313 gathered_new_numbers.data(),
3315 displacements.data(),
3317 tr->get_mpi_communicator());
3327 std::vector<unsigned int> flag_1(this->dof_handler->
n_dofs(), 0);
3328 std::vector<unsigned int> flag_2(this->dof_handler->
n_dofs(), 0);
3329 std::vector<IndexSet> locally_owned_dofs_per_processor =
3331 tr->get_mpi_communicator(),
3332 this->dof_handler->locally_owned_dofs());
3333 for (
unsigned int i = 0; i < n_cpu; ++i)
3335 const IndexSet iset = locally_owned_dofs_per_processor[i];
3342 gathered_new_numbers[shift + ind];
3347 global_gathered_numbers[target] =
value;
3354 Assert(*std::max_element(flag_1.begin(), flag_1.end()) == 1,
3356 Assert(*std::min_element(flag_1.begin(), flag_1.end()) == 1,
3358 Assert((*std::max_element(flag_2.begin(), flag_2.end())) == 1,
3360 Assert((*std::min_element(flag_2.begin(), flag_2.end())) == 1,
3376 return number_cache;
3382 template <
int dim,
int spacedim>
3385 const unsigned int ,
3386 const std::vector<types::global_dof_index> & )
const
3398#ifdef DEAL_II_WITH_MPI
3402 template <
int dim,
int spacedim>
3405 std::vector<std::vector<bool>> &cell_marked)
3407 const auto pack = [](
const auto &cell) {
3411 std::vector<::types::global_dof_index>
data(
3412 cell->get_fe().n_dofs_per_cell());
3413 cell->get_mg_dof_indices(
data);
3418 const auto unpack = [&cell_marked](
const auto &cell,
3420 Assert(cell->get_fe().n_dofs_per_cell() == dofs.size(),
3423 Assert(cell->level_subdomain_id() !=
3427 bool complete =
true;
3428 DoFAccessorImplementation::Implementation::process_dof_indices(
3432 DoFAccessorImplementation::Implementation::
3433 MGDoFIndexProcessor<dim, spacedim>(cell->
level()),
3443 [&complete, invalid_dof_index =
numbers::invalid_dof_index](
3444 auto &stored_index, auto received_index) {
3445 if (*received_index != invalid_dof_index)
3447# if !defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1900
3448 Assert((stored_index == invalid_dof_index) ||
3449 (stored_index == *received_index),
3452 stored_index = *received_index;
3462 Assert(cell_marked[cell->level()][cell->index()],
3466 cell_marked[cell->level()][cell->index()] =
false;
3469 const auto filter = [&cell_marked](
const auto &cell) {
3470 return cell_marked[cell->level()][cell->index()];
3474 std::vector<types::global_dof_index>,
3498 template <
int dim,
int spacedim>
3500 communicate_dof_indices_on_marked_cells(
3502 std::vector<bool> &cell_marked)
3504# ifndef DEAL_II_WITH_MPI
3512 const auto pack = [](
const auto &cell) {
3515 std::vector<::types::global_dof_index>
data(
3516 cell->get_fe().n_dofs_per_cell());
3519 internal::DoFAccessorImplementation::Implementation::
3520 get_dof_indices(*cell,
data, cell->active_fe_index());
3525 const auto unpack = [&cell_marked](
const auto &cell,
3527 Assert(cell->get_fe().n_dofs_per_cell() == dofs.size(),
3535 bool complete =
true;
3536 DoFAccessorImplementation::Implementation::process_dof_indices(
3539 cell->active_fe_index(),
3540 DoFAccessorImplementation::Implementation::
3541 DoFIndexProcessor<dim, spacedim>(),
3552 auto &stored_index, const auto received_index) {
3553 if (*received_index != invalid_dof_index)
3555# if !defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1900
3556 Assert((stored_index == invalid_dof_index) ||
3557 (stored_index == *received_index),
3560 stored_index = *received_index;
3570 Assert(cell_marked[cell->active_cell_index()],
3574 cell_marked[cell->active_cell_index()] =
false;
3577 const auto filter = [&cell_marked](
const auto &cell) {
3578 return cell_marked[cell->active_cell_index()];
3582 std::vector<types::global_dof_index>,
3595 template <
int dim,
int spacedim>
3598 : dof_handler(&dof_handler)
3603 template <
int dim,
int spacedim>
3607#ifndef DEAL_II_WITH_MPI
3656 std::vector<::types::global_dof_index> renumbering(
3657 n_initial_local_dofs, enumeration_dof_index);
3664 renumbering, subdomain_id, *dof_handler);
3668 std::vector<std::map<types::global_dof_index, types::global_dof_index>>
3669 all_constrained_indices(dim);
3684 for (
const auto &constrained_indices : all_constrained_indices)
3685 for (
const auto &
index : constrained_indices)
3687 ++n_identity_constrained_indices;
3690 std::count(renumbering.begin(),
3692 enumeration_dof_index) -
3693 n_identity_constrained_indices;
3697 const auto [my_shift, n_global_dofs] =
3699 n_locally_owned_dofs,
triangulation->get_mpi_communicator());
3704 renumbering, all_constrained_indices, my_shift);
3720 n_locally_owned_dofs);
3734 std::vector<bool> cell_marked(
triangulation->n_active_cells());
3736 if (cell->is_ghost())
3737 cell_marked[cell->active_cell_index()] =
true;
3745 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
3758 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
3764 Assert(cell_marked[cell->active_cell_index()] ==
false,
3772 std::vector<::types::global_dof_index> local_dof_indices;
3775 if (!cell->is_artificial())
3777 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
3778 cell->get_dof_indices(local_dof_indices);
3779 if (local_dof_indices.end() !=
3780 std::find(local_dof_indices.begin(),
3781 local_dof_indices.end(),
3784 if (cell->is_ghost())
3788 "A ghost cell ended up with incomplete "
3789 "DoF index information. This should not "
3797 "A locally owned cell ended up with incomplete "
3798 "DoF index information. This should not "
3805 return number_cache;
3811 template <
int dim,
int spacedim>
3812 std::vector<NumberCache>
3815#ifndef DEAL_II_WITH_MPI
3817 return std::vector<NumberCache>();
3830 "Multigrid DoFs can only be distributed on a parallel "
3831 "Triangulation if the flag construct_multigrid_hierarchy "
3832 "is set in the constructor."));
3839 const unsigned int n_levels =
triangulation->n_global_levels();
3840 std::vector<NumberCache> number_caches;
3841 number_caches.reserve(n_levels);
3847 const unsigned int n_initial_local_dofs =
3853 std::vector<::types::global_dof_index> renumbering(
3854 n_initial_local_dofs, enumeration_dof_index);
3856 if (level < triangulation->n_levels())
3858 std::vector<::types::global_dof_index> local_dof_indices;
3860 for (
const auto &cell :
3862 if (cell->level_subdomain_id() !=
3864 (cell->level_subdomain_id() <
3874 local_dof_indices.resize(
3875 cell->get_fe().n_dofs_per_cell());
3876 cell->get_mg_dof_indices(local_dof_indices);
3877 for (
unsigned int i = 0;
3878 i < cell->get_fe().n_dofs_per_cell();
3881 renumbering[local_dof_indices[i]] =
3887 std::count(renumbering.begin(),
3889 enumeration_dof_index);
3893 const auto [my_shift, n_global_dofs] =
3902 if (
index == enumeration_dof_index)
3903 index = next_free_index++;
3913 if (level < triangulation->n_levels())
3925 number_caches.emplace_back(level_number_cache);
3934 std::vector<std::vector<bool>> cell_marked(
triangulation->n_levels());
3935 for (
unsigned int l = 0; l <
triangulation->n_levels(); ++l)
3938 if (cell->is_ghost_on_level())
3939 cell_marked[cell->level()][cell->index()] =
true;
3944 communicate_mg_ghost_cells(*dof_handler, cell_marked);
3948 communicate_mg_ghost_cells(*dof_handler, cell_marked);
3953 Assert(cell_marked[cell->level()][cell->index()] ==
false,
3963 std::vector<::types::global_dof_index> local_dof_indices;
3965 if (cell->level_subdomain_id() !=
3968 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
3969 cell->get_mg_dof_indices(local_dof_indices);
3970 if (local_dof_indices.end() !=
3971 std::find(local_dof_indices.begin(),
3972 local_dof_indices.end(),
3981 return number_caches;
3987 template <
int dim,
int spacedim>
3990 const std::vector<::types::global_dof_index> &new_numbers)
const
3997#ifndef DEAL_II_WITH_MPI
4015 const bool locally_owned_set_changes =
4016 std::any_of(new_numbers.cbegin(),
4019 return owned_dofs.is_element(i) == false;
4022 IndexSet my_locally_owned_new_dof_indices = owned_dofs;
4023 if (locally_owned_set_changes && owned_dofs.
n_elements() > 0)
4025 std::vector<::types::global_dof_index> new_numbers_sorted =
4027 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
4029 my_locally_owned_new_dof_indices =
IndexSet(dof_handler->
n_dofs());
4031 new_numbers_sorted.begin(), new_numbers_sorted.end());
4032 my_locally_owned_new_dof_indices.
compress();
4051 if (cell->is_ghost())
4053 DoFAccessorImplementation::Implementation::process_dof_indices(
4056 cell->active_fe_index(),
4057 DoFAccessorImplementation::Implementation::
4058 DoFIndexProcessor<dim, spacedim>(),
4059 [&owned_dofs](
auto &stored_index,
auto) {
4086 std::vector<bool> cell_marked(
triangulation->n_active_cells());
4088 if (cell->is_ghost())
4089 cell_marked[cell->active_cell_index()] =
true;
4097 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
4107 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
4115 return number_cache;
4121 template <
int dim,
int spacedim>
4124 const unsigned int level,
4125 const std::vector<types::global_dof_index> &new_numbers)
const
4127#ifndef DEAL_II_WITH_MPI
4150 const bool locally_owned_set_changes =
4151 std::any_of(new_numbers.cbegin(),
4154 return owned_dofs.is_element(i) == false;
4157 IndexSet my_locally_owned_new_dof_indices = owned_dofs;
4158 if (locally_owned_set_changes && owned_dofs.
n_elements() > 0)
4160 std::vector<::types::global_dof_index> new_numbers_sorted =
4162 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
4164 my_locally_owned_new_dof_indices =
4167 new_numbers_sorted.begin(), new_numbers_sorted.end());
4168 my_locally_owned_new_dof_indices.
compress();
4178 if (cell->is_ghost_on_level())
4180 DoFAccessorImplementation::Implementation::process_dof_indices(
4184 DoFAccessorImplementation::Implementation::
4185 MGDoFIndexProcessor<dim, spacedim>(cell->level()),
4186 [&owned_dofs](
auto &stored_index,
auto) {
4195 if (level < triangulation->n_levels() && owned_dofs.
n_elements() > 0)
4197 new_numbers, owned_dofs, *dof_handler,
level,
false);
4201 std::vector<std::vector<bool>> cell_marked(
triangulation->n_levels());
4202 for (
unsigned int l = 0; l <
triangulation->n_levels(); ++l)
4205 if (cell->is_ghost_on_level())
4206 cell_marked[cell->level()][cell->index()] =
true;
4208 communicate_mg_ghost_cells(*dof_handler, cell_marked);
4210 communicate_mg_ghost_cells(*dof_handler, cell_marked);
4218 return number_cache;
4228#include "dof_handler_policy.inst"
std::vector< std::unique_ptr<::internal::DoFHandlerImplementation::DoFLevel< dim > > > mg_levels
hp::FECollection< dim, spacedim > fe_collection
const hp::FECollection< dim, spacedim > & get_fe_collection() const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
const IndexSet & locally_owned_mg_dofs(const unsigned int level) const
std::vector< MGVertexDoFs > mg_vertex_dofs
std::vector< std::array< std::vector< types::global_dof_index >, dim+1 > > object_dof_indices
const Triangulation< dim, spacedim > & get_triangulation() const
const IndexSet & locally_owned_dofs() const
std::unique_ptr<::internal::DoFHandlerImplementation::DoFFaces< dim > > mg_faces
bool hp_capability_enabled
types::global_dof_index n_dofs() const
types::global_dof_index n_locally_owned_dofs() const
unsigned int n_dofs_per_vertex() const
unsigned int n_dofs_per_line() const
unsigned int max_dofs_per_quad() const
unsigned int n_dofs_per_quad(unsigned int face_no=0) const
size_type index_within_set(const size_type global_index) const
size_type n_elements() const
bool is_element(const size_type index) const
void add_range(const size_type begin, const size_type end)
size_type nth_index_in_set(const size_type local_index) const
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
cell_iterator begin(const unsigned int level=0) const
unsigned int n_raw_lines() const
virtual types::subdomain_id locally_owned_subdomain() const
unsigned int n_levels() const
cell_iterator end() const
bool vertex_used(const unsigned int index) const
virtual unsigned int n_global_levels() const
unsigned int n_raw_quads() const
const std::vector< bool > & get_used_vertices() const
unsigned int n_vertices() const
unsigned int size() const
unsigned int find_dominating_fe(const std::set< unsigned int > &fes, const unsigned int codim=0) const
unsigned int max_dofs_per_cell() const
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const override
ParallelDistributed(DoFHandler< dim, spacedim > &dof_handler)
virtual std::vector< NumberCache > distribute_mg_dofs() const override
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const override
virtual NumberCache distribute_dofs() const override
virtual NumberCache distribute_dofs() const override
virtual std::vector< NumberCache > distribute_mg_dofs() const override
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const override
ParallelShared(DoFHandler< dim, spacedim > &dof_handler)
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const override
virtual std::vector< NumberCache > distribute_mg_dofs() const override
virtual NumberCache distribute_dofs() const override
Sequential(DoFHandler< dim, spacedim > &dof_handler)
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const override
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const override
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
IteratorRange< active_cell_iterator > active_cell_iterators() const
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
IteratorRange< cell_iterator > cell_iterators() const
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
Task< RT > new_task(const std::function< RT()> &function)
#define DEAL_II_NOT_IMPLEMENTED()
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)
size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
T unpack(const std::vector< char > &buffer, const bool allow_compression=true)
const types::fe_index invalid_fe_index
const types::subdomain_id artificial_subdomain_id
const types::subdomain_id invalid_subdomain_id
static const unsigned int invalid_unsigned_int
const types::global_dof_index invalid_dof_index
unsigned short int fe_index
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
types::global_dof_index n_global_dofs
IndexSet locally_owned_dofs
types::global_dof_index n_locally_owned_dofs
static void renumber_face_dofs(const std::vector< types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< 3, spacedim > &dof_handler)
static std::map< types::global_dof_index, types::global_dof_index > compute_quad_dof_identities(const DoFHandler< dim, spacedim > &dof_handler)
static void merge_invalid_quad_dofs_on_ghost_interfaces(DoFHandler< 3, spacedim > &dof_handler)
static void renumber_face_mg_dofs(const std::vector<::types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< dim, spacedim > &dof_handler, const unsigned int level, const bool check_validity)
static void renumber_dofs(const std::vector< types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, const DoFHandler< dim, space_dim > &dof_handler, const bool check_validity)
static std::map< types::global_dof_index, types::global_dof_index > compute_line_dof_identities(const DoFHandler< 1, spacedim > &dof_handler)
static void merge_invalid_line_dofs_on_ghost_interfaces(DoFHandler< dim, spacedim > &dof_handler)
static types::global_dof_index unify_dof_indices(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int n_dofs_before_identification, const bool check_validity)
static void merge_invalid_dof_indices_on_ghost_interfaces(DoFHandler< dim, spacedim > &dof_handler)
static void renumber_vertex_dofs(const std::vector< types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< dim, spacedim > &dof_handler, const bool check_validity)
static void merge_invalid_vertex_dofs_on_ghost_interfaces(DoFHandler< dim, spacedim > &dof_handler)
static void renumber_cell_mg_dofs(const std::vector<::types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< dim, spacedim > &dof_handler, const unsigned int level)
static std::map< types::global_dof_index, types::global_dof_index > compute_quad_dof_identities(const DoFHandler< 3, spacedim > &dof_handler)
static void renumber_mg_dofs(const std::vector<::types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< dim, spacedim > &dof_handler, const unsigned int level, const bool check_validity)
static void renumber_vertex_mg_dofs(const std::vector<::types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< dim, spacedim > &dof_handler, const unsigned int level)
static std::map< types::global_dof_index, types::global_dof_index > compute_vertex_dof_identities(const DoFHandler< dim, spacedim > &dof_handler)
static types::global_dof_index enumerate_dof_indices_for_renumbering(std::vector< types::global_dof_index > &new_dof_indices, const std::vector< std::map< types::global_dof_index, types::global_dof_index > > &all_constrained_indices, const types::global_dof_index start_dof_index)
static void merge_invalid_line_dofs_on_ghost_interfaces(DoFHandler< 1, spacedim > &dof_handler)
static void renumber_face_dofs(const std::vector< types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< 2, spacedim > &dof_handler)
static void renumber_face_dofs(const std::vector< types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< dim, spacedim > &dof_handler)
static void compute_dof_identities(std::vector< std::map< types::global_dof_index, types::global_dof_index > > &all_constrained_indices, const DoFHandler< dim, spacedim > &dof_handler)
static void renumber_cell_dofs(const std::vector< types::global_dof_index > &new_numbers, const IndexSet &indices_we_care_about, DoFHandler< dim, spacedim > &dof_handler)
static std::map< types::global_dof_index, types::global_dof_index > compute_line_dof_identities(const DoFHandler< dim, spacedim > &dof_handler)
static void invalidate_dof_indices_on_weaker_ghost_cells_for_renumbering(std::vector< types::global_dof_index > &renumbering, const types::subdomain_id subdomain_id, const DoFHandler< dim, spacedim > &dof_handler)
static types::global_dof_index distribute_dofs(const types::subdomain_id subdomain_id, DoFHandler< dim, spacedim > &dof_handler)
static void merge_invalid_quad_dofs_on_ghost_interfaces(DoFHandler< dim, spacedim > &dof_handler)
static void renumber_face_mg_dofs(const std::vector< types::global_dof_index > &, const IndexSet &, DoFHandler< 1, spacedim > &, const unsigned int, const bool)
static types::global_dof_index distribute_dofs_on_level(const types::subdomain_id level_subdomain_id, DoFHandler< dim, spacedim > &dof_handler, const unsigned int level)
static void renumber_face_dofs(const std::vector< types::global_dof_index > &, const IndexSet &, DoFHandler< 1, spacedim > &)
#define DEAL_II_DOF_INDEX_MPI_TYPE