13#include "Thyra_AztecOOLinearOpWithSolveFactory.hpp"
14#include "Thyra_AztecOOLinearOpWithSolve.hpp"
15#include "Thyra_PreconditionerFactoryHelpers.hpp"
16#include "Thyra_EpetraOperatorViewExtractorStd.hpp"
17#include "Thyra_ScaledAdjointLinearOpBase.hpp"
18#include "Thyra_EpetraLinearOpBase.hpp"
19#include "Thyra_EpetraOperatorWrapper.hpp"
21#include "Teuchos_VerboseObjectParameterListHelpers.hpp"
22#include "Teuchos_ParameterList.hpp"
23#include "Teuchos_dyn_cast.hpp"
24#include "AztecOOParameterList.hpp"
30const std::string AOOLOWSF_epetraPrecOp_str
31=
"AOOLOWSF::epetraPrecOp";
32const std::string AOOLOWSF_aztec_epetra_epetraFwdOp_str
33=
"AOOLOWSF::aztec_epetra_epetraFwdOp";
34const std::string AOOLOWSF_aztec_epetra_epetraAdjOp_str
35=
"AOOLOWSF::aztec_epetra_epetraAdjOp";
36const std::string AOOLOWSF_rowmatrix_epetraFwdOp_str
37=
"AOOLOWSF::rowmatrix_epetraFwdOp";
38const std::string AOOLOWSF_rowmatrix_epetraPrecOp_str
39=
"AOOLOWSF::rowmatrix_epetraPrecOp";
40const std::string AOOLOWSF_aztec_fwd_epetra_epetraPrecOp_str
41=
"AOOLOWSF::aztec_fwd_epetra_epetraPrecOp";
42const std::string AOOLOWSF_aztec_adj_epetra_epetraPrecOp_str
43=
"AOOLOWSF::aztec_adj_epetra_epetraPrecOp";
44const std::string AOOLOWSF_setPrecondtionerOperator_str
45=
"AOOLOWSF::setPrecondtionerOperator";
46const std::string AOOLOWSF_constructedAztecPreconditoner_str
47=
"AOOLOWSF::constructedAztecPreconditoner";
50const std::string ForwardSolve_name =
"Forward Solve";
51const std::string AdjointSolve_name =
"Adjoint Solve";
52const std::string MaxIterations_name =
"Max Iterations";
53const int MaxIterations_default = 400;
54const std::string Tolerance_name =
"Tolerance";
55const double Tolerance_default = 1e-6;
56const std::string OutputEveryRhs_name =
"Output Every RHS";
57const bool OutputEveryRhs_default =
false;
58const std::string AztecOO_Settings_name =
"AztecOO Settings";
71 Teuchos::RCP<Teuchos::ParameterList>
const& paramList
73 :epetraFwdOpViewExtractor_(
Teuchos::rcp(new EpetraOperatorViewExtractorStd()))
74 ,defaultFwdMaxIterations_(MaxIterations_default)
75 ,defaultFwdTolerance_(Tolerance_default)
76 ,defaultAdjMaxIterations_(MaxIterations_default)
77 ,defaultAdjTolerance_(Tolerance_default)
78 ,outputEveryRhs_(OutputEveryRhs_default)
81 updateThisValidParamList();
97 const Teuchos::RCP<PreconditionerFactoryBase<double> > &precFactory,
98 const std::string &precFactoryName
101 TEUCHOS_TEST_FOR_EXCEPT(!precFactory.get());
102 Teuchos::RCP<const Teuchos::ParameterList>
103 precFactoryValidPL = precFactory->getValidParameters();
104 const std::string _precFactoryName =
105 ( precFactoryName !=
""
107 : ( precFactoryValidPL.get()
108 ? precFactoryValidPL->name()
109 :
"GENERIC PRECONDITIONER FACTORY"
112 precFactory_ = precFactory;
113 precFactoryName_ = _precFactoryName;
114 updateThisValidParamList();
118Teuchos::RCP<PreconditionerFactoryBase<double> >
126 Teuchos::RCP<PreconditionerFactoryBase<double> > *precFactory,
127 std::string *precFactoryName
130 if(precFactory) *precFactory = precFactory_;
131 if(precFactoryName) *precFactoryName = precFactoryName_;
132 precFactory_ = Teuchos::null;
133 precFactoryName_ =
"";
134 updateThisValidParamList();
139 const LinearOpSourceBase<double> &fwdOpSrc
142 return epetraFwdOpViewExtractor_->isCompatible(*fwdOpSrc.getOp());
146Teuchos::RCP<LinearOpWithSolveBase<double> >
154 const Teuchos::RCP<
const LinearOpSourceBase<double> > &fwdOpSrc,
155 LinearOpWithSolveBase<double> *Op,
156 const ESupportSolveUse
159 this->initializeOp_impl(fwdOpSrc,Teuchos::null,Teuchos::null,
false,Op);
164 const Teuchos::RCP<
const LinearOpSourceBase<double> > &fwdOpSrc,
165 LinearOpWithSolveBase<double> *Op
168 this->initializeOp_impl(fwdOpSrc,Teuchos::null,Teuchos::null,
true,Op);
173 const EPreconditionerInputType precOpType
176 const_cast<bool&
>(useAztecPrec_) = (
179 paramList_->sublist(ForwardSolve_name).sublist(AztecOO_Settings_name).get(
180 "Aztec Preconditioner",
"none"
184 case PRECONDITIONER_INPUT_TYPE_AS_OPERATOR:
186 case PRECONDITIONER_INPUT_TYPE_AS_MATRIX:
187 return useAztecPrec_;
189 TEUCHOS_TEST_FOR_EXCEPT(
true);
191 TEUCHOS_UNREACHABLE_RETURN(PRECONDITIONER_INPUT_TYPE_AS_OPERATOR);
196 const Teuchos::RCP<
const LinearOpSourceBase<double> > &fwdOpSrc,
197 const Teuchos::RCP<
const PreconditionerBase<double> > &prec,
198 LinearOpWithSolveBase<double> *Op,
199 const ESupportSolveUse
202 TEUCHOS_TEST_FOR_EXCEPT(prec.get()==NULL);
203 this->initializeOp_impl(fwdOpSrc,prec,Teuchos::null,
false,Op);
208 const Teuchos::RCP<
const LinearOpSourceBase<double> > &fwdOpSrc,
209 const Teuchos::RCP<
const LinearOpSourceBase<double> > &approxFwdOpSrc,
210 LinearOpWithSolveBase<double> *Op,
211 const ESupportSolveUse
214 TEUCHOS_TEST_FOR_EXCEPT(approxFwdOpSrc.get()==NULL);
215 TEUCHOS_TEST_FOR_EXCEPT(approxFwdOpSrc->getOp().get()==NULL);
216 this->initializeOp_impl(fwdOpSrc,Teuchos::null,approxFwdOpSrc,
false,Op);
221 LinearOpWithSolveBase<double> *Op,
222 Teuchos::RCP<
const LinearOpSourceBase<double> > *fwdOpSrc,
223 Teuchos::RCP<
const PreconditionerBase<double> > *prec,
224 Teuchos::RCP<
const LinearOpSourceBase<double> > *approxFwdOpSrc,
229 TEUCHOS_TEST_FOR_EXCEPT(Op==NULL);
232 *aztecOp = &Teuchos::dyn_cast<AztecOOLinearOpWithSolve>(*Op);
234 Teuchos::RCP<const LinearOpSourceBase<double> >
237 if(fwdOpSrc) *fwdOpSrc = _fwdOpSrc;
238 if(approxFwdOpSrc) *approxFwdOpSrc = _approxFwdOpSrc;
243 Teuchos::RCP<const PreconditionerBase<double> >
245 if(prec) *prec = _prec;
257 Teuchos::RCP<Teuchos::ParameterList>
const& paramList
260 TEUCHOS_TEST_FOR_EXCEPT(paramList.get()==NULL);
262 paramList_ = paramList;
264 outputEveryRhs_ = paramList_->get(OutputEveryRhs_name,OutputEveryRhs_default);
266 Teuchos::ParameterList
267 &fwdSolvePL = paramList_->sublist(ForwardSolve_name);
268 defaultFwdMaxIterations_ = fwdSolvePL.get(MaxIterations_name,defaultFwdMaxIterations_);
269 defaultFwdTolerance_ = fwdSolvePL.get(Tolerance_name,defaultFwdTolerance_);
271 if( !paramList_->getPtr<Teuchos::ParameterList>(AdjointSolve_name) ) {
273 paramList_->sublist(AdjointSolve_name).setParameters(fwdSolvePL);
275 Teuchos::ParameterList
276 &adjSolvePL = paramList_->sublist(AdjointSolve_name);
277 defaultAdjMaxIterations_ = adjSolvePL.get(MaxIterations_name,defaultAdjMaxIterations_);
278 defaultAdjTolerance_ = adjSolvePL.get(Tolerance_name,defaultAdjTolerance_);
280 if(precFactory_.get()) {
284 const bool nestedPFSublistExists = paramList_->isSublist(precFactoryName_);
285 const bool alreadyHasSublist = !is_null(precFactory_->getParameterList());
286 if( nestedPFSublistExists || !alreadyHasSublist ) {
287 precFactory_->setParameterList(Teuchos::sublist(paramList_,precFactoryName_));
290 Teuchos::readVerboseObjectSublist(&*paramList_,
this);
294Teuchos::RCP<Teuchos::ParameterList>
301Teuchos::RCP<Teuchos::ParameterList>
304 Teuchos::RCP<Teuchos::ParameterList> _paramList = paramList_;
305 paramList_ = Teuchos::null;
310Teuchos::RCP<const Teuchos::ParameterList>
317Teuchos::RCP<const Teuchos::ParameterList>
320 return thisValidParamList_;
329 std::ostringstream oss;
330 oss <<
"Thyra::AztecOOLinearOpWithSolveFactory{";
331 oss <<
"precFactory=";
332 if(!is_null(precFactory_))
333 oss << precFactory_->description();
344Teuchos::RCP<const Teuchos::ParameterList>
345AztecOOLinearOpWithSolveFactory::generateAndGetValidParameters()
347 static Teuchos::RCP<Teuchos::ParameterList> validParamList;
348 if(validParamList.get()==NULL) {
349 validParamList = Teuchos::rcp(
350 new Teuchos::ParameterList(
"AztecOOLinearOpWithSolveFactory"));
352 OutputEveryRhs_name,OutputEveryRhs_default
353 ,
"Determines if output is created for each individual RHS (true or 1) or if output\n"
354 "is just created for an entire set of RHSs (false or 0)."
356 static Teuchos::RCP<const Teuchos::ParameterList>
357 aztecParamList = getValidAztecOOParameters();
358 Teuchos::ParameterList
359 &fwdSolvePL = validParamList->sublist(
360 ForwardSolve_name,
false
361 ,
"Gives the options for the forward solve."
364 Tolerance_name,Tolerance_default
365 ,
"The tolerence used in the convergence check (see the convergence test\n"
366 "in the sublist \"" + AztecOO_Settings_name +
"\")"
369 MaxIterations_name,MaxIterations_default
370 ,
"The maximum number of iterations the AztecOO solver is allowed to perform."
373 AztecOO_Settings_name,
false
374 ,
"Sets the parameters on the AztecOO object itself."
375 ).setParameters(*aztecParamList);
376 Teuchos::ParameterList
377 &adjSolvePL = validParamList->sublist(
378 AdjointSolve_name,
false
379 ,
"The options for the adjoint solve.\n"
380 "If this sublist is missing then the parameters from the\n"
381 "\""+ForwardSolve_name+
"\" sublist are used instead."
384 adjSolvePL.setParameters(fwdSolvePL);
386 return validParamList;
390void AztecOOLinearOpWithSolveFactory::updateThisValidParamList()
392 thisValidParamList_ = Teuchos::rcp(
393 new Teuchos::ParameterList(*generateAndGetValidParameters())
395 if(precFactory_.get()) {
396 Teuchos::RCP<const Teuchos::ParameterList>
397 precFactoryValidParamList = precFactory_->getValidParameters();
398 if(precFactoryValidParamList.get()) {
399 thisValidParamList_->sublist(precFactoryName_).setParameters(
400 *precFactoryValidParamList);
403 Teuchos::setupVerboseObjectSublist(&*thisValidParamList_);
407void AztecOOLinearOpWithSolveFactory::initializeOp_impl(
408 const Teuchos::RCP<
const LinearOpSourceBase<double> > &fwdOpSrc,
409 const Teuchos::RCP<
const PreconditionerBase<double> > &prec,
410 const Teuchos::RCP<
const LinearOpSourceBase<double> > &approxFwdOpSrc,
411 const bool reusePrec,
412 LinearOpWithSolveBase<double> *Op
418 using Teuchos::rcp_dynamic_cast;
419 using Teuchos::rcp_const_cast;
420 using Teuchos::set_extra_data;
421 using Teuchos::get_optional_extra_data;
422 using Teuchos::get_optional_nonconst_extra_data;
423 using Teuchos::outArg;
426 const Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
427 const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
428 Teuchos::OSTab tab(out);
429 if(out.get() &&
static_cast<int>(verbLevel) >
static_cast<int>(Teuchos::VERB_LOW))
430 *out <<
"\nEntering Thyra::AztecOOLinearOpWithSolveFactory::initializeOp_impl(...) ...\n";
432 typedef Teuchos::VerboseObjectTempState<PreconditionerFactoryBase<double> > VOTSPF;
433 VOTSPF precFactoryOutputTempState(precFactory_,out,verbLevel);
436 TEUCHOS_TEST_FOR_EXCEPT(Op==NULL);
437 TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc.get()==NULL);
438 TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc->getOp().get()==NULL);
446 Teuchos::RCP<const LinearOpBase<double> >
447 tmpFwdOp = fwdOpSrc->getOp(),
448 tmpApproxFwdOp = ( approxFwdOpSrc.get() ? approxFwdOpSrc->getOp() : Teuchos::null );
449 Teuchos::RCP<const LinearOpBase<double> > fwdOp;
450 Teuchos::RCP<const LinearOpBase<double> > approxFwdOp;
451 if (
dynamic_cast<const EpetraLinearOpBase*
>(tmpFwdOp.get())!=0 )
454 approxFwdOp = tmpApproxFwdOp;
458 fwdOp = makeEpetraWrapper(tmpFwdOp);
462 dynamic_cast<const EpetraLinearOpBase*
>(&*tmpApproxFwdOp.get())
465 approxFwdOp = makeEpetraWrapper(tmpApproxFwdOp);
472 AztecOOLinearOpWithSolve
473 *aztecOp = &Teuchos::dyn_cast<AztecOOLinearOpWithSolve>(*Op);
478 Teuchos::RCP<const Epetra_Operator> epetra_epetraFwdOp;
479 EOpTransp epetra_epetraFwdOpTransp;
480 EApplyEpetraOpAs epetra_epetraFwdOpApplyAs;
481 EAdjointEpetraOp epetra_epetraFwdOpAdjointSupport;
482 double epetra_epetraFwdOpScalar;
483 epetraFwdOpViewExtractor_->getEpetraOpView(
485 outArg(epetra_epetraFwdOp), outArg(epetra_epetraFwdOpTransp),
486 outArg(epetra_epetraFwdOpApplyAs), outArg(epetra_epetraFwdOpAdjointSupport),
487 outArg(epetra_epetraFwdOpScalar)
489 TEUCHOS_TEST_FOR_EXCEPTION(
490 epetra_epetraFwdOp.get()==NULL, std::logic_error
491 ,
"Error, The input fwdOp object must be fully initialized "
492 "before calling this function!"
498 Teuchos::RCP<PreconditionerBase<double> > myPrec;
499 Teuchos::RCP<const PreconditionerBase<double> > precUsed;
504 else if (precFactory_.get() ) {
508 ( !aztecOp->isExternalPrec()
509 ? Teuchos::rcp_const_cast<PreconditionerBase<double> >(
510 aztecOp->extract_prec())
518 myPrec = precFactory_->createPrec();
520 precFactory_->initializePrec(fwdOpSrc,&*myPrec);
527 RCP<const LinearOpBase<double> > rightPrecOp;
528 if (precUsed.get()) {
529 RCP<const LinearOpBase<double> > unspecified = precUsed->getUnspecifiedPrecOp();
530 RCP<const LinearOpBase<double> > left = precUsed->getLeftPrecOp();
531 RCP<const LinearOpBase<double> > right = precUsed->getRightPrecOp();
532 TEUCHOS_TEST_FOR_EXCEPTION(
533 !( left.get() || right.get() || unspecified.get() ), std::logic_error
534 ,
"Error, at least one preconditoner linear operator objects must be set!"
536 if(unspecified.get()) {
537 rightPrecOp = unspecified;
541 TEUCHOS_TEST_FOR_EXCEPTION(
542 left.get(),std::logic_error
543 ,
"Error, we can not currently handle a left"
544 " preconditioner with the AztecOO/Thyra adapters!"
549 double wrappedPrecOpScalar = 0.0;
550 EOpTransp wrappedPrecOpTransp =
NOTRANS;
551 RCP<const LinearOpBase<double> > wrappedPrecOp = null;
552 RCP<const EpetraLinearOpBase> epetraPrecOp;
553 Teuchos::RCP<const Epetra_Operator> epetra_epetraPrecOp;
554 EOpTransp epetra_epetraPrecOpTransp;
555 EApplyEpetraOpAs epetra_epetraPrecOpApplyAs;
556 EAdjointEpetraOp epetra_epetraPrecOpAdjointSupport;
557 EOpTransp overall_epetra_epetraPrecOpTransp=
NOTRANS;
558 if(rightPrecOp.get()) {
559 RCP<const LinearOpBase<double> > tmpWrappedPrecOp;
561 rightPrecOp,&wrappedPrecOpScalar,&wrappedPrecOpTransp,&tmpWrappedPrecOp);
562 if(
dynamic_cast<const EpetraLinearOpBase*
>(&*tmpWrappedPrecOp) ) {
563 wrappedPrecOp = tmpWrappedPrecOp;
566 wrappedPrecOp = makeEpetraWrapper(tmpWrappedPrecOp);
568 epetraPrecOp = rcp_dynamic_cast<const EpetraLinearOpBase>(
570 epetraPrecOp->getEpetraOpView(
571 outArg(epetra_epetraPrecOp), outArg(epetra_epetraPrecOpTransp),
572 outArg(epetra_epetraPrecOpApplyAs), outArg(epetra_epetraPrecOpAdjointSupport));
573 TEUCHOS_TEST_FOR_EXCEPTION(
574 epetra_epetraPrecOp.get()==NULL,std::logic_error
575 ,
"Error, The input prec object and its embedded preconditioner"
576 " operator must be fully initialized before calling this function!"
585 overall_epetra_epetraPrecOpTransp
587 real_trans(wrappedPrecOpTransp),
588 real_trans(epetra_epetraPrecOpTransp)
596 if(approxFwdOp.get()) {
599 unwrap(approxFwdOp,&wrappedPrecOpScalar,&wrappedPrecOpTransp,&wrappedPrecOp);
600 epetraPrecOp = rcp_dynamic_cast<const EpetraLinearOpBase>(
602 epetraPrecOp->getEpetraOpView(
603 outArg(epetra_epetraPrecOp), outArg(epetra_epetraPrecOpTransp),
604 outArg(epetra_epetraPrecOpApplyAs), outArg(epetra_epetraPrecOpAdjointSupport)
606 TEUCHOS_TEST_FOR_EXCEPTION(
607 epetra_epetraPrecOp.get()==NULL,std::logic_error
608 ,
"Error, The input approxFwdOp object must be fully initialized"
609 " before calling this function!"
619 overall_epetra_epetraPrecOpTransp
621 real_trans(wrappedPrecOpTransp),
622 real_trans(epetra_epetraPrecOpTransp)
630 RCP<const Epetra_RowMatrix>
631 rowmatrix_epetraFwdOp = rcp_dynamic_cast<const Epetra_RowMatrix>(
633 rowmatrix_epetraPrecOp = rcp_dynamic_cast<const Epetra_RowMatrix>(
634 epetra_epetraPrecOp);
640 enum ELocalPrecType {
641 PT_NONE, PT_AZTEC_FROM_OP, PT_AZTEC_FROM_APPROX_FWD_MATRIX,
642 PT_FROM_PREC_OP, PT_UPPER_BOUND
644 ELocalPrecType localPrecType = PT_UPPER_BOUND;
645 if( precUsed.get()==NULL && approxFwdOp.get()==NULL && !useAztecPrec_ ) {
647 localPrecType = PT_NONE;
649 else if( precUsed.get()==NULL && approxFwdOp.get()==NULL && useAztecPrec_ ) {
652 localPrecType = PT_AZTEC_FROM_OP;
654 else if( approxFwdOp.get() && useAztecPrec_ ) {
657 localPrecType = PT_AZTEC_FROM_APPROX_FWD_MATRIX;
659 else if( precUsed.get() ) {
662 localPrecType = PT_FROM_PREC_OP;
664 TEUCHOS_TEST_FOR_EXCEPTION
665 (localPrecType == PT_UPPER_BOUND, std::logic_error,
666 "AztecOOLinearOpWithSolveFactory::initializeOp_impl(...): "
667 "localPrecType == PT_UPPER_BOUND. This means that previously, "
668 "this value might have been used uninitialized. "
669 "Please report this bug to the Stratimikos developers.");
675 RCP<AztecOO> aztecFwdSolver, aztecAdjSolver;
681 Teuchos::RCP<const LinearOpBase<double> > old_fwdOp;
682 Teuchos::RCP<const LinearOpSourceBase<double> > old_fwdOpSrc;
683 Teuchos::RCP<const PreconditionerBase<double> > old_prec;
684 bool old_isExternalPrec;
685 Teuchos::RCP<const LinearOpSourceBase<double> > old_approxFwdOpSrc;
686 Teuchos::RCP<AztecOO> old_aztecFwdSolver;
687 Teuchos::RCP<AztecOO> old_aztecAdjSolver;
688 double old_aztecSolverScalar;
689 aztecOp->uninitialize(
699 ,&old_aztecSolverScalar
701 if( old_aztecFwdSolver.get()==NULL ) {
709 aztecFwdSolver = old_aztecFwdSolver;
710 aztecAdjSolver = old_aztecAdjSolver;
711 startingOver =
false;
714 Ptr<bool> constructedAztecPreconditioner;
718 !is_null(constructedAztecPreconditioner = get_optional_nonconst_extra_data<bool>(
719 aztecFwdSolver,
"AOOLOWSF::constructedAztecPreconditoner") )
721 *constructedAztecPreconditioner
724 aztecFwdSolver->DestroyPreconditioner();
725 *constructedAztecPreconditioner =
false;
729 Ptr<bool> setPreconditionerOperator;
731 localPrecType != PT_FROM_PREC_OP
732 && !is_null( setPreconditionerOperator = get_optional_nonconst_extra_data<bool>(
733 aztecFwdSolver,
"AOOLOWSF::setPreconditonerOperator") )
734 && *setPreconditionerOperator
750 aztecFwdSolver = rcp(
new AztecOO());
751 aztecFwdSolver->SetAztecOption(AZ_diagnostics,AZ_none);
752 aztecFwdSolver->SetAztecOption(AZ_keep_info,1);
755 epetra_epetraFwdOpAdjointSupport==EPETRA_OP_ADJOINT_SUPPORTED
757 localPrecType!=PT_AZTEC_FROM_OP && localPrecType!=PT_AZTEC_FROM_APPROX_FWD_MATRIX
760 aztecAdjSolver = rcp(
new AztecOO());
761 aztecAdjSolver->SetAztecOption(AZ_diagnostics,AZ_none);
771 setAztecOOParameters(
772 ¶mList_->sublist(ForwardSolve_name).sublist(AztecOO_Settings_name),
775 if(aztecAdjSolver.get() && paramList_.get())
776 setAztecOOParameters(
777 ¶mList_->sublist(AdjointSolve_name).sublist(AztecOO_Settings_name),
785 RCP<const Epetra_Operator>
786 aztec_epetra_epetraFwdOp,
787 aztec_epetra_epetraAdjOp;
789 RCP<const Epetra_Operator>
791 = { epetra_epetraFwdOp };
794 = { epetra_epetraFwdOpTransp==
NOTRANS ? Teuchos::NO_TRANS : Teuchos::TRANS };
797 = { epetra_epetraFwdOpApplyAs==EPETRA_OP_APPLY_APPLY
798 ? PO::APPLY_MODE_APPLY
799 : PO::APPLY_MODE_APPLY_INVERSE };
801 epetraOpsTransp[0] == Teuchos::NO_TRANS
803 epetraOpsApplyMode[0] == PO::APPLY_MODE_APPLY
806 aztec_epetra_epetraFwdOp = epetra_epetraFwdOp;
810 aztec_epetra_epetraFwdOp = rcp(
811 new PO(1,epetraOps,epetraOpsTransp,epetraOpsApplyMode));
816 aztec_epetra_epetraFwdOp.get() != aztecFwdSolver->GetUserOperator()
821 aztecFwdSolver->SetUserOperator(
824 aztec_epetra_epetraFwdOp, AOOLOWSF_aztec_epetra_epetraFwdOp_str,
825 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY,
false
829 if( aztecAdjSolver.get() ) {
830 epetraOpsTransp[0] = (
831 epetra_epetraFwdOpTransp==
NOTRANS
836 epetraOpsTransp[0] == Teuchos::NO_TRANS
838 epetraOpsApplyMode[0] == PO::APPLY_MODE_APPLY
841 aztec_epetra_epetraAdjOp = epetra_epetraFwdOp;
844 aztec_epetra_epetraAdjOp = rcp(
845 new PO(1,epetraOps,epetraOpsTransp,epetraOpsApplyMode));
847 aztecAdjSolver->SetUserOperator(
850 aztec_epetra_epetraAdjOp, AOOLOWSF_aztec_epetra_epetraAdjOp_str,
851 Teuchos::inOutArg(aztecAdjSolver), Teuchos::POST_DESTROY,
false
858 RCP<const Epetra_Operator>
859 aztec_fwd_epetra_epetraPrecOp,
860 aztec_adj_epetra_epetraPrecOp;
861 bool setAztecPreconditioner =
false;
862 switch(localPrecType) {
869 case PT_AZTEC_FROM_OP: {
874 if( startingOver || !reusePrec ) {
875 TEUCHOS_TEST_FOR_EXCEPTION(
876 rowmatrix_epetraFwdOp.get()==NULL, std::logic_error,
877 "AztecOOLinearOpWithSolveFactory::initializeOp_impl(...): "
878 "Error, There is no preconditioner given by client, but the client "
879 "passed in an Epetra_Operator for the forward operator of type \'"
880 <<typeName(*epetra_epetraFwdOp)<<
"\' that does not "
881 "support the Epetra_RowMatrix interface!"
883 TEUCHOS_TEST_FOR_EXCEPTION(
884 epetra_epetraFwdOpTransp!=NOTRANS, std::logic_error,
885 "AztecOOLinearOpWithSolveFactory::initializeOp_impl(...):"
886 " Error, There is no preconditioner given by client and the client "
887 "passed in an Epetra_RowMatrix for the forward operator but the "
888 "overall transpose is not NOTRANS and therefore we can can just "
889 "hand this over to aztec without making a copy which is not supported here!"
891 aztecFwdSolver->SetPrecMatrix(
894 rowmatrix_epetraFwdOp, AOOLOWSF_rowmatrix_epetraFwdOp_str,
895 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY,
false
898 setAztecPreconditioner =
true;
901 case PT_AZTEC_FROM_APPROX_FWD_MATRIX: {
906 if( startingOver || !reusePrec ) {
907 TEUCHOS_TEST_FOR_EXCEPTION(
908 rowmatrix_epetraPrecOp.get()==NULL, std::logic_error
909 ,
"AztecOOLinearOpWithSolveFactor::initializeOp_impl(...): The client "
910 "passed in an Epetra_Operator for the preconditioner matrix of type \'"
911 <<typeName(*epetra_epetraPrecOp)<<
"\' that does not "
912 "support the Epetra_RowMatrix interface!"
914 TEUCHOS_TEST_FOR_EXCEPTION(
915 overall_epetra_epetraPrecOpTransp!=NOTRANS, std::logic_error
916 ,
"AztecOOLinearOpWithSolveFactor::initializeOp_impl(...): Error, The client "
917 "passed in an Epetra_RowMatrix for the preconditoner matrix but the overall "
918 "transpose is not NOTRANS and therefore we can can just "
919 "hand this over to aztec without making a copy which is not supported here!"
921 aztecFwdSolver->SetPrecMatrix(
924 rowmatrix_epetraPrecOp, AOOLOWSF_rowmatrix_epetraPrecOp_str,
925 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY,
false
928 setAztecPreconditioner =
true;
931 case PT_FROM_PREC_OP: {
936 RCP<const Epetra_Operator>
938 = { epetra_epetraPrecOp };
941 = { overall_epetra_epetraPrecOpTransp==
NOTRANS
947 theEpetraOpsApplyMode[]
948 = { epetra_epetraPrecOpApplyAs==EPETRA_OP_APPLY_APPLY
949 ? PO::APPLY_MODE_APPLY_INVERSE
950 : PO::APPLY_MODE_APPLY };
952 theEpetraOpsTransp[0] == Teuchos::NO_TRANS
954 epetra_epetraPrecOpApplyAs==EPETRA_OP_APPLY_APPLY_INVERSE
957 aztec_fwd_epetra_epetraPrecOp = epetra_epetraPrecOp;
960 aztec_fwd_epetra_epetraPrecOp = rcp(
new PO(1,theEpetraOps,theEpetraOpsTransp,theEpetraOpsApplyMode));
962 aztecFwdSolver->SetPrecOperator(
965 aztec_fwd_epetra_epetraPrecOp, AOOLOWSF_aztec_fwd_epetra_epetraPrecOp_str,
966 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY,
false
972 epetra_epetraPrecOpAdjointSupport == EPETRA_OP_ADJOINT_SUPPORTED
975 theEpetraOpsTransp[0] = (
976 overall_epetra_epetraPrecOpTransp==
NOTRANS
981 theEpetraOpsTransp[0] == Teuchos::NO_TRANS
983 epetra_epetraPrecOpApplyAs==EPETRA_OP_APPLY_APPLY_INVERSE
986 aztec_adj_epetra_epetraPrecOp = epetra_epetraPrecOp;
989 aztec_adj_epetra_epetraPrecOp = rcp(
990 new PO(1,theEpetraOps,theEpetraOpsTransp,theEpetraOpsApplyMode));
992 aztecAdjSolver->SetPrecOperator(
995 aztec_adj_epetra_epetraPrecOp, AOOLOWSF_aztec_adj_epetra_epetraPrecOp_str,
996 Teuchos::inOutArg(aztecAdjSolver), Teuchos::POST_DESTROY,
false
998 set_extra_data<bool>(
999 true, AOOLOWSF_setPrecondtionerOperator_str,
1000 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY,
false
1006 TEUCHOS_TEST_FOR_EXCEPT(
true);
1012 if(setAztecPreconditioner) {
1013 if( startingOver || !reusePrec ) {
1014 double condNumEst = -1.0;
1015 TEUCHOS_TEST_FOR_EXCEPT(0!=aztecFwdSolver->ConstructPreconditioner(condNumEst));
1017 set_extra_data<bool>(
1018 true, AOOLOWSF_constructedAztecPreconditoner_str,
1019 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY,
false
1030 if(aztecAdjSolver.get() && aztecAdjSolver->GetPrecOperator()) {
1031 aztecOp->initialize(
1032 fwdOp, fwdOpSrc,precUsed, prec.get()!=NULL, approxFwdOpSrc,
1033 aztecFwdSolver,
true, aztecAdjSolver,
true, epetra_epetraFwdOpScalar
1037 aztecOp->initialize(
1038 fwdOp, fwdOpSrc, precUsed, prec.get()!=NULL, approxFwdOpSrc,
1039 aztecFwdSolver,
true, null,
false, epetra_epetraFwdOpScalar
1042 aztecOp->fwdDefaultMaxIterations(defaultFwdMaxIterations_);
1043 aztecOp->fwdDefaultTol(defaultFwdTolerance_);
1044 aztecOp->adjDefaultMaxIterations(defaultAdjMaxIterations_);
1045 aztecOp->adjDefaultTol(defaultAdjTolerance_);
1046 aztecOp->outputEveryRhs(outputEveryRhs_);
1047 aztecOp->setOStream(this->getOStream());
1048 if(!is_null(this->getOverridingOStream()))
1049 aztecOp->setOverridingOStream(this->getOverridingOStream());
1050 aztecOp->setVerbLevel(this->getVerbLevel());
1053 if(paramList_.get())
1057 if(out.get() &&
static_cast<int>(verbLevel) >
static_cast<int>(Teuchos::VERB_LOW))
1058 *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.
RCP< const PreconditionerBase< double > > extract_prec()
Extract the preconditioner.
RCP< const LinearOpSourceBase< double > > extract_fwdOpSrc()
Extract the forward LinearOpBase<double> object so that it can be modified.
bool isExternalPrec() const
Determine if the preconditioner was external or not.
RCP< const LinearOpSourceBase< double > > extract_approxFwdOpSrc()
Extract the approximate forward LinearOpBase<double> object used to build the preconditioner.