45 template <
int dim,
int spacedim,
typename Number>
47 refine_and_coarsen_fixed_fraction_via_l1_norm(
50 const double top_fraction,
51 const double bottom_fraction,
52 const unsigned int max_n_cells)
57 std::sort(criteria_sorted.
begin(),
58 criteria_sorted.
end(),
59 std::greater<double>());
61 const double total_error = criteria_sorted.
l1_norm();
66 (
sum < top_fraction * total_error) && (pp != criteria_sorted.
end());
69 double top_threshold =
70 (pp != criteria_sorted.
begin() ? (*pp + *(pp - 1)) / 2 : *pp);
73 for (
double sum = 0; (
sum < bottom_fraction * total_error) &&
74 (qq != criteria_sorted.
begin() - 1);
77 double bottom_threshold =
78 ((qq != criteria_sorted.
end() - 1) ? (*qq + *(qq + 1)) / 2 : 0.);
92 const unsigned int refine_cells = pp - criteria_sorted.
begin(),
93 coarsen_cells = criteria_sorted.
end() - 1 - qq;
95 if (
static_cast<unsigned int>(
142 const double max_criterion = *(criteria_sorted.
begin()),
143 min_criterion = *(criteria_sorted.
end() - 1);
145 if ((top_threshold == max_criterion) && (top_fraction != 1))
146 top_threshold *= 0.999;
148 if (bottom_threshold >= top_threshold)
149 bottom_threshold = 0.999 * top_threshold;
152 if (top_threshold < max_criterion)
155 if (bottom_threshold > min_criterion)
162template <
int dim,
typename Number,
int spacedim>
166 const double threshold,
167 const unsigned int max_to_mark)
179 const unsigned int n_cells = criteria.
size();
183 double new_threshold = threshold;
187 if (new_threshold == 0)
189 new_threshold = criteria(0);
190 for (
unsigned int index = 1; index < n_cells; ++index)
191 if (criteria(index) > 0 && (criteria(index) < new_threshold))
192 new_threshold = criteria(index);
195 unsigned int marked = 0;
199 cell->is_locally_owned()) &&
200 std::fabs(criteria(cell->active_cell_index())) >= new_threshold)
203 marked >= max_to_mark)
206 cell->set_refine_flag();
212template <
int dim,
typename Number,
int spacedim>
216 const double threshold)
225 cell->is_locally_owned()) &&
226 std::fabs(criteria(cell->active_cell_index())) <= threshold)
227 if (!cell->refine_flag_set())
228 cell->set_coarsen_flag();
234std::pair<double, double>
238 const double top_fraction,
239 const double bottom_fraction)
241 Assert(top_fraction >= 0, ExcInvalidParameterValue());
242 Assert(top_fraction <= 1, ExcInvalidParameterValue());
243 Assert(bottom_fraction >= 0, ExcInvalidParameterValue());
244 Assert(bottom_fraction <= 1, ExcInvalidParameterValue());
245 Assert(top_fraction + bottom_fraction <=
246 1 + 10 * std::numeric_limits<double>::epsilon(),
247 ExcInvalidParameterValue());
249 double refine_cells = current_n_cells * top_fraction;
250 double coarsen_cells = current_n_cells * bottom_fraction;
252 const double cell_increase_on_refine =
254 const double cell_decrease_on_coarsen =
257 std::pair<double, double> adjusted_fractions(top_fraction, bottom_fraction);
261 if (current_n_cells >= max_n_cells)
273 adjusted_fractions.first = 0;
275 (current_n_cells - max_n_cells) / cell_decrease_on_coarsen;
276 adjusted_fractions.second =
277 std::min(coarsen_cells / current_n_cells, 1.0);
293 current_n_cells + refine_cells * cell_increase_on_refine -
294 coarsen_cells * cell_decrease_on_coarsen) > max_n_cells)
304 const double alpha = 1. * (max_n_cells - current_n_cells) /
305 (refine_cells * cell_increase_on_refine -
306 coarsen_cells * cell_decrease_on_coarsen);
308 adjusted_fractions.first = alpha * top_fraction;
309 adjusted_fractions.second = alpha * bottom_fraction;
311 return (adjusted_fractions);
316template <
int dim,
typename Number,
int spacedim>
321 const double top_fraction,
322 const double bottom_fraction,
323 const unsigned int max_n_cells)
327 Assert((top_fraction >= 0) && (top_fraction <= 1),
328 ExcInvalidParameterValue());
329 Assert((bottom_fraction >= 0) && (bottom_fraction <= 1),
330 ExcInvalidParameterValue());
331 Assert(top_fraction + bottom_fraction <=
332 1 + 10 * std::numeric_limits<double>::epsilon(),
333 ExcInvalidParameterValue());
336 const std::pair<double, double> adjusted_fractions =
337 adjust_refine_and_coarsen_number_fraction<dim>(criteria.
size(),
342 const int refine_cells =
343 static_cast<int>(adjusted_fractions.first * criteria.
size());
344 const int coarsen_cells =
345 static_cast<int>(adjusted_fractions.second * criteria.
size());
347 if (refine_cells || coarsen_cells)
352 if (
static_cast<size_t>(refine_cells) == criteria.
size())
353 refine(tria, criteria, std::numeric_limits<double>::lowest());
356 std::nth_element(tmp.
begin(),
357 tmp.
begin() + refine_cells - 1,
359 std::greater<double>());
360 refine(tria, criteria, *(tmp.
begin() + refine_cells - 1));
366 if (
static_cast<size_t>(coarsen_cells) == criteria.
size())
367 coarsen(tria, criteria, std::numeric_limits<double>::max());
370 std::nth_element(tmp.
begin(),
371 tmp.
begin() + tmp.
size() - coarsen_cells,
373 std::greater<double>());
376 *(tmp.
begin() + tmp.
size() - coarsen_cells));
384template <
int dim,
typename Number,
int spacedim>
389 const double top_fraction,
390 const double bottom_fraction,
391 const unsigned int max_n_cells,
395 Assert((top_fraction >= 0) && (top_fraction <= 1),
396 ExcInvalidParameterValue());
397 Assert((bottom_fraction >= 0) && (bottom_fraction <= 1),
398 ExcInvalidParameterValue());
399 Assert(top_fraction + bottom_fraction <=
400 1 + 10 * std::numeric_limits<double>::epsilon(),
401 ExcInvalidParameterValue());
409 refine_and_coarsen_fixed_fraction_via_l1_norm(
410 tria, criteria, top_fraction, bottom_fraction, max_n_cells);
422 std::transform(criteria.
begin(),
424 criteria_squared.
begin(),
425 [](Number c) { return c * c; });
427 refine_and_coarsen_fixed_fraction_via_l1_norm(tria,
445template <
int dim,
typename Number,
int spacedim>
449 const unsigned int order)
456 std::vector<unsigned int> cell_indices(criteria.
size());
457 std::iota(cell_indices.begin(), cell_indices.end(), 0u);
459 std::sort(cell_indices.begin(),
461 [&criteria](
const unsigned int left,
const unsigned int right) {
462 return criteria[left] > criteria[right];
465 double expected_error_reduction = 0;
466 const double original_error = criteria.
l1_norm();
468 const std::size_t N = criteria.
size();
471 double min_cost = std::numeric_limits<double>::max();
472 std::size_t min_arg = 0;
474 const double reduction_factor = (1. -
std::pow(2., -1. * order));
475 for (std::size_t M = 0; M < criteria.
size(); ++M)
477 expected_error_reduction += reduction_factor * criteria(cell_indices[M]);
481 static_cast<double>(order) / dim) *
482 (original_error - expected_error_reduction);
483 if (cost <= min_cost)
490 refine(tria, criteria, criteria(cell_indices[min_arg]));
495#include "grid_refinement.inst"
unsigned int n_active_cells() const
const value_type * const_iterator
virtual size_type size() const override
bool is_non_negative() const
real_type l1_norm() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
IteratorRange< active_cell_iterator > active_cell_iterators() const
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
#define DEAL_II_NOT_IMPLEMENTED()
void refine(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold, const unsigned int max_to_mark=numbers::invalid_unsigned_int)
void refine_and_coarsen_fixed_number(Triangulation< dim, spacedim > &triangulation, const Vector< Number > &criteria, const double top_fraction_of_cells, const double bottom_fraction_of_cells, const unsigned int max_n_cells=std::numeric_limits< unsigned int >::max())
void refine_and_coarsen_optimize(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const unsigned int order=2)
void coarsen(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold)
std::pair< double, double > adjust_refine_and_coarsen_number_fraction(const types::global_cell_index current_n_cells, const types::global_cell_index max_n_cells, const double top_fraction_of_cells, const double bottom_fraction_of_cells)
void refine_and_coarsen_fixed_fraction(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double top_fraction, const double bottom_fraction, const unsigned int max_n_cells=std::numeric_limits< unsigned int >::max(), const VectorTools::NormType norm_type=VectorTools::L1_norm)
T sum(const T &t, const MPI_Comm mpi_communicator)
constexpr T fixed_power(const T t)
static const unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)