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