17 #include <deal.II/base/template_constraints.h> 18 #include <deal.II/lac/vector.h> 19 #include <deal.II/lac/block_vector_base.h> 20 #include <deal.II/lac/block_vector.h> 21 #include <deal.II/lac/trilinos_vector.h> 22 #include <deal.II/lac/trilinos_parallel_block_vector.h> 24 #include <deal.II/grid/grid_refinement.h> 25 #include <deal.II/grid/tria_accessor.h> 26 #include <deal.II/grid/tria_iterator.h> 27 #include <deal.II/grid/tria.h> 35 DEAL_II_NAMESPACE_OPEN
38 template <
int dim,
typename Number,
int spacedim>
40 const Vector<Number> &criteria,
41 const double threshold,
42 const unsigned int max_to_mark)
51 if (criteria.all_zero())
54 const unsigned int n_cells = criteria.size();
58 double new_threshold=threshold;
64 new_threshold = criteria(0);
65 for (
unsigned int index=1; index<n_cells; ++index)
67 && (criteria(index)<new_threshold))
68 new_threshold=criteria(index);
71 unsigned int marked=0;
73 cell != tria.
end(); ++cell)
74 if (std::fabs(criteria(cell->active_cell_index())) >= new_threshold)
79 cell->set_refine_flag();
85 template <
int dim,
typename Number,
int spacedim>
87 const Vector<Number> &criteria,
88 const double threshold)
95 cell != tria.
end(); ++cell)
96 if (std::fabs(criteria(cell->active_cell_index())) <= threshold)
97 if (!cell->refine_flag_set())
98 cell->set_coarsen_flag();
102 std::pair<double, double>
104 const unsigned int max_n_cells,
105 const double top_fraction,
106 const double bottom_fraction)
114 double refine_cells = current_n_cells * top_fraction;
115 double coarsen_cells = current_n_cells * bottom_fraction;
120 std::pair<double, double> adjusted_fractions(top_fraction, bottom_fraction);
124 if (current_n_cells >= max_n_cells)
136 adjusted_fractions.first = 0;
137 coarsen_cells = (current_n_cells - max_n_cells) /
138 cell_decrease_on_coarsen;
139 adjusted_fractions.second = std::min(coarsen_cells/current_n_cells, 1.0);
154 else if (static_cast<unsigned int>
156 + refine_cells * cell_increase_on_refine
157 - coarsen_cells * cell_decrease_on_coarsen)
172 (max_n_cells - current_n_cells)
174 (refine_cells * cell_increase_on_refine
175 - coarsen_cells * cell_decrease_on_coarsen);
177 adjusted_fractions.first = alpha * top_fraction;
178 adjusted_fractions.second = alpha * bottom_fraction;
180 return (adjusted_fractions);
183 template <
int dim,
typename Number,
int spacedim>
186 const Vector<Number> &criteria,
187 const double top_fraction,
188 const double bottom_fraction,
189 const unsigned int max_n_cells)
198 const std::pair<double, double> adjusted_fractions =
199 adjust_refine_and_coarsen_number_fraction<dim> (criteria.size(),
204 const int refine_cells =
static_cast<int>(adjusted_fractions.first * criteria.size());
205 const int coarsen_cells =
static_cast<int>(adjusted_fractions.second * criteria.size());
207 if (refine_cells || coarsen_cells)
209 Vector<Number> tmp (criteria);
212 if (static_cast<size_t>(refine_cells) == criteria.size())
213 refine (tria, criteria, -std::numeric_limits<double>::max());
216 std::nth_element (tmp.begin(), tmp.begin()+refine_cells,
218 std::greater<double>());
219 refine (tria, criteria, *(tmp.begin() + refine_cells));
225 if (static_cast<size_t>(coarsen_cells) == criteria.size())
226 coarsen (tria, criteria, std::numeric_limits<double>::max());
229 std::nth_element (tmp.begin(), tmp.begin()+tmp.size()-coarsen_cells,
231 std::greater<double>());
233 *(tmp.begin() + tmp.size() - coarsen_cells));
241 template <
int dim,
typename Number,
int spacedim>
244 const Vector<Number> &criteria,
245 const double top_fraction,
246 const double bottom_fraction,
247 const unsigned int max_n_cells)
262 const double total_error = tmp.l1_norm();
266 std::sort (tmp.begin(), tmp.end(), std::greater<double>());
269 typename Vector<Number>::const_iterator pp=tmp.begin();
271 (
sum<top_fraction*total_error) && (pp!=(tmp.end()-1));
274 double top_threshold = ( pp != tmp.begin () ?
277 typename Vector<Number>::const_iterator qq=(tmp.end()-1);
279 (
sum<bottom_fraction*total_error) && (qq!=tmp.begin());
282 double bottom_threshold = ( qq != (tmp.end()-1) ?
299 const unsigned int refine_cells = pp - tmp.begin(),
300 coarsen_cells = tmp.end() - qq;
302 if (static_cast<unsigned int>
311 refine_and_coarsen_fixed_number (tria,
313 1.*refine_cells/criteria.size(),
314 1.*coarsen_cells/criteria.size(),
352 const auto minmax_element = std::minmax_element(criteria.begin(), criteria.end());
353 if ((top_threshold == *minmax_element.second) && (top_fraction != 1))
354 top_threshold *= 0.999;
356 if (bottom_threshold>=top_threshold)
357 bottom_threshold = 0.999*top_threshold;
360 if (top_threshold < *minmax_element.second)
361 refine (tria, criteria, top_threshold, pp - tmp.
begin());
363 if (bottom_threshold > *minmax_element.first)
364 coarsen (tria, criteria, bottom_threshold);
369 template <
int dim,
typename Number,
int spacedim>
372 const Vector<Number> &criteria,
373 const unsigned int order)
380 std::vector<unsigned int> cell_indices(criteria.size());
381 std::iota(cell_indices.begin(), cell_indices.end(), 0u);
383 std::sort(cell_indices.begin(), cell_indices.end(),
384 [&criteria](
const unsigned int left,
385 const unsigned int right)
387 return criteria[left] > criteria[right];
390 double expected_error_reduction = 0;
391 const double original_error = criteria.l1_norm();
393 const std::size_t N = criteria.size();
396 double min_cost = std::numeric_limits<double>::max();
397 std::size_t min_arg = 0;
399 for (std::size_t M = 0; M<criteria.size(); ++M)
401 expected_error_reduction += (1-std::pow(2.,-1.*order)) * criteria(cell_indices[M]);
403 const double cost = std::pow(((std::pow(2.,dim)-1)*(1+M)+N),
405 (original_error-expected_error_reduction);
406 if (cost <= min_cost)
413 refine (tria, criteria, criteria(cell_indices[min_arg]));
418 #include "grid_refinement.inst" 420 DEAL_II_NAMESPACE_CLOSE
unsigned int n_active_cells() const
static const unsigned int invalid_unsigned_int
active_cell_iterator begin_active(const unsigned int level=0) const
cell_iterator begin(const unsigned int level=0) const
cell_iterator end() const
void refine_and_coarsen_optimize(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const unsigned int order=2)
static ::ExceptionBase & ExcNegativeCriteria()
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void coarsen(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold)
SymmetricTensor< rank, dim, Number > sum(const SymmetricTensor< rank, dim, Number > &local, const MPI_Comm &mpi_communicator)
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())
std::pair< double, double > adjust_refine_and_coarsen_number_fraction(const unsigned int current_n_cells, const unsigned int max_n_cells, const double top_fraction_of_cells, const double bottom_fraction_of_cells)
static ::ExceptionBase & ExcInvalidParameterValue()
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(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold, const unsigned int max_to_mark=numbers::invalid_unsigned_int)