예제 #1
0
void TpetraLinearSolver::setupLinearSolver(
  Teuchos::RCP<LinSys::Vector> sln,
  Teuchos::RCP<LinSys::Matrix> matrix,
  Teuchos::RCP<LinSys::Vector> rhs,
  Teuchos::RCP<LinSys::MultiVector> coords)
{

  setSystemObjects(matrix,rhs);
  problem_ = Teuchos::RCP<LinSys::LinearProblem>(new LinSys::LinearProblem(matrix_, sln, rhs_) );

  if(activateMueLu_) {
    coords_ = coords;
  }
  else {
    Ifpack2::Factory factory;
    const std::string preconditionerType ("RELAXATION");
    preconditioner_ = factory.create (preconditionerType, Teuchos::rcp_const_cast<const LinSys::Matrix>(matrix_), 0);
    preconditioner_->setParameters(*paramsPrecond_);
    preconditioner_->initialize();
    problem_->setRightPrec(preconditioner_);

    // create the solver, e.g., gmres, cg, tfqmr, bicgstab
    LinSys::SolverFactory sFactory;
    solver_ = sFactory.create(config_->get_method(), params_);
    solver_->setProblem(problem_);
  }
}
예제 #2
0
Teuchos::RCP<Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
build_precond(Teuchos::ParameterList& test_params,
              const Teuchos::RCP<const Tpetra::CrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node,LocalMatVec,LocalMatSolve> >& A)
{
  Teuchos::Time timer("precond");

  typedef Ifpack2::Preconditioner<Scalar,LocalOrdinal,GlobalOrdinal,Node> Tprec;
  Teuchos::RCP<Tprec> prec;
  Ifpack2::Factory factory;

  std::string prec_name("not specified");
  Ifpack2::getParameter(test_params, "Ifpack2::Preconditioner", prec_name);
  prec = factory.create(prec_name, A);

  Teuchos::ParameterList tif_params;
  if (test_params.isSublist("Ifpack2")) {
    tif_params = test_params.sublist("Ifpack2");
  }

  if (A->getRowMap()->getComm()->getRank() == 0) {
    std::cout << "Configuring/Initializing/Computing Ifpack2 preconditioner..."
       << std::endl;
  }

  prec->setParameters(tif_params);
  prec->initialize();
  timer.start();
  prec->compute();
  timer.stop();

  if (A->getRowMap()->getComm()->getRank() == 0) {
    std::cout << "... Finished Computing Ifpack2 preconditioner (time: "<<timer.totalElapsedTime() << "s)"
       << std::endl;
  }

  // typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType magnitudeType;
  // magnitudeType condest = prec->computeCondEst(Ifpack2::Cheap);
  // if (A->getRowMap()->getComm()->getRank() == 0) {
  //   std::cout << "Condition estimate(cheap) for preconditioner on proc 0: "
  //             << condest << std::endl;
  // }
  return prec;
}
예제 #3
0
int main(int argc, char *argv[]) {
  typedef double                            ST;
  typedef Teuchos::ScalarTraits<ST>        SCT;
  typedef SCT::magnitudeType                MT;
  typedef Tpetra::MultiVector<>             MV;
  typedef Tpetra::Operator<>                OP;
  typedef Belos::MultiVecTraits<ST,MV>     MVT;
  typedef Belos::OperatorTraits<ST,MV,OP>  OPT;
  typedef Tpetra::CrsMatrix<>              CrsMatrix;
  typedef Ifpack2::Preconditioner<>        Prec;

  using Teuchos::ParameterList;
  using Teuchos::RCP;
  using Teuchos::rcp;

  // ************************* Initialize MPI **************************
  Teuchos::oblackholestream blackhole;
  Teuchos::GlobalMPISession mpiSession (&argc, &argv, &blackhole);

  // ************** Get the default communicator and node **************
  RCP<const Teuchos::Comm<int> > comm = Tpetra::DefaultPlatform::getDefaultPlatform().getComm();
  const int myRank = comm->getRank();

  bool verbose = true;
  bool success = true;
  bool proc_verbose = false;
  bool leftprec = true;      // left preconditioning or right.
  int frequency = -1;        // frequency of status test output.
  int numrhs = 1;            // number of right-hand sides to solve for
  int maxiters = -1;         // maximum number of iterations allowed per linear system
  std::string filename("cage4.mtx");
  MT tol = 1.0e-5;           // relative residual tolerance

  // ***************** Read the command line arguments *****************
  Teuchos::CommandLineProcessor cmdp(false,false);
  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 test matrix.  Acceptable file extensions: *.hb,*.mtx,*.triU,*.triS");
  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.");
  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;  // reset frequency if test is not verbose
  proc_verbose = verbose && (myRank==0); /* Only print on the zero processor */

  // ************************* Get the problem *************************
  RCP<CrsMatrix> A = Tpetra::MatrixMarket::Reader<CrsMatrix>::readSparseFile(filename,comm);
  RCP<MV> B = rcp(new MV(A->getRowMap(),numrhs,false));
  RCP<MV> X = rcp(new MV(A->getRowMap(),numrhs,false));
  OPT::Apply(*A, *X, *B);
  MVT::MvInit(*X);
  MVT::MvInit(*B,1);

  // ******************** Construct preconditioner *********************
  Ifpack2::Factory factory;
  RCP<Prec> M = factory.create("RELAXATION", A.getConst());
  ParameterList ifpackParams;
  ifpackParams.set("relaxation: type","Jacobi");
  M->setParameters(ifpackParams);
  M->initialize();
  M->compute();

  // ******* Create parameter list for the Belos solver manager ********
  const int NumGlobalElements = MVT::GetGlobalLength(*B);
  if (maxiters == -1)
    maxiters = NumGlobalElements - 1; // maximum number of iterations to run
  //
  ParameterList belosList;
  belosList.set( "Maximum Iterations", maxiters );       // Maximum number of iterations allowed
  belosList.set( "Convergence Tolerance", tol );         // Relative convergence tolerance requested
  if (numrhs > 1) {
    belosList.set( "Show Maximum Residual Norm Only", true );  // Show only the maximum residual norm
  }
  if (verbose) {
    belosList.set( "Verbosity", Belos::Errors + Belos::Warnings +
		   Belos::TimingDetails + Belos::StatusTestDetails );
    if (frequency > 0)
      belosList.set( "Output Frequency", frequency );
  }
  else
    belosList.set( "Verbosity", Belos::Errors + Belos::Warnings + Belos::FinalSummary );

  // ************ Construct a preconditioned linear problem ************
  RCP<Belos::LinearProblem<double,MV,OP> > problem
    = rcp( new Belos::LinearProblem<double,MV,OP>( A, X, B ) );
  if (leftprec) {
    problem->setLeftPrec( M );
  }
  else {
    problem->setRightPrec( M );
  }
  bool set = problem->setProblem();
  if (set == false) {
    if (proc_verbose)
      std::cout << std::endl << "ERROR:  Belos::LinearProblem failed to set up correctly!" << std::endl;
    return -1;
  }

  // **************** Create an iterative solver manager ***************
  RCP< Belos::PETScSolMgr<double,MV,OP> > solver
    = rcp( new Belos::PETScSolMgr<double,MV,OP>(problem, rcp(&belosList,false)) );
  solver->setCLA(argc,argv);

  // ****************** Start the block CG iteration *******************
  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 Krylov iterations: " << maxiters << std::endl;
    std::cout << "Relative residual tolerance: " << tol << std::endl;
    std::cout << std::endl;
  }

  // ************************** Perform solve **************************
  Belos::ReturnType ret = solver->solve();

  // ********************* Compute actual residuals ********************
  bool badRes = false;
  std::vector<double> actual_resids( numrhs );
  std::vector<double> rhs_norm( numrhs );
  RCP<MV> resid = MVT::Clone(*X, 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;
    }
  }

if (ret!=Belos::Converged || badRes) {
  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;
}

return success ? EXIT_SUCCESS : EXIT_FAILURE;
}