421 const std::set<dealii::types::boundary_id> boundary_ids,
424 using namespace dealii;
431 const auto &triangulation = discretization.triangulation();
432 const unsigned int n_levels = triangulation.n_global_levels();
433 const unsigned int min_level =
435 MGLevelObject<IndexSet> relevant_sets(0, n_levels - 1);
438 for (
unsigned int level = 0; level < n_levels; ++level) {
439 relevant_sets[level] =
440 dealii::DoFTools::extract_locally_relevant_level_dofs(
446 std::vector<const dealii::DoFHandler<dim> *> dof_handlers = {
449 mg_constrained_dofs_.initialize(dof_handler, relevant_sets);
451 if (!boundary_ids.empty())
452 mg_constrained_dofs_.make_zero_boundary_constraints(
457 std::vector<dealii::Quadrature<1>> quadratures = {
458 discretization.quadrature_1d()[0],
459 discretization.nodal_quadrature_1d()[0]};
461 typename MatrixFree<dim, float>::AdditionalData additional_data_level;
462 additional_data_level.tasks_parallel_scheme =
463 MatrixFree<dim, float>::AdditionalData::none;
464 level_matrix_free_.resize(min_level, n_levels - 1);
466 for (
unsigned int level = min_level; level < n_levels; ++level) {
467 additional_data_level.mg_level = level;
469 AffineConstraints<float> level_constraints(relevant_sets[level],
470 relevant_sets[level]);
472 if (!boundary_ids.empty()) {
473 level_constraints.add_lines(
474 mg_constrained_dofs_.get_boundary_indices(level));
475 level_constraints.merge(
476 mg_constrained_dofs_.get_level_constraints(level));
478 level_constraints.close();
480 AffineConstraints<float> dummy;
482 std::vector<const dealii::AffineConstraints<float> *>
483 level_constraints_list = {&level_constraints, &dummy};
485 level_matrix_free_[level].reinit(discretization.mapping(),
487 level_constraints_list,
489 additional_data_level);
492 mg_transfer_.
build(dof_handler, mg_constrained_dofs_, level_matrix_free_);
494 level_laplace_matrices_.resize(level_matrix_free_.min_level(),
495 level_matrix_free_.max_level());
497 MGLevelObject<typename Preconditioner::AdditionalData> smoother_data(
498 level_matrix_free_.min_level(), level_matrix_free_.max_level());
500 for (
unsigned int level = level_matrix_free_.min_level();
501 level <= level_matrix_free_.max_level();
504 level_laplace_matrices_[level].initialize(level_matrix_free_[level]);
505 smoother_data[level].preconditioner =
506 std::make_shared<dealii::DiagonalMatrix<ScalarHostVectorFloat>>();
507 level_laplace_matrices_[level].compute_diagonal(
508 *smoother_data[level].preconditioner);
510 if (boundary_ids.empty()) {
511 smoother_data[level].eigenvalue_algorithm =
512 dealii::internal::EigenvalueAlgorithm::power_iteration;
515 if (level == level_matrix_free_.min_level()) {
516 smoother_data[level].degree = numbers::invalid_unsigned_int;
517 smoother_data[level].eig_cg_n_iterations = 500;
518 smoother_data[level].smoothing_range = 1e-3;
521 smoother_data[level].eig_cg_n_iterations =
525 smoother_data[level].max_eigenvalue =
530 relaxation_.initialize(level_laplace_matrices_, smoother_data);
537 create(coarse_solver_data_);
538 create(coarse_solver_, *coarse_solver_control_, *coarse_solver_data_);
539 create(coarse_preconditioner_);
540 level_laplace_matrices_[level_laplace_matrices_.min_level()]
541 .compute_diagonal(*coarse_preconditioner_);
542 create(coarse_grid_solver_,
544 level_laplace_matrices_[level_laplace_matrices_.min_level()],
545 *coarse_preconditioner_);
551 create(mg_matrix_, level_laplace_matrices_);
554 *coarse_grid_solver_,
558 level_laplace_matrices_.min_level(),
559 level_laplace_matrices_.max_level());
560 create(preconditioner_, dof_handler, *mg_, mg_transfer_);