#include <Teuchos_Assert.hpp>
#include <Teuchos_StandardCatchMacros.hpp>
#include <Tpetra_Core.hpp>
#include <Tpetra_CrsMatrix.hpp>
#include <Tpetra_Map.hpp>
#include <Tpetra_MatrixIO.hpp>
#include <Tpetra_MultiVector.hpp>
#include <Tpetra_Operator.hpp>
#include "BelosTpetraAdapter.hpp"
#include "BelosTpetraTestFramework.hpp"
template <typename ScalarType>
int run(int argc, char *argv[]) {
using ST = typename Tpetra::MultiVector<ScalarType>::scalar_type;
using LO = typename Tpetra::Vector<>::local_ordinal_type;
using GO = typename Tpetra::Vector<>::global_ordinal_type;
using NT = typename Tpetra::Vector<>::node_type;
using MV = typename Tpetra::MultiVector<ST, LO, GO, NT>;
using OP = typename Tpetra::Operator<ST, LO, GO, NT>;
using MAP = typename Tpetra::Map<LO, GO, NT>;
using MAT = typename Tpetra::CrsMatrix<ST, LO, GO, NT>;
RCP<const Teuchos::Comm<int>> comm = Tpetra::getDefaultComm();
bool verbose = false;
bool success = true;
try {
bool procVerbose = false;
bool leftPrec = true;
int frequency = -1;
int numRhs = 1;
int maxiters = -1;
std::string filename("osrirr1.hb");
MT tol = STM::squareroot(STM::eps());
cmdp.
setOption(
"verbose",
"quiet", &verbose,
"Print messages and results.");
cmdp.
setOption(
"left-prec",
"right-prec", &leftPrec,
"Left preconditioning or right.");
cmdp.
setOption(
"frequency", &frequency,
"Solvers frequency for printing residuals (#iters).");
cmdp.
setOption(
"filename", &filename,
"Filename for Harwell-Boeing test matrix.");
cmdp.
setOption(
"tol", &tol,
"Relative residual tolerance used by GMRES solver.");
cmdp.
setOption(
"num-rhs", &numRhs,
"Number of right-hand sides to be solved for.");
"Maximum number of iterations per linear system (-1 = adapted to problem/block size).");
return -1;
}
if (!verbose) frequency = -1;
RCP<MAT> A;
Tpetra::Utils::readHBMatrix(filename, comm, A);
RCP<const MAP> map = A->getRowMap();
procVerbose = verbose && (comm->getRank() == 0);
const int numGlobalElements = map->getGlobalNumElements();
if (maxiters == -1) maxiters = numGlobalElements - 1;
RCP<ParameterList> belosList =
rcp(
new ParameterList());
belosList->set("Maximum Iterations", maxiters);
belosList->set("Convergence Tolerance", tol);
if (leftPrec)
belosList->set("Explicit Residual Test", true);
if (verbose) {
if (frequency > 0) belosList->set("Output Frequency", frequency);
} else
RCP<MV> X =
rcp(
new MV(map, numRhs));
X->putScalar(0.0);
RCP<MV> B =
rcp(
new MV(map, numRhs));
B->randomize();
RCP<LinearProblem> problem =
rcp(
new LinearProblem(A, X, B));
bool set = problem->setProblem();
if (set == false) {
if (procVerbose)
std::cout << std::endl << "ERROR: Belos::LinearProblem failed to set up correctly!" << std::endl;
return -1;
}
RCP<PseudoBlockTFQMRSolMgr> solver =
rcp(
new PseudoBlockTFQMRSolMgr(problem, belosList));
if (procVerbose) {
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 Pseudo Block TFQMR iterations: " << maxiters << std::endl;
std::cout << "Relative residual tolerance: " << tol << std::endl;
std::cout << std::endl;
}
bool badRes = false;
std::vector<ST> actualResids(numRhs);
std::vector<ST> rhsNorm(numRhs);
MV resid(map, numRhs);
OPT::Apply(*A, *X, resid);
MVT::MvAddMv(-1.0, resid, 1.0, *B, resid);
MVT::MvNorm(resid, actualResids);
MVT::MvNorm(*B, rhsNorm);
if (procVerbose) {
std::cout << "---------- Actual Residuals (normalized) ----------" << std::endl << std::endl;
for (int i = 0; i < numRhs; i++) {
ST actRes = actualResids[i] / rhsNorm[i];
std::cout << "Problem " << i << " : \t" << actRes << std::endl;
if (actRes > tol) badRes = true;
}
}
success = false;
if (procVerbose) std::cout << std::endl << "ERROR: Belos did not converge!" << std::endl;
} else {
success = true;
if (procVerbose) std::cout << std::endl << "SUCCESS: Belos converged!" << std::endl;
}
}
return success ? EXIT_SUCCESS : EXIT_FAILURE;
}
int main(int argc, char *argv[]) {
return run<double>(argc, argv);
}