#include <iostream>
using namespace gismo;
{
rhs.setZero(N,1);
mat.resize(N,N);
mat.setZero();
real_t meshSize = 1./(N+1);
real_t pi = EIGEN_PI;
mat.reservePerColumn( 3 );
mat(0,0) = 2;
mat(0,1) = -1;
mat(N-1, N-1) = 2;
mat(N-1, N-2) = -1;
{
mat(k,k) = 2;
mat(k,k-1) = -1;
mat(k,k+1) = -1;
}
rhs(k,0) = pi*pi*meshSize*meshSize*math::cos(meshSize*(1+k)*pi);
mat.makeCompressed();
}
template<typename SolverType>
void gsIterativeSolverInfo(const SolverType &method,
real_t error, double time, bool& succeeded )
{
gsInfo << method.detail();
gsInfo << " Computed res. error : " << error << "\n";
gsInfo << " Time to solve: : " << time << "\n";
if ( method.error() <= method.tolerance() && error <= method.tolerance() )
{
gsInfo <<" Test passed.\n";
}
else
{
gsInfo <<" TEST FAILED!\n";
succeeded = false;
}
}
int main(
int argc,
char *argv[])
{
bool succeeded = true;
real_t tol = std::pow(10.0, - REAL_DIG * 0.75);
gsCmdLine cmd(
"Solves a 1D PDE with a Courant discretization with several solvers.");
cmd.addInt ("n", "number", "Number of unknowns", N );
cmd.addReal("", "tol", "Tolerance for the iterative solvers", tol);
try { cmd.getValues(argc,argv); } catch (int rv) { return rv; }
poissonDiscretization(mat, rhs, N);
#ifndef gsGmp_ENABLED
opt.
setInt (
"MaxIterations", 3*N);
gsInfo << opt <<"\n";
gsInfo << "Testing G+Smo's linear solvers:\n";
MinRes.setOptions(opt);
x0.setZero(N,1);
gsInfo << "\nMinRes: Started solving... ";
MinRes.solve(rhs, x0);
gsInfo << "done.\n";
gsIterativeSolverInfo(MinRes, (mat*x0-rhs).norm()/rhs.norm(), clock.
stop(), succeeded);
MinResIR.setOptions(opt);
MinResIR.setInexactResidual(true);
x0.setZero(N,1);
gsInfo << "\nMinResIR: Started solving... ";
MinResIR.solve(rhs, x0);
gsInfo << "done.\n";
gsIterativeSolverInfo(MinResIR, (mat*x0-rhs).norm()/rhs.norm(), clock.
stop(), succeeded);
GMResSolver.setOptions(opt);
x0.setZero(N,1);
if (N < 200)
{
gsInfo << "\nGMRes: Started solving... ";
GMResSolver.solve(rhs,x0);
gsInfo << "done.\n";
gsIterativeSolverInfo(GMResSolver, (mat*x0-rhs).norm()/rhs.norm(), clock.
stop(), succeeded);
}
else
gsInfo << "\nSkipping GMRes due to high number of iterations...\n";
CGSolver.setOptions(opt);
x0.setZero(N,1);
gsInfo << "\nCG: Started solving... ";
CGSolver.solve(rhs,x0);
gsInfo << "done.\n";
gsIterativeSolverInfo(CGSolver, (mat*x0-rhs).norm()/rhs.norm(), clock.
stop(), succeeded);
MRQLPSolver.setOptions(opt);
x0.setZero(N,1);
gsInfo << "\nMRQLPSolver: Started solving... ";
MRQLPSolver.solve(rhs,x0);
gsInfo << "done.\n";
gsIterativeSolverInfo(MRQLPSolver, (mat*x0-rhs).norm()/rhs.norm(), clock.
stop(), succeeded);
gsInfo << "\nTesting Eigen's interative solvers:\n";
gsSparseSolver<>::CGIdentity EigenCGIsolver;
EigenCGIsolver.setMaxIterations(maxIters);
EigenCGIsolver.setTolerance(tol);
gsInfo << "\nEigen's CG + identity prec.: Started solving... ";
EigenCGIsolver.compute(mat);
x0 = EigenCGIsolver.solve(rhs);
gsInfo << "done.\n";
gsIterativeSolverInfo(EigenCGIsolver, (mat*x0-rhs).norm()/rhs.norm(), clock.
stop(), succeeded);
gsSparseSolver<>::CGDiagonal EigenCGDsolver;
EigenCGDsolver.setMaxIterations(maxIters);
EigenCGDsolver.setTolerance(tol);
gsInfo << "\nEigen's CG + diagonal prec.: Started solving... ";
EigenCGDsolver.compute(mat);
x0 = EigenCGDsolver.solve(rhs);
gsInfo << "done.\n";
gsIterativeSolverInfo(EigenCGDsolver, (mat*x0-rhs).norm()/rhs.norm(), clock.
stop(), succeeded);
gsSparseSolver<>::BiCGSTABIdentity EigenBCGIsolver;
EigenBCGIsolver.setMaxIterations(maxIters);
EigenBCGIsolver.setTolerance(tol);
gsInfo << "\nEigen's bi conjugate gradient stabilized + identity prec.: Started solving... ";
EigenBCGIsolver.compute(mat);
x0 = EigenBCGIsolver.solve(rhs);
gsInfo << "done.\n";
gsIterativeSolverInfo(EigenBCGIsolver, (mat*x0-rhs).norm()/rhs.norm(), clock.
stop(), succeeded);
gsSparseSolver<>::BiCGSTABDiagonal EigenBCGDsolver;
EigenBCGDsolver.setMaxIterations(maxIters);
EigenBCGDsolver.setTolerance(tol);
gsInfo << "\nEigen's bi conjugate gradient stabilized solver + diagonal prec.: Started solving... ";
EigenBCGDsolver.compute(mat);
x0 = EigenBCGDsolver.solve(rhs);
gsInfo << "done.\n";
gsIterativeSolverInfo(EigenBCGDsolver, (mat*x0-rhs).norm()/rhs.norm(), clock.
stop(), succeeded);
gsSparseSolver<>::BiCGSTABILUT EigenBCGILUsolver;
EigenBCGILUsolver.setMaxIterations(maxIters);
EigenBCGILUsolver.setTolerance(tol);
gsInfo << "\nEigen's bi conjugate gradient stabilized solver + ILU prec.: Started solving... ";
EigenBCGILUsolver.compute(mat);
x0 = EigenBCGILUsolver.solve(rhs);
gsInfo << "done.\n";
gsIterativeSolverInfo(EigenBCGILUsolver, (mat*x0-rhs).norm()/rhs.norm(), clock.
stop(), succeeded);
gsSparseSolver<>::SimplicialLDLT EigenSLDLTsolver;
gsInfo << "\nEigen's Simplicial LDLT: Started solving... ";
EigenSLDLTsolver.compute(mat);
x0 = EigenSLDLTsolver.solve(rhs);
gsInfo << "done.\n";
gsInfo <<
"Eigen's Simplicial LDLT: Time to solve : " << clock.
stop() <<
"\n";
gsSparseSolver<>::QR solverQR;
gsInfo << "\nEigen's QR: Started solving... ";
solverQR.compute(mat);
x0 = solverQR.solve(rhs);
gsInfo << "done.\n";
gsInfo <<
"Eigen's QR: Time to solve : " << clock.
stop() <<
"\n";
#endif
gsSparseSolver<>::LU solverLU;
gsInfo << "\nEigen's LU: Started solving... ";
solverLU.compute(mat);
x0 = solverLU.solve(rhs);
gsInfo << "done.\n";
gsInfo <<
"Eigen's LU: Time to solve : " << clock.
stop() <<
"\n";
return succeeded ? EXIT_SUCCESS : EXIT_FAILURE;
}