Teko  Version of the Day
 All Classes Files Functions Variables Pages
Teko_TpetraInverseFactoryOperator.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_TpetraInverseFactoryOperator.hpp"
11 
12 // Teko includes
13 #include "Teko_TpetraBasicMappingStrategy.hpp"
14 
15 // Thyra includes
16 #include "Thyra_TpetraLinearOp.hpp"
17 
18 using Teuchos::RCP;
19 using Teuchos::rcp;
20 using Teuchos::rcp_dynamic_cast;
21 using Teuchos::rcpFromRef;
22 
23 namespace Teko {
24 namespace TpetraHelpers {
25 
32 InverseFactoryOperator::InverseFactoryOperator(const Teuchos::RCP<const InverseFactory>& ifp)
33  : inverseFactory_(ifp), firstBuildComplete_(false), setConstFwdOp_(true) {}
34 
48  if (not clearOld) return;
49  invOperator_ = Teuchos::null;
50 }
51 
65  const Teuchos::RCP<const Tpetra::Operator<ST, LO, GO, NT> >& A, bool clear) {
66  Teko_DEBUG_SCOPE("InverseFactoryOperator::buildInverseOperator", 10);
67 
68  // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator
69  RCP<const Thyra::LinearOpBase<ST> > thyraA = extractLinearOp(A);
70 
71  // set the mapping strategy
72  SetMapStrategy(rcp(new InverseMappingStrategy(extractMappingStrategy(A))));
73 
74  initInverse(clear);
75 
76  // actually build the inverse operator
77  invOperator_ = Teko::buildInverse(*inverseFactory_, thyraA);
78 
79  SetOperator(invOperator_, false);
80 
81  firstBuildComplete_ = true;
82 
83  if (setConstFwdOp_) fwdOp_ = A;
84 
85  setConstFwdOp_ = true;
86 
87  TEUCHOS_ASSERT(invOperator_ != Teuchos::null);
88  TEUCHOS_ASSERT(getForwardOp() != Teuchos::null);
89  TEUCHOS_ASSERT(getThyraOp() != Teuchos::null);
90  TEUCHOS_ASSERT(getMapStrategy() != Teuchos::null);
91  TEUCHOS_ASSERT(firstBuildComplete_ == true);
92 }
93 
95  const Teuchos::RCP<Tpetra::Operator<ST, LO, GO, NT> >& A, bool /* clear */) {
96  setConstFwdOp_ = false;
97 
98  fwdOp_.initialize(A);
99 
100  buildInverseOperator(A.getConst());
101 
102  TEUCHOS_ASSERT(setConstFwdOp_ == true);
103 }
104 
118  const Teuchos::RCP<const Tpetra::Operator<ST, LO, GO, NT> >& A) {
119  Teko_DEBUG_SCOPE("InverseFactoryOperator::rebuildPreconditioner", 10);
120 
121  // if the inverse hasn't been built yet, rebuild from scratch
122  if (not firstBuildComplete_) {
123  buildInverseOperator(A, false);
124  return;
125  }
126 
127  RCP<const Thyra::LinearOpBase<ST> > thyraA = extractLinearOp(A);
128  Teko::rebuildInverse(*inverseFactory_, thyraA, invOperator_);
129 
130  if (setConstFwdOp_) fwdOp_.initialize(A);
131 
132  SetOperator(invOperator_, false);
133 
134  setConstFwdOp_ = true;
135 
136  TEUCHOS_ASSERT(getForwardOp() != Teuchos::null);
137  TEUCHOS_ASSERT(invOperator_ != Teuchos::null);
138  TEUCHOS_ASSERT(getThyraOp() != Teuchos::null);
139  TEUCHOS_ASSERT(firstBuildComplete_ == true);
140 }
141 
143  const Teuchos::RCP<Tpetra::Operator<ST, LO, GO, NT> >& A) {
144  setConstFwdOp_ = false;
145 
146  fwdOp_.initialize(A);
147 
148  // build from constant epetra operator
149  rebuildInverseOperator(A.getConst());
150 
151  TEUCHOS_ASSERT(setConstFwdOp_ == true);
152 }
153 
154 Teuchos::RCP<const Thyra::LinearOpBase<ST> > InverseFactoryOperator::extractLinearOp(
155  const Teuchos::RCP<const Tpetra::Operator<ST, LO, GO, NT> >& A) const {
156  // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator
157  const RCP<const TpetraOperatorWrapper>& eow = rcp_dynamic_cast<const TpetraOperatorWrapper>(A);
158 
159  // if it is an EpetraOperatorWrapper, then get the Thyra operator
160  if (eow != Teuchos::null) return eow->getThyraOp();
161 
162  // otherwise wrap it up as a thyra operator
163  return Thyra::constTpetraLinearOp<ST, LO, GO, NT>(
164  Thyra::tpetraVectorSpace<ST, LO, GO, NT>(A->getRangeMap()),
165  Thyra::tpetraVectorSpace<ST, LO, GO, NT>(A->getDomainMap()), A);
166 }
167 
168 Teuchos::RCP<const MappingStrategy> InverseFactoryOperator::extractMappingStrategy(
169  const Teuchos::RCP<const Tpetra::Operator<ST, LO, GO, NT> >& A) const {
170  // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator
171  const RCP<const TpetraOperatorWrapper>& eow = rcp_dynamic_cast<const TpetraOperatorWrapper>(A);
172 
173  // if it is an EpetraOperatorWrapper, then get the Thyra operator
174  if (eow != Teuchos::null) return eow->getMapStrategy();
175 
176  // otherwise wrap it up as a thyra operator
177  RCP<const Tpetra::Map<LO, GO, NT> > range = A->getRangeMap();
178  RCP<const Tpetra::Map<LO, GO, NT> > domain = A->getDomainMap();
179  return rcp(
180  new BasicMappingStrategy(range, domain, *Thyra::convertTpetraToThyraComm(range->getComm())));
181 }
182 
183 } // end namespace TpetraHelpers
184 } // end namespace Teko
void rebuildInverse(const InverseFactory &factory, const LinearOp &A, InverseLinearOp &invA)
virtual void initInverse(bool clearOld=false)
Build the underlying data structure for the inverse operator.
virtual void buildInverseOperator(const Teuchos::RCP< const Tpetra::Operator< ST, LO, GO, NT > > &A, bool clear=true)
Build this inverse operator from an Epetra_Operator passed in to this object.
Teuchos::RCP< const Tpetra::Operator< ST, LO, GO, NT > > getForwardOp() const
const RCP< const Thyra::LinearOpBase< ST > > getThyraOp() const
Return the thyra operator associated with this wrapper.
Flip a mapping strategy object around to give the &quot;inverse&quot; mapping strategy.
InverseLinearOp buildInverse(const InverseFactory &factory, const LinearOp &A)
Build an inverse operator using a factory and a linear operator.
const RCP< const MappingStrategy > getMapStrategy() const
Get the mapping strategy for this wrapper (translate between Thyra and Epetra)
virtual void rebuildInverseOperator(const Teuchos::RCP< const Tpetra::Operator< ST, LO, GO, NT > > &A)
Rebuild this inverse from an Epetra_Operator passed in this to object.
Implements the Epetra_Operator interface with a Thyra LinearOperator. This enables the use of absrtac...