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" 61 Teuchos::RCP<Teuchos::Time> overallTimer, creationTimer, factorizationTimer;
63 const std::string Ifpack_name =
"Ifpack";
65 const std::string IfpackSettings_name =
"Ifpack Settings";
67 const std::string PrecType_name =
"Prec Type";
68 Teuchos::RCP<Teuchos::StringToIntegralParameterEntryValidator<Ifpack::EPrecType> >
70 const Ifpack::EPrecType PrecType_default = Ifpack::ILU;
71 const std::string PrecTypeName_default = Ifpack::precTypeNames[PrecType_default];
73 const std::string Overlap_name =
"Overlap";
74 const int Overlap_default = 0;
77 TEUCHOS_STATIC_SETUP()
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) )
131 Teuchos::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 supportSolveUse
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))
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> *prec
322 ,Teuchos::RCP<
const LinearOpSourceBase<double> > *fwdOpSrc
323 ,ESupportSolveUse *supportSolveUse
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);
353 Teuchos::RCP<Teuchos::ParameterList>
359 Teuchos::RCP<Teuchos::ParameterList>
362 Teuchos::RCP<Teuchos::ParameterList> _paramList =
paramList_;
367 Teuchos::RCP<const Teuchos::ParameterList>
373 Teuchos::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." 414 validParamList->sublist(
415 IfpackSettings_name,
false,
416 "Preconditioner settings that are passed onto the Ifpack preconditioners themselves." 417 ).setParameters(Ifpack_GetValidParameters());
423 Teuchos::setupVerboseObjectSublist(&*validParamList);
425 return validParamList;
432 std::ostringstream oss;
433 oss <<
"Thyra::IfpackPreconditionerFactory{";
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");
static void initializeTimers()
::Ifpack::EPrecType precType_
Teuchos::RCP< Teuchos::ParameterList > paramList_
void initializePrec(const Teuchos::RCP< const LinearOpSourceBase< double > > &fwdOpSrc, PreconditionerBase< double > *prec, const ESupportSolveUse supportSolveUse) const
bool applySupportsConj(EConj conj) const
std::string description() const
IfpackPreconditionerFactory()
void uninitializePrec(PreconditionerBase< double > *prec, Teuchos::RCP< const LinearOpSourceBase< double > > *fwdOpSrc, ESupportSolveUse *supportSolveUse) const
Teuchos::RCP< PreconditionerBase< double > > createPrec() const
bool isCompatible(const LinearOpSourceBase< double > &fwdOpSrc) const
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
bool applyTransposeSupportsConj(EConj conj) const
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const ¶mList)
Teuchos::RCP< const Teuchos::ParameterList > getParameterList() const
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
const char * toString(const ESolverType solverType)
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()