17 #include <deal.II/base/utilities.h> 18 #include <deal.II/lac/vector.h> 19 #include <deal.II/lac/block_vector.h> 20 #include <deal.II/lac/petsc_vector.h> 21 #include <deal.II/lac/petsc_block_vector.h> 22 #include <deal.II/lac/trilinos_vector.h> 23 #include <deal.II/lac/trilinos_block_vector.h> 25 #ifdef DEAL_II_WITH_P4EST 27 #include <deal.II/grid/grid_refinement.h> 28 #include <deal.II/grid/tria_accessor.h> 29 #include <deal.II/grid/tria_iterator.h> 30 #include <deal.II/grid/tria.h> 32 #include <deal.II/distributed/grid_refinement.h> 39 DEAL_II_NAMESPACE_OPEN
44 template <
typename number>
49 return (criteria.
size()>0)
51 (*std::max_element(criteria.
begin(), criteria.
end()))
53 std::numeric_limits<number>::min();
58 template <
typename number>
63 return (criteria.
size()>0)
65 (*std::min_element(criteria.
begin(), criteria.
end()))
67 std::numeric_limits<number>::max();
78 template <
typename number>
79 std::pair<number,number>
80 compute_global_min_and_max_at_root (
const Vector<number> &criteria,
81 MPI_Comm mpi_communicator)
92 const double local_min = min_element (criteria),
93 local_max = max_element (criteria);
94 double comp[2] = { local_min, -local_max };
95 double result[2] = { 0, 0 };
99 MPI_Reduce (comp, result, 2, MPI_DOUBLE,
100 MPI_MIN, 0, mpi_communicator);
105 Assert ((result[0] == 0) && (result[1] == 0),
108 return std::make_pair (result[0], -result[1]);
120 template <
typename number>
123 MPI_Comm mpi_communicator)
125 double my_sum = std::accumulate (criteria.
begin(),
133 MPI_Reduce (&my_sum, &result, 1, MPI_DOUBLE,
134 MPI_SUM, 0, mpi_communicator);
139 Assert (result == 0, ExcInternalError());
152 template <
int dim,
int spacedim,
typename VectorType>
155 const VectorType &criteria,
161 unsigned int owned_index = 0;
164 cell != tria.
end(); ++cell)
167 locally_owned_indicators(owned_index)
168 = criteria(cell->active_cell_index());
193 void adjust_interesting_range (
double (&interesting_range)[2])
195 Assert (interesting_range[0] <= interesting_range[1],
198 Assert (interesting_range[0] >= 0,
206 if (interesting_range[0] > 0)
207 interesting_range[0] *= 0.99;
209 if (interesting_range[1] > 0)
210 interesting_range[1] *= 1.01;
213 += 0.01 * (interesting_range[1] - interesting_range[0]);
225 template <
int dim,
int spacedim,
typename VectorType>
228 const VectorType &criteria,
229 const double top_threshold,
230 const double bottom_threshold)
232 ::GridRefinement::refine (tria, criteria, top_threshold);
233 ::GridRefinement::coarsen (tria, criteria, bottom_threshold);
241 cell != tria.
end(); ++cell)
244 cell->clear_refine_flag ();
245 cell->clear_coarsen_flag ();
259 template <
typename number>
262 const std::pair<double,double> global_min_and_max,
263 const unsigned int n_target_cells,
264 MPI_Comm mpi_communicator)
266 double interesting_range[2] = { global_min_and_max.first,
267 global_min_and_max.second
269 adjust_interesting_range (interesting_range);
271 const unsigned int master_mpi_rank = 0;
272 unsigned int iteration = 0;
276 MPI_Bcast (&interesting_range[0], 2, MPI_DOUBLE,
277 master_mpi_rank, mpi_communicator);
279 if (interesting_range[0] == interesting_range[1])
280 return interesting_range[0];
282 const double test_threshold
283 = (interesting_range[0] > 0
285 std::sqrt(interesting_range[0] * interesting_range[1])
287 (interesting_range[0] + interesting_range[1]) / 2);
295 my_count = std::count_if (criteria.
begin(),
297 std::bind2nd (std::greater<double>(),
300 unsigned int total_count;
301 MPI_Reduce (&my_count, &total_count, 1, MPI_UNSIGNED,
302 MPI_SUM, master_mpi_rank, mpi_communicator);
315 if (total_count > n_target_cells)
316 interesting_range[0] = test_threshold;
317 else if (total_count < n_target_cells)
318 interesting_range[1] = test_threshold;
320 interesting_range[0] = interesting_range[1] = test_threshold;
333 interesting_range[0] = interesting_range[1] = test_threshold;
337 Assert (
false, ExcInternalError());
353 template <
typename number>
356 const std::pair<double,double> global_min_and_max,
357 const double target_error,
358 MPI_Comm mpi_communicator)
360 double interesting_range[2] = { global_min_and_max.first,
361 global_min_and_max.second
363 adjust_interesting_range (interesting_range);
365 const unsigned int master_mpi_rank = 0;
366 unsigned int iteration = 0;
370 MPI_Bcast (&interesting_range[0], 2, MPI_DOUBLE,
371 master_mpi_rank, mpi_communicator);
373 if (interesting_range[0] == interesting_range[1])
383 double final_threshold = std::min (interesting_range[0],
384 global_min_and_max.second);
385 MPI_Bcast (&final_threshold, 1, MPI_DOUBLE,
386 master_mpi_rank, mpi_communicator);
388 return final_threshold;
391 const double test_threshold
392 = (interesting_range[0] > 0
394 std::sqrt(interesting_range[0] * interesting_range[1])
396 (interesting_range[0] + interesting_range[1]) / 2);
402 for (
unsigned int i=0; i<criteria.
size(); ++i)
403 if (criteria(i) > test_threshold)
404 my_error += criteria(i);
407 MPI_Reduce (&my_error, &total_error, 1, MPI_DOUBLE,
408 MPI_SUM, master_mpi_rank, mpi_communicator);
417 if (total_error > target_error)
418 interesting_range[0] = test_threshold;
419 else if (total_error < target_error)
420 interesting_range[1] = test_threshold;
422 interesting_range[0] = interesting_range[1] = test_threshold;
436 interesting_range[0] = interesting_range[1] = test_threshold;
440 Assert (
false, ExcInternalError());
450 namespace distributed
454 template <
int dim,
typename VectorType,
int spacedim>
458 const VectorType &criteria,
459 const double top_fraction_of_cells,
460 const double bottom_fraction_of_cells,
461 const unsigned int max_n_cells)
465 Assert ((top_fraction_of_cells>=0) && (top_fraction_of_cells<=1),
466 ::GridRefinement::ExcInvalidParameterValue());
467 Assert ((bottom_fraction_of_cells>=0) && (bottom_fraction_of_cells<=1),
468 ::GridRefinement::ExcInvalidParameterValue());
469 Assert (top_fraction_of_cells+bottom_fraction_of_cells <= 1,
470 ::GridRefinement::ExcInvalidParameterValue());
471 Assert (criteria.is_non_negative (),
472 ::GridRefinement::ExcNegativeCriteria());
474 const std::pair<double, double> adjusted_fractions =
475 ::GridRefinement::adjust_refine_and_coarsen_number_fraction<dim> (
478 top_fraction_of_cells,
479 bottom_fraction_of_cells);
487 get_locally_owned_indicators (tria,
489 locally_owned_indicators);
499 const std::pair<typename VectorType::value_type,typename VectorType::value_type> global_min_and_max
500 = compute_global_min_and_max_at_root (locally_owned_indicators,
504 double top_threshold, bottom_threshold;
506 RefineAndCoarsenFixedNumber::
507 compute_threshold (locally_owned_indicators,
509 static_cast<unsigned int>
510 (adjusted_fractions.first *
520 if (adjusted_fractions.second > 0)
522 RefineAndCoarsenFixedNumber::
523 compute_threshold (locally_owned_indicators,
525 static_cast<unsigned int>
526 ((1-adjusted_fractions.second) *
531 bottom_threshold = *std::min_element (criteria.begin(),
533 bottom_threshold -= std::fabs(bottom_threshold);
537 mark_cells (tria, criteria, top_threshold, bottom_threshold);
541 template <
int dim,
typename VectorType,
int spacedim>
545 const VectorType &criteria,
546 const double top_fraction_of_error,
547 const double bottom_fraction_of_error)
551 Assert ((top_fraction_of_error>=0) && (top_fraction_of_error<=1),
552 ::GridRefinement::ExcInvalidParameterValue());
553 Assert ((bottom_fraction_of_error>=0) && (bottom_fraction_of_error<=1),
554 ::GridRefinement::ExcInvalidParameterValue());
555 Assert (top_fraction_of_error+bottom_fraction_of_error <= 1,
556 ::GridRefinement::ExcInvalidParameterValue());
557 Assert (criteria.is_non_negative (),
558 ::GridRefinement::ExcNegativeCriteria());
566 get_locally_owned_indicators (tria,
568 locally_owned_indicators);
578 const std::pair<double,double> global_min_and_max
579 = compute_global_min_and_max_at_root (locally_owned_indicators,
582 const double total_error
583 = compute_global_sum (locally_owned_indicators,
585 double top_threshold, bottom_threshold;
587 RefineAndCoarsenFixedFraction::
588 compute_threshold (locally_owned_indicators,
590 top_fraction_of_error *
599 if (bottom_fraction_of_error > 0)
601 RefineAndCoarsenFixedFraction::
602 compute_threshold (locally_owned_indicators,
604 (1-bottom_fraction_of_error) *
609 bottom_threshold = *std::min_element (criteria.begin(),
611 bottom_threshold -= std::fabs(bottom_threshold);
615 mark_cells (tria, criteria, top_threshold, bottom_threshold);
623 #include "grid_refinement.inst" 625 DEAL_II_NAMESPACE_CLOSE
unsigned int n_active_cells() const
active_cell_iterator begin_active(const unsigned int level=0) const
cell_iterator end() const
#define Assert(cond, exc)
virtual MPI_Comm get_communicator() const
virtual types::global_dof_index n_global_active_cells() const
unsigned int n_locally_owned_active_cells() const
void refine_and_coarsen_fixed_fraction(parallel::distributed::Triangulation< dim, spacedim > &tria, const VectorType &criteria, const double top_fraction_of_error, const double bottom_fraction_of_error)
void refine_and_coarsen_fixed_number(parallel::distributed::Triangulation< dim, spacedim > &tria, const VectorType &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())
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
types::subdomain_id locally_owned_subdomain() const