46 namespace DoFHandlerImplementation
63 std::vector<std::pair<unsigned int, unsigned int>>;
76 template <
int structdim,
int dim,
int spacedim>
77 const std::unique_ptr<DoFIdentities> &
78 ensure_existence_and_return_dof_identities(
79 const ::hp::FECollection<dim, spacedim> &fes,
82 std::unique_ptr<DoFIdentities> &identities,
98 if (identities.get() ==
nullptr)
102 std::vector<std::map<unsigned int, unsigned int>>
110 complete_identities = fes.hp_vertex_dof_identities(
111 std::set<unsigned int>{fe_index_1, fe_index_2});
118 complete_identities = fes.hp_line_dof_identities(
119 std::set<unsigned int>{fe_index_1, fe_index_2});
126 std::pair<unsigned int, unsigned int> p1{fe_index_1,
128 std::pair<unsigned int, unsigned int> p2{
129 fe_index_2, face_no_neighbor};
131 complete_identities = fes.hp_quad_dof_identities(
132 std::set<std::pair<unsigned int, unsigned int>>{p1,
150 for (
const auto &complete_identity : complete_identities)
153 Assert(complete_identity.find(fe_index_1) !=
154 complete_identity.end(),
156 Assert(complete_identity.find(fe_index_2) !=
157 complete_identity.end(),
169 DoFIdentities reduced_identities;
170 for (
const auto &complete_identity : complete_identities)
172 const unsigned int dof_index_1 =
173 complete_identity.at(fe_index_1);
174 const unsigned int dof_index_2 =
175 complete_identity.at(fe_index_2);
177 reduced_identities.emplace_back(dof_index_1, dof_index_2);
184 for (
const auto &identity : reduced_identities)
188 fes[fe_index_1].template n_dofs_per_object<structdim>(
193 fes[fe_index_2].template n_dofs_per_object<structdim>(
200 std::make_unique<DoFIdentities>(std::move(reduced_identities));
217 template <
int dim,
int spacedim>
218 static std::map<types::global_dof_index, types::global_dof_index>
226 std::map<types::global_dof_index, types::global_dof_index>
240 for (
unsigned int vertex_index = 0;
246 const unsigned int n_active_fe_indices =
251 std::integral_constant<int, 0>());
253 if (n_active_fe_indices > 1)
255 const std::set<types::fe_index> fe_indices =
261 std::integral_constant<int, 0>());
268 {fe_indices.begin(), fe_indices.end()},
275 most_dominating_fe_index =
282 std::integral_constant<int, 0>());
288 for (
const auto &other_fe_index : fe_indices)
289 if (other_fe_index != most_dominating_fe_index)
293 const auto &identities =
294 *ensure_existence_and_return_dof_identities<0>(
296 most_dominating_fe_index,
298 vertex_dof_identities[most_dominating_fe_index]
309 for (
const auto &identity : identities)
317 most_dominating_fe_index,
319 std::integral_constant<int, 0>());
321 dependent_dof_index =
329 std::integral_constant<int, 0>());
344 if (dependent_dof_index !=
354 if (primary_dof_index !=
357 (dof_identities.find(primary_dof_index) ==
358 dof_identities.end()) ||
359 (dof_identities[dependent_dof_index] ==
363 dof_identities[dependent_dof_index] =
371 return dof_identities;
379 template <
int spacedim>
380 static std::map<types::global_dof_index, types::global_dof_index>
387 return std::map<types::global_dof_index, types::global_dof_index>();
391 template <
int dim,
int spacedim>
392 static std::map<types::global_dof_index, types::global_dof_index>
400 std::map<types::global_dof_index, types::global_dof_index>
425 std::vector<bool> line_touched(
428 for (
const auto l : cell->line_indices())
429 if (!line_touched[cell->line(l)->index()])
431 const auto line = cell->line(l);
432 line_touched[line->index()] =
true;
434 unsigned int unique_sets_of_dofs =
435 line->n_active_fe_indices();
439 const unsigned int n_active_fe_indices =
440 line->n_active_fe_indices();
441 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
442 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
445 line->nth_active_fe_index(f),
447 line->nth_active_fe_index(g);
466 dof_handler.
get_fe(fe_index_2)
472 const unsigned int dofs_per_line =
475 const auto &identities =
476 *ensure_existence_and_return_dof_identities<1>(
480 line_dof_identities[fe_index_1][fe_index_2]);
484 if (identities.size() == dofs_per_line)
487 for (; i < dofs_per_line; ++i)
488 if (identities[i] != std::pair{i, i})
492 if (i == dofs_per_line)
501 --unique_sets_of_dofs;
505 const std::set<types::fe_index> fe_indices{
506 fe_index_1, fe_index_2};
517 if (dominating_fe_index !=
520 (dominating_fe_index == fe_index_1) ?
528 dominating_fe_index = fe_index_1;
529 other_fe_index = fe_index_2;
532 for (
unsigned int j = 0; j < dofs_per_line;
536 primary_dof_index = line->dof_index(
537 j, dominating_fe_index);
539 dependent_dof_index =
540 line->dof_index(j, other_fe_index);
556 if (dependent_dof_index !=
559 if (primary_dof_index !=
566 if (dof_identities.find(
567 primary_dof_index) !=
568 dof_identities.end())
584 [primary_dof_index]) ==
585 dof_identities.end(),
589 [dependent_dof_index] =
599 (dof_identities.find(
600 primary_dof_index) ==
601 dof_identities.end()) ||
603 [dependent_dof_index] ==
608 [dependent_dof_index] =
618 [dependent_dof_index] =
638 if ((unique_sets_of_dofs == 2) && (dim == 2))
640 const std::set<types::fe_index> fe_indices =
641 line->get_active_fe_indices();
648 {fe_indices.begin(), fe_indices.end()},
661 for (
const auto &other_fe_index : fe_indices)
662 if (other_fe_index != most_dominating_fe_index)
664 const auto &identities =
665 *ensure_existence_and_return_dof_identities<
667 most_dominating_fe_index,
670 [most_dominating_fe_index]
673 for (
const auto &identity : identities)
676 primary_dof_index = line->dof_index(
678 most_dominating_fe_index);
680 dependent_dof_index =
681 line->dof_index(identity.second,
697 if (dependent_dof_index !=
707 if (primary_dof_index !=
709 Assert((dof_identities.find(
710 primary_dof_index) ==
711 dof_identities.end()) ||
713 [dependent_dof_index] ==
717 dof_identities[dependent_dof_index] =
726 return dof_identities;
735 template <
int dim,
int spacedim>
736 static std::map<types::global_dof_index, types::global_dof_index>
750 return std::map<types::global_dof_index, types::global_dof_index>();
754 template <
int spacedim>
755 static std::map<types::global_dof_index, types::global_dof_index>
763 std::map<types::global_dof_index, types::global_dof_index>
782 std::vector<bool> quad_touched(
785 for (
const auto q : cell->face_indices())
786 if (!quad_touched[cell->quad(q)->index()] &&
787 (cell->quad(q)->n_active_fe_indices() == 2))
789 const auto quad = cell->quad(q);
790 quad_touched[quad->index()] =
true;
792 const std::set<types::fe_index> fe_indices =
793 quad->get_active_fe_indices();
800 {fe_indices.begin(), fe_indices.end()},
805 const bool this_cell_is_dominating =
806 cell->active_fe_index() == most_dominating_fe_index;
808 const unsigned int most_dominating_fe_index_face_no =
809 this_cell_is_dominating ? q : cell->neighbor_face_no(q);
811 const unsigned int other_fe_index_face_no =
812 this_cell_is_dominating ? cell->neighbor_face_no(q) : q;
826 for (
const auto &other_fe_index : fe_indices)
827 if (other_fe_index != most_dominating_fe_index)
829 const auto &identities =
830 *ensure_existence_and_return_dof_identities<2>(
832 most_dominating_fe_index,
835 [most_dominating_fe_index][other_fe_index]
836 [cell->quad(q)->reference_cell() ==
838 most_dominating_fe_index_face_no,
839 other_fe_index_face_no);
841 for (
const auto &identity : identities)
845 quad->dof_index(identity.first,
846 most_dominating_fe_index);
848 dependent_dof_index =
849 quad->dof_index(identity.second,
857 if (dependent_dof_index !=
867 if (primary_dof_index !=
869 Assert((dof_identities.find(
870 primary_dof_index) ==
871 dof_identities.end()) ||
873 [dependent_dof_index] ==
877 dof_identities[dependent_dof_index] =
885 return dof_identities;
894 template <
int dim,
int spacedim>
898 &all_constrained_indices,
910 all_constrained_indices[i] =
918 all_constrained_indices[i] =
927 all_constrained_indices[i] =
958 std::vector<types::global_dof_index> &new_dof_indices,
960 std::map<types::global_dof_index, types::global_dof_index>>
961 &all_constrained_indices,
965 for (
const auto &constrained_dof_indices : all_constrained_indices)
966 for (
const auto &p : constrained_dof_indices)
969 Assert(new_dof_indices[p.first] == enumeration_dof_index,
972 new_dof_indices[p.first] = p.second;
977 for (
auto &new_dof_index : new_dof_indices)
978 if (new_dof_index == enumeration_dof_index)
979 new_dof_index = next_free_dof++;
983 for (
const auto &constrained_dof_indices : all_constrained_indices)
984 for (
const auto &p : constrained_dof_indices)
987 Assert(new_dof_indices[p.first] != enumeration_dof_index,
991 new_dof_indices[p.first] = new_dof_indices[p.second];
997 Assert(new_dof_index != enumeration_dof_index,
999 Assert(new_dof_index < next_free_dof ||
1004 return next_free_dof;
1017 template <
int dim,
int spacedim>
1022 const bool check_validity)
1025 return n_dofs_before_identification;
1028 std::map<types::global_dof_index, types::global_dof_index>>
1029 all_constrained_indices(dim);
1032 std::vector<::types::global_dof_index> renumbering(
1033 n_dofs_before_identification, enumeration_dof_index);
1036 all_constrained_indices,
1050 template <
int dim,
int spacedim>
1071 std::vector<bool> include_vertex(
1073 if (
dynamic_cast<const ::parallel::
1074 DistributedTriangulationBase<dim, spacedim> *
>(
1077 if (cell->is_ghost())
1078 for (
const unsigned int v : cell->vertex_indices())
1079 include_vertex[cell->vertex_index(v)] =
true;
1082 for (
unsigned int vertex_index = 0;
1087 (include_vertex[vertex_index] ==
true))
1089 const unsigned int n_active_fe_indices =
1094 std::integral_constant<int, 0>());
1096 if (n_active_fe_indices > 1)
1098 const std::set<types::fe_index> fe_indices =
1104 std::integral_constant<int, 0>());
1111 {fe_indices.begin(), fe_indices.end()},
1118 most_dominating_fe_index =
1125 std::integral_constant<int, 0>());
1131 for (
const auto &other_fe_index : fe_indices)
1132 if (other_fe_index != most_dominating_fe_index)
1136 const auto &identities =
1137 *ensure_existence_and_return_dof_identities<0>(
1139 most_dominating_fe_index,
1141 vertex_dof_identities[most_dominating_fe_index]
1152 for (
const auto &identity : identities)
1160 most_dominating_fe_index,
1162 std::integral_constant<int, 0>());
1164 dependent_dof_index =
1172 std::integral_constant<int, 0>());
1186 if ((dependent_dof_index ==
1188 (primary_dof_index !=
1197 std::integral_constant<int, 0>(),
1211 template <
int spacedim>
1222 template <
int dim,
int spacedim>
1232 std::vector<bool> line_marked(
1235 if (cell->is_ghost())
1236 for (
const auto l : cell->line_indices())
1237 line_marked[cell->line(l)->index()] =
true;
1262 for (
const auto l : cell->line_indices())
1263 if ((cell->is_locally_owned()) &&
1264 line_marked[cell->line(l)->index()])
1266 const auto line = cell->line(l);
1267 line_marked[line->index()] =
false;
1269 unsigned int unique_sets_of_dofs =
1270 line->n_active_fe_indices();
1274 const unsigned int n_active_fe_indices =
1275 line->n_active_fe_indices();
1276 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1277 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
1280 line->nth_active_fe_index(f),
1282 line->nth_active_fe_index(g);
1285 dof_handler.
get_fe(fe_index_2)
1291 const unsigned int dofs_per_line =
1294 const auto &identities =
1295 *ensure_existence_and_return_dof_identities<1>(
1299 line_dof_identities[fe_index_1][fe_index_2]);
1303 if (identities.size() == dofs_per_line)
1306 for (; i < dofs_per_line; ++i)
1307 if ((identities[i].
first != i) &&
1308 (identities[i].
second != i))
1312 if (i == dofs_per_line)
1321 --unique_sets_of_dofs;
1325 const std::set<types::fe_index> fe_indices{
1326 fe_index_1, fe_index_2};
1337 if (dominating_fe_index !=
1340 (dominating_fe_index == fe_index_1) ?
1348 dominating_fe_index = fe_index_1;
1349 other_fe_index = fe_index_2;
1352 for (
unsigned int j = 0; j < dofs_per_line;
1356 primary_dof_index = line->dof_index(
1357 j, dominating_fe_index);
1359 dependent_dof_index =
1360 line->dof_index(j, other_fe_index);
1375 if ((dependent_dof_index ==
1377 (primary_dof_index !=
1379 line->set_dof_index(j,
1398 if ((unique_sets_of_dofs == 2) && (dim == 2))
1400 const std::set<types::fe_index> fe_indices =
1401 line->get_active_fe_indices();
1408 {fe_indices.begin(), fe_indices.end()},
1421 for (
const auto &other_fe_index : fe_indices)
1422 if (other_fe_index != most_dominating_fe_index)
1424 const auto &identities =
1425 *ensure_existence_and_return_dof_identities<
1427 most_dominating_fe_index,
1430 [most_dominating_fe_index]
1433 for (
const auto &identity : identities)
1436 primary_dof_index = line->dof_index(
1438 most_dominating_fe_index);
1440 dependent_dof_index =
1441 line->dof_index(identity.second,
1456 if ((dependent_dof_index ==
1458 (primary_dof_index !=
1460 line->set_dof_index(identity.second,
1476 template <
int dim,
int spacedim>
1493 template <
int spacedim>
1504 std::vector<bool> quad_marked(
1507 if (cell->is_ghost())
1508 for (
const auto q : cell->face_indices())
1509 quad_marked[cell->quad(q)->index()] =
true;
1528 for (
const auto q : cell->face_indices())
1529 if ((cell->is_locally_owned()) &&
1530 quad_marked[cell->quad(q)->index()] &&
1531 (cell->quad(q)->n_active_fe_indices() == 2))
1533 const auto quad = cell->quad(q);
1534 quad_marked[quad->index()] =
false;
1536 const std::set<types::fe_index> fe_indices =
1537 quad->get_active_fe_indices();
1544 {fe_indices.begin(), fe_indices.end()},
1549 const bool this_cell_is_dominating =
1550 cell->active_fe_index() == most_dominating_fe_index;
1552 const unsigned int most_dominating_fe_index_face_no =
1553 this_cell_is_dominating ? q : cell->neighbor_face_no(q);
1555 const unsigned int other_fe_index_face_no =
1556 this_cell_is_dominating ? cell->neighbor_face_no(q) : q;
1569 for (
const auto &other_fe_index : fe_indices)
1570 if (other_fe_index != most_dominating_fe_index)
1572 const auto &identities =
1573 *ensure_existence_and_return_dof_identities<2>(
1575 most_dominating_fe_index,
1578 [most_dominating_fe_index][other_fe_index]
1579 [cell->quad(q)->reference_cell() ==
1581 most_dominating_fe_index_face_no,
1582 other_fe_index_face_no);
1584 for (
const auto &identity : identities)
1588 quad->dof_index(identity.first,
1589 most_dominating_fe_index);
1591 dependent_dof_index =
1592 quad->dof_index(identity.second,
1606 if ((dependent_dof_index ==
1608 (primary_dof_index !=
1610 quad->set_dof_index(identity.second,
1633 template <
int dim,
int spacedim>
1674 template <
int dim,
int spacedim>
1686 if (!cell->is_artificial() &&
1688 (cell->subdomain_id() == subdomain_id)))
1696 cell->active_fe_index(),
1698 DoFIndexProcessor<dim, spacedim>(),
1699 [&next_free_dof](
auto &stored_index,
auto) {
1702 stored_index = next_free_dof;
1705 std::numeric_limits<types::global_dof_index>::max(),
1707 "You have reached the maximal number of degrees of "
1708 "freedom that can be stored in the chosen data "
1709 "type. In practice, this can only happen if you "
1710 "are using 32-bit data types. You will have to "
1711 "re-compile deal.II with the "
1712 "`DEAL_II_WITH_64BIT_INDICES' flag set to `ON'."));
1719 return next_free_dof;
1737 template <
int dim,
int spacedim>
1740 std::vector<types::global_dof_index> &renumbering,
1744 std::vector<types::global_dof_index> local_dof_indices;
1747 if (cell->is_ghost() && (cell->subdomain_id() < subdomain_id))
1755 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
1759 cell->active_fe_index());
1760 for (
const auto &local_dof_index : local_dof_indices)
1772 template <
int dim,
int spacedim>
1776 const unsigned int level)
1781 const ::Triangulation<dim, spacedim> &tria =
1784 if (
level >= tria.n_levels())
1791 (cell->level_subdomain_id() == level_subdomain_id))
1798 MGDoFIndexProcessor<dim, spacedim>(
level),
1799 [&next_free_dof](
auto &stored_index,
auto) {
1802 stored_index = next_free_dof;
1805 std::numeric_limits<types::global_dof_index>::max(),
1807 "You have reached the maximal number of degrees of "
1808 "freedom that can be stored in the chosen data "
1809 "type. In practice, this can only happen if you "
1810 "are using 32-bit data types. You will have to "
1811 "re-compile deal.II with the "
1812 "`DEAL_II_WITH_64BIT_INDICES' flag set to `ON'."));
1819 return next_free_dof;
1834 template <
int dim,
int spacedim>
1837 const std::vector<types::global_dof_index> &new_numbers,
1838 const IndexSet &indices_we_care_about,
1841 for (
unsigned int d = 1; d < dim; ++d)
1844 i = ((indices_we_care_about.
size() == 0) ?
1851 template <
int dim,
int spacedim>
1854 const std::vector<types::global_dof_index> &new_numbers,
1855 const IndexSet &indices_we_care_about,
1857 const bool check_validity)
1867 for (std::vector<types::global_dof_index>::iterator i =
1873 (indices_we_care_about.
size() == 0) ?
1876 else if (check_validity)
1887 for (
unsigned int vertex_index = 0;
1891 const unsigned int n_active_fe_indices =
1896 std::integral_constant<int, 0>());
1910 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1919 std::integral_constant<int, 0>());
1921 for (
unsigned int d = 0;
1922 d < dof_handler.
get_fe(fe_index).n_dofs_per_vertex();
1933 std::integral_constant<int, 0>());
1964 if (indices_we_care_about.
size() == 0)
1972 std::integral_constant<int, 0>(),
1973 new_numbers[old_dof_index]);
1985 std::integral_constant<int, 0>(),
1986 new_numbers[indices_we_care_about
1990 ::internal::DoFAccessorImplementation::
1991 Implementation::set_dof_index(
1997 std::integral_constant<int, 0>(),
2008 template <
int dim,
int spacedim>
2011 const std::vector<types::global_dof_index> &new_numbers,
2012 const IndexSet &indices_we_care_about,
2017 for (
unsigned int level = 0;
2022 i = ((indices_we_care_about.
size() == 0) ?
2030 if (!cell->is_artificial())
2034 for (
unsigned int d = 0;
2035 d < dof_handler.
get_fe(fe_index)
2036 .template n_dofs_per_object<dim>();
2040 cell->dof_index(d, fe_index);
2057 if (indices_we_care_about.
size() == 0)
2058 cell->set_dof_index(d,
2059 new_numbers[old_dof_index],
2063 if (indices_we_care_about.
is_element(old_dof_index))
2064 cell->set_dof_index(
2066 new_numbers[indices_we_care_about
2070 cell->set_dof_index(d,
2081 template <
int spacedim>
2084 const std::vector<types::global_dof_index> & ,
2094 template <
int spacedim>
2097 const std::vector<types::global_dof_index> &new_numbers,
2098 const IndexSet &indices_we_care_about,
2101 const unsigned int dim = 2;
2105 for (
unsigned int d = 1; d < dim; ++d)
2108 i = ((indices_we_care_about.
size() == 0) ?
2117 std::vector<bool> line_touched(
2120 if (!cell->is_artificial())
2121 for (
const auto l : cell->line_indices())
2122 if (!line_touched[cell->line(l)->index()])
2124 const auto line = cell->line(l);
2125 line_touched[line->index()] =
true;
2127 const unsigned int n_active_fe_indices =
2128 line->n_active_fe_indices();
2130 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2133 line->nth_active_fe_index(f);
2135 for (
unsigned int d = 0;
2141 line->dof_index(d, fe_index);
2161 if (indices_we_care_about.
size() == 0)
2162 line->set_dof_index(
2163 d, new_numbers[old_dof_index], fe_index);
2168 line->set_dof_index(
2170 new_numbers[indices_we_care_about
2175 line->set_dof_index(
2189 template <
int spacedim>
2192 const std::vector<types::global_dof_index> &new_numbers,
2193 const IndexSet &indices_we_care_about,
2196 const unsigned int dim = 3;
2200 for (
unsigned int d = 1; d < dim; ++d)
2203 i = ((indices_we_care_about.
size() == 0) ?
2212 std::vector<bool> line_touched(
2215 if (!cell->is_artificial())
2216 for (
const auto l : cell->line_indices())
2217 if (!line_touched[cell->line(l)->index()])
2219 const auto line = cell->line(l);
2220 line_touched[line->index()] =
true;
2222 const unsigned int n_active_fe_indices =
2223 line->n_active_fe_indices();
2225 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2228 line->nth_active_fe_index(f);
2230 for (
unsigned int d = 0;
2236 line->dof_index(d, fe_index);
2256 if (indices_we_care_about.
size() == 0)
2257 line->set_dof_index(
2258 d, new_numbers[old_dof_index], fe_index);
2261 line->set_dof_index(
2263 new_numbers[indices_we_care_about
2268 line->set_dof_index(
2278 std::vector<bool> quad_touched(
2281 if (!cell->is_artificial())
2282 for (
const auto q : cell->face_indices())
2283 if (!quad_touched[cell->quad(q)->index()])
2285 const auto quad = cell->quad(q);
2286 quad_touched[quad->index()] =
true;
2288 const unsigned int n_active_fe_indices =
2289 quad->n_active_fe_indices();
2291 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2294 quad->nth_active_fe_index(f);
2297 const unsigned int face_no =
2298 cell->active_fe_index() == fe_index ?
2300 cell->neighbor_face_no(q);
2302 for (
unsigned int d = 0;
2308 quad->dof_index(d, fe_index);
2328 if (indices_we_care_about.
size() == 0)
2329 quad->set_dof_index(
2330 d, new_numbers[old_dof_index], fe_index);
2335 quad->set_dof_index(
2337 new_numbers[indices_we_care_about
2342 quad->set_dof_index(
2367 template <
int dim,
int space_dim>
2370 const IndexSet &indices_we_care_about,
2372 const bool check_validity)
2383 indices_we_care_about,
2390 indices_we_care_about,
2396 indices_we_care_about,
2415 template <
int dim,
int spacedim>
2418 const std::vector<::types::global_dof_index> &new_numbers,
2419 const IndexSet &indices_we_care_about,
2421 const unsigned int level)
2430 if ((i->get_coarsest_level() <=
level) &&
2431 (i->get_finest_level() >=
level))
2432 for (
unsigned int d = 0;
2436 const ::types::global_dof_index idx =
2437 i->access_index(
level,
2445 (idx < new_numbers.size()),
2449 (indices_we_care_about.
size() == 0) ?
2466 template <
int dim,
int spacedim>
2469 const std::vector<::types::global_dof_index> &new_numbers,
2470 const IndexSet &indices_we_care_about,
2472 const unsigned int level)
2474 for (std::vector<types::global_dof_index>::iterator i =
2483 (*i < new_numbers.size())),
2486 (indices_we_care_about.
size() == 0) ?
2502 template <
int spacedim>
2505 const std::vector<types::global_dof_index> & ,
2508 const unsigned int ,
2516 template <
int dim,
int spacedim>
2519 const std::vector<::types::global_dof_index> &new_numbers,
2520 const IndexSet &indices_we_care_about,
2522 const unsigned int level,
2523 const bool check_validity)
2525 const unsigned int dofs_per_line =
2527 if (dofs_per_line > 0 ||
2533 std::vector<bool> line_touched(
2535 std::vector<bool> quad_touched(
2537 for (
const auto &cell :
2539 if (cell->level_subdomain_id() !=
2543 if (dofs_per_line > 0)
2545 const auto line_indices =
2546 internal::TriaAccessorImplementation::Implementation::
2547 get_line_indices_of_cell(*cell);
2548 for (
const auto line : cell->line_indices())
2550 if (!line_touched[line_indices[line]])
2552 line_touched[line_indices[line]] =
true;
2562 std::integral_constant<int, 1>());
2563 for (
unsigned int d = 0; d < dofs_per_line; ++d)
2573 (indices_we_care_about.
size() == 0) ?
2574 new_numbers[indices[d]] :
2575 new_numbers[indices_we_care_about
2585 for (
const auto quad : cell->face_indices())
2586 if (!quad_touched[cell->quad(quad)->index()])
2588 quad_touched[cell->quad(quad)->index()] =
true;
2589 const unsigned int dofs_per_quad =
2591 if (dofs_per_quad > 0)
2599 cell->quad(quad)->index(),
2602 std::integral_constant<int, 2>());
2603 for (
unsigned int d = 0; d < dofs_per_quad; ++d)
2613 (indices_we_care_about.
size() == 0) ?
2614 new_numbers[indices[d]] :
2615 new_numbers[indices_we_care_about
2627 template <
int dim,
int spacedim>
2630 const std::vector<::types::global_dof_index> &new_numbers,
2631 const IndexSet &indices_we_care_about,
2633 const unsigned int level,
2634 const bool check_validity)
2649 indices_we_care_about,
2655 indices_we_care_about,
2662 indices_we_care_about,
2676 template <
int dim,
int spacedim>
2679 : dof_handler(&dof_handler)
2684 template <
int dim,
int spacedim>
2703 template <
int dim,
int spacedim>
2704 std::vector<NumberCache>
2707 std::vector<NumberCache> number_caches;
2708 number_caches.reserve(dof_handler->get_triangulation().n_levels());
2709 for (
unsigned int level = 0;
2710 level < dof_handler->get_triangulation().n_levels();
2719 number_caches.emplace_back(n_level_dofs);
2722 return number_caches;
2727 template <
int dim,
int spacedim>
2730 const std::vector<types::global_dof_index> &new_numbers)
const
2745 if (new_numbers.empty())
2749 *std::max_element(new_numbers.begin(), new_numbers.end()) + 1);
2754 template <
int dim,
int spacedim>
2757 const unsigned int level,
2758 const std::vector<types::global_dof_index> &new_numbers)
const
2771 template <
int dim,
int spacedim>
2774 : dof_handler(&dof_handler)
2789 template <
int dim,
int spacedim>
2790 std::vector<types::subdomain_id>
2791 get_dof_subdomain_association(
2797 std::vector<types::subdomain_id> subdomain_association(
2799 std::vector<types::global_dof_index> local_dof_indices;
2800 local_dof_indices.reserve(
2805 for (
const auto &cell : dof_handler.active_cell_iterators())
2812 const unsigned int dofs_per_cell =
2813 cell->get_fe().n_dofs_per_cell();
2814 local_dof_indices.resize(dofs_per_cell);
2818 cell->active_fe_index());
2823 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2824 if (subdomain_association[local_dof_indices[i]] ==
2826 subdomain_association[local_dof_indices[i]] = subdomain_id;
2827 else if (subdomain_association[local_dof_indices[i]] >
2830 subdomain_association[local_dof_indices[i]] = subdomain_id;
2834 Assert(std::find(subdomain_association.begin(),
2835 subdomain_association.end(),
2837 subdomain_association.end(),
2840 Assert(*std::max_element(subdomain_association.begin(),
2841 subdomain_association.end()) <
n_procs,
2844 return subdomain_association;
2854 template <
int dim,
int spacedim>
2855 std::vector<types::subdomain_id>
2856 get_dof_level_subdomain_association(
2860 const unsigned int level)
2863 std::vector<types::subdomain_id> level_subdomain_association(
2865 std::vector<types::global_dof_index> local_dof_indices;
2866 local_dof_indices.reserve(
2871 for (
const auto &cell : dof_handler.cell_iterators_on_level(
level))
2877 cell->level_subdomain_id();
2878 const unsigned int dofs_per_cell =
2879 cell->get_fe().n_dofs_per_cell();
2880 local_dof_indices.resize(dofs_per_cell);
2881 cell->get_mg_dof_indices(local_dof_indices);
2886 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2887 if (level_subdomain_association[local_dof_indices[i]] ==
2889 level_subdomain_association[local_dof_indices[i]] =
2891 else if (level_subdomain_association[local_dof_indices[i]] >
2894 level_subdomain_association[local_dof_indices[i]] =
2899 Assert(std::find(level_subdomain_association.begin(),
2900 level_subdomain_association.end(),
2902 level_subdomain_association.end(),
2905 Assert(*std::max_element(level_subdomain_association.begin(),
2906 level_subdomain_association.end()) <
n_procs,
2909 return level_subdomain_association;
2915 template <
int dim,
int spacedim>
2919 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
2921 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
2935 const internal::parallel::shared::
2936 TemporarilyRestoreSubdomainIds<dim, spacedim>
2937 subdomain_modifier(*tr);
2943 *this->dof_handler);
2959 std::vector<types::global_dof_index> new_dof_indices(
2960 n_dofs, enumeration_dof_index);
2964 const std::vector<types::subdomain_id> subdomain_association =
2965 get_dof_subdomain_association(*this->dof_handler, n_dofs,
n_procs);
2976 if (subdomain_association[i] == subdomain)
2978 Assert(new_dof_indices[i] == enumeration_dof_index,
2980 new_dof_indices[i] = next_free_index;
2986 Assert(std::find(new_dof_indices.begin(),
2987 new_dof_indices.end(),
2988 enumeration_dof_index) == new_dof_indices.end(),
3009 const std::vector<types::subdomain_id> subdomain_association =
3010 get_dof_subdomain_association(*this->dof_handler, n_dofs,
n_procs);
3013 Assert(subdomain_association[i] >= subdomain_association[i - 1],
3016 std::vector<IndexSet> locally_owned_dofs_per_processor(
3029 while (start_index < n_dofs)
3031 while ((end_index < n_dofs) &&
3032 (subdomain_association[end_index] ==
3033 subdomain_association[start_index]))
3038 if (end_index > start_index)
3041 subdomain_association[start_index];
3042 locally_owned_dofs_per_processor[subdomain_owner].add_range(
3043 start_index, end_index);
3047 start_index = end_index;
3054 locally_owned_dofs_per_processor,
3060 template <
int dim,
int spacedim>
3061 std::vector<NumberCache>
3064 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3066 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3070 AssertThrow((tr->is_multilevel_hierarchy_constructed()),
3072 "Multigrid DoFs can only be distributed on a parallel "
3073 "Triangulation if the flag construct_multigrid_hierarchy "
3074 "is set in the constructor."));
3078 const unsigned int n_levels = tr->n_global_levels();
3080 std::vector<NumberCache> number_caches;
3081 number_caches.reserve(n_levels);
3084 for (
unsigned int lvl = 0; lvl < n_levels; ++lvl)
3092 std::vector<types::subdomain_id> saved_level_subdomain_ids;
3093 saved_level_subdomain_ids.resize(tr->n_cells(lvl));
3095 typename ::parallel::shared::Triangulation<dim, spacedim>::
3096 cell_iterator cell =
3102 const std::vector<types::subdomain_id> &true_level_subdomain_ids =
3103 tr->get_true_level_subdomain_ids_of_cells(lvl);
3105 for (
unsigned int index = 0; cell != endc; ++cell, ++
index)
3107 saved_level_subdomain_ids[
index] = cell->level_subdomain_id();
3108 cell->set_level_subdomain_id(true_level_subdomain_ids[
index]);
3127 std::vector<types::global_dof_index> new_dof_indices(
3132 const std::vector<types::subdomain_id>
3133 level_subdomain_association =
3134 get_dof_level_subdomain_association(*this->dof_handler,
3149 if (level_subdomain_association[i] == level_subdomain)
3153 new_dof_indices[i] = next_free_index;
3159 Assert(std::find(new_dof_indices.begin(),
3160 new_dof_indices.end(),
3162 new_dof_indices.end(),
3171 new_dof_indices,
IndexSet(0), *this->dof_handler, lvl,
true);
3183 const std::vector<types::subdomain_id> level_subdomain_association =
3184 get_dof_level_subdomain_association(*this->dof_handler,
3190 Assert(level_subdomain_association[i] >=
3191 level_subdomain_association[i - 1],
3194 std::vector<IndexSet> locally_owned_dofs_per_processor(
3205 unsigned int start_index = 0;
3206 unsigned int end_index = 0;
3207 while (start_index < n_dofs_on_level)
3209 while ((end_index) < n_dofs_on_level &&
3210 (level_subdomain_association[end_index] ==
3211 level_subdomain_association[start_index]))
3216 if (end_index > start_index)
3218 const unsigned int level_subdomain_owner =
3219 level_subdomain_association[start_index];
3220 locally_owned_dofs_per_processor[level_subdomain_owner]
3221 .add_range(start_index, end_index);
3225 start_index = end_index;
3231 typename ::parallel::shared::Triangulation<dim, spacedim>::
3232 cell_iterator cell =
3238 for (
unsigned int index = 0; cell != endc; ++cell, ++
index)
3239 cell->set_level_subdomain_id(saved_level_subdomain_ids[
index]);
3242 number_caches.emplace_back(
3249 return number_caches;
3254 template <
int dim,
int spacedim>
3257 const std::vector<types::global_dof_index> &new_numbers)
const
3259#ifndef DEAL_II_WITH_MPI
3266 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3268 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3273 const internal::parallel::shared::
3274 TemporarilyRestoreSubdomainIds<dim, spacedim>
3275 subdomain_modifier(*tr);
3277 std::vector<types::global_dof_index> global_gathered_numbers(
3278 this->dof_handler->
n_dofs(), 0);
3283 const bool uses_sequential_numbering =
3284 new_numbers.size() == this->dof_handler->
n_dofs();
3285 const bool all_use_sequential_numbering =
3287 tr->get_mpi_communicator());
3288 if (all_use_sequential_numbering)
3290 global_gathered_numbers = new_numbers;
3294 Assert(new_numbers.size() ==
3295 this->dof_handler->locally_owned_dofs().n_elements(),
3297 const unsigned int n_cpu =
3299 std::vector<types::global_dof_index> gathered_new_numbers(
3300 this->dof_handler->
n_dofs(), 0);
3302 tr->get_mpi_communicator()) ==
3303 this->dof_handler->get_triangulation()
3304 .locally_owned_subdomain(),
3309 std::vector<types::global_dof_index> new_numbers_copy(
3314 std::vector<int> rcounts(n_cpu);
3318 int cur_count = new_numbers_copy.size();
3319 int ierr = MPI_Allgather(&cur_count,
3325 tr->get_mpi_communicator());
3330 std::vector<int> displacements(n_cpu);
3331 for (
unsigned int i = 0; i < n_cpu; ++i)
3333 displacements[i] = shift;
3334 shift += rcounts[i];
3336 Assert(new_numbers_copy.size() ==
3337 static_cast<unsigned int>(
3339 tr->get_mpi_communicator())]),
3341 ierr = MPI_Allgatherv(
3342 new_numbers_copy.data(),
3343 new_numbers_copy.size(),
3344 Utilities::MPI::mpi_type_id_for_type<types::global_dof_index>,
3345 gathered_new_numbers.data(),
3347 displacements.data(),
3348 Utilities::MPI::mpi_type_id_for_type<types::global_dof_index>,
3349 tr->get_mpi_communicator());
3358 std::vector<unsigned int> count_rename_from(
3359 this->dof_handler->
n_dofs(), 0);
3360 std::vector<unsigned int> count_rename_to(
3361 this->dof_handler->
n_dofs(), 0);
3363 const std::vector<IndexSet> locally_owned_dofs_per_processor =
3365 tr->get_mpi_communicator(),
3366 this->dof_handler->locally_owned_dofs());
3368 for (
unsigned int i = 0; i < n_cpu; ++i)
3370 const IndexSet &iset = locally_owned_dofs_per_processor[i];
3377 gathered_new_numbers[shift + ind];
3382 global_gathered_numbers[target] =
value;
3383 count_rename_to[target]++;
3384 count_rename_from[
value]++;
3389 Assert(*std::max_element(count_rename_from.begin(),
3390 count_rename_from.end()) == 1,
3392 Assert(*std::min_element(count_rename_from.begin(),
3393 count_rename_from.end()) == 1,
3395 Assert((*std::max_element(count_rename_to.begin(),
3396 count_rename_to.end())) == 1,
3398 Assert((*std::min_element(count_rename_to.begin(),
3399 count_rename_to.end())) == 1,
3415 return number_cache;
3421 template <
int dim,
int spacedim>
3424 const unsigned int ,
3425 const std::vector<types::global_dof_index> & )
const
3437#ifdef DEAL_II_WITH_MPI
3441 template <
int dim,
int spacedim>
3444 std::vector<std::vector<bool>> &cell_marked)
3446 const auto pack = [](
const auto &cell) {
3450 std::vector<::types::global_dof_index>
data(
3451 cell->get_fe().n_dofs_per_cell());
3452 cell->get_mg_dof_indices(
data);
3457 const auto unpack = [&cell_marked](
const auto &cell,
3459 Assert(cell->get_fe().n_dofs_per_cell() == dofs.size(),
3462 Assert(cell->level_subdomain_id() !=
3466 bool complete =
true;
3472 MGDoFIndexProcessor<dim, spacedim>(cell->
level()),
3482 [&complete, invalid_dof_index =
numbers::invalid_dof_index](
3483 auto &stored_index, auto received_index) {
3484 if (*received_index != invalid_dof_index)
3486# if !defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1900
3487 Assert((stored_index == invalid_dof_index) ||
3488 (stored_index == *received_index),
3491 stored_index = *received_index;
3501 Assert(cell_marked[cell->level()][cell->index()],
3505 cell_marked[cell->level()][cell->index()] =
false;
3508 const auto filter = [&cell_marked](
const auto &cell) {
3509 return cell_marked[cell->level()][cell->index()];
3513 std::vector<types::global_dof_index>,
3537 template <
int dim,
int spacedim>
3539 communicate_dof_indices_on_marked_cells(
3541 std::vector<bool> &cell_marked)
3543# ifndef DEAL_II_WITH_MPI
3551 const auto pack = [](
const auto &cell) {
3554 std::vector<::types::global_dof_index>
data(
3555 cell->get_fe().n_dofs_per_cell());
3564 const auto unpack = [&cell_marked](
const auto &cell,
3566 Assert(cell->get_fe().n_dofs_per_cell() == dofs.size(),
3574 bool complete =
true;
3578 cell->active_fe_index(),
3579 DoFAccessorImplementation::Implementation::
3580 DoFIndexProcessor<dim, spacedim>(),
3591 auto &stored_index,
const auto received_index) {
3592 if (*received_index != invalid_dof_index)
3594# if !defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1900
3595 Assert((stored_index == invalid_dof_index) ||
3596 (stored_index == *received_index),
3599 stored_index = *received_index;
3609 Assert(cell_marked[cell->active_cell_index()],
3613 cell_marked[cell->active_cell_index()] =
false;
3616 const auto filter = [&cell_marked](
const auto &cell) {
3617 return cell_marked[cell->active_cell_index()];
3621 std::vector<types::global_dof_index>,
3634 template <
int dim,
int spacedim>
3637 : dof_handler(&dof_handler)
3642 template <
int dim,
int spacedim>
3646#ifndef DEAL_II_WITH_MPI
3695 std::vector<::types::global_dof_index> renumbering(
3696 n_initial_local_dofs, enumeration_dof_index);
3703 renumbering, subdomain_id, *dof_handler);
3707 std::vector<std::map<types::global_dof_index, types::global_dof_index>>
3708 all_constrained_indices(dim);
3723 for (
const auto &constrained_indices : all_constrained_indices)
3724 for (
const auto &
index : constrained_indices)
3726 ++n_identity_constrained_indices;
3729 std::count(renumbering.begin(),
3731 enumeration_dof_index) -
3732 n_identity_constrained_indices;
3736 const auto [my_shift, n_global_dofs] =
3743 renumbering, all_constrained_indices, my_shift);
3759 n_locally_owned_dofs);
3775 if (cell->is_ghost())
3776 cell_marked[cell->active_cell_index()] =
true;
3784 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
3797 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
3804 Assert(cell_marked[cell->active_cell_index()] ==
false,
3813 std::vector<::types::global_dof_index> local_dof_indices;
3816 if (!cell->is_artificial())
3818 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
3819 cell->get_dof_indices(local_dof_indices);
3820 if (local_dof_indices.end() !=
3821 std::find(local_dof_indices.begin(),
3822 local_dof_indices.end(),
3825 if (cell->is_ghost())
3829 "A ghost cell ended up with incomplete "
3830 "DoF index information. This should not "
3838 "A locally owned cell ended up with incomplete "
3839 "DoF index information. This should not "
3846 return number_cache;
3852 template <
int dim,
int spacedim>
3853 std::vector<NumberCache>
3856#ifndef DEAL_II_WITH_MPI
3858 return std::vector<NumberCache>();
3871 "Multigrid DoFs can only be distributed on a parallel "
3872 "Triangulation if the flag construct_multigrid_hierarchy "
3873 "is set in the constructor."));
3881 std::vector<NumberCache> number_caches;
3882 number_caches.reserve(n_levels);
3888 const unsigned int n_initial_local_dofs =
3894 std::vector<::types::global_dof_index> renumbering(
3895 n_initial_local_dofs, enumeration_dof_index);
3897 if (level < triangulation->n_levels())
3899 std::vector<::types::global_dof_index> local_dof_indices;
3901 for (
const auto &cell :
3903 if (cell->level_subdomain_id() !=
3905 (cell->level_subdomain_id() <
3915 local_dof_indices.resize(
3916 cell->get_fe().n_dofs_per_cell());
3917 cell->get_mg_dof_indices(local_dof_indices);
3918 for (
unsigned int i = 0;
3919 i < cell->get_fe().n_dofs_per_cell();
3922 renumbering[local_dof_indices[i]] =
3928 std::count(renumbering.begin(),
3930 enumeration_dof_index);
3934 const auto [my_shift, n_global_dofs] =
3943 if (
index == enumeration_dof_index)
3944 index = next_free_index++;
3954 if (level < triangulation->n_levels())
3966 number_caches.emplace_back(level_number_cache);
3975 std::vector<std::vector<bool>> cell_marked(triangulation->
n_levels());
3976 for (
unsigned int l = 0; l < triangulation->
n_levels(); ++l)
3977 cell_marked[l].resize(triangulation->
n_raw_cells(l));
3979 if (cell->is_ghost_on_level())
3980 cell_marked[cell->level()][cell->index()] =
true;
3985 communicate_mg_ghost_cells(*dof_handler, cell_marked);
3989 communicate_mg_ghost_cells(*dof_handler, cell_marked);
3995 Assert(cell_marked[cell->level()][cell->index()] ==
false,
4006 std::vector<::types::global_dof_index> local_dof_indices;
4008 if (cell->level_subdomain_id() !=
4011 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
4012 cell->get_mg_dof_indices(local_dof_indices);
4013 if (local_dof_indices.end() !=
4014 std::find(local_dof_indices.begin(),
4015 local_dof_indices.end(),
4019 ExcMessage(
"not all DoFs got distributed!"));
4025 return number_caches;
4031 template <
int dim,
int spacedim>
4034 const std::vector<::types::global_dof_index> &new_numbers)
const
4041#ifndef DEAL_II_WITH_MPI
4059 const bool locally_owned_set_changes =
4060 std::any_of(new_numbers.cbegin(),
4063 return owned_dofs.is_element(i) == false;
4066 IndexSet my_locally_owned_new_dof_indices = owned_dofs;
4067 if (locally_owned_set_changes && owned_dofs.
n_elements() > 0)
4069 std::vector<::types::global_dof_index> new_numbers_sorted =
4071 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
4073 my_locally_owned_new_dof_indices =
IndexSet(dof_handler->
n_dofs());
4075 new_numbers_sorted.begin(), new_numbers_sorted.end());
4076 my_locally_owned_new_dof_indices.
compress();
4095 if (cell->is_ghost())
4100 cell->active_fe_index(),
4102 DoFIndexProcessor<dim, spacedim>(),
4103 [&owned_dofs](
auto &stored_index,
auto) {
4132 if (cell->is_ghost())
4133 cell_marked[cell->active_cell_index()] =
true;
4141 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
4151 communicate_dof_indices_on_marked_cells(*dof_handler, cell_marked);
4156 std::move(my_locally_owned_new_dof_indices);
4160 return number_cache;
4166 template <
int dim,
int spacedim>
4169 const unsigned int level,
4170 const std::vector<types::global_dof_index> &new_numbers)
const
4172#ifndef DEAL_II_WITH_MPI
4195 const bool locally_owned_set_changes =
4196 std::any_of(new_numbers.cbegin(),
4199 return owned_dofs.is_element(i) == false;
4202 IndexSet my_locally_owned_new_dof_indices = owned_dofs;
4203 if (locally_owned_set_changes && owned_dofs.
n_elements() > 0)
4205 std::vector<::types::global_dof_index> new_numbers_sorted =
4207 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
4209 my_locally_owned_new_dof_indices =
4212 new_numbers_sorted.begin(), new_numbers_sorted.end());
4213 my_locally_owned_new_dof_indices.
compress();
4223 if (cell->is_ghost_on_level())
4230 MGDoFIndexProcessor<dim, spacedim>(cell->level()),
4231 [&owned_dofs](
auto &stored_index,
auto) {
4240 if (level < triangulation->n_levels() && owned_dofs.
n_elements() > 0)
4242 new_numbers, owned_dofs, *dof_handler,
level,
false);
4246 std::vector<std::vector<bool>> cell_marked(triangulation->
n_levels());
4247 for (
unsigned int l = 0; l < triangulation->
n_levels(); ++l)
4248 cell_marked[l].resize(triangulation->
n_raw_cells(l));
4250 if (cell->is_ghost_on_level())
4251 cell_marked[cell->level()][cell->index()] =
true;
4253 communicate_mg_ghost_cells(*dof_handler, cell_marked);
4255 communicate_mg_ghost_cells(*dof_handler, cell_marked);
4260 std::move(my_locally_owned_new_dof_indices);
4264 return number_cache;
4274#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_active_cells() const
unsigned int n_levels() const
cell_iterator end() const
unsigned int n_raw_cells(const unsigned int level) 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
types::subdomain_id locally_owned_subdomain() const override
virtual unsigned int n_global_levels() const override
virtual MPI_Comm get_mpi_communicator() const override
virtual bool is_multilevel_hierarchy_constructed() const =0
#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
* * * * std::vector< Number > ThermoPlasticMaterial< dim, ViscoplasticYieldLaw, Number >::get_state_parameters const
constexpr ReferenceCell< 2 > Quadrilateral
std::pair< T, T > partial_and_total_sum(const T &value, const MPI_Comm comm)
bool logical_and(const bool t, const MPI_Comm mpi_communicator)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
std::vector< T > all_gather(const MPI_Comm comm, const T &object_to_send)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
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
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 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 types::global_dof_index unify_dof_indices(const DoFHandler< dim, spacedim > &dof_handler, const types::global_dof_index n_dofs_before_identification, const bool check_validity)
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 > &)