17 #include <deal.II/base/geometry_info.h> 18 #include <deal.II/base/memory_consumption.h> 19 #include <deal.II/base/partitioner.h> 20 #include <deal.II/base/thread_management.h> 21 #include <deal.II/base/utilities.h> 22 #include <deal.II/base/work_stream.h> 24 #include <deal.II/distributed/shared_tria.h> 25 #include <deal.II/distributed/tria.h> 27 #include <deal.II/dofs/dof_accessor.h> 28 #include <deal.II/dofs/dof_handler.h> 29 #include <deal.II/dofs/dof_handler_policy.h> 31 #include <deal.II/fe/fe.h> 33 #include <deal.II/grid/grid_tools.h> 34 #include <deal.II/grid/tria.h> 35 #include <deal.II/grid/tria_iterator.h> 37 #include <boost/archive/binary_iarchive.hpp> 38 #include <boost/archive/binary_oarchive.hpp> 39 #ifdef DEAL_II_WITH_ZLIB 40 # include <boost/iostreams/device/back_inserter.hpp> 41 # include <boost/iostreams/filter/gzip.hpp> 42 # include <boost/iostreams/filtering_stream.hpp> 43 # include <boost/iostreams/stream.hpp> 44 # include <boost/serialization/array.hpp> 52 DEAL_II_NAMESPACE_OPEN
57 namespace DoFHandlerImplementation
68 using ::hp::DoFHandler;
78 template <
class DoFHandlerType>
80 update_all_active_cell_dof_indices_caches(
81 const DoFHandlerType &dof_handler)
83 typename DoFHandlerType::active_cell_iterator
84 beginc = dof_handler.begin_active(),
85 endc = dof_handler.end();
88 [](
const typename DoFHandlerType::active_cell_iterator &cell,
91 if (!cell->is_artificial())
92 cell->update_cell_dof_indices_cache();
104 std::function<
void(
void *)>(),
116 template <
class DoFHandlerType>
118 update_all_level_cell_dof_indices_caches(
119 const DoFHandlerType &dof_handler)
121 typename DoFHandlerType::level_cell_iterator beginc =
123 endc = dof_handler.end();
126 [](
const typename DoFHandlerType::level_cell_iterator &cell,
129 if (cell->has_children() || !cell->is_artificial())
130 cell->update_cell_dof_indices_cache();
142 std::function<
void(
void *)>(),
150 using DoFIdentities =
151 std::vector<std::pair<unsigned int, unsigned int>>;
164 template <
int structdim,
int dim,
int spacedim>
166 ensure_existence_of_dof_identities(
169 std::unique_ptr<DoFIdentities> & identities)
173 if (identities.get() ==
nullptr)
179 identities = std_cxx14::make_unique<DoFIdentities>(
186 identities = std_cxx14::make_unique<DoFIdentities>(
193 identities = std_cxx14::make_unique<DoFIdentities>(
204 for (
unsigned int i = 0; i < identities->size(); ++i)
206 Assert((*identities)[i].first <
207 fe1.template n_dofs_per_object<structdim>(),
209 Assert((*identities)[i].second <
210 fe2.template n_dofs_per_object<structdim>(),
225 template <
int dim,
int spacedim,
typename iterator>
227 get_most_dominating_fe_index(
const iterator &
object)
229 unsigned int dominating_fe_index = 0;
230 for (; dominating_fe_index <
object->n_active_fe_indices();
231 ++dominating_fe_index)
234 object->nth_active_fe_index(dominating_fe_index));
238 for (
unsigned int other_fe_index = 0;
239 other_fe_index <
object->n_active_fe_indices();
241 if (other_fe_index != dominating_fe_index)
245 object->nth_active_fe_index(other_fe_index));
262 if (dominating_fe_index != object->n_active_fe_indices())
266 return object->nth_active_fe_index(dominating_fe_index);
278 struct Implementation
289 template <
int spacedim>
291 distribute_dofs_on_cell(
297 if (dof_handler.
get_fe().dofs_per_vertex > 0)
298 for (
unsigned int v = 0; v < GeometryInfo<1>::vertices_per_cell;
302 for (
unsigned int d = 0;
303 d < dof_handler.
get_fe().dofs_per_vertex;
306 Assert((cell->vertex_dof_index(v, d) ==
309 cell->set_vertex_dof_index(v, d, next_free_dof++);
312 for (
unsigned int d = 0;
313 d < dof_handler.
get_fe().dofs_per_vertex;
315 Assert((cell->vertex_dof_index(v, d) !=
321 for (
unsigned int d = 0;
d < dof_handler.
get_fe().dofs_per_line; ++
d)
322 cell->set_dof_index(d, next_free_dof++);
324 return next_free_dof;
329 template <
int spacedim>
331 distribute_dofs_on_cell(
336 if (dof_handler.
get_fe().dofs_per_vertex > 0)
338 for (
unsigned int vertex = 0;
339 vertex < GeometryInfo<2>::vertices_per_cell;
343 if (cell->vertex_dof_index(vertex, 0) ==
345 for (
unsigned int d = 0;
346 d < dof_handler.
get_fe().dofs_per_vertex;
348 cell->set_vertex_dof_index(vertex, d, next_free_dof++);
351 if (dof_handler.
get_fe().dofs_per_line > 0)
352 for (
unsigned int side = 0; side < GeometryInfo<2>::faces_per_cell;
355 const typename DoFHandler<2, spacedim>::line_iterator line =
363 for (
unsigned int d = 0;
364 d < dof_handler.
get_fe().dofs_per_line;
366 line->set_dof_index(d, next_free_dof++);
371 if (dof_handler.
get_fe().dofs_per_quad > 0)
372 for (
unsigned int d = 0;
d < dof_handler.
get_fe().dofs_per_quad;
374 cell->set_dof_index(d, next_free_dof++);
376 return next_free_dof;
381 template <
int spacedim>
383 distribute_dofs_on_cell(
388 if (dof_handler.
get_fe().dofs_per_vertex > 0)
390 for (
unsigned int vertex = 0;
391 vertex < GeometryInfo<3>::vertices_per_cell;
395 if (cell->vertex_dof_index(vertex, 0) ==
397 for (
unsigned int d = 0;
398 d < dof_handler.
get_fe().dofs_per_vertex;
400 cell->set_vertex_dof_index(vertex, d, next_free_dof++);
403 if (dof_handler.
get_fe().dofs_per_line > 0)
404 for (
unsigned int l = 0; l < GeometryInfo<3>::lines_per_cell; ++
l)
406 const typename DoFHandler<3, spacedim>::line_iterator line =
414 for (
unsigned int d = 0;
415 d < dof_handler.
get_fe().dofs_per_line;
417 line->set_dof_index(d, next_free_dof++);
421 if (dof_handler.
get_fe().dofs_per_quad > 0)
422 for (
unsigned int q = 0; q < GeometryInfo<3>::quads_per_cell; ++q)
424 const typename DoFHandler<3, spacedim>::quad_iterator quad =
432 for (
unsigned int d = 0;
433 d < dof_handler.
get_fe().dofs_per_quad;
435 quad->set_dof_index(d, next_free_dof++);
440 if (dof_handler.
get_fe().dofs_per_hex > 0)
441 for (
unsigned int d = 0;
d < dof_handler.
get_fe().dofs_per_hex; ++
d)
442 cell->set_dof_index(d, next_free_dof++);
444 return next_free_dof;
450 template <
int spacedim>
452 distribute_dofs_on_cell(
458 const unsigned int dim = 1;
461 const unsigned int fe_index = cell->active_fe_index();
468 for (
unsigned int vertex = 0;
469 vertex < GeometryInfo<1>::vertices_per_cell;
471 if (cell->vertex_dof_index(vertex, 0, fe_index) ==
474 ++
d, ++next_free_dof)
475 cell->set_vertex_dof_index(vertex,
483 Assert((cell->dof_index(0, fe_index) ==
488 ++
d, ++next_free_dof)
489 cell->set_dof_index(d, next_free_dof, fe_index);
493 cell->set_user_flag();
495 return next_free_dof;
500 template <
int spacedim>
502 distribute_dofs_on_cell(
508 const unsigned int dim = 2;
511 const unsigned int fe_index = cell->active_fe_index();
518 for (
unsigned int vertex = 0;
519 vertex < GeometryInfo<2>::vertices_per_cell;
521 if (cell->vertex_dof_index(vertex, 0, fe_index) ==
524 ++
d, ++next_free_dof)
525 cell->set_vertex_dof_index(vertex,
534 for (
unsigned int l = 0; l < GeometryInfo<2>::lines_per_cell; ++
l)
536 typename hp::DoFHandler<dim, spacedim>::line_iterator line =
541 ++
d, ++next_free_dof)
542 line->set_dof_index(d, next_free_dof, fe_index);
549 Assert((cell->dof_index(0, fe_index) ==
554 ++
d, ++next_free_dof)
555 cell->set_dof_index(d, next_free_dof, fe_index);
559 cell->set_user_flag();
561 return next_free_dof;
566 template <
int spacedim>
568 distribute_dofs_on_cell(
574 const unsigned int dim = 3;
577 const unsigned int fe_index = cell->active_fe_index();
584 for (
unsigned int vertex = 0;
585 vertex < GeometryInfo<3>::vertices_per_cell;
587 if (cell->vertex_dof_index(vertex, 0, fe_index) ==
590 ++
d, ++next_free_dof)
591 cell->set_vertex_dof_index(vertex,
600 for (
unsigned int l = 0; l < GeometryInfo<3>::lines_per_cell; ++
l)
602 typename hp::DoFHandler<dim, spacedim>::line_iterator line =
607 ++
d, ++next_free_dof)
608 line->set_dof_index(d, next_free_dof, fe_index);
613 for (
unsigned int q = 0; q < GeometryInfo<3>::quads_per_cell; ++q)
615 typename hp::DoFHandler<dim, spacedim>::quad_iterator quad =
620 ++
d, ++next_free_dof)
621 quad->set_dof_index(d, next_free_dof, fe_index);
628 Assert((cell->dof_index(0, fe_index) ==
633 ++
d, ++next_free_dof)
634 cell->set_dof_index(d, next_free_dof, fe_index);
638 cell->set_user_flag();
640 return next_free_dof;
649 template <
int dim,
int spacedim>
650 static std::map<types::global_dof_index, types::global_dof_index>
651 compute_vertex_dof_identities(
654 std::map<types::global_dof_index, types::global_dof_index>
682 std::vector<bool> include_vertex =
688 if (!cell->is_locally_owned())
689 for (
unsigned int v = 0;
690 v < GeometryInfo<dim>::vertices_per_cell;
692 include_vertex[cell->vertex_index(v)] =
false;
696 for (
unsigned int vertex_index = 0;
700 .get_used_vertices()[vertex_index] ==
true) &&
701 (include_vertex[vertex_index] ==
true))
703 const unsigned int n_active_fe_indices =
704 ::internal::DoFAccessorImplementation::Implementation::
705 n_active_vertex_fe_indices(dof_handler, vertex_index);
706 if (n_active_fe_indices > 1)
708 const unsigned int first_fe_index =
709 ::internal::DoFAccessorImplementation::
710 Implementation::nth_active_vertex_fe_index(dof_handler,
716 for (
unsigned int f = 1; f < n_active_fe_indices; ++f)
718 const unsigned int other_fe_index =
719 ::internal::DoFAccessorImplementation::
720 Implementation::nth_active_vertex_fe_index(
721 dof_handler, vertex_index, f);
725 ensure_existence_of_dof_identities<0>(
726 dof_handler.
get_fe(first_fe_index),
727 dof_handler.
get_fe(other_fe_index),
728 vertex_dof_identities[first_fe_index]
739 DoFIdentities &identities =
740 *vertex_dof_identities[first_fe_index]
742 for (
unsigned int i = 0; i < identities.size(); ++i)
745 ::internal::DoFAccessorImplementation::
746 Implementation::get_vertex_dof_index(
750 identities[i].first);
752 ::internal::DoFAccessorImplementation::
753 Implementation::get_vertex_dof_index(
757 identities[i].second);
759 Assert((dof_identities.find(higher_dof_index) ==
760 dof_identities.end()) ||
761 (dof_identities[higher_dof_index] ==
765 dof_identities[higher_dof_index] = lower_dof_index;
771 return dof_identities;
779 template <
int spacedim>
780 static std::map<types::global_dof_index, types::global_dof_index>
783 return std::map<types::global_dof_index, types::global_dof_index>();
787 template <
int dim,
int spacedim>
788 static std::map<types::global_dof_index, types::global_dof_index>
791 std::map<types::global_dof_index, types::global_dof_index>
796 std::vector<bool> user_flags;
800 .clear_user_flags_line();
820 cell != dof_handler.
end();
822 if (cell->is_locally_owned() ==
false)
823 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell;
825 cell->line(l)->set_user_flag();
851 cell != dof_handler.
end();
853 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
854 if (cell->line(l)->user_flag_set() ==
false)
856 const typename hp::DoFHandler<dim, spacedim>::line_iterator
857 line = cell->line(l);
858 line->set_user_flag();
860 unsigned int unique_sets_of_dofs =
861 line->n_active_fe_indices();
865 const unsigned int n_active_fe_indices =
866 line->n_active_fe_indices();
867 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
868 for (
unsigned int g = f + 1; g < n_active_fe_indices; ++g)
870 const unsigned int fe_index_1 =
871 line->nth_active_fe_index(f),
873 line->nth_active_fe_index(g);
875 if ((dof_handler.
get_fe(fe_index_1).dofs_per_line ==
876 dof_handler.
get_fe(fe_index_2).dofs_per_line) &&
877 (dof_handler.
get_fe(fe_index_1).dofs_per_line > 0))
879 ensure_existence_of_dof_identities<1>(
880 dof_handler.
get_fe(fe_index_1),
881 dof_handler.
get_fe(fe_index_2),
882 line_dof_identities[fe_index_1][fe_index_2]);
886 if (line_dof_identities[fe_index_1][fe_index_2]
888 dof_handler.
get_fe(fe_index_1).dofs_per_line)
891 for (; i < dof_handler.
get_fe(fe_index_1)
894 if (((*(line_dof_identities[fe_index_1]
897 ((*(line_dof_identities[fe_index_1]
903 if (i == dof_handler.
get_fe(fe_index_1)
913 --unique_sets_of_dofs;
915 for (
unsigned int j = 0;
916 j < dof_handler.
get_fe(fe_index_1)
922 line->dof_index(j, fe_index_1);
925 line->dof_index(j, fe_index_2);
930 if (dof_identities.find(
932 dof_identities.end())
934 Assert(dof_identities.find(
936 [master_dof_index]) ==
937 dof_identities.end(),
940 dof_identities[slave_dof_index] =
941 dof_identities[master_dof_index];
945 Assert((dof_identities.find(
947 dof_identities.end()) ||
953 dof_identities[slave_dof_index] =
972 if ((unique_sets_of_dofs == 2) && (dim == 2))
976 const unsigned int most_dominating_fe_index =
977 get_most_dominating_fe_index<dim, spacedim>(line);
984 if (most_dominating_fe_index !=
987 const unsigned int n_active_fe_indices =
988 line->n_active_fe_indices();
993 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
994 if (line->nth_active_fe_index(f) !=
995 most_dominating_fe_index)
997 const unsigned int other_fe_index =
998 line->nth_active_fe_index(f);
1000 ensure_existence_of_dof_identities<1>(
1001 dof_handler.
get_fe(most_dominating_fe_index),
1002 dof_handler.
get_fe(other_fe_index),
1003 line_dof_identities[most_dominating_fe_index]
1006 DoFIdentities &identities =
1007 *line_dof_identities[most_dominating_fe_index]
1009 for (
unsigned int i = 0; i < identities.size();
1013 master_dof_index = line->dof_index(
1014 identities[i].first,
1015 most_dominating_fe_index);
1018 line->dof_index(identities[i].second,
1021 Assert((dof_identities.find(
1022 master_dof_index) ==
1023 dof_identities.end()) ||
1024 (dof_identities[slave_dof_index] ==
1028 dof_identities[slave_dof_index] =
1039 .load_user_flags_line(user_flags);
1041 return dof_identities;
1050 template <
int dim,
int spacedim>
1051 static std::map<types::global_dof_index, types::global_dof_index>
1059 return std::map<types::global_dof_index, types::global_dof_index>();
1063 template <
int spacedim>
1064 static std::map<types::global_dof_index, types::global_dof_index>
1069 std::map<types::global_dof_index, types::global_dof_index>
1076 std::vector<bool> user_flags;
1080 .clear_user_flags_quad();
1100 cell != dof_handler.
end();
1102 if (cell->is_locally_owned() ==
false)
1103 for (
unsigned int q = 0; q < GeometryInfo<dim>::quads_per_cell;
1105 cell->quad(q)->set_user_flag();
1124 cell != dof_handler.
end();
1126 for (
unsigned int q = 0; q < GeometryInfo<dim>::quads_per_cell; ++q)
1127 if ((cell->quad(q)->user_flag_set() ==
false) &&
1128 (cell->quad(q)->n_active_fe_indices() == 2))
1130 const typename hp::DoFHandler<dim, spacedim>::quad_iterator
1131 quad = cell->quad(q);
1132 quad->set_user_flag();
1136 const unsigned int most_dominating_fe_index =
1137 get_most_dominating_fe_index<dim, spacedim>(quad);
1147 const unsigned int n_active_fe_indices =
1148 quad->n_active_fe_indices();
1154 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1155 if (quad->nth_active_fe_index(f) !=
1156 most_dominating_fe_index)
1158 const unsigned int other_fe_index =
1159 quad->nth_active_fe_index(f);
1161 ensure_existence_of_dof_identities<2>(
1162 dof_handler.
get_fe(most_dominating_fe_index),
1163 dof_handler.
get_fe(other_fe_index),
1164 quad_dof_identities[most_dominating_fe_index]
1167 DoFIdentities &identities =
1168 *quad_dof_identities[most_dominating_fe_index]
1170 for (
unsigned int i = 0; i < identities.size(); ++i)
1173 quad->dof_index(identities[i].first,
1174 most_dominating_fe_index);
1176 quad->dof_index(identities[i].second,
1179 Assert((dof_identities.find(master_dof_index) ==
1180 dof_identities.end()) ||
1181 (dof_identities[slave_dof_index] ==
1185 dof_identities[slave_dof_index] =
1195 .load_user_flags_quad(user_flags);
1197 return dof_identities;
1211 template <
int dim,
int spacedim>
1214 const unsigned int n_dofs_before_identification,
1217 return n_dofs_before_identification;
1222 template <
int dim,
int spacedim>
1225 const unsigned int n_dofs_before_identification,
1226 const bool check_validity)
1231 std::map<types::global_dof_index, types::global_dof_index>
1232 all_constrained_indices[dim];
1239 all_constrained_indices[i] =
1240 compute_vertex_dof_identities(dof_handler);
1247 all_constrained_indices[i] =
1248 compute_line_dof_identities(dof_handler);
1256 all_constrained_indices[i] =
1257 compute_quad_dof_identities(dof_handler);
1267 std::vector<types::global_dof_index> new_dof_indices(
1270 for (
const auto &constrained_dof_indices : all_constrained_indices)
1271 for (
const auto &p : constrained_dof_indices)
1275 new_dof_indices[p.first] = p.second;
1283 new_dof_indices[i] = next_free_dof;
1289 for (
const auto &constrained_dof_indices : all_constrained_indices)
1290 for (
const auto &p : constrained_dof_indices)
1295 new_dof_indices[p.first] = new_dof_indices[p.second];
1309 renumber_dofs(new_dof_indices,
1315 return next_free_dof;
1326 template <
class DoFHandlerType>
1329 DoFHandlerType & dof_handler)
1331 Assert(dof_handler.get_triangulation().n_levels() > 0,
1337 typename DoFHandlerType::active_cell_iterator
1339 endc = dof_handler.end();
1341 for (; cell != endc; ++cell)
1342 if (!cell->is_artificial())
1344 (cell->subdomain_id() == subdomain_id))
1346 Implementation::distribute_dofs_on_cell(dof_handler,
1357 unify_dof_indices(dof_handler,
1362 update_all_active_cell_dof_indices_caches(dof_handler);
1364 return next_free_dof;
1379 template <
int dim,
int spacedim>
1381 distribute_mg_dofs_on_cell(
1382 const typename DoFHandler<dim, spacedim>::level_cell_iterator &cell,
1384 const std::integral_constant<int, 1> &)
1387 if (cell->
get_fe().dofs_per_vertex > 0)
1388 for (
unsigned int v = 0; v < GeometryInfo<1>::vertices_per_cell;
1391 typename DoFHandler<dim, spacedim>::level_cell_iterator
1392 neighbor = cell->neighbor(v);
1397 if (neighbor->user_flag_set() &&
1398 (neighbor->level() == cell->level()))
1403 for (
unsigned int d = 0;
1404 d < cell->
get_fe().dofs_per_vertex;
1406 cell->set_mg_vertex_dof_index(
1410 neighbor->mg_vertex_dof_index(cell->level(),
1414 for (
unsigned int d = 0;
1415 d < cell->
get_fe().dofs_per_vertex;
1417 cell->set_mg_vertex_dof_index(
1421 neighbor->mg_vertex_dof_index(cell->level(),
1431 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_vertex;
1433 cell->set_mg_vertex_dof_index(cell->level(),
1440 if (cell->
get_fe().dofs_per_line > 0)
1441 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_line; ++
d)
1442 cell->set_mg_dof_index(cell->level(),
d, next_free_dof++);
1445 cell->set_user_flag();
1447 return next_free_dof;
1452 template <
int dim,
int spacedim>
1454 distribute_mg_dofs_on_cell(
1455 const typename DoFHandler<dim, spacedim>::level_cell_iterator &cell,
1457 const std::integral_constant<int, 2> &)
1459 if (cell->
get_fe().dofs_per_vertex > 0)
1461 for (
unsigned int vertex = 0;
1462 vertex < GeometryInfo<2>::vertices_per_cell;
1467 if (cell->mg_vertex_dof_index(cell->level(), vertex, 0) ==
1469 for (
unsigned int d = 0;
d < cell->
get_fe().dofs_per_vertex;
1471 cell->set_mg_vertex_dof_index(cell->level(),
1477 if (cell->
get_fe().dofs_per_line > 0)
1478 for (
unsigned int side = 0; side < GeometryInfo<2>::faces_per_cell;
1481 typename DoFHandler<dim, spacedim>::line_iterator line =
1486 if (line->mg_dof_index(cell->level(), 0) ==
1489 for (
unsigned int d = 0; d < cell->
get_fe().dofs_per_line;
1491 line->set_mg_dof_index(cell->level(), d, next_free_dof++);
1496 if (cell->
get_fe().dofs_per_quad > 0)
1497 for (
unsigned int d = 0; d < cell->
get_fe().dofs_per_quad; ++d)
1498 cell->set_mg_dof_index(cell->level(), d, next_free_dof++);
1502 cell->set_user_flag();
1504 return next_free_dof;
1509 template <
int dim,
int spacedim>
1511 distribute_mg_dofs_on_cell(
1512 const typename DoFHandler<dim, spacedim>::level_cell_iterator &cell,
1514 const std::integral_constant<int, 3> &)
1516 if (cell->
get_fe().dofs_per_vertex > 0)
1518 for (
unsigned int vertex = 0;
1519 vertex < GeometryInfo<3>::vertices_per_cell;
1523 if (cell->mg_vertex_dof_index(cell->level(), vertex, 0) ==
1525 for (
unsigned int d = 0; d < cell->
get_fe().dofs_per_vertex;
1527 cell->set_mg_vertex_dof_index(cell->level(),
1533 if (cell->
get_fe().dofs_per_line > 0)
1534 for (
unsigned int l = 0; l < GeometryInfo<3>::lines_per_cell; ++
l)
1536 typename DoFHandler<dim, spacedim>::line_iterator line =
1542 if (line->mg_dof_index(cell->level(), 0) ==
1545 for (
unsigned int d = 0; d < cell->
get_fe().dofs_per_line;
1547 line->set_mg_dof_index(cell->level(), d, next_free_dof++);
1551 if (cell->
get_fe().dofs_per_quad > 0)
1552 for (
unsigned int q = 0; q < GeometryInfo<3>::quads_per_cell; ++q)
1554 typename DoFHandler<dim, spacedim>::quad_iterator quad =
1560 if (quad->mg_dof_index(cell->level(), 0) ==
1563 for (
unsigned int d = 0; d < cell->
get_fe().dofs_per_quad;
1565 quad->set_mg_dof_index(cell->level(), d, next_free_dof++);
1570 if (cell->
get_fe().dofs_per_hex > 0)
1571 for (
unsigned int d = 0; d < cell->
get_fe().dofs_per_hex; ++d)
1572 cell->set_mg_dof_index(cell->level(), d, next_free_dof++);
1576 cell->set_user_flag();
1578 return next_free_dof;
1584 template <
int spacedim>
1586 distribute_mg_dofs_on_cell(
1594 (void)next_free_dof;
1600 template <
int spacedim>
1602 distribute_mg_dofs_on_cell(
1610 (void)next_free_dof;
1616 template <
int spacedim>
1618 distribute_mg_dofs_on_cell(
1626 (void)next_free_dof;
1632 template <
class DoFHandlerType>
1635 DoFHandlerType & dof_handler,
1636 const unsigned int level)
1638 const unsigned int dim = DoFHandlerType::dimension;
1639 const unsigned int spacedim = DoFHandlerType::space_dimension;
1641 const ::Triangulation<dim, spacedim> &tria =
1644 if (level >= tria.n_levels())
1651 std::vector<bool> user_flags;
1652 tria.save_user_flags(user_flags);
1654 .clear_user_flags();
1657 typename DoFHandler<dim, spacedim>::level_cell_iterator
1658 cell = dof_handler.
begin(level),
1659 endc = dof_handler.end(level);
1661 for (; cell != endc; ++cell)
1663 (cell->level_subdomain_id() == level_subdomain_id))
1665 Implementation::distribute_mg_dofs_on_cell<dim, spacedim>(
1666 cell, next_free_dof, std::integral_constant<int, dim>());
1670 .load_user_flags(user_flags);
1672 return next_free_dof;
1687 template <
int dim,
int spacedim>
1689 renumber_vertex_dofs(
1690 const std::vector<types::global_dof_index> &new_numbers,
1693 const bool check_validity)
1701 for (std::vector<types::global_dof_index>::iterator i =
1706 *i = (indices.
size() == 0) ?
1709 else if (check_validity)
1714 dof_handler.
get_fe().dofs_per_vertex) ==
false,
1727 template <
int dim,
int spacedim>
1730 const std::vector<types::global_dof_index> &new_numbers,
1734 for (
unsigned int level = 0; level < dof_handler.
levels.size();
1736 for (std::vector<types::global_dof_index>::iterator i =
1737 dof_handler.
levels[level]->dof_object.dofs.begin();
1738 i != dof_handler.
levels[level]->dof_object.dofs.end();
1741 *i = ((indices.
size() == 0) ?
1755 template <
int spacedim>
1758 const std::vector<types::global_dof_index> & ,
1767 template <
int spacedim>
1770 const std::vector<types::global_dof_index> &new_numbers,
1775 for (std::vector<types::global_dof_index>::iterator i =
1776 dof_handler.
faces->lines.dofs.begin();
1777 i != dof_handler.
faces->lines.dofs.end();
1780 *i = ((indices.
size() == 0) ?
1787 template <
int spacedim>
1790 const std::vector<types::global_dof_index> &new_numbers,
1795 for (std::vector<types::global_dof_index>::iterator i =
1796 dof_handler.
faces->lines.dofs.begin();
1797 i != dof_handler.
faces->lines.dofs.end();
1800 *i = ((indices.
size() == 0) ?
1805 for (std::vector<types::global_dof_index>::iterator i =
1806 dof_handler.
faces->quads.dofs.begin();
1807 i != dof_handler.
faces->quads.dofs.end();
1810 *i = ((indices.
size() == 0) ?
1817 template <
int dim,
int spacedim>
1819 renumber_vertex_dofs(
1820 const std::vector<types::global_dof_index> &new_numbers,
1823 const bool check_validity)
1825 for (
unsigned int vertex_index = 0;
1829 const unsigned int n_active_fe_indices =
1830 ::internal::DoFAccessorImplementation::Implementation::
1831 n_active_vertex_fe_indices(dof_handler, vertex_index);
1845 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1847 const unsigned int fe_index =
1848 ::internal::DoFAccessorImplementation::
1849 Implementation::nth_active_vertex_fe_index(dof_handler,
1853 for (
unsigned int d = 0;
1854 d < dof_handler.
get_fe(fe_index).dofs_per_vertex;
1858 ::internal::DoFAccessorImplementation::
1859 Implementation::get_vertex_dof_index(dof_handler,
1877 ::internal::DoFAccessorImplementation::
1878 Implementation::set_vertex_dof_index(
1883 (indices.
size() == 0) ?
1884 (new_numbers[old_dof_index]) :
1885 (new_numbers[indices.index_within_set(
1894 template <
int dim,
int spacedim>
1897 const std::vector<types::global_dof_index> &new_numbers,
1903 cell != dof_handler.
end();
1905 if (!cell->is_artificial())
1907 const unsigned int fe_index = cell->active_fe_index();
1909 for (
unsigned int d = 0;
1910 d < dof_handler.
get_fe(fe_index)
1911 .template n_dofs_per_object<dim>();
1915 cell->dof_index(d, fe_index);
1917 cell->set_dof_index(
1919 (indices.
size() == 0) ?
1920 (new_numbers[old_dof_index]) :
1930 template <
int spacedim>
1933 const std::vector<types::global_dof_index> & ,
1943 template <
int spacedim>
1946 const std::vector<types::global_dof_index> &new_numbers,
1950 const unsigned int dim = 2;
1956 std::vector<bool> saved_line_user_flags;
1959 .save_user_flags_line(saved_line_user_flags);
1962 .clear_user_flags_line();
1966 cell != dof_handler.
end();
1968 if (!cell->is_artificial())
1969 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell;
1971 if (cell->line(l)->user_flag_set() ==
false)
1974 spacedim>::line_iterator
1975 line = cell->line(l);
1976 line->set_user_flag();
1978 const unsigned int n_active_fe_indices =
1979 line->n_active_fe_indices();
1981 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
1983 const unsigned int fe_index =
1984 line->nth_active_fe_index(f);
1986 for (
unsigned int d = 0;
1987 d < dof_handler.
get_fe(fe_index).dofs_per_line;
1991 line->dof_index(d, fe_index);
1993 line->set_dof_index(
1995 (indices.
size() == 0) ?
1996 (new_numbers[old_dof_index]) :
2008 .load_user_flags_line(saved_line_user_flags);
2014 template <
int spacedim>
2017 const std::vector<types::global_dof_index> &new_numbers,
2021 const unsigned int dim = 3;
2027 std::vector<bool> saved_line_user_flags;
2030 .save_user_flags_line(saved_line_user_flags);
2033 .clear_user_flags_line();
2037 cell != dof_handler.
end();
2039 if (!cell->is_artificial())
2040 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell;
2042 if (cell->line(l)->user_flag_set() ==
false)
2045 spacedim>::line_iterator
2046 line = cell->line(l);
2047 line->set_user_flag();
2049 const unsigned int n_active_fe_indices =
2050 line->n_active_fe_indices();
2052 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2054 const unsigned int fe_index =
2055 line->nth_active_fe_index(f);
2057 for (
unsigned int d = 0;
2058 d < dof_handler.
get_fe(fe_index).dofs_per_line;
2062 line->dof_index(d, fe_index);
2064 line->set_dof_index(
2066 (indices.
size() == 0) ?
2067 (new_numbers[old_dof_index]) :
2079 .load_user_flags_line(saved_line_user_flags);
2084 std::vector<bool> saved_quad_user_flags;
2087 .save_user_flags_quad(saved_quad_user_flags);
2090 .clear_user_flags_quad();
2094 cell != dof_handler.
end();
2096 if (!cell->is_artificial())
2097 for (
unsigned int q = 0; q < GeometryInfo<dim>::quads_per_cell;
2099 if (cell->quad(q)->user_flag_set() ==
false)
2102 spacedim>::quad_iterator
2103 quad = cell->quad(q);
2104 quad->set_user_flag();
2106 const unsigned int n_active_fe_indices =
2107 quad->n_active_fe_indices();
2109 for (
unsigned int f = 0; f < n_active_fe_indices; ++f)
2111 const unsigned int fe_index =
2112 quad->nth_active_fe_index(f);
2114 for (
unsigned int d = 0;
2115 d < dof_handler.
get_fe(fe_index).dofs_per_quad;
2119 quad->dof_index(d, fe_index);
2121 quad->set_dof_index(
2123 (indices.
size() == 0) ?
2124 (new_numbers[old_dof_index]) :
2135 .load_user_flags_quad(saved_quad_user_flags);
2152 template <
class DoFHandlerType>
2154 renumber_dofs(
const std::vector<types::global_dof_index> &new_numbers,
2156 DoFHandlerType & dof_handler,
2157 const bool check_validity)
2159 if (DoFHandlerType::dimension == 1)
2167 renumber_vertex_dofs(new_numbers,
2173 [&]() { renumber_face_dofs(new_numbers, indices, dof_handler); });
2175 [&]() { renumber_cell_dofs(new_numbers, indices, dof_handler); });
2179 update_all_active_cell_dof_indices_caches(dof_handler);
2194 template <
int dim,
int spacedim>
2196 renumber_vertex_mg_dofs(
2197 const std::vector<::types::global_dof_index> &new_numbers,
2200 const unsigned int level,
2201 const bool check_validity)
2206 for (
typename std::vector<
2212 if ((i->get_coarsest_level() <= level) &&
2213 (i->get_finest_level() >= level))
2214 for (
unsigned int d = 0; d < dof_handler.
get_fe().dofs_per_vertex;
2217 const ::types::global_dof_index idx =
2220 dof_handler.
get_fe().dofs_per_vertex);
2230 dof_handler.
get_fe().dofs_per_vertex,
2231 (indices.
size() == 0) ?
2232 (new_numbers[idx]) :
2246 template <
int dim,
int spacedim>
2248 renumber_cell_mg_dofs(
2249 const std::vector<::types::global_dof_index> &new_numbers,
2252 const unsigned int level)
2254 for (std::vector<types::global_dof_index>::iterator i =
2255 dof_handler.mg_levels[level]->dof_object.dofs.begin();
2256 i != dof_handler.mg_levels[level]->dof_object.dofs.end();
2262 (*i < new_numbers.size())),
2264 *i = (indices.
size() == 0) ?
2280 template <
int spacedim>
2282 renumber_face_mg_dofs(
2283 const std::vector<types::global_dof_index> & ,
2286 const unsigned int ,
2294 template <
int spacedim>
2296 renumber_face_mg_dofs(
2297 const std::vector<::types::global_dof_index> &new_numbers,
2300 const unsigned int level,
2301 const bool check_validity)
2303 if (dof_handler.
get_fe().dofs_per_line > 0)
2306 std::vector<bool> user_flags;
2310 .clear_user_flags();
2316 typename DoFHandler<2, spacedim>::level_cell_iterator cell,
2317 endc = dof_handler.
end(level);
2318 for (cell = dof_handler.
begin(level); cell != endc; ++cell)
2319 for (
unsigned int line = 0;
2320 line < GeometryInfo<2>::faces_per_cell;
2322 cell->face(line)->set_user_flag();
2325 dof_handler.
begin();
2326 cell != dof_handler.
end();
2328 for (
unsigned int l = 0; l < GeometryInfo<2>::lines_per_cell;
2330 if (cell->line(l)->user_flag_set())
2332 for (
unsigned int d = 0;
2333 d < dof_handler.
get_fe().dofs_per_line;
2336 const ::types::global_dof_index idx =
2337 cell->line(l)->mg_dof_index(level, d);
2343 cell->line(l)->set_mg_dof_index(
2346 ((indices.
size() == 0) ?
2350 cell->line(l)->clear_user_flag();
2355 .load_user_flags(user_flags);
2361 template <
int spacedim>
2363 renumber_face_mg_dofs(
2364 const std::vector<::types::global_dof_index> &new_numbers,
2367 const unsigned int level,
2368 const bool check_validity)
2370 if (dof_handler.
get_fe().dofs_per_line > 0 ||
2371 dof_handler.
get_fe().dofs_per_quad > 0)
2374 std::vector<bool> user_flags;
2378 .clear_user_flags();
2383 typename DoFHandler<3, spacedim>::level_cell_iterator cell,
2384 endc = dof_handler.
end(level);
2385 for (cell = dof_handler.
begin(level); cell != endc; ++cell)
2386 for (
unsigned int line = 0;
2387 line < GeometryInfo<3>::lines_per_cell;
2389 cell->line(line)->set_user_flag();
2392 dof_handler.
begin();
2393 cell != dof_handler.
end();
2395 for (
unsigned int l = 0; l < GeometryInfo<3>::lines_per_cell;
2397 if (cell->line(l)->user_flag_set())
2399 for (
unsigned int d = 0;
2400 d < dof_handler.
get_fe().dofs_per_line;
2403 const ::types::global_dof_index idx =
2404 cell->line(l)->mg_dof_index(level, d);
2410 cell->line(l)->set_mg_dof_index(
2413 ((indices.
size() == 0) ?
2417 cell->line(l)->clear_user_flag();
2423 for (cell = dof_handler.
begin(level); cell != endc; ++cell)
2424 for (
unsigned int quad = 0;
2425 quad < GeometryInfo<3>::quads_per_cell;
2427 cell->quad(quad)->set_user_flag();
2430 dof_handler.
begin();
2431 cell != dof_handler.
end();
2433 for (
unsigned int l = 0; l < GeometryInfo<3>::quads_per_cell;
2435 if (cell->quad(l)->user_flag_set())
2437 for (
unsigned int d = 0;
2438 d < dof_handler.
get_fe().dofs_per_quad;
2441 const ::types::global_dof_index idx =
2442 cell->quad(l)->mg_dof_index(level, d);
2448 cell->quad(l)->set_mg_dof_index(
2451 ((indices.
size() == 0) ?
2455 cell->quad(l)->clear_user_flag();
2461 .load_user_flags(user_flags);
2467 template <
int dim,
int spacedim>
2470 const std::vector<::types::global_dof_index> &new_numbers,
2473 const unsigned int level,
2474 const bool check_validity)
2484 renumber_vertex_mg_dofs(
2485 new_numbers, indices, dof_handler, level, check_validity);
2488 renumber_face_mg_dofs(
2489 new_numbers, indices, dof_handler, level, check_validity);
2492 renumber_cell_mg_dofs(new_numbers, indices, dof_handler, level);
2499 template <
int dim,
int spacedim>
2502 const std::vector<::types::global_dof_index> & ,
2505 const unsigned int ,
2518 template <
class DoFHandlerType>
2520 : dof_handler(&dof_handler)
2525 template <
class DoFHandlerType>
2539 template <
class DoFHandlerType>
2540 std::vector<NumberCache>
2543 std::vector<bool> user_flags;
2547 DoFHandlerType::space_dimension
> &>(
2549 .clear_user_flags();
2551 std::vector<NumberCache> number_caches;
2553 for (
unsigned int level = 0;
2559 Implementation::distribute_dofs_on_level(
2563 number_caches.emplace_back(
NumberCache(n_level_dofs));
2567 DoFHandlerType::space_dimension
> &>(
2569 .load_user_flags(user_flags);
2571 return number_caches;
2576 template <
class DoFHandlerType>
2579 const std::vector<types::global_dof_index> &new_numbers)
const 2581 Implementation::renumber_dofs(new_numbers,
2595 *std::max_element(new_numbers.begin(), new_numbers.end()) + 1);
2600 template <
class DoFHandlerType>
2603 const unsigned int level,
2604 const std::vector<types::global_dof_index> &new_numbers)
const 2606 Implementation::renumber_mg_dofs(
2607 new_numbers,
IndexSet(0), *dof_handler, level,
true);
2617 template <
class DoFHandlerType>
2619 DoFHandlerType &dof_handler)
2620 : dof_handler(&dof_handler)
2635 template <
class DoFHandlerType>
2636 std::vector<types::subdomain_id>
2637 get_dof_subdomain_association(
const DoFHandlerType & dof_handler,
2639 const unsigned int n_procs)
2642 std::vector<types::subdomain_id> subdomain_association(
2644 std::vector<types::global_dof_index> local_dof_indices;
2649 typename DoFHandlerType::active_cell_iterator
2651 endc = dof_handler.
end();
2652 for (; cell != endc; ++cell)
2658 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
2659 local_dof_indices.resize(dofs_per_cell);
2660 cell->get_dof_indices(local_dof_indices);
2665 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2666 if (subdomain_association[local_dof_indices[i]] ==
2668 subdomain_association[local_dof_indices[i]] = subdomain_id;
2669 else if (subdomain_association[local_dof_indices[i]] >
2672 subdomain_association[local_dof_indices[i]] = subdomain_id;
2676 Assert(std::find(subdomain_association.begin(),
2677 subdomain_association.end(),
2679 subdomain_association.end(),
2682 Assert(*std::max_element(subdomain_association.begin(),
2683 subdomain_association.end()) < n_procs,
2686 return subdomain_association;
2696 template <
class DoFHandlerType>
2697 std::vector<types::subdomain_id>
2698 get_dof_level_subdomain_association(
2699 const DoFHandlerType & dof_handler,
2701 const unsigned int n_procs,
2702 const unsigned int level)
2705 std::vector<types::subdomain_id> level_subdomain_association(
2707 std::vector<types::global_dof_index> local_dof_indices;
2712 typename DoFHandlerType::cell_iterator cell =
2713 dof_handler.
begin(level),
2714 endc = dof_handler.
end(level);
2715 for (; cell != endc; ++cell)
2721 cell->level_subdomain_id();
2722 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
2723 local_dof_indices.resize(dofs_per_cell);
2724 cell->get_mg_dof_indices(local_dof_indices);
2729 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2730 if (level_subdomain_association[local_dof_indices[i]] ==
2732 level_subdomain_association[local_dof_indices[i]] =
2734 else if (level_subdomain_association[local_dof_indices[i]] >
2737 level_subdomain_association[local_dof_indices[i]] =
2742 Assert(std::find(level_subdomain_association.begin(),
2743 level_subdomain_association.end(),
2745 level_subdomain_association.end(),
2748 Assert(*std::max_element(level_subdomain_association.begin(),
2749 level_subdomain_association.end()) < n_procs,
2752 return level_subdomain_association;
2758 template <
class DoFHandlerType>
2762 const unsigned int dim = DoFHandlerType::dimension;
2763 const unsigned int spacedim = DoFHandlerType::space_dimension;
2770 const unsigned int n_procs =
2777 std::vector<types::subdomain_id> saved_subdomain_ids;
2783 active_cell_iterator
2787 const std::vector<types::subdomain_id> &true_subdomain_ids =
2790 for (
unsigned int index = 0; cell != endc; ++cell, ++index)
2792 saved_subdomain_ids[index] = cell->subdomain_id();
2793 cell->set_subdomain_id(true_subdomain_ids[index]);
2801 *this->dof_handler);
2812 std::vector<types::global_dof_index> new_dof_indices(
2817 const std::vector<types::subdomain_id> subdomain_association =
2818 get_dof_subdomain_association(*this->dof_handler, n_dofs, n_procs);
2829 if (subdomain_association[i] == subdomain)
2833 new_dof_indices[i] = next_free_index;
2839 Assert(std::find(new_dof_indices.begin(),
2840 new_dof_indices.end(),
2848 Implementation::renumber_dofs(new_dof_indices,
2862 const std::vector<types::subdomain_id> subdomain_association =
2863 get_dof_subdomain_association(*this->dof_handler, n_dofs, n_procs);
2865 for (
unsigned int i = 1; i < n_dofs; ++i)
2866 Assert(subdomain_association[i] >= subdomain_association[i - 1],
2869 std::vector<IndexSet> locally_owned_dofs_per_processor(
2880 unsigned int start_index = 0;
2881 unsigned int end_index = 0;
2882 while (start_index < n_dofs)
2884 while ((end_index) < n_dofs &&
2885 (subdomain_association[end_index] ==
2886 subdomain_association[start_index]))
2891 if (end_index > start_index)
2893 const unsigned int subdomain_owner =
2894 subdomain_association[start_index];
2895 locally_owned_dofs_per_processor[subdomain_owner].add_range(
2896 start_index, end_index);
2900 start_index = end_index;
2908 active_cell_iterator
2912 for (
unsigned int index = 0; cell != endc; ++cell, ++index)
2913 cell->set_subdomain_id(saved_subdomain_ids[index]);
2919 locally_owned_dofs_per_processor,
2925 template <
class DoFHandlerType>
2926 std::vector<NumberCache>
2929 const unsigned int dim = DoFHandlerType::dimension;
2930 const unsigned int spacedim = DoFHandlerType::space_dimension;
2937 const unsigned int n_procs =
2941 std::vector<NumberCache> number_caches;
2942 number_caches.reserve(n_levels);
2945 for (
unsigned int lvl = 0; lvl < n_levels; ++lvl)
2953 std::vector<types::subdomain_id> saved_level_subdomain_ids;
2954 saved_level_subdomain_ids.resize(tr->
n_cells(lvl));
2957 spacedim>::cell_iterator
2961 const std::vector<types::subdomain_id> &true_level_subdomain_ids =
2964 for (
unsigned int index = 0; cell != endc; ++cell, ++index)
2966 saved_level_subdomain_ids[index] = cell->level_subdomain_id();
2967 cell->set_level_subdomain_id(true_level_subdomain_ids[index]);
2975 Implementation::distribute_dofs_on_level(
2986 std::vector<types::global_dof_index> new_dof_indices(
2991 const std::vector<types::subdomain_id>
2992 level_subdomain_association =
2993 get_dof_level_subdomain_association(*this->dof_handler,
3005 level_subdomain < n_procs;
3008 if (level_subdomain_association[i] == level_subdomain)
3012 new_dof_indices[i] = next_free_index;
3018 Assert(std::find(new_dof_indices.begin(),
3019 new_dof_indices.end(),
3021 new_dof_indices.end(),
3029 Implementation::renumber_mg_dofs(
3030 new_dof_indices,
IndexSet(0), *this->dof_handler, lvl,
true);
3042 const std::vector<types::subdomain_id> level_subdomain_association =
3043 get_dof_level_subdomain_association(*this->dof_handler,
3048 for (
unsigned int i = 1; i < n_dofs_on_level; ++i)
3049 Assert(level_subdomain_association[i] >=
3050 level_subdomain_association[i - 1],
3053 std::vector<IndexSet> locally_owned_dofs_per_processor(
3054 n_procs,
IndexSet(n_dofs_on_level));
3064 unsigned int start_index = 0;
3065 unsigned int end_index = 0;
3066 while (start_index < n_dofs_on_level)
3068 while ((end_index) < n_dofs_on_level &&
3069 (level_subdomain_association[end_index] ==
3070 level_subdomain_association[start_index]))
3075 if (end_index > start_index)
3077 const unsigned int level_subdomain_owner =
3078 level_subdomain_association[start_index];
3079 locally_owned_dofs_per_processor[level_subdomain_owner]
3080 .add_range(start_index, end_index);
3084 start_index = end_index;
3091 spacedim>::cell_iterator
3095 for (
unsigned int index = 0; cell != endc; ++cell, ++index)
3096 cell->set_level_subdomain_id(saved_level_subdomain_ids[index]);
3099 number_caches.emplace_back(
3102 .locally_owned_subdomain()));
3106 return number_caches;
3111 template <
class DoFHandlerType>
3114 const std::vector<types::global_dof_index> &new_numbers)
const 3116 #ifndef DEAL_II_WITH_MPI 3121 const unsigned int dim = DoFHandlerType::dimension;
3122 const unsigned int spacedim = DoFHandlerType::space_dimension;
3132 spacedim>::active_cell_iterator
3135 std::vector<types::subdomain_id> current_subdomain_ids(
3137 const std::vector<types::subdomain_id> &true_subdomain_ids =
3140 for (
unsigned int index = 0; cell != endc; cell++, index++)
3142 current_subdomain_ids[index] = cell->subdomain_id();
3143 cell->set_subdomain_id(true_subdomain_ids[index]);
3146 std::vector<types::global_dof_index> global_gathered_numbers(
3147 this->dof_handler->
n_dofs(), 0);
3152 if (new_numbers.size() == this->dof_handler->
n_dofs())
3154 global_gathered_numbers = new_numbers;
3158 Assert(new_numbers.size() ==
3161 const unsigned int n_cpu =
3163 std::vector<types::global_dof_index> gathered_new_numbers(
3164 this->dof_handler->
n_dofs(), 0);
3167 .locally_owned_subdomain(),
3172 std::vector<types::global_dof_index> new_numbers_copy(
3177 std::vector<int> rcounts(n_cpu);
3181 int cur_count = new_numbers_copy.size();
3182 int ierr = MPI_Allgather(&cur_count,
3193 std::vector<int> displacements(n_cpu);
3194 for (
unsigned int i = 0; i < n_cpu; i++)
3196 displacements[i] = shift;
3197 shift += rcounts[i];
3199 Assert(((
int)new_numbers_copy.size()) ==
3203 ierr = MPI_Allgatherv(new_numbers_copy.data(),
3204 new_numbers_copy.size(),
3205 DEAL_II_DOF_INDEX_MPI_TYPE,
3206 gathered_new_numbers.data(),
3208 displacements.data(),
3209 DEAL_II_DOF_INDEX_MPI_TYPE,
3220 std::vector<unsigned int> flag_1(this->dof_handler->
n_dofs(), 0);
3221 std::vector<unsigned int> flag_2(this->dof_handler->
n_dofs(), 0);
3222 for (
unsigned int i = 0; i < n_cpu; i++)
3232 gathered_new_numbers[shift + ind];
3237 global_gathered_numbers[target] = value;
3244 Assert(*std::max_element(flag_1.begin(), flag_1.end()) == 1,
3246 Assert(*std::min_element(flag_1.begin(), flag_1.end()) == 1,
3248 Assert((*std::max_element(flag_2.begin(), flag_2.end())) == 1,
3250 Assert((*std::min_element(flag_2.begin(), flag_2.end())) == 1,
3257 Implementation::renumber_dofs(global_gathered_numbers,
3269 for (
unsigned int index = 0; cell != endc; cell++, index++)
3270 cell->set_subdomain_id(current_subdomain_ids[index]);
3272 return number_cache;
3278 template <
class DoFHandlerType>
3281 const unsigned int ,
3282 const std::vector<types::global_dof_index> & )
const 3294 #ifdef DEAL_II_WITH_P4EST 3314 struct CellDataTransferBuffer
3316 std::vector<unsigned int> tree_indices;
3317 std::vector<typename ::internal::p4est::types<dim>::quadrant>
3319 std::vector<::types::global_dof_index> dof_numbers_and_indices;
3326 template <
class Archive>
3328 save(Archive &ar,
const unsigned int )
const 3334 std::vector<char> quadrants_as_chars(
sizeof(quadrants[0]) *
3336 if (quadrants_as_chars.size() > 0)
3339 std::memcpy(quadrants_as_chars.data(),
3341 quadrants_as_chars.size());
3345 ar &quadrants_as_chars &tree_indices &dof_numbers_and_indices;
3352 template <
class Archive>
3354 load(Archive &ar,
const unsigned int )
3357 std::vector<char> quadrants_as_chars;
3358 ar &quadrants_as_chars &tree_indices &dof_numbers_and_indices;
3360 if (quadrants_as_chars.size() > 0)
3362 quadrants.resize(quadrants_as_chars.size() /
3363 sizeof(quadrants[0]));
3364 std::memcpy(quadrants.data(),
3365 quadrants_as_chars.data(),
3366 quadrants_as_chars.size());
3372 BOOST_SERIALIZATION_SPLIT_MEMBER()
3384 std::vector<char> buffer;
3386 # ifdef DEAL_II_WITH_ZLIB 3387 boost::iostreams::filtering_ostream out;
3389 boost::iostreams::gzip_compressor(boost::iostreams::gzip_params(
3390 boost::iostreams::gzip::best_compression)));
3391 out.push(boost::iostreams::back_inserter(buffer));
3393 boost::archive::binary_oarchive archive(out);
3398 std::ostringstream out;
3399 boost::archive::binary_oarchive archive(out);
3401 const std::string &s = out.str();
3402 buffer.reserve(s.size());
3403 buffer.assign(s.begin(), s.end());
3417 unpack_data(
const std::vector<char> &buffer)
3419 std::string decompressed_buffer;
3423 # ifdef DEAL_II_WITH_ZLIB 3424 boost::iostreams::filtering_ostream decompressing_stream;
3425 decompressing_stream.push(boost::iostreams::gzip_decompressor());
3426 decompressing_stream.push(
3427 boost::iostreams::back_inserter(decompressed_buffer));
3428 decompressing_stream.write(buffer.data(), buffer.size());
3430 decompressed_buffer.assign(buffer.begin(), buffer.end());
3435 std::istringstream in(decompressed_buffer);
3436 boost::archive::binary_iarchive archive(in);
3444 template <
int dim,
int spacedim>
3446 get_mg_dofindices_recursively(
3448 const typename ::internal::p4est::types<dim>::quadrant
3450 const typename DoFHandler<dim, spacedim>::level_cell_iterator
3452 const typename ::internal::p4est::types<dim>::quadrant
3454 CellDataTransferBuffer<dim> &cell_data_transfer_buffer)
3456 if (internal::p4est::quadrant_is_equal<dim>(p4est_cell, quadrant))
3459 Assert(dealii_cell->level_subdomain_id() ==
3464 std::vector<::types::global_dof_index> local_dof_indices(
3465 dealii_cell->
get_fe().dofs_per_cell);
3466 dealii_cell->get_mg_dof_indices(local_dof_indices);
3468 cell_data_transfer_buffer.dof_numbers_and_indices.push_back(
3469 dealii_cell->
get_fe().dofs_per_cell);
3470 cell_data_transfer_buffer.dof_numbers_and_indices.insert(
3471 cell_data_transfer_buffer.dof_numbers_and_indices.end(),
3472 local_dof_indices.begin(),
3473 local_dof_indices.end());
3477 if (!dealii_cell->has_children())
3480 if (!internal::p4est::quadrant_is_ancestor<dim>(p4est_cell, quadrant))
3483 typename ::internal::p4est::types<dim>::quadrant
3485 internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
3487 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
3489 get_mg_dofindices_recursively<dim, spacedim>(
3492 dealii_cell->child(c),
3494 cell_data_transfer_buffer);
3498 template <
int dim,
int spacedim>
3500 find_marked_mg_ghost_cells_recursively(
3503 const unsigned int tree_index,
3504 const typename DoFHandler<dim, spacedim>::level_cell_iterator
3506 const typename ::internal::p4est::types<dim>::quadrant
3509 &neighbor_cell_list)
3512 if (dealii_cell->has_children())
3514 typename ::internal::p4est::types<dim>::quadrant
3516 internal::p4est::init_quadrant_children<dim>(p4est_cell,
3520 for (
unsigned int c = 0;
3521 c < GeometryInfo<dim>::max_children_per_cell;
3523 find_marked_mg_ghost_cells_recursively<dim, spacedim>(
3526 dealii_cell->child(c),
3528 neighbor_cell_list);
3531 if (dealii_cell->user_flag_set() &&
3532 dealii_cell->level_subdomain_id() !=
3535 neighbor_cell_list[dealii_cell->level_subdomain_id()]
3536 .tree_indices.push_back(tree_index);
3537 neighbor_cell_list[dealii_cell->level_subdomain_id()]
3538 .quadrants.push_back(p4est_cell);
3543 template <
int dim,
int spacedim>
3545 set_mg_dofindices_recursively(
3547 const typename ::internal::p4est::types<dim>::quadrant
3549 const typename DoFHandler<dim, spacedim>::level_cell_iterator
3551 const typename ::internal::p4est::types<dim>::quadrant
3555 if (internal::p4est::quadrant_is_equal<dim>(p4est_cell, quadrant))
3557 Assert(dealii_cell->level_subdomain_id() !=
3558 ::numbers::artificial_subdomain_id,
3562 std::vector<::types::global_dof_index> dof_indices(
3563 dealii_cell->
get_fe().dofs_per_cell);
3564 dealii_cell->get_mg_dof_indices(dof_indices);
3566 bool complete =
true;
3567 for (
unsigned int i = 0; i < dof_indices.size(); ++i)
3571 (dof_indices[i] == dofs[i]),
3573 dof_indices[i] = dofs[i];
3580 typename DoFHandler<dim, spacedim>::level_cell_iterator &
>(
3585 typename DoFHandler<dim, spacedim>::level_cell_iterator &
>(
3587 ->clear_user_flag();
3590 typename DoFHandler<dim, spacedim>::level_cell_iterator &
>(
3592 ->set_mg_dof_indices(dof_indices);
3596 if (!dealii_cell->has_children())
3599 if (!internal::p4est::quadrant_is_ancestor<dim>(p4est_cell, quadrant))
3602 typename ::internal::p4est::types<dim>::quadrant
3604 internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
3606 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
3608 set_mg_dofindices_recursively<dim, spacedim>(
3609 tria, p4est_child[c], dealii_cell->child(c), quadrant, dofs);
3614 template <
int dim,
int spacedim,
class DoFHandlerType>
3616 communicate_mg_ghost_cells(
3619 DoFHandlerType &dof_handler,
3620 const std::vector<::types::global_dof_index>
3621 &coarse_cell_to_p4est_tree_permutation,
3622 const std::vector<::types::global_dof_index>
3623 &p4est_tree_to_coarse_cell_permutation)
3626 std::set<::types::subdomain_id> level_ghost_owners =
3629 std::map<::types::subdomain_id, CellDataTransferBuffer<dim>>;
3630 cellmap_t neighbor_cell_list;
3631 for (std::set<::types::subdomain_id>::iterator it =
3632 level_ghost_owners.begin();
3633 it != level_ghost_owners.end();
3635 neighbor_cell_list.insert(
3636 std::make_pair(*it, CellDataTransferBuffer<dim>()));
3638 for (
typename DoFHandlerType::level_cell_iterator cell =
3639 dof_handler.
begin(0);
3640 cell != dof_handler.
end(0);
3643 typename ::internal::p4est::types<dim>::quadrant
3645 internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
3647 find_marked_mg_ghost_cells_recursively<dim, spacedim>(
3649 coarse_cell_to_p4est_tree_permutation[cell->index()],
3652 neighbor_cell_list);
3654 Assert(level_ghost_owners.size() == neighbor_cell_list.size(),
3658 std::vector<std::vector<char>> sendbuffers(level_ghost_owners.size());
3659 std::vector<MPI_Request> requests(level_ghost_owners.size());
3661 unsigned int idx = 0;
3662 for (
typename cellmap_t::iterator it = neighbor_cell_list.begin();
3663 it != neighbor_cell_list.end();
3669 sendbuffers[idx] = it->second.pack_data();
3670 const int ierr = MPI_Isend(sendbuffers[idx].data(),
3671 sendbuffers[idx].size(),
3681 std::vector<std::vector<char>> reply_buffers(
3682 level_ghost_owners.size());
3683 std::vector<MPI_Request> reply_requests(level_ghost_owners.size());
3685 for (
unsigned int idx = 0; idx < level_ghost_owners.size(); ++idx)
3687 std::vector<char> receive;
3688 CellDataTransferBuffer<dim> cell_data_transfer_buffer;
3692 int ierr = MPI_Probe(MPI_ANY_SOURCE,
3697 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
3699 receive.resize(len);
3701 char *ptr = receive.data();
3702 ierr = MPI_Recv(ptr,
3711 cell_data_transfer_buffer.unpack_data(receive);
3714 for (
unsigned int c = 0;
3715 c < cell_data_transfer_buffer.tree_indices.size();
3718 typename DoFHandlerType::level_cell_iterator cell(
3719 &dof_handler.get_triangulation(),
3721 p4est_tree_to_coarse_cell_permutation
3722 [cell_data_transfer_buffer.tree_indices[c]],
3725 typename ::internal::p4est::types<dim>::quadrant
3727 internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
3729 get_mg_dofindices_recursively<dim, spacedim>(
3733 cell_data_transfer_buffer.quadrants[c],
3734 cell_data_transfer_buffer);
3738 reply_buffers[idx] = cell_data_transfer_buffer.pack_data();
3739 ierr = MPI_Isend(&(reply_buffers[idx])[0],
3740 reply_buffers[idx].size(),
3745 &reply_requests[idx]);
3750 for (
unsigned int idx = 0; idx < level_ghost_owners.size(); ++idx)
3752 std::vector<char> receive;
3753 CellDataTransferBuffer<dim> cell_data_transfer_buffer;
3757 int ierr = MPI_Probe(MPI_ANY_SOURCE,
3762 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
3764 receive.resize(len);
3766 char *ptr = receive.data();
3767 ierr = MPI_Recv(ptr,
3776 cell_data_transfer_buffer.unpack_data(receive);
3777 if (cell_data_transfer_buffer.tree_indices.size() == 0)
3782 cell_data_transfer_buffer.dof_numbers_and_indices.data();
3783 for (
unsigned int c = 0;
3784 c < cell_data_transfer_buffer.tree_indices.size();
3785 ++c, dofs += 1 + dofs[0])
3787 typename DoFHandlerType::level_cell_iterator cell(
3790 p4est_tree_to_coarse_cell_permutation
3791 [cell_data_transfer_buffer.tree_indices[c]],
3794 typename ::internal::p4est::types<dim>::quadrant
3796 internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
3798 Assert(cell->get_fe().dofs_per_cell == dofs[0],
3801 set_mg_dofindices_recursively<dim, spacedim>(
3805 cell_data_transfer_buffer.quadrants[c],
3812 if (requests.size() > 0)
3814 const int ierr = MPI_Waitall(requests.size(),
3816 MPI_STATUSES_IGNORE);
3819 if (reply_requests.size() > 0)
3821 const int ierr = MPI_Waitall(reply_requests.size(),
3822 reply_requests.data(),
3823 MPI_STATUSES_IGNORE);
3830 template <
int spacedim>
3832 communicate_mg_ghost_cells(
3835 const std::vector<::types::global_dof_index> &,
3836 const std::vector<::types::global_dof_index> &)
3843 template <
int spacedim>
3845 communicate_mg_ghost_cells(
3848 const std::vector<::types::global_dof_index> &,
3849 const std::vector<::types::global_dof_index> &)
3874 template <
int spacedim>
3876 communicate_dof_indices_on_marked_cells(
3878 const std::map<
unsigned int, std::set<::types::subdomain_id>> &,
3879 const std::vector<::types::global_dof_index> &,
3880 const std::vector<::types::global_dof_index> &)
3887 template <
int spacedim>
3889 communicate_dof_indices_on_marked_cells(
3891 const std::map<
unsigned int, std::set<::types::subdomain_id>> &,
3892 const std::vector<::types::global_dof_index> &,
3893 const std::vector<::types::global_dof_index> &)
3900 template <
class DoFHandlerType>
3902 communicate_dof_indices_on_marked_cells(
3903 const DoFHandlerType &dof_handler,
3904 const std::map<
unsigned int, std::set<::types::subdomain_id>> &,
3905 const std::vector<::types::global_dof_index> &,
3906 const std::vector<::types::global_dof_index> &)
3908 # ifndef DEAL_II_WITH_MPI 3909 (void)vertices_with_ghost_neighbors;
3912 const unsigned int dim = DoFHandlerType::dimension;
3913 const unsigned int spacedim = DoFHandlerType::space_dimension;
3919 [](
const typename DoFHandlerType::active_cell_iterator &cell)
3920 -> boost::optional<std::vector<types::global_dof_index>> {
3927 if (cell->user_flag_set())
3930 std::vector<types::global_dof_index> local_dof_indices(
3931 cell->
get_fe().dofs_per_cell);
3932 cell->get_dof_indices(local_dof_indices);
3941 if (std::find(local_dof_indices.begin(),
3942 local_dof_indices.end(),
3944 local_dof_indices.end())
3949 cell->clear_user_flag();
3951 return local_dof_indices;
3960 std::vector<types::global_dof_index> local_dof_indices(
3961 cell->
get_fe().dofs_per_cell);
3962 cell->get_dof_indices(local_dof_indices);
3964 const bool is_complete =
3965 (std::find(local_dof_indices.begin(),
3966 local_dof_indices.end(),
3968 local_dof_indices.end());
3971 return boost::optional<std::vector<types::global_dof_index>>();
3976 [](
const typename DoFHandlerType::active_cell_iterator &cell,
3977 const std::vector<types::global_dof_index> &received_dof_indices)
3993 const bool is_complete = (std::find(received_dof_indices.begin(),
3994 received_dof_indices.end(),
3996 received_dof_indices.end());
3998 cell->clear_user_flag();
4012 std::vector<types::global_dof_index> local_dof_indices(
4013 cell->get_fe().dofs_per_cell);
4014 cell->update_cell_dof_indices_cache();
4015 cell->get_dof_indices(local_dof_indices);
4017 for (
unsigned int i = 0; i < local_dof_indices.size(); ++i)
4019 local_dof_indices[i] = received_dof_indices[i];
4023 Assert((received_dof_indices[i] ==
4025 (received_dof_indices[i] == local_dof_indices[i]),
4028 const_cast<typename DoFHandlerType::active_cell_iterator &
>(cell)
4029 ->set_dof_indices(local_dof_indices);
4033 std::vector<types::global_dof_index>,
4038 update_all_active_cell_dof_indices_caches(dof_handler);
4054 if (
const auto *triangulation =
dynamic_cast< 4056 &dof_handler.get_triangulation()))
4058 const int ierr = MPI_Barrier(triangulation->get_communicator());
4065 "The function communicate_dof_indices_on_marked_cells() " 4066 "only works with parallel distributed triangulations."));
4075 #endif // DEAL_II_WITH_P4EST 4079 template <
class DoFHandlerType>
4081 DoFHandlerType &dof_handler)
4082 : dof_handler(&dof_handler)
4087 template <
class DoFHandlerType>
4091 #ifndef DEAL_II_WITH_P4EST 4095 const unsigned int dim = DoFHandlerType::dimension;
4096 const unsigned int spacedim = DoFHandlerType::space_dimension;
4104 const unsigned int n_cpus =
4127 const ::types::global_dof_index n_initial_local_dofs =
4128 Implementation::distribute_dofs(
4135 std::vector<::types::global_dof_index> renumbering(
4136 n_initial_local_dofs);
4141 std::vector<::types::global_dof_index> local_dof_indices;
4144 if (cell->is_ghost() && (cell->subdomain_id() <
4153 local_dof_indices.resize(cell->
get_fe().dofs_per_cell);
4154 cell->get_dof_indices(local_dof_indices);
4155 for (
auto &local_dof_index : local_dof_indices)
4164 for (
auto &new_index : renumbering)
4166 new_index = n_locally_owned_dofs++;
4170 std::vector<::types::global_dof_index>
4171 n_locally_owned_dofs_per_processor(n_cpus);
4174 MPI_Allgather(&n_locally_owned_dofs,
4176 DEAL_II_DOF_INDEX_MPI_TYPE,
4177 n_locally_owned_dofs_per_processor.data(),
4179 DEAL_II_DOF_INDEX_MPI_TYPE,
4183 const ::types::global_dof_index my_shift =
4184 std::accumulate(n_locally_owned_dofs_per_processor.begin(),
4185 n_locally_owned_dofs_per_processor.begin() +
4188 for (
auto &new_index : renumbering)
4190 new_index += my_shift;
4195 Implementation::renumber_dofs(renumbering,
4201 const ::types::global_dof_index n_global_dofs =
4202 std::accumulate(n_locally_owned_dofs_per_processor.begin(),
4203 n_locally_owned_dofs_per_processor.end(),
4206 std::vector<IndexSet> locally_owned_dofs_per_processor(
4210 for (
unsigned int i = 0; i < n_cpus; ++i)
4212 locally_owned_dofs_per_processor[i].add_range(
4214 current_shift + n_locally_owned_dofs_per_processor[i]);
4215 current_shift += n_locally_owned_dofs_per_processor[i];
4218 NumberCache number_cache(locally_owned_dofs_per_processor,
4221 .locally_owned_dofs_per_processor
4223 .n_elements() == number_cache.n_locally_owned_dofs,
4227 .locally_owned_dofs_per_processor[triangulation
4228 ->locally_owned_subdomain()]
4231 .locally_owned_dofs_per_processor[triangulation
4232 ->locally_owned_subdomain()]
4233 .nth_index_in_set(0) == my_shift,
4244 std::vector<bool> user_flags;
4250 const std::map<unsigned int, std::set<::types::subdomain_id>>
4251 vertices_with_ghost_neighbors =
4258 if (cell->is_locally_owned())
4260 for (
unsigned int v = 0;
4261 v < GeometryInfo<dim>::vertices_per_cell;
4263 if (vertices_with_ghost_neighbors.find(cell->vertex_index(
4264 v)) != vertices_with_ghost_neighbors.end())
4266 cell->set_user_flag();
4270 else if (cell->is_ghost())
4271 cell->set_user_flag();
4281 communicate_dof_indices_on_marked_cells(
4283 vertices_with_ghost_neighbors,
4285 triangulation->p4est_tree_to_coarse_cell_permutation);
4287 communicate_dof_indices_on_marked_cells(
4289 vertices_with_ghost_neighbors,
4291 triangulation->p4est_tree_to_coarse_cell_permutation);
4306 std::vector<::types::global_dof_index> local_dof_indices;
4309 if (!cell->is_artificial())
4311 local_dof_indices.resize(cell->
get_fe().dofs_per_cell);
4312 cell->get_dof_indices(local_dof_indices);
4313 if (local_dof_indices.end() !=
4314 std::find(local_dof_indices.begin(),
4315 local_dof_indices.end(),
4318 if (cell->is_ghost())
4322 "A ghost cell ended up with incomplete " 4323 "DoF index information. This should not " 4331 "A locally owned cell ended up with incomplete " 4332 "DoF index information. This should not " 4339 return number_cache;
4340 #endif // DEAL_II_WITH_P4EST 4345 template <
class DoFHandlerType>
4346 std::vector<NumberCache>
4349 #ifndef DEAL_II_WITH_P4EST 4351 return std::vector<NumberCache>();
4353 const unsigned int dim = DoFHandlerType::dimension;
4354 const unsigned int spacedim = DoFHandlerType::space_dimension;
4364 construct_multigrid_hierarchy),
4366 "Multigrid DoFs can only be distributed on a parallel " 4367 "Triangulation if the flag construct_multigrid_hierarchy " 4368 "is set in the constructor."));
4371 const unsigned int n_cpus =
4380 std::vector<NumberCache> number_caches;
4381 number_caches.reserve(n_levels);
4382 for (
unsigned int level = 0; level < n_levels; ++level)
4387 const unsigned int n_initial_local_dofs =
4388 Implementation::distribute_dofs_on_level(
4393 std::vector<::types::global_dof_index> renumbering(
4394 n_initial_local_dofs);
4399 if (level < triangulation->n_levels())
4401 std::vector<::types::global_dof_index> local_dof_indices;
4403 typename DoFHandlerType::level_cell_iterator
4404 cell = dof_handler->
begin(level),
4405 endc = dof_handler->
end(level);
4407 for (; cell != endc; ++cell)
4408 if (cell->level_subdomain_id() !=
4410 (cell->level_subdomain_id() <
4420 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
4421 cell->get_mg_dof_indices(local_dof_indices);
4422 for (
unsigned int i = 0; i < cell->get_fe().dofs_per_cell;
4425 renumbering[local_dof_indices[i]] =
4433 for (std::vector<::types::global_dof_index>::iterator it =
4434 renumbering.begin();
4435 it != renumbering.end();
4445 int ierr = MPI_Allgather(
4448 DEAL_II_DOF_INDEX_MPI_TYPE,
4451 DEAL_II_DOF_INDEX_MPI_TYPE,
4455 const ::types::global_dof_index shift = std::accumulate(
4460 for (std::vector<::types::global_dof_index>::iterator it =
4461 renumbering.begin();
4462 it != renumbering.end();
4475 if (level < triangulation->n_levels())
4476 Implementation::renumber_mg_dofs(
4495 for (
unsigned int i = 0; i < n_cpus; ++i)
4500 .add_range(current_shift,
4503 .n_locally_owned_dofs_per_processor[i]);
4508 Assert(level_number_cache
4509 .locally_owned_dofs_per_processor
4513 Assert(!level_number_cache
4514 .locally_owned_dofs_per_processor
4520 .nth_index_in_set(0) == shift,
4523 number_caches.emplace_back(level_number_cache);
4532 std::vector<bool> user_flags;
4538 typename DoFHandlerType::level_cell_iterator cell,
4539 endc = dof_handler->
end();
4540 for (cell = dof_handler->
begin(); cell != endc; ++cell)
4541 if (cell->level_subdomain_id() !=
4542 ::numbers::artificial_subdomain_id &&
4543 !cell->is_locally_owned_on_level())
4544 cell->set_user_flag();
4550 communicate_mg_ghost_cells(
4554 triangulation->p4est_tree_to_coarse_cell_permutation);
4574 communicate_mg_ghost_cells(
4578 triangulation->p4est_tree_to_coarse_cell_permutation);
4583 typename DoFHandlerType::level_cell_iterator cell,
4584 endc = dof_handler->
end();
4585 for (cell = dof_handler->
begin(); cell != endc; ++cell)
4586 if (cell->level_subdomain_id() !=
4587 ::numbers::artificial_subdomain_id &&
4588 !cell->is_locally_owned_on_level())
4601 std::vector<::types::global_dof_index> local_dof_indices;
4602 typename DoFHandlerType::level_cell_iterator cell,
4603 endc = dof_handler->
end();
4605 for (cell = dof_handler->
begin(); cell != endc; ++cell)
4606 if (cell->level_subdomain_id() !=
4607 ::numbers::artificial_subdomain_id)
4609 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
4610 cell->get_mg_dof_indices(local_dof_indices);
4611 if (local_dof_indices.end() !=
4612 std::find(local_dof_indices.begin(),
4613 local_dof_indices.end(),
4622 return number_caches;
4624 #endif // DEAL_II_WITH_P4EST 4628 template <
class DoFHandlerType>
4631 const std::vector<::types::global_dof_index> &new_numbers)
const 4638 #ifndef DEAL_II_WITH_P4EST 4642 const unsigned int dim = DoFHandlerType::dimension;
4643 const unsigned int spacedim = DoFHandlerType::space_dimension;
4660 IndexSet my_locally_owned_new_dof_indices(dof_handler->
n_dofs());
4663 std::vector<::types::global_dof_index> new_numbers_sorted =
4665 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
4667 my_locally_owned_new_dof_indices.add_indices(
4668 new_numbers_sorted.begin(), new_numbers_sorted.end());
4669 my_locally_owned_new_dof_indices.compress();
4671 Assert(my_locally_owned_new_dof_indices.n_elements() ==
4688 std::vector<::types::global_dof_index> local_dof_indices;
4691 if (cell->is_ghost())
4693 local_dof_indices.resize(cell->
get_fe().dofs_per_cell);
4694 cell->get_dof_indices(local_dof_indices);
4696 for (
unsigned int i = 0; i < cell->
get_fe().dofs_per_cell; ++i)
4702 local_dof_indices[i])))
4705 cell->set_dof_indices(local_dof_indices);
4712 Implementation::renumber_dofs(new_numbers,
4722 std::vector<bool> user_flags;
4728 if (!cell->is_artificial())
4729 cell->set_user_flag();
4733 const std::map<unsigned int, std::set<::types::subdomain_id>>
4734 vertices_with_ghost_neighbors =
4744 communicate_dof_indices_on_marked_cells(
4746 vertices_with_ghost_neighbors,
4748 triangulation->p4est_tree_to_coarse_cell_permutation);
4750 communicate_dof_indices_on_marked_cells(
4752 vertices_with_ghost_neighbors,
4754 triangulation->p4est_tree_to_coarse_cell_permutation);
4769 const unsigned int n_cpus =
4771 std::vector<IndexSet> locally_owned_dofs_per_processor(
4775 std::vector<char> my_data;
4777 # ifdef DEAL_II_WITH_ZLIB 4779 boost::iostreams::filtering_ostream out;
4781 boost::iostreams::gzip_compressor(boost::iostreams::gzip_params(
4782 boost::iostreams::gzip::best_compression)));
4783 out.push(boost::iostreams::back_inserter(my_data));
4785 boost::archive::binary_oarchive archive(out);
4787 archive << my_locally_owned_new_dof_indices;
4790 std::ostringstream out;
4791 boost::archive::binary_oarchive archive(out);
4792 archive << my_locally_owned_new_dof_indices;
4793 const std::string &s = out.str();
4794 my_data.reserve(s.size());
4795 my_data.assign(s.begin(), s.end());
4800 const unsigned int max_size =
4807 my_data.resize(max_size);
4809 std::vector<char> buffer(max_size * n_cpus);
4810 const int ierr = MPI_Allgather(my_data.data(),
4819 for (
unsigned int i = 0; i < n_cpus; ++i)
4822 locally_owned_dofs_per_processor[i] =
4823 my_locally_owned_new_dof_indices;
4828 std::string decompressed_buffer;
4832 # ifdef DEAL_II_WITH_ZLIB 4834 boost::iostreams::filtering_ostream decompressing_stream;
4835 decompressing_stream.push(
4836 boost::iostreams::gzip_decompressor());
4837 decompressing_stream.push(
4838 boost::iostreams::back_inserter(decompressed_buffer));
4840 decompressing_stream.write(&buffer[i * max_size], max_size);
4842 decompressed_buffer.assign(&buffer[i * max_size], max_size);
4847 std::istringstream in(decompressed_buffer);
4848 boost::archive::binary_iarchive archive(in);
4850 archive >> locally_owned_dofs_per_processor[i];
4854 return NumberCache(locally_owned_dofs_per_processor,
4862 template <
class DoFHandlerType>
4865 const unsigned int level,
4866 const std::vector<types::global_dof_index> &new_numbers)
const 4871 const std::vector<IndexSet> &index_sets =
4874 constexpr
int dim = DoFHandlerType::dimension;
4875 constexpr
int spacedim = DoFHandlerType::space_dimension;
4881 #ifdef DEAL_II_WITH_MPI 4882 const unsigned int my_rank =
4888 Assert(index_sets[my_rank].is_element(i),
4890 "Renumberings that change the locally owned mg dofs " 4891 "partitioning are currently not implemented for " 4892 "the multigrid levels"));
4903 std::vector<types::global_dof_index> ghosted_new_numbers(
4909 std::vector<types::global_dof_index> temp_array(
4910 partitioner.n_import_indices());
4911 const unsigned int communication_channel = 17;
4912 std::vector<MPI_Request> requests;
4914 communication_channel,
4915 make_array_view(new_numbers),
4916 make_array_view(temp_array),
4919 partitioner.n_ghost_indices()),
4921 partitioner.export_to_ghosted_array_finish(
4924 partitioner.n_ghost_indices()),
4931 unsigned int n_ghosts_on_smaller_ranks = 0;
4932 for (std::pair<unsigned int, unsigned int> t :
4933 partitioner.ghost_targets())
4935 if (t.first > my_rank)
4937 n_ghosts_on_smaller_ranks += t.second;
4939 if (n_ghosts_on_smaller_ranks > 0)
4942 std::memmove(ghosted_new_numbers.data(),
4943 ghosted_new_numbers.data() + new_numbers.size(),
4945 n_ghosts_on_smaller_ranks);
4947 if (new_numbers.size() > 0)
4950 std::memcpy(ghosted_new_numbers.data() +
4951 n_ghosts_on_smaller_ranks,
4960 Implementation::renumber_mg_dofs(
4961 ghosted_new_numbers, relevant_dofs, *dof_handler, level,
true);
4977 #include "dof_handler_policy.inst" 4980 DEAL_II_NAMESPACE_CLOSE
std::vector< MGVertexDoFs > mg_vertex_dofs
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const override
static const unsigned int invalid_unsigned_int
active_cell_iterator begin_active(const unsigned int level=0) const
const types::subdomain_id invalid_subdomain_id
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
types::subdomain_id locally_owned_subdomain() const override
Task< RT > new_task(const std::function< RT()> &function)
virtual NumberCache distribute_dofs() const override
const std::vector< types::subdomain_id > & get_true_subdomain_ids_of_cells() const
void load_user_flags(std::istream &in)
IndexSet locally_owned_dofs
const unsigned int dofs_per_quad
size_type n_elements() const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
void export_to_ghosted_array_start(const unsigned int communication_channel, const ArrayView< const Number > &locally_owned_array, const ArrayView< Number > &temporary_storage, const ArrayView< Number > &ghost_array, std::vector< MPI_Request > &requests) const
#define AssertThrow(cond, exc)
const Triangulation< dim, spacedim > & get_triangulation() const
const unsigned int dofs_per_line
unsigned int n_active_cells() const
unsigned long long int global_dof_index
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
virtual std::vector< NumberCache > distribute_mg_dofs() const override
active_cell_iterator begin_active(const unsigned int level=0) const
typename ActiveSelector::active_cell_iterator active_cell_iterator
const std::set< types::subdomain_id > & level_ghost_owners() const
types::global_dof_index n_locally_owned_dofs
virtual MPI_Comm get_communicator() const
virtual std::vector< NumberCache > distribute_mg_dofs() const override
static::ExceptionBase & ExcMessage(std::string arg1)
ParallelDistributed(DoFHandlerType &dof_handler)
virtual std::vector< NumberCache > distribute_mg_dofs() const override
unsigned int subdomain_id
unsigned int n_cells() const
virtual NumberCache distribute_dofs() const override
const Triangulation< dim, spacedim > & get_triangulation() const
virtual NumberCache distribute_dofs() const override
const unsigned int dofs_per_hex
#define Assert(cond, exc)
types::global_dof_index n_dofs() const
void save_user_flags(std::ostream &out) const
Sequential(DoFHandlerType &dof_handler)
bool with_artificial_cells() const
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const override
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const override
unsigned int n_locally_owned_dofs() const
std::vector< types::global_dof_index > n_locally_owned_dofs_per_processor
virtual unsigned int n_global_levels() const override
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const override
const hp::FECollection< dim, spacedim > & get_fe() const
std::unique_ptr<::internal::DoFHandlerImplementation::DoFFaces< dim > > faces
cell_iterator end() const
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
std::vector< std::unique_ptr<::internal::DoFHandlerImplementation::DoFLevel< dim > > > levels
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
void add_range(const size_type begin, const size_type end)
const types::subdomain_id artificial_subdomain_id
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const override
const std::vector< IndexSet > & locally_owned_mg_dofs_per_processor(const unsigned int level) const
cell_iterator begin(const unsigned int level=0) const
cell_iterator end() const
#define AssertThrowMPI(error_code)
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
virtual FiniteElementDomination::Domination compare_for_face_domination(const FiniteElement< dim, spacedim > &fe_other) const
hp::FECollection< dim, spacedim > fe_collection
SmartPointer< DoFHandlerType > dof_handler
size_type index_within_set(const size_type global_index) const
std::vector< IndexSet > locally_owned_dofs_per_processor
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
bool is_element(const size_type index) const
static::ExceptionBase & ExcNotImplemented()
const hp::FECollection< dim, spacedim > & get_fe_collection() const
Iterator points to a valid object.
const unsigned int dofs_per_vertex
void run(const std::vector< std::vector< Iterator >> &colored_iterators, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length=2 *MultithreadInfo::n_threads(), const unsigned int chunk_size=8)
static unsigned int n_threads()
ParallelShared(DoFHandlerType &dof_handler)
typename ActiveSelector::cell_iterator cell_iterator
types::global_dof_index n_global_dofs
active_cell_iterator begin_active(const unsigned int level=0) const
typename ActiveSelector::active_cell_iterator active_cell_iterator
const types::global_dof_index invalid_dof_index
const IndexSet & locally_owned_dofs() const
size_type nth_index_in_set(const unsigned int local_index) const
const std::vector< IndexSet > & locally_owned_dofs_per_processor() const
IteratorRange< active_cell_iterator > active_cell_iterators() const
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const override
T max(const T &t, const MPI_Comm &mpi_communicator)
const std::vector< types::subdomain_id > & get_true_level_subdomain_ids_of_cells(const unsigned int level) const
std::vector< types::global_dof_index > vertex_dofs
std::vector< types::global_dof_index > coarse_cell_to_p4est_tree_permutation
SmartPointer< DoFHandlerType > dof_handler
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
static::ExceptionBase & ExcInternalError()
virtual std::map< unsigned int, std::set<::types::subdomain_id > > compute_vertices_with_ghost_neighbors() const override