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