21#ifdef DEAL_II_WITH_P4EST
38#ifdef DEAL_II_WITH_P4EST
41 template <
int dim,
int spacedim>
45 if (
const auto parallel_tria =
48 return parallel_tria->n_locally_owned_active_cells();
53 template <
typename number>
55 max_element(const ::Vector<number> &criteria)
57 return (criteria.size() > 0) ?
58 (*std::max_element(criteria.begin(), criteria.end())) :
59 std::numeric_limits<number>::
min();
64 template <
typename number>
66 min_element(const ::Vector<number> &criteria)
68 return (criteria.size() > 0) ?
69 (*std::min_element(criteria.begin(), criteria.end())) :
70 std::numeric_limits<number>::
max();
80 template <
typename number>
82 compute_global_sum(const ::Vector<number> &criteria,
86 std::accumulate(criteria.begin(),
94 MPI_Reduce(&my_sum, &result, 1, MPI_DOUBLE, MPI_SUM, 0, mpi_communicator);
110 template <
int dim,
int spacedim,
typename Number>
112 get_locally_owned_indicators(const ::Triangulation<dim, spacedim> &tria,
113 const ::Vector<Number> &criteria,
117 n_locally_owned_active_cells(tria),
120 unsigned int owned_index = 0;
121 for (
const auto &cell :
124 locally_owned_indicators(owned_index) =
125 criteria(cell->active_cell_index());
128 Assert(owned_index == n_locally_owned_active_cells(tria),
141 adjust_interesting_range(
double (&interesting_range)[2])
145 if (interesting_range[0] > 0)
154 interesting_range[0] *= 0.99;
155 interesting_range[1] *= 1.01;
164 const double difference =
165 std::abs(interesting_range[1] - interesting_range[0]);
166 interesting_range[0] -= 0.01 * difference;
167 interesting_range[1] += 0.01 * difference;
178 template <
int dim,
int spacedim,
typename Number>
181 const ::Vector<Number> &criteria,
182 const double top_threshold,
183 const double bottom_threshold)
190 for (
const auto &cell : tria.active_cell_iterators())
193 cell->clear_refine_flag();
194 cell->clear_coarsen_flag();
207 template <
int dim,
int spacedim,
typename Number>
209 refine_and_coarsen_fixed_fraction_via_l1_norm(
211 const ::Vector<Number> &criteria,
212 const double top_fraction_of_error,
213 const double bottom_fraction_of_error)
217 Vector<Number> locally_owned_indicators(n_locally_owned_active_cells(tria));
218 get_locally_owned_indicators(tria, criteria, locally_owned_indicators);
224 const std::pair<double, double> global_min_and_max =
229 const double total_error =
230 compute_global_sum(locally_owned_indicators, mpi_communicator);
232 double top_target_error = top_fraction_of_error * total_error,
233 bottom_target_error = (1. - bottom_fraction_of_error) * total_error;
235 double top_threshold, bottom_threshold;
244 if (bottom_fraction_of_error > 0)
247 locally_owned_indicators,
252 bottom_threshold = std::numeric_limits<Number>::lowest();
255 mark_cells(tria, criteria, top_threshold, bottom_threshold);
265 namespace distributed
269 template <
typename number>
270 std::pair<number, number>
272 const ::Vector<number> &criteria,
280 const double local_min = min_element(criteria),
281 local_max = max_element(criteria);
282 double comp[2] = {local_min, -local_max};
283 double result[2] = {0, 0};
286 const int ierr = MPI_Reduce(
287 comp, result, 2, MPI_DOUBLE, MPI_MIN, 0, mpi_communicator);
294 return std::make_pair(result[0], -result[1]);
299 namespace RefineAndCoarsenFixedNumber
301 template <
typename number>
304 const std::pair<double, double> &global_min_and_max,
308 double interesting_range[2] = {global_min_and_max.first,
309 global_min_and_max.second};
310 adjust_interesting_range(interesting_range);
312 const unsigned int root_mpi_rank = 0;
313 unsigned int iteration = 0;
317 int ierr = MPI_Bcast(interesting_range,
324 if (interesting_range[0] == interesting_range[1])
325 return interesting_range[0];
327 const double test_threshold =
328 (interesting_range[0] > 0 ?
329 std::sqrt(interesting_range[0] * interesting_range[1]) :
330 (interesting_range[0] + interesting_range[1]) / 2);
337 std::count_if(criteria.begin(),
339 [test_threshold](
const double c) {
340 return c > test_threshold;
352 if (total_count > n_target_cells)
353 interesting_range[0] = test_threshold;
354 else if (total_count < n_target_cells)
355 interesting_range[1] = test_threshold;
357 interesting_range[0] = interesting_range[1] = test_threshold;
371 interesting_range[0] = interesting_range[1] = test_threshold;
382 namespace RefineAndCoarsenFixedFraction
384 template <
typename number>
387 const std::pair<double, double> &global_min_and_max,
388 const double target_error,
391 double interesting_range[2] = {global_min_and_max.first,
392 global_min_and_max.second};
393 adjust_interesting_range(interesting_range);
395 const unsigned int root_mpi_rank = 0;
396 unsigned int iteration = 0;
400 int ierr = MPI_Bcast(interesting_range,
407 if (interesting_range[0] == interesting_range[1])
416 double final_threshold =
417 std::min(interesting_range[0], global_min_and_max.second);
418 ierr = MPI_Bcast(&final_threshold,
425 return final_threshold;
428 const double test_threshold =
429 (interesting_range[0] > 0 ?
430 std::sqrt(interesting_range[0] * interesting_range[1]) :
431 (interesting_range[0] + interesting_range[1]) / 2);
436 for (
unsigned int i = 0; i < criteria.size(); ++i)
437 if (criteria(i) > test_threshold)
438 my_error += criteria(i);
440 double total_error = 0.;
442 ierr = MPI_Reduce(&my_error,
458 if (total_error > target_error)
459 interesting_range[0] = test_threshold;
460 else if (total_error < target_error)
461 interesting_range[1] = test_threshold;
463 interesting_range[0] = interesting_range[1] = test_threshold;
477 interesting_range[0] = interesting_range[1] = test_threshold;
494 namespace distributed
498 template <
int dim,
typename Number,
int spacedim>
502 const ::Vector<Number> &criteria,
503 const double top_fraction_of_cells,
504 const double bottom_fraction_of_cells,
509 Assert((top_fraction_of_cells >= 0) && (top_fraction_of_cells <= 1),
511 Assert((bottom_fraction_of_cells >= 0) &&
512 (bottom_fraction_of_cells <= 1),
514 Assert(top_fraction_of_cells + bottom_fraction_of_cells <= 1,
516 Assert(criteria.is_non_negative(),
519 const std::pair<double, double> adjusted_fractions =
523 top_fraction_of_cells,
524 bottom_fraction_of_cells);
529 n_locally_owned_active_cells(tria));
530 get_locally_owned_indicators(tria, criteria, locally_owned_indicators);
536 const std::pair<Number, Number> global_min_and_max =
542 double top_threshold, bottom_threshold;
545 locally_owned_indicators,
553 if (adjusted_fractions.second > 0)
556 locally_owned_indicators,
559 std::ceil((1. - adjusted_fractions.second) *
563 bottom_threshold = std::numeric_limits<Number>::lowest();
566 mark_cells(tria, criteria, top_threshold, bottom_threshold);
571 template <
int dim,
typename Number,
int spacedim>
575 const ::Vector<Number> &criteria,
576 const double top_fraction_of_error,
577 const double bottom_fraction_of_error,
582 Assert((top_fraction_of_error >= 0) && (top_fraction_of_error <= 1),
584 Assert((bottom_fraction_of_error >= 0) &&
585 (bottom_fraction_of_error <= 1),
587 Assert(top_fraction_of_error + bottom_fraction_of_error <= 1,
589 Assert(criteria.is_non_negative(),
597 refine_and_coarsen_fixed_fraction_via_l1_norm(
600 top_fraction_of_error,
601 bottom_fraction_of_error);
613 std::transform(criteria.begin(),
615 criteria_squared.
begin(),
616 [](Number c) { return c * c; });
618 refine_and_coarsen_fixed_fraction_via_l1_norm(
621 top_fraction_of_error * top_fraction_of_error,
622 bottom_fraction_of_error * bottom_fraction_of_error);
637# include "distributed/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 DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
#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)
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)
* * if(update_pressure &update_flags) * compute_pressure(constitutive_request
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