422 const std::set<dealii::types::boundary_id> boundary_ids,
425 using namespace dealii;
432 const auto &triangulation = discretization.triangulation();
433 const unsigned int n_levels = triangulation.n_global_levels();
434 const unsigned int min_level =
436 MGLevelObject<IndexSet> relevant_sets(0, n_levels - 1);
439 for (
unsigned int level = 0; level < n_levels; ++level) {
440 relevant_sets[level] =
441 dealii::DoFTools::extract_locally_relevant_level_dofs(
447 std::vector<const dealii::DoFHandler<dim> *> dof_handlers = {
450 mg_constrained_dofs_.initialize(dof_handler, relevant_sets);
452 if (!boundary_ids.empty())
453 mg_constrained_dofs_.make_zero_boundary_constraints(
458 std::vector<dealii::Quadrature<1>> quadratures = {
459 discretization.quadrature_1d()[0],
460 discretization.nodal_quadrature_1d()[0]};
462 typename MatrixFree<dim, float>::AdditionalData additional_data_level;
463 additional_data_level.tasks_parallel_scheme =
464 MatrixFree<dim, float>::AdditionalData::none;
465 level_matrix_free_.resize(min_level, n_levels - 1);
467 for (
unsigned int level = min_level; level < n_levels; ++level) {
468 additional_data_level.mg_level = level;
470 AffineConstraints<float> level_constraints(relevant_sets[level],
471 relevant_sets[level]);
473 if (!boundary_ids.empty()) {
474 level_constraints.add_lines(
475 mg_constrained_dofs_.get_boundary_indices(level));
476 level_constraints.merge(
477 mg_constrained_dofs_.get_level_constraints(level));
479 level_constraints.close();
481 AffineConstraints<float> dummy;
483 std::vector<const dealii::AffineConstraints<float> *>
484 level_constraints_list = {&level_constraints, &dummy};
486 level_matrix_free_[level].reinit(discretization.mapping(),
488 level_constraints_list,
490 additional_data_level);
493 mg_transfer_.
build(dof_handler, mg_constrained_dofs_, level_matrix_free_);
495 level_laplace_matrices_.resize(level_matrix_free_.min_level(),
496 level_matrix_free_.max_level());
498 MGLevelObject<typename Preconditioner::AdditionalData> smoother_data(
499 level_matrix_free_.min_level(), level_matrix_free_.max_level());
501 for (
unsigned int level = level_matrix_free_.min_level();
502 level <= level_matrix_free_.max_level();
505 level_laplace_matrices_[level].initialize(level_matrix_free_[level]);
506 smoother_data[level].preconditioner =
507 std::make_shared<dealii::DiagonalMatrix<ScalarHostVector<float>>>();
508 level_laplace_matrices_[level].compute_diagonal(
509 *smoother_data[level].preconditioner);
511 if (boundary_ids.empty()) {
512 smoother_data[level].eigenvalue_algorithm =
513 dealii::internal::EigenvalueAlgorithm::power_iteration;
516 if (level == level_matrix_free_.min_level()) {
517 smoother_data[level].degree = numbers::invalid_unsigned_int;
518 smoother_data[level].eig_cg_n_iterations = 500;
519 smoother_data[level].smoothing_range = 1e-3;
522 smoother_data[level].eig_cg_n_iterations =
526 smoother_data[level].max_eigenvalue =
531 relaxation_.initialize(level_laplace_matrices_, smoother_data);
538 create(coarse_solver_data_);
539 create(coarse_solver_, *coarse_solver_control_, *coarse_solver_data_);
540 create(coarse_preconditioner_);
541 level_laplace_matrices_[level_laplace_matrices_.min_level()]
542 .compute_diagonal(*coarse_preconditioner_);
543 create(coarse_grid_solver_,
545 level_laplace_matrices_[level_laplace_matrices_.min_level()],
546 *coarse_preconditioner_);
552 create(mg_matrix_, level_laplace_matrices_);
555 *coarse_grid_solver_,
559 level_laplace_matrices_.min_level(),
560 level_laplace_matrices_.max_level());
561 create(preconditioner_, dof_handler, *mg_, mg_transfer_);