#include <Tpetra_Core.hpp>
#include <Tpetra_CrsMatrix.hpp>
#include <Tpetra_Map.hpp>
#include <Tpetra_MatrixIO.hpp>
#include "BelosTpetraAdapter.hpp"
#include <Teuchos_CommandLineProcessor.hpp>
#include <Teuchos_ParameterList.hpp>
#include <Teuchos_StandardCatchMacros.hpp>
template<typename ScalarType>
int run(int argc, char *argv[])
{
using ST = typename Tpetra::MultiVector<ScalarType>::scalar_type;
using LO = typename Tpetra::MultiVector<>::local_ordinal_type;
using GO = typename Tpetra::MultiVector<>::global_ordinal_type;
using NT = typename Tpetra::MultiVector<>::node_type;
using OP = typename Tpetra::Operator<ST,LO,GO,NT>;
using MV = typename Tpetra::MultiVector<ST,LO,GO,NT>;
using tcrsmatrix_t = Tpetra::CrsMatrix<ST,LO,GO,NT>;
using tmap_t = Tpetra::Map<LO,GO,NT>;
using tmultivector_t = Tpetra::MultiVector<ST,LO,GO,NT>;
using Teuchos::ParameterList;
using Teuchos::RCP;
using Teuchos::rcp;
Teuchos::GlobalMPISession session(&argc, &argv, NULL);
RCP<const Teuchos::Comm<int>> comm = Tpetra::getDefaultComm();
bool verbose = true;
bool success = true;
try
{
int MyPID = rank(*comm);
bool proc_verbose = false;
int frequency = -1;
std::string filename("bcsstk14.hb");
double tol = 1.0e-6;
int numBlocks = 100;
int recycleBlocks = 10;
int numrhs = 2;
int maxiters = 4000;
Teuchos::CommandLineProcessor cmdp(false,true);
cmdp.setOption("verbose","quiet",&verbose,"Print messages and results.");
cmdp.setOption("frequency",&frequency,"Solvers frequency for printing residuals (#iters).");
cmdp.setOption("filename",&filename,"Filename for test matrix.");
cmdp.setOption("tol",&tol,"Relative residual tolerance used by the RCG solver.");
cmdp.setOption("max-subspace",&numBlocks,"Maximum number of vectors in search space (not including recycle space).");
cmdp.setOption("recycle",&recycleBlocks,"Number of vectors in recycle space.");
cmdp.setOption("num-rhs",&numrhs,"Number of right-hand sides to be solved for.");
cmdp.setOption("max-iters",&maxiters,"Maximum number of iterations per linear system (-1 = adapted to problem/block size).");
if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) {
return -1;
}
if (!verbose)
frequency = -1;
RCP<tcrsmatrix_t> A;
Tpetra::Utils::readHBMatrix(filename, comm, A);
RCP<const tmap_t> rowMap = A->getDomainMap();
proc_verbose = ( verbose && (MyPID==0) );
RCP<tmultivector_t> B, X;
X = rcp(new MV(rowMap, numrhs));
MVT::MvRandom(*X);
B = rcp(new MV( rowMap, numrhs));
OPT::Apply( *A, *X, *B );
MVT::MvInit( *X, 0.0 );
const int NumGlobalElements = B->getGlobalLength();
if (maxiters == -1)
maxiters = NumGlobalElements - 1;
ParameterList belosList;
belosList.set( "Maximum Iterations", maxiters );
belosList.set( "Num Blocks", numBlocks);
belosList.set( "Num Recycled Blocks", recycleBlocks );
belosList.set( "Convergence Tolerance", tol );
if (verbose) {
if (frequency > 0)
belosList.set( "Output Frequency", frequency );
}
else
if (set == false) {
if (proc_verbose)
std::cout << std::endl << "ERROR: Belos::LinearProblem failed to set up correctly!" << std::endl;
return -1;
}
RCP< Belos::SolverManager<ST,MV,OP> > newSolver
if (proc_verbose) {
std::cout << std::endl << std::endl;
std::cout << "Dimension of matrix: " << NumGlobalElements << std::endl;
std::cout << "Number of right-hand sides: " << numrhs << std::endl;
std::cout << "Max number of RCG iterations: " << maxiters << std::endl;
std::cout << "Max number of vectors in Krylov space: " << numBlocks << std::endl;
std::cout << "Number of vectors in recycle space: " << recycleBlocks << std::endl;
std::cout << "Relative residual tolerance: " << tol << std::endl;
std::cout << std::endl;
}
bool badRes = false;
std::vector<ST> actual_resids( numrhs );
std::vector<ST> rhs_norm( numrhs );
MV resid(rowMap, numrhs);
OPT::Apply( *A, *X, resid );
MVT::MvAddMv( -1.0, resid, 1.0, *B, resid );
MVT::MvNorm( resid, actual_resids );
MVT::MvNorm( *B, rhs_norm );
if (proc_verbose) {
std::cout<< "---------- Actual Residuals (normalized) ----------"<<std::endl<<std::endl;
for ( int i=0; i<numrhs; i++) {
double actRes = actual_resids[i]/rhs_norm[i];
std::cout<<"Problem "<<i<<" : \t"<< actRes <<std::endl;
if (actRes > tol) badRes = true;
}
}
success = false;
if (proc_verbose)
std::cout << std::endl << "ERROR: Belos did not converge!" << std::endl;
}
else {
success = true;
if (proc_verbose)
std::cout << std::endl << "SUCCESS: Belos converged!" << std::endl;
}
}
TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success);
return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
}
int main(int argc, char *argv[]) {
return run<double>(argc,argv);
}
Belos header file which uses auto-configuration information to include necessary C++ headers.
Class which describes the linear problem to be solved by the iterative solver.
The Belos::RCGSolMgr provides a solver manager for the RCG (Recycling Conjugate Gradient) linear solv...
virtual bool setProblem(const Teuchos::RCP< MV > &newX=Teuchos::null, const Teuchos::RCP< const MV > &newB=Teuchos::null)
Set up the linear problem manager.
Traits class which defines basic operations on multivectors.
Class which defines basic traits for the operator type.
Implementation of the RCG (Recycling Conjugate Gradient) iterative linear solver.
ReturnType
Whether the Belos solve converged for all linear systems.