diff --git a/include/GMGPolar/MultigridMethods/extrapolated_multigrid_F_Cycle.h b/include/GMGPolar/MultigridMethods/extrapolated_multigrid_F_Cycle.h index 403dc95b..2e249315 100644 --- a/include/GMGPolar/MultigridMethods/extrapolated_multigrid_F_Cycle.h +++ b/include/GMGPolar/MultigridMethods/extrapolated_multigrid_F_Cycle.h @@ -1,7 +1,7 @@ template void GMGPolar::extrapolated_multigrid_F_Cycle(int level_depth, Vector solution, - Vector rhs, + ConstVector rhs, Vector residual) { assert(0 <= level_depth && level_depth < number_of_levels_ - 1); @@ -94,8 +94,14 @@ void GMGPolar::extrapolated_multigri assign(next_level.residual(), 0.0); /* Step 3: Solve for the error by recursively calling the multigrid cycle. */ - multigrid_F_Cycle(level_depth + 1, next_level.residual(), next_level.error_correction(), next_level.solution()); - multigrid_V_Cycle(level_depth + 1, next_level.residual(), next_level.error_correction(), next_level.solution()); + multigrid_F_Cycle(level_depth + 1, + next_level.residual(), // error (solution) + next_level.error_correction(), // coarse residual (rhs) + next_level.solution()); // workspace + multigrid_V_Cycle(level_depth + 1, + next_level.residual(), // error (solution) + next_level.error_correction(), // coarse residual (rhs) + next_level.solution()); // workspace } /* Interpolate the correction */ diff --git a/include/GMGPolar/MultigridMethods/extrapolated_multigrid_V_Cycle.h b/include/GMGPolar/MultigridMethods/extrapolated_multigrid_V_Cycle.h index 2462f398..1877c621 100644 --- a/include/GMGPolar/MultigridMethods/extrapolated_multigrid_V_Cycle.h +++ b/include/GMGPolar/MultigridMethods/extrapolated_multigrid_V_Cycle.h @@ -1,7 +1,7 @@ template void GMGPolar::extrapolated_multigrid_V_Cycle(int level_depth, Vector solution, - Vector rhs, + ConstVector rhs, Vector residual) { assert(0 <= level_depth && level_depth < number_of_levels_ - 1); @@ -94,7 +94,10 @@ void GMGPolar::extrapolated_multigri assign(next_level.residual(), 0.0); /* Step 3: Solve for the error by recursively calling the multigrid cycle. */ - multigrid_V_Cycle(level_depth + 1, next_level.residual(), next_level.error_correction(), next_level.solution()); + multigrid_V_Cycle(level_depth + 1, + next_level.residual(), // error (solution) + next_level.error_correction(), // coarse residual (rhs) + next_level.solution()); // workspace } /* Interpolate the correction */ diff --git a/include/GMGPolar/MultigridMethods/extrapolated_multigrid_W_Cycle.h b/include/GMGPolar/MultigridMethods/extrapolated_multigrid_W_Cycle.h index 55dc257e..173ed826 100644 --- a/include/GMGPolar/MultigridMethods/extrapolated_multigrid_W_Cycle.h +++ b/include/GMGPolar/MultigridMethods/extrapolated_multigrid_W_Cycle.h @@ -1,7 +1,7 @@ template void GMGPolar::extrapolated_multigrid_W_Cycle(int level_depth, Vector solution, - Vector rhs, + ConstVector rhs, Vector residual) { assert(0 <= level_depth && level_depth < number_of_levels_ - 1); @@ -94,8 +94,14 @@ void GMGPolar::extrapolated_multigri assign(next_level.residual(), 0.0); /* Step 3: Solve for the error by recursively calling the multigrid cycle. */ - multigrid_W_Cycle(level_depth + 1, next_level.residual(), next_level.error_correction(), next_level.solution()); - multigrid_W_Cycle(level_depth + 1, next_level.residual(), next_level.error_correction(), next_level.solution()); + multigrid_W_Cycle(level_depth + 1, + next_level.residual(), // error (solution) + next_level.error_correction(), // coarse residual (rhs) + next_level.solution()); // workspace + multigrid_W_Cycle(level_depth + 1, + next_level.residual(), // error (solution) + next_level.error_correction(), // coarse residual (rhs) + next_level.solution()); // workspace } /* Interpolate the correction */ diff --git a/include/GMGPolar/MultigridMethods/multigrid_F_Cycle.h b/include/GMGPolar/MultigridMethods/multigrid_F_Cycle.h index 913bd972..a2eaa57b 100644 --- a/include/GMGPolar/MultigridMethods/multigrid_F_Cycle.h +++ b/include/GMGPolar/MultigridMethods/multigrid_F_Cycle.h @@ -1,63 +1,71 @@ +#pragma once + template void GMGPolar::multigrid_F_Cycle(int level_depth, Vector solution, - Vector rhs, + ConstVector rhs, Vector 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]; - - auto start_MGC_preSmoothing = std::chrono::high_resolution_clock::now(); - - /* ------------ */ - /* Presmoothing */ - for (int i = 0; i < pre_smoothing_steps_; i++) { - level.smoothing(solution, rhs, residual); - } - - auto end_MGC_preSmoothing = std::chrono::high_resolution_clock::now(); - t_avg_MGC_preSmoothing_ += std::chrono::duration(end_MGC_preSmoothing - start_MGC_preSmoothing).count(); - - /* ---------------------- */ - /* Coarse grid correction */ - /* ---------------------- */ - - auto start_MGC_residual = std::chrono::high_resolution_clock::now(); - - /* Compute the residual */ - level.computeResidual(residual, rhs, solution); + /* ------------------------ */ + /* Solve A * solution = rhs */ + /* ------------------------ */ + if (level_depth == number_of_levels_ - 1) { + /* ------------------------------ */ + /* Coarsest level: solve directly */ + /* ------------------------------ */ + Level& level = levels_[level_depth]; - auto end_MGC_residual = std::chrono::high_resolution_clock::now(); - t_avg_MGC_residual_ += std::chrono::duration(end_MGC_residual - start_MGC_residual).count(); + /* Step 1: Copy rhs in solution */ + Kokkos::deep_copy(solution, rhs); - /* -------------------------- */ - /* Solve A * error = residual */ - if (level_depth + 1 == number_of_levels_ - 1) { - /* --------------------- */ - /* Using a direct solver */ - /* --------------------- */ - - /* Step 1: Restrict the residual */ - restriction(level_depth, next_level.residual(), residual); - - /* Step 2: Solve for the error in place */ + /* Step 2: Solve for the solution in place */ auto start_MGC_directSolver = std::chrono::high_resolution_clock::now(); - next_level.directSolveInPlace(next_level.residual()); + level.directSolveInPlace(solution); auto end_MGC_directSolver = std::chrono::high_resolution_clock::now(); t_avg_MGC_directSolver_ += std::chrono::duration(end_MGC_directSolver - start_MGC_directSolver).count(); } else { - /* ------------------------------------------ */ + /* ------------------------------------------------------- */ + /* Multigrid V-cycle on current level: */ + /* presmoothing, coarse-grid correction, and postsmoothing */ + /* ------------------------------------------------------- */ + Level& level = levels_[level_depth]; + Level& next_level = levels_[level_depth + 1]; + + auto start_MGC_preSmoothing = std::chrono::high_resolution_clock::now(); + + /* ------------ */ + /* Presmoothing */ + for (int i = 0; i < pre_smoothing_steps_; i++) { + level.smoothing(solution, rhs, residual); + } + + auto end_MGC_preSmoothing = std::chrono::high_resolution_clock::now(); + t_avg_MGC_preSmoothing_ += std::chrono::duration(end_MGC_preSmoothing - start_MGC_preSmoothing).count(); + + /* ----------------------------- */ + /* Compute fine-grid residual */ + /* residual = rhs - A * solution */ + /* ----------------------------- */ + auto start_MGC_residual = std::chrono::high_resolution_clock::now(); + + level.computeResidual(residual, rhs, solution); + + auto end_MGC_residual = std::chrono::high_resolution_clock::now(); + t_avg_MGC_residual_ += std::chrono::duration(end_MGC_residual - start_MGC_residual).count(); + + /* -------------------------- */ + /* Solve A * error = residual */ + /* -------------------------- */ /* By recursively calling the multigrid cycle */ - /* ------------------------------------------ */ /* Step 1: Restrict the residual. */ restriction(level_depth, next_level.error_correction(), residual); @@ -66,29 +74,36 @@ void GMGPolar::multigrid_F_Cycle(int assign(next_level.residual(), 0.0); /* Step 3: Solve for the error by recursively calling the multigrid cycle. */ - multigrid_F_Cycle(level_depth + 1, next_level.residual(), next_level.error_correction(), next_level.solution()); - multigrid_V_Cycle(level_depth + 1, next_level.residual(), next_level.error_correction(), next_level.solution()); - } - - /* Interpolate the correction */ - prolongation(level_depth + 1, residual, next_level.residual()); - - /* Compute the corrected approximation: u = u + error */ - add(solution, ConstVector(residual)); - - auto start_MGC_postSmoothing = std::chrono::high_resolution_clock::now(); - - /* ------------- */ - /* Postsmoothing */ - for (int i = 0; i < post_smoothing_steps_; i++) { - level.smoothing(solution, rhs, residual); + multigrid_F_Cycle(level_depth + 1, + next_level.residual(), // error (solution) + next_level.error_correction(), // coarse residual (rhs) + next_level.solution()); // workspace + multigrid_V_Cycle(level_depth + 1, + next_level.residual(), // error (solution) + next_level.error_correction(), // coarse residual (rhs) + next_level.solution()); // workspace + + /* Interpolate the correction */ + prolongation(level_depth + 1, residual, next_level.residual()); + + /* Compute the corrected approximation: u = u + error */ + add(solution, ConstVector(residual)); + + auto start_MGC_postSmoothing = std::chrono::high_resolution_clock::now(); + + /* ------------- */ + /* Postsmoothing */ + for (int i = 0; i < post_smoothing_steps_; i++) { + level.smoothing(solution, rhs, residual); + } + + auto end_MGC_postSmoothing = std::chrono::high_resolution_clock::now(); + t_avg_MGC_postSmoothing_ += + std::chrono::duration(end_MGC_postSmoothing - start_MGC_postSmoothing).count(); } - auto end_MGC_postSmoothing = std::chrono::high_resolution_clock::now(); - t_avg_MGC_postSmoothing_ += std::chrono::duration(end_MGC_postSmoothing - start_MGC_postSmoothing).count(); - if (level_depth == 0) { auto end_MGC = std::chrono::high_resolution_clock::now(); t_avg_MGC_total_ += std::chrono::duration(end_MGC - start_MGC).count(); } -} +} \ No newline at end of file diff --git a/include/GMGPolar/MultigridMethods/multigrid_V_Cycle.h b/include/GMGPolar/MultigridMethods/multigrid_V_Cycle.h index 931ec0c7..596928b3 100644 --- a/include/GMGPolar/MultigridMethods/multigrid_V_Cycle.h +++ b/include/GMGPolar/MultigridMethods/multigrid_V_Cycle.h @@ -1,63 +1,71 @@ +#pragma once + template void GMGPolar::multigrid_V_Cycle(int level_depth, Vector solution, - Vector rhs, + ConstVector rhs, Vector 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]; - - auto start_MGC_preSmoothing = std::chrono::high_resolution_clock::now(); - - /* ------------ */ - /* Presmoothing */ - for (int i = 0; i < pre_smoothing_steps_; i++) { - level.smoothing(solution, rhs, residual); - } - - auto end_MGC_preSmoothing = std::chrono::high_resolution_clock::now(); - t_avg_MGC_preSmoothing_ += std::chrono::duration(end_MGC_preSmoothing - start_MGC_preSmoothing).count(); - - /* ---------------------- */ - /* Coarse grid correction */ - /* ---------------------- */ - - auto start_MGC_residual = std::chrono::high_resolution_clock::now(); + /* ------------------------ */ + /* Solve A * solution = rhs */ + /* ------------------------ */ + if (level_depth == number_of_levels_ - 1) { + /* ------------------------------ */ + /* Coarsest level: solve directly */ + /* ------------------------------ */ + Level& level = levels_[level_depth]; - /* Compute the residual */ - level.computeResidual(residual, rhs, solution); + /* Step 1: Copy rhs in solution */ + Kokkos::deep_copy(solution, rhs); - auto end_MGC_residual = std::chrono::high_resolution_clock::now(); - t_avg_MGC_residual_ += std::chrono::duration(end_MGC_residual - start_MGC_residual).count(); - - /* -------------------------- */ - /* Solve A * error = residual */ - if (level_depth + 1 == number_of_levels_ - 1) { - /* --------------------- */ - /* Using a direct solver */ - /* --------------------- */ - - /* Step 1: Restrict the residual */ - restriction(level_depth, next_level.residual(), residual); - - /* Step 2: Solve for the error in place */ + /* Step 2: Solve for the solution in place */ auto start_MGC_directSolver = std::chrono::high_resolution_clock::now(); - next_level.directSolveInPlace(next_level.residual()); + level.directSolveInPlace(solution); auto end_MGC_directSolver = std::chrono::high_resolution_clock::now(); t_avg_MGC_directSolver_ += std::chrono::duration(end_MGC_directSolver - start_MGC_directSolver).count(); } else { - /* ------------------------------------------ */ + /* ------------------------------------------------------- */ + /* Multigrid V-cycle on current level: */ + /* presmoothing, coarse-grid correction, and postsmoothing */ + /* ------------------------------------------------------- */ + Level& level = levels_[level_depth]; + Level& next_level = levels_[level_depth + 1]; + + auto start_MGC_preSmoothing = std::chrono::high_resolution_clock::now(); + + /* ------------ */ + /* Presmoothing */ + for (int i = 0; i < pre_smoothing_steps_; i++) { + level.smoothing(solution, rhs, residual); + } + + auto end_MGC_preSmoothing = std::chrono::high_resolution_clock::now(); + t_avg_MGC_preSmoothing_ += std::chrono::duration(end_MGC_preSmoothing - start_MGC_preSmoothing).count(); + + /* ----------------------------- */ + /* Compute fine-grid residual */ + /* residual = rhs - A * solution */ + /* ----------------------------- */ + auto start_MGC_residual = std::chrono::high_resolution_clock::now(); + + level.computeResidual(residual, rhs, solution); + + auto end_MGC_residual = std::chrono::high_resolution_clock::now(); + t_avg_MGC_residual_ += std::chrono::duration(end_MGC_residual - start_MGC_residual).count(); + + /* -------------------------- */ + /* Solve A * error = residual */ + /* -------------------------- */ /* By recursively calling the multigrid cycle */ - /* ------------------------------------------ */ /* Step 1: Restrict the residual. */ restriction(level_depth, next_level.error_correction(), residual); @@ -66,28 +74,32 @@ void GMGPolar::multigrid_V_Cycle(int assign(next_level.residual(), 0.0); /* Step 3: Solve for the error by recursively calling the multigrid cycle. */ - multigrid_V_Cycle(level_depth + 1, next_level.residual(), next_level.error_correction(), next_level.solution()); - } + multigrid_V_Cycle(level_depth + 1, + next_level.residual(), // error (solution) + next_level.error_correction(), // coarse residual (rhs) + next_level.solution()); // workspace - /* Interpolate the correction */ - prolongation(level_depth + 1, residual, next_level.residual()); + /* Interpolate the correction */ + prolongation(level_depth + 1, residual, next_level.residual()); - /* Compute the corrected approximation: u = u + error */ - add(solution, ConstVector(residual)); + /* Compute the corrected approximation: u = u + error */ + add(solution, ConstVector(residual)); - auto start_MGC_postSmoothing = std::chrono::high_resolution_clock::now(); + auto start_MGC_postSmoothing = std::chrono::high_resolution_clock::now(); - /* ------------- */ - /* Postsmoothing */ - for (int i = 0; i < post_smoothing_steps_; i++) { - level.smoothing(solution, rhs, residual); - } + /* ------------- */ + /* Postsmoothing */ + for (int i = 0; i < post_smoothing_steps_; i++) { + level.smoothing(solution, rhs, residual); + } - auto end_MGC_postSmoothing = std::chrono::high_resolution_clock::now(); - t_avg_MGC_postSmoothing_ += std::chrono::duration(end_MGC_postSmoothing - start_MGC_postSmoothing).count(); + auto end_MGC_postSmoothing = std::chrono::high_resolution_clock::now(); + t_avg_MGC_postSmoothing_ += + std::chrono::duration(end_MGC_postSmoothing - start_MGC_postSmoothing).count(); + } if (level_depth == 0) { auto end_MGC = std::chrono::high_resolution_clock::now(); t_avg_MGC_total_ += std::chrono::duration(end_MGC - start_MGC).count(); } -} +} \ No newline at end of file diff --git a/include/GMGPolar/MultigridMethods/multigrid_W_Cycle.h b/include/GMGPolar/MultigridMethods/multigrid_W_Cycle.h index a2d1c522..1c52d56d 100644 --- a/include/GMGPolar/MultigridMethods/multigrid_W_Cycle.h +++ b/include/GMGPolar/MultigridMethods/multigrid_W_Cycle.h @@ -1,63 +1,71 @@ +#pragma once + template void GMGPolar::multigrid_W_Cycle(int level_depth, Vector solution, - Vector rhs, + ConstVector rhs, Vector 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]; - - auto start_MGC_preSmoothing = std::chrono::high_resolution_clock::now(); - - /* ------------ */ - /* Presmoothing */ - for (int i = 0; i < pre_smoothing_steps_; i++) { - level.smoothing(solution, rhs, residual); - } - - auto end_MGC_preSmoothing = std::chrono::high_resolution_clock::now(); - t_avg_MGC_preSmoothing_ += std::chrono::duration(end_MGC_preSmoothing - start_MGC_preSmoothing).count(); - - /* ---------------------- */ - /* Coarse grid correction */ - /* ---------------------- */ - - auto start_MGC_residual = std::chrono::high_resolution_clock::now(); - - /* Compute the residual */ - level.computeResidual(residual, rhs, solution); + /* ------------------------ */ + /* Solve A * solution = rhs */ + /* ------------------------ */ + if (level_depth == number_of_levels_ - 1) { + /* ------------------------------ */ + /* Coarsest level: solve directly */ + /* ------------------------------ */ + Level& level = levels_[level_depth]; - auto end_MGC_residual = std::chrono::high_resolution_clock::now(); - t_avg_MGC_residual_ += std::chrono::duration(end_MGC_residual - start_MGC_residual).count(); + /* Step 1: Copy rhs in solution */ + Kokkos::deep_copy(solution, rhs); - /* -------------------------- */ - /* Solve A * error = residual */ - if (level_depth + 1 == number_of_levels_ - 1) { - /* --------------------- */ - /* Using a direct solver */ - /* --------------------- */ - - /* Step 1: Restrict the residual */ - restriction(level_depth, next_level.residual(), residual); - - /* Step 2: Solve for the error in place */ + /* Step 2: Solve for the solution in place */ auto start_MGC_directSolver = std::chrono::high_resolution_clock::now(); - next_level.directSolveInPlace(next_level.residual()); + level.directSolveInPlace(solution); auto end_MGC_directSolver = std::chrono::high_resolution_clock::now(); t_avg_MGC_directSolver_ += std::chrono::duration(end_MGC_directSolver - start_MGC_directSolver).count(); } else { - /* ------------------------------------------ */ + /* ------------------------------------------------------- */ + /* Multigrid V-cycle on current level: */ + /* presmoothing, coarse-grid correction, and postsmoothing */ + /* ------------------------------------------------------- */ + Level& level = levels_[level_depth]; + Level& next_level = levels_[level_depth + 1]; + + auto start_MGC_preSmoothing = std::chrono::high_resolution_clock::now(); + + /* ------------ */ + /* Presmoothing */ + for (int i = 0; i < pre_smoothing_steps_; i++) { + level.smoothing(solution, rhs, residual); + } + + auto end_MGC_preSmoothing = std::chrono::high_resolution_clock::now(); + t_avg_MGC_preSmoothing_ += std::chrono::duration(end_MGC_preSmoothing - start_MGC_preSmoothing).count(); + + /* ----------------------------- */ + /* Compute fine-grid residual */ + /* residual = rhs - A * solution */ + /* ----------------------------- */ + auto start_MGC_residual = std::chrono::high_resolution_clock::now(); + + level.computeResidual(residual, rhs, solution); + + auto end_MGC_residual = std::chrono::high_resolution_clock::now(); + t_avg_MGC_residual_ += std::chrono::duration(end_MGC_residual - start_MGC_residual).count(); + + /* -------------------------- */ + /* Solve A * error = residual */ + /* -------------------------- */ /* By recursively calling the multigrid cycle */ - /* ------------------------------------------ */ /* Step 1: Restrict the residual. */ restriction(level_depth, next_level.error_correction(), residual); @@ -66,29 +74,36 @@ void GMGPolar::multigrid_W_Cycle(int assign(next_level.residual(), 0.0); /* Step 3: Solve for the error by recursively calling the multigrid cycle. */ - multigrid_W_Cycle(level_depth + 1, next_level.residual(), next_level.error_correction(), next_level.solution()); - multigrid_W_Cycle(level_depth + 1, next_level.residual(), next_level.error_correction(), next_level.solution()); - } - - /* Interpolate the correction */ - prolongation(level_depth + 1, residual, next_level.residual()); - - /* Compute the corrected approximation: u = u + error */ - add(solution, ConstVector(residual)); - - auto start_MGC_postSmoothing = std::chrono::high_resolution_clock::now(); - - /* ------------- */ - /* Postsmoothing */ - for (int i = 0; i < post_smoothing_steps_; i++) { - level.smoothing(solution, rhs, residual); + multigrid_W_Cycle(level_depth + 1, + next_level.residual(), // error (solution) + next_level.error_correction(), // coarse residual (rhs) + next_level.solution()); // workspace + multigrid_W_Cycle(level_depth + 1, + next_level.residual(), // error (solution) + next_level.error_correction(), // coarse residual (rhs) + next_level.solution()); // workspace + + /* Interpolate the correction */ + prolongation(level_depth + 1, residual, next_level.residual()); + + /* Compute the corrected approximation: u = u + error */ + add(solution, ConstVector(residual)); + + auto start_MGC_postSmoothing = std::chrono::high_resolution_clock::now(); + + /* ------------- */ + /* Postsmoothing */ + for (int i = 0; i < post_smoothing_steps_; i++) { + level.smoothing(solution, rhs, residual); + } + + auto end_MGC_postSmoothing = std::chrono::high_resolution_clock::now(); + t_avg_MGC_postSmoothing_ += + std::chrono::duration(end_MGC_postSmoothing - start_MGC_postSmoothing).count(); } - auto end_MGC_postSmoothing = std::chrono::high_resolution_clock::now(); - t_avg_MGC_postSmoothing_ += std::chrono::duration(end_MGC_postSmoothing - start_MGC_postSmoothing).count(); - if (level_depth == 0) { auto end_MGC = std::chrono::high_resolution_clock::now(); t_avg_MGC_total_ += std::chrono::duration(end_MGC - start_MGC).count(); } -} +} \ No newline at end of file diff --git a/include/GMGPolar/gmgpolar.h b/include/GMGPolar/gmgpolar.h index cbd070ae..4d5ee2c6 100644 --- a/include/GMGPolar/gmgpolar.h +++ b/include/GMGPolar/gmgpolar.h @@ -167,14 +167,14 @@ class GMGPolar : public IGMGPolar /* ------------------- */ /* Multigrid Functions */ - void multigrid_V_Cycle(int level_depth, Vector solution, Vector rhs, Vector residual); - void multigrid_W_Cycle(int level_depth, Vector solution, Vector rhs, Vector residual); - void multigrid_F_Cycle(int level_depth, Vector solution, Vector rhs, Vector residual); - void extrapolated_multigrid_V_Cycle(int level_depth, Vector solution, Vector rhs, + void multigrid_V_Cycle(int level_depth, Vector solution, ConstVector rhs, Vector residual); + void multigrid_W_Cycle(int level_depth, Vector solution, ConstVector rhs, Vector residual); + void multigrid_F_Cycle(int level_depth, Vector solution, ConstVector rhs, Vector residual); + void extrapolated_multigrid_V_Cycle(int level_depth, Vector solution, ConstVector rhs, Vector residual); - void extrapolated_multigrid_W_Cycle(int level_depth, Vector solution, Vector rhs, + void extrapolated_multigrid_W_Cycle(int level_depth, Vector solution, ConstVector rhs, Vector residual); - void extrapolated_multigrid_F_Cycle(int level_depth, Vector solution, Vector rhs, + void extrapolated_multigrid_F_Cycle(int level_depth, Vector solution, ConstVector rhs, Vector residual); /* ----------------------- */ diff --git a/include/GMGPolar/setup.h b/include/GMGPolar/setup.h index d9194b21..24f6ca29 100644 --- a/include/GMGPolar/setup.h +++ b/include/GMGPolar/setup.h @@ -174,7 +174,7 @@ int GMGPolar::chooseNumberOfLevels(c const int minAngularDivisions = 4; // Minimum level for Multigrid - const int multigridMinLevel = 2; + const int multigridMinLevel = (extrapolation_ == ExtrapolationType::NONE) ? 1 : 2; // Calculate radial maximum level int radialNodes = finestGrid.nr(); diff --git a/tests/GMGPolar/solve_tests.cpp b/tests/GMGPolar/solve_tests.cpp index e6f69c1c..aa6c53e3 100644 --- a/tests/GMGPolar/solve_tests.cpp +++ b/tests/GMGPolar/solve_tests.cpp @@ -545,6 +545,108 @@ using gmgpolar_test_suite = testing::Types< std::integral_constant, // expected_l2_error std::integral_constant, // expected_inf_error std::integral_constant // expected_residual_reduction + >, + std::tuple< + CzarnyGeometry, + SonnendruckerGyroCoefficients, + PolarR6_Boundary_CzarnyGeometry, + PolarR6_Sonnendrucker_CzarnyGeometry, + PolarR6_CzarnyGeometry, + std::integral_constant, // R0 + std::integral_constant, // Rmax + std::integral_constant, // nrExp + std::integral_constant, // nthetaExp + std::integral_constant, // refinementRadius + std::integral_constant, // anisotropicFactor + std::integral_constant, // divideBy2 + std::integral_constant, // verbose + std::integral_constant, // maxOpenMPThreads + std::integral_constant, // DirBC_Interior + std::integral_constant, // StencilDistributionMethod + std::integral_constant, // cacheDensityProfileCoefficient + std::integral_constant, // cacheDomainGeometry + std::integral_constant, // extrapolation + std::integral_constant, // maxLevels + std::integral_constant, // multigridCycle + std::integral_constant, // FMG + std::integral_constant, // FMG_iterations + std::integral_constant, // FMG_cycle + std::integral_constant, // maxIterations + std::integral_constant, // residualNormType + std::integral_constant, // absoluteTolerance + std::integral_constant, // relativeTolerance + std::integral_constant, // expected_iterations + std::integral_constant, // expected_l2_error + std::integral_constant, // expected_inf_error + std::integral_constant // expected_residual_reduction + >, + std::tuple< + CzarnyGeometry, + SonnendruckerGyroCoefficients, + PolarR6_Boundary_CzarnyGeometry, + PolarR6_Sonnendrucker_CzarnyGeometry, + PolarR6_CzarnyGeometry, + std::integral_constant, // R0 + std::integral_constant, // Rmax + std::integral_constant, // nrExp + std::integral_constant, // nthetaExp + std::integral_constant, // refinementRadius + std::integral_constant, // anisotropicFactor + std::integral_constant, // divideBy2 + std::integral_constant, // verbose + std::integral_constant, // maxOpenMPThreads + std::integral_constant, // DirBC_Interior + std::integral_constant, // StencilDistributionMethod + std::integral_constant, // cacheDensityProfileCoefficient + std::integral_constant, // cacheDomainGeometry + std::integral_constant, // extrapolation + std::integral_constant, // maxLevels + std::integral_constant, // multigridCycle + std::integral_constant, // FMG + std::integral_constant, // FMG_iterations + std::integral_constant, // FMG_cycle + std::integral_constant, // maxIterations + std::integral_constant, // residualNormType + std::integral_constant, // absoluteTolerance + std::integral_constant, // relativeTolerance + std::integral_constant, // expected_iterations + std::integral_constant, // expected_l2_error + std::integral_constant, // expected_inf_error + std::integral_constant // expected_residual_reduction + >, + std::tuple< + CzarnyGeometry, + SonnendruckerGyroCoefficients, + PolarR6_Boundary_CzarnyGeometry, + PolarR6_Sonnendrucker_CzarnyGeometry, + PolarR6_CzarnyGeometry, + std::integral_constant, // R0 + std::integral_constant, // Rmax + std::integral_constant, // nrExp + std::integral_constant, // nthetaExp + std::integral_constant, // refinementRadius + std::integral_constant, // anisotropicFactor + std::integral_constant, // divideBy2 + std::integral_constant, // verbose + std::integral_constant, // maxOpenMPThreads + std::integral_constant, // DirBC_Interior + std::integral_constant, // StencilDistributionMethod + std::integral_constant, // cacheDensityProfileCoefficient + std::integral_constant, // cacheDomainGeometry + std::integral_constant, // extrapolation + std::integral_constant, // maxLevels + std::integral_constant, // multigridCycle + std::integral_constant, // FMG + std::integral_constant, // FMG_iterations + std::integral_constant, // FMG_cycle + std::integral_constant, // maxIterations + std::integral_constant, // residualNormType + std::integral_constant, // absoluteTolerance + std::integral_constant, // relativeTolerance + std::integral_constant, // expected_iterations + std::integral_constant, // expected_l2_error + std::integral_constant, // expected_inf_error + std::integral_constant // expected_residual_reduction > >; // clang-format on