10 #include "Teko_MLLinearOp.hpp"
12 #include "Teko_EpetraOperatorWrapper.hpp"
13 #include "Teko_mlutils.hpp"
14 #include "Teko_PreconditionerLinearOp.hpp"
16 #include "ml_MultiLevelPreconditioner.h"
20 MLLinearOp::MLLinearOp(
const Teuchos::RCP<ML_Epetra::MultiLevelPreconditioner> &mlPrecOp)
21 : mlPrecOp_(mlPrecOp) {
22 extractConversionInformation(*mlPrecOp_);
25 void MLLinearOp::extractConversionInformation(ML_Epetra::MultiLevelPreconditioner &mlPrec) {
26 const ML *ml = mlPrec.GetML();
27 const ML_Smoother *preSmoother = ml->pre_smoother;
28 const ML_Smoother *postSmoother = ml->post_smoother;
31 const mlutils::SmootherData *smootherData;
33 smootherData = (
const mlutils::SmootherData *)ML_Get_MySmootherData(preSmoother);
34 else if (postSmoother != 0)
35 smootherData = (
const mlutils::SmootherData *)ML_Get_MySmootherData(preSmoother);
37 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
38 "MLLinearOp::extractConversionInformation pre and post smoother "
39 <<
"are both null, cannot build operator");
41 Amat_ = Teuchos::rcp_dynamic_cast<Epetra::EpetraOperatorWrapper>(smootherData->Amat);
44 mappingStrategy_ = Amat_->getMapStrategy();
47 BlockedLinearOp bloA = toBlockedLinearOp(Amat_->getThyraOp());
50 productRange_ = bloA->productDomain();
53 void MLLinearOp::implicitApply(
const BlockedMultiVector &x, BlockedMultiVector &y,
54 const double alpha,
const double beta)
const {
55 int columns = x->domain()->dim();
56 TEUCHOS_ASSERT(columns == y->domain()->dim());
59 if (eX_ == Teuchos::null || columns != eX_->NumVectors()) {
60 eX_ = Teuchos::rcp(
new Epetra_MultiVector(mlPrecOp_->OperatorDomainMap(), x->domain()->dim()));
61 eY_ = Teuchos::rcp(
new Epetra_MultiVector(mlPrecOp_->OperatorRangeMap(), y->domain()->dim()));
64 BlockedMultiVector yCopy;
72 mappingStrategy_->copyThyraIntoEpetra(x, *eX_);
75 mlPrecOp_->ApplyInverse(*eX_, *eY_);
78 mappingStrategy_->copyEpetraIntoThyra(*eY_, yCopy.ptr());
82 update(alpha, yCopy, beta, y);
83 else if (alpha != 1.0)
87 void MLLinearOp::describe(Teuchos::FancyOStream &out_arg,
88 const Teuchos::EVerbosityLevel verbLevel)
const {
89 out_arg <<
"MLLinearOp";
92 Teuchos::RCP<const ML_Epetra::MultiLevelPreconditioner> MLLinearOp::getMLPreconditioner()
const {
96 Teuchos::RCP<ML_Epetra::MultiLevelPreconditioner> MLLinearOp::getMLPreconditioner() {
100 Teuchos::RCP<const ML_Epetra::MultiLevelPreconditioner> getMLPreconditioner(
101 const Teko::LinearOp &lo) {
102 Teko::LinearOp precOp = lo;
105 Teuchos::RCP<const Teko::PreconditionerLinearOp<double> > plo =
107 if (plo != Teuchos::null) precOp = plo->
getOperator();
110 Teuchos::RCP<const MLLinearOp> mlOp = Teuchos::rcp_dynamic_cast<
const MLLinearOp>(precOp);
112 TEUCHOS_TEST_FOR_EXCEPTION(
113 mlOp == Teuchos::null, std::runtime_error,
114 "Teko::getMLPreconditioner could not extract a MLLinearOp from the passed in argument");
116 return mlOp->getMLPreconditioner();
Teko::LinearOp getOperator() const
Get teko linear operator.
Class that wraps a PreconditionerBase object it makes it behave like a linear operator.