Teko Version of the Day
Loading...
Searching...
No Matches
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
18using Teuchos::RCP;
19using Teuchos::rcp;
20using Teuchos::rcp_dynamic_cast;
21using Teuchos::rcpFromRef;
22
23namespace Teko {
24namespace Epetra {
25
32InverseFactoryOperator::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
64void 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
94void 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
117void 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
141void 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
152Teuchos::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
164Teuchos::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
const RCP< const MappingStrategy > getMapStrategy() const
Get the mapping strategy for this wrapper (translate between Thyra and Epetra).
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.
InverseFactoryOperator(const Teuchos::RCP< const InverseFactory > &bfp)
Constructor that takes the InverseFactory that will build the operator.
virtual void initInverse(bool clearOld=false)
Build the underlying data structure for the inverse operator.
virtual void rebuildInverseOperator(const Teuchos::RCP< const Epetra_Operator > &A)
Rebuild this inverse from an Epetra_Operator passed in this to object.
Teuchos::RCP< const Epetra_Operator > getForwardOp() const
Flip a mapping strategy object around to give the "inverse" mapping strategy.