void TrilinosCrsMatrix::solve(LSS::Vector& solution, LSS::Vector& rhs)
{
  cf3_assert(m_is_created);
  cf3_assert(solution.is_created());
  cf3_assert(rhs.is_created());

  LSS::TrilinosVector& tsol = dynamic_cast<LSS::TrilinosVector&>(solution);
  LSS::TrilinosVector& trhs = dynamic_cast<LSS::TrilinosVector&>(rhs);

  Teuchos::RCP<Teuchos::ParameterList> paramList = Teuchos::getParametersFromXmlFile(options().option("settings_file").value_str());

  // Build Thyra linear algebra objects
  Teuchos::RCP<const Thyra::LinearOpBase<double> > th_mat = Thyra::epetraLinearOp(m_mat);
  Teuchos::RCP<const Thyra::VectorBase<double> > th_rhs = Thyra::create_Vector(trhs.epetra_vector(),th_mat->range());
  Teuchos::RCP<Thyra::VectorBase<double> > th_sol = Thyra::create_Vector(tsol.epetra_vector(),th_mat->domain());

  // Build stratimikos solver
  /////////////////////////////////////////////////////////

  Stratimikos::DefaultLinearSolverBuilder linearSolverBuilder;

  //Teko::addTekoToStratimikosBuilder(linearSolverBuilder);
  linearSolverBuilder.setParameterList(paramList);

  Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<double> > lowsFactory = Thyra::createLinearSolveStrategy(linearSolverBuilder);
  Teuchos::RCP<Thyra::LinearOpWithSolveBase<double> > th_invA = Thyra::linearOpWithSolve(*lowsFactory, th_mat);

  Thyra::assign(th_sol.ptr(), 0.0);
  Thyra::SolveStatus<double> status = Thyra::solve<double>(*th_invA, Thyra::NOTRANS, *th_rhs, th_sol.ptr());
  CFinfo << "Thyra::solve finished with status " << status.message << CFendl;
}
Esempio n. 2
0
void TrilinosMatrix::solve(LSS::Vector& solution, LSS::Vector& rhs)
{
  cf3_assert(m_is_created);
  cf3_assert(solution.is_created());
  cf3_assert(rhs.is_created());

  // general setup phase
  Stratimikos::DefaultLinearSolverBuilder linearSolverBuilder(options().option("settings_file").value_str());
  /// @todo decouple from fancyostream to ostream or to C stdout when possible
  Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
  Teuchos::CommandLineProcessor  clp(false); // false: don't throw exceptions
  linearSolverBuilder.setupCLP(&clp); // not used, TODO: see if can be removed safely since not really used
  /// @todo check whgats wrtong with input options via string
  //clp.setOption( "tol",            &tol,            "Tolerance to check against the scaled residual norm." ); // input options via string, not working for some reason
  int argc=0; char** argv=0; Teuchos::CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
  if( parse_return != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL ) throw common::ParsingFailed(FromHere(),"Emulated command line parsing for stratimikos failed");

  // wrapping epetra to thyra
  Teuchos::RCP<const Thyra::LinearOpBase<double> > A = Thyra::epetraLinearOp( m_mat );
  LSS::TrilinosVector& tsol = dynamic_cast<LSS::TrilinosVector&>(solution);
  Teuchos::RCP<Thyra::VectorBase<double> >         x = Thyra::create_Vector( tsol.epetra_vector() , A->domain() );
  LSS::TrilinosVector& trhs = dynamic_cast<LSS::TrilinosVector&>(rhs);
  Teuchos::RCP<const Thyra::VectorBase<double> >   b = Thyra::create_Vector( trhs.epetra_vector() , A->range() );

  // r = b - A*x, initial L2 norm
  double norm2_in=0.;
  {
    Epetra_Vector epetra_r(*trhs.epetra_vector());
    Epetra_Vector m_mat_x(m_mat->OperatorRangeMap());
    m_mat->Apply(*tsol.epetra_vector(),m_mat_x);
    epetra_r.Update(-1.0,m_mat_x,1.0);
    epetra_r.Norm2(&norm2_in);
  }

  // Reading in the solver parameters from the parameters file and/or from
  // the command line.  This was setup by the command-line options
  // set by the setupCLP(...) function above.
  linearSolverBuilder.readParameters(0); // out.get() if want confirmation about the xml file within trilinos
  Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<double> > lowsFactory = linearSolverBuilder.createLinearSolveStrategy(""); // create linear solver strategy
/// @todo verbosity level from option
  lowsFactory->setVerbLevel((Teuchos::EVerbosityLevel)4); // set verbosity

  // print back default and current settings
  if (false) {
    std::ofstream ofs("./trilinos_default.txt");
    linearSolverBuilder.getValidParameters()->print(ofs,Teuchos::ParameterList::PrintOptions().indent(2).showTypes(true).showDoc(true)); // the last true-false is the deciding about whether printing documentation to option or not
    ofs.flush();ofs.close();
    ofs.open("./trilinos_default.xml");
    Teuchos::writeParameterListToXmlOStream(*linearSolverBuilder.getValidParameters(),ofs);
    ofs.flush();ofs.close();
  }
  if (false) {
    linearSolverBuilder.writeParamsFile(*lowsFactory,"./trilinos_current.xml");
  }

  // solve the matrix
  Teuchos::RCP<Thyra::LinearOpWithSolveBase<double> > lows = Thyra::linearOpWithSolve(*lowsFactory, A);
  lows->solve(Thyra::NOTRANS,*b,x.ptr());

  // r = b - A*x, final L2 norm
  double norm2_out=0.;
  {
    Epetra_Vector epetra_r(*trhs.epetra_vector());
    Epetra_Vector m_mat_x(m_mat->OperatorRangeMap());
    m_mat->Apply(*tsol.epetra_vector(),m_mat_x);
    epetra_r.Update(-1.0,m_mat_x,1.0);
    epetra_r.Norm2(&norm2_out);
  }

  // print in and out residuals
  CFinfo << "Solver residuals: in " << norm2_in << ", out " << norm2_out << CFendl;
}