43#include "Thyra_EpetraOperatorViewExtractorStd.hpp"
44#include "Thyra_EpetraLinearOp.hpp"
45#include "Thyra_DefaultPreconditioner.hpp"
46#include "Ifpack_ValidParameters.h"
47#include "Ifpack_Preconditioner.h"
49#include "Epetra_RowMatrix.h"
50#include "Teuchos_TimeMonitor.hpp"
51#include "Teuchos_dyn_cast.hpp"
52#include "Teuchos_implicit_cast.hpp"
53#include "Teuchos_StandardParameterEntryValidators.hpp"
54#include "Teuchos_VerboseObjectParameterListHelpers.hpp"
55#include "Teuchos_ValidatorXMLConverterDB.hpp"
56#include "Teuchos_StaticSetupMacro.hpp"
61Teuchos::RCP<Teuchos::Time> overallTimer, creationTimer, factorizationTimer;
63const std::string Ifpack_name =
"Ifpack";
65const std::string IfpackSettings_name =
"Ifpack Settings";
67const std::string PrecType_name =
"Prec Type";
68Teuchos::RCP<Teuchos::StringToIntegralParameterEntryValidator<Ifpack::EPrecType> >
70const Ifpack::EPrecType PrecType_default = Ifpack::ILU;
71const std::string PrecTypeName_default = Ifpack::precTypeNames[PrecType_default];
73const std::string Overlap_name =
"Overlap";
74const int Overlap_default = 0;
79 TEUCHOS_ADD_STRINGTOINTEGRALVALIDATOR_CONVERTER(Ifpack::EPrecType);
90 :epetraFwdOpViewExtractor_(
Teuchos::rcp(new EpetraOperatorViewExtractorStd()))
91 ,precType_(PrecType_default)
92 ,overlap_(Overlap_default)
101 const LinearOpSourceBase<double> &fwdOpSrc
104 using Teuchos::outArg;
105 Teuchos::RCP<const Epetra_Operator> epetraFwdOp;
106 EOpTransp epetraFwdOpTransp;
107 EApplyEpetraOpAs epetraFwdOpApplyAs;
108 EAdjointEpetraOp epetraFwdOpAdjointSupport;
109 double epetraFwdOpScalar;
110 epetraFwdOpViewExtractor_->getEpetraOpView(
112 outArg(epetraFwdOp), outArg(epetraFwdOpTransp),
113 outArg(epetraFwdOpApplyAs), outArg(epetraFwdOpAdjointSupport),
114 outArg(epetraFwdOpScalar)
116 if( !
dynamic_cast<const Epetra_RowMatrix*
>(&*epetraFwdOp) )
131Teuchos::RCP<PreconditionerBase<double> >
134 return Teuchos::rcp(
new DefaultPreconditioner<double>());
138 const Teuchos::RCP<
const LinearOpSourceBase<double> > &fwdOpSrc
139 ,PreconditionerBase<double> *prec
140 ,
const ESupportSolveUse
143 using Teuchos::outArg;
144 using Teuchos::OSTab;
145 using Teuchos::dyn_cast;
149 using Teuchos::rcp_dynamic_cast;
150 using Teuchos::rcp_const_cast;
151 using Teuchos::set_extra_data;
152 using Teuchos::get_optional_extra_data;
153 using Teuchos::implicit_cast;
154 Teuchos::Time totalTimer(
""), timer(
"");
155 totalTimer.start(
true);
156#ifdef STRATIMIKOS_TEUCHOS_TIME_MONITOR
157 Teuchos::TimeMonitor overallTimeMonitor(*overallTimer);
159 const Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
160 const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
161 Teuchos::OSTab tab(out);
162 if(out.get() && implicit_cast<int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW))
163 *out <<
"\nEntering Thyra::IfpackPreconditionerFactory::initializePrec(...) ...\n";
165 TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc.get()==NULL);
166 TEUCHOS_TEST_FOR_EXCEPT(prec==NULL);
168 Teuchos::RCP<const LinearOpBase<double> >
169 fwdOp = fwdOpSrc->getOp();
171 TEUCHOS_TEST_FOR_EXCEPT(fwdOp.get()==NULL);
176 Teuchos::RCP<const Epetra_Operator> epetraFwdOp;
177 EOpTransp epetraFwdOpTransp;
178 EApplyEpetraOpAs epetraFwdOpApplyAs;
179 EAdjointEpetraOp epetraFwdOpAdjointSupport;
180 double epetraFwdOpScalar;
181 epetraFwdOpViewExtractor_->getEpetraOpView(
183 outArg(epetraFwdOp), outArg(epetraFwdOpTransp),
184 outArg(epetraFwdOpApplyAs), outArg(epetraFwdOpAdjointSupport),
185 outArg(epetraFwdOpScalar)
188 RCP<const Epetra_RowMatrix>
189 epetraFwdRowMat = rcp_dynamic_cast<const Epetra_RowMatrix>(epetraFwdOp,
true);
190 TEUCHOS_TEST_FOR_EXCEPTION(
191 epetraFwdOpApplyAs != EPETRA_OP_APPLY_APPLY, std::logic_error
192 ,
"Error, incorrect apply mode for an Epetra_RowMatrix"
197 DefaultPreconditioner<double>
198 *defaultPrec = &Teuchos::dyn_cast<DefaultPreconditioner<double> >(*prec);
203 epetra_precOp = rcp_dynamic_cast<EpetraLinearOp>(defaultPrec->getNonconstUnspecifiedPrecOp(),
true);
207 Teuchos::RCP<Ifpack_Preconditioner>
209 if(epetra_precOp.get())
210 ifpack_precOp = rcp_dynamic_cast<Ifpack_Preconditioner>(epetra_precOp->epetra_op(),
true);
214 if(ifpack_precOp.get()) {
222 const bool startingOver =
true;
229 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
230 *out <<
"\nCreating the initial Ifpack_Preconditioner object of type \'"<<Ifpack::toString(
precType_)<<
"\' ...\n";
232#ifdef STRATIMIKOS_TEUCHOS_TIME_MONITOR
233 Teuchos::TimeMonitor creationTimeMonitor(*creationTimer);
239 ,
const_cast<Epetra_RowMatrix*
>(&*epetraFwdRowMat)
244 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
245 OSTab(out).o() <<
"=> Creation time = "<<timer.totalElapsedTime()<<
" sec\n";
248 Teuchos::ParameterList
249 &ifpackSettingsPL =
paramList_->sublist(IfpackSettings_name);
251 TEUCHOS_TEST_FOR_EXCEPT(0!=ifpack_precOp->SetParameters(ifpackSettingsPL));
256 TEUCHOS_TEST_FOR_EXCEPT(0!=ifpack_precOp->Initialize());
261 set_extra_data(epetraFwdOp,
"IFPF::epetraFwdOp", Teuchos::inOutArg(ifpack_precOp),
262 Teuchos::POST_DESTROY,
false);
267 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
268 *out <<
"\nComputing the preconditioner ...\n";
269#ifdef STRATIMIKOS_TEUCHOS_TIME_MONITOR
270 Teuchos::TimeMonitor factorizationTimeMonitor(*factorizationTimer);
273 TEUCHOS_TEST_FOR_EXCEPT(0!=ifpack_precOp->Compute());
275 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
276 OSTab(out).o() <<
"=> Setup time = "<<timer.totalElapsedTime()<<
" sec\n";
287 set_extra_data(fwdOpSrc,
"IFPF::fwdOpSrc", Teuchos::inOutArg(ifpack_precOp),
288 Teuchos::POST_DESTROY,
false);
293 epetra_precOp = rcp(
new EpetraLinearOp);
295 epetra_precOp->initialize(
298 ,EPETRA_OP_APPLY_APPLY_INVERSE
299 ,EPETRA_OP_ADJOINT_SUPPORTED
301 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_MEDIUM)) {
302 *out <<
"\nDescription of created preconditioner:\n";
304 ifpack_precOp->Print(*out);
310 defaultPrec->initializeUnspecified(
311 Teuchos::rcp_implicit_cast<LinearOpBase<double> >(epetra_precOp)
314 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
315 *out <<
"\nTotal time in IfpackPreconditionerFactory = "<<totalTimer.totalElapsedTime()<<
" sec\n";
316 if(out.get() && implicit_cast<int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW))
317 *out <<
"\nLeaving Thyra::IfpackPreconditionerFactory::initializePrec(...) ...\n";
321 PreconditionerBase<double> *
322 ,Teuchos::RCP<
const LinearOpSourceBase<double> > *
326 TEUCHOS_TEST_FOR_EXCEPT(
true);
333 TEUCHOS_TEST_FOR_EXCEPT(paramList.get()==NULL);
339 std::ostringstream oss;
340 oss <<
"(sub)list \""<<paramList->name()<<
"\"parameter \"Prec Type\"";
343 ? precTypeValidator->getIntegralValue(*
paramList_,PrecType_name,PrecTypeName_default)
346 Teuchos::readVerboseObjectSublist(&*
paramList_,
this);
353Teuchos::RCP<Teuchos::ParameterList>
359Teuchos::RCP<Teuchos::ParameterList>
362 Teuchos::RCP<Teuchos::ParameterList> _paramList =
paramList_;
367Teuchos::RCP<const Teuchos::ParameterList>
373Teuchos::RCP<const Teuchos::ParameterList>
377 using Teuchos::rcp_implicit_cast;
378 typedef Teuchos::ParameterEntryValidator PEV;
379 static Teuchos::RCP<Teuchos::ParameterList> validParamList;
380 if(validParamList.get()==NULL) {
381 validParamList = Teuchos::rcp(
new Teuchos::ParameterList(Ifpack_name));
384 Teuchos::Array<std::string>
386 precTypeNames.insert(
387 precTypeNames.begin(),
388 &Ifpack::precTypeNames[0],
389 &Ifpack::precTypeNames[0] + Ifpack::numPrecTypes
391 Teuchos::Array<Ifpack::EPrecType>
393 precTypeValues.insert(
394 precTypeValues.begin(),
395 &Ifpack::precTypeValues[0],
396 &Ifpack::precTypeValues[0] + Ifpack::numPrecTypes
398 precTypeValidator = rcp(
399 new Teuchos::StringToIntegralParameterEntryValidator<Ifpack::EPrecType>(
400 precTypeNames,precTypeValues,PrecType_name
405 PrecType_name, PrecTypeName_default,
406 "Type of Ifpack preconditioner to use.",
407 rcp_implicit_cast<const PEV>(precTypeValidator)
410 Overlap_name, Overlap_default,
411 "Number of rows/columns overlapped between subdomains in different"
412 "\nprocesses in the additive Schwarz-type domain-decomposition preconditioners."
415 IfpackSettings_name, Ifpack_GetValidParameters(),
416 "Preconditioner settings that are passed onto the Ifpack preconditioners themselves."
423 Teuchos::setupVerboseObjectSublist(&*validParamList);
425 return validParamList;
432 std::ostringstream oss;
433 oss <<
"Thyra::IfpackPreconditionerFactory{";
434 oss <<
"precType=\"" << ::Ifpack::toString(
precType_) <<
"\"";
444 if(!overallTimer.get()) {
445#ifdef STRATIMIKOS_TEUCHOS_TIME_MONITOR
446 overallTimer = Teuchos::TimeMonitor::getNewTimer(
"Stratimikos: IfpackPF");
447 creationTimer = Teuchos::TimeMonitor::getNewTimer(
"Stratimikos: IfpackPF:Creation");
448 factorizationTimer = Teuchos::TimeMonitor::getNewTimer(
"Stratimikos: IfpackPF:Factorization");
Teuchos::RCP< Teuchos::ParameterList > paramList_
bool applySupportsConj(EConj conj) const
Teuchos::RCP< const Teuchos::ParameterList > getParameterList() const
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const ¶mList)
std::string description() const
::Ifpack::EPrecType precType_
static void initializeTimers()
void uninitializePrec(PreconditionerBase< double > *prec, Teuchos::RCP< const LinearOpSourceBase< double > > *fwdOpSrc, ESupportSolveUse *supportSolveUse) const
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Teuchos::RCP< PreconditionerBase< double > > createPrec() const
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
bool applyTransposeSupportsConj(EConj conj) const
IfpackPreconditionerFactory()
bool isCompatible(const LinearOpSourceBase< double > &fwdOpSrc) const
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
void initializePrec(const Teuchos::RCP< const LinearOpSourceBase< double > > &fwdOpSrc, PreconditionerBase< double > *prec, const ESupportSolveUse supportSolveUse) const