11#include <deal.II/base/array_view.h>
12#include <deal.II/grid/grid_refinement.h>
13#include <deal.II/numerics/error_estimator.h>
17 template <
typename Description,
int dim,
typename Number>
25 const std::string &subsection )
26 : ParameterAcceptor(subsection)
27 , mpi_ensemble_(mpi_ensemble)
28 , offline_data_(&offline_data)
29 , hyperbolic_system_(&hyperbolic_system)
30 , parabolic_system_(¶bolic_system)
31 , need_mesh_adaptation_(false)
32 , initial_precomputed_(initial_precomputed)
36 add_parameter(
"adaptation strategy",
38 "The chosen adaptation strategy. Possible values are: global "
39 "refinement, random adaptation, kelly estimator");
42 add_parameter(
"marking strategy",
44 "The chosen marking strategy. Possible values are: fixed "
45 "number, fixed fraction");
47 time_point_selection_strategy_ =
49 add_parameter(
"time point selection strategy",
50 time_point_selection_strategy_,
51 "The chosen time point selection strategy. Possible values "
52 "are: fixed time points, simulation cycle");
55 enter_subsection(
"adaptation strategies");
56 random_adaptation_mersenne_twister_seed_ = 42u;
57 add_parameter(
"random adaptation: mersenne_twister_seed",
58 random_adaptation_mersenne_twister_seed_,
59 "Seed for 64bit Mersenne Twister used for random refinement");
62 "kelly estimator: quantities",
64 "List of conserved, primitive or precomputed quantities that will be "
65 "used for the Kelly error estimator for refinement and coarsening.");
70 enter_subsection(
"marking strategies");
71 refinement_fraction_ = 0.3;
72 add_parameter(
"refinement fraction",
74 "Marking: fraction of cells selected for refinement.");
76 coarsening_fraction_ = 0.3;
77 add_parameter(
"coarsening fraction",
79 "Marking: fraction of cells selected for coarsening.");
81 min_refinement_level_ = 0;
82 add_parameter(
"minimal refinement level",
83 min_refinement_level_,
84 "Marking: minimal refinement level of cells that will be "
85 "maintained while coarsening cells.");
87 max_refinement_level_ = 1000;
88 add_parameter(
"maximal refinement level",
89 max_refinement_level_,
90 "Marking: maximal refinement level of cells that will be "
91 "maintained while refininig cells.");
93 max_num_cells_ = 100000;
95 "maximal number of cells",
97 "Marking: maximal number of cells used for the fixed fraction "
98 "strategy. Note this is only an indicator and not strictly enforced.");
104 enter_subsection(
"time point selection strategies");
105 adaptation_time_points_ = {};
106 add_parameter(
"fixed time points",
107 adaptation_time_points_,
108 "List of time points in (simulation) time at which we will "
109 "perform a mesh adaptation cycle.");
111 adaptation_cycle_interval_ = 5;
112 add_parameter(
"simulation cycle: interval",
113 adaptation_cycle_interval_,
114 "The nth simulation cycle at which we will "
115 "perform mesh adapation.");
118 const auto call_back = [
this] {
120 mersenne_twister_.seed(random_adaptation_mersenne_twister_seed_);
124 ParameterAcceptor::parse_parameters_call_back.connect(call_back);
128 template <
typename Description,
int dim,
typename Number>
132 std::cout <<
"MeshAdaptor<dim, Number>::prepare()" << std::endl;
135 if (time_point_selection_strategy_ ==
138 const auto new_end = std::remove_if(
139 adaptation_time_points_.begin(),
140 adaptation_time_points_.end(),
141 [&](
const Number &t_refinement) { return (t > t_refinement); });
142 adaptation_time_points_.erase(new_end, adaptation_time_points_.end());
151 need_mesh_adaptation_ =
false;
155 template <
typename Description,
int dim,
typename Number>
158 std::generate(std::begin(indicators_), std::end(indicators_), [&]() {
159 static std::uniform_real_distribution<double> distribution(0.0, 10.0);
160 return distribution(mersenne_twister_);
165 template <
typename Description,
int dim,
typename Number>
170 const auto &affine_constraints = offline_data_->affine_constraints();
176 initial_precomputed_,
180 for (
auto &it : kelly_components_) {
181 affine_constraints.distribute(it);
182 it.update_ghost_values();
187 template <
typename Description,
int dim,
typename Number>
188 void MeshAdaptor<Description, dim, Number>::compute_kelly_indicators()
const
190#if !DEAL_II_VERSION_GTE(9, 6, 0)
193 dealii::ExcMessage(
"The MeshAdaptor::compute_kelly_indicators() method "
194 "needs deal.II version 9.6.0 or newer"));
201 std::vector<dealii::Vector<float>> kelly_errors;
202 std::vector<dealii::Vector<float> *> ptr_kelly_errors;
204 const auto size = indicators_.size();
205 kelly_errors.resize(kelly_components_.size());
207 for (
auto &it : kelly_errors) {
209 ptr_kelly_errors.push_back(&it);
212 auto array_view_kelly_errors = dealii::make_array_view(ptr_kelly_errors);
213 std::vector<const dealii::ReadVector<Number> *> ptr_kelly_components;
214 for (
const auto &it : kelly_components_)
215 ptr_kelly_components.push_back(&it);
217 const auto array_view_kelly_components =
218 dealii::make_array_view(ptr_kelly_components);
220 dealii::KellyErrorEstimator<dim>::estimate(
221 offline_data_->discretization().mapping(),
222 offline_data_->dof_handler(),
223 offline_data_->discretization().face_quadrature(),
225 array_view_kelly_components,
226 array_view_kelly_errors);
229 for (
const auto &it : kelly_errors)
235 template <
typename Description,
int dim,
typename Number>
237 const StateVector &state_vector,
const Number t,
unsigned int cycle)
240 std::cout <<
"MeshAdaptor<dim, Number>::analyze()" << std::endl;
248 switch (time_point_selection_strategy_) {
251 const auto new_end = std::remove_if(
252 adaptation_time_points_.begin(),
253 adaptation_time_points_.end(),
254 [&](
const Number &t_refinement) {
255 if (t < t_refinement)
257 need_mesh_adaptation_ = true;
260 adaptation_time_points_.erase(new_end, adaptation_time_points_.end());
265 if (cycle % adaptation_cycle_interval_ == 0)
266 need_mesh_adaptation_ =
true;
270 AssertThrow(
false, dealii::ExcInternalError());
274 if (!need_mesh_adaptation_)
282 switch (adaptation_strategy_) {
292 populate_kelly_quantities(state_vector);
296 AssertThrow(
false, dealii::ExcInternalError());
302 template <
typename Description,
int dim,
typename Number>
307 auto &discretization [[maybe_unused]] = offline_data_->discretization();
308 Assert(&triangulation == &discretization.triangulation(),
309 dealii::ExcInternalError());
315 switch (adaptation_strategy_) {
318 for (
auto &cell : triangulation.active_cell_iterators())
319 cell->set_refine_flag();
324 indicators_.reinit(triangulation.n_active_cells());
325 compute_random_indicators();
329 indicators_.reinit(triangulation.n_active_cells());
330 compute_kelly_indicators();
334 AssertThrow(
false, dealii::ExcInternalError());
342 Assert(indicators_.size() == triangulation.n_active_cells(),
343 dealii::ExcInternalError());
345 switch (marking_strategy_) {
347 dealii::GridRefinement::refine_and_coarsen_fixed_number(
350 refinement_fraction_,
351 coarsening_fraction_);
354 dealii::GridRefinement::refine_and_coarsen_fixed_fraction(
357 refinement_fraction_,
358 coarsening_fraction_,
363 AssertThrow(
false, dealii::ExcInternalError());
372 if (triangulation.n_levels() > max_refinement_level_)
373 for (
const auto &cell :
374 triangulation.active_cell_iterators_on_level(max_refinement_level_))
375 cell->clear_refine_flag();
377 for (
const auto &cell :
378 triangulation.active_cell_iterators_on_level(min_refinement_level_))
379 cell->clear_coarsen_flag();
typename View::StateVector StateVector
typename Discretization< dim >::Triangulation Triangulation
Vectors::ScalarVector< Number > ScalarVector
MeshAdaptor(const MPIEnsemble &mpi_ensemble, const OfflineData< dim, Number > &offline_data, const HyperbolicSystem &hyperbolic_system, const ParabolicSystem ¶bolic_system, const InitialPrecomputedVector &initial_precomputed, const ScalarVector &alpha, const std::string &subsection="/MeshAdaptor")
void analyze(const StateVector &state_vector, const Number t, unsigned int cycle)
typename View::InitialPrecomputedVector InitialPrecomputedVector
typename Description::ParabolicSystem ParabolicSystem
typename Description::HyperbolicSystem HyperbolicSystem
void prepare(const Number t)
void mark_cells_for_coarsening_and_refinement(Triangulation &triangulation) const
std::tuple< MultiComponentVector< Number, problem_dim >, MultiComponentVector< Number, prec_dim >, BlockVector< Number > > StateVector