135  const RCP<Teuchos::ParameterList> &solverPL,
 
  137  const RCP<
const LinearOpSourceBase<Scalar> > &fwdOpSrc,
 
  138  const RCP<
const PreconditionerBase<Scalar> > &prec,
 
  139  const bool isExternalPrec_in,
 
  140  const RCP<
const LinearOpSourceBase<Scalar> > &approxFwdOpSrc,
 
  141  const ESupportSolveUse &supportSolveUse_in,
 
  142  const int convergenceTestFrequency
 
  146  using Teuchos::TypeNameTraits;
 
  147  using Teuchos::Exceptions::InvalidParameterType;
 
  148  typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType magnitude_type;
 
  150  this->setLinePrefix(
"BELOS/T");
 
  153  solverPL_ = solverPL;
 
  154  iterativeSolver_ = iterativeSolver;
 
  155  fwdOpSrc_ = fwdOpSrc;
 
  157  isExternalPrec_ = isExternalPrec_in;
 
  158  approxFwdOpSrc_ = approxFwdOpSrc;
 
  159  supportSolveUse_ = supportSolveUse_in;
 
  160  convergenceTestFrequency_ = convergenceTestFrequency;
 
  163  if ( !is_null(solverPL_) ) {
 
  164    if (solverPL_->isParameter(
"Convergence Tolerance")) {
 
  170      if (solverPL_->isType<
double> (
"Convergence Tolerance")) {
 
  172          as<magnitude_type> (solverPL_->get<
double> (
"Convergence Tolerance"));
 
  174      else if (std::is_same_v<double, magnitude_type>) {
 
  177        TEUCHOS_TEST_FOR_EXCEPTION(
 
  178          true, std::invalid_argument, 
"BelosLinearOpWithSolve::initialize: " 
  179          "The \"Convergence Tolerance\" parameter, which you provided, must " 
  180          "have type double (the type of the magnitude of Scalar = double).");
 
  182      else if (solverPL_->isType<magnitude_type> (
"Convergence Tolerance")) {
 
  183        defaultTol_ = solverPL_->get<magnitude_type> (
"Convergence Tolerance");
 
  191        TEUCHOS_TEST_FOR_EXCEPTION(
 
  192          true, InvalidParameterType, 
"BelosLinearOpWithSolve::initialize: " 
  193          "The \"Convergence Tolerance\" parameter, which you provided, must " 
  194          "have type double (preferred) or the type of the magnitude of Scalar " 
  195          "= " << TypeNameTraits<Scalar>::name () << 
", which is " <<
 
  196          TypeNameTraits<magnitude_type>::name () << 
" in this case.  You can " 
  197          "find that type using Teuchos::ScalarTraits<Scalar>::magnitudeType.");
 
  201    if (solverPL_->isParameter(
"Timer Label") && solverPL_->isType<std::string>(
"Timer Label")) {
 
  202      label_ = solverPL_->get<std::string>(
"Timer Label");
 
  203      lp_->setLabel(label_);
 
  205    if (solverPL_->isParameter(
"Filename LHS") && solverPL_->isType<std::string>(
"Filename LHS")) {
 
  206      filenameLHS_ = solverPL_->get<std::string>(
"Filename LHS");
 
  208    if (solverPL_->isParameter(
"Filename RHS") && solverPL_->isType<std::string>(
"Filename RHS")) {
 
  209      filenameRHS_ = solverPL_->get<std::string>(
"Filename RHS");
 
  213    RCP<const Teuchos::ParameterList> defaultPL =
 
  214      iterativeSolver->getValidParameters();
 
  220    if (defaultPL->isType<
double> (
"Convergence Tolerance")) {
 
  222        as<magnitude_type> (defaultPL->get<
double> (
"Convergence Tolerance"));
 
  224    else if (std::is_same_v<double, magnitude_type>) {
 
  227      TEUCHOS_TEST_FOR_EXCEPTION(
 
  228        true, std::invalid_argument, 
"BelosLinearOpWithSolve::initialize: " 
  229        "The \"Convergence Tolerance\" parameter, which you provided, must " 
  230        "have type double (the type of the magnitude of Scalar = double).");
 
  232    else if (defaultPL->isType<magnitude_type> (
"Convergence Tolerance")) {
 
  233      defaultTol_ = defaultPL->get<magnitude_type> (
"Convergence Tolerance");
 
  241      TEUCHOS_TEST_FOR_EXCEPTION(
 
  242        true, InvalidParameterType, 
"BelosLinearOpWithSolve::initialize: " 
  243        "The \"Convergence Tolerance\" parameter, which you provided, must " 
  244        "have type double (preferred) or the type of the magnitude of Scalar " 
  245        "= " << TypeNameTraits<Scalar>::name () << 
", which is " <<
 
  246        TypeNameTraits<magnitude_type>::name () << 
" in this case.  You can " 
  247        "find that type using Teuchos::ScalarTraits<Scalar>::magnitudeType.");
 
 
  303  RCP<Teuchos::ParameterList> *solverPL,
 
  305  RCP<
const LinearOpSourceBase<Scalar> > *fwdOpSrc,
 
  306  RCP<
const PreconditionerBase<Scalar> > *prec,
 
  307  bool *isExternalPrec_in,
 
  308  RCP<
const LinearOpSourceBase<Scalar> > *approxFwdOpSrc,
 
  309  ESupportSolveUse *supportSolveUse_in
 
  313  if (solverPL) *solverPL = solverPL_;
 
  314  if (iterativeSolver) *iterativeSolver = iterativeSolver_;
 
  315  if (fwdOpSrc) *fwdOpSrc = fwdOpSrc_;
 
  316  if (prec) *prec = prec_;
 
  317  if (isExternalPrec_in) *isExternalPrec_in = isExternalPrec_;
 
  318  if (approxFwdOpSrc) *approxFwdOpSrc = approxFwdOpSrc_;
 
  319  if (supportSolveUse_in) *supportSolveUse_in = supportSolveUse_;
 
  322  solverPL_ = Teuchos::null;
 
  323  iterativeSolver_ = Teuchos::null;
 
  324  fwdOpSrc_ = Teuchos::null;
 
  325  prec_ = Teuchos::null;
 
  326  isExternalPrec_ = 
false;
 
  327  approxFwdOpSrc_ = Teuchos::null;
 
  328  supportSolveUse_ = SUPPORT_SOLVE_UNSPECIFIED;
 
 
  503  const EOpTransp M_trans,
 
  504  const MultiVectorBase<Scalar> &B,
 
  505  const Ptr<MultiVectorBase<Scalar> > &X,
 
  506  const Ptr<
const SolveCriteria<Scalar> > solveCriteria
 
  510  THYRA_FUNC_TIME_MONITOR(
"Stratimikos: BelosLOWS");
 
  513  using Teuchos::rcpFromRef;
 
  514  using Teuchos::rcpFromPtr;
 
  515  using Teuchos::FancyOStream;
 
  516  using Teuchos::OSTab;
 
  517  using Teuchos::ParameterList;
 
  518  using Teuchos::parameterList;
 
  519  using Teuchos::describe;
 
  520  typedef Teuchos::ScalarTraits<Scalar> ST;
 
  521  typedef typename ST::magnitudeType ScalarMag;
 
  522  Teuchos::Time totalTimer(
"Stratimikos::BelosLinearOpWithSolve::totalTime");
 
  523  totalTimer.start(
true);
 
  525  assertSolveSupports(*
this, M_trans, solveCriteria);
 
  529  const RCP<FancyOStream> out = this->getOStream();
 
  530  const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
 
  531  OSTab tab = this->getOSTab();
 
  532  if (out.get() && 
static_cast<int>(verbLevel) > 
static_cast<int>(Teuchos::VERB_LOW)) {
 
  533    *out << 
"\nStarting iterations with Belos:\n";
 
  535    *out << 
"Using forward operator = " << describe(*fwdOpSrc_->getOp(),verbLevel);
 
  536    *out << 
"Using iterative solver = " << describe(*iterativeSolver_,verbLevel);
 
  537    *out << 
"With #Eqns="<<B.range()->dim()<<
", #RHSs="<<B.domain()->dim()<<
" ...\n";
 
  540#ifdef HAVE_STRATIMIKOS_THYRATPETRAADAPTERS 
  544  if (filenameLHS_ != 
"") {
 
  546      auto tmv = Thyra::TpetraOperatorVectorExtraction<Scalar>::getTpetraMultiVector(Teuchos::rcpFromPtr(X));
 
  547      Tpetra::MatrixMarket::Writer<::Tpetra::CrsMatrix<Scalar> >::writeDenseFile(filenameLHS_+ 
"." + label_ + 
"." + std::to_string(counter_), *tmv, 
"", 
"");
 
  548    } 
catch (
const std::logic_error&) {
 
  549      *out << 
"Warning: Cannot write LHS multivector to file.\n";
 
  552  if (filenameRHS_ != 
"") {
 
  554      auto tmv = Thyra::TpetraOperatorVectorExtraction<Scalar>::getConstTpetraMultiVector(Teuchos::rcpFromRef(B));
 
  555      Tpetra::MatrixMarket::Writer<::Tpetra::CrsMatrix<Scalar> >::writeDenseFile(filenameRHS_+ 
"." + label_ + 
"." + std::to_string(counter_), *tmv, 
"", 
"");
 
  556    } 
catch (
const std::logic_error&) {
 
  557      *out << 
"Warning: Cannot write RHS multivector to file.\n";
 
  567  bool ret = lp_->setProblem( rcpFromPtr(X), rcpFromRef(B) );
 
  568  TEUCHOS_TEST_FOR_EXCEPTION(
 
  569    ret == 
false, CatastrophicSolveFailure
 
  570    ,
"Error, the Belos::LinearProblem could not be set for the current solve!" 
  578  const RCP<ParameterList> tmpPL = Teuchos::parameterList();
 
  581  RCP<const ParameterList> validPL = iterativeSolver_->getValidParameters();
 
  583  SolveMeasureType solveMeasureType;
 
  584  RCP<GeneralSolveCriteriaBelosStatusTest<Scalar> > generalSolveCriteriaBelosStatusTest;
 
  585  if (nonnull(solveCriteria)) {
 
  586    solveMeasureType = solveCriteria->solveMeasureType;
 
  587    const ScalarMag requestedTol = solveCriteria->requestedTol;
 
  588    if (solveMeasureType.useDefault()) {
 
  589      tmpPL->set(
"Convergence Tolerance", defaultTol_);
 
  591    else if (solveMeasureType(SOLVE_MEASURE_NORM_RESIDUAL, SOLVE_MEASURE_NORM_RHS)) {
 
  592      if (requestedTol != SolveCriteria<Scalar>::unspecifiedTolerance()) {
 
  593        tmpPL->set(
"Convergence Tolerance", requestedTol);
 
  596        tmpPL->set(
"Convergence Tolerance", defaultTol_);
 
  598      setResidualScalingType (tmpPL, validPL, 
"Norm of RHS");
 
  600    else if (solveMeasureType(SOLVE_MEASURE_NORM_RESIDUAL, SOLVE_MEASURE_NORM_INIT_RESIDUAL)) {
 
  601      if (requestedTol != SolveCriteria<Scalar>::unspecifiedTolerance()) {
 
  602        tmpPL->set(
"Convergence Tolerance", requestedTol);
 
  605        tmpPL->set(
"Convergence Tolerance", defaultTol_);
 
  607      setResidualScalingType (tmpPL, validPL, 
"Norm of Initial Residual");
 
  611      generalSolveCriteriaBelosStatusTest = createGeneralSolveCriteriaBelosStatusTest(
 
  612        *solveCriteria, convergenceTestFrequency_);
 
  614      generalSolveCriteriaBelosStatusTest->setOStream(out);
 
  615      generalSolveCriteriaBelosStatusTest->setVerbLevel(incrVerbLevel(verbLevel, -1));
 
  618      tmpPL->set(
"Convergence Tolerance", 1.0);
 
  621    if (nonnull(solveCriteria->extraParameters)) {
 
  622      if (Teuchos::isParameterType<int>(*solveCriteria->extraParameters,
"Maximum Iterations")) {
 
  623        tmpPL->set(
"Maximum Iterations", Teuchos::get<int>(*solveCriteria->extraParameters,
"Maximum Iterations"));
 
  628    if (Teuchos::nonnull(lp_->getLeftPrec()) &&
 
  629        validPL->isParameter (
"Implicit Residual Scaling"))
 
  630      tmpPL->set(
"Implicit Residual Scaling",
 
  631                 "Norm of Preconditioned Initial Residual");
 
  635    tmpPL->set(
"Convergence Tolerance", defaultTol_);
 
  647      ( 
static_cast<int>(verbLevel) >= 
static_cast<int>(Teuchos::VERB_LOW)
 
  649        : rcp(
new FancyOStream(rcp(
new Teuchos::oblackholestream())))
 
  651    Teuchos::OSTab tab1(outUsed,1,
"BELOS");
 
  652    tmpPL->set(
"Output Stream", outUsed);
 
  653    iterativeSolver_->setParameters(tmpPL);
 
  654    if (nonnull(generalSolveCriteriaBelosStatusTest)) {
 
  655      iterativeSolver_->setUserConvStatusTest(generalSolveCriteriaBelosStatusTest);
 
  658      belosSolveStatus = iterativeSolver_->solve();
 
  661      TEUCHOS_TEST_FOR_EXCEPTION( 
true,
 
  662                                  CatastrophicSolveFailure,
 
  673  SolveStatus<Scalar> solveStatus;
 
  675  switch (belosSolveStatus) {
 
  677      solveStatus.solveStatus = SOLVE_STATUS_UNCONVERGED;
 
  688        solveStatus.achievedTol = iterativeSolver_->achievedTol();
 
  689      } 
catch (std::runtime_error&) {
 
  695      solveStatus.solveStatus = SOLVE_STATUS_CONVERGED;
 
  696      if (nonnull(generalSolveCriteriaBelosStatusTest)) {
 
  701        const ArrayView<const ScalarMag> achievedTol =
 
  702          generalSolveCriteriaBelosStatusTest->achievedTol();
 
  703        solveStatus.achievedTol = Teuchos::ScalarTraits<ScalarMag>::zero();
 
  704        for (Ordinal i = 0; i < achievedTol.size(); ++i) {
 
  705          solveStatus.achievedTol = std::max(solveStatus.achievedTol, achievedTol[i]);
 
  712          solveStatus.achievedTol = iterativeSolver_->achievedTol();
 
  713        } 
catch (std::runtime_error&) {
 
  716          solveStatus.achievedTol = tmpPL->get(
"Convergence Tolerance", defaultTol_);
 
  721    TEUCHOS_SWITCH_DEFAULT_DEBUG_ASSERT();
 
  724  std::ostringstream ossmessage;
 
  726    << 
"The Belos solver " << (label_ != 
"" ? (
"\"" + label_  + 
"\" ") : 
"")
 
  727    << 
"of type \""<<iterativeSolver_->description()
 
  728    <<
"\" returned a solve status of \""<< toString(solveStatus.solveStatus) << 
"\"" 
  729    << 
" in " << iterativeSolver_->getNumIters() << 
" iterations" 
  730    << 
" with total CPU time of " << totalTimer.totalElapsedTime() << 
" sec" ;
 
  731  if (out.get() && 
static_cast<int>(verbLevel) > 
static_cast<int>(Teuchos::VERB_LOW))
 
  732    *out << 
"\n" << ossmessage.str() << 
"\n";
 
  734  solveStatus.message = ossmessage.str();
 
  739  if (solveStatus.extraParameters.is_null()) {
 
  740    solveStatus.extraParameters = parameterList ();
 
  742  solveStatus.extraParameters->set (
"Belos/Iteration Count",
 
  743                                    iterativeSolver_->getNumIters());\
 
  745  solveStatus.extraParameters->set (
"Iteration Count",
 
  746                                    iterativeSolver_->getNumIters());\
 
  753  solveStatus.extraParameters->set (
"Belos/Achieved Tolerance",
 
  754                                    solveStatus.achievedTol);