Teko  Version of the Day
 All Classes Files Functions Variables Pages
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 
21 namespace Teko {
22 
23 using Teuchos::RCP;
24 using Teuchos::ParameterList;
25 
26 // hide stuff
27 namespace {
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
64 StratimikosFactory::StratimikosFactory(const Teuchos::RCP<Teko::RequestHandler> & rh)
65  :epetraFwdOpViewExtractor_(Teuchos::rcp(new Thyra::EpetraOperatorViewExtractorStd()))
66 {
68 }
69 
70 StratimikosFactory::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
79 bool 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 
109 bool StratimikosFactory::applySupportsConj(Thyra::EConj /* conj */) const
110 {
111  return false;
112 }
113 
114 
115 bool StratimikosFactory::applyTransposeSupportsConj(Thyra::EConj /* conj */) const
116 {
117  return false; // See comment below
118 }
119 
120 
121 Teuchos::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 
432 Teuchos::RCP<Teuchos::ParameterList>
434 {
435  return paramList_;
436 }
437 
438 
439 Teuchos::RCP<Teuchos::ParameterList>
441 {
442  Teuchos::RCP<ParameterList> _paramList = paramList_;
443  paramList_ = Teuchos::null;
444  return _paramList;
445 }
446 
447 
448 Teuchos::RCP<const Teuchos::ParameterList>
450 {
451  return paramList_;
452 }
453 
454 
455 Teuchos::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 
507 Teuchos::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 
580 void 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 
610 void 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 
624 void 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
bool applySupportsConj(Thyra::EConj conj) const
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
void rebuildInverse(const InverseFactory &factory, const LinearOp &A, InverseLinearOp &invA)
void setRequestHandler(const Teuchos::RCP< Teko::RequestHandler > &rh)
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
void initializePrec(const Teuchos::RCP< const Thyra::LinearOpSourceBase< double > > &fwdOp, Thyra::PreconditionerBase< double > *prec, const Thyra::ESupportSolveUse supportSolveUse) const
void uninitializePrec(Thyra::PreconditionerBase< double > *prec, Teuchos::RCP< const Thyra::LinearOpSourceBase< double > > *fwdOp, Thyra::ESupportSolveUse *supportSolveUse) const
bool applyTransposeSupportsConj(Thyra::EConj conj) const
Teuchos::RCP< const Teuchos::ParameterList > getParameterList() const
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
void initializePrec_Thyra(const Teuchos::RCP< const Thyra::LinearOpSourceBase< double > > &fwdOp, Thyra::PreconditionerBase< double > *prec, const Thyra::ESupportSolveUse supportSolveUse) const
A single Epetra wrapper for all operators constructed from an inverse operator.
bool isCompatible(const Thyra::LinearOpSourceBase< double > &fwdOp) const
Teuchos::RCP< Thyra::PreconditionerBase< double > > createPrec() const
InverseLinearOp buildInverse(const InverseFactory &factory, const LinearOp &A)
Build an inverse operator using a factory and a linear operator.
Teuchos::RCP< const BlockReorderManager > blockedReorderFromString(std::string &reorder)
Convert a string to a block reorder manager object.
This class takes a blocked linear op and represents it in a flattened form.
void initializePrec_Epetra(const Teuchos::RCP< const Thyra::LinearOpSourceBase< double > > &fwdOp, Thyra::PreconditionerBase< double > *prec, const Thyra::ESupportSolveUse supportSolveUse) const
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const &paramList)
Tear about a user specified Epetra_Operator (CrsMatrix) using a vector of vectors of GIDs for each bl...
virtual void WriteBlocks(const std::string &prefix) const