Fluid structure interaction suite
grid_refinement.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2022 by Luca Heltai
4 //
5 // This file is part of the FSI-suite platform, based on the deal.II library.
6 //
7 // The FSI-suite platform is free software; you can use it, redistribute it,
8 // and/or modify it under the terms of the GNU Lesser General Public License as
9 // published by the Free Software Foundation; either version 3.0 of the License,
10 // or (at your option) any later version. The full text of the license can be
11 // found in the file LICENSE at the top level of the FSI-suite platform
12 // distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef parsed_tools_grid_refinement_h
17 #define parsed_tools_grid_refinement_h
18 
22 
24 
26 #include <deal.II/grid/tria.h>
27 
29 
30 #ifdef DEAL_II_WITH_MPI
31 # ifdef DEAL_II_WITH_P4EST
34 # endif
35 #endif
36 
37 #include "parsed_tools/enum.h"
38 
39 namespace ParsedTools
40 {
44  enum class RefinementStrategy
45  {
46  global = 1,
47  fixed_fraction = 2,
48  fixed_number = 3,
49  };
50 
68  class GridRefinement : public dealii::ParameterAcceptor
69  {
70  public:
75  const std::string &section_name = "",
76  const unsigned int &n_refinement_cycles = 1,
78  const std::string &estimator_type = "kelly",
79  const double &top_parameter = .3,
80  const double &bottom_parameter = 0.1,
81  const unsigned int &max_cells = 0,
82  const int &min_level = 0,
83  const int &max_level = 0,
84  const std::map<std::string, std::function<void(dealii::Vector<float> &)>>
85  &optional_estimators = {},
86  const dealii::ComponentMask &component_mask = dealii::ComponentMask());
87 
97  template <int dim, int spacedim>
98  void
99  mark_cells(const dealii::Vector<float> &criteria,
100  dealii::Triangulation<dim, spacedim> &tria) const;
101 
102 #ifdef DEAL_II_WITH_MPI
103 # ifdef DEAL_II_WITH_P4EST
115  template <int dim, int spacedim>
116  void
118  const dealii::Vector<float> &criteria,
119  dealii::parallel::distributed::Triangulation<dim, spacedim> &tria) const;
120 # endif
121 #endif
122 
126  template <int dim, int spacedim, typename VectorType>
127  void
129  const dealii::Mapping<dim, spacedim> &mapping,
130  const dealii::DoFHandler<dim, spacedim> &dof_handler,
131  const VectorType &solution,
132  dealii::Vector<float> &estimated_error_per_cell,
133  const std::map<
134  dealii::types::boundary_id,
135  const dealii::Function<spacedim, typename VectorType::value_type> *>
136  &neumann_bc = {},
137  const dealii::Function<spacedim> *coefficients = nullptr,
138  const typename dealii::KellyErrorEstimator<dim, spacedim>::Strategy
139  strategy =
140  dealii::KellyErrorEstimator<dim, spacedim>::cell_diameter_over_24)
141  const;
142 
147  template <int dim, int spacedim, typename VectorType>
148  void
150  const dealii::DoFHandler<dim, spacedim> &dof_handler,
151  const VectorType &solution,
152  dealii::Vector<float> &estimated_error_per_cell,
153  const std::map<
154  dealii::types::boundary_id,
155  const dealii::Function<spacedim, typename VectorType::value_type> *>
156  &neumann_bc = {},
157  const dealii::Function<spacedim> *coefficients = nullptr,
158  const typename dealii::KellyErrorEstimator<dim, spacedim>::Strategy
159  strategy =
160  dealii::KellyErrorEstimator<dim, spacedim>::cell_diameter_over_24)
161  const;
162 
166  const RefinementStrategy &
167  get_strategy() const
168  {
169  return strategy;
170  }
171 
175  const unsigned int &
177  {
178  return n_refinement_cycles;
179  }
180 
185  dealii::std_cxx20::ranges::iota_view<unsigned int, unsigned int>
187  {
188  return dealii::std_cxx20::ranges::iota_view<unsigned int, unsigned int>(
190  }
191 
195  template <int dim, int spacedim, typename VectorType, typename Tria>
196  void
197  estimate_mark_refine(const dealii::Mapping<dim, spacedim> &mapping,
198  const dealii::DoFHandler<dim, spacedim> &dof_handler,
199  const VectorType &solution,
200  Tria &tria) const;
201 
205  template <int dim, int spacedim, typename VectorType, typename Tria>
206  void
207  estimate_mark_refine(const dealii::DoFHandler<dim, spacedim> &dof_handler,
208  const VectorType &solution,
209  Tria &tria) const;
210 
211  private:
216  template <int dim, int spacedim>
217  void
218  limit_levels(dealii::Triangulation<dim, spacedim> &tria) const;
219 
220  unsigned int n_refinement_cycles;
224  unsigned int max_cells;
227 
228  std::string estimator_type;
229  std::map<std::string, std::function<void(dealii::Vector<float> &)>>
231  dealii::ComponentMask component_mask;
232  dealii::types::subdomain_id subdomain_id =
233  dealii::numbers::invalid_material_id;
234  dealii::types::material_id material_id =
235  dealii::numbers::invalid_material_id;
236  };
237 
238  // ================================================================
239  // Template implementation
240  // ================================================================
241 #ifndef DOXYGEN
242 
243 # ifdef DEAL_II_WITH_MPI
244 # ifdef DEAL_II_WITH_P4EST
245  template <int dim, int spacedim>
246  void
248  const dealii::Vector<float> &criteria,
249  dealii::parallel::distributed::Triangulation<dim, spacedim> &tria) const
250  {
252  {
253  if constexpr (dim > 1)
254  {
255  dealii::parallel::distributed::GridRefinement::
256  refine_and_coarsen_fixed_number(
257  tria,
258  criteria,
261  max_cells > 0 ? max_cells :
262  std::numeric_limits<unsigned int>::max());
263  }
264  else
265  {
266  AssertThrow(false, dealii::ExcMessage("Not implemented for dim=1"));
267  }
268  }
270  {
271  if constexpr (dim > 1)
272  {
273  dealii::parallel::distributed::GridRefinement::
274  refine_and_coarsen_fixed_fraction(tria,
275  criteria,
278  }
279  else
280  {
281  AssertThrow(false, dealii::ExcMessage("Not implemented for dim=1"));
282  }
283  }
285  for (const auto &cell : tria.active_cell_iterators())
286  cell->set_refine_flag();
287  else
289  limit_levels(tria);
290  }
291 # endif
292 # endif
293 
294 
295 
296  template <int dim, int spacedim>
297  void
298  GridRefinement::mark_cells(const dealii::Vector<float> &criteria,
299  dealii::Triangulation<dim, spacedim> &tria) const
300  {
302  {
303  if constexpr (dim == 1 && spacedim == 3)
304  {
305  AssertThrow(false,
307  "Not instantiated for dim=1, spacedim=3"));
308  }
309  else
310  {
311  dealii::GridRefinement::refine_and_coarsen_fixed_number(
312  tria,
313  criteria,
316  max_cells > 0 ? max_cells :
317  std::numeric_limits<unsigned int>::max());
318  }
319  }
321  {
322  if constexpr (dim == 1 && spacedim == 3)
323  {
324  AssertThrow(false,
326  "Not instantiated for dim=1, spacedim=3"));
327  }
328  else
329  {
330  dealii::GridRefinement::refine_and_coarsen_fixed_fraction(
331  tria,
332  criteria,
335  max_cells > 0 ? max_cells :
336  std::numeric_limits<unsigned int>::max());
337  }
338  }
340  {
341  for (const auto &cell : tria.active_cell_iterators())
342  if (cell->is_locally_owned())
343  cell->set_refine_flag();
344  }
345  else
347  limit_levels(tria);
348  }
349 
350 
351 
352  template <int dim, int spacedim>
353  void
354  GridRefinement::limit_levels(dealii::Triangulation<dim, spacedim> &tria) const
355  {
356  if (min_level != 0 || max_level != 0)
357  for (const auto &cell : tria.active_cell_iterators())
358  if (cell->is_locally_owned())
359  {
360  if (min_level != 0 && cell->level() < min_level)
361  cell->set_refine_flag();
362  else if (max_level != 0 && cell->level() > max_level)
363  cell->set_coarsen_flag();
364  else if (max_level != 0 && cell->level() == max_level)
365  cell->clear_refine_flag();
366  else if (min_level != 0 && cell->level() == min_level)
367  cell->clear_coarsen_flag();
368  }
369  }
370 
371 
372 
373  template <int dim, int spacedim, typename VectorType>
374  void
376  const dealii::Mapping<dim, spacedim> &mapping,
377  const dealii::DoFHandler<dim, spacedim> &dof_handler,
378  const VectorType &solution,
379  dealii::Vector<float> &estimated_error_per_cell,
380  const std::map<
381  dealii::types::boundary_id,
382  const dealii::Function<spacedim, typename VectorType::value_type> *>
383  &neumann_bc,
384  const dealii::Function<spacedim> *coefficients,
385  const typename dealii::KellyErrorEstimator<dim, spacedim>::Strategy
386  strategy) const
387  {
388  if (this->strategy != RefinementStrategy::global)
389  {
390  AssertThrow(
391  dof_handler.get_triangulation().all_reference_cells_are_hyper_cube(),
393  "Local refinement is only supported on quad-only or "
394  "hex-only triangulations."));
395  if (this->estimator_type == "kelly")
396  {
397  dealii::QGauss<dim - 1> face_quadrature_formula(
398  dof_handler.get_fe().tensor_degree() + 1);
399 
400  estimated_error_per_cell.reinit(
401  dof_handler.get_triangulation().n_active_cells());
402 
403  dealii::KellyErrorEstimator<dim, spacedim>::estimate(
404  mapping,
405  dof_handler,
406  face_quadrature_formula,
407  neumann_bc,
408  solution,
409  estimated_error_per_cell,
410  this->component_mask,
411  coefficients,
412  dealii::numbers::invalid_unsigned_int,
413  this->subdomain_id,
414  this->material_id,
415  strategy);
416  }
417  else
418  {
420  estimated_error_per_cell);
421  }
422  }
423  }
424 
429  template <int dim, int spacedim, typename VectorType>
430  void
432  const dealii::DoFHandler<dim, spacedim> &dof_handler,
433  const VectorType &solution,
434  dealii::Vector<float> &estimated_error_per_cell,
435  const std::map<
436  dealii::types::boundary_id,
437  const dealii::Function<spacedim, typename VectorType::value_type> *>
438  &neumann_bc,
439  const dealii::Function<spacedim> *coefficients,
440  const typename dealii::KellyErrorEstimator<dim, spacedim>::Strategy
441  strategy) const
442  {
443  const auto &mapping =
444  dealii::get_default_linear_mapping(dof_handler.get_triangulation());
445  estimate_error(mapping,
446  dof_handler,
447  solution,
448  estimated_error_per_cell,
449  neumann_bc,
450  coefficients,
451  strategy);
452  }
453 
454 
455 
456  template <int dim, int spacedim, typename VectorType, typename Tria>
457  void
459  const dealii::DoFHandler<dim, spacedim> &dof_handler,
460  const VectorType &solution,
461  Tria &tria) const
462  {
463  const auto &mapping =
464  dealii::get_default_linear_mapping(dof_handler.get_triangulation());
465  estimate_mark_refine(mapping, dof_handler, solution, tria);
466  }
467 
468 
469 
470  template <int dim, int spacedim, typename VectorType, typename Tria>
471  void
473  const dealii::Mapping<dim, spacedim> &mapping,
474  const dealii::DoFHandler<dim, spacedim> &dof_handler,
475  const VectorType &solution,
476  Tria &tria) const
477  {
478  // No estimates to do in global refinement case
480  tria.refine_global(1);
481  else
482  {
483  dealii::Vector<float> estimated_error_per_cell;
484  estimate_error(mapping,
485  dof_handler,
486  solution,
487  estimated_error_per_cell);
488  mark_cells(estimated_error_per_cell, tria);
489  tria.execute_coarsening_and_refinement();
490  }
491  }
492 
493 #endif
494 
495 } // namespace ParsedTools
496 
497 
498 #endif
const std::string section_name
void estimate_mark_refine(const DoFHandler< dim, spacedim > &dof_handler, const VectorType &solution, Tria &tria) const
Perform all the steps of the ESTIMATE-MARK-REFINE cycle.
GridRefinement(const std::string &section_name="", const unsigned int &n_refinement_cycles=1, const RefinementStrategy &strategy=RefinementStrategy::global, const std::string &estimator_type="kelly", const double &top_parameter=.3, const double &bottom_parameter=0.1, const unsigned int &max_cells=0, const int &min_level=0, const int &max_level=0, const std::map< std::string, std::function< void(Vector< float > &)>> &optional_estimators={}, const ComponentMask &component_mask=ComponentMask())
Constructor.
RefinementStrategy strategy
std_cxx20::ranges::iota_view< unsigned int, unsigned int > get_refinement_cycles() const
Get Return an object that can be thought of as an array containing all indices from zero to n_refinem...
void estimate_mark_refine(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof_handler, const VectorType &solution, Tria &tria) const
Perform all the steps of the ESTIMATE-MARK-REFINE cycle.
const unsigned int & get_n_refinement_cycles() const
Get the total number of refinemt cycles.
void estimate_error(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof_handler, const VectorType &solution, Vector< float > &estimated_error_per_cell, const std::map< types::boundary_id, const Function< spacedim, typename VectorType::value_type > * > &neumann_bc={}, const Function< spacedim > *coefficients=nullptr, const typename KellyErrorEstimator< dim, spacedim >::Strategy strategy=KellyErrorEstimator< dim, spacedim >::cell_diameter_over_24) const
Call the error estimator specified in the parameter file.
void limit_levels(Triangulation< dim, spacedim > &tria) const
Make sure that the refinement level is kept between min_level and max_level.
void estimate_error(const DoFHandler< dim, spacedim > &dof_handler, const VectorType &solution, Vector< float > &estimated_error_per_cell, const std::map< types::boundary_id, const Function< spacedim, typename VectorType::value_type > * > &neumann_bc={}, const Function< spacedim > *coefficients=nullptr, const typename KellyErrorEstimator< dim, spacedim >::Strategy strategy=KellyErrorEstimator< dim, spacedim >::cell_diameter_over_24) const
Call the error estimator specified in the parameter file with a default mapping.
const RefinementStrategy & get_strategy() const
Get the current strategy object.
types::material_id material_id
void mark_cells(const Vector< float > &criteria, Triangulation< dim, spacedim > &tria) const
Mark cells a the triangulation for refinement or coarsening, according to the given strategy applied ...
std::map< std::string, std::function< void(Vector< float > &)> > optional_estimators
void mark_cells(const Vector< float > &criteria, parallel::distributed::Triangulation< dim, spacedim > &tria) const
Mark cells of a distribtued triangulation for refinement or coarsening, according to the given strate...
types::subdomain_id subdomain_id
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
We collect in this namespace some wrappers around commonly used deal.II classes, derived from the Par...
RefinementStrategy
Refinement strategy implemented in the GridRefinement class.