43 template <
int dim,
int spacedim,
typename Number>
45 refine_and_coarsen_fixed_fraction_via_l1_norm(
48 const double top_fraction,
49 const double bottom_fraction,
50 const unsigned int max_n_cells)
55 std::sort(criteria_sorted.
begin(),
56 criteria_sorted.
end(),
57 std::greater<double>());
59 const double total_error = criteria_sorted.
l1_norm();
64 (
sum < top_fraction * total_error) && (pp != criteria_sorted.
end());
67 double top_threshold =
68 (pp != criteria_sorted.
begin() ? (*pp + *(pp - 1)) / 2 : *pp);
71 for (
double sum = 0; (
sum < bottom_fraction * total_error) &&
72 (qq != criteria_sorted.
begin() - 1);
75 double bottom_threshold =
76 ((qq != criteria_sorted.
end() - 1) ? (*qq + *(qq + 1)) / 2 : 0.);
90 const unsigned int refine_cells = pp - criteria_sorted.
begin(),
91 coarsen_cells = criteria_sorted.
end() - 1 - qq;
93 if (
static_cast<unsigned int>(
140 const double max_criterion = *(criteria_sorted.
begin()),
141 min_criterion = *(criteria_sorted.
end() - 1);
143 if ((top_threshold == max_criterion) && (top_fraction != 1))
144 top_threshold *= 0.999;
146 if (bottom_threshold >= top_threshold)
147 bottom_threshold = 0.999 * top_threshold;
150 if (top_threshold < max_criterion)
153 if (bottom_threshold > min_criterion)
160template <
int dim,
typename Number,
int spacedim>
164 const double threshold,
165 const unsigned int max_to_mark)
177 const unsigned int n_cells = criteria.
size();
181 double new_threshold = threshold;
185 if (new_threshold == 0)
187 new_threshold = criteria(0);
188 for (
unsigned int index = 1; index < n_cells; ++index)
189 if (criteria(index) > 0 && (criteria(index) < new_threshold))
190 new_threshold = criteria(index);
193 unsigned int marked = 0;
197 cell->is_locally_owned()) &&
198 std::fabs(criteria(cell->active_cell_index())) >= new_threshold)
201 marked >= max_to_mark)
204 cell->set_refine_flag();
210template <
int dim,
typename Number,
int spacedim>
214 const double threshold)
223 cell->is_locally_owned()) &&
224 std::fabs(criteria(cell->active_cell_index())) <= threshold)
225 if (!cell->refine_flag_set())
226 cell->set_coarsen_flag();
232std::pair<double, double>
236 const double top_fraction,
237 const double bottom_fraction)
239 Assert(top_fraction >= 0, ExcInvalidParameterValue());
240 Assert(top_fraction <= 1, ExcInvalidParameterValue());
241 Assert(bottom_fraction >= 0, ExcInvalidParameterValue());
242 Assert(bottom_fraction <= 1, ExcInvalidParameterValue());
243 Assert(top_fraction + bottom_fraction <=
244 1 + 10 * std::numeric_limits<double>::epsilon(),
245 ExcInvalidParameterValue());
247 double refine_cells = current_n_cells * top_fraction;
248 double coarsen_cells = current_n_cells * bottom_fraction;
250 const double cell_increase_on_refine =
252 const double cell_decrease_on_coarsen =
255 std::pair<double, double> adjusted_fractions(top_fraction, bottom_fraction);
259 if (current_n_cells >= max_n_cells)
271 adjusted_fractions.first = 0;
273 (current_n_cells - max_n_cells) / cell_decrease_on_coarsen;
274 adjusted_fractions.second =
275 std::min(coarsen_cells / current_n_cells, 1.0);
291 current_n_cells + refine_cells * cell_increase_on_refine -
292 coarsen_cells * cell_decrease_on_coarsen) > max_n_cells)
302 const double alpha = 1. * (max_n_cells - current_n_cells) /
303 (refine_cells * cell_increase_on_refine -
304 coarsen_cells * cell_decrease_on_coarsen);
306 adjusted_fractions.first = alpha * top_fraction;
307 adjusted_fractions.second = alpha * bottom_fraction;
309 return (adjusted_fractions);
314template <
int dim,
typename Number,
int spacedim>
319 const double top_fraction,
320 const double bottom_fraction,
321 const unsigned int max_n_cells)
325 Assert((top_fraction >= 0) && (top_fraction <= 1),
326 ExcInvalidParameterValue());
327 Assert((bottom_fraction >= 0) && (bottom_fraction <= 1),
328 ExcInvalidParameterValue());
329 Assert(top_fraction + bottom_fraction <=
330 1 + 10 * std::numeric_limits<double>::epsilon(),
331 ExcInvalidParameterValue());
334 const std::pair<double, double> adjusted_fractions =
335 adjust_refine_and_coarsen_number_fraction<dim>(criteria.
size(),
340 const int refine_cells =
341 static_cast<int>(adjusted_fractions.first * criteria.
size());
342 const int coarsen_cells =
343 static_cast<int>(adjusted_fractions.second * criteria.
size());
345 if (refine_cells || coarsen_cells)
350 if (
static_cast<std::size_t
>(refine_cells) == criteria.
size())
351 refine(tria, criteria, std::numeric_limits<double>::lowest());
354 std::nth_element(tmp.
begin(),
355 tmp.
begin() + refine_cells - 1,
357 std::greater<double>());
358 refine(tria, criteria, *(tmp.
begin() + refine_cells - 1));
364 if (
static_cast<std::size_t
>(coarsen_cells) == criteria.
size())
365 coarsen(tria, criteria, std::numeric_limits<double>::max());
368 std::nth_element(tmp.
begin(),
369 tmp.
begin() + tmp.
size() - coarsen_cells,
371 std::greater<double>());
374 *(tmp.
begin() + tmp.
size() - coarsen_cells));
382template <
int dim,
typename Number,
int spacedim>
387 const double top_fraction,
388 const double bottom_fraction,
389 const unsigned int max_n_cells,
393 Assert((top_fraction >= 0) && (top_fraction <= 1),
394 ExcInvalidParameterValue());
395 Assert((bottom_fraction >= 0) && (bottom_fraction <= 1),
396 ExcInvalidParameterValue());
397 Assert(top_fraction + bottom_fraction <=
398 1 + 10 * std::numeric_limits<double>::epsilon(),
399 ExcInvalidParameterValue());
407 refine_and_coarsen_fixed_fraction_via_l1_norm(
408 tria, criteria, top_fraction, bottom_fraction, max_n_cells);
420 std::transform(criteria.
begin(),
422 criteria_squared.
begin(),
423 [](Number c) { return c * c; });
425 refine_and_coarsen_fixed_fraction_via_l1_norm(tria,
443template <
int dim,
typename Number,
int spacedim>
447 const unsigned int order)
454 std::vector<unsigned int> cell_indices(criteria.
size());
455 std::iota(cell_indices.begin(), cell_indices.end(), 0u);
457 std::sort(cell_indices.begin(),
459 [&criteria](
const unsigned int left,
const unsigned int right) {
460 return criteria[left] > criteria[right];
463 double expected_error_reduction = 0;
464 const double original_error = criteria.
l1_norm();
466 const std::size_t N = criteria.
size();
469 double min_cost = std::numeric_limits<double>::max();
470 std::size_t min_arg = 0;
472 const double reduction_factor = (1. -
std::pow(2., -1. * order));
473 for (std::size_t M = 0; M < criteria.
size(); ++M)
475 expected_error_reduction += reduction_factor * criteria(cell_indices[M]);
478 std::pow(((Utilities::fixed_power<dim>(2) - 1) * (1 + M) + N),
479 static_cast<double>(order) / dim) *
480 (original_error - expected_error_reduction);
481 if (cost <= min_cost)
488 refine(tria, criteria, criteria(cell_indices[min_arg]));
493#include "grid/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
#define DEAL_II_NOT_IMPLEMENTED()
IteratorRange< active_cell_iterator > active_cell_iterators() const
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
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 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)