Teko  Version of the Day
 All Classes Files Functions Variables Pages
Teko_InverseFactoryOperator.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_InverseFactoryOperator.hpp"
11 
12 // Teko includes
13 #include "Teko_BasicMappingStrategy.hpp"
14 
15 // Thyra includes
16 #include "Thyra_EpetraLinearOp.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 Epetra {
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 
64 void InverseFactoryOperator::buildInverseOperator(const Teuchos::RCP<const Epetra_Operator>& A,
65  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<double> > 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 
94 void InverseFactoryOperator::buildInverseOperator(const Teuchos::RCP<Epetra_Operator>& A,
95  bool /* clear */) {
96  setConstFwdOp_ = false;
97 
98  fwdOp_.initialize(A);
99 
100  buildInverseOperator(A.getConst());
101 
102  TEUCHOS_ASSERT(setConstFwdOp_ == true);
103 }
104 
117 void InverseFactoryOperator::rebuildInverseOperator(const Teuchos::RCP<const Epetra_Operator>& A) {
118  Teko_DEBUG_SCOPE("InverseFactoryOperator::rebuildPreconditioner", 10);
119 
120  // if the inverse hasn't been built yet, rebuild from scratch
121  if (not firstBuildComplete_) {
122  buildInverseOperator(A, false);
123  return;
124  }
125 
126  RCP<const Thyra::LinearOpBase<double> > thyraA = extractLinearOp(A);
127  Teko::rebuildInverse(*inverseFactory_, thyraA, invOperator_);
128 
129  if (setConstFwdOp_) fwdOp_.initialize(A);
130 
131  SetOperator(invOperator_, false);
132 
133  setConstFwdOp_ = true;
134 
135  TEUCHOS_ASSERT(getForwardOp() != Teuchos::null);
136  TEUCHOS_ASSERT(invOperator_ != Teuchos::null);
137  TEUCHOS_ASSERT(getThyraOp() != Teuchos::null);
138  TEUCHOS_ASSERT(firstBuildComplete_ == true);
139 }
140 
141 void InverseFactoryOperator::rebuildInverseOperator(const Teuchos::RCP<Epetra_Operator>& A) {
142  setConstFwdOp_ = false;
143 
144  fwdOp_.initialize(A);
145 
146  // build from constant epetra operator
147  rebuildInverseOperator(A.getConst());
148 
149  TEUCHOS_ASSERT(setConstFwdOp_ == true);
150 }
151 
152 Teuchos::RCP<const Thyra::LinearOpBase<double> > InverseFactoryOperator::extractLinearOp(
153  const Teuchos::RCP<const Epetra_Operator>& A) const {
154  // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator
155  const RCP<const EpetraOperatorWrapper>& eow = rcp_dynamic_cast<const EpetraOperatorWrapper>(A);
156 
157  // if it is an EpetraOperatorWrapper, then get the Thyra operator
158  if (eow != Teuchos::null) return eow->getThyraOp();
159 
160  // otherwise wrap it up as a thyra operator
161  return Thyra::epetraLinearOp(A);
162 }
163 
164 Teuchos::RCP<const MappingStrategy> InverseFactoryOperator::extractMappingStrategy(
165  const Teuchos::RCP<const Epetra_Operator>& A) const {
166  // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator
167  const RCP<const EpetraOperatorWrapper>& eow = rcp_dynamic_cast<const EpetraOperatorWrapper>(A);
168 
169  // if it is an EpetraOperatorWrapper, then get the Thyra operator
170  if (eow != Teuchos::null) return eow->getMapStrategy();
171 
172  // otherwise wrap it up as a thyra operator
173  RCP<const Epetra_Map> range = rcpFromRef(A->OperatorRangeMap());
174  RCP<const Epetra_Map> domain = rcpFromRef(A->OperatorDomainMap());
175  return rcp(new BasicMappingStrategy(range, domain, A->Comm()));
176 }
177 
178 } // end namespace Epetra
179 } // end namespace Teko
void rebuildInverse(const InverseFactory &factory, const LinearOp &A, InverseLinearOp &invA)
Teuchos::RCP< const Epetra_Operator > getForwardOp() const
virtual void rebuildInverseOperator(const Teuchos::RCP< const Epetra_Operator > &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...
virtual void initInverse(bool clearOld=false)
Build the underlying data structure for the inverse operator.
Flip a mapping strategy object around to give the &quot;inverse&quot; mapping strategy.
const RCP< const MappingStrategy > getMapStrategy() const
Get the mapping strategy for this wrapper (translate between Thyra and Epetra)
InverseLinearOp buildInverse(const InverseFactory &factory, const LinearOp &A)
Build an inverse operator using a factory and a linear operator.
const RCP< const Thyra::LinearOpBase< double > > getThyraOp() const
Return the thyra operator associated with this wrapper.
virtual void buildInverseOperator(const Teuchos::RCP< const Epetra_Operator > &A, bool clear=true)
Build this inverse operator from an Epetra_Operator passed in to this object.