46#include "Thyra_AztecOOLinearOpWithSolveFactory.hpp"
47#include "Thyra_AztecOOLinearOpWithSolve.hpp"
48#include "Thyra_PreconditionerFactoryHelpers.hpp"
49#include "Thyra_EpetraOperatorViewExtractorStd.hpp"
50#include "Thyra_ScaledAdjointLinearOpBase.hpp"
51#include "Thyra_EpetraLinearOpBase.hpp"
52#include "Thyra_EpetraOperatorWrapper.hpp"
54#include "Teuchos_VerboseObjectParameterListHelpers.hpp"
55#include "Teuchos_ParameterList.hpp"
56#include "Teuchos_dyn_cast.hpp"
57#include "AztecOOParameterList.hpp"
63const std::string AOOLOWSF_epetraPrecOp_str
64=
"AOOLOWSF::epetraPrecOp";
65const std::string AOOLOWSF_aztec_epetra_epetraFwdOp_str
66=
"AOOLOWSF::aztec_epetra_epetraFwdOp";
67const std::string AOOLOWSF_aztec_epetra_epetraAdjOp_str
68=
"AOOLOWSF::aztec_epetra_epetraAdjOp";
69const std::string AOOLOWSF_rowmatrix_epetraFwdOp_str
70=
"AOOLOWSF::rowmatrix_epetraFwdOp";
71const std::string AOOLOWSF_rowmatrix_epetraPrecOp_str
72=
"AOOLOWSF::rowmatrix_epetraPrecOp";
73const std::string AOOLOWSF_aztec_fwd_epetra_epetraPrecOp_str
74=
"AOOLOWSF::aztec_fwd_epetra_epetraPrecOp";
75const std::string AOOLOWSF_aztec_adj_epetra_epetraPrecOp_str
76=
"AOOLOWSF::aztec_adj_epetra_epetraPrecOp";
77const std::string AOOLOWSF_setPrecondtionerOperator_str
78=
"AOOLOWSF::setPrecondtionerOperator";
79const std::string AOOLOWSF_constructedAztecPreconditoner_str
80=
"AOOLOWSF::constructedAztecPreconditoner";
83const std::string ForwardSolve_name =
"Forward Solve";
84const std::string AdjointSolve_name =
"Adjoint Solve";
85const std::string MaxIterations_name =
"Max Iterations";
86const int MaxIterations_default = 400;
87const std::string Tolerance_name =
"Tolerance";
88const double Tolerance_default = 1e-6;
89const std::string OutputEveryRhs_name =
"Output Every RHS";
90const bool OutputEveryRhs_default =
false;
91const std::string AztecOO_Settings_name =
"AztecOO Settings";
104 Teuchos::RCP<Teuchos::ParameterList>
const& paramList
106 :epetraFwdOpViewExtractor_(
Teuchos::rcp(new EpetraOperatorViewExtractorStd()))
107 ,defaultFwdMaxIterations_(MaxIterations_default)
108 ,defaultFwdTolerance_(Tolerance_default)
109 ,defaultAdjMaxIterations_(MaxIterations_default)
110 ,defaultAdjTolerance_(Tolerance_default)
111 ,outputEveryRhs_(OutputEveryRhs_default)
112 ,useAztecPrec_(false)
114 updateThisValidParamList();
130 const Teuchos::RCP<PreconditionerFactoryBase<double> > &precFactory,
131 const std::string &precFactoryName
134 TEUCHOS_TEST_FOR_EXCEPT(!precFactory.get());
135 Teuchos::RCP<const Teuchos::ParameterList>
136 precFactoryValidPL = precFactory->getValidParameters();
137 const std::string _precFactoryName =
138 ( precFactoryName !=
""
140 : ( precFactoryValidPL.get()
141 ? precFactoryValidPL->name()
142 :
"GENERIC PRECONDITIONER FACTORY"
145 precFactory_ = precFactory;
146 precFactoryName_ = _precFactoryName;
147 updateThisValidParamList();
151Teuchos::RCP<PreconditionerFactoryBase<double> >
159 Teuchos::RCP<PreconditionerFactoryBase<double> > *precFactory,
160 std::string *precFactoryName
163 if(precFactory) *precFactory = precFactory_;
164 if(precFactoryName) *precFactoryName = precFactoryName_;
165 precFactory_ = Teuchos::null;
166 precFactoryName_ =
"";
167 updateThisValidParamList();
172 const LinearOpSourceBase<double> &fwdOpSrc
175 return epetraFwdOpViewExtractor_->isCompatible(*fwdOpSrc.getOp());
179Teuchos::RCP<LinearOpWithSolveBase<double> >
187 const Teuchos::RCP<
const LinearOpSourceBase<double> > &fwdOpSrc,
188 LinearOpWithSolveBase<double> *Op,
189 const ESupportSolveUse
192 this->initializeOp_impl(fwdOpSrc,Teuchos::null,Teuchos::null,
false,Op);
197 const Teuchos::RCP<
const LinearOpSourceBase<double> > &fwdOpSrc,
198 LinearOpWithSolveBase<double> *Op
201 this->initializeOp_impl(fwdOpSrc,Teuchos::null,Teuchos::null,
true,Op);
206 const EPreconditionerInputType precOpType
209 const_cast<bool&
>(useAztecPrec_) = (
212 paramList_->sublist(ForwardSolve_name).sublist(AztecOO_Settings_name).get(
213 "Aztec Preconditioner",
"none"
217 case PRECONDITIONER_INPUT_TYPE_AS_OPERATOR:
219 case PRECONDITIONER_INPUT_TYPE_AS_MATRIX:
220 return useAztecPrec_;
222 TEUCHOS_TEST_FOR_EXCEPT(
true);
224 TEUCHOS_UNREACHABLE_RETURN(PRECONDITIONER_INPUT_TYPE_AS_OPERATOR);
229 const Teuchos::RCP<
const LinearOpSourceBase<double> > &fwdOpSrc,
230 const Teuchos::RCP<
const PreconditionerBase<double> > &prec,
231 LinearOpWithSolveBase<double> *Op,
232 const ESupportSolveUse
235 TEUCHOS_TEST_FOR_EXCEPT(prec.get()==NULL);
236 this->initializeOp_impl(fwdOpSrc,prec,Teuchos::null,
false,Op);
241 const Teuchos::RCP<
const LinearOpSourceBase<double> > &fwdOpSrc,
242 const Teuchos::RCP<
const LinearOpSourceBase<double> > &approxFwdOpSrc,
243 LinearOpWithSolveBase<double> *Op,
244 const ESupportSolveUse
247 TEUCHOS_TEST_FOR_EXCEPT(approxFwdOpSrc.get()==NULL);
248 TEUCHOS_TEST_FOR_EXCEPT(approxFwdOpSrc->getOp().get()==NULL);
249 this->initializeOp_impl(fwdOpSrc,Teuchos::null,approxFwdOpSrc,
false,Op);
254 LinearOpWithSolveBase<double> *Op,
255 Teuchos::RCP<
const LinearOpSourceBase<double> > *fwdOpSrc,
256 Teuchos::RCP<
const PreconditionerBase<double> > *prec,
257 Teuchos::RCP<
const LinearOpSourceBase<double> > *approxFwdOpSrc,
262 TEUCHOS_TEST_FOR_EXCEPT(Op==NULL);
265 *aztecOp = &Teuchos::dyn_cast<AztecOOLinearOpWithSolve>(*Op);
267 Teuchos::RCP<const LinearOpSourceBase<double> >
268 _fwdOpSrc = aztecOp->extract_fwdOpSrc(),
269 _approxFwdOpSrc = aztecOp->extract_approxFwdOpSrc();
270 if(fwdOpSrc) *fwdOpSrc = _fwdOpSrc;
271 if(approxFwdOpSrc) *approxFwdOpSrc = _approxFwdOpSrc;
275 if(aztecOp->isExternalPrec()) {
276 Teuchos::RCP<const PreconditionerBase<double> >
277 _prec = aztecOp->extract_prec();
278 if(prec) *prec = _prec;
290 Teuchos::RCP<Teuchos::ParameterList>
const& paramList
293 TEUCHOS_TEST_FOR_EXCEPT(paramList.get()==NULL);
295 paramList_ = paramList;
297 outputEveryRhs_ = paramList_->get(OutputEveryRhs_name,OutputEveryRhs_default);
299 Teuchos::ParameterList
300 &fwdSolvePL = paramList_->sublist(ForwardSolve_name);
301 defaultFwdMaxIterations_ = fwdSolvePL.get(MaxIterations_name,defaultFwdMaxIterations_);
302 defaultFwdTolerance_ = fwdSolvePL.get(Tolerance_name,defaultFwdTolerance_);
304 if( !paramList_->getPtr<Teuchos::ParameterList>(AdjointSolve_name) ) {
306 paramList_->sublist(AdjointSolve_name).setParameters(fwdSolvePL);
308 Teuchos::ParameterList
309 &adjSolvePL = paramList_->sublist(AdjointSolve_name);
310 defaultAdjMaxIterations_ = adjSolvePL.get(MaxIterations_name,defaultAdjMaxIterations_);
311 defaultAdjTolerance_ = adjSolvePL.get(Tolerance_name,defaultAdjTolerance_);
313 if(precFactory_.get()) {
317 const bool nestedPFSublistExists = paramList_->isSublist(precFactoryName_);
318 const bool alreadyHasSublist = !is_null(precFactory_->getParameterList());
319 if( nestedPFSublistExists || !alreadyHasSublist ) {
320 precFactory_->setParameterList(Teuchos::sublist(paramList_,precFactoryName_));
323 Teuchos::readVerboseObjectSublist(&*paramList_,
this);
327Teuchos::RCP<Teuchos::ParameterList>
334Teuchos::RCP<Teuchos::ParameterList>
337 Teuchos::RCP<Teuchos::ParameterList> _paramList = paramList_;
338 paramList_ = Teuchos::null;
343Teuchos::RCP<const Teuchos::ParameterList>
350Teuchos::RCP<const Teuchos::ParameterList>
353 return thisValidParamList_;
362 std::ostringstream oss;
363 oss <<
"Thyra::AztecOOLinearOpWithSolveFactory{";
364 oss <<
"precFactory=";
365 if(!is_null(precFactory_))
366 oss << precFactory_->description();
377Teuchos::RCP<const Teuchos::ParameterList>
378AztecOOLinearOpWithSolveFactory::generateAndGetValidParameters()
380 static Teuchos::RCP<Teuchos::ParameterList> validParamList;
381 if(validParamList.get()==NULL) {
382 validParamList = Teuchos::rcp(
383 new Teuchos::ParameterList(
"AztecOOLinearOpWithSolveFactory"));
385 OutputEveryRhs_name,OutputEveryRhs_default
386 ,
"Determines if output is created for each individual RHS (true or 1) or if output\n"
387 "is just created for an entire set of RHSs (false or 0)."
389 static Teuchos::RCP<const Teuchos::ParameterList>
390 aztecParamList = getValidAztecOOParameters();
391 Teuchos::ParameterList
392 &fwdSolvePL = validParamList->sublist(
393 ForwardSolve_name,
false
394 ,
"Gives the options for the forward solve."
397 Tolerance_name,Tolerance_default
398 ,
"The tolerence used in the convergence check (see the convergence test\n"
399 "in the sublist \"" + AztecOO_Settings_name +
"\")"
402 MaxIterations_name,MaxIterations_default
403 ,
"The maximum number of iterations the AztecOO solver is allowed to perform."
406 AztecOO_Settings_name,
false
407 ,
"Sets the parameters on the AztecOO object itself."
408 ).setParameters(*aztecParamList);
409 Teuchos::ParameterList
410 &adjSolvePL = validParamList->sublist(
411 AdjointSolve_name,
false
412 ,
"The options for the adjoint solve.\n"
413 "If this sublist is missing then the parameters from the\n"
414 "\""+ForwardSolve_name+
"\" sublist are used instead."
417 adjSolvePL.setParameters(fwdSolvePL);
419 return validParamList;
423void AztecOOLinearOpWithSolveFactory::updateThisValidParamList()
425 thisValidParamList_ = Teuchos::rcp(
426 new Teuchos::ParameterList(*generateAndGetValidParameters())
428 if(precFactory_.get()) {
429 Teuchos::RCP<const Teuchos::ParameterList>
430 precFactoryValidParamList = precFactory_->getValidParameters();
431 if(precFactoryValidParamList.get()) {
432 thisValidParamList_->sublist(precFactoryName_).setParameters(
433 *precFactoryValidParamList);
436 Teuchos::setupVerboseObjectSublist(&*thisValidParamList_);
440void AztecOOLinearOpWithSolveFactory::initializeOp_impl(
441 const Teuchos::RCP<
const LinearOpSourceBase<double> > &fwdOpSrc,
442 const Teuchos::RCP<
const PreconditionerBase<double> > &prec,
443 const Teuchos::RCP<
const LinearOpSourceBase<double> > &approxFwdOpSrc,
444 const bool reusePrec,
445 LinearOpWithSolveBase<double> *Op
451 using Teuchos::rcp_dynamic_cast;
452 using Teuchos::rcp_const_cast;
453 using Teuchos::set_extra_data;
454 using Teuchos::get_optional_extra_data;
455 using Teuchos::get_optional_nonconst_extra_data;
456 using Teuchos::outArg;
459 const Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
460 const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
461 Teuchos::OSTab tab(out);
462 if(out.get() &&
static_cast<int>(verbLevel) >
static_cast<int>(Teuchos::VERB_LOW))
463 *out <<
"\nEntering Thyra::AztecOOLinearOpWithSolveFactory::initializeOp_impl(...) ...\n";
465 typedef Teuchos::VerboseObjectTempState<PreconditionerFactoryBase<double> > VOTSPF;
466 VOTSPF precFactoryOutputTempState(precFactory_,out,verbLevel);
469 TEUCHOS_TEST_FOR_EXCEPT(Op==NULL);
470 TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc.get()==NULL);
471 TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc->getOp().get()==NULL);
479 Teuchos::RCP<const LinearOpBase<double> >
480 tmpFwdOp = fwdOpSrc->getOp(),
481 tmpApproxFwdOp = ( approxFwdOpSrc.get() ? approxFwdOpSrc->getOp() : Teuchos::null );
482 Teuchos::RCP<const LinearOpBase<double> > fwdOp;
483 Teuchos::RCP<const LinearOpBase<double> > approxFwdOp;
484 if (
dynamic_cast<const EpetraLinearOpBase*
>(tmpFwdOp.get())!=0 )
487 approxFwdOp = tmpApproxFwdOp;
491 fwdOp = makeEpetraWrapper(tmpFwdOp);
495 dynamic_cast<const EpetraLinearOpBase*
>(&*tmpApproxFwdOp.get())
498 approxFwdOp = makeEpetraWrapper(tmpApproxFwdOp);
505 AztecOOLinearOpWithSolve
506 *aztecOp = &Teuchos::dyn_cast<AztecOOLinearOpWithSolve>(*Op);
511 Teuchos::RCP<const Epetra_Operator> epetra_epetraFwdOp;
512 EOpTransp epetra_epetraFwdOpTransp;
513 EApplyEpetraOpAs epetra_epetraFwdOpApplyAs;
514 EAdjointEpetraOp epetra_epetraFwdOpAdjointSupport;
515 double epetra_epetraFwdOpScalar;
516 epetraFwdOpViewExtractor_->getEpetraOpView(
518 outArg(epetra_epetraFwdOp), outArg(epetra_epetraFwdOpTransp),
519 outArg(epetra_epetraFwdOpApplyAs), outArg(epetra_epetraFwdOpAdjointSupport),
520 outArg(epetra_epetraFwdOpScalar)
522 TEUCHOS_TEST_FOR_EXCEPTION(
523 epetra_epetraFwdOp.get()==NULL, std::logic_error
524 ,
"Error, The input fwdOp object must be fully initialized "
525 "before calling this function!"
531 Teuchos::RCP<PreconditionerBase<double> > myPrec;
532 Teuchos::RCP<const PreconditionerBase<double> > precUsed;
537 else if (precFactory_.get() ) {
541 ( !aztecOp->isExternalPrec()
542 ? Teuchos::rcp_const_cast<PreconditionerBase<double> >(
543 aztecOp->extract_prec())
551 myPrec = precFactory_->createPrec();
553 precFactory_->initializePrec(fwdOpSrc,&*myPrec);
560 RCP<const LinearOpBase<double> > rightPrecOp;
561 if (precUsed.get()) {
562 RCP<const LinearOpBase<double> > unspecified = precUsed->getUnspecifiedPrecOp();
563 RCP<const LinearOpBase<double> > left = precUsed->getLeftPrecOp();
564 RCP<const LinearOpBase<double> > right = precUsed->getRightPrecOp();
565 TEUCHOS_TEST_FOR_EXCEPTION(
566 !( left.get() || right.get() || unspecified.get() ), std::logic_error
567 ,
"Error, at least one preconditoner linear operator objects must be set!"
569 if(unspecified.get()) {
570 rightPrecOp = unspecified;
574 TEUCHOS_TEST_FOR_EXCEPTION(
575 left.get(),std::logic_error
576 ,
"Error, we can not currently handle a left"
577 " preconditioner with the AztecOO/Thyra adapters!"
582 double wrappedPrecOpScalar = 0.0;
583 EOpTransp wrappedPrecOpTransp =
NOTRANS;
584 RCP<const LinearOpBase<double> > wrappedPrecOp = null;
585 RCP<const EpetraLinearOpBase> epetraPrecOp;
586 Teuchos::RCP<const Epetra_Operator> epetra_epetraPrecOp;
587 EOpTransp epetra_epetraPrecOpTransp;
588 EApplyEpetraOpAs epetra_epetraPrecOpApplyAs;
589 EAdjointEpetraOp epetra_epetraPrecOpAdjointSupport;
590 EOpTransp overall_epetra_epetraPrecOpTransp=
NOTRANS;
591 if(rightPrecOp.get()) {
592 RCP<const LinearOpBase<double> > tmpWrappedPrecOp;
594 rightPrecOp,&wrappedPrecOpScalar,&wrappedPrecOpTransp,&tmpWrappedPrecOp);
595 if(
dynamic_cast<const EpetraLinearOpBase*
>(&*tmpWrappedPrecOp) ) {
596 wrappedPrecOp = tmpWrappedPrecOp;
599 wrappedPrecOp = makeEpetraWrapper(tmpWrappedPrecOp);
601 epetraPrecOp = rcp_dynamic_cast<const EpetraLinearOpBase>(
603 epetraPrecOp->getEpetraOpView(
604 outArg(epetra_epetraPrecOp), outArg(epetra_epetraPrecOpTransp),
605 outArg(epetra_epetraPrecOpApplyAs), outArg(epetra_epetraPrecOpAdjointSupport));
606 TEUCHOS_TEST_FOR_EXCEPTION(
607 epetra_epetraPrecOp.get()==NULL,std::logic_error
608 ,
"Error, The input prec object and its embedded preconditioner"
609 " operator must be fully initialized before calling this function!"
618 overall_epetra_epetraPrecOpTransp
620 real_trans(wrappedPrecOpTransp),
621 real_trans(epetra_epetraPrecOpTransp)
629 if(approxFwdOp.get()) {
632 unwrap(approxFwdOp,&wrappedPrecOpScalar,&wrappedPrecOpTransp,&wrappedPrecOp);
633 epetraPrecOp = rcp_dynamic_cast<const EpetraLinearOpBase>(
635 epetraPrecOp->getEpetraOpView(
636 outArg(epetra_epetraPrecOp), outArg(epetra_epetraPrecOpTransp),
637 outArg(epetra_epetraPrecOpApplyAs), outArg(epetra_epetraPrecOpAdjointSupport)
639 TEUCHOS_TEST_FOR_EXCEPTION(
640 epetra_epetraPrecOp.get()==NULL,std::logic_error
641 ,
"Error, The input approxFwdOp object must be fully initialized"
642 " before calling this function!"
652 overall_epetra_epetraPrecOpTransp
654 real_trans(wrappedPrecOpTransp),
655 real_trans(epetra_epetraPrecOpTransp)
663 RCP<const Epetra_RowMatrix>
664 rowmatrix_epetraFwdOp = rcp_dynamic_cast<const Epetra_RowMatrix>(
666 rowmatrix_epetraPrecOp = rcp_dynamic_cast<const Epetra_RowMatrix>(
667 epetra_epetraPrecOp);
673 enum ELocalPrecType {
674 PT_NONE, PT_AZTEC_FROM_OP, PT_AZTEC_FROM_APPROX_FWD_MATRIX,
675 PT_FROM_PREC_OP, PT_UPPER_BOUND
677 ELocalPrecType localPrecType = PT_UPPER_BOUND;
678 if( precUsed.get()==NULL && approxFwdOp.get()==NULL && !useAztecPrec_ ) {
680 localPrecType = PT_NONE;
682 else if( precUsed.get()==NULL && approxFwdOp.get()==NULL && useAztecPrec_ ) {
685 localPrecType = PT_AZTEC_FROM_OP;
687 else if( approxFwdOp.get() && useAztecPrec_ ) {
690 localPrecType = PT_AZTEC_FROM_APPROX_FWD_MATRIX;
692 else if( precUsed.get() ) {
695 localPrecType = PT_FROM_PREC_OP;
697 TEUCHOS_TEST_FOR_EXCEPTION
698 (localPrecType == PT_UPPER_BOUND, std::logic_error,
699 "AztecOOLinearOpWithSolveFactory::initializeOp_impl(...): "
700 "localPrecType == PT_UPPER_BOUND. This means that previously, "
701 "this value might have been used uninitialized. "
702 "Please report this bug to the Stratimikos developers.");
708 RCP<AztecOO> aztecFwdSolver, aztecAdjSolver;
714 Teuchos::RCP<const LinearOpBase<double> > old_fwdOp;
715 Teuchos::RCP<const LinearOpSourceBase<double> > old_fwdOpSrc;
716 Teuchos::RCP<const PreconditionerBase<double> > old_prec;
717 bool old_isExternalPrec;
718 Teuchos::RCP<const LinearOpSourceBase<double> > old_approxFwdOpSrc;
719 Teuchos::RCP<AztecOO> old_aztecFwdSolver;
720 Teuchos::RCP<AztecOO> old_aztecAdjSolver;
721 double old_aztecSolverScalar;
722 aztecOp->uninitialize(
732 ,&old_aztecSolverScalar
734 if( old_aztecFwdSolver.get()==NULL ) {
742 aztecFwdSolver = old_aztecFwdSolver;
743 aztecAdjSolver = old_aztecAdjSolver;
744 startingOver =
false;
747 Ptr<bool> constructedAztecPreconditioner;
751 !is_null(constructedAztecPreconditioner = get_optional_nonconst_extra_data<bool>(
752 aztecFwdSolver,
"AOOLOWSF::constructedAztecPreconditoner") )
754 *constructedAztecPreconditioner
757 aztecFwdSolver->DestroyPreconditioner();
758 *constructedAztecPreconditioner =
false;
762 Ptr<bool> setPreconditionerOperator;
764 localPrecType != PT_FROM_PREC_OP
765 && !is_null( setPreconditionerOperator = get_optional_nonconst_extra_data<bool>(
766 aztecFwdSolver,
"AOOLOWSF::setPreconditonerOperator") )
767 && *setPreconditionerOperator
783 aztecFwdSolver = rcp(
new AztecOO());
784 aztecFwdSolver->SetAztecOption(AZ_diagnostics,AZ_none);
785 aztecFwdSolver->SetAztecOption(AZ_keep_info,1);
788 epetra_epetraFwdOpAdjointSupport==EPETRA_OP_ADJOINT_SUPPORTED
790 localPrecType!=PT_AZTEC_FROM_OP && localPrecType!=PT_AZTEC_FROM_APPROX_FWD_MATRIX
793 aztecAdjSolver = rcp(
new AztecOO());
794 aztecAdjSolver->SetAztecOption(AZ_diagnostics,AZ_none);
804 setAztecOOParameters(
805 ¶mList_->sublist(ForwardSolve_name).sublist(AztecOO_Settings_name),
808 if(aztecAdjSolver.get() && paramList_.get())
809 setAztecOOParameters(
810 ¶mList_->sublist(AdjointSolve_name).sublist(AztecOO_Settings_name),
818 RCP<const Epetra_Operator>
819 aztec_epetra_epetraFwdOp,
820 aztec_epetra_epetraAdjOp;
822 RCP<const Epetra_Operator>
824 = { epetra_epetraFwdOp };
827 = { epetra_epetraFwdOpTransp==
NOTRANS ? Teuchos::NO_TRANS : Teuchos::TRANS };
830 = { epetra_epetraFwdOpApplyAs==EPETRA_OP_APPLY_APPLY
831 ? PO::APPLY_MODE_APPLY
832 : PO::APPLY_MODE_APPLY_INVERSE };
834 epetraOpsTransp[0] == Teuchos::NO_TRANS
836 epetraOpsApplyMode[0] == PO::APPLY_MODE_APPLY
839 aztec_epetra_epetraFwdOp = epetra_epetraFwdOp;
843 aztec_epetra_epetraFwdOp = rcp(
844 new PO(1,epetraOps,epetraOpsTransp,epetraOpsApplyMode));
849 aztec_epetra_epetraFwdOp.get() != aztecFwdSolver->GetUserOperator()
854 aztecFwdSolver->SetUserOperator(
857 aztec_epetra_epetraFwdOp, AOOLOWSF_aztec_epetra_epetraFwdOp_str,
858 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY,
false
862 if( aztecAdjSolver.get() ) {
863 epetraOpsTransp[0] = (
864 epetra_epetraFwdOpTransp==
NOTRANS
869 epetraOpsTransp[0] == Teuchos::NO_TRANS
871 epetraOpsApplyMode[0] == PO::APPLY_MODE_APPLY
874 aztec_epetra_epetraAdjOp = epetra_epetraFwdOp;
877 aztec_epetra_epetraAdjOp = rcp(
878 new PO(1,epetraOps,epetraOpsTransp,epetraOpsApplyMode));
880 aztecAdjSolver->SetUserOperator(
883 aztec_epetra_epetraAdjOp, AOOLOWSF_aztec_epetra_epetraAdjOp_str,
884 Teuchos::inOutArg(aztecAdjSolver), Teuchos::POST_DESTROY,
false
891 RCP<const Epetra_Operator>
892 aztec_fwd_epetra_epetraPrecOp,
893 aztec_adj_epetra_epetraPrecOp;
894 bool setAztecPreconditioner =
false;
895 switch(localPrecType) {
902 case PT_AZTEC_FROM_OP: {
907 if( startingOver || !reusePrec ) {
908 TEUCHOS_TEST_FOR_EXCEPTION(
909 rowmatrix_epetraFwdOp.get()==NULL, std::logic_error,
910 "AztecOOLinearOpWithSolveFactory::initializeOp_impl(...): "
911 "Error, There is no preconditioner given by client, but the client "
912 "passed in an Epetra_Operator for the forward operator of type \'"
913 <<typeName(*epetra_epetraFwdOp)<<
"\' that does not "
914 "support the Epetra_RowMatrix interface!"
916 TEUCHOS_TEST_FOR_EXCEPTION(
917 epetra_epetraFwdOpTransp!=NOTRANS, std::logic_error,
918 "AztecOOLinearOpWithSolveFactory::initializeOp_impl(...):"
919 " Error, There is no preconditioner given by client and the client "
920 "passed in an Epetra_RowMatrix for the forward operator but the "
921 "overall transpose is not NOTRANS and therefore we can can just "
922 "hand this over to aztec without making a copy which is not supported here!"
924 aztecFwdSolver->SetPrecMatrix(
927 rowmatrix_epetraFwdOp, AOOLOWSF_rowmatrix_epetraFwdOp_str,
928 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY,
false
931 setAztecPreconditioner =
true;
934 case PT_AZTEC_FROM_APPROX_FWD_MATRIX: {
939 if( startingOver || !reusePrec ) {
940 TEUCHOS_TEST_FOR_EXCEPTION(
941 rowmatrix_epetraPrecOp.get()==NULL, std::logic_error
942 ,
"AztecOOLinearOpWithSolveFactor::initializeOp_impl(...): The client "
943 "passed in an Epetra_Operator for the preconditioner matrix of type \'"
944 <<typeName(*epetra_epetraPrecOp)<<
"\' that does not "
945 "support the Epetra_RowMatrix interface!"
947 TEUCHOS_TEST_FOR_EXCEPTION(
948 overall_epetra_epetraPrecOpTransp!=NOTRANS, std::logic_error
949 ,
"AztecOOLinearOpWithSolveFactor::initializeOp_impl(...): Error, The client "
950 "passed in an Epetra_RowMatrix for the preconditoner matrix but the overall "
951 "transpose is not NOTRANS and therefore we can can just "
952 "hand this over to aztec without making a copy which is not supported here!"
954 aztecFwdSolver->SetPrecMatrix(
957 rowmatrix_epetraPrecOp, AOOLOWSF_rowmatrix_epetraPrecOp_str,
958 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY,
false
961 setAztecPreconditioner =
true;
964 case PT_FROM_PREC_OP: {
969 RCP<const Epetra_Operator>
971 = { epetra_epetraPrecOp };
974 = { overall_epetra_epetraPrecOpTransp==
NOTRANS
980 theEpetraOpsApplyMode[]
981 = { epetra_epetraPrecOpApplyAs==EPETRA_OP_APPLY_APPLY
982 ? PO::APPLY_MODE_APPLY_INVERSE
983 : PO::APPLY_MODE_APPLY };
985 theEpetraOpsTransp[0] == Teuchos::NO_TRANS
987 epetra_epetraPrecOpApplyAs==EPETRA_OP_APPLY_APPLY_INVERSE
990 aztec_fwd_epetra_epetraPrecOp = epetra_epetraPrecOp;
993 aztec_fwd_epetra_epetraPrecOp = rcp(
new PO(1,theEpetraOps,theEpetraOpsTransp,theEpetraOpsApplyMode));
995 aztecFwdSolver->SetPrecOperator(
998 aztec_fwd_epetra_epetraPrecOp, AOOLOWSF_aztec_fwd_epetra_epetraPrecOp_str,
999 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY,
false
1003 aztecAdjSolver.get()
1005 epetra_epetraPrecOpAdjointSupport == EPETRA_OP_ADJOINT_SUPPORTED
1008 theEpetraOpsTransp[0] = (
1009 overall_epetra_epetraPrecOpTransp==
NOTRANS
1014 theEpetraOpsTransp[0] == Teuchos::NO_TRANS
1016 epetra_epetraPrecOpApplyAs==EPETRA_OP_APPLY_APPLY_INVERSE
1019 aztec_adj_epetra_epetraPrecOp = epetra_epetraPrecOp;
1022 aztec_adj_epetra_epetraPrecOp = rcp(
1023 new PO(1,theEpetraOps,theEpetraOpsTransp,theEpetraOpsApplyMode));
1025 aztecAdjSolver->SetPrecOperator(
1028 aztec_adj_epetra_epetraPrecOp, AOOLOWSF_aztec_adj_epetra_epetraPrecOp_str,
1029 Teuchos::inOutArg(aztecAdjSolver), Teuchos::POST_DESTROY,
false
1031 set_extra_data<bool>(
1032 true, AOOLOWSF_setPrecondtionerOperator_str,
1033 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY,
false
1039 TEUCHOS_TEST_FOR_EXCEPT(
true);
1045 if(setAztecPreconditioner) {
1046 if( startingOver || !reusePrec ) {
1047 double condNumEst = -1.0;
1048 TEUCHOS_TEST_FOR_EXCEPT(0!=aztecFwdSolver->ConstructPreconditioner(condNumEst));
1050 set_extra_data<bool>(
1051 true, AOOLOWSF_constructedAztecPreconditoner_str,
1052 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY,
false
1063 if(aztecAdjSolver.get() && aztecAdjSolver->GetPrecOperator()) {
1064 aztecOp->initialize(
1065 fwdOp, fwdOpSrc,precUsed, prec.get()!=NULL, approxFwdOpSrc,
1066 aztecFwdSolver,
true, aztecAdjSolver,
true, epetra_epetraFwdOpScalar
1070 aztecOp->initialize(
1071 fwdOp, fwdOpSrc, precUsed, prec.get()!=NULL, approxFwdOpSrc,
1072 aztecFwdSolver,
true, null,
false, epetra_epetraFwdOpScalar
1075 aztecOp->fwdDefaultMaxIterations(defaultFwdMaxIterations_);
1076 aztecOp->fwdDefaultTol(defaultFwdTolerance_);
1077 aztecOp->adjDefaultMaxIterations(defaultAdjMaxIterations_);
1078 aztecOp->adjDefaultTol(defaultAdjTolerance_);
1079 aztecOp->outputEveryRhs(outputEveryRhs_);
1080 aztecOp->setOStream(this->getOStream());
1081 if(!is_null(this->getOverridingOStream()))
1082 aztecOp->setOverridingOStream(this->getOverridingOStream());
1083 aztecOp->setVerbLevel(this->getVerbLevel());
1086 if(paramList_.get())
1090 if(out.get() &&
static_cast<int>(verbLevel) >
static_cast<int>(Teuchos::VERB_LOW))
1091 *out <<
"\nLeaving Thyra::AztecOOLinearOpWithSolveFactory::initializeOp_impl(...) ...\n";
void unsetPreconditionerFactory(Teuchos::RCP< PreconditionerFactoryBase< double > > *precFactory, std::string *precFactoryName)
bool isCompatible(const LinearOpSourceBase< double > &fwdOpSrc) const
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const ¶mList)
bool acceptsPreconditionerFactory() const
Returns true .
Teuchos::RCP< PreconditionerFactoryBase< double > > getPreconditionerFactory() const
void initializeApproxPreconditionedOp(const Teuchos::RCP< const LinearOpSourceBase< double > > &fwdOpSrc, const Teuchos::RCP< const LinearOpSourceBase< double > > &approxFwdOpSrc, LinearOpWithSolveBase< double > *Op, const ESupportSolveUse supportSolveUse) const
AztecOOLinearOpWithSolveFactory(Teuchos::RCP< Teuchos::ParameterList > const ¶mList=Teuchos::null)
Construct uninitialized.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
void initializeOp(const Teuchos::RCP< const LinearOpSourceBase< double > > &fwdOpSrc, LinearOpWithSolveBase< double > *Op, const ESupportSolveUse supportSolveUse) const
void initializeAndReuseOp(const Teuchos::RCP< const LinearOpSourceBase< double > > &fwdOpSrc, LinearOpWithSolveBase< double > *Op) const
std::string description() const
void setPreconditionerFactory(const Teuchos::RCP< PreconditionerFactoryBase< double > > &precFactory, const std::string &precFactoryName)
void uninitializeOp(LinearOpWithSolveBase< double > *Op, Teuchos::RCP< const LinearOpSourceBase< double > > *fwdOpSrc, Teuchos::RCP< const PreconditionerBase< double > > *prec, Teuchos::RCP< const LinearOpSourceBase< double > > *approxFwdOpSrc, ESupportSolveUse *supportSolveUse) const
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
bool supportsPreconditionerInputType(const EPreconditionerInputType precOpType) const
Teuchos::RCP< LinearOpWithSolveBase< double > > createOp() const
Teuchos::RCP< const Teuchos::ParameterList > getParameterList() const
void initializePreconditionedOp(const Teuchos::RCP< const LinearOpSourceBase< double > > &fwdOpSrc, const Teuchos::RCP< const PreconditionerBase< double > > &prec, LinearOpWithSolveBase< double > *Op, const ESupportSolveUse supportSolveUse) const
Concrete LinearOpWithSolveBase subclass implemented using AztecOO.