69 const std::vector<bool> &p_flags)
71 if (dof_handler.get_fe_collection().empty())
75 Assert(dof_handler.has_hp_capabilities(),
80 for (
const auto &cell : dof_handler.active_cell_iterators())
81 if (cell->is_locally_owned() && p_flags[cell->active_cell_index()])
83 if (cell->refine_flag_set())
85 const unsigned int super_fe_index =
86 dof_handler.get_fe_collection().next_in_hierarchy(
87 cell->active_fe_index());
90 if (super_fe_index != cell->active_fe_index())
91 cell->set_future_fe_index(super_fe_index);
93 else if (cell->coarsen_flag_set())
95 const unsigned int sub_fe_index =
96 dof_handler.get_fe_collection().previous_in_hierarchy(
97 cell->active_fe_index());
100 if (sub_fe_index != cell->active_fe_index())
101 cell->set_future_fe_index(sub_fe_index);
113 const Number p_refine_threshold,
114 const Number p_coarsen_threshold,
120 if (dof_handler.get_fe_collection().empty())
124 Assert(dof_handler.has_hp_capabilities(),
129 std::vector<bool> p_flags(
130 dof_handler.get_triangulation().n_active_cells(),
false);
132 for (
const auto &cell : dof_handler.active_cell_iterators())
133 if (cell->is_locally_owned() &&
134 ((cell->refine_flag_set() &&
135 compare_refine(criteria[cell->active_cell_index()],
136 p_refine_threshold)) ||
137 (cell->coarsen_flag_set() &&
138 compare_coarsen(criteria[cell->active_cell_index()],
139 p_coarsen_threshold))))
140 p_flags[cell->active_cell_index()] =
true;
152 const double p_refine_fraction,
153 const double p_coarsen_fraction,
159 if (dof_handler.get_fe_collection().empty())
163 Assert(dof_handler.has_hp_capabilities(),
167 Assert((p_refine_fraction >= 0) && (p_refine_fraction <= 1),
169 Assert((p_coarsen_fraction >= 0) && (p_coarsen_fraction <= 1),
174 Number max_criterion_refine = std::numeric_limits<Number>::lowest(),
175 min_criterion_refine = std::numeric_limits<Number>::max();
176 Number max_criterion_coarsen = max_criterion_refine,
177 min_criterion_coarsen = min_criterion_refine;
179 for (
const auto &cell : dof_handler.active_cell_iterators())
180 if (cell->is_locally_owned())
182 if (cell->refine_flag_set())
184 max_criterion_refine =
186 criteria(cell->active_cell_index()));
187 min_criterion_refine =
189 criteria(cell->active_cell_index()));
191 else if (cell->coarsen_flag_set())
193 max_criterion_coarsen =
195 criteria(cell->active_cell_index()));
196 min_criterion_coarsen =
198 criteria(cell->active_cell_index()));
204 &dof_handler.get_triangulation());
205 if (parallel_tria !=
nullptr &&
207 &dof_handler.get_triangulation()) ==
nullptr)
209 max_criterion_refine =
212 min_criterion_refine =
215 max_criterion_coarsen =
218 min_criterion_coarsen =
225 const Number threshold_refine =
226 min_criterion_refine +
228 (max_criterion_refine - min_criterion_refine),
230 min_criterion_coarsen +
232 (max_criterion_coarsen - min_criterion_coarsen);
249 const double p_refine_fraction,
250 const double p_coarsen_fraction,
256 if (dof_handler.get_fe_collection().empty())
260 Assert(dof_handler.has_hp_capabilities(),
264 Assert((p_refine_fraction >= 0) && (p_refine_fraction <= 1),
266 Assert((p_coarsen_fraction >= 0) && (p_coarsen_fraction <= 1),
274 [](
const Number &,
const Number &) {
return false; };
276 [](
const Number &,
const Number &) {
return true; };
280 unsigned int n_flags_refinement = 0;
281 unsigned int n_flags_coarsening = 0;
283 dof_handler.get_triangulation().n_active_cells());
285 dof_handler.get_triangulation().n_active_cells());
286 for (
const auto &cell :
287 dof_handler.get_triangulation().active_cell_iterators())
288 if (!cell->is_artificial() && cell->is_locally_owned())
290 if (cell->refine_flag_set())
291 indicators_refinement(n_flags_refinement++) =
292 criteria(cell->active_cell_index());
293 else if (cell->coarsen_flag_set())
294 indicators_coarsening(n_flags_coarsening++) =
295 criteria(cell->active_cell_index());
316 Number threshold_refinement = 0.;
317 Number threshold_coarsening = 0.;
318 auto reference_compare_refine = std::cref(compare_refine);
319 auto reference_compare_coarsen = std::cref(compare_coarsen);
323 &dof_handler.get_triangulation());
324 if (parallel_tria !=
nullptr &&
326 &dof_handler.get_triangulation()) ==
nullptr)
328#ifndef DEAL_II_WITH_P4EST
339 const unsigned int n_global_flags_refinement =
341 const unsigned int n_global_flags_coarsening =
344 const unsigned int target_index_refinement =
345 static_cast<unsigned int>(
346 std::floor(p_refine_fraction * n_global_flags_refinement));
347 const unsigned int target_index_coarsening =
348 static_cast<unsigned int>(
349 std::ceil((1 - p_coarsen_fraction) * n_global_flags_coarsening));
353 const std::pair<Number, Number> global_min_max_refinement =
358 const std::pair<Number, Number> global_min_max_coarsening =
364 if (target_index_refinement == 0)
365 reference_compare_refine = std::cref(compare_false);
366 else if (target_index_refinement == n_global_flags_refinement)
367 reference_compare_refine = std::cref(compare_true);
371 indicators_refinement,
372 global_min_max_refinement,
373 target_index_refinement,
376 if (target_index_coarsening == n_global_flags_coarsening)
377 reference_compare_coarsen = std::cref(compare_false);
378 else if (target_index_coarsening == 0)
379 reference_compare_coarsen = std::cref(compare_true);
383 indicators_coarsening,
384 global_min_max_coarsening,
385 target_index_coarsening,
396 const unsigned int n_p_refine_cells =
static_cast<unsigned int>(
397 std::floor(p_refine_fraction * n_flags_refinement));
398 const unsigned int n_p_coarsen_cells =
static_cast<unsigned int>(
399 std::floor(p_coarsen_fraction * n_flags_coarsening));
402 if (n_p_refine_cells == 0)
403 reference_compare_refine = std::cref(compare_false);
404 else if (n_p_refine_cells == n_flags_refinement)
405 reference_compare_refine = std::cref(compare_true);
408 std::nth_element(indicators_refinement.
begin(),
409 indicators_refinement.
begin() +
410 n_p_refine_cells - 1,
411 indicators_refinement.
end(),
412 std::greater<Number>());
413 threshold_refinement =
414 *(indicators_refinement.
begin() + n_p_refine_cells - 1);
417 if (n_p_coarsen_cells == 0)
418 reference_compare_coarsen = std::cref(compare_false);
419 else if (n_p_coarsen_cells == n_flags_coarsening)
420 reference_compare_coarsen = std::cref(compare_true);
423 std::nth_element(indicators_coarsening.
begin(),
424 indicators_coarsening.
begin() +
425 n_p_coarsen_cells - 1,
426 indicators_coarsening.
end(),
427 std::less<Number>());
428 threshold_coarsening =
429 *(indicators_coarsening.
begin() + n_p_coarsen_cells - 1);
436 threshold_refinement,
437 threshold_coarsening,
438 std::cref(reference_compare_refine),
440 reference_compare_coarsen));
450 if (dof_handler.get_fe_collection().empty())
454 Assert(dof_handler.has_hp_capabilities(),
457 sobolev_indices.
size());
459 for (
const auto &cell : dof_handler.active_cell_iterators())
460 if (cell->is_locally_owned())
462 if (cell->refine_flag_set())
464 const unsigned int super_fe_index =
465 dof_handler.get_fe_collection().next_in_hierarchy(
466 cell->active_fe_index());
469 if (super_fe_index != cell->active_fe_index())
471 const unsigned int super_fe_degree =
472 dof_handler.get_fe_collection()[super_fe_index].degree;
474 if (sobolev_indices[cell->active_cell_index()] >
476 cell->set_future_fe_index(super_fe_index);
479 else if (cell->coarsen_flag_set())
481 const unsigned int sub_fe_index =
482 dof_handler.get_fe_collection().previous_in_hierarchy(
483 cell->active_fe_index());
486 if (sub_fe_index != cell->active_fe_index())
488 const unsigned int sub_fe_degree =
489 dof_handler.get_fe_collection()[sub_fe_index].degree;
491 if (sobolev_indices[cell->active_cell_index()] <
493 cell->set_future_fe_index(sub_fe_index);
512 if (dof_handler.get_fe_collection().empty())
516 Assert(dof_handler.has_hp_capabilities(),
523 std::vector<bool> p_flags(
524 dof_handler.get_triangulation().n_active_cells(),
false);
526 for (
const auto &cell : dof_handler.active_cell_iterators())
527 if (cell->is_locally_owned() &&
528 ((cell->refine_flag_set() &&
529 compare_refine(criteria[cell->active_cell_index()],
530 references[cell->active_cell_index()])) ||
531 (cell->coarsen_flag_set() &&
532 compare_coarsen(criteria[cell->active_cell_index()],
533 references[cell->active_cell_index()]))))
534 p_flags[cell->active_cell_index()] =
true;
549 const double gamma_p,
550 const double gamma_h,
551 const double gamma_n)
553 if (dof_handler.get_fe_collection().empty())
558 error_indicators.
size());
560 predicted_errors.
size());
561 Assert(0 < gamma_p && gamma_p < 1,
571 std::map<typename DoFHandler<dim, spacedim>::cell_iterator,
unsigned int>
572 future_fe_indices_on_coarsened_cells;
575 predicted_errors = error_indicators;
577 for (
const auto &cell : dof_handler.active_cell_iterators() |
581 if (!(cell->future_fe_index_set()) && !(cell->refine_flag_set()) &&
582 !(cell->coarsen_flag_set()))
584 predicted_errors[cell->active_cell_index()] *= gamma_n;
590 if (cell->coarsen_flag_set())
593 ExcMessage(
"A coarse cell is flagged for coarsening. "
594 "Please read the note in the documentation "
595 "of predict_error()."));
599 const auto &parent = cell->parent();
600 if (future_fe_indices_on_coarsened_cells.find(parent) ==
601 future_fe_indices_on_coarsened_cells.end())
605 for (
const auto &child : parent->child_iterators())
606 Assert(child->is_active() && child->coarsen_flag_set(),
608 dim>::ExcInconsistentCoarseningFlags());
611 parent_future_fe_index =
615 future_fe_indices_on_coarsened_cells.insert(
616 {parent, parent_future_fe_index});
620 parent_future_fe_index =
621 future_fe_indices_on_coarsened_cells[parent];
625 dof_handler.get_fe_collection()[parent_future_fe_index].degree;
631 dof_handler.get_fe_collection()[cell->future_fe_index()].degree;
635 if (cell->future_fe_index_set())
637 if (future_fe_degree > cell->get_fe().degree)
638 predicted_errors[cell->active_cell_index()] *=
640 future_fe_degree - cell->get_fe().degree);
641 else if (future_fe_degree < cell->
get_fe().degree)
642 predicted_errors[cell->active_cell_index()] /=
644 cell->get_fe().degree - future_fe_degree);
653 if (cell->refine_flag_set())
655 predicted_errors[cell->active_cell_index()] *=
661 else if (cell->coarsen_flag_set())
663 predicted_errors[cell->active_cell_index()] /=
702 if (dof_handler.get_fe_collection().empty())
706 Assert(dof_handler.has_hp_capabilities(),
716 &dof_handler.get_triangulation())))
726 for (
const auto &cell : dof_handler.active_cell_iterators())
727 if (cell->is_locally_owned() && cell->future_fe_index_set())
732 cell->clear_refine_flag();
738 if (cell->coarsen_flag_set())
740 if (cell->level() == 0)
745 cell->clear_coarsen_flag();
749 const auto &parent = cell->parent();
750 const unsigned int n_children = parent->n_children();
752 unsigned int h_flagged_children = 0, p_flagged_children = 0;
753 for (
const auto &child : parent->child_iterators())
755 if (child->is_active())
757 Assert(child->is_artificial() ==
false,
760 if (child->coarsen_flag_set())
761 ++h_flagged_children;
770 future_fe_index_set<dim, spacedim, false>(
772 ++p_flagged_children;
776 if (h_flagged_children == n_children &&
777 p_flagged_children != n_children)
781 for (
const auto &child : parent->child_iterators())
786 if (child->is_locally_owned())
787 child->clear_future_fe_index();
794 for (
const auto &child : parent->child_iterators())
796 if (child->is_active() && child->is_locally_owned())
797 child->clear_coarsen_flag();
812 const unsigned int max_difference,
813 const unsigned int contains_fe_index)
815 if (dof_handler.get_fe_collection().empty())
819 Assert(dof_handler.has_hp_capabilities(),
824 "This function does not serve any purpose for max_difference = 0."));
826 dof_handler.get_fe_collection().size());
836 const auto invalid_level =
static_cast<level_type
>(-1);
840 const std::vector<unsigned int> fe_index_for_hierarchy_level =
841 dof_handler.get_fe_collection().get_hierarchy_sequence(
847 std::vector<unsigned int> hierarchy_level_for_fe_index(
848 dof_handler.get_fe_collection().size(), invalid_level);
849 for (
unsigned int l = 0; l < fe_index_for_hierarchy_level.size(); ++l)
850 hierarchy_level_for_fe_index[fe_index_for_hierarchy_level[l]] = l;
863 if (
const auto parallel_tria =
865 &(dof_handler.get_triangulation())))
868 parallel_tria->global_active_cell_index_partitioner().lock());
873 dof_handler.get_triangulation().n_active_cells());
876 for (
const auto &cell : dof_handler.active_cell_iterators() |
878 future_levels[cell->global_active_cell_index()] =
879 hierarchy_level_for_fe_index[cell->future_fe_index()];
894 const auto update_neighbor_level =
895 [&future_levels, max_difference, invalid_level](
896 const auto &neighbor,
const level_type cell_level) ->
bool {
901 if (neighbor->is_locally_owned())
903 const level_type neighbor_level =
static_cast<level_type
>(
904 future_levels[neighbor->global_active_cell_index()]);
907 if (neighbor_level == invalid_level)
910 if ((cell_level - max_difference) > neighbor_level)
912 future_levels[neighbor->global_active_cell_index()] =
913 cell_level - max_difference;
937 const auto prepare_level_for_parent = [&](
const auto &neighbor) ->
bool {
939 if (neighbor->coarsen_flag_set() && neighbor->is_locally_owned())
941 const auto parent = neighbor->parent();
943 std::vector<unsigned int> future_levels_children;
944 future_levels_children.reserve(parent->n_children());
945 for (
const auto &child : parent->child_iterators())
947 Assert(child->is_active() && child->coarsen_flag_set(),
949 ExcInconsistentCoarseningFlags()));
951 const level_type child_level =
static_cast<level_type
>(
952 future_levels[child->global_active_cell_index()]);
953 Assert(child_level != invalid_level,
955 "The FiniteElement on one of the siblings of "
956 "a cell you are trying to coarsen is not part "
957 "of the registered p-adaptation hierarchy."));
958 future_levels_children.push_back(child_level);
962 const unsigned int max_level_children =
963 *std::max_element(future_levels_children.begin(),
964 future_levels_children.end());
966 bool children_changed =
false;
967 for (
const auto &child : parent->child_iterators())
971 if (child->is_locally_owned() &&
972 future_levels[child->global_active_cell_index()] !=
975 future_levels[child->global_active_cell_index()] =
977 children_changed =
true;
979 return children_changed;
985 bool levels_changed =
false;
986 bool levels_changed_in_cycle;
989 levels_changed_in_cycle =
false;
993 for (
const auto &cell : dof_handler.active_cell_iterators())
994 if (!cell->is_artificial())
996 const level_type cell_level =
static_cast<level_type
>(
997 future_levels[cell->global_active_cell_index()]);
1000 if (cell_level == invalid_level)
1005 if (cell_level <= max_difference)
1008 for (
unsigned int f = 0; f < cell->n_faces(); ++f)
1009 if (cell->face(f)->at_boundary() ==
false)
1011 if (cell->face(f)->has_children())
1013 for (
unsigned int sf = 0;
1014 sf < cell->face(f)->n_children();
1017 const auto neighbor =
1018 cell->neighbor_child_on_subface(f, sf);
1020 levels_changed_in_cycle |=
1021 update_neighbor_level(neighbor, cell_level);
1023 levels_changed_in_cycle |=
1024 prepare_level_for_parent(neighbor);
1029 const auto neighbor = cell->neighbor(f);
1031 levels_changed_in_cycle |=
1032 update_neighbor_level(neighbor, cell_level);
1034 levels_changed_in_cycle |=
1035 prepare_level_for_parent(neighbor);
1040 levels_changed_in_cycle =
1042 dof_handler.get_mpi_communicator());
1043 levels_changed |= levels_changed_in_cycle;
1045 while (levels_changed_in_cycle);
1048 for (
const auto &cell : dof_handler.active_cell_iterators() |
1051 const level_type cell_level =
static_cast<level_type
>(
1052 future_levels[cell->global_active_cell_index()]);
1054 if (cell_level != invalid_level)
1056 const unsigned int fe_index =
1057 fe_index_for_hierarchy_level[cell_level];
1059 if (fe_index != cell->active_fe_index())
1060 cell->set_future_fe_index(fe_index);
1062 cell->clear_future_fe_index();
1066 return levels_changed;