Teko Version of the Day
Loading...
Searching...
No Matches
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
18using Teuchos::RCP;
19using Teuchos::rcp;
20using Teuchos::rcp_dynamic_cast;
21using Teuchos::rcpFromRef;
22
23namespace Teko {
24namespace TpetraHelpers {
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
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
154Teuchos::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
168Teuchos::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
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.
InverseFactoryOperator(const Teuchos::RCP< const InverseFactory > &bfp)
Constructor that takes the InverseFactory that will build the operator.
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.
virtual void initInverse(bool clearOld=false)
Build the underlying data structure for the inverse operator.
Teuchos::RCP< const Tpetra::Operator< ST, LO, GO, NT > > getForwardOp() const
Flip a mapping strategy object around to give the "inverse" mapping strategy.
const RCP< const MappingStrategy > getMapStrategy() const
Get the mapping strategy for this wrapper (translate between Thyra and Epetra).
const RCP< const Thyra::LinearOpBase< ST > > getThyraOp() const
Return the thyra operator associated with this wrapper.