42 #include "Thyra_MLPreconditionerFactory.hpp" 44 #include "Thyra_EpetraOperatorViewExtractorStd.hpp" 45 #include "Thyra_EpetraLinearOp.hpp" 46 #include "Thyra_DefaultPreconditioner.hpp" 47 #include "ml_MultiLevelPreconditioner.h" 48 #include "ml_MultiLevelOperator.h" 49 #include "ml_ValidateParameters.h" 50 #include "Epetra_RowMatrix.h" 51 #include "Teuchos_StandardParameterEntryValidators.hpp" 52 #include "Teuchos_dyn_cast.hpp" 53 #include "Teuchos_TimeMonitor.hpp" 54 #include "Teuchos_implicit_cast.hpp" 55 #include "Teuchos_ValidatorXMLConverterDB.hpp" 56 #include "Teuchos_StaticSetupMacro.hpp" 57 #include "Teuchos_iostream_helpers.hpp" 65 ML_PROBTYPE_SMOOTHED_AGGREGATION,
66 ML_PROBTYPE_NONSYMMETRIC_SMOOTHED_AGGREGATION,
67 ML_PROBTYPE_DOMAIN_DECOMPOSITION,
68 ML_PROBTYPE_DOMAIN_DECOMPOSITION_ML,
71 const std::string BaseMethodDefaults_valueNames_none =
"none";
72 const Teuchos::Array<std::string> BaseMethodDefaults_valueNames
73 = Teuchos::tuple<std::string>(
74 BaseMethodDefaults_valueNames_none,
83 TEUCHOS_ENUM_INPUT_STREAM_OPERATOR(EMLProblemType)
86 TEUCHOS_STATIC_SETUP()
88 TEUCHOS_ADD_STRINGTOINTEGRALVALIDATOR_CONVERTER(EMLProblemType);
91 const std::string BaseMethodDefaults_name =
"Base Method Defaults";
92 const std::string BaseMethodDefaults_default =
"SA";
94 Teuchos::StringToIntegralParameterEntryValidator<EMLProblemType>
96 BaseMethodDefaults_validator;
98 const std::string ReuseFineLevelSmoother_name =
"Reuse Fine Level Smoother";
99 const bool ReuseFineLevelSmoother_default =
false;
101 const std::string MLSettings_name =
"ML Settings";
111 using Teuchos::ParameterList;
118 :epetraFwdOpViewExtractor_(
Teuchos::rcp(new EpetraOperatorViewExtractorStd()))
126 const LinearOpSourceBase<double> &fwdOpSrc
129 using Teuchos::outArg;
130 Teuchos::RCP<const Epetra_Operator> epetraFwdOp;
131 EOpTransp epetraFwdOpTransp;
132 EApplyEpetraOpAs epetraFwdOpApplyAs;
133 EAdjointEpetraOp epetraFwdOpAdjointSupport;
134 double epetraFwdOpScalar;
135 Teuchos::RCP<const LinearOpBase<double> >
136 fwdOp = fwdOpSrc.getOp();
137 epetraFwdOpViewExtractor_->getEpetraOpView(
139 outArg(epetraFwdOp),outArg(epetraFwdOpTransp),
140 outArg(epetraFwdOpApplyAs),
141 outArg(epetraFwdOpAdjointSupport),
142 outArg(epetraFwdOpScalar)
144 if( !dynamic_cast<const Epetra_RowMatrix*>(&*epetraFwdOp) )
162 RCP<PreconditionerBase<double> >
165 return Teuchos::rcp(
new DefaultPreconditioner<double>());
170 const Teuchos::RCP<
const LinearOpSourceBase<double> > &fwdOpSrc,
171 PreconditionerBase<double> *prec,
172 const ESupportSolveUse supportSolveUse
175 using Teuchos::outArg;
176 using Teuchos::OSTab;
177 using Teuchos::dyn_cast;
181 using Teuchos::rcp_dynamic_cast;
182 using Teuchos::rcp_const_cast;
183 using Teuchos::set_extra_data;
184 using Teuchos::get_optional_extra_data;
185 using Teuchos::implicit_cast;
186 Teuchos::Time totalTimer(
""), timer(
"");
187 totalTimer.start(
true);
188 const RCP<Teuchos::FancyOStream> out = this->getOStream();
189 const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
190 Teuchos::OSTab tab(out);
191 if(out.get() && implicit_cast<
int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW))
192 *out <<
"\nEntering Thyra::MLPreconditionerFactory::initializePrec(...) ...\n";
194 Teuchos::RCP<const LinearOpBase<double> > fwdOp = fwdOpSrc->getOp();
196 TEUCHOS_TEST_FOR_EXCEPT(fwdOp.get()==NULL);
197 TEUCHOS_TEST_FOR_EXCEPT(prec==NULL);
202 Teuchos::RCP<const Epetra_Operator> epetraFwdOp;
203 EOpTransp epetraFwdOpTransp;
204 EApplyEpetraOpAs epetraFwdOpApplyAs;
205 EAdjointEpetraOp epetraFwdOpAdjointSupport;
206 double epetraFwdOpScalar;
207 epetraFwdOpViewExtractor_->getEpetraOpView(
208 fwdOp,outArg(epetraFwdOp),outArg(epetraFwdOpTransp),outArg(epetraFwdOpApplyAs),
209 outArg(epetraFwdOpAdjointSupport),outArg(epetraFwdOpScalar)
212 RCP<const Epetra_RowMatrix>
213 epetraFwdRowMat = rcp_dynamic_cast<
const Epetra_RowMatrix>(epetraFwdOp,
true);
214 TEUCHOS_TEST_FOR_EXCEPTION(
215 epetraFwdOpApplyAs != EPETRA_OP_APPLY_APPLY, std::logic_error
216 ,
"Error, incorrect apply mode for an Epetra_RowMatrix" 222 DefaultPreconditioner<double>
223 *defaultPrec = &Teuchos::dyn_cast<DefaultPreconditioner<double> >(*prec);
228 epetra_precOp = rcp_dynamic_cast<EpetraLinearOp>(defaultPrec->getNonconstUnspecifiedPrecOp(),
true);
232 Teuchos::RCP<ML_Epetra::MultiLevelPreconditioner> ml_precOp;
233 if(epetra_precOp.get())
234 ml_precOp = rcp_dynamic_cast<ML_Epetra::MultiLevelPreconditioner>(epetra_precOp->epetra_op(),
true);
238 if(ml_precOp!=Teuchos::null) {
241 const Epetra_RowMatrix & rm = ml_precOp->RowMatrix();
243 TEUCHOS_TEST_FOR_EXCEPTION(
244 &rm!=&*epetraFwdRowMat, std::logic_error
245 ,
"ML requires Epetra_RowMatrix to be the same for each initialization of the preconditioner" 251 const bool startingOver = (ml_precOp.get() == NULL);
254 if(out.get() && implicit_cast<
int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
255 *out <<
"\nCreating the initial ML_Epetra::MultiLevelPreconditioner object...\n";
259 new ML_Epetra::MultiLevelPreconditioner(
260 *epetraFwdRowMat, paramList_->sublist(MLSettings_name),false
265 if(out.get() && implicit_cast<
int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
266 OSTab(out).o() <<
"> Creation time = "<<timer.totalElapsedTime()<<
" sec\n";
275 TEUCHOS_TEST_FOR_EXCEPT(
276 0!=ml_precOp->SetParameterList(paramList_->sublist(MLSettings_name))
284 set_extra_data(epetraFwdOp,
"IFPF::epetraFwdOp", Teuchos::inOutArg(ml_precOp),
285 Teuchos::POST_DESTROY,
false);
289 if(out.get() && implicit_cast<
int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
290 *out <<
"\nComputing the preconditioner ...\n";
293 TEUCHOS_TEST_FOR_EXCEPT(0!=ml_precOp->ComputePreconditioner());
296 TEUCHOS_TEST_FOR_EXCEPT(0!=ml_precOp->ReComputePreconditioner(paramList_->get<
bool>(ReuseFineLevelSmoother_name)));
299 if(out.get() && implicit_cast<
int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
300 OSTab(out).o() <<
"=> Setup time = "<<timer.totalElapsedTime()<<
" sec\n";
310 set_extra_data(fwdOp,
"IFPF::fwdOp", Teuchos::inOutArg(ml_precOp),
311 Teuchos::POST_DESTROY,
false);
316 epetra_precOp = rcp(
new EpetraLinearOp);
318 epetra_precOp->initialize(
321 ,EPETRA_OP_APPLY_APPLY_INVERSE
322 ,EPETRA_OP_ADJOINT_UNSUPPORTED
327 defaultPrec->initializeUnspecified(
328 Teuchos::rcp_implicit_cast<LinearOpBase<double> >(epetra_precOp)
331 if(out.get() && implicit_cast<
int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
332 *out <<
"\nTotal time in MLPreconditionerFactory = "<<totalTimer.totalElapsedTime()<<
" sec\n";
333 if(out.get() && implicit_cast<
int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW))
334 *out <<
"\nLeaving Thyra::MLPreconditionerFactory::initializePrec(...) ...\n";
339 PreconditionerBase<double> *prec,
340 Teuchos::RCP<
const LinearOpSourceBase<double> > *fwdOp,
341 ESupportSolveUse *supportSolveUse
344 TEUCHOS_TEST_FOR_EXCEPT(
true);
352 Teuchos::RCP<ParameterList>
const& paramList
355 TEUCHOS_TEST_FOR_EXCEPT(paramList.get()==NULL);
357 paramList_ = paramList;
360 if(!paramList_->isType<
bool>(ReuseFineLevelSmoother_name))
361 paramList_->set<
bool>(ReuseFineLevelSmoother_name,ReuseFineLevelSmoother_default);
364 defaultType = BaseMethodDefaults_validator->getIntegralValue(
365 *paramList_,BaseMethodDefaults_name,BaseMethodDefaults_default
367 if( ML_PROBTYPE_NONE != defaultType ) {
369 defaultTypeStr = BaseMethodDefaults_valueNames[defaultType];
370 Teuchos::ParameterList defaultParams;
371 TEUCHOS_TEST_FOR_EXCEPTION(
372 0!=ML_Epetra::SetDefaults(defaultTypeStr,defaultParams)
373 ,Teuchos::Exceptions::InvalidParameterValue
374 ,
"Error, the ML problem type \"" << defaultTypeStr <<
"\' is not recognized by ML!" 386 paramList_->sublist(MLSettings_name).setParametersNotAlreadySet(
405 Teuchos::RCP<ParameterList> _paramList = paramList_;
406 paramList_ = Teuchos::null;
411 RCP<const ParameterList>
418 RCP<const ParameterList>
423 using Teuchos::tuple;
424 using Teuchos::implicit_cast;
425 using Teuchos::rcp_implicit_cast;
426 typedef Teuchos::ParameterEntryValidator PEV;
428 static RCP<const ParameterList> validPL;
430 if(is_null(validPL)) {
433 pl = rcp(
new ParameterList());
435 BaseMethodDefaults_validator = rcp(
436 new Teuchos::StringToIntegralParameterEntryValidator<EMLProblemType>(
437 BaseMethodDefaults_valueNames,
439 "Do not set any default parameters",
440 "Set default parameters for a smoothed aggregation method",
441 "Set default parameters for a nonsymmetric smoothed aggregation method",
442 "Set default parameters for a domain decomposition method",
443 "Set default parameters for a domain decomposition method special to ML",
444 "Set default parameters for a Maxwell-type of linear operator" 446 tuple<EMLProblemType>(
448 ML_PROBTYPE_SMOOTHED_AGGREGATION,
449 ML_PROBTYPE_NONSYMMETRIC_SMOOTHED_AGGREGATION,
450 ML_PROBTYPE_DOMAIN_DECOMPOSITION,
451 ML_PROBTYPE_DOMAIN_DECOMPOSITION_ML,
454 BaseMethodDefaults_name
458 pl->set(BaseMethodDefaults_name,BaseMethodDefaults_default,
459 "Select the default method type which also sets parameter defaults\n" 460 "in the sublist \"" + MLSettings_name +
"\"!",
461 rcp_implicit_cast<const PEV>(BaseMethodDefaults_validator)
464 pl->set(ReuseFineLevelSmoother_name,ReuseFineLevelSmoother_default,
465 "Enables/disables the reuse of the fine level smoother.");
479 ParameterList &mlSettingsPL = pl->sublist(
480 MLSettings_name,
false,
481 "Sampling of the parameters directly accepted by ML\n" 482 "This list of parameters is generated by combining all of\n" 483 "the parameters set for all of the default problem types supported\n" 484 "by ML. Therefore, do not assume these parameters are at values that\n" 485 "are reasonable to ML. This list is just to give a sense of some of\n" 486 "the parameters that ML accepts. Consult ML documentation on how to\n" 487 "set these parameters. Also, you can print the parameter list after\n" 488 "it is used and see what defaults where set for each default problem\n" 489 "type. Warning! the parameters in this sublist are currently *not*\n" 490 "being validated by ML!" 496 i < implicit_cast<int>(BaseMethodDefaults_valueNames.size());
500 ParameterList defaultParams;
501 const std::string defaultTypeStr = BaseMethodDefaults_valueNames[i];
502 if (defaultTypeStr != BaseMethodDefaults_valueNames_none) {
503 TEUCHOS_TEST_FOR_EXCEPTION(
504 0!=ML_Epetra::SetDefaults(defaultTypeStr,defaultParams)
505 ,Teuchos::Exceptions::InvalidParameterValue
506 ,
"Error, the ML problem type \"" << defaultTypeStr
507 <<
"\' is not recognized by ML!" 509 mlSettingsPL.setParameters(defaultParams);
529 std::ostringstream oss;
530 oss <<
"Thyra::MLPreconditionerFactory";
bool isCompatible(const LinearOpSourceBase< double > &fwdOp) const
std::string description() const
Teuchos::RCP< const Teuchos::ParameterList > getParameterList() const
bool applyTransposeSupportsConj(EConj conj) const
void uninitializePrec(PreconditionerBase< double > *prec, Teuchos::RCP< const LinearOpSourceBase< double > > *fwdOp, ESupportSolveUse *supportSolveUse) const
MLPreconditionerFactory()
bool applySupportsConj(EConj conj) const
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const ¶mList)
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Teuchos::RCP< PreconditionerBase< double > > createPrec() const
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
void initializePrec(const Teuchos::RCP< const LinearOpSourceBase< double > > &fwdOp, PreconditionerBase< double > *prec, const ESupportSolveUse supportSolveUse) const