313 dealii::Triangulation<dim> &triangulation [[maybe_unused]])
const
315 auto &discretization [[maybe_unused]] = offline_data_->discretization();
316 Assert(&triangulation == &discretization.triangulation(),
317 dealii::ExcInternalError());
323 switch (adaptation_strategy_) {
326 for (
auto &cell : triangulation.active_cell_iterators())
327 cell->set_refine_flag();
332 indicators_.reinit(triangulation.n_active_cells());
333 populate_cell_indicators_with_random_values();
337 indicators_.reinit(triangulation.n_active_cells());
338 populate_cell_indicators_from_smoothness_indicators();
342 AssertThrow(
false, dealii::ExcInternalError());
350 switch (marking_strategy_) {
353 float inv_denominator = 1.f;
356 if (!absolute_threshold_) {
361 float minimum = std::numeric_limits<float>::max();
363 for (
const auto &cell : triangulation.active_cell_iterators()) {
364 if (!cell->is_locally_owned())
366 const auto indicator = indicators_[cell->active_cell_index()];
370 minimum = dealii::Utilities::MPI::min(
371 minimum, mpi_ensemble_.ensemble_communicator());
372 maximum = dealii::Utilities::MPI::max(
373 maximum, mpi_ensemble_.ensemble_communicator());
375 constexpr float eps = std::numeric_limits<float>::epsilon();
378 bias = (
minimum + 5.f * eps) * inv_denominator;
385 for (
const auto &cell : triangulation.active_cell_iterators()) {
386 if (!cell->is_locally_owned())
389 auto indicator = indicators_[cell->active_cell_index()];
390 indicator = indicator * inv_denominator - bias;
391 if (indicator < coarsening_threshold_)
392 cell->set_coarsen_flag();
393 else if (indicator > refinement_threshold_)
394 cell->set_refine_flag();
399 AssertThrow(
false, dealii::ExcInternalError());
408 if (triangulation.n_levels() > max_refinement_level_)
409 for (
const auto &cell :
410 triangulation.active_cell_iterators_on_level(max_refinement_level_))
411 cell->clear_refine_flag();
413 for (
const auto &cell :
414 triangulation.active_cell_iterators_on_level(min_refinement_level_))
415 cell->clear_coarsen_flag();
426 const auto &[U, precomputed, parabolic] = state_vector;
427 U.template copy_to_memory_space<dealii::MemorySpace::Host>();
428 precomputed.template copy_to_memory_space<dealii::MemorySpace::Host>();
431 const auto &affine_constraints = offline_data_->affine_constraints();
432 const unsigned int n_internal = offline_data_->n_locally_internal();
433 const unsigned int n_owned = offline_data_->n_locally_owned();
434 const auto sparsity_simd_view =
435 offline_data_->sparsity_pattern_simd().view();
436 const auto betaij_matrix_view = offline_data_->betaij_matrix().view();
437 using VA = dealii::VectorizedArray<Number>;
443 selected_components_extractor_.prepare_extraction(state_vector);
444 auto quantities = selected_components_extractor_.view().extract();
446 for (
auto &it : quantities) {
447 it.update_ghost_values();
448 affine_constraints.distribute(it);
449 it.update_ghost_values();
456 const unsigned int n_entries = quantities.size();
457 const auto &scalar_partitioner = offline_data_->scalar_partitioner();
464 std::vector<ScalarHostVector> numerator(std::max(1u, n_entries));
465 std::vector<ScalarHostVector> denominator(std::max(1u, n_entries));
466 for (
auto &it : numerator)
467 it.reinit(scalar_partitioner);
468 for (
auto &it : denominator)
469 it.reinit(scalar_partitioner);
475 const auto body = [&](
auto sentinel,
unsigned int i) {
476 using T =
decltype(sentinel);
477 unsigned int stride_size = get_stride_size<T>;
480 const unsigned int row_length = sparsity_simd_view.row_length(i);
484 boost::container::small_vector<T, 10> value_i(n_entries, T(0.));
485 for (
unsigned int k = 0; k < n_entries; ++k) {
486 value_i[k] = read_entry<T>(quantities[k], i);
489 boost::container::small_vector<T, 10> numerator_i(n_entries, T(0.));
490 boost::container::small_vector<T, 10> denominator_i(n_entries, T(0.));
492 const unsigned int *js = sparsity_simd_view.columns(i);
493 for (
unsigned int col_idx = 0; col_idx < row_length;
494 ++col_idx, js += stride_size) {
501 betaij_matrix_view.template read_entry<T>(i, col_idx);
503 for (
unsigned int k = 0; k < n_entries; ++k) {
504 const auto value_j_k = read_entry<T>(quantities[k], js);
505 numerator_i[k] += beta_ij * (value_j_k - value_i[k]);
508 std::max(std::abs(value_j_k), std::abs(value_i[k]));
511 for (
unsigned int k = 0; k < n_entries; ++k) {
512 write_entry<T>(numerator[k], numerator_i[k], i);
513 write_entry<T>(denominator[k], denominator_i[k], i);
518 cpu_simd_loop<Number>(
"mesh_adaptor_1", body, 0, n_internal, n_owned);
524 constexpr Number eps = std::numeric_limits<Number>::epsilon();
526 std::vector<Number> denominator_global_maximum(n_entries);
527 for (
unsigned int k = 0; k < n_entries; ++k) {
528 denominator_global_maximum[k] = dealii::Utilities::MPI::max(
529 denominator[k].linfty_norm(), mpi_ensemble_.ensemble_communicator());
531 denominator_global_maximum[k] =
532 std::max(denominator_global_maximum[k], eps);
535 const auto body_normalize = [&](
auto sentinel,
unsigned int i) {
536 using T =
decltype(sentinel);
539 const unsigned int row_length = sparsity_simd_view.row_length(i);
543 auto alpha_i = T(0.);
544 for (
unsigned int k = 0; k < n_entries; ++k) {
545 const auto numerator_i = read_entry<T>(numerator[k], i);
546 const auto denominator_i = read_entry<T>(denominator[k], i);
549 (Number(1.) - smoothness_local_global_ratio_) * denominator_i +
550 smoothness_local_global_ratio_ * denominator_global_maximum[k];
551 denominator = std::max(T(eps), denominator);
553 alpha_i += std::abs(numerator_i) / denominator;
556 alpha_i = std::min(alpha_i, T(smoothness_max_cutoff_));
557 alpha_i = std::max(alpha_i, T(smoothness_min_cutoff_));
558 write_entry<T>( numerator[0], alpha_i, i);
561 cpu_simd_loop<Number>(
562 "mesh_adaptor_2", body_normalize, 0, n_internal, n_owned);
568 const auto body_widen = [&](
auto sentinel,
unsigned int i) {
569 using T =
decltype(sentinel);
570 unsigned int stride_size = get_stride_size<T>;
573 const unsigned int row_length = sparsity_simd_view.row_length(i);
577 auto alpha_i = read_entry<T>(numerator[0], i);
579 const unsigned int *js = sparsity_simd_view.columns(i);
580 for (
unsigned int col_idx = 0; col_idx < row_length;
581 ++col_idx, js += stride_size) {
587 const auto alpha_j = read_entry<T>(numerator[0], js);
589 alpha_i = std::max(alpha_i, alpha_j);
592 write_entry<T>( denominator[0], alpha_i, i);
595 for (
unsigned int cycle = 0; cycle < smoothness_widen_stencil_; ++cycle) {
596 numerator[0].update_ghost_values();
597 cpu_simd_loop<Number>(
598 "mesh_adaptor_3", body_widen, 0, n_internal, n_owned);
599 numerator[0] = denominator[0];
602 numerator[0].update_ghost_values();
603 affine_constraints.distribute(numerator[0]);
609 smoothness_indicators_.reinit_with_scalar_partitioner(scalar_partitioner);
610 const auto smoothness_indicators_view = smoothness_indicators_.view();
611 smoothness_indicators_view.insert_component(numerator[0], 0);
612 smoothness_indicators_view.update_ghost_values();