Support single-level multigrid (maxLevels = 1) when extrapolation is disabled#179
Support single-level multigrid (maxLevels = 1) when extrapolation is disabled#179julianlitz wants to merge 1 commit intomainfrom
Conversation
| // ------------------------------------------------ // | ||
| // Define residual operator on all multigrid levels // | ||
| // ------------------------------------------------ // | ||
| for (int level_depth = 0; level_depth < number_of_levels_; level_depth++) { | ||
| // ---------------------- // | ||
| // Level 0 (finest Level) // | ||
| // ---------------------- // | ||
| if (level_depth == 0) { | ||
| auto start_setup_smoother = std::chrono::high_resolution_clock::now(); | ||
| switch (extrapolation_) { | ||
| case ExtrapolationType::NONE: | ||
| full_grid_smoothing_ = true; | ||
| levels_[level_depth].initializeSmoothing(domain_geometry_, density_profile_coefficients_, | ||
| DirBC_Interior_, max_omp_threads_, | ||
| stencil_distribution_method_); | ||
| break; | ||
| case ExtrapolationType::IMPLICIT_EXTRAPOLATION: | ||
| full_grid_smoothing_ = false; | ||
| levels_[level_depth].initializeExtrapolatedSmoothing(domain_geometry_, density_profile_coefficients_, | ||
| DirBC_Interior_, max_omp_threads_, | ||
| stencil_distribution_method_); | ||
| break; | ||
| case ExtrapolationType::IMPLICIT_FULL_GRID_SMOOTHING: | ||
| full_grid_smoothing_ = true; | ||
| levels_[level_depth].initializeSmoothing(domain_geometry_, density_profile_coefficients_, | ||
| DirBC_Interior_, max_omp_threads_, | ||
| stencil_distribution_method_); | ||
| break; | ||
| case ExtrapolationType::COMBINED: | ||
| full_grid_smoothing_ = true; | ||
| levels_[level_depth].initializeSmoothing(domain_geometry_, density_profile_coefficients_, | ||
| DirBC_Interior_, max_omp_threads_, | ||
| stencil_distribution_method_); | ||
| levels_[level_depth].initializeExtrapolatedSmoothing(domain_geometry_, density_profile_coefficients_, | ||
| DirBC_Interior_, max_omp_threads_, | ||
| stencil_distribution_method_); | ||
| break; | ||
| default: | ||
| full_grid_smoothing_ = false; | ||
| levels_[level_depth].initializeSmoothing(domain_geometry_, density_profile_coefficients_, | ||
| DirBC_Interior_, max_omp_threads_, | ||
| stencil_distribution_method_); | ||
| levels_[level_depth].initializeExtrapolatedSmoothing(domain_geometry_, density_profile_coefficients_, | ||
| DirBC_Interior_, max_omp_threads_, | ||
| stencil_distribution_method_); | ||
| break; | ||
| } | ||
| auto end_setup_smoother = std::chrono::high_resolution_clock::now(); | ||
| t_setup_smoother_ += std::chrono::duration<double>(end_setup_smoother - start_setup_smoother).count(); | ||
| levels_[level_depth].initializeResidual(domain_geometry_, density_profile_coefficients_, DirBC_Interior_, | ||
| max_omp_threads_, stencil_distribution_method_); | ||
| levels_[level_depth].initializeResidual(domain_geometry_, density_profile_coefficients_, DirBC_Interior_, | ||
| max_omp_threads_, stencil_distribution_method_); | ||
| } |
There was a problem hiding this comment.
Extract Residual initialization
| // ----------------------------------------- // | ||
| // Build direct solver on the coarsest level // | ||
| // ----------------------------------------- // | ||
| auto start_setup_directSolver = std::chrono::high_resolution_clock::now(); | ||
| levels_[number_of_levels_ - 1].initializeDirectSolver(domain_geometry_, density_profile_coefficients_, | ||
| DirBC_Interior_, max_omp_threads_, | ||
| stencil_distribution_method_); | ||
| auto end_setup_directSolver = std::chrono::high_resolution_clock::now(); | ||
| t_setup_directSolver_ += std::chrono::duration<double>(end_setup_directSolver - start_setup_directSolver).count(); |
There was a problem hiding this comment.
Extract DirectSolver initialization
| // ---------------------------------------------------------- // | ||
| // Build the full-grid smoother and the extrapolated smoother // | ||
| // ---------------------------------------------------------- // | ||
| auto start_setup_smoother = std::chrono::high_resolution_clock::now(); | ||
|
|
||
| bool do_full_grid_smoothing = false; | ||
| bool do_extrapolated_smoothing = false; | ||
|
|
||
| switch (extrapolation_) { | ||
|
|
||
| case ExtrapolationType::NONE: | ||
| do_full_grid_smoothing = true; | ||
| break; | ||
|
|
||
| case ExtrapolationType::IMPLICIT_EXTRAPOLATION: | ||
| do_extrapolated_smoothing = true; | ||
| break; | ||
|
|
||
| case ExtrapolationType::IMPLICIT_FULL_GRID_SMOOTHING: | ||
| do_full_grid_smoothing = true; | ||
| break; | ||
|
|
||
| case ExtrapolationType::COMBINED: | ||
| do_full_grid_smoothing = true; | ||
| do_extrapolated_smoothing = true; | ||
| break; | ||
| } | ||
|
|
||
| full_grid_smoothing_ = do_full_grid_smoothing; | ||
|
|
||
| if (number_of_levels_ > 1) { | ||
| if (do_full_grid_smoothing) { | ||
| levels_[0].initializeSmoothing(domain_geometry_, density_profile_coefficients_, DirBC_Interior_, | ||
| max_omp_threads_, stencil_distribution_method_); | ||
| } | ||
| // -------------------------- // | ||
| // Level n-1 (coarsest Level) // | ||
| // -------------------------- // | ||
| else if (level_depth == number_of_levels_ - 1) { | ||
| auto start_setup_directSolver = std::chrono::high_resolution_clock::now(); | ||
| levels_[level_depth].initializeDirectSolver(domain_geometry_, density_profile_coefficients_, | ||
| DirBC_Interior_, max_omp_threads_, | ||
| stencil_distribution_method_); | ||
| auto end_setup_directSolver = std::chrono::high_resolution_clock::now(); | ||
| t_setup_directSolver_ += | ||
| std::chrono::duration<double>(end_setup_directSolver - start_setup_directSolver).count(); | ||
| levels_[level_depth].initializeResidual(domain_geometry_, density_profile_coefficients_, DirBC_Interior_, | ||
| max_omp_threads_, stencil_distribution_method_); | ||
| if (do_extrapolated_smoothing) { | ||
| levels_[0].initializeExtrapolatedSmoothing(domain_geometry_, density_profile_coefficients_, DirBC_Interior_, | ||
| max_omp_threads_, stencil_distribution_method_); | ||
| } | ||
| // ------------------- // | ||
| // Intermediate levels // | ||
| // ------------------- // | ||
| else { | ||
| auto start_setup_smoother = std::chrono::high_resolution_clock::now(); | ||
| for (int level_depth = 1; level_depth < number_of_levels_ - 1; level_depth++) { | ||
| levels_[level_depth].initializeSmoothing(domain_geometry_, density_profile_coefficients_, DirBC_Interior_, | ||
| max_omp_threads_, stencil_distribution_method_); | ||
| auto end_setup_smoother = std::chrono::high_resolution_clock::now(); | ||
| t_setup_smoother_ += std::chrono::duration<double>(end_setup_smoother - start_setup_smoother).count(); | ||
| levels_[level_depth].initializeResidual(domain_geometry_, density_profile_coefficients_, DirBC_Interior_, | ||
| max_omp_threads_, stencil_distribution_method_); | ||
| } | ||
| } |
There was a problem hiding this comment.
Extract Smoother initialization. Simpler to read.
| void IGMGPolar::multigrid_F_Cycle(int level_depth, Vector<double> solution, ConstVector<double> rhs, | ||
| Vector<double> residual) | ||
| { | ||
| assert(0 <= level_depth && level_depth < number_of_levels_ - 1); | ||
| assert(0 <= level_depth && level_depth < number_of_levels_); | ||
|
|
||
| std::chrono::high_resolution_clock::time_point start_MGC; | ||
| if (level_depth == 0) { | ||
| start_MGC = std::chrono::high_resolution_clock::now(); | ||
| } | ||
|
|
||
| Level& level = levels_[level_depth]; | ||
| Level& next_level = levels_[level_depth + 1]; | ||
| /* ------------------------ */ | ||
| /* Solve A * solution = rhs */ | ||
| /* ------------------------ */ | ||
| if (level_depth == number_of_levels_ - 1) { | ||
| /* ------------------------------ */ | ||
| /* Coarsest level: solve directly */ | ||
| /* ------------------------------ */ |
There was a problem hiding this comment.
We can now also solve on level_depth = 0 directly, which was not possible before.
For this I moved some code sections around.
|
|
||
| // Minimum level for Multigrid | ||
| const int multigridMinLevel = 2; | ||
| const int multigridMinLevel = (extrapolation_ == ExtrapolationType::NONE) ? 1 : 2; |
There was a problem hiding this comment.
With extrapolation=None, we are now able to choose maxLevels=1.
| throw std::runtime_error( | ||
| "Extrapolation Error: Finest PolarGrid does not originate from a single uniform refinement."); |
There was a problem hiding this comment.
Abort immediately may not be a good idea. Better replace by a warning?
| int level_depth = 0; | ||
| auto finest_levelCache = std::make_unique<LevelCache>(*finest_grid, density_profile_coefficients_, domain_geometry_, | ||
| cache_density_profile_coefficients_, cache_domain_geometry_); | ||
| levels_.emplace_back(level_depth, std::move(finest_grid), std::move(finest_levelCache), extrapolation_, FMG_); |
There was a problem hiding this comment.
Avoid variable shadowing in later loops.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #179 +/- ##
==========================================
+ Coverage 95.11% 95.25% +0.13%
==========================================
Files 95 95
Lines 9458 9460 +2
==========================================
+ Hits 8996 9011 +15
+ Misses 462 449 -13 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Merge Request - GuideLine Checklist
Guideline to check code before resolve WIP and approval, respectively.
As many checkboxes as possible should be ticked.
Checks by code author:
Always to be checked:
If functions were changed or functionality was added:
If new functionality was added:
If new third party software is used:
If new mathematical methods or epidemiological terms are used:
Checks by code reviewer(s):