47 namespace DoFHandlerImplementation
58 using ::hp::DoFHandler;
77 template <
class DoFHandlerType>
79 update_all_active_cell_dof_indices_caches(
80 const DoFHandlerType &dof_handler)
82 typename DoFHandlerType::active_cell_iterator
83 beginc = dof_handler.begin_active(),
84 endc = dof_handler.end();
87 [](
const typename DoFHandlerType::active_cell_iterator &cell,
90 if (!cell->is_artificial())
91 cell->update_cell_dof_indices_cache();
103 std::function<
void(
void *)>(),
115 template <
class DoFHandlerType>
117 update_all_level_cell_dof_indices_caches(
118 const DoFHandlerType &dof_handler)
120 typename DoFHandlerType::level_cell_iterator beginc =
122 endc = dof_handler.end();
125 [](
const typename DoFHandlerType::level_cell_iterator &cell,
128 if (cell->has_children() || !cell->is_artificial())
129 cell->update_cell_dof_indices_cache();
141 std::function<
void(
void *)>(),
149 using DoFIdentities =
150 std::vector<std::pair<unsigned int, unsigned int>>;
163 template <
int structdim,
int dim,
int spacedim>
165 ensure_existence_of_dof_identities(
168 std::unique_ptr<DoFIdentities> & identities)
172 if (identities.get() ==
nullptr)
178 identities = std_cxx14::make_unique<DoFIdentities>(
185 identities = std_cxx14::make_unique<DoFIdentities>(
192 identities = std_cxx14::make_unique<DoFIdentities>(
203 for (
unsigned int i = 0; i < identities->size(); ++i)
206 fe1.template n_dofs_per_object<structdim>(),
209 fe2.template n_dofs_per_object<structdim>(),
226 template <
int dim,
int spacedim>
227 static std::map<types::global_dof_index, types::global_dof_index>
231 std::map<types::global_dof_index, types::global_dof_index>
245 for (
unsigned int vertex_index = 0;
249 .get_used_vertices()[vertex_index] ==
true)
251 const unsigned int n_active_fe_indices =
252 ::internal::DoFAccessorImplementation::Implementation::
253 n_active_vertex_fe_indices(dof_handler, vertex_index);
255 if (n_active_fe_indices > 1)
257 const std::set<unsigned int> fe_indices =
258 ::internal::DoFAccessorImplementation::
259 Implementation::get_active_vertex_fe_indices(
260 dof_handler, vertex_index);
264 unsigned int most_dominating_fe_index =
271 if (most_dominating_fe_index ==
273 most_dominating_fe_index =
274 ::internal::DoFAccessorImplementation::
275 Implementation::nth_active_vertex_fe_index(
276 dof_handler, vertex_index, 0);
282 for (
const auto &other_fe_index : fe_indices)
283 if (other_fe_index != most_dominating_fe_index)
287 ensure_existence_of_dof_identities<0>(
288 dof_handler.
get_fe(most_dominating_fe_index),
289 dof_handler.
get_fe(other_fe_index),
290 vertex_dof_identities[most_dominating_fe_index]
301 DoFIdentities &identities =
302 *vertex_dof_identities[most_dominating_fe_index]
304 for (
const auto &
identity : identities)
307 ::internal::DoFAccessorImplementation::
308 Implementation::get_vertex_dof_index(
311 most_dominating_fe_index,
314 ::internal::DoFAccessorImplementation::
315 Implementation::get_vertex_dof_index(
343 if (master_dof_index !=
345 Assert((dof_identities.find(
347 dof_identities.end()) ||
348 (dof_identities[slave_dof_index] ==
352 dof_identities[slave_dof_index] =
360 return dof_identities;
368 template <
int spacedim>
369 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>
381 std::map<types::global_dof_index, types::global_dof_index>
386 std::vector<bool> user_flags;
390 .clear_user_flags_line();
415 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
416 if (cell->line(
l)->user_flag_set() ==
false)
419 line = cell->line(
l);
420 line->set_user_flag();
422 unsigned int unique_sets_of_dofs =
423 line->n_active_fe_indices();
427 const unsigned int n_active_fe_indices =
428 line->n_active_fe_indices();
429 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
430 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
432 const unsigned int fe_index_1 =
433 line->nth_active_fe_index(f),
435 line->nth_active_fe_index(g);
453 if ((dof_handler.
get_fe(fe_index_1).dofs_per_line ==
454 dof_handler.
get_fe(fe_index_2).dofs_per_line) &&
455 (dof_handler.
get_fe(fe_index_1).dofs_per_line > 0))
458 const unsigned int dofs_per_line =
459 dof_handler.
get_fe(fe_index_1).dofs_per_line;
461 ensure_existence_of_dof_identities<1>(
462 dof_handler.
get_fe(fe_index_1),
463 dof_handler.
get_fe(fe_index_2),
464 line_dof_identities[fe_index_1][fe_index_2]);
468 if (line_dof_identities[fe_index_1][fe_index_2]
469 ->size() == dofs_per_line)
472 for (; i < dofs_per_line; ++i)
473 if (((*(line_dof_identities[fe_index_1]
476 ((*(line_dof_identities[fe_index_1]
482 if (i == dofs_per_line)
491 --unique_sets_of_dofs;
495 const std::set<unsigned int> fe_indices{
496 fe_index_1, fe_index_2};
498 unsigned int dominating_fe_index =
500 .find_dominating_fe(fe_indices,
502 unsigned int other_fe_index =
505 if (dominating_fe_index !=
508 (dominating_fe_index == fe_index_1) ?
516 dominating_fe_index = fe_index_1;
517 other_fe_index = fe_index_2;
520 for (
unsigned int j = 0; j < dofs_per_line;
524 master_dof_index = line->dof_index(
525 j, dominating_fe_index);
528 line->dof_index(j, other_fe_index);
544 if (slave_dof_index !=
547 if (master_dof_index !=
554 if (dof_identities.find(
556 dof_identities.end())
572 [master_dof_index]) ==
573 dof_identities.end(),
587 (dof_identities.find(
589 dof_identities.end()) ||
626 if ((unique_sets_of_dofs == 2) && (dim == 2))
628 const std::set<unsigned int> fe_indices =
633 const unsigned int most_dominating_fe_index =
643 if (most_dominating_fe_index !=
649 for (
const auto &other_fe_index : fe_indices)
650 if (other_fe_index != most_dominating_fe_index)
652 ensure_existence_of_dof_identities<1>(
653 dof_handler.
get_fe(most_dominating_fe_index),
654 dof_handler.
get_fe(other_fe_index),
655 line_dof_identities[most_dominating_fe_index]
658 DoFIdentities &identities =
659 *line_dof_identities[most_dominating_fe_index]
661 for (
const auto &
identity : identities)
664 master_dof_index = line->dof_index(
666 most_dominating_fe_index);
685 if (slave_dof_index !=
695 if (master_dof_index !=
697 Assert((dof_identities.find(
699 dof_identities.end()) ||
705 dof_identities[slave_dof_index] =
717 .load_user_flags_line(user_flags);
719 return dof_identities;
728 template <
int dim,
int spacedim>
729 static std::map<types::global_dof_index, types::global_dof_index>
737 return std::map<types::global_dof_index, types::global_dof_index>();
741 template <
int spacedim>
742 static std::map<types::global_dof_index, types::global_dof_index>
748 std::map<types::global_dof_index, types::global_dof_index>
755 std::vector<bool> user_flags;
759 .clear_user_flags_quad();
776 for (
unsigned int q = 0; q < GeometryInfo<dim>::quads_per_cell; ++q)
777 if ((cell->quad(q)->user_flag_set() ==
false) &&
778 (cell->quad(q)->n_active_fe_indices() == 2))
781 quad = cell->quad(q);
782 quad->set_user_flag();
784 const std::set<unsigned int> fe_indices =
789 const unsigned int most_dominating_fe_index =
806 for (
const auto &other_fe_index : fe_indices)
807 if (other_fe_index != most_dominating_fe_index)
809 ensure_existence_of_dof_identities<2>(
810 dof_handler.
get_fe(most_dominating_fe_index),
811 dof_handler.
get_fe(other_fe_index),
812 quad_dof_identities[most_dominating_fe_index]
815 DoFIdentities &identities =
816 *quad_dof_identities[most_dominating_fe_index]
818 for (
const auto &
identity : identities)
822 most_dominating_fe_index);
832 if (slave_dof_index !=
842 if (master_dof_index !=
845 (dof_identities.find(
847 dof_identities.end()) ||
848 (dof_identities[slave_dof_index] ==
852 dof_identities[slave_dof_index] =
863 .load_user_flags_quad(user_flags);
865 return dof_identities;
874 template <
int dim,
int spacedim>
878 std::map<types::global_dof_index, types::global_dof_index>> &,
883 template <
int dim,
int spacedim>
887 &all_constrained_indices,
896 all_constrained_indices[i] =
904 all_constrained_indices[i] =
913 all_constrained_indices[i] =
942 template <
class DoFHandlerType>
945 std::vector<types::global_dof_index> &new_dof_indices,
947 std::map<types::global_dof_index, types::global_dof_index>>
948 &all_constrained_indices,
949 const DoFHandlerType &)
951 Assert(all_constrained_indices.size() == DoFHandlerType::dimension,
955 for (
const auto &constrained_dof_indices : all_constrained_indices)
956 for (
const auto &p : constrained_dof_indices)
959 Assert(new_dof_indices[p.first] == enumeration_dof_index,
962 new_dof_indices[p.first] = p.second;
967 for (
auto &new_dof_index : new_dof_indices)
968 if (new_dof_index == enumeration_dof_index)
969 new_dof_index = next_free_dof++;
973 for (
const auto &constrained_dof_indices : all_constrained_indices)
974 for (
const auto &p : constrained_dof_indices)
977 Assert(new_dof_indices[p.first] != enumeration_dof_index,
981 new_dof_indices[p.first] = new_dof_indices[p.second];
987 Assert(new_dof_index != enumeration_dof_index,
989 Assert(new_dof_index < next_free_dof ||
994 return next_free_dof;
1008 template <
int dim,
int spacedim>
1011 const unsigned int n_dofs_before_identification,
1014 return n_dofs_before_identification;
1018 template <
int dim,
int spacedim>
1021 const unsigned int n_dofs_before_identification,
1022 const bool check_validity)
1025 std::map<types::global_dof_index, types::global_dof_index>>
1026 all_constrained_indices(dim);
1029 std::vector<::types::global_dof_index> renumbering(
1030 n_dofs_before_identification, enumeration_dof_index);
1033 all_constrained_indices,
1038 update_all_active_cell_dof_indices_caches(dof_handler);
1049 template <
int dim,
int spacedim>
1065 std::vector<bool> include_vertex(
1067 if (
dynamic_cast<const ::parallel::
1068 DistributedTriangulationBase<dim, spacedim> *
>(
1071 if (cell->is_ghost())
1073 include_vertex[cell->vertex_index(v)] =
true;
1076 for (
unsigned int vertex_index = 0;
1080 .get_used_vertices()[vertex_index] ==
true) &&
1081 (include_vertex[vertex_index] ==
true))
1083 const unsigned int n_active_fe_indices =
1084 ::internal::DoFAccessorImplementation::Implementation::
1085 n_active_vertex_fe_indices(dof_handler, vertex_index);
1087 if (n_active_fe_indices > 1)
1089 const std::set<unsigned int> fe_indices =
1090 ::internal::DoFAccessorImplementation::
1091 Implementation::get_active_vertex_fe_indices(
1092 dof_handler, vertex_index);
1096 const unsigned int most_dominating_fe_index =
1107 if (most_dominating_fe_index !=
1114 for (
const auto &other_fe_index : fe_indices)
1115 if (other_fe_index != most_dominating_fe_index)
1119 ensure_existence_of_dof_identities<0>(
1120 dof_handler.
get_fe(most_dominating_fe_index),
1121 dof_handler.
get_fe(other_fe_index),
1122 vertex_dof_identities[most_dominating_fe_index]
1133 DoFIdentities &identities =
1134 *vertex_dof_identities[most_dominating_fe_index]
1136 for (
const auto &
identity : identities)
1139 master_dof_index = ::internal::
1140 DoFAccessorImplementation::
1141 Implementation::get_vertex_dof_index(
1144 most_dominating_fe_index,
1147 slave_dof_index = ::internal::
1148 DoFAccessorImplementation::
1149 Implementation::get_vertex_dof_index(
1167 if ((slave_dof_index ==
1169 (master_dof_index !=
1172 DoFAccessorImplementation::
1173 Implementation::set_vertex_dof_index(
1192 template <
int spacedim>
1198 template <
int dim,
int spacedim>
1205 std::vector<bool> user_flags;
1209 .clear_user_flags_line();
1213 if (cell->is_ghost())
1214 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell;
1216 cell->line(
l)->set_user_flag();
1241 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
1242 if ((cell->is_locally_owned()) &&
1243 (cell->line(
l)->user_flag_set() ==
true))
1246 line = cell->line(
l);
1247 line->clear_user_flag();
1249 unsigned int unique_sets_of_dofs =
1250 line->n_active_fe_indices();
1254 const unsigned int n_active_fe_indices =
1255 line->n_active_fe_indices();
1256 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1257 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
1259 const unsigned int fe_index_1 =
1260 line->nth_active_fe_index(f),
1262 line->nth_active_fe_index(g);
1264 if ((dof_handler.
get_fe(fe_index_1).dofs_per_line ==
1265 dof_handler.
get_fe(fe_index_2).dofs_per_line) &&
1266 (dof_handler.
get_fe(fe_index_1).dofs_per_line > 0))
1269 const unsigned int dofs_per_line =
1270 dof_handler.
get_fe(fe_index_1).dofs_per_line;
1272 ensure_existence_of_dof_identities<1>(
1273 dof_handler.
get_fe(fe_index_1),
1274 dof_handler.
get_fe(fe_index_2),
1275 line_dof_identities[fe_index_1][fe_index_2]);
1279 if (line_dof_identities[fe_index_1][fe_index_2]
1280 ->size() == dofs_per_line)
1283 for (; i < dofs_per_line; ++i)
1284 if (((*(line_dof_identities[fe_index_1]
1287 ((*(line_dof_identities[fe_index_1]
1293 if (i == dofs_per_line)
1302 --unique_sets_of_dofs;
1306 const std::set<unsigned int> fe_indices{
1307 fe_index_1, fe_index_2};
1309 unsigned int dominating_fe_index =
1311 .find_dominating_fe(fe_indices,
1313 unsigned int other_fe_index =
1316 if (dominating_fe_index !=
1319 (dominating_fe_index == fe_index_1) ?
1327 dominating_fe_index = fe_index_1;
1328 other_fe_index = fe_index_2;
1331 for (
unsigned int j = 0; j < dofs_per_line;
1335 master_dof_index = line->dof_index(
1336 j, dominating_fe_index);
1339 line->dof_index(j, other_fe_index);
1354 if ((slave_dof_index ==
1356 (master_dof_index !=
1377 if ((unique_sets_of_dofs == 2) && (dim == 2))
1379 const std::set<unsigned int> fe_indices =
1384 const unsigned int most_dominating_fe_index =
1394 if (most_dominating_fe_index !=
1400 for (
const auto &other_fe_index : fe_indices)
1401 if (other_fe_index != most_dominating_fe_index)
1403 ensure_existence_of_dof_identities<1>(
1404 dof_handler.
get_fe(most_dominating_fe_index),
1405 dof_handler.
get_fe(other_fe_index),
1406 line_dof_identities[most_dominating_fe_index]
1409 DoFIdentities &identities =
1410 *line_dof_identities[most_dominating_fe_index]
1412 for (
const auto &
identity : identities)
1415 master_dof_index = line->dof_index(
1417 most_dominating_fe_index);
1435 if ((slave_dof_index ==
1437 (master_dof_index !=
1451 .load_user_flags_line(user_flags);
1460 template <
int dim,
int spacedim>
1472 template <
int spacedim>
1481 std::vector<bool> user_flags;
1485 .clear_user_flags_quad();
1489 if (cell->is_ghost())
1490 for (
unsigned int q = 0; q < GeometryInfo<dim>::quads_per_cell;
1492 cell->quad(q)->set_user_flag();
1509 for (
unsigned int q = 0; q < GeometryInfo<dim>::quads_per_cell; ++q)
1510 if ((cell->is_locally_owned()) &&
1511 (cell->quad(q)->user_flag_set() ==
true) &&
1512 (cell->quad(q)->n_active_fe_indices() == 2))
1515 quad = cell->quad(q);
1516 quad->clear_user_flag();
1518 const std::set<unsigned int> fe_indices =
1523 const unsigned int most_dominating_fe_index =
1540 for (
const auto &other_fe_index : fe_indices)
1541 if (other_fe_index != most_dominating_fe_index)
1543 ensure_existence_of_dof_identities<2>(
1544 dof_handler.
get_fe(most_dominating_fe_index),
1545 dof_handler.
get_fe(other_fe_index),
1546 quad_dof_identities[most_dominating_fe_index]
1549 DoFIdentities &identities =
1550 *quad_dof_identities[most_dominating_fe_index]
1552 for (
const auto &
identity : identities)
1556 most_dominating_fe_index);
1572 if ((slave_dof_index ==
1574 (master_dof_index !=
1587 .load_user_flags_quad(user_flags);
1604 template <
int dim,
int spacedim>
1611 template <
int dim,
int spacedim>
1640 update_all_active_cell_dof_indices_caches(dof_handler);
1651 template <
class DoFHandlerType>
1654 DoFHandlerType & dof_handler)
1656 Assert(dof_handler.get_triangulation().n_levels() > 0,
1662 typename DoFHandlerType::active_cell_iterator
1663 cell = dof_handler.begin_active(),
1664 endc = dof_handler.end();
1666 for (; cell != endc; ++cell)
1667 if (!cell->is_artificial())
1671 std::vector<types::global_dof_index> dof_indices(
1672 cell->get_fe().dofs_per_cell);
1674 internal::DoFAccessorImplementation::get_dof_indices(
1675 *cell, dof_indices, cell->active_fe_index());
1677 for (
auto &dof_index : dof_indices)
1679 dof_index = next_free_dof++;
1681 cell->set_dof_indices(dof_indices);
1684 update_all_active_cell_dof_indices_caches(dof_handler);
1686 return next_free_dof;
1704 template <
class DoFHandlerType>
1707 std::vector<types::global_dof_index> &renumbering,
1709 const DoFHandlerType & dof_handler)
1711 std::vector<types::global_dof_index> local_dof_indices;
1713 for (
const auto &cell : dof_handler.active_cell_iterators())
1714 if (cell->is_ghost() && (cell->subdomain_id() <
subdomain_id))
1722 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
1723 cell->get_dof_indices(local_dof_indices);
1724 for (
const auto &local_dof_index : local_dof_indices)
1742 template <
int dim,
int spacedim>
1747 const std::integral_constant<int, 1> &)
1750 if (cell->
get_fe().dofs_per_vertex > 0)
1754 neighbor = cell->neighbor(v);
1759 if (neighbor->user_flag_set() &&
1760 (neighbor->level() == cell->level()))
1765 for (
unsigned int d = 0;
1766 d < cell->
get_fe().dofs_per_vertex;
1768 cell->set_mg_vertex_dof_index(
1772 neighbor->mg_vertex_dof_index(cell->level(),
1776 for (
unsigned int d = 0;
1777 d < cell->
get_fe().dofs_per_vertex;
1779 cell->set_mg_vertex_dof_index(
1783 neighbor->mg_vertex_dof_index(cell->level(),
1793 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_vertex;
1795 cell->set_mg_vertex_dof_index(cell->level(),
1802 if (cell->
get_fe().dofs_per_line > 0)
1803 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_line; ++
d)
1804 cell->set_mg_dof_index(cell->level(),
d, next_free_dof++);
1807 cell->set_user_flag();
1809 return next_free_dof;
1814 template <
int dim,
int spacedim>
1819 const std::integral_constant<int, 2> &)
1821 if (cell->
get_fe().dofs_per_vertex > 0)
1827 if (cell->mg_vertex_dof_index(cell->level(), vertex, 0) ==
1829 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_vertex;
1831 cell->set_mg_vertex_dof_index(cell->level(),
1837 if (cell->
get_fe().dofs_per_line > 0)
1845 if (line->mg_dof_index(cell->level(), 0) ==
1848 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_line;
1850 line->set_mg_dof_index(cell->level(),
d, next_free_dof++);
1855 if (cell->
get_fe().dofs_per_quad > 0)
1856 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_quad; ++
d)
1857 cell->set_mg_dof_index(cell->level(),
d, next_free_dof++);
1861 cell->set_user_flag();
1863 return next_free_dof;
1868 template <
int dim,
int spacedim>
1873 const std::integral_constant<int, 3> &)
1875 if (cell->
get_fe().dofs_per_vertex > 0)
1880 if (cell->mg_vertex_dof_index(cell->level(), vertex, 0) ==
1882 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_vertex;
1884 cell->set_mg_vertex_dof_index(cell->level(),
1890 if (cell->
get_fe().dofs_per_line > 0)
1891 for (
unsigned int l = 0; l < GeometryInfo<3>::lines_per_cell; ++
l)
1899 if (line->mg_dof_index(cell->level(), 0) ==
1902 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_line;
1904 line->set_mg_dof_index(cell->level(),
d, next_free_dof++);
1908 if (cell->
get_fe().dofs_per_quad > 0)
1909 for (
unsigned int q = 0; q < GeometryInfo<3>::quads_per_cell; ++q)
1917 if (quad->mg_dof_index(cell->level(), 0) ==
1920 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_quad;
1922 quad->set_mg_dof_index(cell->level(),
d, next_free_dof++);
1927 if (cell->
get_fe().dofs_per_hex > 0)
1928 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_hex; ++
d)
1929 cell->set_mg_dof_index(cell->level(),
d, next_free_dof++);
1933 cell->set_user_flag();
1935 return next_free_dof;
1941 template <
int spacedim>
1951 (void)next_free_dof;
1957 template <
int spacedim>
1967 (void)next_free_dof;
1973 template <
int spacedim>
1983 (void)next_free_dof;
1989 template <
class DoFHandlerType>
1992 DoFHandlerType & dof_handler,
1993 const unsigned int level)
1995 const unsigned int dim = DoFHandlerType::dimension;
1996 const unsigned int spacedim = DoFHandlerType::space_dimension;
1998 const ::Triangulation<dim, spacedim> &tria =
1999 dof_handler.get_triangulation();
2001 if (
level >= tria.n_levels())
2008 std::vector<bool> user_flags;
2009 tria.save_user_flags(user_flags);
2011 .clear_user_flags();
2015 cell = dof_handler.begin(
level),
2016 endc = dof_handler.end(
level);
2018 for (; cell != endc; ++cell)
2020 (cell->level_subdomain_id() == level_subdomain_id))
2022 Implementation::distribute_mg_dofs_on_cell<dim, spacedim>(
2023 cell, next_free_dof, std::integral_constant<int, dim>());
2027 .load_user_flags(user_flags);
2029 return next_free_dof;
2044 template <
int dim,
int spacedim>
2047 const std::vector<types::global_dof_index> &new_numbers,
2048 const IndexSet & indices_we_care_about,
2050 const bool check_validity)
2058 for (std::vector<types::global_dof_index>::iterator i =
2063 *i = (indices_we_care_about.
size() == 0) ?
2066 else if (check_validity)
2071 dof_handler.
get_fe().dofs_per_vertex) ==
false,
2084 template <
int dim,
int spacedim>
2087 const std::vector<types::global_dof_index> &new_numbers,
2088 const IndexSet & indices_we_care_about,
2093 for (std::vector<types::global_dof_index>::iterator i =
2094 dof_handler.
levels[
level]->dof_object.dofs.begin();
2095 i != dof_handler.
levels[
level]->dof_object.dofs.end();
2099 ((indices_we_care_about.
size() == 0) ?
2113 template <
int spacedim>
2116 const std::vector<types::global_dof_index> & ,
2125 template <
int spacedim>
2128 const std::vector<types::global_dof_index> &new_numbers,
2129 const IndexSet & indices_we_care_about,
2133 for (std::vector<types::global_dof_index>::iterator i =
2134 dof_handler.
faces->lines.dofs.begin();
2135 i != dof_handler.
faces->lines.dofs.end();
2138 *i = ((indices_we_care_about.
size() == 0) ?
2145 template <
int spacedim>
2148 const std::vector<types::global_dof_index> &new_numbers,
2149 const IndexSet & indices_we_care_about,
2153 for (std::vector<types::global_dof_index>::iterator i =
2154 dof_handler.
faces->lines.dofs.begin();
2155 i != dof_handler.
faces->lines.dofs.end();
2158 *i = ((indices_we_care_about.
size() == 0) ?
2163 for (std::vector<types::global_dof_index>::iterator i =
2164 dof_handler.
faces->quads.dofs.begin();
2165 i != dof_handler.
faces->quads.dofs.end();
2168 *i = ((indices_we_care_about.
size() == 0) ?
2175 template <
int dim,
int spacedim>
2178 const std::vector<types::global_dof_index> &new_numbers,
2179 const IndexSet & indices_we_care_about,
2181 const bool check_validity)
2183 for (
unsigned int vertex_index = 0;
2187 const unsigned int n_active_fe_indices =
2188 ::internal::DoFAccessorImplementation::Implementation::
2189 n_active_vertex_fe_indices(dof_handler, vertex_index);
2203 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2205 const unsigned int fe_index =
2206 ::internal::DoFAccessorImplementation::
2207 Implementation::nth_active_vertex_fe_index(dof_handler,
2211 for (
unsigned int d = 0;
2212 d < dof_handler.
get_fe(fe_index).dofs_per_vertex;
2216 ::internal::DoFAccessorImplementation::
2217 Implementation::get_vertex_dof_index(dof_handler,
2251 if (indices_we_care_about.
size() == 0)
2252 ::internal::DoFAccessorImplementation::
2253 Implementation::set_vertex_dof_index(
2258 new_numbers[old_dof_index]);
2263 ::internal::DoFAccessorImplementation::
2264 Implementation::set_vertex_dof_index(
2269 new_numbers[indices_we_care_about
2273 ::internal::DoFAccessorImplementation::
2274 Implementation::set_vertex_dof_index(
2289 template <
int dim,
int spacedim>
2292 const std::vector<types::global_dof_index> &new_numbers,
2293 const IndexSet & indices_we_care_about,
2297 if (!cell->is_artificial())
2299 const unsigned int fe_index = cell->active_fe_index();
2301 for (
unsigned int d = 0;
2302 d < dof_handler.
get_fe(fe_index)
2303 .
template n_dofs_per_object<dim>();
2307 cell->dof_index(
d, fe_index);
2324 if (indices_we_care_about.
size() == 0)
2325 cell->set_dof_index(
d,
2326 new_numbers[old_dof_index],
2330 if (indices_we_care_about.
is_element(old_dof_index))
2331 cell->set_dof_index(
2333 new_numbers[indices_we_care_about
2334 .index_within_set(old_dof_index)],
2337 cell->set_dof_index(
d,
2348 template <
int spacedim>
2351 const std::vector<types::global_dof_index> & ,
2361 template <
int spacedim>
2364 const std::vector<types::global_dof_index> &new_numbers,
2365 const IndexSet & indices_we_care_about,
2368 const unsigned int dim = 2;
2374 std::vector<bool> saved_line_user_flags;
2377 .save_user_flags_line(saved_line_user_flags);
2380 .clear_user_flags_line();
2383 if (!cell->is_artificial())
2384 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell;
2386 if (cell->line(
l)->user_flag_set() ==
false)
2389 spacedim>::line_iterator
2390 line = cell->line(
l);
2391 line->set_user_flag();
2393 const unsigned int n_active_fe_indices =
2394 line->n_active_fe_indices();
2396 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2398 const unsigned int fe_index =
2399 line->nth_active_fe_index(f);
2401 for (
unsigned int d = 0;
2402 d < dof_handler.
get_fe(fe_index).dofs_per_line;
2406 line->dof_index(
d, fe_index);
2426 if (indices_we_care_about.
size() == 0)
2427 line->set_dof_index(
2428 d, new_numbers[old_dof_index], fe_index);
2433 line->set_dof_index(
2435 new_numbers[indices_we_care_about
2440 line->set_dof_index(
2454 .load_user_flags_line(saved_line_user_flags);
2460 template <
int spacedim>
2463 const std::vector<types::global_dof_index> &new_numbers,
2464 const IndexSet & indices_we_care_about,
2467 const unsigned int dim = 3;
2473 std::vector<bool> saved_line_user_flags;
2476 .save_user_flags_line(saved_line_user_flags);
2479 .clear_user_flags_line();
2482 if (!cell->is_artificial())
2483 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell;
2485 if (cell->line(
l)->user_flag_set() ==
false)
2488 spacedim>::line_iterator
2489 line = cell->line(
l);
2490 line->set_user_flag();
2492 const unsigned int n_active_fe_indices =
2493 line->n_active_fe_indices();
2495 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2497 const unsigned int fe_index =
2498 line->nth_active_fe_index(f);
2500 for (
unsigned int d = 0;
2501 d < dof_handler.
get_fe(fe_index).dofs_per_line;
2505 line->dof_index(
d, fe_index);
2525 if (indices_we_care_about.
size() == 0)
2526 line->set_dof_index(
2527 d, new_numbers[old_dof_index], fe_index);
2530 line->set_dof_index(
2532 new_numbers[indices_we_care_about
2537 line->set_dof_index(
2548 .load_user_flags_line(saved_line_user_flags);
2553 std::vector<bool> saved_quad_user_flags;
2556 .save_user_flags_quad(saved_quad_user_flags);
2559 .clear_user_flags_quad();
2562 if (!cell->is_artificial())
2563 for (
unsigned int q = 0; q < GeometryInfo<dim>::quads_per_cell;
2565 if (cell->quad(q)->user_flag_set() ==
false)
2568 spacedim>::quad_iterator
2569 quad = cell->quad(q);
2570 quad->set_user_flag();
2572 const unsigned int n_active_fe_indices =
2573 quad->n_active_fe_indices();
2575 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2577 const unsigned int fe_index =
2578 quad->nth_active_fe_index(f);
2580 for (
unsigned int d = 0;
2581 d < dof_handler.
get_fe(fe_index).dofs_per_quad;
2585 quad->dof_index(
d, fe_index);
2605 if (indices_we_care_about.
size() == 0)
2606 quad->set_dof_index(
2607 d, new_numbers[old_dof_index], fe_index);
2612 quad->set_dof_index(
2614 new_numbers[indices_we_care_about
2619 quad->set_dof_index(
2632 .load_user_flags_quad(saved_quad_user_flags);
2649 template <
class DoFHandlerType>
2652 const IndexSet &indices_we_care_about,
2653 DoFHandlerType &dof_handler,
2654 const bool check_validity)
2656 if (DoFHandlerType::dimension == 1)
2665 indices_we_care_about,
2678 update_all_active_cell_dof_indices_caches(dof_handler);
2693 template <
int dim,
int spacedim>
2696 const std::vector<::types::global_dof_index> &new_numbers,
2697 const IndexSet & indices_we_care_about,
2699 const unsigned int level,
2700 const bool check_validity)
2702 (void)check_validity;
2706 for (
typename std::vector<
2712 if ((i->get_coarsest_level() <=
level) &&
2713 (i->get_finest_level() >=
level))
2714 for (
unsigned int d = 0;
d < dof_handler.
get_fe().dofs_per_vertex;
2720 dof_handler.
get_fe().dofs_per_vertex);
2724 Assert(check_validity ==
false ||
2725 (indices_we_care_about.
size() > 0 ?
2727 (idx < new_numbers.size())),
2731 dof_handler.
get_fe().dofs_per_vertex,
2732 (indices_we_care_about.
size() == 0) ?
2733 (new_numbers[idx]) :
2734 (new_numbers[indices_we_care_about
2749 template <
int dim,
int spacedim>
2752 const std::vector<::types::global_dof_index> &new_numbers,
2753 const IndexSet & indices_we_care_about,
2755 const unsigned int level)
2757 for (std::vector<types::global_dof_index>::iterator i =
2766 (*i < new_numbers.size())),
2769 (indices_we_care_about.
size() == 0) ?
2785 template <
int spacedim>
2788 const std::vector<types::global_dof_index> & ,
2791 const unsigned int ,
2799 template <
int spacedim>
2802 const std::vector<::types::global_dof_index> &new_numbers,
2803 const IndexSet & indices_we_care_about,
2805 const unsigned int level,
2806 const bool check_validity)
2808 if (dof_handler.
get_fe().dofs_per_line > 0)
2811 std::vector<bool> user_flags;
2815 .clear_user_flags();
2823 for (cell = dof_handler.
begin(
level); cell != endc; ++cell)
2824 if (cell->level_subdomain_id() !=
2826 for (
const unsigned int line :
2828 cell->face(line)->set_user_flag();
2831 dof_handler.
begin();
2832 cell != dof_handler.
end();
2834 for (
unsigned int l = 0; l < GeometryInfo<2>::lines_per_cell;
2836 if (cell->line(
l)->user_flag_set())
2838 for (
unsigned int d = 0;
2839 d < dof_handler.
get_fe().dofs_per_line;
2843 cell->line(
l)->mg_dof_index(
level,
d);
2849 cell->line(
l)->set_mg_dof_index(
2852 ((indices_we_care_about.
size() == 0) ?
2854 new_numbers[indices_we_care_about
2857 cell->line(
l)->clear_user_flag();
2862 .load_user_flags(user_flags);
2868 template <
int spacedim>
2871 const std::vector<::types::global_dof_index> &new_numbers,
2872 const IndexSet & indices_we_care_about,
2874 const unsigned int level,
2875 const bool check_validity)
2877 if (dof_handler.
get_fe().dofs_per_line > 0 ||
2878 dof_handler.
get_fe().dofs_per_quad > 0)
2881 std::vector<bool> user_flags;
2885 .clear_user_flags();
2892 for (cell = dof_handler.
begin(
level); cell != endc; ++cell)
2893 if (cell->level_subdomain_id() !=
2895 for (
unsigned int line = 0;
2896 line < GeometryInfo<3>::lines_per_cell;
2898 cell->line(line)->set_user_flag();
2901 dof_handler.
begin();
2902 cell != dof_handler.
end();
2904 for (
unsigned int l = 0; l < GeometryInfo<3>::lines_per_cell;
2906 if (cell->line(
l)->user_flag_set())
2908 for (
unsigned int d = 0;
2909 d < dof_handler.
get_fe().dofs_per_line;
2913 cell->line(
l)->mg_dof_index(
level,
d);
2919 cell->line(
l)->set_mg_dof_index(
2922 ((indices_we_care_about.
size() == 0) ?
2924 new_numbers[indices_we_care_about
2927 cell->line(
l)->clear_user_flag();
2933 for (cell = dof_handler.
begin(
level); cell != endc; ++cell)
2934 if (cell->level_subdomain_id() !=
2936 for (
unsigned int quad = 0;
2937 quad < GeometryInfo<3>::quads_per_cell;
2939 cell->quad(quad)->set_user_flag();
2942 dof_handler.
begin();
2943 cell != dof_handler.
end();
2945 for (
unsigned int l = 0; l < GeometryInfo<3>::quads_per_cell;
2947 if (cell->quad(
l)->user_flag_set())
2949 for (
unsigned int d = 0;
2950 d < dof_handler.
get_fe().dofs_per_quad;
2954 cell->quad(
l)->mg_dof_index(
level,
d);
2960 cell->quad(
l)->set_mg_dof_index(
2963 ((indices_we_care_about.
size() == 0) ?
2965 new_numbers[indices_we_care_about
2968 cell->quad(
l)->clear_user_flag();
2974 .load_user_flags(user_flags);
2980 template <
int dim,
int spacedim>
2983 const std::vector<::types::global_dof_index> &new_numbers,
2984 const IndexSet & indices_we_care_about,
2986 const unsigned int level,
2987 const bool check_validity)
2998 indices_we_care_about,
3005 indices_we_care_about,
3012 indices_we_care_about,
3021 template <
int dim,
int spacedim>
3024 const std::vector<::types::global_dof_index> & ,
3027 const unsigned int ,
3040 template <
class DoFHandlerType>
3042 : dof_handler(&dof_handler)
3047 template <
class DoFHandlerType>
3066 template <
class DoFHandlerType>
3067 std::vector<NumberCache>
3070 std::vector<bool> user_flags;
3071 dof_handler->get_triangulation().save_user_flags(user_flags);
3074 DoFHandlerType::space_dimension
> &>(
3075 dof_handler->get_triangulation())
3076 .clear_user_flags();
3078 std::vector<NumberCache> number_caches;
3079 number_caches.reserve(dof_handler->get_triangulation().n_levels());
3080 for (
unsigned int level = 0;
3081 level < dof_handler->get_triangulation().n_levels();
3090 number_caches.emplace_back(n_level_dofs);
3094 DoFHandlerType::space_dimension
> &>(
3095 dof_handler->get_triangulation())
3096 .load_user_flags(user_flags);
3098 return number_caches;
3103 template <
class DoFHandlerType>
3106 const std::vector<types::global_dof_index> &new_numbers)
const
3122 *std::max_element(new_numbers.begin(), new_numbers.end()) + 1);
3127 template <
class DoFHandlerType>
3130 const unsigned int level,
3131 const std::vector<types::global_dof_index> &new_numbers)
const
3144 template <
class DoFHandlerType>
3146 DoFHandlerType &dof_handler)
3147 : dof_handler(&dof_handler)
3162 template <
class DoFHandlerType>
3163 std::vector<types::subdomain_id>
3164 get_dof_subdomain_association(
const DoFHandlerType & dof_handler,
3166 const unsigned int n_procs)
3169 std::vector<types::subdomain_id> subdomain_association(
3171 std::vector<types::global_dof_index> local_dof_indices;
3176 typename DoFHandlerType::active_cell_iterator
3177 cell = dof_handler.begin_active(),
3178 endc = dof_handler.end();
3179 for (; cell != endc; ++cell)
3185 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
3186 local_dof_indices.resize(dofs_per_cell);
3187 cell->get_dof_indices(local_dof_indices);
3192 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
3193 if (subdomain_association[local_dof_indices[i]] ==
3195 subdomain_association[local_dof_indices[i]] =
subdomain_id;
3196 else if (subdomain_association[local_dof_indices[i]] >
3199 subdomain_association[local_dof_indices[i]] =
subdomain_id;
3203 Assert(std::find(subdomain_association.begin(),
3204 subdomain_association.end(),
3206 subdomain_association.end(),
3209 Assert(*std::max_element(subdomain_association.begin(),
3210 subdomain_association.end()) < n_procs,
3213 return subdomain_association;
3223 template <
class DoFHandlerType>
3224 std::vector<types::subdomain_id>
3225 get_dof_level_subdomain_association(
3226 const DoFHandlerType & dof_handler,
3228 const unsigned int n_procs,
3229 const unsigned int level)
3232 std::vector<types::subdomain_id> level_subdomain_association(
3234 std::vector<types::global_dof_index> local_dof_indices;
3239 typename DoFHandlerType::cell_iterator cell =
3240 dof_handler.begin(
level),
3241 endc = dof_handler.end(
level);
3242 for (; cell != endc; ++cell)
3248 cell->level_subdomain_id();
3249 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
3250 local_dof_indices.resize(dofs_per_cell);
3251 cell->get_mg_dof_indices(local_dof_indices);
3256 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
3257 if (level_subdomain_association[local_dof_indices[i]] ==
3259 level_subdomain_association[local_dof_indices[i]] =
3261 else if (level_subdomain_association[local_dof_indices[i]] >
3264 level_subdomain_association[local_dof_indices[i]] =
3269 Assert(std::find(level_subdomain_association.begin(),
3270 level_subdomain_association.end(),
3272 level_subdomain_association.end(),
3275 Assert(*std::max_element(level_subdomain_association.begin(),
3276 level_subdomain_association.end()) < n_procs,
3279 return level_subdomain_association;
3285 template <
class DoFHandlerType>
3289 const unsigned int dim = DoFHandlerType::dimension;
3290 const unsigned int spacedim = DoFHandlerType::space_dimension;
3292 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3294 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3295 &this->dof_handler->get_triangulation()));
3298 const unsigned int n_procs =
3305 std::vector<types::subdomain_id> saved_subdomain_ids;
3306 if (tr->with_artificial_cells())
3308 saved_subdomain_ids.resize(tr->n_active_cells());
3310 const std::vector<types::subdomain_id> &true_subdomain_ids =
3311 tr->get_true_subdomain_ids_of_cells();
3313 for (
const auto &cell : tr->active_cell_iterators())
3315 const unsigned int index = cell->active_cell_index();
3316 saved_subdomain_ids[index] = cell->subdomain_id();
3317 cell->set_subdomain_id(true_subdomain_ids[index]);
3325 *this->dof_handler);
3341 std::vector<types::global_dof_index> new_dof_indices(
3342 n_dofs, enumeration_dof_index);
3346 const std::vector<types::subdomain_id> subdomain_association =
3347 get_dof_subdomain_association(*this->dof_handler, n_dofs, n_procs);
3358 if (subdomain_association[i] == subdomain)
3360 Assert(new_dof_indices[i] == enumeration_dof_index,
3362 new_dof_indices[i] = next_free_index;
3368 Assert(std::find(new_dof_indices.begin(),
3369 new_dof_indices.end(),
3370 enumeration_dof_index) == new_dof_indices.end(),
3391 const std::vector<types::subdomain_id> subdomain_association =
3392 get_dof_subdomain_association(*this->dof_handler, n_dofs, n_procs);
3394 for (
unsigned int i = 1; i < n_dofs; ++i)
3395 Assert(subdomain_association[i] >= subdomain_association[i - 1],
3398 std::vector<IndexSet> locally_owned_dofs_per_processor(
3409 unsigned int start_index = 0;
3410 unsigned int end_index = 0;
3411 while (start_index < n_dofs)
3413 while ((end_index) < n_dofs &&
3414 (subdomain_association[end_index] ==
3415 subdomain_association[start_index]))
3420 if (end_index > start_index)
3422 const unsigned int subdomain_owner =
3423 subdomain_association[start_index];
3424 locally_owned_dofs_per_processor[subdomain_owner].add_range(
3425 start_index, end_index);
3429 start_index = end_index;
3434 if (tr->with_artificial_cells())
3435 for (
const auto &cell : tr->active_cell_iterators())
3436 cell->set_subdomain_id(
3437 saved_subdomain_ids[cell->active_cell_index()]);
3442 locally_owned_dofs_per_processor,
3443 this->dof_handler->get_triangulation().locally_owned_subdomain());
3448 template <
class DoFHandlerType>
3449 std::vector<NumberCache>
3452 const unsigned int dim = DoFHandlerType::dimension;
3453 const unsigned int spacedim = DoFHandlerType::space_dimension;
3455 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3457 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3458 &this->dof_handler->get_triangulation()));
3461 const unsigned int n_procs =
3463 const unsigned int n_levels = tr->n_global_levels();
3465 std::vector<NumberCache> number_caches;
3466 number_caches.reserve(n_levels);
3469 for (
unsigned int lvl = 0; lvl < n_levels; ++lvl)
3477 std::vector<types::subdomain_id> saved_level_subdomain_ids;
3478 saved_level_subdomain_ids.resize(tr->n_cells(lvl));
3480 typename ::parallel::shared::Triangulation<dim, spacedim>::
3481 cell_iterator cell =
3482 this->dof_handler->get_triangulation().begin(
3485 this->dof_handler->get_triangulation().end(lvl);
3487 const std::vector<types::subdomain_id> &true_level_subdomain_ids =
3488 tr->get_true_level_subdomain_ids_of_cells(lvl);
3490 for (
unsigned int index = 0; cell != endc; ++cell, ++index)
3492 saved_level_subdomain_ids[index] = cell->level_subdomain_id();
3493 cell->set_level_subdomain_id(true_level_subdomain_ids[index]);
3512 std::vector<types::global_dof_index> new_dof_indices(
3517 const std::vector<types::subdomain_id>
3518 level_subdomain_association =
3519 get_dof_level_subdomain_association(*this->dof_handler,
3531 level_subdomain < n_procs;
3534 if (level_subdomain_association[i] == level_subdomain)
3538 new_dof_indices[i] = next_free_index;
3544 Assert(std::find(new_dof_indices.begin(),
3545 new_dof_indices.end(),
3547 new_dof_indices.end(),
3556 new_dof_indices,
IndexSet(0), *this->dof_handler, lvl,
true);
3568 const std::vector<types::subdomain_id> level_subdomain_association =
3569 get_dof_level_subdomain_association(*this->dof_handler,
3574 for (
unsigned int i = 1; i < n_dofs_on_level; ++i)
3575 Assert(level_subdomain_association[i] >=
3576 level_subdomain_association[i - 1],
3579 std::vector<IndexSet> locally_owned_dofs_per_processor(
3580 n_procs,
IndexSet(n_dofs_on_level));
3590 unsigned int start_index = 0;
3591 unsigned int end_index = 0;
3592 while (start_index < n_dofs_on_level)
3594 while ((end_index) < n_dofs_on_level &&
3595 (level_subdomain_association[end_index] ==
3596 level_subdomain_association[start_index]))
3601 if (end_index > start_index)
3603 const unsigned int level_subdomain_owner =
3604 level_subdomain_association[start_index];
3605 locally_owned_dofs_per_processor[level_subdomain_owner]
3606 .add_range(start_index, end_index);
3610 start_index = end_index;
3616 typename ::parallel::shared::Triangulation<dim, spacedim>::
3617 cell_iterator cell =
3618 this->dof_handler->get_triangulation().begin(
3621 this->dof_handler->get_triangulation().end(lvl);
3623 for (
unsigned int index = 0; cell != endc; ++cell, ++index)
3624 cell->set_level_subdomain_id(saved_level_subdomain_ids[index]);
3627 number_caches.emplace_back(
3629 this->dof_handler->get_triangulation()
3630 .locally_owned_subdomain()));
3634 return number_caches;
3639 template <
class DoFHandlerType>
3642 const std::vector<types::global_dof_index> &new_numbers)
const
3644 #ifndef DEAL_II_WITH_MPI
3649 const unsigned int dim = DoFHandlerType::dimension;
3650 const unsigned int spacedim = DoFHandlerType::space_dimension;
3654 const ::parallel::shared::Triangulation<dim, spacedim> *tr =
3656 const ::parallel::shared::Triangulation<dim, spacedim> *
>(
3657 &this->dof_handler->get_triangulation()));
3660 typename ::parallel::shared::Triangulation<dim, spacedim>::
3661 active_cell_iterator
3662 cell = this->dof_handler->get_triangulation().begin_active(),
3663 endc = this->dof_handler->get_triangulation().end();
3664 std::vector<types::subdomain_id> current_subdomain_ids(
3665 tr->n_active_cells());
3666 const std::vector<types::subdomain_id> &true_subdomain_ids =
3667 tr->get_true_subdomain_ids_of_cells();
3668 if (tr->with_artificial_cells())
3669 for (
unsigned int index = 0; cell != endc; cell++, index++)
3671 current_subdomain_ids[index] = cell->subdomain_id();
3672 cell->set_subdomain_id(true_subdomain_ids[index]);
3675 std::vector<types::global_dof_index> global_gathered_numbers(
3676 this->dof_handler->n_dofs(), 0);
3681 if (new_numbers.size() == this->dof_handler->n_dofs())
3683 global_gathered_numbers = new_numbers;
3687 Assert(new_numbers.size() ==
3688 this->dof_handler->locally_owned_dofs().n_elements(),
3690 const unsigned int n_cpu =
3692 std::vector<types::global_dof_index> gathered_new_numbers(
3693 this->dof_handler->n_dofs(), 0);
3695 this->dof_handler->get_triangulation()
3696 .locally_owned_subdomain(),
3701 std::vector<types::global_dof_index> new_numbers_copy(
3706 std::vector<int> rcounts(n_cpu);
3710 int cur_count = new_numbers_copy.size();
3711 int ierr = MPI_Allgather(&cur_count,
3717 tr->get_communicator());
3722 std::vector<int> displacements(n_cpu);
3723 for (
unsigned int i = 0; i < n_cpu; i++)
3725 displacements[i] =
shift;
3726 shift += rcounts[i];
3728 Assert(new_numbers_copy.size() ==
3729 static_cast<unsigned int>(
3731 tr->get_communicator())]),
3733 ierr = MPI_Allgatherv(new_numbers_copy.data(),
3734 new_numbers_copy.size(),
3736 gathered_new_numbers.data(),
3738 displacements.data(),
3740 tr->get_communicator());
3750 std::vector<unsigned int> flag_1(this->dof_handler->n_dofs(), 0);
3751 std::vector<unsigned int> flag_2(this->dof_handler->n_dofs(), 0);
3752 for (
unsigned int i = 0; i < n_cpu; i++)
3755 this->dof_handler->locally_owned_dofs_per_processor()[i];
3762 gathered_new_numbers[
shift + ind];
3763 Assert(target < this->dof_handler->n_dofs(),
3765 Assert(value < this->dof_handler->n_dofs(),
3767 global_gathered_numbers[target] =
value;
3774 Assert(*std::max_element(flag_1.begin(), flag_1.end()) == 1,
3776 Assert(*std::min_element(flag_1.begin(), flag_1.end()) == 1,
3778 Assert((*std::max_element(flag_2.begin(), flag_2.end())) == 1,
3780 Assert((*std::min_element(flag_2.begin(), flag_2.end())) == 1,
3794 this->dof_handler->get_triangulation().locally_owned_subdomain());
3797 cell = tr->begin_active();
3798 if (tr->with_artificial_cells())
3799 for (
unsigned int index = 0; cell != endc; cell++, index++)
3800 cell->set_subdomain_id(current_subdomain_ids[index]);
3802 return number_cache;
3808 template <
class DoFHandlerType>
3811 const unsigned int ,
3812 const std::vector<types::global_dof_index> & )
const
3824 #ifdef DEAL_II_WITH_MPI
3828 template <
int dim,
int spacedim>
3830 get_mg_dofindices_recursively(
3831 const ::parallel::DistributedTriangulationBase<dim, spacedim>
3836 std::vector<::types::global_dof_index> &dof_numbers_and_indices)
3838 if (dealii_cell->id() ==
CellId(quadrant))
3841 Assert(dealii_cell->level_subdomain_id() ==
3842 tria.locally_owned_subdomain(),
3845 std::vector<::types::global_dof_index> local_dof_indices(
3846 dealii_cell->
get_fe().dofs_per_cell);
3847 dealii_cell->get_mg_dof_indices(local_dof_indices);
3849 dof_numbers_and_indices.push_back(
3850 dealii_cell->
get_fe().dofs_per_cell);
3851 dof_numbers_and_indices.insert(dof_numbers_and_indices.end(),
3852 local_dof_indices.begin(),
3853 local_dof_indices.end());
3857 if (dealii_cell->is_active())
3860 if (!dealii_cell->id().is_ancestor_of(
CellId(quadrant)))
3863 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
3865 get_mg_dofindices_recursively<dim, spacedim>(
3866 tria, dealii_cell->child(c), quadrant, dof_numbers_and_indices);
3871 template <
int dim,
int spacedim>
3873 find_marked_mg_ghost_cells_recursively(
3874 const typename ::parallel::
3875 DistributedTriangulationBase<dim, spacedim> &tria,
3881 std::vector<std::pair<unsigned int, typename CellId::binary_type>>>
3882 &neighbor_cell_list)
3885 if (dealii_cell->has_children())
3887 for (
unsigned int c = 0;
3888 c < GeometryInfo<dim>::max_children_per_cell;
3890 find_marked_mg_ghost_cells_recursively<dim, spacedim>(
3891 tria,
tree_index, dealii_cell->child(c), neighbor_cell_list);
3894 if (dealii_cell->user_flag_set() &&
3895 dealii_cell->level_subdomain_id() !=
3896 tria.locally_owned_subdomain())
3898 neighbor_cell_list[dealii_cell->level_subdomain_id()]
3900 dealii_cell->id().template to_binary<spacedim>());
3906 template <
int dim,
int spacedim>
3908 set_mg_dofindices_recursively(
3909 const ::parallel::DistributedTriangulationBase<dim, spacedim>
3916 if (dealii_cell->id() ==
CellId(quadrant))
3918 Assert(dealii_cell->level_subdomain_id() !=
3923 std::vector<::types::global_dof_index> dof_indices(
3924 dealii_cell->
get_fe().dofs_per_cell);
3925 dealii_cell->get_mg_dof_indices(dof_indices);
3927 bool complete =
true;
3928 for (
unsigned int i = 0; i < dof_indices.size(); ++i)
3932 (dof_indices[i] == dofs[i]),
3934 dof_indices[i] = dofs[i];
3948 ->clear_user_flag();
3953 ->set_mg_dof_indices(dof_indices);
3957 if (dealii_cell->is_active())
3960 if (!dealii_cell->id().is_ancestor_of(
CellId(quadrant)))
3963 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
3965 set_mg_dofindices_recursively<dim, spacedim>(tria,
3966 dealii_cell->child(c),
3973 template <
int dim,
int spacedim,
class DoFHandlerType>
3975 communicate_mg_ghost_cells(
3976 const typename ::parallel::
3977 DistributedTriangulationBase<dim, spacedim> &tria,
3978 DoFHandlerType & dof_handler)
3980 using QuadrantBufferType =
3981 std::vector<std::pair<unsigned int, typename CellId::binary_type>>;
3983 std::set<::types::subdomain_id> level_ghost_owners =
3984 tria.level_ghost_owners();
3985 std::map<::types::subdomain_id, QuadrantBufferType>
3987 for (
const auto level_ghost_owner : level_ghost_owners)
3988 neighbor_cell_list[level_ghost_owner] = {};
3990 for (
typename DoFHandlerType::level_cell_iterator cell =
3991 dof_handler.begin(0);
3992 cell != dof_handler.end(0);
4008 find_marked_mg_ghost_cells_recursively<dim, spacedim>(
4011 Assert(level_ghost_owners.size() == neighbor_cell_list.size(),
4019 mutex, tria.get_communicator());
4027 std::vector<MPI_Request> requests(level_ghost_owners.size());
4029 unsigned int idx = 0;
4030 for (
const auto &it : neighbor_cell_list)
4034 MPI_Isend(it.second.data(),
4035 it.second.size() *
sizeof(it.second[0]),
4039 tria.get_communicator(),
4047 std::vector<QuadrantBufferType> quadrant_data_to_send(
4048 level_ghost_owners.size());
4049 std::vector<std::vector<types::global_dof_index>>
4050 send_dof_numbers_and_indices(level_ghost_owners.size());
4051 std::vector<MPI_Request> reply_requests(level_ghost_owners.size());
4053 for (
unsigned int idx = 0; idx < level_ghost_owners.size(); ++idx)
4056 int ierr = MPI_Probe(MPI_ANY_SOURCE,
4058 tria.get_communicator(),
4063 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
4065 Assert(len %
sizeof(quadrant_data_to_send[idx][0]) == 0,
4069 len /
sizeof(quadrant_data_to_send[idx][0]);
4070 quadrant_data_to_send[idx].resize(
n_cells);
4072 ierr = MPI_Recv(quadrant_data_to_send[idx].data(),
4077 tria.get_communicator(),
4082 for (
unsigned int c = 0; c < static_cast<unsigned int>(
n_cells);
4086 CellId(quadrant_data_to_send[idx][c].
first, 0,
nullptr)
4089 typename DoFHandlerType::level_cell_iterator cell(
4090 &dof_handler.get_triangulation(),
4095 get_mg_dofindices_recursively<dim, spacedim>(
4098 quadrant_data_to_send[idx][c].
second,
4099 send_dof_numbers_and_indices[idx]);
4103 ierr = MPI_Isend(send_dof_numbers_and_indices[idx].data(),
4104 send_dof_numbers_and_indices[idx].size(),
4108 tria.get_communicator(),
4109 &reply_requests[idx]);
4114 for (
unsigned int idx = 0; idx < level_ghost_owners.size(); ++idx)
4117 int ierr = MPI_Probe(MPI_ANY_SOURCE,
4119 tria.get_communicator(),
4125 neighbor_cell_list[status.MPI_SOURCE];
4130 std::vector<types::global_dof_index>
4131 receive_dof_numbers_and_indices(len);
4133 ierr = MPI_Recv(receive_dof_numbers_and_indices.data(),
4138 tria.get_communicator(),
4144 receive_dof_numbers_and_indices.data();
4147 const auto temp =
CellId(it.first, 0,
nullptr).
to_cell(tria);
4149 typename DoFHandlerType::level_cell_iterator cell(
4150 &tria, 0, temp->index(), &dof_handler);
4152 Assert(cell->get_fe().dofs_per_cell == dofs[0],
4155 set_mg_dofindices_recursively<dim, spacedim>(tria,
4159 dofs += 1 + dofs[0];
4161 Assert(dofs == receive_dof_numbers_and_indices.data() +
4162 receive_dof_numbers_and_indices.size(),
4168 if (requests.size() > 0)
4170 const int ierr = MPI_Waitall(requests.size(),
4172 MPI_STATUSES_IGNORE);
4175 if (reply_requests.size() > 0)
4177 const int ierr = MPI_Waitall(reply_requests.size(),
4178 reply_requests.data(),
4179 MPI_STATUSES_IGNORE);
4186 template <
int spacedim>
4188 communicate_mg_ghost_cells(
const typename ::parallel::
4189 distributed::Triangulation<1, spacedim> &,
4197 template <
int spacedim>
4199 communicate_mg_ghost_cells(
const typename ::parallel::
4200 distributed::Triangulation<1, spacedim> &,
4226 template <
class DoFHandlerType>
4228 communicate_dof_indices_on_marked_cells(
4229 const DoFHandlerType &dof_handler,
4230 const std::map<
unsigned int, std::set<::types::subdomain_id>> &)
4232 # ifndef DEAL_II_WITH_MPI
4236 const unsigned int dim = DoFHandlerType::dimension;
4237 const unsigned int spacedim = DoFHandlerType::space_dimension;
4243 [](
const typename DoFHandlerType::active_cell_iterator &cell)
4244 -> std_cxx17::optional<std::vector<types::global_dof_index>> {
4251 if (cell->user_flag_set())
4254 std::vector<types::global_dof_index> local_dof_indices(
4255 cell->get_fe().dofs_per_cell);
4256 cell->get_dof_indices(local_dof_indices);
4265 if (std::find(local_dof_indices.begin(),
4266 local_dof_indices.end(),
4268 local_dof_indices.end())
4273 cell->clear_user_flag();
4275 return local_dof_indices;
4284 std::vector<types::global_dof_index> local_dof_indices(
4285 cell->get_fe().dofs_per_cell);
4286 cell->get_dof_indices(local_dof_indices);
4288 const bool is_complete =
4289 (std::find(local_dof_indices.begin(),
4290 local_dof_indices.end(),
4292 local_dof_indices.end());
4295 return std_cxx17::optional<
4296 std::vector<types::global_dof_index>>();
4301 [](
const typename DoFHandlerType::active_cell_iterator &cell,
4302 const std::vector<types::global_dof_index> &received_dof_indices)
4318 const bool is_complete = (std::find(received_dof_indices.begin(),
4319 received_dof_indices.end(),
4321 received_dof_indices.end());
4323 cell->clear_user_flag();
4337 std::vector<types::global_dof_index> local_dof_indices(
4338 cell->get_fe().dofs_per_cell);
4339 cell->update_cell_dof_indices_cache();
4340 cell->get_dof_indices(local_dof_indices);
4342 for (
unsigned int i = 0; i < local_dof_indices.size(); ++i)
4344 local_dof_indices[i] = received_dof_indices[i];
4348 Assert((received_dof_indices[i] ==
4350 (received_dof_indices[i] == local_dof_indices[i]),
4353 const_cast<typename DoFHandlerType::active_cell_iterator &
>(cell)
4354 ->set_dof_indices(local_dof_indices);
4358 std::vector<types::global_dof_index>,
4363 update_all_active_cell_dof_indices_caches(dof_handler);
4380 dynamic_cast<const ::parallel::
4381 DistributedTriangulationBase<dim, spacedim> *
>(
4382 &dof_handler.get_triangulation()))
4384 const int ierr = MPI_Barrier(
triangulation->get_communicator());
4391 "The function communicate_dof_indices_on_marked_cells() "
4392 "only works with parallel distributed triangulations."));
4401 #endif // DEAL_II_WITH_MPI
4405 template <
class DoFHandlerType>
4407 DoFHandlerType &dof_handler)
4408 : dof_handler(&dof_handler)
4413 template <
class DoFHandlerType>
4417 #ifndef DEAL_II_WITH_MPI
4421 const unsigned int dim = DoFHandlerType::dimension;
4422 const unsigned int spacedim = DoFHandlerType::space_dimension;
4429 &dof_handler->get_triangulation())));
4468 std::vector<::types::global_dof_index> renumbering(
4469 n_initial_local_dofs, enumeration_dof_index);
4479 std::vector<std::map<types::global_dof_index, types::global_dof_index>>
4480 all_constrained_indices(dim);
4496 renumbering, all_constrained_indices, *dof_handler);
4511 for (
auto &new_index : renumbering)
4513 new_index += my_shift;
4534 n_locally_owned_dofs);
4545 std::vector<bool> user_flags;
4551 const std::map<unsigned int, std::set<::types::subdomain_id>>
4558 for (
const auto &cell : dof_handler->active_cell_iterators())
4559 if (cell->is_locally_owned())
4565 cell->set_user_flag();
4569 else if (cell->is_ghost())
4570 cell->set_user_flag();
4580 communicate_dof_indices_on_marked_cells(
4595 communicate_dof_indices_on_marked_cells(
4601 for (
const auto &cell : dof_handler->active_cell_iterators())
4611 std::vector<::types::global_dof_index> local_dof_indices;
4613 for (
const auto &cell : dof_handler->active_cell_iterators())
4614 if (!cell->is_artificial())
4616 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
4617 cell->get_dof_indices(local_dof_indices);
4618 if (local_dof_indices.end() !=
4619 std::find(local_dof_indices.begin(),
4620 local_dof_indices.end(),
4623 if (cell->is_ghost())
4627 "A ghost cell ended up with incomplete "
4628 "DoF index information. This should not "
4636 "A locally owned cell ended up with incomplete "
4637 "DoF index information. This should not "
4644 return number_cache;
4645 #endif // DEAL_II_WITH_MPI
4650 template <
class DoFHandlerType>
4651 std::vector<NumberCache>
4654 #ifndef DEAL_II_WITH_MPI
4656 return std::vector<NumberCache>();
4658 const unsigned int dim = DoFHandlerType::dimension;
4659 const unsigned int spacedim = DoFHandlerType::space_dimension;
4666 &dof_handler->get_triangulation())));
4671 "Multigrid DoFs can only be distributed on a parallel "
4672 "Triangulation if the flag construct_multigrid_hierarchy "
4673 "is set in the constructor."));
4680 const unsigned int n_levels =
triangulation->n_global_levels();
4681 std::vector<NumberCache> number_caches;
4682 number_caches.reserve(n_levels);
4688 const unsigned int n_initial_local_dofs =
4694 std::vector<::types::global_dof_index> renumbering(
4695 n_initial_local_dofs);
4700 if (level < triangulation->n_levels())
4702 std::vector<::types::global_dof_index> local_dof_indices;
4704 typename DoFHandlerType::level_cell_iterator
4705 cell = dof_handler->begin(
level),
4706 endc = dof_handler->end(
level);
4708 for (; cell != endc; ++cell)
4709 if (cell->level_subdomain_id() !=
4711 (cell->level_subdomain_id() <
4721 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
4722 cell->get_mg_dof_indices(local_dof_indices);
4723 for (
unsigned int i = 0; i < cell->get_fe().dofs_per_cell;
4726 renumbering[local_dof_indices[i]] =
4774 if (level < triangulation->n_levels())
4785 number_caches.emplace_back(level_number_cache);
4794 std::vector<bool> user_flags;
4800 typename DoFHandlerType::level_cell_iterator cell,
4801 endc = dof_handler->end();
4802 for (cell = dof_handler->begin(); cell != endc; ++cell)
4803 if (cell->level_subdomain_id() !=
4805 !cell->is_locally_owned_on_level())
4806 cell->set_user_flag();
4827 const int ierr = MPI_Barrier(
triangulation->get_communicator());
4837 typename DoFHandlerType::level_cell_iterator cell,
4838 endc = dof_handler->end();
4839 for (cell = dof_handler->begin(); cell != endc; ++cell)
4840 if (cell->level_subdomain_id() !=
4842 !cell->is_locally_owned_on_level())
4855 std::vector<::types::global_dof_index> local_dof_indices;
4856 typename DoFHandlerType::level_cell_iterator cell,
4857 endc = dof_handler->end();
4859 for (cell = dof_handler->begin(); cell != endc; ++cell)
4860 if (cell->level_subdomain_id() !=
4863 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
4864 cell->get_mg_dof_indices(local_dof_indices);
4865 if (local_dof_indices.end() !=
4866 std::find(local_dof_indices.begin(),
4867 local_dof_indices.end(),
4876 return number_caches;
4878 #endif // DEAL_II_WITH_MPI
4882 template <
class DoFHandlerType>
4885 const std::vector<::types::global_dof_index> &new_numbers)
const
4889 Assert(new_numbers.size() == dof_handler->n_locally_owned_dofs(),
4892 #ifndef DEAL_II_WITH_MPI
4896 const unsigned int dim = DoFHandlerType::dimension;
4897 const unsigned int spacedim = DoFHandlerType::space_dimension;
4904 &dof_handler->get_triangulation())));
4912 const bool locally_owned_set_changes =
4913 std::any_of(new_numbers.cbegin(),
4916 return dof_handler->locally_owned_dofs().is_element(
4921 locally_owned_set_changes),
4934 std::vector<types::global_dof_index> ghosted_new_numbers(
4938 dof_handler->locally_owned_dofs(),
4945 const unsigned int communication_channel = 19;
4946 std::vector<types::global_dof_index> temp_array(
4948 std::vector<MPI_Request> requests;
4950 communication_channel,
4954 ghosted_new_numbers.data() + new_numbers.size(),
4959 ghosted_new_numbers.data() + new_numbers.size(),
4968 unsigned int n_ghosts_on_smaller_ranks = 0;
4969 for (std::pair<unsigned int, unsigned int> t :
4974 n_ghosts_on_smaller_ranks += t.second;
4976 if (n_ghosts_on_smaller_ranks > 0)
4978 Assert(ghosted_new_numbers.data() !=
nullptr,
4980 std::memmove(ghosted_new_numbers.data(),
4981 ghosted_new_numbers.data() + new_numbers.size(),
4983 n_ghosts_on_smaller_ranks);
4985 if (new_numbers.size() > 0)
4988 std::memcpy(ghosted_new_numbers.data() +
4989 n_ghosts_on_smaller_ranks,
4992 new_numbers.size());
5011 return number_cache;
5025 IndexSet my_locally_owned_new_dof_indices(dof_handler->n_dofs());
5026 if (dof_handler->n_locally_owned_dofs() > 0)
5028 std::vector<::types::global_dof_index>
5029 new_numbers_sorted = new_numbers;
5030 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
5033 new_numbers_sorted.begin(), new_numbers_sorted.end());
5034 my_locally_owned_new_dof_indices.
compress();
5053 std::vector<::types::global_dof_index> local_dof_indices;
5055 for (
auto cell : dof_handler->active_cell_iterators())
5056 if (cell->is_ghost())
5058 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
5059 cell->get_dof_indices(local_dof_indices);
5061 for (
unsigned int i = 0; i < cell->get_fe().dofs_per_cell;
5066 if ((local_dof_indices[i] !=
5068 (!dof_handler->locally_owned_dofs().is_element(
5069 local_dof_indices[i])))
5072 cell->set_dof_indices(local_dof_indices);
5078 if (dof_handler->locally_owned_dofs().n_elements() > 0)
5080 dof_handler->locally_owned_dofs(),
5091 std::vector<bool> user_flags;
5096 for (
const auto &cell : dof_handler->active_cell_iterators())
5097 if (!cell->is_artificial())
5098 cell->set_user_flag();
5102 const std::map<
unsigned int,
5103 std::set<::types::subdomain_id>>
5115 communicate_dof_indices_on_marked_cells(
5126 communicate_dof_indices_on_marked_cells(
5137 return number_cache;
5144 template <
class DoFHandlerType>
5147 const unsigned int level,
5148 const std::vector<types::global_dof_index> &new_numbers)
const
5153 const IndexSet index_set = dof_handler->locally_owned_mg_dofs(
level);
5155 #ifdef DEAL_II_WITH_MPI
5157 constexpr
int dim = DoFHandlerType::dimension;
5158 constexpr
int spacedim = DoFHandlerType::space_dimension;
5159 const ::parallel::TriangulationBase<dim, spacedim> *tr =
5160 (
dynamic_cast<const ::parallel::TriangulationBase<dim, spacedim>
5161 *
>(&this->dof_handler->get_triangulation()));
5164 const unsigned int my_rank =
5172 "Renumberings that change the locally owned mg dofs "
5173 "partitioning are currently not implemented for "
5174 "the multigrid levels"));
5185 std::vector<types::global_dof_index> ghosted_new_numbers(
5190 tr->get_communicator());
5191 std::vector<types::global_dof_index> temp_array(
5193 const unsigned int communication_channel = 17;
5194 std::vector<MPI_Request> requests;
5196 communication_channel,
5213 unsigned int n_ghosts_on_smaller_ranks = 0;
5214 for (std::pair<unsigned int, unsigned int> t :
5217 if (t.first > my_rank)
5219 n_ghosts_on_smaller_ranks += t.second;
5221 if (n_ghosts_on_smaller_ranks > 0)
5224 std::memmove(ghosted_new_numbers.data(),
5225 ghosted_new_numbers.data() + new_numbers.size(),
5227 n_ghosts_on_smaller_ranks);
5229 if (new_numbers.size() > 0)
5232 std::memcpy(ghosted_new_numbers.data() +
5233 n_ghosts_on_smaller_ranks,
5241 if (level < this->dof_handler->get_triangulation().n_levels() &&
5244 ghosted_new_numbers, relevant_dofs, *dof_handler,
level,
true);
5255 return number_cache;
5264 #include "dof_handler_policy.inst"