23#ifdef DEAL_II_WITH_P4EST
44 template <
int dim,
int spacedim>
48 if (
const auto parallel_tria =
51 return parallel_tria->n_locally_owned_active_cells();
56 template <
typename number>
58 max_element(const ::Vector<number> &criteria)
60 return (criteria.size() > 0) ?
61 (*std::max_element(criteria.begin(), criteria.end())) :
62 std::numeric_limits<number>::
min();
67 template <
typename number>
69 min_element(const ::Vector<number> &criteria)
71 return (criteria.size() > 0) ?
72 (*std::min_element(criteria.begin(), criteria.end())) :
73 std::numeric_limits<number>::
max();
83 template <
typename number>
85 compute_global_sum(const ::Vector<number> &criteria,
89 std::accumulate(criteria.begin(),
97 MPI_Reduce(&my_sum, &result, 1, MPI_DOUBLE, MPI_SUM, 0, mpi_communicator);
113 template <
int dim,
int spacedim,
typename Number>
115 get_locally_owned_indicators(const ::Triangulation<dim, spacedim> &tria,
116 const ::Vector<Number> &criteria,
120 n_locally_owned_active_cells(tria),
123 unsigned int owned_index = 0;
124 for (
const auto &cell :
127 locally_owned_indicators(owned_index) =
128 criteria(cell->active_cell_index());
131 Assert(owned_index == n_locally_owned_active_cells(tria),
144 adjust_interesting_range(
double (&interesting_range)[2])
148 if (interesting_range[0] > 0)
157 interesting_range[0] *= 0.99;
158 interesting_range[1] *= 1.01;
167 const double difference =
168 std::abs(interesting_range[1] - interesting_range[0]);
169 interesting_range[0] -= 0.01 * difference;
170 interesting_range[1] += 0.01 * difference;
181 template <
int dim,
int spacedim,
typename Number>
184 const ::Vector<Number> &criteria,
185 const double top_threshold,
186 const double bottom_threshold)
193 for (
const auto &cell : tria.active_cell_iterators())
194 if (cell->
subdomain_id() != tria.locally_owned_subdomain())
196 cell->clear_refine_flag();
197 cell->clear_coarsen_flag();
210 template <
int dim,
int spacedim,
typename Number>
212 refine_and_coarsen_fixed_fraction_via_l1_norm(
214 const ::Vector<Number> &criteria,
215 const double top_fraction_of_error,
216 const double bottom_fraction_of_error)
220 Vector<Number> locally_owned_indicators(n_locally_owned_active_cells(tria));
221 get_locally_owned_indicators(tria, criteria, locally_owned_indicators);
227 const std::pair<double, double> global_min_and_max =
232 const double total_error =
233 compute_global_sum(locally_owned_indicators, mpi_communicator);
235 double top_target_error = top_fraction_of_error * total_error,
236 bottom_target_error = (1. - bottom_fraction_of_error) * total_error;
238 double top_threshold, bottom_threshold;
247 if (bottom_fraction_of_error > 0)
250 locally_owned_indicators,
255 bottom_threshold = std::numeric_limits<Number>::lowest();
258 mark_cells(tria, criteria, top_threshold, bottom_threshold);
268 namespace distributed
272 template <
typename number>
273 std::pair<number, number>
275 const ::Vector<number> &criteria,
283 const double local_min = min_element(criteria),
284 local_max = max_element(criteria);
285 double comp[2] = {local_min, -local_max};
286 double result[2] = {0, 0};
289 const int ierr = MPI_Reduce(
290 comp, result, 2, MPI_DOUBLE, MPI_MIN, 0, mpi_communicator);
297 return std::make_pair(result[0], -result[1]);
302 namespace RefineAndCoarsenFixedNumber
304 template <
typename number>
307 const std::pair<double, double> &global_min_and_max,
311 double interesting_range[2] = {global_min_and_max.first,
312 global_min_and_max.second};
313 adjust_interesting_range(interesting_range);
315 const unsigned int root_mpi_rank = 0;
316 unsigned int iteration = 0;
320 int ierr = MPI_Bcast(interesting_range,
327 if (interesting_range[0] == interesting_range[1])
328 return interesting_range[0];
330 const double test_threshold =
331 (interesting_range[0] > 0 ?
332 std::sqrt(interesting_range[0] * interesting_range[1]) :
333 (interesting_range[0] + interesting_range[1]) / 2);
340 std::count_if(criteria.begin(),
342 [test_threshold](
const double c) {
343 return c > test_threshold;
355 if (total_count > n_target_cells)
356 interesting_range[0] = test_threshold;
357 else if (total_count < n_target_cells)
358 interesting_range[1] = test_threshold;
360 interesting_range[0] = interesting_range[1] = test_threshold;
374 interesting_range[0] = interesting_range[1] = test_threshold;
385 namespace RefineAndCoarsenFixedFraction
387 template <
typename number>
390 const std::pair<double, double> &global_min_and_max,
391 const double target_error,
394 double interesting_range[2] = {global_min_and_max.first,
395 global_min_and_max.second};
396 adjust_interesting_range(interesting_range);
398 const unsigned int root_mpi_rank = 0;
399 unsigned int iteration = 0;
403 int ierr = MPI_Bcast(interesting_range,
410 if (interesting_range[0] == interesting_range[1])
419 double final_threshold =
420 std::min(interesting_range[0], global_min_and_max.second);
421 ierr = MPI_Bcast(&final_threshold,
428 return final_threshold;
431 const double test_threshold =
432 (interesting_range[0] > 0 ?
433 std::sqrt(interesting_range[0] * interesting_range[1]) :
434 (interesting_range[0] + interesting_range[1]) / 2);
439 for (
unsigned int i = 0; i < criteria.size(); ++i)
440 if (criteria(i) > test_threshold)
441 my_error += criteria(i);
443 double total_error = 0.;
445 ierr = MPI_Reduce(&my_error,
461 if (total_error > target_error)
462 interesting_range[0] = test_threshold;
463 else if (total_error < target_error)
464 interesting_range[1] = test_threshold;
466 interesting_range[0] = interesting_range[1] = test_threshold;
480 interesting_range[0] = interesting_range[1] = test_threshold;
497 namespace distributed
501 template <
int dim,
typename Number,
int spacedim>
505 const ::Vector<Number> &criteria,
506 const double top_fraction_of_cells,
507 const double bottom_fraction_of_cells,
512 Assert((top_fraction_of_cells >= 0) && (top_fraction_of_cells <= 1),
514 Assert((bottom_fraction_of_cells >= 0) &&
515 (bottom_fraction_of_cells <= 1),
517 Assert(top_fraction_of_cells + bottom_fraction_of_cells <= 1,
519 Assert(criteria.is_non_negative(),
522 const std::pair<double, double> adjusted_fractions =
526 top_fraction_of_cells,
527 bottom_fraction_of_cells);
532 n_locally_owned_active_cells(tria));
533 get_locally_owned_indicators(tria, criteria, locally_owned_indicators);
539 const std::pair<Number, Number> global_min_and_max =
545 double top_threshold, bottom_threshold;
548 locally_owned_indicators,
556 if (adjusted_fractions.second > 0)
559 locally_owned_indicators,
562 std::ceil((1. - adjusted_fractions.second) *
566 bottom_threshold = std::numeric_limits<Number>::lowest();
569 mark_cells(tria, criteria, top_threshold, bottom_threshold);
574 template <
int dim,
typename Number,
int spacedim>
578 const ::Vector<Number> &criteria,
579 const double top_fraction_of_error,
580 const double bottom_fraction_of_error,
585 Assert((top_fraction_of_error >= 0) && (top_fraction_of_error <= 1),
587 Assert((bottom_fraction_of_error >= 0) &&
588 (bottom_fraction_of_error <= 1),
590 Assert(top_fraction_of_error + bottom_fraction_of_error <= 1,
592 Assert(criteria.is_non_negative(),
600 refine_and_coarsen_fixed_fraction_via_l1_norm(
603 top_fraction_of_error,
604 bottom_fraction_of_error);
616 std::transform(criteria.begin(),
618 criteria_squared.
begin(),
619 [](Number c) { return c * c; });
621 refine_and_coarsen_fixed_fraction_via_l1_norm(
624 top_fraction_of_error * top_fraction_of_error,
625 bottom_fraction_of_error * bottom_fraction_of_error);
640# include "grid_refinement.inst"
virtual types::global_cell_index n_global_active_cells() const
virtual MPI_Comm get_mpi_communicator() const
unsigned int n_active_cells() const
virtual size_type size() const override
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
#define AssertThrowMPI(error_code)
static ::ExceptionBase & ExcNegativeCriteria()
static ::ExceptionBase & ExcInvalidParameterValue()
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
#define DEAL_II_ASSERT_UNREACHABLE()
#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 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)
T sum(const T &t, const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
number compute_threshold(const ::Vector< number > &criteria, const std::pair< double, double > &global_min_and_max, const double target_error, const MPI_Comm mpi_communicator)
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)
void refine_and_coarsen_fixed_fraction(::Triangulation< dim, spacedim > &tria, const ::Vector< Number > &criteria, const double top_fraction_of_error, const double bottom_fraction_of_error, const VectorTools::NormType norm_type=VectorTools::L1_norm)
void refine_and_coarsen_fixed_number(::Triangulation< dim, spacedim > &tria, const ::Vector< Number > &criteria, const double top_fraction_of_cells, const double bottom_fraction_of_cells, const types::global_cell_index max_n_cells=std::numeric_limits< types::global_cell_index >::max())
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
unsigned int subdomain_id