316 dealii::Triangulation<dim> &triangulation [[maybe_unused]])
const
318 auto &discretization [[maybe_unused]] = offline_data_->discretization();
319 Assert(&triangulation == &discretization.triangulation(),
320 dealii::ExcInternalError());
326 switch (adaptation_strategy_) {
329 for (
auto &cell : triangulation.active_cell_iterators())
330 cell->set_refine_flag();
335 indicators_.reinit(triangulation.n_active_cells());
336 populate_cell_indicators_with_random_values();
340 indicators_.reinit(triangulation.n_active_cells());
341 populate_cell_indicators_from_smoothness_indicators();
345 AssertThrow(
false, dealii::ExcInternalError());
353 switch (marking_strategy_) {
356 float inv_denominator = 1.f;
359 if (!absolute_threshold_) {
364 float minimum = std::numeric_limits<float>::max();
366 for (
const auto &cell : triangulation.active_cell_iterators()) {
367 if (!cell->is_locally_owned())
369 const auto indicator = indicators_[cell->active_cell_index()];
373 minimum = dealii::Utilities::MPI::min(
374 minimum, mpi_ensemble_.ensemble_communicator());
375 maximum = dealii::Utilities::MPI::max(
376 maximum, mpi_ensemble_.ensemble_communicator());
378 constexpr float eps = std::numeric_limits<float>::epsilon();
381 bias = (
minimum + 5.f * eps) * inv_denominator;
388 for (
const auto &cell : triangulation.active_cell_iterators()) {
389 if (!cell->is_locally_owned())
392 auto indicator = indicators_[cell->active_cell_index()];
393 indicator = indicator * inv_denominator - bias;
394 if (indicator < coarsening_threshold_)
395 cell->set_coarsen_flag();
396 else if (indicator > refinement_threshold_)
397 cell->set_refine_flag();
402 AssertThrow(
false, dealii::ExcInternalError());
411 if (triangulation.n_levels() > max_refinement_level_)
412 for (
const auto &cell :
413 triangulation.active_cell_iterators_on_level(max_refinement_level_))
414 cell->clear_refine_flag();
416 for (
const auto &cell :
417 triangulation.active_cell_iterators_on_level(min_refinement_level_))
418 cell->clear_coarsen_flag();
427 const auto &affine_constraints = offline_data_->affine_constraints();
428 const unsigned int n_internal = offline_data_->n_locally_internal();
429 const unsigned int n_owned = offline_data_->n_locally_owned();
430 const auto sparsity_simd_view =
431 offline_data_->sparsity_pattern_simd().view();
432 const auto betaij_matrix_view = offline_data_->betaij_matrix().view();
433 using VA = dealii::VectorizedArray<Number>;
439 selected_components_extractor_.prepare_extraction(state_vector);
440 auto quantities = selected_components_extractor_.view().extract();
442 for (
auto &it : quantities) {
443 it.update_ghost_values();
444 affine_constraints.distribute(it);
445 it.update_ghost_values();
452 const unsigned int n_entries = quantities.size();
453 const auto &scalar_partitioner = offline_data_->scalar_partitioner();
459 std::vector<ScalarHostVector<Number>> numerator(std::max(1u, n_entries));
460 std::vector<ScalarHostVector<Number>> denominator(std::max(1u, n_entries));
461 for (
auto &it : numerator)
462 it.reinit(scalar_partitioner);
463 for (
auto &it : denominator)
464 it.reinit(scalar_partitioner);
470 const auto body = [&](
auto sentinel,
unsigned int i) {
471 using T =
decltype(sentinel);
472 const unsigned int stride_size = sparsity_simd_view.stride_of_row(i);
475 const unsigned int row_length = sparsity_simd_view.row_length(i);
479 boost::container::small_vector<T, 10> value_i(n_entries, T(0.));
480 for (
unsigned int k = 0; k < n_entries; ++k) {
481 value_i[k] = read_entry<T>(quantities[k], i);
484 boost::container::small_vector<T, 10> numerator_i(n_entries, T(0.));
485 boost::container::small_vector<T, 10> denominator_i(n_entries, T(0.));
487 const unsigned int *js = sparsity_simd_view.columns(i);
488 for (
unsigned int col_idx = 0; col_idx < row_length;
489 ++col_idx, js += stride_size) {
496 betaij_matrix_view.template read_entry<T>(i, col_idx);
498 for (
unsigned int k = 0; k < n_entries; ++k) {
499 const auto value_j_k = read_entry<T>(quantities[k], js);
500 numerator_i[k] += beta_ij * (value_j_k - value_i[k]);
503 std::max(std::abs(value_j_k), std::abs(value_i[k]));
506 for (
unsigned int k = 0; k < n_entries; ++k) {
507 write_entry<T>(numerator[k], numerator_i[k], i);
508 write_entry<T>(denominator[k], denominator_i[k], i);
513 cpu_simd_loop<Number>(
"mesh_adaptor_1", body, 0, n_internal, n_owned);
519 constexpr Number eps = std::numeric_limits<Number>::epsilon();
521 std::vector<Number> denominator_global_maximum(n_entries);
522 for (
unsigned int k = 0; k < n_entries; ++k) {
523 denominator_global_maximum[k] = dealii::Utilities::MPI::max(
524 denominator[k].linfty_norm(), mpi_ensemble_.ensemble_communicator());
526 denominator_global_maximum[k] =
527 std::max(denominator_global_maximum[k], eps);
530 const auto body_normalize = [&](
auto sentinel,
unsigned int i) {
531 using T =
decltype(sentinel);
534 const unsigned int row_length = sparsity_simd_view.row_length(i);
538 auto alpha_i = T(0.);
539 for (
unsigned int k = 0; k < n_entries; ++k) {
540 const auto numerator_i = read_entry<T>(numerator[k], i);
541 const auto denominator_i = read_entry<T>(denominator[k], i);
544 (Number(1.) - smoothness_local_global_ratio_) * denominator_i +
545 smoothness_local_global_ratio_ * denominator_global_maximum[k];
546 denominator = std::max(T(eps), denominator);
548 alpha_i += std::abs(numerator_i) / denominator;
551 alpha_i = std::min(alpha_i, T(smoothness_max_cutoff_));
552 alpha_i = std::max(alpha_i, T(smoothness_min_cutoff_));
553 write_entry<T>( numerator[0], alpha_i, i);
556 cpu_simd_loop<Number>(
557 "mesh_adaptor_2", body_normalize, 0, n_internal, n_owned);
563 const auto body_widen = [&](
auto sentinel,
unsigned int i) {
564 using T =
decltype(sentinel);
565 const unsigned int stride_size = sparsity_simd_view.stride_of_row(i);
568 const unsigned int row_length = sparsity_simd_view.row_length(i);
572 auto alpha_i = read_entry<T>(numerator[0], i);
574 const unsigned int *js = sparsity_simd_view.columns(i);
575 for (
unsigned int col_idx = 0; col_idx < row_length;
576 ++col_idx, js += stride_size) {
582 const auto alpha_j = read_entry<T>(numerator[0], js);
584 alpha_i = std::max(alpha_i, alpha_j);
587 write_entry<T>( denominator[0], alpha_i, i);
590 for (
unsigned int cycle = 0; cycle < smoothness_widen_stencil_; ++cycle) {
591 numerator[0].update_ghost_values();
592 cpu_simd_loop<Number>(
593 "mesh_adaptor_3", body_widen, 0, n_internal, n_owned);
594 numerator[0] = denominator[0];
597 numerator[0].update_ghost_values();
598 affine_constraints.distribute(numerator[0]);
604 smoothness_indicators_.reinit_with_scalar_partitioner(scalar_partitioner,
606 const auto smoothness_indicators_view =
607 smoothness_indicators_.template view<1>();
608 smoothness_indicators_view.insert_component(numerator[0], 0);
609 smoothness_indicators_view.update_ghost_values();