388 using Teuchos::tuple;
389 using Teuchos::setStringToIntegralParameter;
390Teuchos::ValidatorXMLConverterDB::addConverter(
391 Teuchos::DummyObjectGetter<
392 Teuchos::StringToIntegralParameterEntryValidator<EBelosSolverType>
394 Teuchos::DummyObjectGetter<Teuchos::StringToIntegralValidatorXMLConverter<
397 typedef MultiVectorBase<Scalar> MV_t;
398 typedef LinearOpBase<Scalar> LO_t;
399 static RCP<Teuchos::ParameterList> validParamList;
400 if(validParamList.get()==NULL) {
401 validParamList = Teuchos::rcp(
new Teuchos::ParameterList(
"BelosLinearOpWithSolveFactory"));
402 setStringToIntegralParameter<EBelosSolverType>(
404 "Type of linear solver algorithm to use.",
407 "Pseudo Block GMRES",
410 "Pseudo Block Stochastic CG",
418 "TPETRA GMRES PIPELINE",
419 "TPETRA GMRES SINGLE REDUCE",
420 "TPETRA GMRES S-STEP"
423 "Block GMRES solver for nonsymmetric linear systems. It can also solve "
424 "single right-hand side systems, and can also perform Flexible GMRES "
425 "(where the preconditioner may change at every iteration, for example "
426 "for inner-outer iterations), by setting options in the \"Block GMRES\" "
429 "GMRES solver for nonsymmetric linear systems, that performs single "
430 "right-hand side solves on multiple right-hand sides at once. It "
431 "exploits operator multivector multiplication in order to amortize "
432 "global communication costs. Individual linear systems are deflated "
433 "out as they are solved.",
435 "Block CG solver for symmetric (Hermitian in complex arithmetic) "
436 "positive definite linear systems. It can also solve single "
437 "right-hand-side systems.",
439 "CG solver that performs single right-hand side CG on multiple right-hand "
440 "sides at once. It exploits operator multivector multiplication in order "
441 "to amortize global communication costs. Individual linear systems are "
442 "deflated out as they are solved.",
444 "stochastic CG solver that performs single right-hand side CG on multiple right-hand "
445 "sides at once. It exploits operator multivector multiplication in order "
446 "to amortize global communication costs. Individual linear systems are "
447 "deflated out as they are solved. [EXPERIMENTAL]",
449 "Variant of GMRES that performs subspace recycling to accelerate "
450 "convergence for sequences of solves with related linear systems. "
451 "Individual linear systems are deflated out as they are solved. "
452 "The current implementation only supports real-valued Scalar types.",
454 "CG solver for symmetric (Hermitian in complex arithmetic) positive "
455 "definite linear systems, that performs subspace recycling to "
456 "accelerate convergence for sequences of related linear systems.",
458 "MINRES solver for symmetric indefinite linear systems. It performs "
459 "single-right-hand-side solves on multiple right-hand sides sequentially.",
461 "TFQMR (Transpose-Free QMR) solver for nonsymmetric linear systems.",
463 "BiCGStab solver for nonsymmetric linear systems.",
465 "Fixed point iteration",
467 "Native Tpetra implementation of GMRES",
469 "Native Tpetra implementation of pipeline GMRES",
471 "Native Tpetra implementation of single-reduce GMRES",
473 "Native Tpetra implementation of s-step GMRES"
475 tuple<EBelosSolverType>(
495 "Number of linear solver iterations to skip between applying"
496 " user-defined convergence test.");
498 LeftPreconditionerIfUnspecified_name,
false,
499 "If the preconditioner does not specify if it is left or right, and this\n"
500 "option is set to true, put the preconditioner on the left side.\n"
501 "Historically, preconditioning is on the right. Some solvers may not\n"
502 "support left preconditioning.");
503 Teuchos::ParameterList
506 const bool lapackSupportsScalar = Belos::Details::LapackSupportsScalar<Scalar>::value;
507 const bool scalarIsReal = !Teuchos::ScalarTraits<Scalar>::isComplex;
510 Belos::BlockGmresSolMgr<Scalar,MV_t,LO_t> mgr;
512 *mgr.getValidParameters()
516 Belos::PseudoBlockGmresSolMgr<Scalar,MV_t,LO_t> mgr;
518 *mgr.getValidParameters()
521 if (lapackSupportsScalar) {
522 Belos::BlockCGSolMgr<Scalar,MV_t,LO_t> mgr;
524 *mgr.getValidParameters()
527 if (lapackSupportsScalar) {
528 Belos::PseudoBlockCGSolMgr<Scalar,MV_t,LO_t> mgr;
530 *mgr.getValidParameters()
534 Belos::PseudoBlockStochasticCGSolMgr<Scalar,MV_t,LO_t> mgr;
536 *mgr.getValidParameters()
539 if (lapackSupportsScalar) {
540 Belos::GCRODRSolMgr<Scalar,MV_t,LO_t> mgr;
542 *mgr.getValidParameters()
545 if (lapackSupportsScalar && scalarIsReal) {
546 Belos::RCGSolMgr<Scalar,MV_t,LO_t> mgr;
547 solverTypesSL.sublist(
RCG_name).setParameters(
548 *mgr.getValidParameters()
552 Belos::MinresSolMgr<Scalar,MV_t,LO_t> mgr;
554 *mgr.getValidParameters()
558 Belos::TFQMRSolMgr<Scalar,MV_t,LO_t> mgr;
559 solverTypesSL.sublist(
TFQMR_name).setParameters(
560 *mgr.getValidParameters()
564 Belos::BiCGStabSolMgr<Scalar,MV_t,LO_t> mgr;
566 *mgr.getValidParameters()
570 Belos::FixedPointSolMgr<Scalar,MV_t,LO_t> mgr;
572 *mgr.getValidParameters()
600 return validParamList;
616 const RCP<
const LinearOpSourceBase<Scalar> > &fwdOpSrc,
617 const RCP<
const LinearOpSourceBase<Scalar> > &approxFwdOpSrc,
618 const RCP<
const PreconditionerBase<Scalar> > &prec_in,
619 const bool reusePrec,
620 LinearOpWithSolveBase<Scalar> *Op,
621 const ESupportSolveUse supportSolveUse
626 using Teuchos::set_extra_data;
627 typedef Teuchos::ScalarTraits<Scalar>
ST;
628 typedef MultiVectorBase<Scalar> MV_t;
629 typedef LinearOpBase<Scalar> LO_t;
631 const RCP<Teuchos::FancyOStream> out = this->getOStream();
632 const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
633 Teuchos::OSTab tab(out);
634 if(out.get() &&
static_cast<int>(verbLevel) >
static_cast<int>(Teuchos::VERB_LOW))
635 *out <<
"\nEntering Thyra::BelosLinearOpWithSolveFactory<"<<ST::name()<<
">::initializeOpImpl(...) ...\n";
642 TEUCHOS_TEST_FOR_EXCEPT(Op==NULL);
643 TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc.get()==NULL);
644 TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc->getOp().get()==NULL);
645 RCP<const LinearOpBase<Scalar> >
646 fwdOp = fwdOpSrc->getOp(),
647 approxFwdOp = ( approxFwdOpSrc.get() ? approxFwdOpSrc->getOp() : Teuchos::null );
654 *belosOp = &Teuchos::dyn_cast<BelosLinearOpWithSolve<Scalar> >(*Op);
660 RCP<PreconditionerBase<Scalar> > myPrec = Teuchos::null;
661 RCP<const PreconditionerBase<Scalar> > prec = Teuchos::null;
671 ? Teuchos::rcp_const_cast<PreconditionerBase<Scalar> >(belosOp->
extract_prec())
674 bool hasExistingPrec =
false;
676 hasExistingPrec =
true;
681 hasExistingPrec =
false;
684 if( hasExistingPrec && reusePrec ) {
689 if(approxFwdOp.get())
702 bool oldIsExternalPrec =
false;
703 RCP<Belos::LinearProblem<Scalar,MV_t,LO_t> > oldLP = Teuchos::null;
704 RCP<Belos::SolverManager<Scalar,MV_t,LO_t> > oldIterSolver = Teuchos::null;
705 RCP<const LinearOpSourceBase<Scalar> > oldFwdOpSrc = Teuchos::null;
706 RCP<const LinearOpSourceBase<Scalar> > oldApproxFwdOpSrc = Teuchos::null;
707 ESupportSolveUse oldSupportSolveUse = SUPPORT_SOLVE_UNSPECIFIED;
709 belosOp->
uninitialize( &oldLP, NULL, &oldIterSolver, &oldFwdOpSrc,
710 NULL, &oldIsExternalPrec, &oldApproxFwdOpSrc, &oldSupportSolveUse );
717 typedef Belos::LinearProblem<Scalar,MV_t,LO_t> LP_t;
719 if (oldLP != Teuchos::null) {
723 lp = rcp(
new LP_t());
730 lp->setOperator(fwdOp);
737 RCP<const LinearOpBase<Scalar> > unspecified = prec->getUnspecifiedPrecOp();
738 RCP<const LinearOpBase<Scalar> > left = prec->getLeftPrecOp();
739 RCP<const LinearOpBase<Scalar> > right = prec->getRightPrecOp();
740 TEUCHOS_TEST_FOR_EXCEPTION(
741 !( left.get() || right.get() || unspecified.get() ), std::logic_error
742 ,
"Error, at least one preconditoner linear operator objects must be set!"
744 if (nonnull(unspecified)) {
745 if (
paramList_->get<
bool>(LeftPreconditionerIfUnspecified_name,
false))
746 lp->setLeftPrec(unspecified);
748 lp->setRightPrec(unspecified);
750 else if (nonnull(left)) {
751 lp->setLeftPrec(left);
753 else if (nonnull(right)) {
754 lp->setRightPrec(right);
758 TEUCHOS_TEST_FOR_EXCEPTION(
759 nonnull(left) && nonnull(right),std::logic_error
760 ,
"Error, we can not currently handle split preconditioners!"
765 set_extra_data<RCP<PreconditionerBase<Scalar> > >(myPrec,
"Belos::InternalPrec",
766 Teuchos::inOutArg(lp), Teuchos::POST_DESTROY,
false);
768 else if(prec.get()) {
769 set_extra_data<RCP<const PreconditionerBase<Scalar> > >(prec,
"Belos::ExternalPrec",
770 Teuchos::inOutArg(lp), Teuchos::POST_DESTROY,
false);
777 typedef Belos::SolverManager<Scalar,MV_t,LO_t> IterativeSolver_t;
778 RCP<IterativeSolver_t> iterativeSolver = Teuchos::null;
779 RCP<Teuchos::ParameterList> solverPL = Teuchos::rcp(
new Teuchos::ParameterList() );
787 Teuchos::ParameterList &gmresPL = solverTypesPL.sublist(
BlockGMRES_name);
788 solverPL = Teuchos::rcp( &gmresPL,
false );
791 if (oldIterSolver != Teuchos::null) {
792 iterativeSolver = oldIterSolver;
793 iterativeSolver->setProblem( lp );
794 iterativeSolver->setParameters( solverPL );
797 iterativeSolver = rcp(
new Belos::BlockGmresSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
807 solverPL = Teuchos::rcp( &pbgmresPL,
false );
812 if (oldIterSolver != Teuchos::null) {
813 iterativeSolver = oldIterSolver;
814 iterativeSolver->setProblem( lp );
815 iterativeSolver->setParameters( solverPL );
818 iterativeSolver = rcp(
new Belos::PseudoBlockGmresSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
827 Teuchos::ParameterList &cgPL = solverTypesPL.sublist(
BlockCG_name);
828 solverPL = Teuchos::rcp( &cgPL,
false );
831 if (oldIterSolver != Teuchos::null) {
832 iterativeSolver = oldIterSolver;
833 iterativeSolver->setProblem( lp );
834 iterativeSolver->setParameters( solverPL );
837 iterativeSolver = rcp(
new Belos::BlockCGSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
847 solverPL = Teuchos::rcp( &pbcgPL,
false );
852 if (oldIterSolver != Teuchos::null) {
853 iterativeSolver = oldIterSolver;
854 iterativeSolver->setProblem( lp );
855 iterativeSolver->setParameters( solverPL );
858 iterativeSolver = rcp(
new Belos::PseudoBlockCGSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
868 solverPL = Teuchos::rcp( &pbcgPL,
false );
873 if (oldIterSolver != Teuchos::null) {
874 iterativeSolver = oldIterSolver;
875 iterativeSolver->setProblem( lp );
876 iterativeSolver->setParameters( solverPL );
879 iterativeSolver = rcp(
new Belos::PseudoBlockStochasticCGSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
888 Teuchos::ParameterList &gcrodrPL = solverTypesPL.sublist(
GCRODR_name);
889 solverPL = Teuchos::rcp( &gcrodrPL,
false );
892 if (oldIterSolver != Teuchos::null) {
893 iterativeSolver = oldIterSolver;
894 iterativeSolver->setProblem( lp );
895 iterativeSolver->setParameters( solverPL );
898 iterativeSolver = rcp(
new Belos::GCRODRSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
907 Teuchos::ParameterList &rcgPL = solverTypesPL.sublist(
RCG_name);
908 solverPL = Teuchos::rcp( &rcgPL,
false );
911 if (oldIterSolver != Teuchos::null) {
912 iterativeSolver = oldIterSolver;
913 iterativeSolver->setProblem( lp );
914 iterativeSolver->setParameters( solverPL );
917 iterativeSolver = rcp(
new Belos::RCGSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
926 Teuchos::ParameterList &minresPL = solverTypesPL.sublist(
MINRES_name);
927 solverPL = Teuchos::rcp( &minresPL,
false );
930 if (oldIterSolver != Teuchos::null) {
931 iterativeSolver = oldIterSolver;
932 iterativeSolver->setProblem( lp );
933 iterativeSolver->setParameters( solverPL );
936 iterativeSolver = rcp(
new Belos::MinresSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
945 Teuchos::ParameterList &minresPL = solverTypesPL.sublist(
TFQMR_name);
946 solverPL = Teuchos::rcp( &minresPL,
false );
949 if (oldIterSolver != Teuchos::null) {
950 iterativeSolver = oldIterSolver;
951 iterativeSolver->setProblem( lp );
952 iterativeSolver->setParameters( solverPL );
955 iterativeSolver = rcp(
new Belos::TFQMRSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
964 Teuchos::ParameterList &bicgstabPL = solverTypesPL.sublist(
BiCGStab_name);
965 solverPL = Teuchos::rcp( &bicgstabPL,
false );
968 if (oldIterSolver != Teuchos::null) {
969 iterativeSolver = oldIterSolver;
970 iterativeSolver->setProblem( lp );
971 iterativeSolver->setParameters( solverPL );
974 iterativeSolver = rcp(
new Belos::BiCGStabSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
983 Teuchos::ParameterList &fixedPointPL = solverTypesPL.sublist(
FixedPoint_name);
984 solverPL = Teuchos::rcp( &fixedPointPL,
false );
987 if (oldIterSolver != Teuchos::null) {
988 iterativeSolver = oldIterSolver;
989 iterativeSolver->setProblem( lp );
990 iterativeSolver->setParameters( solverPL );
993 iterativeSolver = rcp(
new Belos::FixedPointSolMgr<Scalar,MV_t,LO_t>(lp,solverPL));
1002 Teuchos::ParameterList &tpetraGmresPL = solverTypesPL.sublist(
TpetraGmres_name);
1003 solverPL = Teuchos::rcp( &tpetraGmresPL,
false );
1008 iterativeSolver->setProblem( lp );
1009 iterativeSolver->setParameters( solverPL );
1018 solverPL = Teuchos::rcp( &tpetraGmresPipelinePL,
false );
1023 iterativeSolver->setProblem( lp );
1024 iterativeSolver->setParameters( solverPL );
1033 solverPL = Teuchos::rcp( &tpetraGmresSingleReducePL,
false );
1038 iterativeSolver->setProblem( lp );
1039 iterativeSolver->setParameters( solverPL );
1048 solverPL = Teuchos::rcp( &tpetraGmresSstepPL,
false );
1053 iterativeSolver->setProblem( lp );
1054 iterativeSolver->setParameters( solverPL );
1060 TEUCHOS_TEST_FOR_EXCEPT(
true);
1069 lp, solverPL, iterativeSolver,
1070 fwdOpSrc, prec, myPrec.get()==NULL, approxFwdOpSrc,
1073 belosOp->setOStream(out);
1074 belosOp->setVerbLevel(verbLevel);
1081 if(out.get() &&
static_cast<int>(verbLevel) >
static_cast<int>(Teuchos::VERB_LOW))
1082 *out <<
"\nLeaving Thyra::BelosLinearOpWithSolveFactory<"<<ST::name()<<
">::initializeOpImpl(...) ...\n";