315 dealii::Triangulation<dim> &triangulation [[maybe_unused]])
const
317 auto &discretization [[maybe_unused]] = offline_data_->discretization();
318 Assert(&triangulation == &discretization.triangulation(),
319 dealii::ExcInternalError());
325 switch (adaptation_strategy_) {
328 for (
auto &cell : triangulation.active_cell_iterators())
329 cell->set_refine_flag();
334 indicators_.reinit(triangulation.n_active_cells());
335 populate_cell_indicators_with_random_values();
339 indicators_.reinit(triangulation.n_active_cells());
340 populate_cell_indicators_from_smoothness_indicators();
344 AssertThrow(
false, dealii::ExcInternalError());
352 switch (marking_strategy_) {
355 float inv_denominator = 1.f;
358 if (!absolute_threshold_) {
363 float minimum = std::numeric_limits<float>::max();
365 for (
const auto &cell : triangulation.active_cell_iterators()) {
366 if (!cell->is_locally_owned())
368 const auto indicator = indicators_[cell->active_cell_index()];
372 minimum = dealii::Utilities::MPI::min(
373 minimum, mpi_ensemble_.ensemble_communicator());
374 maximum = dealii::Utilities::MPI::max(
375 maximum, mpi_ensemble_.ensemble_communicator());
377 constexpr float eps = std::numeric_limits<float>::epsilon();
380 bias = (
minimum + 5.f * eps) * inv_denominator;
387 for (
const auto &cell : triangulation.active_cell_iterators()) {
388 if (!cell->is_locally_owned())
391 auto indicator = indicators_[cell->active_cell_index()];
392 indicator = indicator * inv_denominator - bias;
393 if (indicator < coarsening_threshold_)
394 cell->set_coarsen_flag();
395 else if (indicator > refinement_threshold_)
396 cell->set_refine_flag();
401 AssertThrow(
false, dealii::ExcInternalError());
410 if (triangulation.n_levels() > max_refinement_level_)
411 for (
const auto &cell :
412 triangulation.active_cell_iterators_on_level(max_refinement_level_))
413 cell->clear_refine_flag();
415 for (
const auto &cell :
416 triangulation.active_cell_iterators_on_level(min_refinement_level_))
417 cell->clear_coarsen_flag();
428 const auto &[U, precomputed, parabolic] = state_vector;
429 U.template copy_to_memory_space<dealii::MemorySpace::Host>();
430 precomputed.template copy_to_memory_space<dealii::MemorySpace::Host>();
433 const auto &affine_constraints = offline_data_->affine_constraints();
434 const unsigned int n_internal = offline_data_->n_locally_internal();
435 const unsigned int n_owned = offline_data_->n_locally_owned();
436 const auto sparsity_simd_view =
437 offline_data_->sparsity_pattern_simd().view();
438 const auto betaij_matrix_view = offline_data_->betaij_matrix().view();
439 using VA = dealii::VectorizedArray<Number>;
451 initial_precomputed_,
454 smoothness_selected_quantities_);
456 for (
auto &it : quantities) {
457 it.update_ghost_values();
458 affine_constraints.distribute(it);
459 it.update_ghost_values();
466 const unsigned int n_entries = quantities.size();
467 const auto &scalar_partitioner = offline_data_->scalar_partitioner();
474 std::vector<ScalarHostVector> numerator(std::max(1u, n_entries));
475 std::vector<ScalarHostVector> denominator(std::max(1u, n_entries));
476 for (
auto &it : numerator)
477 it.reinit(scalar_partitioner);
478 for (
auto &it : denominator)
479 it.reinit(scalar_partitioner);
485 const auto body = [&](
auto sentinel,
unsigned int i) {
486 using T =
decltype(sentinel);
487 unsigned int stride_size = get_stride_size<T>;
490 const unsigned int row_length = sparsity_simd_view.row_length(i);
494 boost::container::small_vector<T, 10> value_i(n_entries, T(0.));
495 for (
unsigned int k = 0; k < n_entries; ++k) {
496 value_i[k] = read_entry<T>(quantities[k], i);
499 boost::container::small_vector<T, 10> numerator_i(n_entries, T(0.));
500 boost::container::small_vector<T, 10> denominator_i(n_entries, T(0.));
502 const unsigned int *js = sparsity_simd_view.columns(i);
503 for (
unsigned int col_idx = 0; col_idx < row_length;
504 ++col_idx, js += stride_size) {
511 betaij_matrix_view.template read_entry<T>(i, col_idx);
513 for (
unsigned int k = 0; k < n_entries; ++k) {
514 const auto value_j_k = read_entry<T>(quantities[k], js);
515 numerator_i[k] += beta_ij * (value_j_k - value_i[k]);
518 std::max(std::abs(value_j_k), std::abs(value_i[k]));
521 for (
unsigned int k = 0; k < n_entries; ++k) {
522 write_entry<T>(numerator[k], numerator_i[k], i);
523 write_entry<T>(denominator[k], denominator_i[k], i);
528 cpu_simd_loop<Number>(
"mesh_adaptor_1", body, 0, n_internal, n_owned);
534 constexpr Number eps = std::numeric_limits<Number>::epsilon();
536 std::vector<Number> denominator_global_maximum(n_entries);
537 for (
unsigned int k = 0; k < n_entries; ++k) {
538 denominator_global_maximum[k] = dealii::Utilities::MPI::max(
539 denominator[k].linfty_norm(), mpi_ensemble_.ensemble_communicator());
541 denominator_global_maximum[k] =
542 std::max(denominator_global_maximum[k], eps);
545 const auto body_normalize = [&](
auto sentinel,
unsigned int i) {
546 using T =
decltype(sentinel);
549 const unsigned int row_length = sparsity_simd_view.row_length(i);
553 auto alpha_i = T(0.);
554 for (
unsigned int k = 0; k < n_entries; ++k) {
555 const auto numerator_i = read_entry<T>(numerator[k], i);
556 const auto denominator_i = read_entry<T>(denominator[k], i);
559 (Number(1.) - smoothness_local_global_ratio_) * denominator_i +
560 smoothness_local_global_ratio_ * denominator_global_maximum[k];
561 denominator = std::max(T(eps), denominator);
563 alpha_i += std::abs(numerator_i) / denominator;
566 alpha_i = std::min(alpha_i, T(smoothness_max_cutoff_));
567 alpha_i = std::max(alpha_i, T(smoothness_min_cutoff_));
568 write_entry<T>( numerator[0], alpha_i, i);
571 cpu_simd_loop<Number>(
572 "mesh_adaptor_2", body_normalize, 0, n_internal, n_owned);
578 const auto body_widen = [&](
auto sentinel,
unsigned int i) {
579 using T =
decltype(sentinel);
580 unsigned int stride_size = get_stride_size<T>;
583 const unsigned int row_length = sparsity_simd_view.row_length(i);
587 auto alpha_i = read_entry<T>(numerator[0], i);
589 const unsigned int *js = sparsity_simd_view.columns(i);
590 for (
unsigned int col_idx = 0; col_idx < row_length;
591 ++col_idx, js += stride_size) {
597 const auto alpha_j = read_entry<T>(numerator[0], js);
599 alpha_i = std::max(alpha_i, alpha_j);
602 write_entry<T>( denominator[0], alpha_i, i);
605 for (
unsigned int cycle = 0; cycle < smoothness_widen_stencil_; ++cycle) {
606 numerator[0].update_ghost_values();
607 cpu_simd_loop<Number>(
608 "mesh_adaptor_3", body_widen, 0, n_internal, n_owned);
609 numerator[0] = denominator[0];
612 numerator[0].update_ghost_values();
613 affine_constraints.distribute(numerator[0]);
619 smoothness_indicators_.reinit_with_scalar_partitioner(scalar_partitioner);
620 const auto smoothness_indicators_view = smoothness_indicators_.view();
621 smoothness_indicators_view.insert_component(numerator[0], 0);
622 smoothness_indicators_view.update_ghost_values();