17 #include <deal.II/base/utilities.h> 18 #include <deal.II/base/std_cxx11/bind.h> 19 #include <deal.II/lac/vector.h> 20 #include <deal.II/lac/block_vector.h> 21 #include <deal.II/lac/petsc_vector.h> 22 #include <deal.II/lac/petsc_block_vector.h> 23 #include <deal.II/lac/trilinos_vector.h> 24 #include <deal.II/lac/trilinos_block_vector.h> 26 #ifdef DEAL_II_WITH_P4EST 28 #include <deal.II/grid/grid_refinement.h> 29 #include <deal.II/grid/tria_accessor.h> 30 #include <deal.II/grid/tria_iterator.h> 31 #include <deal.II/grid/tria.h> 33 #include <deal.II/distributed/grid_refinement.h> 40 DEAL_II_NAMESPACE_OPEN
45 template <
typename number>
50 return (criteria.
size()>0)
52 (*std::max_element(criteria.
begin(), criteria.
end()))
54 std::numeric_limits<number>::min();
59 template <
typename number>
64 return (criteria.
size()>0)
66 (*std::min_element(criteria.
begin(), criteria.
end()))
68 std::numeric_limits<number>::max();
79 template <
typename number>
80 std::pair<number,number>
81 compute_global_min_and_max_at_root (
const Vector<number> &criteria,
82 MPI_Comm mpi_communicator)
93 const double local_min = min_element (criteria),
94 local_max = max_element (criteria);
95 double comp[2] = { local_min, -local_max };
96 double result[2] = { 0, 0 };
100 const int ierr = MPI_Reduce (comp, result, 2, MPI_DOUBLE,
101 MPI_MIN, 0, mpi_communicator);
107 Assert ((result[0] == 0) && (result[1] == 0),
110 return std::make_pair (result[0], -result[1]);
122 template <
typename number>
125 MPI_Comm mpi_communicator)
127 double my_sum = std::accumulate (criteria.
begin(),
135 const int ierr = MPI_Reduce (&my_sum, &result, 1, MPI_DOUBLE,
136 MPI_SUM, 0, mpi_communicator);
155 template <
int dim,
int spacedim,
typename VectorType>
158 const VectorType &criteria,
164 unsigned int owned_index = 0;
167 cell != tria.
end(); ++cell)
170 locally_owned_indicators(owned_index)
171 = criteria(cell->active_cell_index());
196 void adjust_interesting_range (
double (&interesting_range)[2])
198 Assert (interesting_range[0] <= interesting_range[1],
201 Assert (interesting_range[0] >= 0,
209 if (interesting_range[0] > 0)
210 interesting_range[0] *= 0.99;
212 if (interesting_range[1] > 0)
213 interesting_range[1] *= 1.01;
216 += 0.01 * (interesting_range[1] - interesting_range[0]);
228 template <
int dim,
int spacedim,
typename VectorType>
231 const VectorType &criteria,
232 const double top_threshold,
233 const double bottom_threshold)
235 ::GridRefinement::refine (tria, criteria, top_threshold);
236 ::GridRefinement::coarsen (tria, criteria, bottom_threshold);
244 cell != tria.
end(); ++cell)
247 cell->clear_refine_flag ();
248 cell->clear_coarsen_flag ();
262 template <
typename number>
265 const std::pair<double,double> global_min_and_max,
266 const unsigned int n_target_cells,
267 MPI_Comm mpi_communicator)
269 double interesting_range[2] = { global_min_and_max.first,
270 global_min_and_max.second
272 adjust_interesting_range (interesting_range);
274 const unsigned int master_mpi_rank = 0;
275 unsigned int iteration = 0;
279 int ierr = MPI_Bcast (&interesting_range[0], 2, MPI_DOUBLE,
280 master_mpi_rank, mpi_communicator);
283 if (interesting_range[0] == interesting_range[1])
284 return interesting_range[0];
286 const double test_threshold
287 = (interesting_range[0] > 0
289 std::sqrt(interesting_range[0] * interesting_range[1])
291 (interesting_range[0] + interesting_range[1]) / 2);
299 my_count = std::count_if (criteria.
begin(),
301 std_cxx11::bind (std::greater<double>(),
305 unsigned int total_count;
306 ierr = MPI_Reduce (&my_count, &total_count, 1, MPI_UNSIGNED,
307 MPI_SUM, master_mpi_rank, mpi_communicator);
321 if (total_count > n_target_cells)
322 interesting_range[0] = test_threshold;
323 else if (total_count < n_target_cells)
324 interesting_range[1] = test_threshold;
326 interesting_range[0] = interesting_range[1] = test_threshold;
339 interesting_range[0] = interesting_range[1] = test_threshold;
359 template <
typename number>
362 const std::pair<double,double> global_min_and_max,
363 const double target_error,
364 MPI_Comm mpi_communicator)
366 double interesting_range[2] = { global_min_and_max.first,
367 global_min_and_max.second
369 adjust_interesting_range (interesting_range);
371 const unsigned int master_mpi_rank = 0;
372 unsigned int iteration = 0;
376 int ierr = MPI_Bcast (&interesting_range[0], 2, MPI_DOUBLE,
377 master_mpi_rank, mpi_communicator);
380 if (interesting_range[0] == interesting_range[1])
390 double final_threshold = std::min (interesting_range[0],
391 global_min_and_max.second);
392 ierr = MPI_Bcast (&final_threshold, 1, MPI_DOUBLE,
393 master_mpi_rank, mpi_communicator);
396 return final_threshold;
399 const double test_threshold
400 = (interesting_range[0] > 0
402 std::sqrt(interesting_range[0] * interesting_range[1])
404 (interesting_range[0] + interesting_range[1]) / 2);
410 for (
unsigned int i=0; i<criteria.
size(); ++i)
411 if (criteria(i) > test_threshold)
412 my_error += criteria(i);
415 ierr = MPI_Reduce (&my_error, &total_error, 1, MPI_DOUBLE,
416 MPI_SUM, master_mpi_rank, mpi_communicator);
426 if (total_error > target_error)
427 interesting_range[0] = test_threshold;
428 else if (total_error < target_error)
429 interesting_range[1] = test_threshold;
431 interesting_range[0] = interesting_range[1] = test_threshold;
445 interesting_range[0] = interesting_range[1] = test_threshold;
459 namespace distributed
463 template <
int dim,
typename VectorType,
int spacedim>
467 const VectorType &criteria,
468 const double top_fraction_of_cells,
469 const double bottom_fraction_of_cells,
470 const unsigned int max_n_cells)
474 Assert ((top_fraction_of_cells>=0) && (top_fraction_of_cells<=1),
476 Assert ((bottom_fraction_of_cells>=0) && (bottom_fraction_of_cells<=1),
478 Assert (top_fraction_of_cells+bottom_fraction_of_cells <= 1,
480 Assert (criteria.is_non_negative (),
483 const std::pair<double, double> adjusted_fractions =
484 ::GridRefinement::adjust_refine_and_coarsen_number_fraction<dim> (
487 top_fraction_of_cells,
488 bottom_fraction_of_cells);
496 get_locally_owned_indicators (tria,
498 locally_owned_indicators);
508 const std::pair<typename VectorType::value_type,typename VectorType::value_type> global_min_and_max
509 = compute_global_min_and_max_at_root (locally_owned_indicators,
513 double top_threshold, bottom_threshold;
515 RefineAndCoarsenFixedNumber::
516 compute_threshold (locally_owned_indicators,
518 static_cast<unsigned int>
519 (adjusted_fractions.first *
529 if (adjusted_fractions.second > 0)
531 RefineAndCoarsenFixedNumber::
532 compute_threshold (locally_owned_indicators,
534 static_cast<unsigned int>
535 ((1-adjusted_fractions.second) *
540 bottom_threshold = *std::min_element (criteria.begin(),
542 bottom_threshold -= std::fabs(bottom_threshold);
546 mark_cells (tria, criteria, top_threshold, bottom_threshold);
550 template <
int dim,
typename VectorType,
int spacedim>
554 const VectorType &criteria,
555 const double top_fraction_of_error,
556 const double bottom_fraction_of_error)
560 Assert ((top_fraction_of_error>=0) && (top_fraction_of_error<=1),
562 Assert ((bottom_fraction_of_error>=0) && (bottom_fraction_of_error<=1),
564 Assert (top_fraction_of_error+bottom_fraction_of_error <= 1,
566 Assert (criteria.is_non_negative (),
575 get_locally_owned_indicators (tria,
577 locally_owned_indicators);
587 const std::pair<double,double> global_min_and_max
588 = compute_global_min_and_max_at_root (locally_owned_indicators,
591 const double total_error
592 = compute_global_sum (locally_owned_indicators,
594 double top_threshold, bottom_threshold;
596 RefineAndCoarsenFixedFraction::
597 compute_threshold (locally_owned_indicators,
599 top_fraction_of_error *
608 if (bottom_fraction_of_error > 0)
610 RefineAndCoarsenFixedFraction::
611 compute_threshold (locally_owned_indicators,
613 (1-bottom_fraction_of_error) *
618 bottom_threshold = *std::min_element (criteria.begin(),
620 bottom_threshold -= std::fabs(bottom_threshold);
624 mark_cells (tria, criteria, top_threshold, bottom_threshold);
632 #include "grid_refinement.inst" 634 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
static ::ExceptionBase & ExcNegativeCriteria()
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
virtual MPI_Comm get_communicator() const
virtual types::global_dof_index n_global_active_cells() const
unsigned int n_locally_owned_active_cells() const
#define AssertThrowMPI(error_code)
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
static ::ExceptionBase & ExcInvalidParameterValue()
static ::ExceptionBase & ExcInternalError()