Teko  Version of the Day
 All Classes Files Functions Variables Pages
Teko_MLLinearOp.cpp
1 #include "Teko_MLLinearOp.hpp"
2 
3 #include "Teko_EpetraOperatorWrapper.hpp"
4 #include "Teko_mlutils.hpp"
5 #include "Teko_PreconditionerLinearOp.hpp"
6 
7 #include "ml_MultiLevelPreconditioner.h"
8 
9 namespace Teko {
10 
11 MLLinearOp::MLLinearOp(const Teuchos::RCP<ML_Epetra::MultiLevelPreconditioner> &mlPrecOp)
12  : mlPrecOp_(mlPrecOp) {
13  extractConversionInformation(*mlPrecOp_);
14 }
15 
16 void MLLinearOp::extractConversionInformation(ML_Epetra::MultiLevelPreconditioner &mlPrec) {
17  const ML *ml = mlPrec.GetML();
18  const ML_Smoother *preSmoother = ml->pre_smoother;
19  const ML_Smoother *postSmoother = ml->post_smoother;
20 
21  // grab data object
22  const mlutils::SmootherData *smootherData;
23  if (preSmoother != 0)
24  smootherData = (const mlutils::SmootherData *)ML_Get_MySmootherData(preSmoother);
25  else if (postSmoother != 0)
26  smootherData = (const mlutils::SmootherData *)ML_Get_MySmootherData(preSmoother);
27  else
28  TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
29  "MLLinearOp::extractConversionInformation pre and post smoother "
30  << "are both null, cannot build operator");
31 
32  Amat_ = Teuchos::rcp_dynamic_cast<Epetra::EpetraOperatorWrapper>(smootherData->Amat);
33 
34  // for doing Epetra_Vector -> Thyra vector conversion
35  mappingStrategy_ = Amat_->getMapStrategy();
36 
37  // to construct vectorspace for this object
38  BlockedLinearOp bloA = toBlockedLinearOp(Amat_->getThyraOp());
39  productDomain_ =
40  bloA->productRange(); // this operator is the inverse of bloA...hence swap range and domain
41  productRange_ = bloA->productDomain();
42 }
43 
44 void MLLinearOp::implicitApply(const BlockedMultiVector &x, BlockedMultiVector &y,
45  const double alpha, const double beta) const {
46  int columns = x->domain()->dim();
47  TEUCHOS_ASSERT(columns == y->domain()->dim()); // check for equal columns
48 
49  // (re)allocate vectors conditinolly if required size changed
50  if (eX_ == Teuchos::null || columns != eX_->NumVectors()) {
51  eX_ = Teuchos::rcp(new Epetra_MultiVector(mlPrecOp_->OperatorDomainMap(), x->domain()->dim()));
52  eY_ = Teuchos::rcp(new Epetra_MultiVector(mlPrecOp_->OperatorRangeMap(), y->domain()->dim()));
53  }
54 
55  BlockedMultiVector yCopy;
56  if (beta != 0)
57  yCopy = deepcopy(y);
58  else
59  yCopy = y;
60 
61  // initialize Epetra vectors
62  eY_->PutScalar(0.0);
63  mappingStrategy_->copyThyraIntoEpetra(x, *eX_);
64 
65  // run multigrid
66  mlPrecOp_->ApplyInverse(*eX_, *eY_);
67 
68  // fill thyra vectors
69  mappingStrategy_->copyEpetraIntoThyra(*eY_, yCopy.ptr());
70 
71  // scale result by alpha
72  if (beta != 0)
73  update(alpha, yCopy, beta, y); // y = alpha * yCopy + beta * y
74  else if (alpha != 1.0)
75  scale(alpha, y); // y = alpha * y
76 }
77 
78 void MLLinearOp::describe(Teuchos::FancyOStream &out_arg,
79  const Teuchos::EVerbosityLevel verbLevel) const {
80  out_arg << "MLLinearOp";
81 }
82 
83 Teuchos::RCP<const ML_Epetra::MultiLevelPreconditioner> MLLinearOp::getMLPreconditioner() const {
84  return mlPrecOp_;
85 }
86 
87 Teuchos::RCP<ML_Epetra::MultiLevelPreconditioner> MLLinearOp::getMLPreconditioner() {
88  return mlPrecOp_;
89 }
90 
91 Teuchos::RCP<const ML_Epetra::MultiLevelPreconditioner> getMLPreconditioner(
92  const Teko::LinearOp &lo) {
93  Teko::LinearOp precOp = lo;
94 
95  // try to pull it of a preconditioner linear op
96  Teuchos::RCP<const Teko::PreconditionerLinearOp<double> > plo =
97  Teuchos::rcp_dynamic_cast<const Teko::PreconditionerLinearOp<double> >(lo);
98  if (plo != Teuchos::null) precOp = plo->getOperator();
99 
100  // try to extract the ML operator
101  Teuchos::RCP<const MLLinearOp> mlOp = Teuchos::rcp_dynamic_cast<const MLLinearOp>(precOp);
102 
103  TEUCHOS_TEST_FOR_EXCEPTION(
104  mlOp == Teuchos::null, std::runtime_error,
105  "Teko::getMLPreconditioner could not extract a MLLinearOp from the passed in argument");
106 
107  return mlOp->getMLPreconditioner();
108 }
109 
110 } // namespace Teko
Teko::LinearOp getOperator() const
Get teko linear operator.
Class that wraps a PreconditionerBase object it makes it behave like a linear operator.