17 #include <deal.II/base/geometry_info.h> 18 #include <deal.II/base/work_stream.h> 19 #include <deal.II/base/utilities.h> 20 #include <deal.II/base/memory_consumption.h> 21 #include <deal.II/base/thread_management.h> 22 #include <deal.II/base/partitioner.h> 23 #include <deal.II/grid/grid_tools.h> 24 #include <deal.II/grid/tria.h> 25 #include <deal.II/grid/tria_iterator.h> 26 #include <deal.II/dofs/dof_handler.h> 27 #include <deal.II/dofs/dof_accessor.h> 28 #include <deal.II/dofs/dof_handler_policy.h> 29 #include <deal.II/fe/fe.h> 30 #include <deal.II/distributed/shared_tria.h> 31 #include <deal.II/distributed/tria.h> 33 #include <boost/archive/binary_oarchive.hpp> 34 #include <boost/archive/binary_iarchive.hpp> 35 #ifdef DEAL_II_WITH_ZLIB 36 #include <boost/iostreams/stream.hpp> 37 #include <boost/iostreams/filtering_stream.hpp> 38 #include <boost/iostreams/device/back_inserter.hpp> 39 #include <boost/iostreams/filter/gzip.hpp> 40 #include <boost/serialization/array.hpp> 48 DEAL_II_NAMESPACE_OPEN
53 namespace DoFHandlerImplementation
64 using ::hp::DoFHandler;
74 template <
class DoFHandlerType>
76 update_all_active_cell_dof_indices_caches (
const DoFHandlerType &dof_handler)
78 typename DoFHandlerType::active_cell_iterator
79 beginc = dof_handler.begin_active(),
80 endc = dof_handler.end();
83 = [] (
const typename DoFHandlerType::active_cell_iterator &cell,
87 if (!cell->is_artificial())
88 cell->update_cell_dof_indices_cache ();
99 std::function<
void (
void *)>(),
111 template <
class DoFHandlerType>
113 update_all_level_cell_dof_indices_caches (
const DoFHandlerType &dof_handler)
115 typename DoFHandlerType::level_cell_iterator
116 beginc = dof_handler.begin(),
117 endc = dof_handler.end();
120 = [] (
const typename DoFHandlerType::level_cell_iterator &cell,
124 if (cell->has_children()
125 || !cell->is_artificial())
126 cell->update_cell_dof_indices_cache ();
137 std::function<
void (
void *)>(),
146 std::vector<std::pair<unsigned int, unsigned int> > DoFIdentities;
159 template <
int structdim,
int dim,
int spacedim>
163 std::unique_ptr<DoFIdentities> &identities)
167 if (identities.get() ==
nullptr)
173 identities = std_cxx14::make_unique<DoFIdentities>
180 identities = std_cxx14::make_unique<DoFIdentities>
187 identities = std_cxx14::make_unique<DoFIdentities>
198 for (
unsigned int i=0; i<identities->size(); ++i)
200 Assert ((*identities)[i].first < fe1.template n_dofs_per_object<structdim>(),
202 Assert ((*identities)[i].second < fe2.template n_dofs_per_object<structdim>(),
217 template <
int dim,
int spacedim,
typename iterator>
219 get_most_dominating_fe_index (
const iterator &
object)
221 unsigned int dominating_fe_index = 0;
222 for (; dominating_fe_index<
object->n_active_fe_indices();
223 ++dominating_fe_index)
226 =
object->get_fe (object->nth_active_fe_index(dominating_fe_index));
230 for (
unsigned int other_fe_index=0;
231 other_fe_index<
object->n_active_fe_indices();
233 if (other_fe_index != dominating_fe_index)
237 =
object->get_fe (object->nth_active_fe_index(other_fe_index));
239 domination = domination &
254 if (dominating_fe_index != object->n_active_fe_indices())
258 return object->nth_active_fe_index(dominating_fe_index);
270 struct Implementation
282 template <
int spacedim>
291 if (dof_handler.
get_fe().dofs_per_vertex > 0)
292 for (
unsigned int v=0; v<GeometryInfo<1>::vertices_per_cell; ++v)
295 for (
unsigned int d=0;
d<dof_handler.
get_fe().dofs_per_vertex; ++
d)
297 Assert ((cell->vertex_dof_index (v,d) ==
300 cell->set_vertex_dof_index (v, d, next_free_dof++);
303 for (
unsigned int d=0;
d<dof_handler.
get_fe().dofs_per_vertex; ++
d)
304 Assert ((cell->vertex_dof_index (v,d) !=
310 for (
unsigned int d=0;
d<dof_handler.
get_fe().dofs_per_line; ++
d)
311 cell->set_dof_index (d, next_free_dof++);
313 return next_free_dof;
318 template <
int spacedim>
325 if (dof_handler.
get_fe().dofs_per_vertex > 0)
327 for (
unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_cell; ++vertex)
331 for (
unsigned int d=0;
d<dof_handler.
get_fe().dofs_per_vertex; ++
d)
332 cell->set_vertex_dof_index (vertex, d, next_free_dof++);
335 if (dof_handler.
get_fe().dofs_per_line > 0)
336 for (
unsigned int side=0; side<GeometryInfo<2>::faces_per_cell; ++side)
338 const typename DoFHandler<2,spacedim>::line_iterator
339 line = cell->line(side);
345 for (
unsigned int d=0;
d<dof_handler.
get_fe().dofs_per_line; ++
d)
346 line->set_dof_index (d, next_free_dof++);
351 if (dof_handler.
get_fe().dofs_per_quad > 0)
352 for (
unsigned int d=0;
d<dof_handler.
get_fe().dofs_per_quad; ++
d)
353 cell->set_dof_index (d, next_free_dof++);
355 return next_free_dof;
360 template <
int spacedim>
367 if (dof_handler.
get_fe().dofs_per_vertex > 0)
369 for (
unsigned int vertex=0; vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
373 for (
unsigned int d=0;
d<dof_handler.
get_fe().dofs_per_vertex; ++
d)
374 cell->set_vertex_dof_index (vertex, d, next_free_dof++);
377 if (dof_handler.
get_fe().dofs_per_line > 0)
378 for (
unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++
l)
380 const typename DoFHandler<3,spacedim>::line_iterator
381 line = cell->line(l);
387 for (
unsigned int d=0;
d<dof_handler.
get_fe().dofs_per_line; ++
d)
388 line->set_dof_index (d, next_free_dof++);
392 if (dof_handler.
get_fe().dofs_per_quad > 0)
393 for (
unsigned int q=0; q<GeometryInfo<3>::quads_per_cell; ++q)
395 const typename DoFHandler<3,spacedim>::quad_iterator
396 quad = cell->quad(q);
402 for (
unsigned int d=0;
d<dof_handler.
get_fe().dofs_per_quad; ++
d)
403 quad->set_dof_index (d, next_free_dof++);
408 if (dof_handler.
get_fe().dofs_per_hex > 0)
409 for (
unsigned int d=0;
d<dof_handler.
get_fe().dofs_per_hex; ++
d)
410 cell->set_dof_index (d, next_free_dof++);
412 return next_free_dof;
418 template <
int spacedim>
425 const unsigned int dim = 1;
428 const unsigned int fe_index = cell->active_fe_index ();
435 for (
unsigned int vertex=0; vertex<GeometryInfo<1>::vertices_per_cell; ++vertex)
436 if (cell->vertex_dof_index(vertex, 0, fe_index) ==
439 cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
444 Assert ((cell->dof_index(0, fe_index) ==
449 cell->set_dof_index (d, next_free_dof, fe_index);
453 cell->set_user_flag ();
455 return next_free_dof;
460 template <
int spacedim>
467 const unsigned int dim = 2;
470 const unsigned int fe_index = cell->active_fe_index ();
477 for (
unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_cell; ++vertex)
478 if (cell->vertex_dof_index(vertex, 0, fe_index) ==
481 cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
487 for (
unsigned int l=0; l<GeometryInfo<2>::lines_per_cell; ++
l)
489 typename hp::DoFHandler<dim,spacedim>::line_iterator
490 line = cell->line(l);
492 if (line->dof_index(0,fe_index) ==
495 line->set_dof_index (d, next_free_dof, fe_index);
502 Assert ((cell->dof_index(0, fe_index) ==
507 cell->set_dof_index (d, next_free_dof, fe_index);
511 cell->set_user_flag ();
513 return next_free_dof;
518 template <
int spacedim>
525 const unsigned int dim = 3;
528 const unsigned int fe_index = cell->active_fe_index ();
535 for (
unsigned int vertex=0; vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
536 if (cell->vertex_dof_index(vertex, 0, fe_index) ==
539 cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
545 for (
unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++
l)
547 typename hp::DoFHandler<dim,spacedim>::line_iterator
548 line = cell->line(l);
550 if (line->dof_index(0,fe_index) ==
553 line->set_dof_index (d, next_free_dof, fe_index);
558 for (
unsigned int q=0; q<GeometryInfo<3>::quads_per_cell; ++q)
560 typename hp::DoFHandler<dim,spacedim>::quad_iterator
561 quad = cell->quad(q);
563 if (quad->dof_index(0,fe_index) ==
566 quad->set_dof_index (d, next_free_dof, fe_index);
573 Assert ((cell->dof_index(0, fe_index) ==
578 cell->set_dof_index (d, next_free_dof, fe_index);
582 cell->set_user_flag ();
584 return next_free_dof;
593 template <
int dim,
int spacedim>
595 std::map<types::global_dof_index, types::global_dof_index>
598 std::map<types::global_dof_index, types::global_dof_index> dof_identities;
625 std::vector<bool> include_vertex = dof_handler.
get_triangulation().get_used_vertices();
630 if (! cell->is_locally_owned())
631 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
632 include_vertex[cell->vertex_index(v)] =
false;
636 for (
unsigned int vertex_index=0; vertex_index<dof_handler.
get_triangulation().n_vertices();
640 (include_vertex[vertex_index] ==
true))
642 const unsigned int n_active_fe_indices
643 = ::internal::DoFAccessorImplementation::Implementation::
644 n_active_vertex_fe_indices (dof_handler, vertex_index);
645 if (n_active_fe_indices > 1)
649 = ::internal::DoFAccessorImplementation::Implementation::
650 nth_active_vertex_fe_index (dof_handler, vertex_index, 0);
654 for (
unsigned int f=1; f<n_active_fe_indices; ++f)
658 = ::internal::DoFAccessorImplementation::Implementation::
659 nth_active_vertex_fe_index (dof_handler, vertex_index, f);
663 ensure_existence_of_dof_identities<0>
664 (dof_handler.
get_fe(first_fe_index),
665 dof_handler.
get_fe(other_fe_index),
666 vertex_dof_identities[first_fe_index][other_fe_index]);
676 DoFIdentities &identities
677 = *vertex_dof_identities[first_fe_index][other_fe_index];
678 for (
unsigned int i=0; i<identities.size(); ++i)
681 = ::internal::DoFAccessorImplementation::Implementation::
682 get_vertex_dof_index (dof_handler,
685 identities[i].first);
687 = ::internal::DoFAccessorImplementation::Implementation::
688 get_vertex_dof_index (dof_handler,
691 identities[i].second);
693 Assert ((dof_identities.find(higher_dof_index) == dof_identities.end())
695 (dof_identities[higher_dof_index] ==
699 dof_identities[higher_dof_index] = lower_dof_index;
705 return dof_identities;
713 template <
int spacedim>
715 std::map<types::global_dof_index, types::global_dof_index>
718 return std::map<types::global_dof_index, types::global_dof_index>();
722 template <
int dim,
int spacedim>
724 std::map<types::global_dof_index, types::global_dof_index>
727 std::map<types::global_dof_index, types::global_dof_index> dof_identities;
731 std::vector<bool> user_flags;
752 cell!=dof_handler.
end(); ++cell)
753 if (cell->is_locally_owned() ==
false)
754 for (
unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++
l)
755 cell->line(l)->set_user_flag();
779 cell!=dof_handler.
end(); ++cell)
780 for (
unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++
l)
781 if (cell->line(l)->user_flag_set() ==
false)
783 const typename hp::DoFHandler<dim,spacedim>::line_iterator line = cell->line(l);
784 line->set_user_flag ();
786 unsigned int unique_sets_of_dofs
787 = line->n_active_fe_indices();
791 const unsigned int n_active_fe_indices = line->n_active_fe_indices();
792 for (
unsigned int f=0; f<n_active_fe_indices; ++f)
793 for (
unsigned int g=f+1; g<n_active_fe_indices; ++g)
795 const unsigned int fe_index_1 = line->nth_active_fe_index (f),
796 fe_index_2 = line->nth_active_fe_index (g);
798 if ((dof_handler.
get_fe(fe_index_1).dofs_per_line
800 dof_handler.
get_fe(fe_index_2).dofs_per_line)
802 (dof_handler.
get_fe(fe_index_1).dofs_per_line > 0))
804 ensure_existence_of_dof_identities<1>
805 (dof_handler.
get_fe(fe_index_1),
806 dof_handler.
get_fe(fe_index_2),
807 line_dof_identities[fe_index_1][fe_index_2]);
810 if (line_dof_identities[fe_index_1][fe_index_2]->size()
812 dof_handler.
get_fe(fe_index_1).dofs_per_line)
815 for (; i<dof_handler.
get_fe(fe_index_1).dofs_per_line; ++i)
816 if (((*(line_dof_identities[fe_index_1][fe_index_2]))[i].first != i)
818 ((*(line_dof_identities[fe_index_1][fe_index_2]))[i].second != i))
822 if (i == dof_handler.
get_fe(fe_index_1).dofs_per_line)
829 --unique_sets_of_dofs;
831 for (
unsigned int j=0; j<dof_handler.
get_fe(fe_index_1).dofs_per_line; ++j)
834 = line->dof_index (j, fe_index_1);
836 = line->dof_index (j, fe_index_2);
841 if (dof_identities.find(master_dof_index) != dof_identities.end())
843 Assert (dof_identities.find(dof_identities[master_dof_index])
844 == dof_identities.end(),
847 dof_identities[slave_dof_index]
848 = dof_identities[master_dof_index];
852 Assert ((dof_identities.find(master_dof_index) == dof_identities.end())
854 (dof_identities[slave_dof_index] ==
858 dof_identities[slave_dof_index] = master_dof_index;
874 if ((unique_sets_of_dofs == 2) && (dim == 2))
878 const unsigned int most_dominating_fe_index
879 = get_most_dominating_fe_index<dim,spacedim> (line);
887 const unsigned int n_active_fe_indices
888 = line->n_active_fe_indices ();
893 for (
unsigned int f=0; f<n_active_fe_indices; ++f)
894 if (line->nth_active_fe_index (f) !=
895 most_dominating_fe_index)
898 other_fe_index = line->nth_active_fe_index (f);
900 ensure_existence_of_dof_identities<1>
901 (dof_handler.
get_fe(most_dominating_fe_index),
902 dof_handler.
get_fe(other_fe_index),
903 line_dof_identities[most_dominating_fe_index][other_fe_index]);
905 DoFIdentities &identities
906 = *line_dof_identities[most_dominating_fe_index][other_fe_index];
907 for (
unsigned int i=0; i<identities.size(); ++i)
910 = line->dof_index (identities[i].first, most_dominating_fe_index);
912 = line->dof_index (identities[i].second, other_fe_index);
914 Assert ((dof_identities.find(master_dof_index) == dof_identities.end())
916 (dof_identities[slave_dof_index] ==
920 dof_identities[slave_dof_index] = master_dof_index;
929 .load_user_flags_line(user_flags);
931 return dof_identities;
940 template <
int dim,
int spacedim>
942 std::map<types::global_dof_index, types::global_dof_index>
950 return std::map<types::global_dof_index, types::global_dof_index>();
954 template <
int spacedim>
956 std::map<types::global_dof_index, types::global_dof_index>
961 std::map<types::global_dof_index, types::global_dof_index> dof_identities;
967 std::vector<bool> user_flags;
988 cell!=dof_handler.
end(); ++cell)
989 if (cell->is_locally_owned() ==
false)
990 for (
unsigned int q=0; q<GeometryInfo<dim>::quads_per_cell; ++q)
991 cell->quad(q)->set_user_flag();
1011 cell!=dof_handler.
end(); ++cell)
1012 for (
unsigned int q=0; q<GeometryInfo<dim>::quads_per_cell; ++q)
1013 if ((cell->quad(q)->user_flag_set() ==
false)
1015 (cell->quad(q)->n_active_fe_indices() == 2))
1017 const typename hp::DoFHandler<dim,spacedim>::quad_iterator quad = cell->quad(q);
1018 quad->set_user_flag ();
1022 const unsigned int most_dominating_fe_index
1023 = get_most_dominating_fe_index<dim,spacedim> (quad);
1033 const unsigned int n_active_fe_indices
1034 = quad->n_active_fe_indices ();
1040 for (
unsigned int f=0; f<n_active_fe_indices; ++f)
1041 if (quad->nth_active_fe_index (f) !=
1042 most_dominating_fe_index)
1045 other_fe_index = quad->nth_active_fe_index (f);
1047 ensure_existence_of_dof_identities<2>
1048 (dof_handler.
get_fe(most_dominating_fe_index),
1049 dof_handler.
get_fe(other_fe_index),
1050 quad_dof_identities[most_dominating_fe_index][other_fe_index]);
1052 DoFIdentities &identities
1053 = *quad_dof_identities[most_dominating_fe_index][other_fe_index];
1054 for (
unsigned int i=0; i<identities.size(); ++i)
1057 = quad->dof_index (identities[i].first, most_dominating_fe_index);
1059 = quad->dof_index (identities[i].second, other_fe_index);
1061 Assert ((dof_identities.find(master_dof_index) == dof_identities.end())
1063 (dof_identities[slave_dof_index] ==
1067 dof_identities[slave_dof_index] = master_dof_index;
1075 .load_user_flags_quad(user_flags);
1077 return dof_identities;
1091 template <
int dim,
int spacedim>
1095 const unsigned int n_dofs_before_identification,
1098 return n_dofs_before_identification;
1103 template <
int dim,
int spacedim>
1107 const unsigned int n_dofs_before_identification,
1108 const bool check_validity)
1113 std::map<types::global_dof_index, types::global_dof_index> all_constrained_indices[dim];
1121 all_constrained_indices[i] = compute_vertex_dof_identities (dof_handler);
1129 all_constrained_indices[i] = compute_line_dof_identities (dof_handler);
1138 all_constrained_indices[i] = compute_quad_dof_identities (dof_handler);
1147 std::vector<types::global_dof_index>
1150 for (
const auto &constrained_dof_indices : all_constrained_indices)
1151 for (
const auto &p : constrained_dof_indices)
1155 new_dof_indices[p.first] = p.second;
1162 new_dof_indices[i] = next_free_dof;
1168 for (
const auto &constrained_dof_indices : all_constrained_indices)
1169 for (
const auto &p : constrained_dof_indices)
1174 new_dof_indices[p.first] = new_dof_indices[p.second];
1181 Assert (new_dof_indices[i] < next_free_dof,
1188 renumber_dofs (new_dof_indices,
1194 return next_free_dof;
1205 template <
class DoFHandlerType>
1209 DoFHandlerType &dof_handler)
1211 Assert (dof_handler.get_triangulation().n_levels() > 0,
1217 typename DoFHandlerType::active_cell_iterator
1219 endc = dof_handler.end();
1221 for (; cell != endc; ++cell)
1222 if (! cell->is_artificial())
1227 = Implementation::distribute_dofs_on_cell (dof_handler,
1237 next_free_dof = unify_dof_indices (dof_handler, next_free_dof,
1240 update_all_active_cell_dof_indices_caches (dof_handler);
1242 return next_free_dof;
1257 template <
int dim,
int spacedim>
1260 distribute_mg_dofs_on_cell (
const typename DoFHandler<dim,spacedim>::level_cell_iterator &cell,
1262 const std::integral_constant<int, 1> &)
1265 if (cell->
get_fe().dofs_per_vertex > 0)
1266 for (
unsigned int v=0; v<GeometryInfo<1>::vertices_per_cell; ++v)
1268 typename DoFHandler<dim,spacedim>::level_cell_iterator neighbor = cell->neighbor(v);
1273 if (neighbor->user_flag_set() &&
1274 (neighbor->level() == cell->level()))
1279 for (
unsigned int d=0;
d<cell->
get_fe().dofs_per_vertex; ++
d)
1280 cell->set_mg_vertex_dof_index (cell->level(), 0,
d,
1281 neighbor->mg_vertex_dof_index (cell->level(), 1,
d));
1283 for (
unsigned int d=0;
d<cell->
get_fe().dofs_per_vertex; ++
d)
1284 cell->set_mg_vertex_dof_index (cell->level(), 1,
d,
1285 neighbor->mg_vertex_dof_index (cell->level(), 0,
d));
1293 for (
unsigned int d=0;
d<cell->
get_fe().dofs_per_vertex; ++
d)
1294 cell->set_mg_vertex_dof_index (cell->level(), v,
d, next_free_dof++);
1298 if (cell->
get_fe().dofs_per_line > 0)
1299 for (
unsigned int d=0;
d<cell->
get_fe().dofs_per_line; ++
d)
1300 cell->set_mg_dof_index (cell->level(),
d, next_free_dof++);
1303 cell->set_user_flag ();
1305 return next_free_dof;
1310 template <
int dim,
int spacedim>
1313 distribute_mg_dofs_on_cell (
const typename DoFHandler<dim,spacedim>::level_cell_iterator &cell,
1315 const std::integral_constant<int, 2> &)
1317 if (cell->
get_fe().dofs_per_vertex > 0)
1319 for (
unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_cell; ++vertex)
1324 for (
unsigned int d=0;
d<cell->
get_fe().dofs_per_vertex; ++
d)
1325 cell->set_mg_vertex_dof_index (cell->level(), vertex,
d, next_free_dof++);
1328 if (cell->
get_fe().dofs_per_line > 0)
1329 for (
unsigned int side=0; side<GeometryInfo<2>::faces_per_cell; ++side)
1331 typename DoFHandler<dim,spacedim>::line_iterator line = cell->line(side);
1337 for (
unsigned int d=0;
d<cell->
get_fe().dofs_per_line; ++
d)
1338 line->set_mg_dof_index (cell->level(),
d, next_free_dof++);
1343 if (cell->
get_fe().dofs_per_quad > 0)
1344 for (
unsigned int d=0;
d<cell->
get_fe().dofs_per_quad; ++
d)
1345 cell->set_mg_dof_index (cell->level(),
d, next_free_dof++);
1349 cell->set_user_flag ();
1351 return next_free_dof;
1356 template <
int dim,
int spacedim>
1359 distribute_mg_dofs_on_cell (
const typename DoFHandler<dim,spacedim>::level_cell_iterator &cell,
1361 const std::integral_constant<int, 3> &)
1363 if (cell->
get_fe().dofs_per_vertex > 0)
1365 for (
unsigned int vertex=0; vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
1369 for (
unsigned int d=0;
d<cell->
get_fe().dofs_per_vertex; ++
d)
1370 cell->set_mg_vertex_dof_index (cell->level(), vertex,
d, next_free_dof++);
1373 if (cell->
get_fe().dofs_per_line > 0)
1374 for (
unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++
l)
1376 typename DoFHandler<dim,spacedim>::line_iterator line = cell->line(l);
1383 for (
unsigned int d=0;
d<cell->
get_fe().dofs_per_line; ++
d)
1384 line->set_mg_dof_index (cell->level(),
d, next_free_dof++);
1388 if (cell->
get_fe().dofs_per_quad > 0)
1389 for (
unsigned int q=0; q<GeometryInfo<3>::quads_per_cell; ++q)
1391 typename DoFHandler<dim,spacedim>::quad_iterator quad = cell->quad(q);
1398 for (
unsigned int d=0;
d<cell->
get_fe().dofs_per_quad; ++
d)
1399 quad->set_mg_dof_index (cell->level(),
d, next_free_dof++);
1404 if (cell->
get_fe().dofs_per_hex > 0)
1405 for (
unsigned int d=0;
d<cell->
get_fe().dofs_per_hex; ++
d)
1406 cell->set_mg_dof_index (cell->level(),
d, next_free_dof++);
1410 cell->set_user_flag ();
1412 return next_free_dof;
1418 template <
int spacedim>
1427 (void)next_free_dof;
1433 template <
int spacedim>
1442 (void)next_free_dof;
1448 template <
int spacedim>
1457 (void)next_free_dof;
1463 template <
class DoFHandlerType>
1467 DoFHandlerType &dof_handler,
1468 const unsigned int level)
1470 const unsigned int dim = DoFHandlerType::dimension;
1471 const unsigned int spacedim = DoFHandlerType::space_dimension;
1473 const ::Triangulation<dim,spacedim> &tria
1476 if (level>=tria.n_levels())
1483 std::vector<bool> user_flags;
1484 tria.save_user_flags(user_flags);
1488 typename DoFHandler<dim,spacedim>::level_cell_iterator
1489 cell = dof_handler.
begin(level),
1490 endc = dof_handler.end(level);
1492 for (; cell != endc; ++cell)
1495 (cell->level_subdomain_id() == level_subdomain_id))
1497 = Implementation::distribute_mg_dofs_on_cell<dim,spacedim> (cell, next_free_dof,
1498 std::integral_constant<int, dim>());
1503 return next_free_dof;
1518 template <
int dim,
int spacedim>
1521 renumber_vertex_dofs (
const std::vector<types::global_dof_index> &new_numbers,
1524 const bool check_validity)
1532 for (std::vector<types::global_dof_index>::iterator
1536 *i = (indices.
size() == 0)?
1539 else if (check_validity)
1543 .vertex_used((i-dof_handler.
vertex_dofs.begin()) /
1544 dof_handler.
get_fe().dofs_per_vertex)
1558 template <
int dim,
int spacedim>
1561 renumber_cell_dofs (
const std::vector<types::global_dof_index> &new_numbers,
1565 for (
unsigned int level=0; level<dof_handler.
levels.size(); ++level)
1566 for (std::vector<types::global_dof_index>::iterator
1567 i=dof_handler.
levels[level]->dof_object.dofs.begin();
1568 i!=dof_handler.
levels[level]->dof_object.dofs.end(); ++i)
1570 *i = ((indices.
size() == 0) ?
1584 template <
int spacedim>
1587 renumber_face_dofs (
const std::vector<types::global_dof_index> &,
1596 template <
int spacedim>
1599 renumber_face_dofs (
const std::vector<types::global_dof_index> &new_numbers,
1604 for (std::vector<types::global_dof_index>::iterator
1605 i=dof_handler.
faces->lines.dofs.begin();
1606 i!=dof_handler.
faces->lines.dofs.end(); ++i)
1608 *i = ((indices.
size() == 0) ?
1615 template <
int spacedim>
1618 renumber_face_dofs (
const std::vector<types::global_dof_index> &new_numbers,
1623 for (std::vector<types::global_dof_index>::iterator
1624 i=dof_handler.
faces->lines.dofs.begin();
1625 i!=dof_handler.
faces->lines.dofs.end(); ++i)
1627 *i = ((indices.
size() == 0) ?
1632 for (std::vector<types::global_dof_index>::iterator
1633 i=dof_handler.
faces->quads.dofs.begin();
1634 i!=dof_handler.
faces->quads.dofs.end(); ++i)
1636 *i = ((indices.
size() == 0) ?
1643 template <
int dim,
int spacedim>
1646 renumber_vertex_dofs (
const std::vector<types::global_dof_index> &new_numbers,
1649 const bool check_validity)
1651 for (
unsigned int vertex_index=0; vertex_index<dof_handler.
get_triangulation().n_vertices();
1654 const unsigned int n_active_fe_indices
1655 = ::internal::DoFAccessorImplementation::Implementation::
1656 n_active_vertex_fe_indices (dof_handler, vertex_index);
1662 Assert (n_active_fe_indices == 0,
1668 for (
unsigned int f=0; f<n_active_fe_indices; ++f)
1670 const unsigned int fe_index
1671 = ::internal::DoFAccessorImplementation::Implementation::
1672 nth_active_vertex_fe_index (dof_handler, vertex_index, f);
1674 for (
unsigned int d=0;
d<dof_handler.
get_fe(fe_index).dofs_per_vertex; ++
d)
1677 = ::internal::DoFAccessorImplementation::Implementation::
1678 get_vertex_dof_index(dof_handler,
1696 ::internal::DoFAccessorImplementation::Implementation::
1697 set_vertex_dof_index (dof_handler,
1701 (indices.
size() == 0)?
1702 (new_numbers[old_dof_index]) :
1703 (new_numbers[indices.index_within_set(old_dof_index)]));
1711 template <
int dim,
int spacedim>
1714 renumber_cell_dofs (
const std::vector<types::global_dof_index> &new_numbers,
1720 cell!=dof_handler.
end(); ++cell)
1721 if (!cell->is_artificial())
1723 const unsigned int fe_index = cell->active_fe_index ();
1725 for (
unsigned int d=0;
d<dof_handler.
get_fe(fe_index).template n_dofs_per_object<dim>(); ++
d)
1729 cell->set_dof_index (d,
1730 (indices.
size() == 0)?
1731 (new_numbers[old_dof_index]) :
1740 template <
int spacedim>
1743 renumber_face_dofs (
const std::vector<types::global_dof_index> &,
1753 template <
int spacedim>
1756 renumber_face_dofs (
const std::vector<types::global_dof_index> &new_numbers,
1760 const unsigned int dim = 2;
1766 std::vector<bool> saved_line_user_flags;
1768 .save_user_flags_line (saved_line_user_flags);
1770 .clear_user_flags_line ();
1774 if (!cell->is_artificial())
1775 for (
unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++
l)
1776 if (cell->line(l)->user_flag_set() ==
false)
1778 const typename hp::DoFHandler<dim,spacedim>::line_iterator line = cell->line(l);
1779 line->set_user_flag();
1781 const unsigned int n_active_fe_indices
1782 = line->n_active_fe_indices ();
1784 for (
unsigned int f=0; f<n_active_fe_indices; ++f)
1786 const unsigned int fe_index
1787 = line->nth_active_fe_index (f);
1789 for (
unsigned int d=0;
d<dof_handler.
get_fe(fe_index).dofs_per_line; ++
d)
1793 line->set_dof_index (d,
1794 (indices.
size() == 0)?
1795 (new_numbers[old_dof_index]) :
1805 .load_user_flags_line (saved_line_user_flags);
1811 template <
int spacedim>
1814 renumber_face_dofs (
const std::vector<types::global_dof_index> &new_numbers,
1818 const unsigned int dim = 3;
1824 std::vector<bool> saved_line_user_flags;
1826 .save_user_flags_line (saved_line_user_flags);
1828 .clear_user_flags_line ();
1832 if (!cell->is_artificial())
1833 for (
unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++
l)
1834 if (cell->line(l)->user_flag_set() ==
false)
1836 const typename hp::DoFHandler<dim,spacedim>::line_iterator line = cell->line(l);
1837 line->set_user_flag();
1839 const unsigned int n_active_fe_indices
1840 = line->n_active_fe_indices ();
1842 for (
unsigned int f=0; f<n_active_fe_indices; ++f)
1844 const unsigned int fe_index
1845 = line->nth_active_fe_index (f);
1847 for (
unsigned int d=0;
d<dof_handler.
get_fe(fe_index).dofs_per_line; ++
d)
1851 line->set_dof_index (d,
1852 (indices.
size() == 0)?
1853 (new_numbers[old_dof_index]) :
1863 .load_user_flags_line (saved_line_user_flags);
1868 std::vector<bool> saved_quad_user_flags;
1870 .save_user_flags_quad (saved_quad_user_flags);
1872 .clear_user_flags_quad ();
1876 if (!cell->is_artificial())
1877 for (
unsigned int q=0; q<GeometryInfo<dim>::quads_per_cell; ++q)
1878 if (cell->quad(q)->user_flag_set() ==
false)
1880 const typename hp::DoFHandler<dim,spacedim>::quad_iterator quad = cell->quad(q);
1881 quad->set_user_flag();
1883 const unsigned int n_active_fe_indices
1884 = quad->n_active_fe_indices ();
1886 for (
unsigned int f=0; f<n_active_fe_indices; ++f)
1888 const unsigned int fe_index
1889 = quad->nth_active_fe_index (f);
1891 for (
unsigned int d=0;
d<dof_handler.
get_fe(fe_index).dofs_per_quad; ++
d)
1895 quad->set_dof_index (d,
1896 (indices.
size() == 0)?
1897 (new_numbers[old_dof_index]) :
1906 .load_user_flags_quad (saved_quad_user_flags);
1924 template <
class DoFHandlerType>
1927 renumber_dofs (
const std::vector<types::global_dof_index> &new_numbers,
1929 DoFHandlerType &dof_handler,
1930 const bool check_validity)
1932 if (DoFHandlerType::dimension == 1)
1941 renumber_vertex_dofs (new_numbers, indices, dof_handler, check_validity);
1945 renumber_face_dofs (new_numbers, indices, dof_handler);
1949 renumber_cell_dofs (new_numbers, indices, dof_handler);
1954 update_all_active_cell_dof_indices_caches (dof_handler);
1968 template <
int dim,
int spacedim>
1971 renumber_vertex_mg_dofs (
const std::vector<::types::global_dof_index> &new_numbers,
1974 const unsigned int level,
1975 const bool check_validity)
1985 if ((i->get_coarsest_level() <= level) &&
1986 (i->get_finest_level() >= level))
1987 for (
unsigned int d=0;
d<dof_handler.
get_fe().dofs_per_vertex; ++
d)
1989 const ::types::global_dof_index idx
1990 = i->get_index (level, d, dof_handler.
get_fe().dofs_per_vertex);
1996 i->set_index (level, d,
1997 dof_handler.
get_fe().dofs_per_vertex,
1998 (indices.
size() == 0)?
1999 (new_numbers[idx]) :
2013 template <
int dim,
int spacedim>
2016 renumber_cell_mg_dofs (
const std::vector<::types::global_dof_index> &new_numbers,
2019 const unsigned int level)
2021 for (std::vector<types::global_dof_index>::iterator
2022 i=dof_handler.mg_levels[level]->dof_object.dofs.begin();
2023 i!=dof_handler.mg_levels[level]->dof_object.dofs.end();
2031 *i = (indices.
size() == 0)?
2047 template <
int spacedim>
2050 renumber_face_mg_dofs (
const std::vector<types::global_dof_index> &,
2053 const unsigned int ,
2061 template <
int spacedim>
2064 renumber_face_mg_dofs (
const std::vector<::types::global_dof_index> &new_numbers,
2067 const unsigned int level,
2068 const bool check_validity)
2070 if (dof_handler.
get_fe().dofs_per_line > 0)
2073 std::vector<bool> user_flags;
2081 typename DoFHandler<2,spacedim>::level_cell_iterator cell,
2082 endc = dof_handler.
end(level);
2083 for (cell = dof_handler.
begin(level); cell != endc; ++cell)
2084 for (
unsigned int line=0; line < GeometryInfo<2>::faces_per_cell; ++line)
2085 cell->face(line)->set_user_flag();
2088 cell != dof_handler.
end(); ++cell)
2089 for (
unsigned int l=0; l<GeometryInfo<2>::lines_per_cell; ++
l)
2090 if (cell->line(l)->user_flag_set())
2092 for (
unsigned int d=0;
d<dof_handler.
get_fe().dofs_per_line; ++
d)
2094 const ::types::global_dof_index idx = cell->line(l)->mg_dof_index(level, d);
2099 cell->line(l)->set_mg_dof_index (level, d, ((indices.
size() == 0) ?
2103 cell->line(l)->clear_user_flag();
2112 template <
int spacedim>
2115 renumber_face_mg_dofs (
const std::vector<::types::global_dof_index> &new_numbers,
2118 const unsigned int level,
2119 const bool check_validity)
2121 if (dof_handler.
get_fe().dofs_per_line > 0 ||
2122 dof_handler.
get_fe().dofs_per_quad > 0)
2125 std::vector<bool> user_flags;
2132 typename DoFHandler<3,spacedim>::level_cell_iterator cell,
2133 endc = dof_handler.
end(level);
2134 for (cell = dof_handler.
begin(level); cell != endc; ++cell)
2135 for (
unsigned int line=0; line < GeometryInfo<3>::lines_per_cell; ++line)
2136 cell->line(line)->set_user_flag();
2139 cell != dof_handler.
end(); ++cell)
2140 for (
unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++
l)
2141 if (cell->line(l)->user_flag_set())
2143 for (
unsigned int d=0;
d<dof_handler.
get_fe().dofs_per_line; ++
d)
2145 const ::types::global_dof_index idx = cell->line(l)->mg_dof_index(level, d);
2150 cell->line(l)->set_mg_dof_index (level, d, ((indices.
size() == 0) ?
2154 cell->line(l)->clear_user_flag();
2160 for (cell = dof_handler.
begin(level); cell != endc; ++cell)
2161 for (
unsigned int quad=0; quad < GeometryInfo<3>::quads_per_cell; ++quad)
2162 cell->quad(quad)->set_user_flag();
2165 cell != dof_handler.
end(); ++cell)
2166 for (
unsigned int l=0; l<GeometryInfo<3>::quads_per_cell; ++
l)
2167 if (cell->quad(l)->user_flag_set())
2169 for (
unsigned int d=0;
d<dof_handler.
get_fe().dofs_per_quad; ++
d)
2171 const ::types::global_dof_index idx = cell->quad(l)->mg_dof_index(level, d);
2176 cell->quad(l)->set_mg_dof_index (level, d, ((indices.
size() == 0) ?
2180 cell->quad(l)->clear_user_flag();
2190 template <
int dim,
int spacedim>
2193 renumber_mg_dofs (
const std::vector<::types::global_dof_index> &new_numbers,
2196 const unsigned int level,
2197 const bool check_validity)
2208 renumber_vertex_mg_dofs (new_numbers, indices, dof_handler, level, check_validity);
2212 renumber_face_mg_dofs (new_numbers, indices, dof_handler, level, check_validity);
2216 renumber_cell_mg_dofs (new_numbers, indices, dof_handler, level);
2223 template <
int dim,
int spacedim>
2226 renumber_mg_dofs (
const std::vector<::types::global_dof_index> &,
2229 const unsigned int ,
2243 template <
class DoFHandlerType>
2247 dof_handler (&dof_handler)
2252 template <
class DoFHandlerType>
2267 template <
class DoFHandlerType>
2268 std::vector<NumberCache>
2272 std::vector<bool> user_flags;
2278 std::vector<NumberCache> number_caches;
2280 for (
unsigned int level = 0; level < dof_handler->
get_triangulation().n_levels(); ++level)
2285 *dof_handler, level);
2288 number_caches.emplace_back (
NumberCache(n_level_dofs));
2294 return number_caches;
2299 template <
class DoFHandlerType>
2304 Implementation::renumber_dofs (new_numbers,
IndexSet(0),
2305 *dof_handler,
true);
2315 return NumberCache (*std::max_element(new_numbers.begin(),
2316 new_numbers.end()) + 1);
2321 template <
class DoFHandlerType>
2325 const std::vector<types::global_dof_index> &new_numbers)
const 2327 Implementation::renumber_mg_dofs (new_numbers,
IndexSet(0),
2328 *dof_handler, level,
true);
2338 template <
class DoFHandlerType>
2342 dof_handler (&dof_handler)
2357 template <
class DoFHandlerType>
2358 std::vector<types::subdomain_id>
2359 get_dof_subdomain_association (
const DoFHandlerType &dof_handler,
2361 const unsigned int n_procs)
2364 std::vector<types::subdomain_id> subdomain_association (n_dofs,
2366 std::vector<types::global_dof_index> local_dof_indices;
2371 typename DoFHandlerType::active_cell_iterator
2373 endc = dof_handler.
end();
2374 for (; cell!=endc; ++cell)
2380 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
2381 local_dof_indices.resize (dofs_per_cell);
2382 cell->get_dof_indices (local_dof_indices);
2387 for (
unsigned int i=0; i<dofs_per_cell; ++i)
2388 if (subdomain_association[local_dof_indices[i]] ==
2390 subdomain_association[local_dof_indices[i]] = subdomain_id;
2391 else if (subdomain_association[local_dof_indices[i]] > subdomain_id)
2393 subdomain_association[local_dof_indices[i]] = subdomain_id;
2397 Assert (std::find (subdomain_association.begin(),
2398 subdomain_association.end(),
2400 == subdomain_association.end(),
2403 Assert (*std::max_element (subdomain_association.begin(),
2404 subdomain_association.end())
2408 return subdomain_association;
2418 template <
class DoFHandlerType>
2419 std::vector<types::subdomain_id>
2420 get_dof_level_subdomain_association (
const DoFHandlerType &dof_handler,
2422 const unsigned int n_procs,
2423 const unsigned int level)
2426 std::vector<types::subdomain_id> level_subdomain_association (n_dofs_on_level,
2428 std::vector<types::global_dof_index> local_dof_indices;
2433 typename DoFHandlerType::cell_iterator
2434 cell = dof_handler.begin(level),
2435 endc = dof_handler.
end(level);
2436 for (; cell!=endc; ++cell)
2442 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
2443 local_dof_indices.resize (dofs_per_cell);
2444 cell->get_mg_dof_indices (local_dof_indices);
2449 for (
unsigned int i=0; i<dofs_per_cell; ++i)
2450 if (level_subdomain_association[local_dof_indices[i]] ==
2452 level_subdomain_association[local_dof_indices[i]] = level_subdomain_id;
2453 else if (level_subdomain_association[local_dof_indices[i]] > level_subdomain_id)
2455 level_subdomain_association[local_dof_indices[i]] = level_subdomain_id;
2459 Assert (std::find (level_subdomain_association.begin(),
2460 level_subdomain_association.end(),
2462 == level_subdomain_association.end(),
2465 Assert (*std::max_element (level_subdomain_association.begin(),
2466 level_subdomain_association.end())
2470 return level_subdomain_association;
2476 template <
class DoFHandlerType>
2481 const unsigned int dim = DoFHandlerType::dimension;
2482 const unsigned int spacedim = DoFHandlerType::space_dimension;
2494 std::vector<types::subdomain_id> saved_subdomain_ids;
2499 typename parallel::shared::Triangulation<dim,spacedim>::active_cell_iterator
2500 cell = this->dof_handler->get_triangulation().begin_active(),
2503 const std::vector<types::subdomain_id> &true_subdomain_ids
2506 for (
unsigned int index=0; cell != endc; ++cell, ++index)
2508 saved_subdomain_ids[index] = cell->subdomain_id();
2509 cell->set_subdomain_id(true_subdomain_ids[index]);
2517 *this->dof_handler);
2528 std::vector<types::global_dof_index> new_dof_indices (n_dofs,
2533 const std::vector<types::subdomain_id> subdomain_association
2534 = get_dof_subdomain_association (*this->dof_handler, n_dofs, n_procs);
2544 if (subdomain_association[i] == subdomain)
2548 new_dof_indices[i] = next_free_index;
2554 Assert (std::find (new_dof_indices.begin(), new_dof_indices.end(),
2556 == new_dof_indices.end(),
2563 Implementation::renumber_dofs (new_dof_indices,
IndexSet(0),
2564 *this->dof_handler,
true);
2575 const std::vector<types::subdomain_id> subdomain_association
2576 = get_dof_subdomain_association (*this->dof_handler, n_dofs, n_procs);
2578 for (
unsigned int i=1; i<n_dofs; ++i)
2579 Assert (subdomain_association[i] >= subdomain_association[i-1],
2582 std::vector<IndexSet> locally_owned_dofs_per_processor (n_procs,
2593 unsigned int start_index = 0;
2594 unsigned int end_index = 0;
2595 while (start_index < n_dofs)
2597 while ((end_index) < n_dofs &&
2598 (subdomain_association[end_index] == subdomain_association[start_index]))
2603 if (end_index > start_index)
2605 const unsigned int subdomain_owner = subdomain_association[start_index];
2606 locally_owned_dofs_per_processor[subdomain_owner]
2607 .add_range (start_index, end_index);
2611 start_index = end_index;
2618 typename parallel::shared::Triangulation<dim,spacedim>::active_cell_iterator
2619 cell = this->dof_handler->get_triangulation().begin_active(),
2622 for (
unsigned int index=0; cell != endc; ++cell, ++index)
2623 cell->set_subdomain_id(saved_subdomain_ids[index]);
2628 return NumberCache(locally_owned_dofs_per_processor,
2629 this->dof_handler->get_triangulation().locally_owned_subdomain ());
2634 template <
class DoFHandlerType>
2635 std::vector<NumberCache>
2639 const unsigned int dim = DoFHandlerType::dimension;
2640 const unsigned int spacedim = DoFHandlerType::space_dimension;
2649 std::vector<NumberCache> number_caches;
2650 number_caches.reserve(n_levels);
2653 for (
unsigned int lvl=0; lvl<n_levels; ++lvl)
2661 std::vector<types::subdomain_id> saved_level_subdomain_ids;
2662 saved_level_subdomain_ids.resize(tr->
n_cells(lvl));
2664 typename parallel::shared::Triangulation<dim,spacedim>::cell_iterator
2665 cell = this->dof_handler->get_triangulation().begin(lvl),
2668 const std::vector<types::subdomain_id> &true_level_subdomain_ids
2671 for (
unsigned int index=0; cell != endc; ++cell, ++index)
2673 saved_level_subdomain_ids[index] = cell->level_subdomain_id();
2674 cell->set_level_subdomain_id(true_level_subdomain_ids[index]);
2694 std::vector<types::global_dof_index> new_dof_indices (n_dofs_on_level,
2699 const std::vector<types::subdomain_id> level_subdomain_association
2700 = get_dof_level_subdomain_association (*this->dof_handler,
2701 n_dofs_on_level, n_procs, lvl);
2711 if (level_subdomain_association[i] == level_subdomain)
2715 new_dof_indices[i] = next_free_index;
2721 Assert (std::find (new_dof_indices.begin(), new_dof_indices.end(),
2723 == new_dof_indices.end(),
2731 Implementation::renumber_mg_dofs (new_dof_indices,
IndexSet(0),
2732 *this->dof_handler, lvl,
true);
2743 const std::vector<types::subdomain_id> level_subdomain_association
2744 = get_dof_level_subdomain_association (*this->dof_handler,
2745 n_dofs_on_level, n_procs, lvl);
2747 for (
unsigned int i=1; i<n_dofs_on_level; ++i)
2748 Assert (level_subdomain_association[i] >= level_subdomain_association[i-1],
2751 std::vector<IndexSet> locally_owned_dofs_per_processor (n_procs,
2762 unsigned int start_index = 0;
2763 unsigned int end_index = 0;
2764 while (start_index < n_dofs_on_level)
2766 while ((end_index) < n_dofs_on_level &&
2767 (level_subdomain_association[end_index] == level_subdomain_association[start_index]))
2772 if (end_index > start_index)
2774 const unsigned int level_subdomain_owner = level_subdomain_association[start_index];
2775 locally_owned_dofs_per_processor[level_subdomain_owner]
2776 .add_range (start_index, end_index);
2780 start_index = end_index;
2786 typename parallel::shared::Triangulation<dim,spacedim>::cell_iterator
2787 cell = this->dof_handler->get_triangulation().begin(lvl),
2790 for (
unsigned int index=0; cell != endc; ++cell, ++index)
2791 cell->set_level_subdomain_id(saved_level_subdomain_ids[index]);
2794 number_caches.emplace_back (
NumberCache(locally_owned_dofs_per_processor,
2795 this->dof_handler->get_triangulation()
2796 .locally_owned_subdomain ()));
2800 return number_caches;
2807 template <
class DoFHandlerType>
2813 #ifndef DEAL_II_WITH_MPI 2818 const unsigned int dim = DoFHandlerType::dimension;
2819 const unsigned int spacedim = DoFHandlerType::space_dimension;
2827 typename parallel::shared::Triangulation<dim,spacedim>::active_cell_iterator
2828 cell = this->dof_handler->get_triangulation().begin_active(),
2830 std::vector<types::subdomain_id> current_subdomain_ids(tr->
n_active_cells());
2833 for (
unsigned int index=0; cell != endc; cell++, index++)
2835 current_subdomain_ids[index] = cell->subdomain_id();
2836 cell->set_subdomain_id(true_subdomain_ids[index]);
2839 std::vector<types::global_dof_index> global_gathered_numbers (this->dof_handler->n_dofs (), 0);
2843 if (new_numbers.size () == this->dof_handler->n_dofs ())
2845 global_gathered_numbers = new_numbers;
2849 Assert(new_numbers.size() == this->dof_handler->locally_owned_dofs().n_elements(),
2852 std::vector<types::global_dof_index> gathered_new_numbers (this->dof_handler->n_dofs (), 0);
2854 this->dof_handler->get_triangulation().locally_owned_subdomain (),
2859 std::vector<types::global_dof_index> new_numbers_copy (new_numbers);
2862 std::vector<int> rcounts(n_cpu);
2866 int cur_count = new_numbers_copy.size ();
2867 int ierr = MPI_Allgather (&cur_count, 1, MPI_INT,
2868 rcounts.data(), 1, MPI_INT,
2874 std::vector<int> displacements(n_cpu);
2875 for (
unsigned int i = 0; i < n_cpu; i++)
2877 displacements[i] = shift;
2878 shift += rcounts[i];
2880 Assert(((
int)new_numbers_copy.size()) ==
2883 ierr = MPI_Allgatherv (new_numbers_copy.data(), new_numbers_copy.size (),
2884 DEAL_II_DOF_INDEX_MPI_TYPE,
2885 gathered_new_numbers.data(), rcounts.data(),
2886 displacements.data(),
2887 DEAL_II_DOF_INDEX_MPI_TYPE,
2897 std::vector<unsigned int> flag_1 (this->dof_handler->n_dofs (), 0);
2898 std::vector<unsigned int> flag_2 (this->dof_handler->n_dofs (), 0);
2899 for (
unsigned int i = 0; i < n_cpu; i++)
2902 this->dof_handler->locally_owned_dofs_per_processor()[i];
2910 global_gathered_numbers[target] = value;
2917 Assert(*std::max_element(flag_1.begin(), flag_1.end()) == 1,
2919 Assert(*std::min_element(flag_1.begin(), flag_1.end()) == 1,
2921 Assert((*std::max_element(flag_2.begin(), flag_2.end())) == 1,
2923 Assert((*std::min_element(flag_2.begin(), flag_2.end())) == 1,
2930 Implementation::renumber_dofs (global_gathered_numbers,
IndexSet(0),
2931 *this->dof_handler,
true);
2934 this->dof_handler->get_triangulation().locally_owned_subdomain ());
2939 for (
unsigned int index=0; cell != endc; cell++, index++)
2940 cell->set_subdomain_id(current_subdomain_ids[index]);
2942 return number_cache;
2948 template <
class DoFHandlerType>
2952 const std::vector<types::global_dof_index> &)
const 2964 #ifdef DEAL_II_WITH_P4EST 2984 struct CellDataTransferBuffer
2986 std::vector<unsigned int> tree_indices;
2987 std::vector<typename ::internal::p4est::types<dim>::quadrant> quadrants;
2988 std::vector<::types::global_dof_index> dof_numbers_and_indices;
2995 template <
class Archive>
2996 void save (Archive &ar,
2997 const unsigned int )
const 3003 std::vector<char> quadrants_as_chars (
sizeof(quadrants[0]) * quadrants.size());
3004 if (quadrants_as_chars.size()>0)
3007 std::memcpy(quadrants_as_chars.data(),
3009 quadrants_as_chars.size());
3013 ar &quadrants_as_chars
3015 &dof_numbers_and_indices;
3022 template <
class Archive>
3023 void load (Archive &ar,
3024 const unsigned int )
3027 std::vector<char> quadrants_as_chars;
3028 ar &quadrants_as_chars
3030 &dof_numbers_and_indices;
3032 if (quadrants_as_chars.size()>0)
3034 quadrants.resize (quadrants_as_chars.size() /
sizeof(quadrants[0]));
3035 std::memcpy(quadrants.data(),
3036 quadrants_as_chars.data(),
3037 quadrants_as_chars.size());
3043 BOOST_SERIALIZATION_SPLIT_MEMBER()
3055 std::vector<char> buffer;
3057 #ifdef DEAL_II_WITH_ZLIB 3058 boost::iostreams::filtering_ostream out;
3059 out.push(boost::iostreams::gzip_compressor
3060 (boost::iostreams::gzip_params
3061 (boost::iostreams::gzip::best_compression)));
3062 out.push(boost::iostreams::back_inserter(buffer));
3064 boost::archive::binary_oarchive archive(out);
3069 std::ostringstream out;
3070 boost::archive::binary_oarchive archive(out);
3072 const std::string &s = out.str();
3073 buffer.reserve(s.size());
3074 buffer.assign(s.begin(), s.end());
3087 void unpack_data (
const std::vector<char> &buffer)
3089 std::string decompressed_buffer;
3093 #ifdef DEAL_II_WITH_ZLIB 3094 boost::iostreams::filtering_ostream decompressing_stream;
3095 decompressing_stream.push(boost::iostreams::gzip_decompressor());
3096 decompressing_stream.push(boost::iostreams::back_inserter(decompressed_buffer));
3097 decompressing_stream.write (buffer.data(), buffer.size());
3099 decompressed_buffer.assign (buffer.begin(), buffer.end());
3104 std::istringstream in(decompressed_buffer);
3105 boost::archive::binary_iarchive archive(in);
3114 template <
int dim,
int spacedim>
3116 get_mg_dofindices_recursively (
3118 const typename ::internal::p4est::types<dim>::quadrant &p4est_cell,
3119 const typename DoFHandler<dim,spacedim>::level_cell_iterator &dealii_cell,
3120 const typename ::internal::p4est::types<dim>::quadrant &quadrant,
3121 CellDataTransferBuffer<dim> &cell_data_transfer_buffer)
3123 if (internal::p4est::quadrant_is_equal<dim>(p4est_cell, quadrant))
3129 std::vector<::types::global_dof_index>
3130 local_dof_indices (dealii_cell->
get_fe().dofs_per_cell);
3131 dealii_cell->get_mg_dof_indices (local_dof_indices);
3133 cell_data_transfer_buffer.dof_numbers_and_indices.push_back(dealii_cell->
get_fe().dofs_per_cell);
3134 cell_data_transfer_buffer.dof_numbers_and_indices.insert(cell_data_transfer_buffer.dof_numbers_and_indices.end(),
3135 local_dof_indices.begin(),
3136 local_dof_indices.end());
3140 if (! dealii_cell->has_children())
3143 if (! internal::p4est::quadrant_is_ancestor<dim> (p4est_cell, quadrant))
3146 typename ::internal::p4est::types<dim>::quadrant
3148 internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
3150 for (
unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
3151 get_mg_dofindices_recursively<dim,spacedim> (tria, p4est_child[c],
3152 dealii_cell->child(c),
3153 quadrant, cell_data_transfer_buffer);
3157 template <
int dim,
int spacedim>
3160 const unsigned int tree_index,
3161 const typename DoFHandler<dim,spacedim>::level_cell_iterator &dealii_cell,
3162 const typename ::internal::p4est::types<dim>::quadrant &p4est_cell,
3166 if (dealii_cell->has_children())
3168 typename ::internal::p4est::types<dim>::quadrant
3170 internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
3173 for (
unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
3174 find_marked_mg_ghost_cells_recursively<dim,spacedim>(tria,
3176 dealii_cell->child(c),
3178 neighbor_cell_list);
3183 neighbor_cell_list[dealii_cell->level_subdomain_id()].tree_indices.push_back(tree_index);
3184 neighbor_cell_list[dealii_cell->level_subdomain_id()].quadrants.push_back(p4est_cell);
3189 template <
int dim,
int spacedim>
3191 set_mg_dofindices_recursively (
3193 const typename ::internal::p4est::types<dim>::quadrant &p4est_cell,
3194 const typename DoFHandler<dim,spacedim>::level_cell_iterator &dealii_cell,
3195 const typename ::internal::p4est::types<dim>::quadrant &quadrant,
3198 if (internal::p4est::quadrant_is_equal<dim>(p4est_cell, quadrant))
3203 std::vector<::types::global_dof_index>
3204 dof_indices (dealii_cell->
get_fe().dofs_per_cell);
3205 dealii_cell->get_mg_dof_indices(dof_indices);
3207 bool complete =
true;
3208 for (
unsigned int i=0; i<dof_indices.size(); ++i)
3211 Assert((dof_indices[i] ==
3214 (dof_indices[i]==dofs[i]),
3216 dof_indices[i]=dofs[i];
3223 <
typename DoFHandler<dim,spacedim>::level_cell_iterator &>
3224 (dealii_cell)->set_user_flag();
3227 <
typename DoFHandler<dim,spacedim>::level_cell_iterator &>
3228 (dealii_cell)->clear_user_flag();
3231 <
typename DoFHandler<dim,spacedim>::level_cell_iterator &>
3232 (dealii_cell)->set_mg_dof_indices(dof_indices);
3236 if (! dealii_cell->has_children())
3239 if (! internal::p4est::quadrant_is_ancestor<dim> (p4est_cell, quadrant))
3242 typename ::internal::p4est::types<dim>::quadrant
3244 internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
3246 for (
unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
3247 set_mg_dofindices_recursively<dim,spacedim> (tria, p4est_child[c],
3248 dealii_cell->child(c),
3255 template <
int dim,
int spacedim,
class DoFHandlerType>
3258 DoFHandlerType &dof_handler,
3259 const std::vector<::types::global_dof_index> &coarse_cell_to_p4est_tree_permutation,
3260 const std::vector<::types::global_dof_index> &p4est_tree_to_coarse_cell_permutation)
3264 typedef std::map<::types::subdomain_id, CellDataTransferBuffer<dim>> cellmap_t;
3265 cellmap_t neighbor_cell_list;
3266 for (std::set<::types::subdomain_id>::iterator it = level_ghost_owners.begin();
3267 it != level_ghost_owners.end();
3269 neighbor_cell_list.insert(std::make_pair(*it, CellDataTransferBuffer<dim>()));
3271 for (
typename DoFHandlerType::level_cell_iterator
3272 cell = dof_handler.begin(0);
3273 cell != dof_handler.end(0);
3276 typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
3277 internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
3279 find_marked_mg_ghost_cells_recursively<dim,spacedim>
3281 coarse_cell_to_p4est_tree_permutation[cell->index()],
3284 neighbor_cell_list);
3289 std::vector<std::vector<char> > sendbuffers (level_ghost_owners.size());
3290 std::vector<MPI_Request> requests (level_ghost_owners.size());
3293 for (
typename cellmap_t::iterator it = neighbor_cell_list.begin();
3294 it!=neighbor_cell_list.end();
3300 sendbuffers[idx] = it->second.pack_data ();
3301 const int ierr = MPI_Isend(sendbuffers[idx].data(), sendbuffers[idx].size(),
3302 MPI_BYTE, it->first,
3303 1100101, tria.get_communicator(), &requests[idx]);
3308 std::vector<std::vector<char> > reply_buffers (level_ghost_owners.size());
3309 std::vector<MPI_Request> reply_requests (level_ghost_owners.size());
3311 for (
unsigned int idx=0; idx<level_ghost_owners.size(); ++idx)
3313 std::vector<char> receive;
3314 CellDataTransferBuffer<dim> cell_data_transfer_buffer;
3318 int ierr = MPI_Probe(MPI_ANY_SOURCE, 1100101, tria.get_communicator(), &status);
3320 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
3322 receive.resize(len);
3324 char *ptr = receive.data();
3325 ierr = MPI_Recv(ptr, len, MPI_BYTE, status.MPI_SOURCE, status.MPI_TAG,
3326 tria.get_communicator(), &status);
3329 cell_data_transfer_buffer.unpack_data(receive);
3332 for (
unsigned int c=0; c<cell_data_transfer_buffer.tree_indices.size(); ++c)
3334 typename DoFHandlerType::level_cell_iterator
3335 cell (&dof_handler.get_triangulation(),
3337 p4est_tree_to_coarse_cell_permutation[cell_data_transfer_buffer.tree_indices[c]],
3340 typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
3341 internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
3343 get_mg_dofindices_recursively<dim,spacedim> (tria,
3346 cell_data_transfer_buffer.quadrants[c],
3347 cell_data_transfer_buffer);
3351 reply_buffers[idx] = cell_data_transfer_buffer.pack_data();
3352 ierr = MPI_Isend(&(reply_buffers[idx])[0], reply_buffers[idx].size(),
3353 MPI_BYTE, status.MPI_SOURCE,
3354 1100102, tria.get_communicator(), &reply_requests[idx]);
3359 for (
unsigned int idx=0; idx<level_ghost_owners.size(); ++idx)
3361 std::vector<char> receive;
3362 CellDataTransferBuffer<dim> cell_data_transfer_buffer;
3366 int ierr = MPI_Probe(MPI_ANY_SOURCE, 1100102, tria.get_communicator(), &status);
3368 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
3370 receive.resize(len);
3372 char *ptr = receive.data();
3373 ierr = MPI_Recv(ptr, len, MPI_BYTE, status.MPI_SOURCE, status.MPI_TAG,
3374 tria.get_communicator(), &status);
3377 cell_data_transfer_buffer.unpack_data(receive);
3378 if (cell_data_transfer_buffer.tree_indices.size()==0)
3383 for (
unsigned int c=0; c<cell_data_transfer_buffer.tree_indices.size(); ++c, dofs+=1+dofs[0])
3385 typename DoFHandlerType::level_cell_iterator
3388 p4est_tree_to_coarse_cell_permutation[cell_data_transfer_buffer.tree_indices[c]],
3391 typename ::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
3392 internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
3396 set_mg_dofindices_recursively<dim,spacedim> (tria,
3399 cell_data_transfer_buffer.quadrants[c],
3406 if (requests.size() > 0)
3408 const int ierr = MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
3411 if (reply_requests.size() > 0)
3413 const int ierr = MPI_Waitall(reply_requests.size(), reply_requests.data(), MPI_STATUSES_IGNORE);
3420 template <
int spacedim>
3424 const std::vector<::types::global_dof_index> &,
3425 const std::vector<::types::global_dof_index> &)
3433 template <
int spacedim>
3437 const std::vector<::types::global_dof_index> &,
3438 const std::vector<::types::global_dof_index> &)
3463 template <
int spacedim>
3465 communicate_dof_indices_on_marked_cells
3467 const std::map<
unsigned int, std::set<::types::subdomain_id> > &,
3468 const std::vector<::types::global_dof_index> &,
3469 const std::vector<::types::global_dof_index> &)
3476 template <
int spacedim>
3478 communicate_dof_indices_on_marked_cells
3480 const std::map<
unsigned int, std::set<::types::subdomain_id> > &,
3481 const std::vector<::types::global_dof_index> &,
3482 const std::vector<::types::global_dof_index> &)
3489 template <
class DoFHandlerType>
3491 communicate_dof_indices_on_marked_cells
3492 (
const DoFHandlerType &dof_handler,
3493 const std::map<
unsigned int, std::set<::types::subdomain_id> > &,
3494 const std::vector<::types::global_dof_index> &,
3495 const std::vector<::types::global_dof_index> &)
3497 #ifndef DEAL_II_WITH_MPI 3498 (void)vertices_with_ghost_neighbors;
3501 const unsigned int dim = DoFHandlerType::dimension;
3502 const unsigned int spacedim = DoFHandlerType::space_dimension;
3508 = [] (
const typename DoFHandlerType::active_cell_iterator &cell) -> boost::optional<std::vector<types::global_dof_index>>
3516 if (cell->user_flag_set())
3519 std::vector<types::global_dof_index> local_dof_indices (cell->get_fe().dofs_per_cell);
3520 cell->get_dof_indices (local_dof_indices);
3529 if (std::find (local_dof_indices.begin(),
3530 local_dof_indices.end(),
3533 local_dof_indices.end())
3538 cell->clear_user_flag();
3540 return local_dof_indices;
3549 std::vector<types::global_dof_index> local_dof_indices (cell->get_fe().dofs_per_cell);
3550 cell->get_dof_indices (local_dof_indices);
3552 const bool is_complete
3554 == local_dof_indices.end());
3557 return boost::optional<std::vector<types::global_dof_index>>();
3562 = [] (
const typename DoFHandlerType::active_cell_iterator &cell,
3563 const std::vector<types::global_dof_index> &received_dof_indices) ->
void 3579 const bool is_complete
3581 == received_dof_indices.end());
3583 cell->clear_user_flag();
3597 std::vector<types::global_dof_index> local_dof_indices (cell->get_fe().dofs_per_cell);
3598 cell->update_cell_dof_indices_cache();
3599 cell->get_dof_indices (local_dof_indices);
3601 for (
unsigned int i=0; i<local_dof_indices.size(); ++i)
3603 local_dof_indices[i] = received_dof_indices[i];
3609 (received_dof_indices[i] == local_dof_indices[i]),
3612 const_cast<typename DoFHandlerType::active_cell_iterator &
>(cell)->set_dof_indices(local_dof_indices);
3615 GridTools::exchange_cell_data_to_ghosts<std::vector<types::global_dof_index>, DoFHandlerType>
3620 update_all_active_cell_dof_indices_caches (dof_handler);
3636 if (
const auto *triangulation =
3639 const int ierr = MPI_Barrier(triangulation->get_communicator());
3644 Assert(
false,
ExcMessage(
"The function communicate_dof_indices_on_marked_cells() " 3645 "only works with parallel distributed triangulations."));
3658 #endif // DEAL_II_WITH_P4EST 3662 template <
class DoFHandlerType>
3666 dof_handler (&dof_handler)
3674 template <
class DoFHandlerType>
3679 #ifndef DEAL_II_WITH_P4EST 3683 const unsigned int dim = DoFHandlerType::dimension;
3684 const unsigned int spacedim = DoFHandlerType::space_dimension;
3689 (&dof_handler->get_triangulation())));
3714 const ::types::global_dof_index n_initial_local_dofs =
3715 Implementation::distribute_dofs (triangulation->locally_owned_subdomain(),
3722 std::vector<::types::global_dof_index> renumbering(n_initial_local_dofs);
3727 std::vector<::types::global_dof_index> local_dof_indices;
3729 for (
auto cell : dof_handler->active_cell_iterators())
3730 if (cell->is_ghost()
3732 (cell->subdomain_id() < triangulation->locally_owned_subdomain()))
3740 local_dof_indices.resize (cell->get_fe().dofs_per_cell);
3741 cell->get_dof_indices (local_dof_indices);
3742 for (
auto &local_dof_index : local_dof_indices)
3744 renumbering[local_dof_index]
3752 for (
auto &new_index : renumbering)
3754 new_index = n_locally_owned_dofs++;
3758 std::vector<::types::global_dof_index> n_locally_owned_dofs_per_processor(n_cpus);
3760 const int ierr = MPI_Allgather ( &n_locally_owned_dofs,
3761 1, DEAL_II_DOF_INDEX_MPI_TYPE,
3762 n_locally_owned_dofs_per_processor.data(),
3763 1, DEAL_II_DOF_INDEX_MPI_TYPE,
3764 triangulation->get_communicator());
3767 const ::types::global_dof_index
3768 my_shift = std::accumulate (n_locally_owned_dofs_per_processor.begin(),
3769 n_locally_owned_dofs_per_processor.begin()
3770 + triangulation->locally_owned_subdomain(),
3772 for (
auto &new_index : renumbering)
3774 new_index += my_shift;
3779 Implementation::renumber_dofs (renumbering,
IndexSet(0),
3780 *dof_handler,
false);
3783 const ::types::global_dof_index n_global_dofs
3784 = std::accumulate (n_locally_owned_dofs_per_processor.begin(),
3785 n_locally_owned_dofs_per_processor.end(),
3788 std::vector<IndexSet> locally_owned_dofs_per_processor (n_cpus,
3792 for (
unsigned int i=0; i<n_cpus; ++i)
3794 locally_owned_dofs_per_processor[i]
3795 .add_range(current_shift,
3797 n_locally_owned_dofs_per_processor[i]);
3798 current_shift += n_locally_owned_dofs_per_processor[i];
3801 NumberCache number_cache (locally_owned_dofs_per_processor,
3802 triangulation->locally_owned_subdomain());
3803 Assert(number_cache.locally_owned_dofs_per_processor
3804 [triangulation->locally_owned_subdomain()].n_elements()
3806 number_cache.n_locally_owned_dofs,
3808 Assert(!number_cache.locally_owned_dofs_per_processor
3809 [triangulation->locally_owned_subdomain()].n_elements()
3811 number_cache.locally_owned_dofs_per_processor
3812 [triangulation->locally_owned_subdomain()].nth_index_in_set(0)
3824 std::vector<bool> user_flags;
3825 triangulation->save_user_flags(user_flags);
3826 triangulation->clear_user_flags ();
3830 const std::map<unsigned int, std::set<::types::subdomain_id> >
3831 vertices_with_ghost_neighbors
3832 = triangulation->compute_vertices_with_ghost_neighbors ();
3837 for (
auto cell : dof_handler->active_cell_iterators())
3838 if (cell->is_locally_owned())
3840 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
3841 if (vertices_with_ghost_neighbors.find (cell->vertex_index(v))
3842 != vertices_with_ghost_neighbors.end())
3844 cell->set_user_flag();
3848 else if (cell->is_ghost())
3849 cell->set_user_flag();
3859 communicate_dof_indices_on_marked_cells (*dof_handler,
3860 vertices_with_ghost_neighbors,
3861 triangulation->coarse_cell_to_p4est_tree_permutation,
3862 triangulation->p4est_tree_to_coarse_cell_permutation);
3864 communicate_dof_indices_on_marked_cells (*dof_handler,
3865 vertices_with_ghost_neighbors,
3866 triangulation->coarse_cell_to_p4est_tree_permutation,
3867 triangulation->p4est_tree_to_coarse_cell_permutation);
3872 for (
auto cell : dof_handler->active_cell_iterators())
3873 Assert (cell->user_flag_set() ==
false,
3877 triangulation->load_user_flags(user_flags);
3883 std::vector<::types::global_dof_index> local_dof_indices;
3885 for (
auto cell : dof_handler->active_cell_iterators())
3886 if (!cell->is_artificial())
3888 local_dof_indices.resize (cell->get_fe().dofs_per_cell);
3889 cell->get_dof_indices (local_dof_indices);
3890 if (local_dof_indices.end() !=
3891 std::find (local_dof_indices.begin(),
3892 local_dof_indices.end(),
3895 if (cell->is_ghost())
3898 ExcMessage (
"A ghost cell ended up with incomplete " 3899 "DoF index information. This should not " 3905 ExcMessage (
"A locally owned cell ended up with incomplete " 3906 "DoF index information. This should not " 3913 return number_cache;
3914 #endif // DEAL_II_WITH_P4EST 3919 template <
class DoFHandlerType>
3920 std::vector<NumberCache>
3924 #ifndef DEAL_II_WITH_P4EST 3926 return std::vector<NumberCache>();
3928 const unsigned int dim = DoFHandlerType::dimension;
3929 const unsigned int spacedim = DoFHandlerType::space_dimension;
3934 (&dof_handler->get_triangulation())));
3939 ExcMessage(
"Multigrid DoFs can only be distributed on a parallel " 3940 "Triangulation if the flag construct_multigrid_hierarchy " 3941 "is set in the constructor."));
3952 const unsigned int n_levels = triangulation->n_global_levels();
3953 std::vector<NumberCache> number_caches;
3954 number_caches.reserve(n_levels);
3955 for (
unsigned int level = 0; level < n_levels; ++level)
3960 const unsigned int n_initial_local_dofs =
3961 Implementation::distribute_dofs_on_level(triangulation->locally_owned_subdomain(),
3967 std::vector<::types::global_dof_index> renumbering(n_initial_local_dofs);
3971 if (level < triangulation->n_levels())
3973 std::vector<::types::global_dof_index> local_dof_indices;
3975 typename DoFHandlerType::level_cell_iterator
3976 cell = dof_handler->begin(level),
3977 endc = dof_handler->
end(level);
3979 for (; cell != endc; ++cell)
3981 (cell->level_subdomain_id() < triangulation->locally_owned_subdomain()))
3990 local_dof_indices.resize (cell->get_fe().dofs_per_cell);
3991 cell->get_mg_dof_indices (local_dof_indices);
3992 for (
unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
3994 renumbering[local_dof_indices[i]]
4002 for (std::vector<::types::global_dof_index>::iterator it=renumbering.begin();
4003 it!=renumbering.end(); ++it)
4012 1, DEAL_II_DOF_INDEX_MPI_TYPE,
4014 1, DEAL_II_DOF_INDEX_MPI_TYPE,
4015 triangulation->get_communicator());
4018 const ::types::global_dof_index
4019 shift = std::accumulate (level_number_cache
4020 .n_locally_owned_dofs_per_processor.begin(),
4023 + triangulation->locally_owned_subdomain(),
4025 for (std::vector<::types::global_dof_index>::iterator it=renumbering.begin();
4026 it!=renumbering.end(); ++it)
4038 if (level < triangulation->n_levels())
4039 Implementation::renumber_mg_dofs (renumbering,
IndexSet(0),
4040 *dof_handler, level,
4045 = std::accumulate (level_number_cache
4046 .n_locally_owned_dofs_per_processor.begin(),
4061 for (
unsigned int i=0; i<n_cpus; ++i)
4066 .add_range(current_shift,
4073 [triangulation->locally_owned_subdomain()].n_elements()
4078 [triangulation->locally_owned_subdomain()].n_elements()
4081 [triangulation->locally_owned_subdomain()].nth_index_in_set(0)
4085 number_caches.emplace_back (level_number_cache);
4094 std::vector<bool> user_flags;
4095 triangulation->save_user_flags(user_flags);
4096 triangulation->clear_user_flags ();
4100 typename DoFHandlerType::level_cell_iterator
4101 cell, endc = dof_handler->
end();
4102 for (cell = dof_handler->begin(); cell != endc; ++cell)
4103 if (cell->level_subdomain_id() != ::numbers::artificial_subdomain_id
4104 && !cell->is_locally_owned_on_level())
4105 cell->set_user_flag();
4111 communicate_mg_ghost_cells(*triangulation,
4113 triangulation->coarse_cell_to_p4est_tree_permutation,
4114 triangulation->p4est_tree_to_coarse_cell_permutation);
4129 const int ierr = MPI_Barrier(triangulation->get_communicator());
4134 communicate_mg_ghost_cells(*triangulation,
4136 triangulation->coarse_cell_to_p4est_tree_permutation,
4137 triangulation->p4est_tree_to_coarse_cell_permutation);
4142 typename DoFHandlerType::level_cell_iterator
4143 cell, endc = dof_handler->
end();
4144 for (cell = dof_handler->begin(); cell != endc; ++cell)
4145 if (cell->level_subdomain_id() != ::numbers::artificial_subdomain_id
4146 && !cell->is_locally_owned_on_level())
4151 triangulation->load_user_flags(user_flags);
4160 std::vector<::types::global_dof_index> local_dof_indices;
4161 typename DoFHandlerType::level_cell_iterator
4162 cell, endc = dof_handler->
end();
4164 for (cell = dof_handler->begin(); cell != endc; ++cell)
4165 if (cell->level_subdomain_id() != ::numbers::artificial_subdomain_id)
4167 local_dof_indices.resize (cell->get_fe().dofs_per_cell);
4168 cell->get_mg_dof_indices (local_dof_indices);
4169 if (local_dof_indices.end() !=
4170 std::find (local_dof_indices.begin(),
4171 local_dof_indices.end(),
4180 return number_caches;
4182 #endif // DEAL_II_WITH_P4EST 4186 template <
class DoFHandlerType>
4193 Assert (new_numbers.size() == dof_handler->n_locally_owned_dofs(),
4196 #ifndef DEAL_II_WITH_P4EST 4200 const unsigned int dim = DoFHandlerType::dimension;
4201 const unsigned int spacedim = DoFHandlerType::space_dimension;
4206 (&dof_handler->get_triangulation())));
4218 IndexSet my_locally_owned_new_dof_indices (dof_handler->n_dofs());
4219 if (dof_handler->n_locally_owned_dofs() > 0)
4221 std::vector<::types::global_dof_index> new_numbers_sorted = new_numbers;
4222 std::sort(new_numbers_sorted.begin(), new_numbers_sorted.end());
4224 my_locally_owned_new_dof_indices.add_indices (new_numbers_sorted.begin(),
4225 new_numbers_sorted.end());
4226 my_locally_owned_new_dof_indices.compress();
4228 Assert (my_locally_owned_new_dof_indices.n_elements() == new_numbers.size(),
4244 std::vector<::types::global_dof_index> local_dof_indices;
4246 for (
auto cell : dof_handler->active_cell_iterators())
4247 if (cell->is_ghost())
4249 local_dof_indices.resize (cell->get_fe().dofs_per_cell);
4250 cell->get_dof_indices (local_dof_indices);
4252 for (
unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
4258 (!dof_handler->locally_owned_dofs().is_element(local_dof_indices[i])))
4261 cell->set_dof_indices (local_dof_indices);
4267 if (dof_handler->locally_owned_dofs().n_elements() > 0)
4268 Implementation::renumber_dofs (new_numbers,
4269 dof_handler->locally_owned_dofs(),
4278 std::vector<bool> user_flags;
4279 triangulation->save_user_flags(user_flags);
4280 triangulation->clear_user_flags ();
4283 for (
auto cell : dof_handler->active_cell_iterators())
4284 if (!cell->is_artificial())
4285 cell->set_user_flag();
4289 const std::map<unsigned int, std::set<::types::subdomain_id> >
4290 vertices_with_ghost_neighbors
4291 = triangulation->compute_vertices_with_ghost_neighbors ();
4300 communicate_dof_indices_on_marked_cells (*dof_handler,
4301 vertices_with_ghost_neighbors,
4302 triangulation->coarse_cell_to_p4est_tree_permutation,
4303 triangulation->p4est_tree_to_coarse_cell_permutation);
4305 communicate_dof_indices_on_marked_cells (*dof_handler,
4306 vertices_with_ghost_neighbors,
4307 triangulation->coarse_cell_to_p4est_tree_permutation,
4308 triangulation->p4est_tree_to_coarse_cell_permutation);
4310 triangulation->load_user_flags(user_flags);
4324 std::vector<IndexSet> locally_owned_dofs_per_processor(n_cpus,
4328 std::vector<char> my_data;
4330 #ifdef DEAL_II_WITH_ZLIB 4332 boost::iostreams::filtering_ostream out;
4333 out.push(boost::iostreams::gzip_compressor
4334 (boost::iostreams::gzip_params
4335 (boost::iostreams::gzip::best_compression)));
4336 out.push(boost::iostreams::back_inserter(my_data));
4338 boost::archive::binary_oarchive archive(out);
4340 archive << my_locally_owned_new_dof_indices;
4343 std::ostringstream out;
4344 boost::archive::binary_oarchive archive(out);
4345 archive << my_locally_owned_new_dof_indices;
4346 const std::string &s = out.str();
4347 my_data.reserve(s.size());
4348 my_data.assign(s.begin(), s.end());
4353 const unsigned int max_size
4359 my_data.resize(max_size);
4361 std::vector<char> buffer(max_size*n_cpus);
4362 const int ierr = MPI_Allgather(my_data.data(), max_size, MPI_BYTE,
4363 buffer.data(), max_size, MPI_BYTE,
4364 triangulation->get_communicator());
4367 for (
unsigned int i=0; i<n_cpus; ++i)
4369 locally_owned_dofs_per_processor[i] = my_locally_owned_new_dof_indices;
4374 std::string decompressed_buffer;
4378 #ifdef DEAL_II_WITH_ZLIB 4380 boost::iostreams::filtering_ostream decompressing_stream;
4381 decompressing_stream.push(boost::iostreams::gzip_decompressor());
4382 decompressing_stream.push(boost::iostreams::back_inserter(decompressed_buffer));
4384 decompressing_stream.write(&buffer[i*max_size], max_size);
4386 decompressed_buffer.assign (&buffer[i*max_size], max_size);
4391 std::istringstream in(decompressed_buffer);
4392 boost::archive::binary_iarchive archive(in);
4394 archive >> locally_owned_dofs_per_processor[i];
4398 return NumberCache (locally_owned_dofs_per_processor,
4405 template <
class DoFHandlerType>
4409 const std::vector<types::global_dof_index> &new_numbers)
const 4414 const std::vector<IndexSet> &index_sets = dof_handler->locally_owned_mg_dofs_per_processor(level);
4416 constexpr
int dim = DoFHandlerType::dimension;
4417 constexpr
int spacedim = DoFHandlerType::space_dimension;
4420 (&this->dof_handler->get_triangulation()));
4423 #ifdef DEAL_II_WITH_MPI 4429 Assert(index_sets[my_rank].is_element(i),
4431 "partitioning are currently not implemented for " 4432 "the multigrid levels"));
4441 std::vector<types::global_dof_index> ghosted_new_numbers(relevant_dofs.
n_elements());
4445 std::vector<types::global_dof_index> temp_array(partitioner.n_import_indices());
4446 const unsigned int communication_channel = 17;
4447 std::vector<MPI_Request> requests;
4449 (communication_channel,
4450 make_array_view(new_numbers),
4451 make_array_view(temp_array),
4453 new_numbers.size(), partitioner.n_ghost_indices()),
4455 partitioner.export_to_ghosted_array_finish
4457 new_numbers.size(), partitioner.n_ghost_indices()),
4464 unsigned int n_ghosts_on_smaller_ranks = 0;
4465 for (std::pair<unsigned int,unsigned int> t : partitioner.ghost_targets())
4467 if (t.first > my_rank)
4469 n_ghosts_on_smaller_ranks += t.second;
4471 if (n_ghosts_on_smaller_ranks>0)
4474 std::memmove(ghosted_new_numbers.data(),
4475 ghosted_new_numbers.data()+new_numbers.size(),
4478 if (new_numbers.size()>0)
4481 std::memcpy(ghosted_new_numbers.data()+n_ghosts_on_smaller_ranks,
4489 if (level < this->dof_handler->get_triangulation().n_levels())
4490 Implementation::renumber_mg_dofs (ghosted_new_numbers, relevant_dofs,
4491 *dof_handler, level,
true);
4508 #include "dof_handler_policy.inst" 4511 DEAL_II_NAMESPACE_CLOSE
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const
unsigned int n_active_cells() const
std::vector< MGVertexDoFs > mg_vertex_dofs
static const unsigned int invalid_unsigned_int
const types::subdomain_id invalid_subdomain_id
cell_iterator begin(const unsigned int level=0) const
virtual NumberCache distribute_dofs() const
unsigned int n_cells() const
size_type nth_index_in_set(const unsigned int local_index) const
Task< RT > new_task(const std::function< RT()> &function)
const std::vector< types::subdomain_id > & get_true_subdomain_ids_of_cells() const
cell_iterator end() const
IndexSet locally_owned_dofs
const unsigned int dofs_per_quad
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
std::vector< std::unique_ptr<::internal::DoFHandlerImplementation::DoFLevel< dim > > > levels
active_cell_iterator begin_active(const unsigned int level=0) const
T unpack(const std::vector< char > &buffer)
ActiveSelector::active_cell_iterator active_cell_iterator
active_cell_iterator begin_active(const unsigned int level=0) const
virtual std::vector< NumberCache > distribute_mg_dofs() const
#define AssertThrow(cond, exc)
const unsigned int dofs_per_line
const std::vector< types::subdomain_id > & get_true_level_subdomain_ids_of_cells(const unsigned int level) const
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const
hp::FECollection< dim, spacedim > fe_collection
ActiveSelector::active_cell_iterator active_cell_iterator
active_cell_iterator begin_active(const unsigned int level=0) const
const hp::FECollection< dim, spacedim > & get_fe() const
types::global_dof_index n_locally_owned_dofs
static ::ExceptionBase & ExcMessage(std::string arg1)
ParallelDistributed(DoFHandlerType &dof_handler)
ActiveSelector::cell_iterator cell_iterator
unsigned int global_dof_index
const unsigned int dofs_per_hex
#define Assert(cond, exc)
virtual std::vector< NumberCache > distribute_mg_dofs() const
IteratorRange< active_cell_iterator > active_cell_iterators() const
size_type index_within_set(const size_type global_index) const
Sequential(DoFHandlerType &dof_handler)
virtual MPI_Comm get_communicator() const
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const
std::vector< types::global_dof_index > n_locally_owned_dofs_per_processor
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
virtual NumberCache distribute_dofs() const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
std::unique_ptr<::internal::DoFHandlerImplementation::DoFFaces< dim > > faces
unsigned int subdomain_id
const hp::FECollection< dim, spacedim > & get_fe_collection() const
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
virtual unsigned int n_global_levels() const
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
const std::set< types::subdomain_id > & level_ghost_owners() const
void add_range(const size_type begin, const size_type end)
const types::subdomain_id artificial_subdomain_id
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
#define AssertThrowMPI(error_code)
virtual NumberCache renumber_mg_dofs(const unsigned int level, const std::vector< types::global_dof_index > &new_numbers) const
const Triangulation< dim, spacedim > & get_triangulation() const
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const
size_t pack(const T &object, std::vector< char > &dest_buffer)
bool with_artificial_cells() const
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)
std::vector< IndexSet > locally_owned_dofs_per_processor
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
static ::ExceptionBase & ExcNotImplemented()
const Triangulation< dim, spacedim > & get_triangulation() const
Iterator points to a valid object.
const unsigned int dofs_per_vertex
static unsigned int n_threads()
virtual std::vector< NumberCache > distribute_mg_dofs() const
ParallelShared(DoFHandlerType &dof_handler)
bool is_element(const size_type index) const
types::global_dof_index n_global_dofs
virtual NumberCache distribute_dofs() const
types::subdomain_id locally_owned_subdomain() const
const types::global_dof_index invalid_dof_index
virtual NumberCache renumber_dofs(const std::vector< types::global_dof_index > &new_numbers) const
size_type n_elements() const
cell_iterator end() const
T max(const T &t, const MPI_Comm &mpi_communicator)
virtual FiniteElementDomination::Domination compare_for_face_domination(const FiniteElement< dim, spacedim > &fe_other) const
std::vector< types::global_dof_index > vertex_dofs
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
static ::ExceptionBase & ExcInternalError()