25#include <deal.II/dofs/dof_accessor.templates.h>
46 template <
int dim,
int spacedim>
50 if (dof_handler.get_fe_collection().size() == 0)
55 dof_handler.has_hp_capabilities(),
56 (typename ::DoFHandler<dim, spacedim>::ExcOnlyAvailableWithHP()));
58 std::vector<bool> p_flags(
59 dof_handler.get_triangulation().n_active_cells(),
true);
66 template <
int dim,
int spacedim>
69 const ::DoFHandler<dim, spacedim> &dof_handler,
70 const std::vector<bool> & p_flags)
72 if (dof_handler.get_fe_collection().size() == 0)
77 dof_handler.has_hp_capabilities(),
78 (typename ::DoFHandler<dim, spacedim>::ExcOnlyAvailableWithHP()));
82 for (
const auto &cell : dof_handler.active_cell_iterators())
83 if (cell->is_locally_owned() && p_flags[cell->active_cell_index()])
85 if (cell->refine_flag_set())
87 const unsigned int super_fe_index =
88 dof_handler.get_fe_collection().next_in_hierarchy(
89 cell->active_fe_index());
92 if (super_fe_index != cell->active_fe_index())
93 cell->set_future_fe_index(super_fe_index);
95 else if (cell->coarsen_flag_set())
97 const unsigned int sub_fe_index =
98 dof_handler.get_fe_collection().previous_in_hierarchy(
99 cell->active_fe_index());
102 if (sub_fe_index != cell->active_fe_index())
103 cell->set_future_fe_index(sub_fe_index);
110 template <
int dim,
typename Number,
int spacedim>
113 const ::DoFHandler<dim, spacedim> &dof_handler,
115 const Number p_refine_threshold,
116 const Number p_coarsen_threshold,
121 if (dof_handler.get_fe_collection().size() == 0)
126 dof_handler.has_hp_capabilities(),
127 (typename ::DoFHandler<dim, spacedim>::ExcOnlyAvailableWithHP()));
131 std::vector<bool> p_flags(
132 dof_handler.get_triangulation().n_active_cells(),
false);
134 for (
const auto &cell : dof_handler.active_cell_iterators())
135 if (cell->is_locally_owned() &&
136 ((cell->refine_flag_set() &&
137 compare_refine(criteria[cell->active_cell_index()],
138 p_refine_threshold)) ||
139 (cell->coarsen_flag_set() &&
140 compare_coarsen(criteria[cell->active_cell_index()],
141 p_coarsen_threshold))))
142 p_flags[cell->active_cell_index()] =
true;
149 template <
int dim,
typename Number,
int spacedim>
152 const ::DoFHandler<dim, spacedim> &dof_handler,
154 const double p_refine_fraction,
155 const double p_coarsen_fraction,
160 if (dof_handler.get_fe_collection().size() == 0)
165 dof_handler.has_hp_capabilities(),
166 (typename ::DoFHandler<dim, spacedim>::ExcOnlyAvailableWithHP()));
169 Assert((p_refine_fraction >= 0) && (p_refine_fraction <= 1),
171 Assert((p_coarsen_fraction >= 0) && (p_coarsen_fraction <= 1),
176 Number max_criterion_refine = std::numeric_limits<Number>::lowest(),
177 min_criterion_refine = std::numeric_limits<Number>::max();
178 Number max_criterion_coarsen = max_criterion_refine,
179 min_criterion_coarsen = min_criterion_refine;
181 for (
const auto &cell : dof_handler.active_cell_iterators())
182 if (cell->is_locally_owned())
184 if (cell->refine_flag_set())
186 max_criterion_refine =
188 criteria(cell->active_cell_index()));
189 min_criterion_refine =
191 criteria(cell->active_cell_index()));
193 else if (cell->coarsen_flag_set())
195 max_criterion_coarsen =
197 criteria(cell->active_cell_index()));
198 min_criterion_coarsen =
200 criteria(cell->active_cell_index()));
206 &dof_handler.get_triangulation());
207 if (parallel_tria !=
nullptr &&
209 &dof_handler.get_triangulation()) ==
nullptr)
211 max_criterion_refine =
214 min_criterion_refine =
217 max_criterion_coarsen =
220 min_criterion_coarsen =
227 const Number threshold_refine =
228 min_criterion_refine +
230 (max_criterion_refine - min_criterion_refine),
232 min_criterion_coarsen +
234 (max_criterion_coarsen - min_criterion_coarsen);
246 template <
int dim,
typename Number,
int spacedim>
249 const ::DoFHandler<dim, spacedim> &dof_handler,
251 const double p_refine_fraction,
252 const double p_coarsen_fraction,
257 if (dof_handler.get_fe_collection().size() == 0)
262 dof_handler.has_hp_capabilities(),
263 (typename ::DoFHandler<dim, spacedim>::ExcOnlyAvailableWithHP()));
266 Assert((p_refine_fraction >= 0) && (p_refine_fraction <= 1),
268 Assert((p_coarsen_fraction >= 0) && (p_coarsen_fraction <= 1),
276 [](
const Number &,
const Number &) {
return false; };
278 [](
const Number &,
const Number &) {
return true; };
282 unsigned int n_flags_refinement = 0;
283 unsigned int n_flags_coarsening = 0;
285 dof_handler.get_triangulation().n_active_cells());
287 dof_handler.get_triangulation().n_active_cells());
288 for (
const auto &cell :
289 dof_handler.get_triangulation().active_cell_iterators())
290 if (!cell->is_artificial() && cell->is_locally_owned())
292 if (cell->refine_flag_set())
293 indicators_refinement(n_flags_refinement++) =
294 criteria(cell->active_cell_index());
295 else if (cell->coarsen_flag_set())
296 indicators_coarsening(n_flags_coarsening++) =
297 criteria(cell->active_cell_index());
318 Number threshold_refinement = 0.;
319 Number threshold_coarsening = 0.;
320 auto reference_compare_refine = std::cref(compare_refine);
321 auto reference_compare_coarsen = std::cref(compare_coarsen);
325 &dof_handler.get_triangulation());
326 if (parallel_tria !=
nullptr &&
328 &dof_handler.get_triangulation()) ==
nullptr)
330#ifndef DEAL_II_WITH_P4EST
341 const unsigned int n_global_flags_refinement =
343 const unsigned int n_global_flags_coarsening =
346 const unsigned int target_index_refinement =
347 static_cast<unsigned int>(
348 std::floor(p_refine_fraction * n_global_flags_refinement));
349 const unsigned int target_index_coarsening =
350 static_cast<unsigned int>(
351 std::ceil((1 - p_coarsen_fraction) * n_global_flags_coarsening));
355 const std::pair<Number, Number> global_min_max_refinement =
360 const std::pair<Number, Number> global_min_max_coarsening =
366 if (target_index_refinement == 0)
367 reference_compare_refine = std::cref(compare_false);
368 else if (target_index_refinement == n_global_flags_refinement)
369 reference_compare_refine = std::cref(compare_true);
373 indicators_refinement,
374 global_min_max_refinement,
375 target_index_refinement,
378 if (target_index_coarsening == n_global_flags_coarsening)
379 reference_compare_coarsen = std::cref(compare_false);
380 else if (target_index_coarsening == 0)
381 reference_compare_coarsen = std::cref(compare_true);
385 indicators_coarsening,
386 global_min_max_coarsening,
387 target_index_coarsening,
398 const unsigned int n_p_refine_cells =
static_cast<unsigned int>(
399 std::floor(p_refine_fraction * n_flags_refinement));
400 const unsigned int n_p_coarsen_cells =
static_cast<unsigned int>(
401 std::floor(p_coarsen_fraction * n_flags_coarsening));
404 if (n_p_refine_cells == 0)
405 reference_compare_refine = std::cref(compare_false);
406 else if (n_p_refine_cells == n_flags_refinement)
407 reference_compare_refine = std::cref(compare_true);
410 std::nth_element(indicators_refinement.
begin(),
411 indicators_refinement.
begin() +
412 n_p_refine_cells - 1,
413 indicators_refinement.
end(),
414 std::greater<Number>());
415 threshold_refinement =
416 *(indicators_refinement.
begin() + n_p_refine_cells - 1);
419 if (n_p_coarsen_cells == 0)
420 reference_compare_coarsen = std::cref(compare_false);
421 else if (n_p_coarsen_cells == n_flags_coarsening)
422 reference_compare_coarsen = std::cref(compare_true);
425 std::nth_element(indicators_coarsening.
begin(),
426 indicators_coarsening.
begin() +
427 n_p_coarsen_cells - 1,
428 indicators_coarsening.
end(),
429 std::less<Number>());
430 threshold_coarsening =
431 *(indicators_coarsening.
begin() + n_p_coarsen_cells - 1);
438 threshold_refinement,
439 threshold_coarsening,
440 std::cref(reference_compare_refine),
442 reference_compare_coarsen));
447 template <
int dim,
typename Number,
int spacedim>
450 const ::DoFHandler<dim, spacedim> &dof_handler,
453 if (dof_handler.get_fe_collection().size() == 0)
458 dof_handler.has_hp_capabilities(),
459 (typename ::DoFHandler<dim, spacedim>::ExcOnlyAvailableWithHP()));
461 sobolev_indices.
size());
463 for (
const auto &cell : dof_handler.active_cell_iterators())
464 if (cell->is_locally_owned())
466 if (cell->refine_flag_set())
468 const unsigned int super_fe_index =
469 dof_handler.get_fe_collection().next_in_hierarchy(
470 cell->active_fe_index());
473 if (super_fe_index != cell->active_fe_index())
475 const unsigned int super_fe_degree =
476 dof_handler.get_fe_collection()[super_fe_index].degree;
478 if (sobolev_indices[cell->active_cell_index()] >
480 cell->set_future_fe_index(super_fe_index);
483 else if (cell->coarsen_flag_set())
485 const unsigned int sub_fe_index =
486 dof_handler.get_fe_collection().previous_in_hierarchy(
487 cell->active_fe_index());
490 if (sub_fe_index != cell->active_fe_index())
492 const unsigned int sub_fe_degree =
493 dof_handler.get_fe_collection()[sub_fe_index].degree;
495 if (sobolev_indices[cell->active_cell_index()] <
497 cell->set_future_fe_index(sub_fe_index);
505 template <
int dim,
typename Number,
int spacedim>
508 const ::DoFHandler<dim, spacedim> & dof_handler,
515 if (dof_handler.get_fe_collection().size() == 0)
520 dof_handler.has_hp_capabilities(),
521 (typename ::DoFHandler<dim, spacedim>::ExcOnlyAvailableWithHP()));
527 std::vector<bool> p_flags(
528 dof_handler.get_triangulation().n_active_cells(),
false);
530 for (
const auto &cell : dof_handler.active_cell_iterators())
531 if (cell->is_locally_owned() &&
532 ((cell->refine_flag_set() &&
533 compare_refine(criteria[cell->active_cell_index()],
534 references[cell->active_cell_index()])) ||
535 (cell->coarsen_flag_set() &&
536 compare_coarsen(criteria[cell->active_cell_index()],
537 references[cell->active_cell_index()]))))
538 p_flags[cell->active_cell_index()] =
true;
548 template <
int dim,
typename Number,
int spacedim>
553 const double gamma_p,
554 const double gamma_h,
555 const double gamma_n)
557 if (dof_handler.get_fe_collection().size() == 0)
562 error_indicators.
size());
564 predicted_errors.
size());
565 Assert(0 < gamma_p && gamma_p < 1,
575 std::map<typename DoFHandler<dim, spacedim>::cell_iterator,
unsigned int>
576 future_fe_indices_on_coarsened_cells;
579 predicted_errors = error_indicators;
581 for (
const auto &cell : dof_handler.active_cell_iterators() |
585 if (!(cell->future_fe_index_set()) && !(cell->refine_flag_set()) &&
586 !(cell->coarsen_flag_set()))
588 predicted_errors[cell->active_cell_index()] *= gamma_n;
594 if (cell->coarsen_flag_set())
598 const auto &parent = cell->parent();
599 if (future_fe_indices_on_coarsened_cells.find(parent) ==
600 future_fe_indices_on_coarsened_cells.end())
603 for (
const auto &child : parent->child_iterators())
604 Assert(child->is_active() && child->coarsen_flag_set(),
605 typename ::Triangulation<
606 dim>::ExcInconsistentCoarseningFlags());
609 parent_future_fe_index =
610 ::internal::hp::DoFHandlerImplementation::
611 dominated_future_fe_on_children<dim, spacedim>(parent);
613 future_fe_indices_on_coarsened_cells.insert(
614 {parent, parent_future_fe_index});
618 parent_future_fe_index =
619 future_fe_indices_on_coarsened_cells[parent];
623 dof_handler.get_fe_collection()[parent_future_fe_index].degree;
629 dof_handler.get_fe_collection()[cell->future_fe_index()].degree;
633 if (cell->future_fe_index_set())
635 predicted_errors[cell->active_cell_index()] *=
637 int(future_fe_degree) -
int(cell->get_fe().degree));
641 if (cell->refine_flag_set())
643 predicted_errors[cell->active_cell_index()] *=
644 (gamma_h *
std::pow(.5, future_fe_degree));
649 else if (cell->coarsen_flag_set())
651 predicted_errors[cell->active_cell_index()] /=
652 (gamma_h *
std::pow(.5, future_fe_degree));
665 template <
int dim,
int spacedim>
669 if (dof_handler.get_fe_collection().size() == 0)
674 dof_handler.has_hp_capabilities(),
675 (typename ::DoFHandler<dim, spacedim>::ExcOnlyAvailableWithHP()));
677 for (
const auto &cell : dof_handler.active_cell_iterators())
678 if (cell->is_locally_owned() && cell->future_fe_index_set())
680 cell->clear_refine_flag();
681 cell->clear_coarsen_flag();
687 template <
int dim,
int spacedim>
691 if (dof_handler.get_fe_collection().size() == 0)
696 dof_handler.has_hp_capabilities(),
697 (typename ::DoFHandler<dim, spacedim>::ExcOnlyAvailableWithHP()));
703 &dof_handler.get_triangulation()) !=
nullptr)
708 for (
const auto &cell : dof_handler.active_cell_iterators())
709 if (cell->is_locally_owned() && cell->future_fe_index_set())
711 cell->clear_refine_flag();
717 if (cell->coarsen_flag_set())
719 const auto & parent = cell->parent();
720 const unsigned int n_children = parent->n_children();
722 unsigned int h_flagged_children = 0, p_flagged_children = 0;
723 for (
const auto &child : parent->child_iterators())
725 if (child->is_active())
727 if (child->is_locally_owned())
729 if (child->coarsen_flag_set())
730 ++h_flagged_children;
731 if (child->future_fe_index_set())
732 ++p_flagged_children;
734 else if (child->is_ghost())
740 (
dynamic_cast<const parallel::shared::
741 Triangulation<dim, spacedim> *
>(
742 &dof_handler.get_triangulation()) !=
nullptr),
745 if (child->coarsen_flag_set())
746 ++h_flagged_children;
753 DoFCellAccessorImplementation::
755 future_fe_index_set<dim, spacedim, false>(
757 ++p_flagged_children;
768 if (h_flagged_children == n_children &&
769 p_flagged_children != n_children)
773 for (
const auto &child : parent->child_iterators())
778 if (child->is_locally_owned())
779 child->clear_future_fe_index();
786 for (
const auto &child : parent->child_iterators())
788 if (child->is_active() && child->is_locally_owned())
789 child->clear_coarsen_flag();
801 template <
int dim,
int spacedim>
804 const ::DoFHandler<dim, spacedim> &dof_handler,
805 const unsigned int max_difference,
806 const unsigned int contains_fe_index)
808 if (dof_handler.get_fe_collection().size() == 0)
813 dof_handler.has_hp_capabilities(),
814 (typename ::DoFHandler<dim, spacedim>::ExcOnlyAvailableWithHP()));
818 "This function does not serve any purpose for max_difference = 0."));
820 dof_handler.get_fe_collection().size());
830 typename ::DoFHandler<dim, spacedim>::active_fe_index_type;
831 const auto invalid_level =
static_cast<level_type
>(-1);
835 const std::vector<unsigned int> fe_index_for_hierarchy_level =
836 dof_handler.get_fe_collection().get_hierarchy_sequence(
842 std::vector<unsigned int> hierarchy_level_for_fe_index(
843 dof_handler.get_fe_collection().size(), invalid_level);
844 for (
unsigned int l = 0; l < fe_index_for_hierarchy_level.size(); ++l)
845 hierarchy_level_for_fe_index[fe_index_for_hierarchy_level[l]] = l;
858 if (
const auto parallel_tria =
860 &(dof_handler.get_triangulation())))
863 parallel_tria->global_active_cell_index_partitioner().lock());
868 dof_handler.get_triangulation().n_active_cells());
871 for (
const auto &cell : dof_handler.active_cell_iterators() |
873 future_levels[cell->global_active_cell_index()] =
874 hierarchy_level_for_fe_index[cell->future_fe_index()];
889 const auto update_neighbor_level =
890 [&future_levels, max_difference, invalid_level](
891 const auto &neighbor,
const level_type cell_level) ->
bool {
896 if (neighbor->is_locally_owned())
898 const level_type neighbor_level =
static_cast<level_type
>(
899 future_levels[neighbor->global_active_cell_index()]);
902 if (neighbor_level == invalid_level)
905 if ((cell_level - max_difference) > neighbor_level)
907 future_levels[neighbor->global_active_cell_index()] =
908 cell_level - max_difference;
932 const auto prepare_level_for_parent = [&](
const auto &neighbor) ->
bool {
934 if (neighbor->coarsen_flag_set() && neighbor->is_locally_owned())
936 const auto parent = neighbor->parent();
938 std::vector<unsigned int> future_levels_children;
939 future_levels_children.reserve(parent->n_children());
940 for (
const auto &child : parent->child_iterators())
942 Assert(child->is_active() && child->coarsen_flag_set(),
943 (typename ::Triangulation<dim, spacedim>::
944 ExcInconsistentCoarseningFlags()));
946 const level_type child_level =
static_cast<level_type
>(
947 future_levels[child->global_active_cell_index()]);
948 Assert(child_level != invalid_level,
950 "The FiniteElement on one of the siblings of "
951 "a cell you are trying to coarsen is not part "
952 "of the registered p-adaptation hierarchy."));
953 future_levels_children.push_back(child_level);
957 const unsigned int max_level_children =
958 *std::max_element(future_levels_children.begin(),
959 future_levels_children.end());
961 bool children_changed =
false;
962 for (
const auto &child : parent->child_iterators())
966 if (child->is_locally_owned() &&
967 future_levels[child->global_active_cell_index()] !=
970 future_levels[child->global_active_cell_index()] =
972 children_changed =
true;
974 return children_changed;
980 bool levels_changed =
false;
981 bool levels_changed_in_cycle;
984 levels_changed_in_cycle =
false;
988 for (
const auto &cell : dof_handler.active_cell_iterators())
989 if (!cell->is_artificial())
991 const level_type cell_level =
static_cast<level_type
>(
992 future_levels[cell->global_active_cell_index()]);
995 if (cell_level == invalid_level)
1000 if (cell_level <= max_difference)
1003 for (
unsigned int f = 0; f < cell->n_faces(); ++f)
1004 if (cell->face(f)->at_boundary() ==
false)
1006 if (cell->face(f)->has_children())
1008 for (
unsigned int sf = 0;
1009 sf < cell->face(f)->n_children();
1012 const auto neighbor =
1013 cell->neighbor_child_on_subface(f, sf);
1015 levels_changed_in_cycle |=
1016 update_neighbor_level(neighbor, cell_level);
1018 levels_changed_in_cycle |=
1019 prepare_level_for_parent(neighbor);
1024 const auto neighbor = cell->neighbor(f);
1026 levels_changed_in_cycle |=
1027 update_neighbor_level(neighbor, cell_level);
1029 levels_changed_in_cycle |=
1030 prepare_level_for_parent(neighbor);
1035 levels_changed_in_cycle =
1037 dof_handler.get_communicator());
1038 levels_changed |= levels_changed_in_cycle;
1040 while (levels_changed_in_cycle);
1043 for (
const auto &cell : dof_handler.active_cell_iterators() |
1046 const level_type cell_level =
static_cast<level_type
>(
1047 future_levels[cell->global_active_cell_index()]);
1049 if (cell_level != invalid_level)
1051 const unsigned int fe_index =
1052 fe_index_for_hierarchy_level[cell_level];
1055 if (fe_index != cell->active_fe_index())
1056 cell->set_future_fe_index(fe_index);
1060 return levels_changed;
1067#include "refinement.inst"
virtual MPI_Comm get_communicator() const override
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInvalidParameterValue()
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
void update_ghost_values() const
void grow_or_shrink(const size_type N)
void reinit(const size_type size, const bool omit_zeroing_entries=false)
T logical_or(const T &t, const MPI_Comm &mpi_communicator)
T min(const T &t, const MPI_Comm &mpi_communicator)
T sum(const T &t, const MPI_Comm &mpi_communicator)
T max(const T &t, const MPI_Comm &mpi_communicator)
void p_adaptivity_from_reference(const ::DoFHandler< dim, spacedim > &dof_handler, const Vector< Number > &criteria, const Vector< Number > &references, const ComparisonFunction< typename identity< Number >::type > &compare_refine, const ComparisonFunction< typename identity< Number >::type > &compare_coarsen)
bool limit_p_level_difference(const ::DoFHandler< dim, spacedim > &dof_handler, const unsigned int max_difference=1, const unsigned int contains_fe_index=0)
void choose_p_over_h(const ::DoFHandler< dim, spacedim > &dof_handler)
void p_adaptivity_from_flags(const ::DoFHandler< dim, spacedim > &dof_handler, const std::vector< bool > &p_flags)
void p_adaptivity_from_relative_threshold(const ::DoFHandler< dim, spacedim > &dof_handler, const Vector< Number > &criteria, const double p_refine_fraction=0.5, const double p_coarsen_fraction=0.5, const ComparisonFunction< typename identity< Number >::type > &compare_refine=std::greater_equal< Number >(), const ComparisonFunction< typename identity< Number >::type > &compare_coarsen=std::less_equal< Number >())
void p_adaptivity_fixed_number(const ::DoFHandler< dim, spacedim > &dof_handler, const Vector< Number > &criteria, const double p_refine_fraction=0.5, const double p_coarsen_fraction=0.5, const ComparisonFunction< typename identity< Number >::type > &compare_refine=std::greater_equal< Number >(), const ComparisonFunction< typename identity< Number >::type > &compare_coarsen=std::less_equal< Number >())
void force_p_over_h(const ::DoFHandler< dim, spacedim > &dof_handler)
void full_p_adaptivity(const ::DoFHandler< dim, spacedim > &dof_handler)
void p_adaptivity_from_absolute_threshold(const ::DoFHandler< dim, spacedim > &dof_handler, const Vector< Number > &criteria, const Number p_refine_threshold, const Number p_coarsen_threshold, const ComparisonFunction< typename identity< Number >::type > &compare_refine=std::greater_equal< Number >(), const ComparisonFunction< typename identity< Number >::type > &compare_coarsen=std::less_equal< Number >())
void predict_error(const ::DoFHandler< dim, spacedim > &dof_handler, const Vector< Number > &error_indicators, Vector< Number > &predicted_errors, const double gamma_p=std::sqrt(0.4), const double gamma_h=2., const double gamma_n=1.)
std::function< bool(const Number &, const Number &)> ComparisonFunction
void p_adaptivity_from_regularity(const ::DoFHandler< dim, spacedim > &dof_handler, const Vector< Number > &sobolev_indices)
void communicate_future_fe_indices(DoFHandler< dim, spacedim > &dof_handler)
number compute_threshold(const ::Vector< number > &criteria, const std::pair< double, double > &global_min_and_max, const types::global_cell_index n_target_cells, const MPI_Comm &mpi_communicator)
std::pair< number, number > compute_global_min_and_max_at_root(const ::Vector< number > &criteria, const MPI_Comm &mpi_communicator)
static const unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)