Teko Version of the Day
Teko_StratimikosFactory.cpp
1#include "Teko_StratimikosFactory.hpp"
2
3#include "Teuchos_Time.hpp"
4#include "Teuchos_AbstractFactoryStd.hpp"
5
6#include "Thyra_EpetraOperatorViewExtractorStd.hpp"
7#include "Thyra_EpetraLinearOp.hpp"
8#include "Thyra_DefaultPreconditioner.hpp"
9
10#include "Teko_InverseLibrary.hpp"
11#include "Teko_Preconditioner.hpp"
12#include "Teko_InverseFactoryOperator.hpp"
13#include "Teko_Utilities.hpp"
14#include "Teko_InverseLibrary.hpp"
15#include "Teko_StridedEpetraOperator.hpp"
16#include "Teko_BlockedEpetraOperator.hpp"
17#include "Teko_ReorderedLinearOp.hpp"
18
19#include "EpetraExt_RowMatrixOut.h"
20
21namespace Teko {
22
23using Teuchos::RCP;
24using Teuchos::ParameterList;
25
26// hide stuff
27namespace {
28 // Simple preconditioner class that adds a counter
29 class StratimikosFactoryPreconditioner : public Thyra::DefaultPreconditioner<double>{
30 public:
31 StratimikosFactoryPreconditioner() : iter_(0) {}
32
33 inline void incrIter() { iter_++; }
34 inline std::size_t getIter() { return iter_; }
35
36 private:
37 StratimikosFactoryPreconditioner(const StratimikosFactoryPreconditioner &);
38
39 std::size_t iter_;
40 };
41
42 // factory used to initialize the Teko::StratimikosFactory
43 // user data
44 class TekoFactoryBuilder
45 : public Teuchos::AbstractFactory<Thyra::PreconditionerFactoryBase<double> > {
46 public:
47 TekoFactoryBuilder(const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & builder,
48 const Teuchos::RCP<Teko::RequestHandler> & rh) : builder_(builder), requestHandler_(rh) {}
49 Teuchos::RCP<Thyra::PreconditionerFactoryBase<double> > create() const
50 { return Teuchos::rcp(new StratimikosFactory(builder_,requestHandler_)); }
51
52 private:
53 Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> builder_;
54 Teuchos::RCP<Teko::RequestHandler> requestHandler_;
55 };
56}
57
58// Constructors/initializers/accessors
60 :epetraFwdOpViewExtractor_(Teuchos::rcp(new Thyra::EpetraOperatorViewExtractorStd()))
61{}
62
63// Constructors/initializers/accessors
64StratimikosFactory::StratimikosFactory(const Teuchos::RCP<Teko::RequestHandler> & rh)
65 :epetraFwdOpViewExtractor_(Teuchos::rcp(new Thyra::EpetraOperatorViewExtractorStd()))
66{
68}
69
70StratimikosFactory::StratimikosFactory(const Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> & builder,
71 const Teuchos::RCP<Teko::RequestHandler> & rh)
72 :epetraFwdOpViewExtractor_(Teuchos::rcp(new Thyra::EpetraOperatorViewExtractorStd())), builder_(builder)
73{
75}
76
77
78// Overridden from PreconditionerFactoryBase
79bool StratimikosFactory::isCompatible(const Thyra::LinearOpSourceBase<double> &/* fwdOpSrc */) const
80{
81 using Teuchos::outArg;
82
83 TEUCHOS_ASSERT(false); // what you doing?
84
85/*
86 Teuchos::RCP<const Epetra_Operator> epetraFwdOp;
87 Thyra::EOpTransp epetraFwdOpTransp;
88 Thyra::EApplyEpetraOpAs epetraFwdOpApplyAs;
89 Thyra::EAdjointEpetraOp epetraFwdOpAdjointSupport;
90 double epetraFwdOpScalar;
91
92 // check to make sure this is an epetra CrsMatrix
93 Teuchos::RCP<const LinearOpBase<double> > fwdOp = fwdOpSrc.getOp();
94 epetraFwdOpViewExtractor_->getEpetraOpView(
95 fwdOp,
96 outArg(epetraFwdOp),outArg(epetraFwdOpTransp),
97 outArg(epetraFwdOpApplyAs),
98 outArg(epetraFwdOpAdjointSupport),
99 outArg(epetraFwdOpScalar));
100
101 if( !dynamic_cast<const Epetra_CrsMatrix*>(&*epetraFwdOp) )
102 return false;
103*/
104
105 return true;
106}
107
108
109bool StratimikosFactory::applySupportsConj(Thyra::EConj /* conj */) const
110{
111 return false;
112}
113
114
115bool StratimikosFactory::applyTransposeSupportsConj(Thyra::EConj /* conj */) const
116{
117 return false; // See comment below
118}
119
120
121Teuchos::RCP<Thyra::PreconditionerBase<double> >
123{
124 return Teuchos::rcp(new StratimikosFactoryPreconditioner());
125}
126
127
129 const Teuchos::RCP<const Thyra::LinearOpSourceBase<double> > &fwdOpSrc,
130 Thyra::PreconditionerBase<double> *prec,
131 const Thyra::ESupportSolveUse supportSolveUse
132 ) const
133{
134 Teuchos::RCP<const LinearOpBase<double> > fwdOp = fwdOpSrc->getOp();
135
136 if(epetraFwdOpViewExtractor_->isCompatible(*fwdOp))
137 initializePrec_Epetra(fwdOpSrc,prec,supportSolveUse);
138 else
139 initializePrec_Thyra(fwdOpSrc,prec,supportSolveUse);
140}
141
143 const Teuchos::RCP<const Thyra::LinearOpSourceBase<double> > &fwdOpSrc,
144 Thyra::PreconditionerBase<double> *prec,
145 const Thyra::ESupportSolveUse /* supportSolveUse */
146 ) const
147{
148 using Teuchos::RCP;
149 using Teuchos::rcp;
150 using Teuchos::rcp_dynamic_cast;
151 using Teuchos::implicit_cast;
152 using Thyra::LinearOpBase;
153
154 Teuchos::Time totalTimer(""), timer("");
155 totalTimer.start(true);
156
157 const RCP<Teuchos::FancyOStream> out = this->getOStream();
158 const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
159
160 bool mediumVerbosity = (out.get() && implicit_cast<int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW));
161
162 Teuchos::OSTab tab(out);
163 if(mediumVerbosity)
164 *out << "\nEntering Teko::StratimikosFactory::initializePrec_Thyra(...) ...\n";
165
166 Teuchos::RCP<const LinearOpBase<double> > fwdOp = fwdOpSrc->getOp();
167
168 // Get the concrete preconditioner object
169 StratimikosFactoryPreconditioner & defaultPrec
170 = Teuchos::dyn_cast<StratimikosFactoryPreconditioner>(*prec);
171 Teuchos::RCP<LinearOpBase<double> > prec_Op = defaultPrec.getNonconstUnspecifiedPrecOp();
172
173 // Permform initialization if needed
174 const bool startingOver = (prec_Op == Teuchos::null);
175 if(startingOver) {
176 // start over
177 invLib_ = Teuchos::null;
178 invFactory_ = Teuchos::null;
179
180 if(mediumVerbosity)
181 *out << "\nCreating the initial Teko Operator object...\n";
182
183 timer.start(true);
184
185 // build library, and set request handler (user defined!)
186 invLib_ = Teko::InverseLibrary::buildFromParameterList(paramList_->sublist("Inverse Factory Library"),builder_);
187 invLib_->setRequestHandler(reqHandler_);
188
189 // build preconditioner factory
190 invFactory_ = invLib_->getInverseFactory(paramList_->get<std::string>("Inverse Type"));
191
192 timer.stop();
193 if(mediumVerbosity)
194 Teuchos::OSTab(out).o() <<"> Creation time = "<<timer.totalElapsedTime()<<" sec\n";
195 }
196
197 if(mediumVerbosity)
198 *out << "\nComputing the preconditioner ...\n";
199
200 // setup reordering if required
201 std::string reorderType = paramList_->get<std::string>("Reorder Type");
202 if(reorderType!="") {
203
204 Teuchos::RCP<const Thyra::BlockedLinearOpBase<double> > blkFwdOp =
205 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<double> >(fwdOp,true);
206 RCP<const Teko::BlockReorderManager> brm = Teko::blockedReorderFromString(reorderType);
207 Teko::LinearOp blockedFwdOp = Teko::buildReorderedLinearOp(*brm,blkFwdOp);
208
209 if(prec_Op==Teuchos::null) {
210 Teko::ModifiableLinearOp reorderedPrec = Teko::buildInverse(*invFactory_,blockedFwdOp);
211 prec_Op = Teuchos::rcp(new ReorderedLinearOp(brm,reorderedPrec));
212 }
213 else {
214 Teko::ModifiableLinearOp reorderedPrec = Teuchos::rcp_dynamic_cast<ReorderedLinearOp>(prec_Op,true)->getBlockedOp();
215 Teko::rebuildInverse(*invFactory_,blockedFwdOp,reorderedPrec);
216 }
217 }
218 else {
219 // no reordering required
220 if(prec_Op==Teuchos::null)
221 prec_Op = Teko::buildInverse(*invFactory_,fwdOp);
222 else
223 Teko::rebuildInverse(*invFactory_,fwdOp,prec_Op);
224 }
225
226 // construct preconditioner
227 timer.stop();
228
229 if(mediumVerbosity)
230 Teuchos::OSTab(out).o() <<"=> Preconditioner construction time = "<<timer.totalElapsedTime()<<" sec\n";
231
232
233 // Initialize the preconditioner
234 defaultPrec.initializeUnspecified( prec_Op);
235 defaultPrec.incrIter();
236 totalTimer.stop();
237
238 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
239 *out << "\nTotal time in Teko::StratimikosFactory = "<<totalTimer.totalElapsedTime()<<" sec\n";
240 if(mediumVerbosity)
241 *out << "\nLeaving Teko::StratimikosFactory::initializePrec_Thyra(...) ...\n";
242}
243
245 const Teuchos::RCP<const Thyra::LinearOpSourceBase<double> > &fwdOpSrc,
246 Thyra::PreconditionerBase<double> *prec,
247 const Thyra::ESupportSolveUse /* supportSolveUse */
248 ) const
249{
250 using Teuchos::outArg;
251 using Teuchos::RCP;
252 using Teuchos::rcp;
253 using Teuchos::rcp_dynamic_cast;
254 using Teuchos::implicit_cast;
255
256 Teuchos::Time totalTimer(""), timer("");
257 totalTimer.start(true);
258
259 const RCP<Teuchos::FancyOStream> out = this->getOStream();
260 const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
261
262 bool mediumVerbosity = (out.get() && implicit_cast<int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW));
263
264 Teuchos::OSTab tab(out);
265 if(mediumVerbosity)
266 *out << "\nEntering Teko::StratimikosFactory::initializePrec_Epetra(...) ...\n";
267
268 Teuchos::RCP<const LinearOpBase<double> > fwdOp = fwdOpSrc->getOp();
269#ifdef _DEBUG
270 TEUCHOS_TEST_FOR_EXCEPT(fwdOp.get()==NULL);
271 TEUCHOS_TEST_FOR_EXCEPT(prec==NULL);
272#endif
273
274 //
275 // Unwrap and get the forward Epetra_Operator object
276 //
277 Teuchos::RCP<const Epetra_Operator> epetraFwdOp;
278 Thyra::EOpTransp epetraFwdOpTransp;
279 Thyra::EApplyEpetraOpAs epetraFwdOpApplyAs;
280 Thyra::EAdjointEpetraOp epetraFwdOpAdjointSupport;
281 double epetraFwdOpScalar;
282 epetraFwdOpViewExtractor_->getEpetraOpView(
283 fwdOp,outArg(epetraFwdOp),outArg(epetraFwdOpTransp),outArg(epetraFwdOpApplyAs),
284 outArg(epetraFwdOpAdjointSupport),outArg(epetraFwdOpScalar)
285 );
286 // Get the concrete preconditioner object
287 StratimikosFactoryPreconditioner & defaultPrec
288 = Teuchos::dyn_cast<StratimikosFactoryPreconditioner>(*prec);
289
290 // Get the EpetraLinearOp object that is used to implement the preconditoner linear op
291 RCP<Thyra::EpetraLinearOp> epetra_precOp
292 = rcp_dynamic_cast<Thyra::EpetraLinearOp>(defaultPrec.getNonconstUnspecifiedPrecOp(),true);
293
294 // Get the embedded ML_Epetra::MultiLevelPreconditioner object if it exists
295 Teuchos::RCP<Teko::Epetra::InverseFactoryOperator> teko_precOp;
296 if(epetra_precOp!=Teuchos::null)
297 teko_precOp = rcp_dynamic_cast<Teko::Epetra::InverseFactoryOperator>(epetra_precOp->epetra_op(),true);
298
299 // Permform initialization if needed
300 const bool startingOver = (teko_precOp == Teuchos::null);
301 if(startingOver) {
302 // start over
303 invLib_ = Teuchos::null;
304 invFactory_ = Teuchos::null;
305 decomp_.clear();
306
307 if(mediumVerbosity)
308 *out << "\nCreating the initial Teko::Epetra::InverseFactoryOperator object...\n";
309
310 timer.start(true);
311
312 std::stringstream ss;
313 ss << paramList_->get<std::string>("Strided Blocking");
314
315 // figure out the decomposition requested by the string
316 while(not ss.eof()) {
317 int num=0;
318 ss >> num;
319
320 TEUCHOS_ASSERT(num>0);
321
322 decomp_.push_back(num);
323 }
324
325 // build library, and set request handler (user defined!)
326 invLib_ = Teko::InverseLibrary::buildFromParameterList(paramList_->sublist("Inverse Factory Library"),builder_);
327 invLib_->setRequestHandler(reqHandler_);
328
329 // build preconditioner factory
330 invFactory_ = invLib_->getInverseFactory(paramList_->get<std::string>("Inverse Type"));
331
332 // Create the initial preconditioner: DO NOT compute it yet
333 teko_precOp = rcp( new Teko::Epetra::InverseFactoryOperator(invFactory_));
334
335 timer.stop();
336 if(mediumVerbosity)
337 Teuchos::OSTab(out).o() <<"> Creation time = "<<timer.totalElapsedTime()<<" sec\n";
338 }
339
340 if(mediumVerbosity)
341 *out << "\nComputing the preconditioner ...\n";
342
343 // construct preconditioner
344 {
345 bool writeBlockOps = paramList_->get<bool>("Write Block Operator");
346 timer.start(true);
347 teko_precOp->initInverse();
348
349 if(decomp_.size()==1) {
350 teko_precOp->rebuildInverseOperator(epetraFwdOp);
351
352 // write out to disk
353 if(writeBlockOps) {
354 std::stringstream ss;
355 ss << "block-" << defaultPrec.getIter() << "_00.mm";
356 EpetraExt::RowMatrixToMatrixMarketFile(ss.str().c_str(),*rcp_dynamic_cast<const Epetra_CrsMatrix>(epetraFwdOp));
357 }
358 }
359 else {
360 Teuchos::RCP<Epetra_Operator> wrappedFwdOp
361 = buildWrappedEpetraOperator(epetraFwdOp,teko_precOp->getNonconstForwardOp(),*out);
362
363 // write out to disk
364 if(writeBlockOps) {
365 std::stringstream ss;
366 ss << "block-" << defaultPrec.getIter();
367 // Teuchos::RCP<Teko::Epetra::StridedEpetraOperator> stridedJac
368 // = Teuchos::rcp_dynamic_cast<Teko::Epetra::StridedEpetraOperator>(wrappedFwdOp);
369 Teuchos::RCP<Teko::Epetra::BlockedEpetraOperator> stridedJac
370 = Teuchos::rcp_dynamic_cast<Teko::Epetra::BlockedEpetraOperator>(wrappedFwdOp);
371 if(stridedJac!=Teuchos::null) {
372 // write out blocks of strided operator
373 stridedJac->WriteBlocks(ss.str());
374 }
375 else TEUCHOS_ASSERT(false);
376 }
377
378 teko_precOp->rebuildInverseOperator(wrappedFwdOp);
379 }
380
381 timer.stop();
382 }
383
384 if(mediumVerbosity)
385 Teuchos::OSTab(out).o() <<"=> Preconditioner construction time = "<<timer.totalElapsedTime()<<" sec\n";
386
387 // Initialize the output EpetraLinearOp
388 if(startingOver) {
389 epetra_precOp = rcp(new Thyra::EpetraLinearOp);
390 }
391 epetra_precOp->initialize(teko_precOp,epetraFwdOpTransp
392 ,Thyra::EPETRA_OP_APPLY_APPLY_INVERSE
393 ,Thyra::EPETRA_OP_ADJOINT_UNSUPPORTED);
394
395 // Initialize the preconditioner
396 defaultPrec.initializeUnspecified( Teuchos::rcp_implicit_cast<LinearOpBase<double> >(epetra_precOp));
397 defaultPrec.incrIter();
398 totalTimer.stop();
399
400 if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
401 *out << "\nTotal time in Teko::StratimikosFactory = "<<totalTimer.totalElapsedTime()<<" sec\n";
402 if(mediumVerbosity)
403 *out << "\nLeaving Teko::StratimikosFactory::initializePrec(...) ...\n";
404}
405
406
408 Thyra::PreconditionerBase<double> * /* prec */,
409 Teuchos::RCP<const Thyra::LinearOpSourceBase<double> > * /* fwdOp */,
410 Thyra::ESupportSolveUse * /* supportSolveUse */
411 ) const
412{
413 TEUCHOS_TEST_FOR_EXCEPT(true);
414}
415
416
417// Overridden from ParameterListAcceptor
418
419
421 Teuchos::RCP<Teuchos::ParameterList> const& paramList
422 )
423{
424 TEUCHOS_TEST_FOR_EXCEPT(paramList.get()==NULL);
425
426 paramList->validateParametersAndSetDefaults(*this->getValidParameters(),0);
427 paramList_ = paramList;
428
429}
430
431
432Teuchos::RCP<Teuchos::ParameterList>
434{
435 return paramList_;
436}
437
438
439Teuchos::RCP<Teuchos::ParameterList>
441{
442 Teuchos::RCP<ParameterList> _paramList = paramList_;
443 paramList_ = Teuchos::null;
444 return _paramList;
445}
446
447
448Teuchos::RCP<const Teuchos::ParameterList>
450{
451 return paramList_;
452}
453
454
455Teuchos::RCP<const Teuchos::ParameterList>
457{
458
459 using Teuchos::rcp;
460 using Teuchos::tuple;
461 using Teuchos::implicit_cast;
462 using Teuchos::rcp_implicit_cast;
463
464 static RCP<const ParameterList> validPL;
465
466 if(is_null(validPL)) {
467
468 Teuchos::RCP<Teuchos::ParameterList> pl = rcp(new Teuchos::ParameterList());
469
470 pl->set("Test Block Operator",false,
471 "If Stratiikos/Teko is used to break an operator into its parts,\n"
472 "then setting this parameter to true will compare applications of the\n"
473 "segregated operator to the original operator.");
474 pl->set("Write Block Operator",false,
475 "Write out the segregated operator to disk with the name \"block-?_xx\"");
476 pl->set("Strided Blocking","1",
477 "Assuming that the user wants Strided blocking, break the operator into\n"
478 "blocks. The syntax can be thought to be associated with the solution\n"
479 "vector. For example if your variables are [u v w p T], and we want [u v w]\n"
480 "blocked together, and p and T separate then the relevant string is \"3 1 1\".\n"
481 "Meaning put the first 3 unknowns per node together and separate the v and w\n"
482 "components.");
483 pl->set("Reorder Type","",
484 "This specifies how the blocks are reordered for use in the preconditioner.\n"
485 "For example, assume the linear system is generated from 3D Navier-Stokes\n"
486 "with an energy equation, yielding the unknowns [u v w p T]. If the\n"
487 "\"Strided Blocking\" string is \"3 1 1\", then setting this parameter to\n"
488 "\"[2 [0 1]]\" will reorder the blocked operator so its nested with the\n"
489 "velocity and pressure forming an inner two-by-two block, and then the\n"
490 "temperature unknowns forming a two-by-two system with the velocity-pressure\n"
491 "block.");
492 pl->set("Inverse Type","Amesos",
493 "The type of inverse operator the user wants. This can be one of the defaults\n"
494 "from Stratimikos, or a Teko preconditioner defined in the\n"
495 "\"Inverse Factory Library\".");
496 pl->sublist("Inverse Factory Library",false,"Definition of Teko preconditioners.");
497
498 validPL = pl;
499 }
500
501 return validPL;
502}
503
507Teuchos::RCP<Epetra_Operator> StratimikosFactory::buildWrappedEpetraOperator(
508 const Teuchos::RCP<const Epetra_Operator> & Jac,
509 const Teuchos::RCP<Epetra_Operator> & wrapInput,
510 std::ostream & out
511 ) const
512{
513 Teuchos::RCP<Epetra_Operator> wrappedOp = wrapInput;
514
515// // initialize jacobian
516// if(wrappedOp==Teuchos::null)
517// {
518// wrappedOp = Teuchos::rcp(new Teko::Epetra::StridedEpetraOperator(decomp_,Jac));
519//
520// // reorder the blocks if requested
521// std::string reorderType = paramList_->get<std::string>("Reorder Type");
522// if(reorderType!="") {
523// RCP<const Teko::BlockReorderManager> brm = Teko::blockedReorderFromString(reorderType);
524//
525// // out << "Teko: Reordering = " << brm->toString() << std::endl;
526// Teuchos::rcp_dynamic_cast<Teko::Epetra::StridedEpetraOperator>(wrappedOp)->Reorder(*brm);
527// }
528// }
529// else {
530// Teuchos::rcp_dynamic_cast<Teko::Epetra::StridedEpetraOperator>(wrappedOp)->RebuildOps();
531// }
532//
533// // test blocked operator for correctness
534// if(paramList_->get<bool>("Test Block Operator")) {
535// bool result
536// = Teuchos::rcp_dynamic_cast<Teko::Epetra::StridedEpetraOperator>(wrappedOp)->testAgainstFullOperator(600,1e-14);
537//
538// out << "Teko: Tested operator correctness: " << (result ? "passed" : "FAILED!") << std::endl;
539// }
540
541 // initialize jacobian
542 if(wrappedOp==Teuchos::null)
543 {
544 // build strided vector
545 std::vector<std::vector<int> > vars;
546 buildStridedVectors(*Jac,decomp_,vars);
547 wrappedOp = Teuchos::rcp(new Teko::Epetra::BlockedEpetraOperator(vars,Jac));
548
549 // reorder the blocks if requested
550 std::string reorderType = paramList_->get<std::string>("Reorder Type");
551 if(reorderType!="") {
552 RCP<const Teko::BlockReorderManager> brm = Teko::blockedReorderFromString(reorderType);
553
554 // out << "Teko: Reordering = " << brm->toString() << std::endl;
555 Teuchos::rcp_dynamic_cast<Teko::Epetra::BlockedEpetraOperator>(wrappedOp)->Reorder(*brm);
556 }
557 }
558 else {
559 Teuchos::rcp_dynamic_cast<Teko::Epetra::BlockedEpetraOperator>(wrappedOp)->RebuildOps();
560 }
561
562 // test blocked operator for correctness
563 if(paramList_->get<bool>("Test Block Operator")) {
564 bool result
565 = Teuchos::rcp_dynamic_cast<Teko::Epetra::BlockedEpetraOperator>(wrappedOp)->testAgainstFullOperator(600,1e-14);
566
567 out << "Teko: Tested operator correctness: " << (result ? "passed" : "FAILED!") << std::endl;
568 }
569
570 return wrappedOp;
571}
572
574{
575 std::ostringstream oss;
576 oss << "Teko::StratimikosFactory";
577 return oss.str();
578}
579
580void StratimikosFactory::buildStridedVectors(const Epetra_Operator & Jac,
581 const std::vector<int> & decomp,
582 std::vector<std::vector<int> > & vars) const
583{
584 const Epetra_Map & rangeMap = Jac.OperatorRangeMap();
585
586 // compute total number of variables
587 int numVars = 0;
588 for(std::size_t i=0;i<decomp.size();i++)
589 numVars += decomp[i];
590
591 // verify that the decomposition is appropriate for this matrix
592 TEUCHOS_ASSERT((rangeMap.NumMyElements() % numVars)==0);
593 TEUCHOS_ASSERT((rangeMap.NumGlobalElements() % numVars)==0);
594
595 int * globalIds = rangeMap.MyGlobalElements();
596
597 vars.resize(decomp.size());
598 for(int i=0;i<rangeMap.NumMyElements();) {
599
600 // for each "node" copy global ids to vectors
601 for(std::size_t d=0;d<decomp.size();d++) {
602 // for this variable copy global ids to variable arrays
603 int current = decomp[d];
604 for(int v=0;v<current;v++,i++)
605 vars[d].push_back(globalIds[i]);
606 }
607 }
608}
609
610void addTekoToStratimikosBuilder(Stratimikos::DefaultLinearSolverBuilder & builder,
611 const std::string & stratName)
612{
613 TEUCHOS_TEST_FOR_EXCEPTION(builder.getValidParameters()->sublist("Preconditioner Types").isParameter(stratName),std::logic_error,
614 "Teko::addTekoToStratimikosBuilder cannot add \"" + stratName +"\" because it is already included in builder!");
615
616 Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> builderCopy
617 = Teuchos::rcp(new Stratimikos::DefaultLinearSolverBuilder(builder));
618
619 // use default constructor to add Teko::StratimikosFactory
620 Teuchos::RCP<TekoFactoryBuilder> tekoFactoryBuilder = Teuchos::rcp(new TekoFactoryBuilder(builderCopy,Teuchos::null));
621 builder.setPreconditioningStrategyFactory(tekoFactoryBuilder,stratName);
622}
623
624void addTekoToStratimikosBuilder(Stratimikos::DefaultLinearSolverBuilder & builder,
625 const Teuchos::RCP<Teko::RequestHandler> & rh,
626 const std::string & stratName)
627{
628 TEUCHOS_TEST_FOR_EXCEPTION(builder.getValidParameters()->sublist("Preconditioner Types").isParameter(stratName),std::logic_error,
629 "Teko::addTekoToStratimikosBuilder cannot add \"" + stratName +"\" because it is already included in builder!");
630
631 Teuchos::RCP<Stratimikos::DefaultLinearSolverBuilder> builderCopy
632 = Teuchos::rcp(new Stratimikos::DefaultLinearSolverBuilder(builder));
633
634 // build an instance of a Teuchos::AbsractFactory<Thyra::PFB> so request handler is passed onto
635 // the resulting StratimikosFactory
636 Teuchos::RCP<TekoFactoryBuilder> tekoFactoryBuilder = Teuchos::rcp(new TekoFactoryBuilder(builderCopy,rh));
637 builder.setPreconditioningStrategyFactory(tekoFactoryBuilder,stratName);
638}
639
640} // namespace Thyra
Teuchos::RCP< const BlockReorderManager > blockedReorderFromString(std::string &reorder)
Convert a string to a block reorder manager object.
InverseLinearOp buildInverse(const InverseFactory &factory, const LinearOp &A)
Build an inverse operator using a factory and a linear operator.
void rebuildInverse(const InverseFactory &factory, const LinearOp &A, InverseLinearOp &invA)
Tear about a user specified Epetra_Operator (CrsMatrix) using a vector of vectors of GIDs for each bl...
A single Epetra wrapper for all operators constructed from an inverse operator.
This class takes a blocked linear op and represents it in a flattened form.
void initializePrec(const Teuchos::RCP< const Thyra::LinearOpSourceBase< double > > &fwdOp, Thyra::PreconditionerBase< double > *prec, const Thyra::ESupportSolveUse supportSolveUse) const
void initializePrec_Epetra(const Teuchos::RCP< const Thyra::LinearOpSourceBase< double > > &fwdOp, Thyra::PreconditionerBase< double > *prec, const Thyra::ESupportSolveUse supportSolveUse) const
Teuchos::RCP< const Teuchos::ParameterList > getParameterList() const
Teuchos::RCP< Thyra::PreconditionerBase< double > > createPrec() const
bool isCompatible(const Thyra::LinearOpSourceBase< double > &fwdOp) const
bool applyTransposeSupportsConj(Thyra::EConj conj) const
bool applySupportsConj(Thyra::EConj conj) const
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const &paramList)
void uninitializePrec(Thyra::PreconditionerBase< double > *prec, Teuchos::RCP< const Thyra::LinearOpSourceBase< double > > *fwdOp, Thyra::ESupportSolveUse *supportSolveUse) const
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
void setRequestHandler(const Teuchos::RCP< Teko::RequestHandler > &rh)
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
void initializePrec_Thyra(const Teuchos::RCP< const Thyra::LinearOpSourceBase< double > > &fwdOp, Thyra::PreconditionerBase< double > *prec, const Thyra::ESupportSolveUse supportSolveUse) const
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const