144 const Teuchos::RCP<
const LinearOpSourceBase<double> > &fwdOpSrc,
145 PreconditionerBase<double> *prec,
146 const ESupportSolveUse
149 using Teuchos::outArg;
150 using Teuchos::OSTab;
151 using Teuchos::dyn_cast;
155 using Teuchos::rcp_dynamic_cast;
156 using Teuchos::rcp_const_cast;
157 using Teuchos::set_extra_data;
158 using Teuchos::get_optional_extra_data;
159 using Teuchos::implicit_cast;
160 Teuchos::Time totalTimer(
""), timer(
"");
161 totalTimer.start(
true);
162 const RCP<Teuchos::FancyOStream> out = this->getOStream();
163 const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
164 Teuchos::OSTab tab(out);
165 if(out.get() && implicit_cast<int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW))
166 *out <<
"\nEntering Thyra::MLPreconditionerFactory::initializePrec(...) ...\n";
169 const EMLProblemType problemType = BaseMethodDefaults_validator->getIntegralValue(*paramList_,BaseMethodDefaults_name,BaseMethodDefaults_default);
171 Teuchos::RCP<const LinearOpBase<double> > fwdOp = fwdOpSrc->getOp();
173 TEUCHOS_TEST_FOR_EXCEPT(fwdOp.get()==NULL);
174 TEUCHOS_TEST_FOR_EXCEPT(prec==NULL);
179 Teuchos::RCP<const Epetra_Operator> epetraFwdOp;
180 EOpTransp epetraFwdOpTransp;
181 EApplyEpetraOpAs epetraFwdOpApplyAs;
182 EAdjointEpetraOp epetraFwdOpAdjointSupport;
183 double epetraFwdOpScalar;
184 epetraFwdOpViewExtractor_->getEpetraOpView(
185 fwdOp,outArg(epetraFwdOp),outArg(epetraFwdOpTransp),outArg(epetraFwdOpApplyAs),
186 outArg(epetraFwdOpAdjointSupport),outArg(epetraFwdOpScalar)
189 RCP<const Epetra_RowMatrix>
190 epetraFwdRowMat = rcp_dynamic_cast<const Epetra_RowMatrix>(epetraFwdOp,
true);
191 TEUCHOS_TEST_FOR_EXCEPTION(
192 epetraFwdOpApplyAs != EPETRA_OP_APPLY_APPLY, std::logic_error
193 ,
"Error, incorrect apply mode for an Epetra_RowMatrix"
195 RCP<const Epetra_CrsMatrix> epetraFwdCrsMat = rcp_dynamic_cast<const Epetra_CrsMatrix>(epetraFwdRowMat);
200 DefaultPreconditioner<double>
201 *defaultPrec = &Teuchos::dyn_cast<DefaultPreconditioner<double> >(*prec);
206 epetra_precOp = rcp_dynamic_cast<EpetraLinearOp>(defaultPrec->getNonconstUnspecifiedPrecOp(),
true);
210 Teuchos::RCP<ML_Epetra::MultiLevelPreconditioner> ml_precOp;
211 Teuchos::RCP<ML_Epetra::RefMaxwellPreconditioner> rm_precOp;
212 Teuchos::RCP<ML_Epetra::GradDivPreconditioner> gd_precOp;
213 if(epetra_precOp.get()) {
214 if(problemType == ML_PROBTYPE_REFMAXWELL)
215 rm_precOp = rcp_dynamic_cast<ML_Epetra::RefMaxwellPreconditioner>(epetra_precOp->epetra_op(),
true);
216 else if(problemType == ML_PROBTYPE_GRADDIV)
217 gd_precOp = rcp_dynamic_cast<ML_Epetra::GradDivPreconditioner>(epetra_precOp->epetra_op(),
true);
219 ml_precOp = rcp_dynamic_cast<ML_Epetra::MultiLevelPreconditioner>(epetra_precOp->epetra_op(),
true);
224 if(ml_precOp!=Teuchos::null) {
229 TEUCHOS_TEST_FOR_EXCEPTION(
230 &rm!=&*epetraFwdRowMat, std::logic_error
231 ,
"ML requires Epetra_RowMatrix to be the same for each initialization of the preconditioner"
239 const bool startingOver = (ml_precOp.get() == NULL && rm_precOp.get() == NULL);
242 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
243 *out <<
"\nCreating the initial ML_Epetra::MultiLevelPreconditioner object...\n";
247 if(problemType==ML_PROBTYPE_REFMAXWELL)
248 rm_precOp = rcp(
new ML_Epetra::RefMaxwellPreconditioner(*epetraFwdCrsMat, paramList_->sublist(MLSettings_name),
false));
249 else if(problemType==ML_PROBTYPE_GRADDIV)
250 gd_precOp = rcp(
new ML_Epetra::GradDivPreconditioner(*epetraFwdCrsMat, paramList_->sublist(MLSettings_name),
false));
252 ml_precOp = rcp(
new ML_Epetra::MultiLevelPreconditioner(*epetraFwdRowMat, paramList_->sublist(MLSettings_name),
false));
256 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
257 OSTab(out).o() <<
"> Creation time = "<<timer.totalElapsedTime()<<
" sec\n";
265 if(paramList_.get()) {
266 if (problemType==ML_PROBTYPE_REFMAXWELL) {
267 TEUCHOS_TEST_FOR_EXCEPT(0!=rm_precOp->SetParameterList(paramList_->sublist(MLSettings_name)));
269 else if (problemType==ML_PROBTYPE_GRADDIV) {
270 TEUCHOS_TEST_FOR_EXCEPT(0!=gd_precOp->SetParameterList(paramList_->sublist(MLSettings_name)));
273 TEUCHOS_TEST_FOR_EXCEPT(0!=ml_precOp->SetParameterList(paramList_->sublist(MLSettings_name)));
280 if (problemType==ML_PROBTYPE_REFMAXWELL)
281 set_extra_data(epetraFwdOp,
"IFPF::epetraFwdOp", Teuchos::inOutArg(rm_precOp),
282 Teuchos::POST_DESTROY,
false);
283 else if (problemType==ML_PROBTYPE_GRADDIV)
284 set_extra_data(epetraFwdOp,
"IFPF::epetraFwdOp", Teuchos::inOutArg(gd_precOp),
285 Teuchos::POST_DESTROY,
false);
287 set_extra_data(epetraFwdOp,
"IFPF::epetraFwdOp", Teuchos::inOutArg(ml_precOp),
288 Teuchos::POST_DESTROY,
false);
292 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
293 *out <<
"\nComputing the preconditioner ...\n";
295 if (problemType==ML_PROBTYPE_REFMAXWELL) {
297 TEUCHOS_TEST_FOR_EXCEPT(0!=rm_precOp->ComputePreconditioner());
300 TEUCHOS_TEST_FOR_EXCEPT(0!=rm_precOp->ReComputePreconditioner());
303 else if (problemType==ML_PROBTYPE_GRADDIV) {
305 TEUCHOS_TEST_FOR_EXCEPT(0!=gd_precOp->ComputePreconditioner());
308 TEUCHOS_TEST_FOR_EXCEPT(0!=gd_precOp->ReComputePreconditioner());
313 TEUCHOS_TEST_FOR_EXCEPT(0!=ml_precOp->ComputePreconditioner());
316 TEUCHOS_TEST_FOR_EXCEPT(0!=ml_precOp->ReComputePreconditioner(paramList_->get<
bool>(ReuseFineLevelSmoother_name)));
320 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
321 OSTab(out).o() <<
"=> Setup time = "<<timer.totalElapsedTime()<<
" sec\n";
331 if (problemType==ML_PROBTYPE_REFMAXWELL)
332 set_extra_data(fwdOp,
"IFPF::fwdOp", Teuchos::inOutArg(rm_precOp),
333 Teuchos::POST_DESTROY,
false);
334 else if (problemType==ML_PROBTYPE_GRADDIV)
335 set_extra_data(fwdOp,
"IFPF::fwdOp", Teuchos::inOutArg(gd_precOp),
336 Teuchos::POST_DESTROY,
false);
338 set_extra_data(fwdOp,
"IFPF::fwdOp", Teuchos::inOutArg(ml_precOp),
339 Teuchos::POST_DESTROY,
false);
344 epetra_precOp = rcp(
new EpetraLinearOp);
347 if (problemType==ML_PROBTYPE_REFMAXWELL)
348 epetra_precOp->initialize(rm_precOp,epetraFwdOpTransp,EPETRA_OP_APPLY_APPLY_INVERSE,EPETRA_OP_ADJOINT_UNSUPPORTED);
349 else if (problemType==ML_PROBTYPE_GRADDIV)
350 epetra_precOp->initialize(gd_precOp,epetraFwdOpTransp,EPETRA_OP_APPLY_APPLY_INVERSE,EPETRA_OP_ADJOINT_UNSUPPORTED);
352 epetra_precOp->initialize(ml_precOp,epetraFwdOpTransp,EPETRA_OP_APPLY_APPLY_INVERSE,EPETRA_OP_ADJOINT_UNSUPPORTED);
356 defaultPrec->initializeUnspecified(
357 Teuchos::rcp_implicit_cast<LinearOpBase<double> >(epetra_precOp)
360 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
361 *out <<
"\nTotal time in MLPreconditionerFactory = "<<totalTimer.totalElapsedTime()<<
" sec\n";
362 if(out.get() && implicit_cast<int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW))
363 *out <<
"\nLeaving Thyra::MLPreconditionerFactory::initializePrec(...) ...\n";