418 const std::set<dealii::types::boundary_id> boundary_ids,
421 using namespace dealii;
428 const auto &triangulation = discretization.triangulation();
429 const unsigned int n_levels = triangulation.n_global_levels();
430 const unsigned int min_level =
432 MGLevelObject<IndexSet> relevant_sets(0, n_levels - 1);
435 for (
unsigned int level = 0; level < n_levels; ++level) {
436 relevant_sets[level] =
437 dealii::DoFTools::extract_locally_relevant_level_dofs(
443 std::vector<const dealii::DoFHandler<dim> *> dof_handlers = {
446 mg_constrained_dofs_.initialize(dof_handler, relevant_sets);
448 if (!boundary_ids.empty())
449 mg_constrained_dofs_.make_zero_boundary_constraints(
454 std::vector<dealii::Quadrature<1>> quadratures = {
455 discretization.quadrature_1d()[0],
456 discretization.nodal_quadrature_1d()[0]};
458 typename MatrixFree<dim, float>::AdditionalData additional_data_level;
459 additional_data_level.tasks_parallel_scheme =
460 MatrixFree<dim, float>::AdditionalData::none;
461 level_matrix_free_.resize(min_level, n_levels - 1);
463 for (
unsigned int level = min_level; level < n_levels; ++level) {
464 additional_data_level.mg_level = level;
466 AffineConstraints<float> level_constraints(relevant_sets[level],
467 relevant_sets[level]);
469 if (!boundary_ids.empty()) {
470 level_constraints.add_lines(
471 mg_constrained_dofs_.get_boundary_indices(level));
472 level_constraints.merge(
473 mg_constrained_dofs_.get_level_constraints(level));
475 level_constraints.close();
477 AffineConstraints<float> dummy;
479 std::vector<const dealii::AffineConstraints<float> *>
480 level_constraints_list = {&level_constraints, &dummy};
482 level_matrix_free_[level].reinit(discretization.mapping(),
484 level_constraints_list,
486 additional_data_level);
489 mg_transfer_.
build(dof_handler, mg_constrained_dofs_, level_matrix_free_);
491 level_laplace_matrices_.resize(level_matrix_free_.min_level(),
492 level_matrix_free_.max_level());
494 MGLevelObject<typename Preconditioner::AdditionalData> smoother_data(
495 level_matrix_free_.min_level(), level_matrix_free_.max_level());
497 for (
unsigned int level = level_matrix_free_.min_level();
498 level <= level_matrix_free_.max_level();
501 level_laplace_matrices_[level].initialize(level_matrix_free_[level]);
502 smoother_data[level].preconditioner =
503 std::make_shared<dealii::DiagonalMatrix<ScalarHostVectorFloat>>();
504 level_laplace_matrices_[level].compute_diagonal(
505 *smoother_data[level].preconditioner);
507 if (boundary_ids.empty()) {
508 smoother_data[level].eigenvalue_algorithm =
509 dealii::internal::EigenvalueAlgorithm::power_iteration;
512 if (level == level_matrix_free_.min_level()) {
513 smoother_data[level].degree = numbers::invalid_unsigned_int;
514 smoother_data[level].eig_cg_n_iterations = 500;
515 smoother_data[level].smoothing_range = 1e-3;
518 smoother_data[level].eig_cg_n_iterations =
522 smoother_data[level].max_eigenvalue =
527 relaxation_.initialize(level_laplace_matrices_, smoother_data);
534 create(coarse_solver_data_);
535 create(coarse_solver_, *coarse_solver_control_, *coarse_solver_data_);
536 create(coarse_preconditioner_);
537 level_laplace_matrices_[level_laplace_matrices_.min_level()]
538 .compute_diagonal(*coarse_preconditioner_);
539 create(coarse_grid_solver_,
541 level_laplace_matrices_[level_laplace_matrices_.min_level()],
542 *coarse_preconditioner_);
548 create(mg_matrix_, level_laplace_matrices_);
551 *coarse_grid_solver_,
555 level_laplace_matrices_.min_level(),
556 level_laplace_matrices_.max_level());
557 create(preconditioner_, dof_handler, *mg_, mg_transfer_);