Skip to content

Comments

Support single-level multigrid (maxLevels = 1) when extrapolation is disabled#179

Open
julianlitz wants to merge 1 commit intomainfrom
litz_allow_no_mg
Open

Support single-level multigrid (maxLevels = 1) when extrapolation is disabled#179
julianlitz wants to merge 1 commit intomainfrom
litz_allow_no_mg

Conversation

@julianlitz
Copy link
Collaborator

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:

  • There is at least one issue associated with the pull request.
  • New code adheres with the coding guidelines
  • No large data files have been added to the repository. Maximum size for files should be of the order of KB not MB. In particular avoid adding of pdf, word, or other files that cannot be change-tracked correctly by git.

If functions were changed or functionality was added:

  • Tests for new functionality has been added
  • A local test was succesful

If new functionality was added:

  • There is appropriate documentation of your work. (use doxygen style comments)

If new third party software is used:

  • Did you pay attention to its license? Please remember to add it to the wiki after successful merging.

If new mathematical methods or epidemiological terms are used:

  • Are new methods referenced? Did you provide further documentation?

Checks by code reviewer(s):

  • Is the code clean of development artifacts e.g., unnecessary comments, prints, ...
  • The ticket goals for each associated issue are reached or problems are clearly addressed (i.e., a new issue was introduced).
  • There are appropriate unit tests and they pass.
  • The git history is clean and linearized for the merge request. All reviewers should squash commits and write a simple and meaningful commit message.
  • Coverage report for new code is acceptable.
  • No large data files have been added to the repository. Maximum size for files should be of the order of KB not MB. In particular avoid adding of pdf, word, or other files that cannot be change-tracked correctly by git.

Comment on lines +82 to +88
// ------------------------------------------------ //
// 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_);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract Residual initialization

Comment on lines +90 to +98
// ----------------------------------------- //
// 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();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract DirectSolver initialization

Comment on lines +100 to 143
// ---------------------------------------------------------- //
// 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_);
}
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract Smoother initialization. Simpler to read.

Comment on lines +3 to +19
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 */
/* ------------------------------ */
Copy link
Collaborator Author

@julianlitz julianlitz Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Collaborator Author

@julianlitz julianlitz Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With extrapolation=None, we are now able to choose maxLevels=1.

Comment on lines -45 to -46
throw std::runtime_error(
"Extrapolation Error: Finest PolarGrid does not originate from a single uniform refinement.");
Copy link
Collaborator Author

@julianlitz julianlitz Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abort immediately may not be a good idea. Better replace by a warning?

Comment on lines -57 to -60
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_);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid variable shadowing in later loops.

@codecov
Copy link

codecov bot commented Feb 17, 2026

Codecov Report

❌ Patch coverage is 94.19355% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.25%. Comparing base (8ba043e) to head (ae29cb9).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...ultigridMethods/extrapolated_multigrid_W_Cycle.cpp 11.11% 8 Missing ⚠️
include/GMGPolar/setup.h 97.22% 1 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant