diff --git a/packages/muelu/example/basic/Simple.cpp b/packages/muelu/example/basic/Simple.cpp index 6a7d86bde632..4afe89e0b5e1 100644 --- a/packages/muelu/example/basic/Simple.cpp +++ b/packages/muelu/example/basic/Simple.cpp @@ -83,6 +83,8 @@ int main_(Teuchos::CommandLineProcessor &clp, Xpetra::UnderlyingLib &lib, int ar clp.setOption("solver", &solveType, "solve type: (none | belos)"); std::string belosType = "cg"; clp.setOption("belosType", &belosType, "belos solver type: (Pseudoblock CG | Block CG | Pseudoblock GMRES | Block GMRES | ...) see BelosSolverFactory.hpp for exhaustive list of solvers"); + bool computeCondEst = false; + clp.setOption("condEst", "noCondEst", &computeCondEst, "compute condition number estimate (currently only available for Pseudoblock CG)"); double tol = 1e-12; clp.setOption("tol", &tol, "solver convergence tolerance"); bool binaryFormat = false; @@ -199,7 +201,7 @@ int main_(Teuchos::CommandLineProcessor &clp, Xpetra::UnderlyingLib &lib, int ar // ========================================================================= { comm->barrier(); - SystemSolve(A, X, B, H, Prec, out, solveType, belosType, false, false, useML, cacheSize, 0, scaleResidualHist, solvePreconditioned, maxIts, tol); + SystemSolve(A, X, B, H, Prec, out, solveType, belosType, false, false, useML, cacheSize, 0, scaleResidualHist, solvePreconditioned, maxIts, tol, computeCondEst); comm->barrier(); } diff --git a/packages/muelu/test/scaling/Driver.cpp b/packages/muelu/test/scaling/Driver.cpp index 42f478638720..39f2fd5d2053 100644 --- a/packages/muelu/test/scaling/Driver.cpp +++ b/packages/muelu/test/scaling/Driver.cpp @@ -202,6 +202,8 @@ int main_(Teuchos::CommandLineProcessor& clp, Xpetra::UnderlyingLib& lib, int ar clp.setOption("solver", &dsolveType, "solve type: (none | belos | standalone | matvec)"); std::string belosType = "cg"; clp.setOption("belosType", &belosType, "belos solver type: (Pseudoblock CG | Block CG | Pseudoblock GMRES | Block GMRES | ...) see BelosSolverFactory.hpp for exhaustive list of solvers"); + bool computeCondEst = false; + clp.setOption("condEst", "noCondEst", &computeCondEst, "compute condition number estimate (currently only available for Pseudoblock CG)"); double dtol = 1e-12, tol; clp.setOption("tol", &dtol, "solver convergence tolerance"); bool binaryFormat = false; @@ -521,7 +523,7 @@ int main_(Teuchos::CommandLineProcessor& clp, Xpetra::UnderlyingLib& lib, int ar } // Solve the system numResolves+1 times - SystemSolve(A, X, B, H, Prec, out2, solveType, belosType, profileSolve, useAMGX, useML, cacheSize, numResolves, scaleResidualHist, solvePreconditioned, maxIts, tol); + SystemSolve(A, X, B, H, Prec, out2, solveType, belosType, profileSolve, useAMGX, useML, cacheSize, numResolves, scaleResidualHist, solvePreconditioned, maxIts, tol, computeCondEst); comm->barrier(); } catch (const std::exception& e) { diff --git a/packages/muelu/test/scaling/DriverCore.hpp b/packages/muelu/test/scaling/DriverCore.hpp index 1d90d2b457e8..e04b9e51748b 100644 --- a/packages/muelu/test/scaling/DriverCore.hpp +++ b/packages/muelu/test/scaling/DriverCore.hpp @@ -232,7 +232,8 @@ void SystemSolve(Teuchos::RCP using Teuchos::RCP; using Teuchos::rcp; @@ -337,6 +338,9 @@ void SystemSolve(Teuchos::RCP(H)); // Turns a MueLu::Hierarchy object into a Belos operator } + std::string belosTypeUpper(belosType); + std::transform(belosTypeUpper.begin(), belosTypeUpper.end(), belosTypeUpper.begin(), ::toupper); + // Belos parameter list RCP belosList = Teuchos::parameterList(); belosList->set("Maximum Iterations", maxIts); // Maximum number of iterations allowed @@ -346,8 +350,12 @@ void SystemSolve(Teuchos::RCPset("Output Style", Belos::Brief); if (!scaleResidualHist) belosList->set("Implicit Residual Scaling", "None"); + if (computeCondEst && (belosTypeUpper == "CG" || belosTypeUpper == "PSEUDOBLOCK CG")) + belosList->set("Estimate Condition Number", true); int numIts; + Scalar conditionNumberEstimate = zero; + Teuchos::ArrayRCP eigenvalueEstimates; Belos::ReturnType ret = Belos::Unconverged; constexpr bool verbose = false; @@ -393,6 +401,13 @@ void SystemSolve(Teuchos::RCPsolve(); numIts = solver->getNumIters(); + if ((belosTypeUpper == "CG" || belosTypeUpper == "PSEUDOBLOCK CG") && + belosList->isParameter("Estimate Condition Number") && + belosList->get("Estimate Condition Number")) { + conditionNumberEstimate = Teuchos::rcp_dynamic_cast>(solver)->getConditionEstimate(); + eigenvalueEstimates = Teuchos::rcp_dynamic_cast>(solver)->getEigenEstimates(); + } + } catch (std::invalid_argument&) { // Construct a Belos LinearProblem object RCP> belosProblem = rcp(new Belos::LinearProblem(belosOp, X, B)); @@ -411,11 +426,23 @@ void SystemSolve(Teuchos::RCPsolve(); numIts = solver->getNumIters(); + + if ((belosTypeUpper == "CG" || belosTypeUpper == "PSEUDOBLOCK CG") && + belosList->isParameter("Estimate Condition Number") && + belosList->get("Estimate Condition Number")) { + conditionNumberEstimate = Teuchos::rcp_dynamic_cast>(solver)->getConditionEstimate(); + eigenvalueEstimates = Teuchos::rcp_dynamic_cast>(solver)->getEigenEstimates(); + } } // Get the number of iterations for this solve. out << "Number of iterations performed for this solve: " << numIts << std::endl; + if (conditionNumberEstimate != zero) { + out << "Condition number estimate: " << conditionNumberEstimate << std::endl; + out << "Eigenvalue estimates: " << eigenvalueEstimates().toString() << std::endl; + } + // Check convergence if (ret != Belos::Converged) out << std::endl