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