Teko Version of the Day
Loading...
Searching...
No Matches
Teko_MLLinearOp.cpp
1// @HEADER
2// *****************************************************************************
3// Teko: A package for block and physics based preconditioning
4//
5// Copyright 2010 NTESS and the Teko contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#include "Teko_MLLinearOp.hpp"
11
12#include "Teko_EpetraOperatorWrapper.hpp"
13#include "Teko_mlutils.hpp"
14#include "Teko_PreconditionerLinearOp.hpp"
15
16#include "ml_MultiLevelPreconditioner.h"
17
18namespace Teko {
19
20MLLinearOp::MLLinearOp(const Teuchos::RCP<ML_Epetra::MultiLevelPreconditioner> &mlPrecOp)
21 : mlPrecOp_(mlPrecOp) {
22 extractConversionInformation(*mlPrecOp_);
23}
24
25void 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;
29
30 // grab data object
31 const mlutils::SmootherData *smootherData;
32 if (preSmoother != 0)
33 smootherData = (const mlutils::SmootherData *)ML_Get_MySmootherData(preSmoother);
34 else if (postSmoother != 0)
35 smootherData = (const mlutils::SmootherData *)ML_Get_MySmootherData(preSmoother);
36 else
37 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
38 "MLLinearOp::extractConversionInformation pre and post smoother "
39 << "are both null, cannot build operator");
40
41 Amat_ = Teuchos::rcp_dynamic_cast<Epetra::EpetraOperatorWrapper>(smootherData->Amat);
42
43 // for doing Epetra_Vector -> Thyra vector conversion
44 mappingStrategy_ = Amat_->getMapStrategy();
45
46 // to construct vectorspace for this object
47 BlockedLinearOp bloA = toBlockedLinearOp(Amat_->getThyraOp());
48 productDomain_ =
49 bloA->productRange(); // this operator is the inverse of bloA...hence swap range and domain
50 productRange_ = bloA->productDomain();
51}
52
53void 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()); // check for equal columns
57
58 // (re)allocate vectors conditinolly if required size changed
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()));
62 }
63
64 BlockedMultiVector yCopy;
65 if (beta != 0)
66 yCopy = deepcopy(y);
67 else
68 yCopy = y;
69
70 // initialize Epetra vectors
71 eY_->PutScalar(0.0);
72 mappingStrategy_->copyThyraIntoEpetra(x, *eX_);
73
74 // run multigrid
75 mlPrecOp_->ApplyInverse(*eX_, *eY_);
76
77 // fill thyra vectors
78 mappingStrategy_->copyEpetraIntoThyra(*eY_, yCopy.ptr());
79
80 // scale result by alpha
81 if (beta != 0)
82 update(alpha, yCopy, beta, y); // y = alpha * yCopy + beta * y
83 else if (alpha != 1.0)
84 scale(alpha, y); // y = alpha * y
85}
86
87void MLLinearOp::describe(Teuchos::FancyOStream &out_arg,
88 const Teuchos::EVerbosityLevel verbLevel) const {
89 out_arg << "MLLinearOp";
90}
91
92Teuchos::RCP<const ML_Epetra::MultiLevelPreconditioner> MLLinearOp::getMLPreconditioner() const {
93 return mlPrecOp_;
94}
95
96Teuchos::RCP<ML_Epetra::MultiLevelPreconditioner> MLLinearOp::getMLPreconditioner() {
97 return mlPrecOp_;
98}
99
100Teuchos::RCP<const ML_Epetra::MultiLevelPreconditioner> getMLPreconditioner(
101 const Teko::LinearOp &lo) {
102 Teko::LinearOp precOp = lo;
103
104 // try to pull it of a preconditioner linear op
105 Teuchos::RCP<const Teko::PreconditionerLinearOp<double> > plo =
106 Teuchos::rcp_dynamic_cast<const Teko::PreconditionerLinearOp<double> >(lo);
107 if (plo != Teuchos::null) precOp = plo->getOperator();
108
109 // try to extract the ML operator
110 Teuchos::RCP<const MLLinearOp> mlOp = Teuchos::rcp_dynamic_cast<const MLLinearOp>(precOp);
111
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");
115
116 return mlOp->getMLPreconditioner();
117}
118
119} // namespace Teko
MultiVector deepcopy(const MultiVector &v)
Perform a deep copy of the vector.