10#include "Teko_TpetraBlockPreconditioner.hpp"
11#include "Teko_Preconditioner.hpp"
14#include "Thyra_DefaultLinearOpSource.hpp"
15#include "Thyra_TpetraLinearOp.hpp"
16#include "Thyra_TpetraThyraWrappers.hpp"
19#include "Teuchos_Time.hpp"
22#include "Teko_TpetraBasicMappingStrategy.hpp"
26namespace TpetraHelpers {
30using Teuchos::rcp_dynamic_cast;
31using Teuchos::rcpFromRef;
39TpetraBlockPreconditioner::TpetraBlockPreconditioner(
40 const Teuchos::RCP<const PreconditionerFactory>& bfp)
41 : preconFactory_(bfp), firstBuildComplete_(false) {}
44 if ((not clearOld) && preconObj_ != Teuchos::null)
return;
45 preconObj_ = preconFactory_->createPrec();
61 const Teuchos::RCP<
const Tpetra::Operator<ST, LO, GO, NT> >& A,
bool clear) {
62 Teko_DEBUG_SCOPE(
"TBP::buildPreconditioner", 10);
65 RCP<const Thyra::LinearOpBase<ST> > thyraA = extractLinearOp(A);
75 RCP<const Thyra::LinearOpSourceBase<ST> > lOpSrc = Thyra::defaultLinearOpSource(thyraA);
76 preconFactory_->initializePrec(lOpSrc, &*preconObj_, Thyra::SUPPORT_SOLVE_UNSPECIFIED);
79 RCP<const Thyra::LinearOpBase<ST> > preconditioner = preconObj_->getUnspecifiedPrecOp();
81 SetOperator(preconditioner,
false);
83 firstBuildComplete_ =
true;
85 TEUCHOS_ASSERT(preconObj_ != Teuchos::null);
88 TEUCHOS_ASSERT(firstBuildComplete_ ==
true);
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);
110 RCP<const Thyra::LinearOpBase<ST> > thyraA = extractLinearOp(A);
118 RCP<Thyra::MultiVectorBase<ST> > thyra_mv =
119 Thyra::createMembers(thyraA->range(), tpetra_mv.getNumVectors());
126 preconFactory_->initializePrec(Thyra::defaultLinearOpSource(thyraA), thyra_mv, &*preconObj_,
127 Thyra::SUPPORT_SOLVE_UNSPECIFIED);
128 RCP<const Thyra::LinearOpBase<ST> > preconditioner = preconObj_->getUnspecifiedPrecOp();
130 SetOperator(preconditioner,
false);
132 firstBuildComplete_ =
true;
134 TEUCHOS_ASSERT(preconObj_ != Teuchos::null);
135 TEUCHOS_ASSERT(
getThyraOp() != Teuchos::null);
137 TEUCHOS_ASSERT(firstBuildComplete_ ==
true);
154 const Teuchos::RCP<
const Tpetra::Operator<ST, LO, GO, NT> >& A) {
155 Teko_DEBUG_SCOPE(
"TBP::rebuildPreconditioner", 10);
158 if (not firstBuildComplete_) {
162 Teko_DEBUG_EXPR(Teuchos::Time timer(
""));
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);
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);
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);
183 TEUCHOS_ASSERT(preconObj_ != Teuchos::null);
184 TEUCHOS_ASSERT(
getThyraOp() != Teuchos::null);
185 TEUCHOS_ASSERT(firstBuildComplete_ ==
true);
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);
207 if (not firstBuildComplete_) {
211 Teko_DEBUG_EXPR(Teuchos::Time timer(
""));
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);
220 Teko_DEBUG_EXPR(timer.start(
true));
221 RCP<Thyra::MultiVectorBase<ST> > thyra_mv =
222 Thyra::createMembers(thyraA->range(), tpetra_mv.getNumVectors());
224 Teko_DEBUG_EXPR(timer.stop());
225 Teko_DEBUG_MSG(
"TBP::rebuild vector copy time = " << timer.totalElapsedTime(), 2);
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);
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);
240 TEUCHOS_ASSERT(preconObj_ != Teuchos::null);
241 TEUCHOS_ASSERT(
getThyraOp() != Teuchos::null);
242 TEUCHOS_ASSERT(firstBuildComplete_ ==
true);
255 Teuchos::RCP<Preconditioner> bp = rcp_dynamic_cast<Preconditioner>(preconObj_);
257 if (bp != Teuchos::null)
return bp->getStateObject();
259 return Teuchos::null;
272 Teuchos::RCP<const Preconditioner> bp = rcp_dynamic_cast<const Preconditioner>(preconObj_);
274 if (bp != Teuchos::null)
return bp->getStateObject();
276 return Teuchos::null;
279Teuchos::RCP<const Thyra::LinearOpBase<ST> > TpetraBlockPreconditioner::extractLinearOp(
280 const Teuchos::RCP<
const Tpetra::Operator<ST, LO, GO, NT> >& A)
const {
282 const RCP<const TpetraOperatorWrapper>& tow = rcp_dynamic_cast<const TpetraOperatorWrapper>(A);
285 if (tow != Teuchos::null)
return tow->getThyraOp();
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);
293Teuchos::RCP<const MappingStrategy> TpetraBlockPreconditioner::extractMappingStrategy(
294 const Teuchos::RCP<
const Tpetra::Operator<ST, LO, GO, NT> >& A)
const {
296 const RCP<const TpetraOperatorWrapper>& tow = rcp_dynamic_cast<const TpetraOperatorWrapper>(A);
299 if (tow != Teuchos::null)
return tow->getMapStrategy();
302 RCP<const Tpetra::Map<LO, GO, NT> > range = A->getRangeMap();
303 RCP<const Tpetra::Map<LO, GO, NT> > domain = A->getDomainMap();
305 new BasicMappingStrategy(range, domain, *Thyra::convertTpetraToThyraComm(range->getComm())));
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.