Teko Version of the Day
Loading...
Searching...
No Matches
Teko_TpetraBlockPreconditioner.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_TpetraBlockPreconditioner.hpp"
11#include "Teko_Preconditioner.hpp"
12
13// Thyra includes
14#include "Thyra_DefaultLinearOpSource.hpp"
15#include "Thyra_TpetraLinearOp.hpp"
16
17// Teuchos includes
18#include "Teuchos_Time.hpp"
19
20// Teko includes
21#include "Teko_TpetraBasicMappingStrategy.hpp"
22#include "Teko_Utilities.hpp"
23
24namespace Teko {
25namespace TpetraHelpers {
26
27using Teuchos::RCP;
28using Teuchos::rcp;
29using Teuchos::rcp_dynamic_cast;
30using Teuchos::rcpFromRef;
31
39 const Teuchos::RCP<const PreconditionerFactory>& bfp)
40 : preconFactory_(bfp), firstBuildComplete_(false) {}
41
43 if ((not clearOld) && preconObj_ != Teuchos::null) return;
44 preconObj_ = preconFactory_->createPrec();
45}
46
60 const Teuchos::RCP<const Tpetra::Operator<ST, LO, GO, NT> >& A, bool clear) {
61 Teko_DEBUG_SCOPE("TBP::buildPreconditioner", 10);
62
63 // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator
64 RCP<const Thyra::LinearOpBase<ST> > thyraA = extractLinearOp(A);
65
66 // set the mapping strategy
67 // SetMapStrategy(rcp(new InverseMappingStrategy(eow->getMapStrategy())));
68 SetMapStrategy(rcp(new InverseMappingStrategy(extractMappingStrategy(A))));
69
70 // build preconObj_
71 initPreconditioner(clear);
72
73 // actually build the preconditioner
74 RCP<const Thyra::LinearOpSourceBase<ST> > lOpSrc = Thyra::defaultLinearOpSource(thyraA);
75 preconFactory_->initializePrec(lOpSrc, &*preconObj_, Thyra::SUPPORT_SOLVE_UNSPECIFIED);
76
77 // extract preconditioner operator
78 RCP<const Thyra::LinearOpBase<ST> > preconditioner = preconObj_->getUnspecifiedPrecOp();
79
80 SetOperator(preconditioner, false);
81
82 firstBuildComplete_ = true;
83
84 TEUCHOS_ASSERT(preconObj_ != Teuchos::null);
85 TEUCHOS_ASSERT(getThyraOp() != Teuchos::null);
86 TEUCHOS_ASSERT(getMapStrategy() != Teuchos::null);
87 TEUCHOS_ASSERT(firstBuildComplete_ == true);
88}
89
104 const Teuchos::RCP<const Tpetra::Operator<ST, LO, GO, NT> >& A,
105 const Tpetra::MultiVector<ST, LO, GO, NT>& tpetra_mv, bool clear) {
106 Teko_DEBUG_SCOPE("TBP::buildPreconditioner - with solution", 10);
107
108 // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator
109 RCP<const Thyra::LinearOpBase<ST> > thyraA = extractLinearOp(A);
110
111 // set the mapping strategy
112 SetMapStrategy(rcp(new InverseMappingStrategy(extractMappingStrategy(A))));
113
114 TEUCHOS_ASSERT(getMapStrategy() != Teuchos::null);
115
116 // build the thyra version of the source multivector
117 RCP<Thyra::MultiVectorBase<ST> > thyra_mv =
118 Thyra::createMembers(thyraA->range(), tpetra_mv.getNumVectors());
119 getMapStrategy()->copyTpetraIntoThyra(tpetra_mv, thyra_mv.ptr());
120
121 // build preconObj_
122 initPreconditioner(clear);
123
124 // actually build the preconditioner
125 preconFactory_->initializePrec(Thyra::defaultLinearOpSource(thyraA), thyra_mv, &*preconObj_,
126 Thyra::SUPPORT_SOLVE_UNSPECIFIED);
127 RCP<const Thyra::LinearOpBase<ST> > preconditioner = preconObj_->getUnspecifiedPrecOp();
128
129 SetOperator(preconditioner, false);
130
131 firstBuildComplete_ = true;
132
133 TEUCHOS_ASSERT(preconObj_ != Teuchos::null);
134 TEUCHOS_ASSERT(getThyraOp() != Teuchos::null);
135 TEUCHOS_ASSERT(getMapStrategy() != Teuchos::null);
136 TEUCHOS_ASSERT(firstBuildComplete_ == true);
137}
138
153 const Teuchos::RCP<const Tpetra::Operator<ST, LO, GO, NT> >& A) {
154 Teko_DEBUG_SCOPE("TBP::rebuildPreconditioner", 10);
155
156 // if the preconditioner hasn't been built yet, rebuild from scratch
157 if (not firstBuildComplete_) {
158 buildPreconditioner(A, false);
159 return;
160 }
161 Teko_DEBUG_EXPR(Teuchos::Time timer(""));
162
163 // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator
164 Teko_DEBUG_EXPR(timer.start(true));
165 RCP<const Thyra::LinearOpBase<ST> > thyraA = extractLinearOp(A);
166 Teko_DEBUG_EXPR(timer.stop());
167 Teko_DEBUG_MSG("TBP::rebuild get thyraop time = " << timer.totalElapsedTime(), 2);
168
169 // reinitialize the preconditioner
170 Teko_DEBUG_EXPR(timer.start(true));
171 preconFactory_->initializePrec(Thyra::defaultLinearOpSource(thyraA), &*preconObj_,
172 Thyra::SUPPORT_SOLVE_UNSPECIFIED);
173 RCP<const Thyra::LinearOpBase<ST> > preconditioner = preconObj_->getUnspecifiedPrecOp();
174 Teko_DEBUG_EXPR(timer.stop());
175 Teko_DEBUG_MSG("TBP::rebuild initialize prec time = " << timer.totalElapsedTime(), 2);
176
177 Teko_DEBUG_EXPR(timer.start(true));
178 SetOperator(preconditioner, false);
179 Teko_DEBUG_EXPR(timer.stop());
180 Teko_DEBUG_MSG("TBP::rebuild set operator time = " << timer.totalElapsedTime(), 2);
181
182 TEUCHOS_ASSERT(preconObj_ != Teuchos::null);
183 TEUCHOS_ASSERT(getThyraOp() != Teuchos::null);
184 TEUCHOS_ASSERT(firstBuildComplete_ == true);
185}
186
201 const Teuchos::RCP<const Tpetra::Operator<ST, LO, GO, NT> >& A,
202 const Tpetra::MultiVector<ST, LO, GO, NT>& tpetra_mv) {
203 Teko_DEBUG_SCOPE("TBP::rebuildPreconditioner - with solution", 10);
204
205 // if the preconditioner hasn't been built yet, rebuild from scratch
206 if (not firstBuildComplete_) {
207 buildPreconditioner(A, tpetra_mv, false);
208 return;
209 }
210 Teko_DEBUG_EXPR(Teuchos::Time timer(""));
211
212 // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator
213 Teko_DEBUG_EXPR(timer.start(true));
214 RCP<const Thyra::LinearOpBase<ST> > thyraA = extractLinearOp(A);
215 Teko_DEBUG_EXPR(timer.stop());
216 Teko_DEBUG_MSG("TBP::rebuild get thyraop time = " << timer.totalElapsedTime(), 2);
217
218 // build the thyra version of the source multivector
219 Teko_DEBUG_EXPR(timer.start(true));
220 RCP<Thyra::MultiVectorBase<ST> > thyra_mv =
221 Thyra::createMembers(thyraA->range(), tpetra_mv.getNumVectors());
222 getMapStrategy()->copyTpetraIntoThyra(tpetra_mv, thyra_mv.ptr());
223 Teko_DEBUG_EXPR(timer.stop());
224 Teko_DEBUG_MSG("TBP::rebuild vector copy time = " << timer.totalElapsedTime(), 2);
225
226 // reinitialize the preconditioner
227 Teko_DEBUG_EXPR(timer.start(true));
228 preconFactory_->initializePrec(Thyra::defaultLinearOpSource(thyraA), thyra_mv, &*preconObj_,
229 Thyra::SUPPORT_SOLVE_UNSPECIFIED);
230 RCP<const Thyra::LinearOpBase<ST> > preconditioner = preconObj_->getUnspecifiedPrecOp();
231 Teko_DEBUG_EXPR(timer.stop());
232 Teko_DEBUG_MSG("TBP::rebuild initialize prec time = " << timer.totalElapsedTime(), 2);
233
234 Teko_DEBUG_EXPR(timer.start(true));
235 SetOperator(preconditioner, false);
236 Teko_DEBUG_EXPR(timer.stop());
237 Teko_DEBUG_MSG("TBP::rebuild set operator time = " << timer.totalElapsedTime(), 2);
238
239 TEUCHOS_ASSERT(preconObj_ != Teuchos::null);
240 TEUCHOS_ASSERT(getThyraOp() != Teuchos::null);
241 TEUCHOS_ASSERT(firstBuildComplete_ == true);
242}
243
253Teuchos::RCP<PreconditionerState> TpetraBlockPreconditioner::getPreconditionerState() {
254 Teuchos::RCP<Preconditioner> bp = rcp_dynamic_cast<Preconditioner>(preconObj_);
255
256 if (bp != Teuchos::null) return bp->getStateObject();
257
258 return Teuchos::null;
259}
260
270Teuchos::RCP<const PreconditionerState> TpetraBlockPreconditioner::getPreconditionerState() const {
271 Teuchos::RCP<const Preconditioner> bp = rcp_dynamic_cast<const Preconditioner>(preconObj_);
272
273 if (bp != Teuchos::null) return bp->getStateObject();
274
275 return Teuchos::null;
276}
277
278Teuchos::RCP<const Thyra::LinearOpBase<ST> > TpetraBlockPreconditioner::extractLinearOp(
279 const Teuchos::RCP<const Tpetra::Operator<ST, LO, GO, NT> >& A) const {
280 // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator
281 const RCP<const TpetraOperatorWrapper>& tow = rcp_dynamic_cast<const TpetraOperatorWrapper>(A);
282
283 // if it is an EpetraOperatorWrapper, then get the Thyra operator
284 if (tow != Teuchos::null) return tow->getThyraOp();
285
286 // otherwise wrap it up as a thyra operator
287 return Thyra::constTpetraLinearOp<ST, LO, GO, NT>(
288 Thyra::tpetraVectorSpace<ST, LO, GO, NT>(A->getDomainMap()),
289 Thyra::tpetraVectorSpace<ST, LO, GO, NT>(A->getRangeMap()), A);
290}
291
292Teuchos::RCP<const MappingStrategy> TpetraBlockPreconditioner::extractMappingStrategy(
293 const Teuchos::RCP<const Tpetra::Operator<ST, LO, GO, NT> >& A) const {
294 // extract EpetraOperatorWrapper (throw on failure) and corresponding thyra operator
295 const RCP<const TpetraOperatorWrapper>& tow = rcp_dynamic_cast<const TpetraOperatorWrapper>(A);
296
297 // if it is an EpetraOperatorWrapper, then get the Thyra operator
298 if (tow != Teuchos::null) return tow->getMapStrategy();
299
300 // otherwise wrap it up as a thyra operator
301 RCP<const Tpetra::Map<LO, GO, NT> > range = A->getRangeMap();
302 RCP<const Tpetra::Map<LO, GO, NT> > domain = A->getDomainMap();
303 return rcp(
304 new BasicMappingStrategy(range, domain, *Thyra::convertTpetraToThyraComm(range->getComm())));
305}
306
307} // namespace TpetraHelpers
308} // end namespace Teko
Flip a mapping strategy object around to give the "inverse" mapping strategy.
TpetraBlockPreconditioner(const Teuchos::RCP< const PreconditionerFactory > &bfp)
Constructor that takes the BlockPreconditionerFactory that will build the preconditioner.
virtual Teuchos::RCP< PreconditionerState > getPreconditionerState()
virtual void initPreconditioner(bool clearOld=false)
Build the underlying data structure for the preconditioner.
virtual void buildPreconditioner(const Teuchos::RCP< const Tpetra::Operator< ST, LO, GO, NT > > &A, bool clear=true)
Build this preconditioner from an Epetra_Operator passed in to this object.
virtual void rebuildPreconditioner(const Teuchos::RCP< const Tpetra::Operator< ST, LO, GO, NT > > &A)
Rebuild this preconditioner from an Epetra_Operator passed in this to object.
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.