386 using Teuchos::tuple;
387 using Teuchos::setStringToIntegralParameter;
388Teuchos::ValidatorXMLConverterDB::addConverter(
389 Teuchos::DummyObjectGetter<
390 Teuchos::StringToIntegralParameterEntryValidator<EBelosSolverType>
392 Teuchos::DummyObjectGetter<Teuchos::StringToIntegralValidatorXMLConverter<
395 typedef MultiVectorBase<Scalar> MV_t;
396 typedef LinearOpBase<Scalar> LO_t;
397 static RCP<Teuchos::ParameterList> validParamList;
398 if(validParamList.get()==NULL) {
399 validParamList = Teuchos::rcp(
new Teuchos::ParameterList(
"BelosLinearOpWithSolveFactory"));
400 setStringToIntegralParameter<EBelosSolverType>(
402 "Type of linear solver algorithm to use.",
405 "Pseudo Block GMRES",
408 "Pseudo Block Stochastic CG",
416 "TPETRA GMRES PIPELINE",
417 "TPETRA GMRES SINGLE REDUCE",
418 "TPETRA GMRES S-STEP"
421 "Block GMRES solver for nonsymmetric linear systems. It can also solve "
422 "single right-hand side systems, and can also perform Flexible GMRES "
423 "(where the preconditioner may change at every iteration, for example "
424 "for inner-outer iterations), by setting options in the \"Block GMRES\" "
427 "GMRES solver for nonsymmetric linear systems, that performs single "
428 "right-hand side solves on multiple right-hand sides at once. It "
429 "exploits operator multivector multiplication in order to amortize "
430 "global communication costs. Individual linear systems are deflated "
431 "out as they are solved.",
433 "Block CG solver for symmetric (Hermitian in complex arithmetic) "
434 "positive definite linear systems. It can also solve single "
435 "right-hand-side systems.",
437 "CG solver that performs single right-hand side CG on multiple right-hand "
438 "sides at once. It exploits operator multivector multiplication in order "
439 "to amortize global communication costs. Individual linear systems are "
440 "deflated out as they are solved.",
442 "stochastic CG solver that performs single right-hand side CG on multiple right-hand "
443 "sides at once. It exploits operator multivector multiplication in order "
444 "to amortize global communication costs. Individual linear systems are "
445 "deflated out as they are solved. [EXPERIMENTAL]",
447 "Variant of GMRES that performs subspace recycling to accelerate "
448 "convergence for sequences of solves with related linear systems. "
449 "Individual linear systems are deflated out as they are solved. "
450 "The current implementation only supports real-valued Scalar types.",
452 "CG solver for symmetric (Hermitian in complex arithmetic) positive "
453 "definite linear systems, that performs subspace recycling to "
454 "accelerate convergence for sequences of related linear systems.",
456 "MINRES solver for symmetric indefinite linear systems. It performs "
457 "single-right-hand-side solves on multiple right-hand sides sequentially.",
459 "TFQMR (Transpose-Free QMR) solver for nonsymmetric linear systems.",
461 "BiCGStab solver for nonsymmetric linear systems.",
463 "Fixed point iteration",
465 "Native Tpetra implementation of GMRES",
467 "Native Tpetra implementation of pipeline GMRES",
469 "Native Tpetra implementation of single-reduce GMRES",
471 "Native Tpetra implementation of s-step GMRES"
473 tuple<EBelosSolverType>(
493 "Number of linear solver iterations to skip between applying"
494 " user-defined convergence test.");
496 LeftPreconditionerIfUnspecified_name,
false,
497 "If the preconditioner does not specify if it is left or right, and this\n"
498 "option is set to true, put the preconditioner on the left side.\n"
499 "Historically, preconditioning is on the right. Some solvers may not\n"
500 "support left preconditioning.");
501 Teuchos::ParameterList
504 const bool lapackSupportsScalar = Belos::Details::LapackSupportsScalar<Scalar>::value;
505 const bool scalarIsReal = !Teuchos::ScalarTraits<Scalar>::isComplex;
508 Belos::BlockGmresSolMgr<Scalar,MV_t,LO_t> mgr;
510 *mgr.getValidParameters()
514 Belos::PseudoBlockGmresSolMgr<Scalar,MV_t,LO_t> mgr;
516 *mgr.getValidParameters()
519 if (lapackSupportsScalar) {
520 Belos::BlockCGSolMgr<Scalar,MV_t,LO_t> mgr;
522 *mgr.getValidParameters()
525 if (lapackSupportsScalar) {
526 Belos::PseudoBlockCGSolMgr<Scalar,MV_t,LO_t> mgr;
528 *mgr.getValidParameters()
532 Belos::PseudoBlockStochasticCGSolMgr<Scalar,MV_t,LO_t> mgr;
534 *mgr.getValidParameters()
537 if (lapackSupportsScalar) {
538 Belos::GCRODRSolMgr<Scalar,MV_t,LO_t> mgr;
540 *mgr.getValidParameters()
543 if (lapackSupportsScalar && scalarIsReal) {
544 Belos::RCGSolMgr<Scalar,MV_t,LO_t> mgr;
545 solverTypesSL.sublist(
RCG_name).setParameters(
546 *mgr.getValidParameters()
550 Belos::MinresSolMgr<Scalar,MV_t,LO_t> mgr;
552 *mgr.getValidParameters()
556 Belos::TFQMRSolMgr<Scalar,MV_t,LO_t> mgr;
557 solverTypesSL.sublist(
TFQMR_name).setParameters(
558 *mgr.getValidParameters()
562 Belos::BiCGStabSolMgr<Scalar,MV_t,LO_t> mgr;
564 *mgr.getValidParameters()
568 Belos::FixedPointSolMgr<Scalar,MV_t,LO_t> mgr;
570 *mgr.getValidParameters()
598 return validParamList;
614 const RCP<
const LinearOpSourceBase<Scalar> > &fwdOpSrc,
615 const RCP<
const LinearOpSourceBase<Scalar> > &approxFwdOpSrc,
616 const RCP<
const PreconditionerBase<Scalar> > &prec_in,
617 const bool reusePrec,
618 LinearOpWithSolveBase<Scalar> *Op,
619 const ESupportSolveUse supportSolveUse
624 using Teuchos::set_extra_data;
625 typedef Teuchos::ScalarTraits<Scalar>
ST;
626 typedef MultiVectorBase<Scalar> MV_t;
627 typedef LinearOpBase<Scalar> LO_t;
629 const RCP<Teuchos::FancyOStream> out = this->getOStream();
630 const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
631 Teuchos::OSTab tab(out);
632 if(out.get() &&
static_cast<int>(verbLevel) >
static_cast<int>(Teuchos::VERB_LOW))
633 *out <<
"\nEntering Thyra::BelosLinearOpWithSolveFactory<"<<ST::name()<<
">::initializeOpImpl(...) ...\n";
640 TEUCHOS_TEST_FOR_EXCEPT(Op==NULL);
641 TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc.get()==NULL);
642 TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc->getOp().get()==NULL);
643 RCP<const LinearOpBase<Scalar> >
644 fwdOp = fwdOpSrc->getOp(),
645 approxFwdOp = ( approxFwdOpSrc.get() ? approxFwdOpSrc->getOp() : Teuchos::null );
652 *belosOp = &Teuchos::dyn_cast<BelosLinearOpWithSolve<Scalar> >(*Op);
658 RCP<PreconditionerBase<Scalar> > myPrec = Teuchos::null;
659 RCP<const PreconditionerBase<Scalar> > prec = Teuchos::null;
669 ? Teuchos::rcp_const_cast<PreconditionerBase<Scalar> >(belosOp->
extract_prec())
672 bool hasExistingPrec =
false;
674 hasExistingPrec =
true;
679 hasExistingPrec =
false;
682 if( hasExistingPrec && reusePrec ) {
687 if(approxFwdOp.get())
700 bool oldIsExternalPrec =
false;
701 RCP<Belos::LinearProblem<Scalar,MV_t,LO_t> > oldLP = Teuchos::null;
702 RCP<Belos::SolverManager<Scalar,MV_t,LO_t> > oldIterSolver = Teuchos::null;
703 RCP<const LinearOpSourceBase<Scalar> > oldFwdOpSrc = Teuchos::null;
704 RCP<const LinearOpSourceBase<Scalar> > oldApproxFwdOpSrc = Teuchos::null;
705 ESupportSolveUse oldSupportSolveUse = SUPPORT_SOLVE_UNSPECIFIED;
707 belosOp->
uninitialize( &oldLP, NULL, &oldIterSolver, &oldFwdOpSrc,
708 NULL, &oldIsExternalPrec, &oldApproxFwdOpSrc, &oldSupportSolveUse );
715 typedef Belos::LinearProblem<Scalar,MV_t,LO_t> LP_t;
717 if (oldLP != Teuchos::null) {
721 lp = rcp(
new LP_t());
728 lp->setOperator(fwdOp);
735 RCP<const LinearOpBase<Scalar> > unspecified = prec->getUnspecifiedPrecOp();
736 RCP<const LinearOpBase<Scalar> > left = prec->getLeftPrecOp();
737 RCP<const LinearOpBase<Scalar> > right = prec->getRightPrecOp();
738 TEUCHOS_TEST_FOR_EXCEPTION(
739 !( left.get() || right.get() || unspecified.get() ), std::logic_error
740 ,
"Error, at least one preconditoner linear operator objects must be set!"
742 if (nonnull(unspecified)) {
743 if (
paramList_->get<
bool>(LeftPreconditionerIfUnspecified_name,
false))
744 lp->setLeftPrec(unspecified);
746 lp->setRightPrec(unspecified);
748 else if (nonnull(left)) {
749 lp->setLeftPrec(left);
751 else if (nonnull(right)) {
752 lp->setRightPrec(right);
756 TEUCHOS_TEST_FOR_EXCEPTION(
757 nonnull(left) && nonnull(right),std::logic_error
758 ,
"Error, we can not currently handle split preconditioners!"
763 set_extra_data<RCP<PreconditionerBase<Scalar> > >(myPrec,
"Belos::InternalPrec",
764 Teuchos::inOutArg(lp), Teuchos::POST_DESTROY,
false);
766 else if(prec.get()) {
767 set_extra_data<RCP<const PreconditionerBase<Scalar> > >(prec,
"Belos::ExternalPrec",
768 Teuchos::inOutArg(lp), Teuchos::POST_DESTROY,
false);
775 typedef Belos::SolverManager<Scalar,MV_t,LO_t> IterativeSolver_t;
776 RCP<IterativeSolver_t> iterativeSolver = Teuchos::null;
777 RCP<Teuchos::ParameterList> solverPL = Teuchos::rcp(
new Teuchos::ParameterList() );
785 Teuchos::ParameterList &gmresPL = solverTypesPL.sublist(
BlockGMRES_name);
786 solverPL = Teuchos::rcp( &gmresPL,
false );
789 if (oldIterSolver != Teuchos::null) {
790 iterativeSolver = oldIterSolver;
791 iterativeSolver->setProblem( lp );
792 iterativeSolver->setParameters( solverPL );
795 iterativeSolver = rcp(
new Belos::BlockGmresSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
805 solverPL = Teuchos::rcp( &pbgmresPL,
false );
810 if (oldIterSolver != Teuchos::null) {
811 iterativeSolver = oldIterSolver;
812 iterativeSolver->setProblem( lp );
813 iterativeSolver->setParameters( solverPL );
816 iterativeSolver = rcp(
new Belos::PseudoBlockGmresSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
825 Teuchos::ParameterList &cgPL = solverTypesPL.sublist(
BlockCG_name);
826 solverPL = Teuchos::rcp( &cgPL,
false );
829 if (oldIterSolver != Teuchos::null) {
830 iterativeSolver = oldIterSolver;
831 iterativeSolver->setProblem( lp );
832 iterativeSolver->setParameters( solverPL );
835 iterativeSolver = rcp(
new Belos::BlockCGSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
845 solverPL = Teuchos::rcp( &pbcgPL,
false );
850 if (oldIterSolver != Teuchos::null) {
851 iterativeSolver = oldIterSolver;
852 iterativeSolver->setProblem( lp );
853 iterativeSolver->setParameters( solverPL );
856 iterativeSolver = rcp(
new Belos::PseudoBlockCGSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
866 solverPL = Teuchos::rcp( &pbcgPL,
false );
871 if (oldIterSolver != Teuchos::null) {
872 iterativeSolver = oldIterSolver;
873 iterativeSolver->setProblem( lp );
874 iterativeSolver->setParameters( solverPL );
877 iterativeSolver = rcp(
new Belos::PseudoBlockStochasticCGSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
886 Teuchos::ParameterList &gcrodrPL = solverTypesPL.sublist(
GCRODR_name);
887 solverPL = Teuchos::rcp( &gcrodrPL,
false );
890 if (oldIterSolver != Teuchos::null) {
891 iterativeSolver = oldIterSolver;
892 iterativeSolver->setProblem( lp );
893 iterativeSolver->setParameters( solverPL );
896 iterativeSolver = rcp(
new Belos::GCRODRSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
905 Teuchos::ParameterList &rcgPL = solverTypesPL.sublist(
RCG_name);
906 solverPL = Teuchos::rcp( &rcgPL,
false );
909 if (oldIterSolver != Teuchos::null) {
910 iterativeSolver = oldIterSolver;
911 iterativeSolver->setProblem( lp );
912 iterativeSolver->setParameters( solverPL );
915 iterativeSolver = rcp(
new Belos::RCGSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
924 Teuchos::ParameterList &minresPL = solverTypesPL.sublist(
MINRES_name);
925 solverPL = Teuchos::rcp( &minresPL,
false );
928 if (oldIterSolver != Teuchos::null) {
929 iterativeSolver = oldIterSolver;
930 iterativeSolver->setProblem( lp );
931 iterativeSolver->setParameters( solverPL );
934 iterativeSolver = rcp(
new Belos::MinresSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
943 Teuchos::ParameterList &minresPL = solverTypesPL.sublist(
TFQMR_name);
944 solverPL = Teuchos::rcp( &minresPL,
false );
947 if (oldIterSolver != Teuchos::null) {
948 iterativeSolver = oldIterSolver;
949 iterativeSolver->setProblem( lp );
950 iterativeSolver->setParameters( solverPL );
953 iterativeSolver = rcp(
new Belos::TFQMRSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
962 Teuchos::ParameterList &bicgstabPL = solverTypesPL.sublist(
BiCGStab_name);
963 solverPL = Teuchos::rcp( &bicgstabPL,
false );
966 if (oldIterSolver != Teuchos::null) {
967 iterativeSolver = oldIterSolver;
968 iterativeSolver->setProblem( lp );
969 iterativeSolver->setParameters( solverPL );
972 iterativeSolver = rcp(
new Belos::BiCGStabSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
981 Teuchos::ParameterList &fixedPointPL = solverTypesPL.sublist(
FixedPoint_name);
982 solverPL = Teuchos::rcp( &fixedPointPL,
false );
985 if (oldIterSolver != Teuchos::null) {
986 iterativeSolver = oldIterSolver;
987 iterativeSolver->setProblem( lp );
988 iterativeSolver->setParameters( solverPL );
991 iterativeSolver = rcp(
new Belos::FixedPointSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
1000 Teuchos::ParameterList &tpetraGmresPL = solverTypesPL.sublist(
TpetraGmres_name);
1001 solverPL = Teuchos::rcp( &tpetraGmresPL,
false );
1006 iterativeSolver->setProblem( lp );
1007 iterativeSolver->setParameters( solverPL );
1016 solverPL = Teuchos::rcp( &tpetraGmresPipelinePL,
false );
1021 iterativeSolver->setProblem( lp );
1022 iterativeSolver->setParameters( solverPL );
1031 solverPL = Teuchos::rcp( &tpetraGmresSingleReducePL,
false );
1036 iterativeSolver->setProblem( lp );
1037 iterativeSolver->setParameters( solverPL );
1046 solverPL = Teuchos::rcp( &tpetraGmresSstepPL,
false );
1051 iterativeSolver->setProblem( lp );
1052 iterativeSolver->setParameters( solverPL );
1058 TEUCHOS_TEST_FOR_EXCEPT(
true);
1067 lp, solverPL, iterativeSolver,
1068 fwdOpSrc, prec, myPrec.get()==NULL, approxFwdOpSrc,
1071 belosOp->setOStream(out);
1072 belosOp->setVerbLevel(verbLevel);
1079 if(out.get() &&
static_cast<int>(verbLevel) >
static_cast<int>(Teuchos::VERB_LOW))
1080 *out <<
"\nLeaving Thyra::BelosLinearOpWithSolveFactory<"<<ST::name()<<
">::initializeOpImpl(...) ...\n";