Teko  Version of the Day
 All Classes Files Functions Variables Pages
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 
24 namespace Teko {
25 namespace TpetraHelpers {
26 
27 using Teuchos::RCP;
28 using Teuchos::rcp;
29 using Teuchos::rcp_dynamic_cast;
30 using Teuchos::rcpFromRef;
31 
38 TpetraBlockPreconditioner::TpetraBlockPreconditioner(
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 
253 Teuchos::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 
270 Teuchos::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 
278 Teuchos::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 
292 Teuchos::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
virtual const RCP< PreconditionerState > getStateObject()
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 Teuchos::RCP< PreconditionerState > getPreconditionerState()
const RCP< const Thyra::LinearOpBase< ST > > getThyraOp() const
Return the thyra operator associated with this wrapper.
Flip a mapping strategy object around to give the &quot;inverse&quot; mapping strategy.
virtual void initPreconditioner(bool clearOld=false)
Build the underlying data structure for the preconditioner.
An extension of the Thyra::DefaultPreconditioner class with some specializations useful for use withi...
const RCP< const MappingStrategy > getMapStrategy() const
Get the mapping strategy for this wrapper (translate between Thyra and Epetra)
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.
Implements the Epetra_Operator interface with a Thyra LinearOperator. This enables the use of absrtac...