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 "ml_RefMaxwell.h"
51#include "Epetra_RowMatrix.h"
52#include "Teuchos_StandardParameterEntryValidators.hpp"
53#include "Teuchos_dyn_cast.hpp"
54#include "Teuchos_TimeMonitor.hpp"
55#include "Teuchos_implicit_cast.hpp"
56#include "Teuchos_ValidatorXMLConverterDB.hpp"
57#include "Teuchos_StaticSetupMacro.hpp"
58#include "Teuchos_iostream_helpers.hpp"
66 ML_PROBTYPE_SMOOTHED_AGGREGATION,
67 ML_PROBTYPE_NONSYMMETRIC_SMOOTHED_AGGREGATION,
68 ML_PROBTYPE_DOMAIN_DECOMPOSITION,
69 ML_PROBTYPE_DOMAIN_DECOMPOSITION_ML,
71 ML_PROBTYPE_REFMAXWELL
73const std::string BaseMethodDefaults_valueNames_none =
"none";
74const Teuchos::Array<std::string> BaseMethodDefaults_valueNames
75= Teuchos::tuple<std::string>(
76 BaseMethodDefaults_valueNames_none,
86TEUCHOS_ENUM_INPUT_STREAM_OPERATOR(EMLProblemType)
91 TEUCHOS_ADD_STRINGTOINTEGRALVALIDATOR_CONVERTER(EMLProblemType);
94const std::string BaseMethodDefaults_name =
"Base Method Defaults";
95const std::string BaseMethodDefaults_default =
"SA";
97 Teuchos::StringToIntegralParameterEntryValidator<EMLProblemType>
99BaseMethodDefaults_validator;
101const std::string ReuseFineLevelSmoother_name =
"Reuse Fine Level Smoother";
102const bool ReuseFineLevelSmoother_default =
false;
104const std::string MLSettings_name =
"ML Settings";
114using Teuchos::ParameterList;
121 :epetraFwdOpViewExtractor_(
Teuchos::rcp(new EpetraOperatorViewExtractorStd()))
129 const LinearOpSourceBase<double> &fwdOpSrc
132 using Teuchos::outArg;
133 Teuchos::RCP<const Epetra_Operator> epetraFwdOp;
134 EOpTransp epetraFwdOpTransp;
135 EApplyEpetraOpAs epetraFwdOpApplyAs;
136 EAdjointEpetraOp epetraFwdOpAdjointSupport;
137 double epetraFwdOpScalar;
138 Teuchos::RCP<const LinearOpBase<double> >
139 fwdOp = fwdOpSrc.getOp();
140 epetraFwdOpViewExtractor_->getEpetraOpView(
142 outArg(epetraFwdOp),outArg(epetraFwdOpTransp),
143 outArg(epetraFwdOpApplyAs),
144 outArg(epetraFwdOpAdjointSupport),
145 outArg(epetraFwdOpScalar)
147 if( !
dynamic_cast<const Epetra_RowMatrix*
>(&*epetraFwdOp) )
165RCP<PreconditionerBase<double> >
168 return Teuchos::rcp(
new DefaultPreconditioner<double>());
173 const Teuchos::RCP<
const LinearOpSourceBase<double> > &fwdOpSrc,
174 PreconditionerBase<double> *prec,
175 const ESupportSolveUse
178 using Teuchos::outArg;
179 using Teuchos::OSTab;
180 using Teuchos::dyn_cast;
184 using Teuchos::rcp_dynamic_cast;
185 using Teuchos::rcp_const_cast;
186 using Teuchos::set_extra_data;
187 using Teuchos::get_optional_extra_data;
188 using Teuchos::implicit_cast;
189 Teuchos::Time totalTimer(
""), timer(
"");
190 totalTimer.start(
true);
191 const RCP<Teuchos::FancyOStream> out = this->getOStream();
192 const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
193 Teuchos::OSTab tab(out);
194 if(out.get() && implicit_cast<int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW))
195 *out <<
"\nEntering Thyra::MLPreconditionerFactory::initializePrec(...) ...\n";
198 const EMLProblemType problemType = BaseMethodDefaults_validator->getIntegralValue(*
paramList_,BaseMethodDefaults_name,BaseMethodDefaults_default);
200 Teuchos::RCP<const LinearOpBase<double> > fwdOp = fwdOpSrc->getOp();
202 TEUCHOS_TEST_FOR_EXCEPT(fwdOp.get()==NULL);
203 TEUCHOS_TEST_FOR_EXCEPT(prec==NULL);
208 Teuchos::RCP<const Epetra_Operator> epetraFwdOp;
209 EOpTransp epetraFwdOpTransp;
210 EApplyEpetraOpAs epetraFwdOpApplyAs;
211 EAdjointEpetraOp epetraFwdOpAdjointSupport;
212 double epetraFwdOpScalar;
213 epetraFwdOpViewExtractor_->getEpetraOpView(
214 fwdOp,outArg(epetraFwdOp),outArg(epetraFwdOpTransp),outArg(epetraFwdOpApplyAs),
215 outArg(epetraFwdOpAdjointSupport),outArg(epetraFwdOpScalar)
218 RCP<const Epetra_RowMatrix>
219 epetraFwdRowMat = rcp_dynamic_cast<const Epetra_RowMatrix>(epetraFwdOp,
true);
220 TEUCHOS_TEST_FOR_EXCEPTION(
221 epetraFwdOpApplyAs != EPETRA_OP_APPLY_APPLY, std::logic_error
222 ,
"Error, incorrect apply mode for an Epetra_RowMatrix"
224 RCP<const Epetra_CrsMatrix> epetraFwdCrsMat = rcp_dynamic_cast<const Epetra_CrsMatrix>(epetraFwdRowMat);
229 DefaultPreconditioner<double>
230 *defaultPrec = &Teuchos::dyn_cast<DefaultPreconditioner<double> >(*prec);
235 epetra_precOp = rcp_dynamic_cast<EpetraLinearOp>(defaultPrec->getNonconstUnspecifiedPrecOp(),
true);
239 Teuchos::RCP<ML_Epetra::MultiLevelPreconditioner> ml_precOp;
240 Teuchos::RCP<ML_Epetra::RefMaxwellPreconditioner> rm_precOp;
241 if(epetra_precOp.get()) {
242 if(problemType == ML_PROBTYPE_REFMAXWELL)
243 rm_precOp = rcp_dynamic_cast<ML_Epetra::RefMaxwellPreconditioner>(epetra_precOp->epetra_op(),
true);
245 ml_precOp = rcp_dynamic_cast<ML_Epetra::MultiLevelPreconditioner>(epetra_precOp->epetra_op(),
true);
250 if(ml_precOp!=Teuchos::null) {
253 const Epetra_RowMatrix & rm = ml_precOp->RowMatrix();
255 TEUCHOS_TEST_FOR_EXCEPTION(
256 &rm!=&*epetraFwdRowMat, std::logic_error
257 ,
"ML requires Epetra_RowMatrix to be the same for each initialization of the preconditioner"
265 const bool startingOver = (ml_precOp.get() == NULL && rm_precOp.get() == NULL);
268 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
269 *out <<
"\nCreating the initial ML_Epetra::MultiLevelPreconditioner object...\n";
273 if(problemType==ML_PROBTYPE_REFMAXWELL)
274 rm_precOp = rcp(
new ML_Epetra::RefMaxwellPreconditioner(*epetraFwdCrsMat,
paramList_->sublist(MLSettings_name),
false));
276 ml_precOp = rcp(
new ML_Epetra::MultiLevelPreconditioner(*epetraFwdRowMat,
paramList_->sublist(MLSettings_name),
false));
280 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
281 OSTab(out).o() <<
"> Creation time = "<<timer.totalElapsedTime()<<
" sec\n";
290 if (problemType==ML_PROBTYPE_REFMAXWELL) {
291 TEUCHOS_TEST_FOR_EXCEPT(0!=rm_precOp->SetParameterList(
paramList_->sublist(MLSettings_name)));
294 TEUCHOS_TEST_FOR_EXCEPT(0!=ml_precOp->SetParameterList(
paramList_->sublist(MLSettings_name)));
301 if (problemType==ML_PROBTYPE_REFMAXWELL)
302 set_extra_data(epetraFwdOp,
"IFPF::epetraFwdOp", Teuchos::inOutArg(rm_precOp),
303 Teuchos::POST_DESTROY,
false);
305 set_extra_data(epetraFwdOp,
"IFPF::epetraFwdOp", Teuchos::inOutArg(ml_precOp),
306 Teuchos::POST_DESTROY,
false);
310 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
311 *out <<
"\nComputing the preconditioner ...\n";
313 if (problemType==ML_PROBTYPE_REFMAXWELL) {
315 TEUCHOS_TEST_FOR_EXCEPT(0!=rm_precOp->ComputePreconditioner());
318 TEUCHOS_TEST_FOR_EXCEPT(0!=rm_precOp->ReComputePreconditioner());
323 TEUCHOS_TEST_FOR_EXCEPT(0!=ml_precOp->ComputePreconditioner());
326 TEUCHOS_TEST_FOR_EXCEPT(0!=ml_precOp->ReComputePreconditioner(
paramList_->get<
bool>(ReuseFineLevelSmoother_name)));
330 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
331 OSTab(out).o() <<
"=> Setup time = "<<timer.totalElapsedTime()<<
" sec\n";
341 if (problemType==ML_PROBTYPE_REFMAXWELL)
342 set_extra_data(fwdOp,
"IFPF::fwdOp", Teuchos::inOutArg(rm_precOp),
343 Teuchos::POST_DESTROY,
false);
345 set_extra_data(fwdOp,
"IFPF::fwdOp", Teuchos::inOutArg(ml_precOp),
346 Teuchos::POST_DESTROY,
false);
351 epetra_precOp = rcp(
new EpetraLinearOp);
354 if (problemType==ML_PROBTYPE_REFMAXWELL)
355 epetra_precOp->initialize(rm_precOp,epetraFwdOpTransp,EPETRA_OP_APPLY_APPLY_INVERSE,EPETRA_OP_ADJOINT_UNSUPPORTED);
357 epetra_precOp->initialize(ml_precOp,epetraFwdOpTransp,EPETRA_OP_APPLY_APPLY_INVERSE,EPETRA_OP_ADJOINT_UNSUPPORTED);
361 defaultPrec->initializeUnspecified(
362 Teuchos::rcp_implicit_cast<LinearOpBase<double> >(epetra_precOp)
365 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
366 *out <<
"\nTotal time in MLPreconditionerFactory = "<<totalTimer.totalElapsedTime()<<
" sec\n";
367 if(out.get() && implicit_cast<int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW))
368 *out <<
"\nLeaving Thyra::MLPreconditionerFactory::initializePrec(...) ...\n";
373 PreconditionerBase<double> * ,
374 Teuchos::RCP<
const LinearOpSourceBase<double> > * ,
378 TEUCHOS_TEST_FOR_EXCEPT(
true);
386 Teuchos::RCP<ParameterList>
const& paramList
389 TEUCHOS_TEST_FOR_EXCEPT(paramList.get()==NULL);
396 if(!
paramList_->isType<
bool>(ReuseFineLevelSmoother_name))
397 paramList_->set<
bool>(ReuseFineLevelSmoother_name,ReuseFineLevelSmoother_default);
400 defaultType = BaseMethodDefaults_validator->getIntegralValue(
401 *
paramList_,BaseMethodDefaults_name,BaseMethodDefaults_default
403 if( ML_PROBTYPE_NONE != defaultType ) {
404 const std::string defaultTypeStr = BaseMethodDefaults_valueNames[defaultType];
407 Teuchos::ParameterList defaultParams;
408 if(defaultType == ML_PROBTYPE_REFMAXWELL) {
409 ML_Epetra::SetDefaultsRefMaxwell(defaultParams);
412 TEUCHOS_TEST_FOR_EXCEPTION(0!=ML_Epetra::SetDefaults(defaultTypeStr,defaultParams)
413 ,Teuchos::Exceptions::InvalidParameterValue
414 ,
"Error, the ML problem type \"" << defaultTypeStr <<
"\' is not recognized by ML!"
428 paramList_->sublist(MLSettings_name).setParametersNotAlreadySet(
445 Teuchos::RCP<ParameterList> _paramList =
paramList_;
451RCP<const ParameterList>
458RCP<const ParameterList>
466 using Teuchos::tuple;
467 using Teuchos::implicit_cast;
468 using Teuchos::rcp_implicit_cast;
469 typedef Teuchos::ParameterEntryValidator PEV;
471 static RCP<const ParameterList> validPL;
473 if(is_null(validPL)) {
476 pl = rcp(
new ParameterList());
478 BaseMethodDefaults_validator = rcp(
479 new Teuchos::StringToIntegralParameterEntryValidator<EMLProblemType>(
480 BaseMethodDefaults_valueNames,
482 "Do not set any default parameters",
483 "Set default parameters for a smoothed aggregation method",
484 "Set default parameters for a nonsymmetric smoothed aggregation method",
485 "Set default parameters for a domain decomposition method",
486 "Set default parameters for a domain decomposition method special to ML",
487 "Set default parameters for a Maxwell-type of preconditioner",
488 "Set default parameters for a RefMaxwell-type preconditioner"
490 tuple<EMLProblemType>(
492 ML_PROBTYPE_SMOOTHED_AGGREGATION,
493 ML_PROBTYPE_NONSYMMETRIC_SMOOTHED_AGGREGATION,
494 ML_PROBTYPE_DOMAIN_DECOMPOSITION,
495 ML_PROBTYPE_DOMAIN_DECOMPOSITION_ML,
497 ML_PROBTYPE_REFMAXWELL
499 BaseMethodDefaults_name
503 pl->set(BaseMethodDefaults_name,BaseMethodDefaults_default,
504 "Select the default method type which also sets parameter defaults\n"
505 "in the sublist \"" + MLSettings_name +
"\"!",
506 rcp_implicit_cast<const PEV>(BaseMethodDefaults_validator)
509 pl->set(ReuseFineLevelSmoother_name,ReuseFineLevelSmoother_default,
510 "Enables/disables the reuse of the fine level smoother.");
513 pl->set(MLSettings_name,mlpl,
514 "Sampling of the parameters directly accepted by ML\n"
515 "This list of parameters is generated by combining all of\n"
516 "the parameters set for all of the default problem types supported\n"
517 "by ML. Therefore, do not assume these parameters are at values that\n"
518 "are reasonable to ML. This list is just to give a sense of some of\n"
519 "the parameters that ML accepts. Consult ML documentation on how to\n"
520 "set these parameters. Also, you can print the parameter list after\n"
521 "it is used and see what defaults where set for each default problem\n"
522 "type. Warning! the parameters in this sublist are currently *not*\n"
523 "being validated by ML!"
540 std::ostringstream oss;
541 oss <<
"Thyra::MLPreconditionerFactory";
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
bool isCompatible(const LinearOpSourceBase< double > &fwdOp) const
MLPreconditionerFactory()
bool applySupportsConj(EConj conj) const
bool applyTransposeSupportsConj(EConj conj) const
std::string description() const
void uninitializePrec(PreconditionerBase< double > *prec, Teuchos::RCP< const LinearOpSourceBase< double > > *fwdOp, ESupportSolveUse *supportSolveUse) const
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
void initializePrec(const Teuchos::RCP< const LinearOpSourceBase< double > > &fwdOp, PreconditionerBase< double > *prec, const ESupportSolveUse supportSolveUse) const
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Teuchos::RCP< const Teuchos::ParameterList > getParameterList() const
Teuchos::RCP< PreconditionerBase< double > > createPrec() const
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const ¶mList)
Teuchos::RCP< Teuchos::ParameterList > paramList_