From d109c2e765ee6ac95079eff39e1129f4987317b3 Mon Sep 17 00:00:00 2001 From: stark256-spec Date: Tue, 11 Aug 2026 22:59:22 -0500 Subject: [PATCH] SystemSolver: use Preconditioner::Side enum for preconditioning side SystemSolver::preconditionerSetup() took a std::string and manually mapped "left"/"right" to Preconditioner::Side. Left preconditioning was added in #417 and the other solvers already select the side via the enum, so this brought SystemSolver in line with them. Change preconditionerSetup() to accept Preconditioner::Side directly and drop the internal string parsing. The string-to-enum conversion now happens once at the CLI boundary in the sysGmres example and the functionality test, where the option is already validated. Closes #439 --- examples/sysGmres.cpp | 8 +++++++- resolve/SystemSolver.cpp | 23 +++++------------------ resolve/SystemSolver.hpp | 2 +- tests/functionality/testSysGmres.cpp | 11 ++++++++--- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/examples/sysGmres.cpp b/examples/sysGmres.cpp index 7bd9ba687..c71b54e9f 100644 --- a/examples/sysGmres.cpp +++ b/examples/sysGmres.cpp @@ -9,6 +9,7 @@ #include #include "ExampleHelper.hpp" +#include #include #include #include @@ -171,6 +172,11 @@ int sysGmres(int argc, char* argv[]) processInputs(method, gs, sketch, flexible, side); + // processInputs guarantees `side` is "left" or "right". + ReSolve::Preconditioner::Side prec_side = + (side == "left") ? ReSolve::Preconditioner::Side::LEFT + : ReSolve::Preconditioner::Side::RIGHT; + std::cout << "Matrix file: " << matrix_pathname << "\n" << "RHS file: " << rhs_pathname << "\n"; @@ -255,7 +261,7 @@ int sysGmres(int argc, char* argv[]) // Set up the preconditioner if (return_code == 0) { - status = solver.preconditionerSetup(side); + status = solver.preconditionerSetup(prec_side); std::cout << "solver.preconditionerSetup returned status: " << status << "\n"; if (status != 0) { diff --git a/resolve/SystemSolver.cpp b/resolve/SystemSolver.cpp index 789285d9f..541cc7b95 100644 --- a/resolve/SystemSolver.cpp +++ b/resolve/SystemSolver.cpp @@ -619,9 +619,12 @@ namespace ReSolve * * Initializes and attaches the preconditioner to the iterative solver. * + * @param[in] side - preconditioning side (Preconditioner::Side::LEFT or + * Preconditioner::Side::RIGHT) + * * @return int 0 if successful, 1 if it fails */ - int SystemSolver::preconditionerSetup(std::string side) + int SystemSolver::preconditionerSetup(Preconditioner::Side side) { int status = 0; @@ -642,23 +645,7 @@ namespace ReSolve return status; } - Preconditioner::Side prec_side; - if (side == "left") - { - prec_side = Preconditioner::LEFT; - } - else if (side == "right") - { - prec_side = Preconditioner::RIGHT; - } - else - { - out::error() << "Preconditioning side '" << side - << "' not recognized. Use 'left' or 'right'.\n"; - return 1; - } - - status += preconditioner_->setSide(prec_side); + status += preconditioner_->setSide(side); status += preconditioner_->setup(A_); if (memspace_ != "cpu") diff --git a/resolve/SystemSolver.hpp b/resolve/SystemSolver.hpp index 67a3307d5..e3643f88c 100644 --- a/resolve/SystemSolver.hpp +++ b/resolve/SystemSolver.hpp @@ -61,7 +61,7 @@ namespace ReSolve int factorize(); // numeric part int refactorize(); int refactorizationSetup(); - int preconditionerSetup(std::string side); + int preconditionerSetup(Preconditioner::Side side); int resetPreconditioner(matrix_type* A); int solve(vector_type* rhs, vector_type* x); // for direct and iterative int refine(vector_type* rhs, vector_type* x); // for iterative refinement diff --git a/tests/functionality/testSysGmres.cpp b/tests/functionality/testSysGmres.cpp index e3033fa39..b5a4d2109 100644 --- a/tests/functionality/testSysGmres.cpp +++ b/tests/functionality/testSysGmres.cpp @@ -109,6 +109,11 @@ int test(int argc, char* argv[]) processInputs(method, gs, sketch, side); + // processInputs guarantees `side` is "left" or "right". + ReSolve::Preconditioner::Side prec_side = + (side == "left") ? ReSolve::Preconditioner::Side::LEFT + : ReSolve::Preconditioner::Side::RIGHT; + // Create workspace and initialize its handles. workspace_type workspace; workspace.initializeHandles(); @@ -170,7 +175,7 @@ int test(int argc, char* argv[]) solver.getIterativeSolver().setCliParam("restart", "200"); // Set preconditioner (default in this case ILU0) - status = solver.preconditionerSetup(side); + status = solver.preconditionerSetup(prec_side); error_sum += status; // Solve system @@ -207,7 +212,7 @@ int test(int argc, char* argv[]) bad_guess_solver.getIterativeSolver().setCliParam("flexible", flexible); bad_guess_solver.getIterativeSolver().setCliParam("restart", "200"); - status = bad_guess_solver.preconditionerSetup(side); + status = bad_guess_solver.preconditionerSetup(prec_side); error_sum += status; const real_type bad_guess_rnorm = bad_guess_solver.getResidualNorm(vec_rhs, &bad_guess_x); @@ -265,7 +270,7 @@ int test(int argc, char* argv[]) accepted_guess_solver.getIterativeSolver().setCliParam("flexible", flexible); accepted_guess_solver.getIterativeSolver().setCliParam("restart", "200"); - status = accepted_guess_solver.preconditionerSetup(side); + status = accepted_guess_solver.preconditionerSetup(prec_side); error_sum += status; const real_type initial_guess_rnorm = accepted_guess_solver.getResidualNorm(vec_rhs, &vec_x_guess);