Stratimikos Package Browser (Single Doxygen Collection)  Version of the Day
Thyra_AztecOOLinearOpWithSolveFactory.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Stratimikos: Thyra-based strategies for linear solvers
5 // Copyright (2006) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 
43 #ifndef SUN_CXX
44 
45 
48 #include "Thyra_PreconditionerFactoryHelpers.hpp"
49 #include "Thyra_EpetraOperatorViewExtractorStd.hpp"
50 #include "Thyra_ScaledAdjointLinearOpBase.hpp"
51 #include "Thyra_EpetraLinearOpBase.hpp"
52 #include "Thyra_EpetraOperatorWrapper.hpp"
53 #include "EpetraExt_ProductOperator.h"
54 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
55 #include "Teuchos_ParameterList.hpp"
56 #include "Teuchos_dyn_cast.hpp"
57 #include "AztecOOParameterList.hpp"
58 
59 
60 namespace {
61 
62 
63 const std::string AOOLOWSF_epetraPrecOp_str
64 = "AOOLOWSF::epetraPrecOp";
65 const std::string AOOLOWSF_aztec_epetra_epetraFwdOp_str
66 = "AOOLOWSF::aztec_epetra_epetraFwdOp";
67 const std::string AOOLOWSF_aztec_epetra_epetraAdjOp_str
68 = "AOOLOWSF::aztec_epetra_epetraAdjOp";
69 const std::string AOOLOWSF_rowmatrix_epetraFwdOp_str
70 = "AOOLOWSF::rowmatrix_epetraFwdOp";
71 const std::string AOOLOWSF_rowmatrix_epetraPrecOp_str
72 = "AOOLOWSF::rowmatrix_epetraPrecOp";
73 const std::string AOOLOWSF_aztec_fwd_epetra_epetraPrecOp_str
74 = "AOOLOWSF::aztec_fwd_epetra_epetraPrecOp";
75 const std::string AOOLOWSF_aztec_adj_epetra_epetraPrecOp_str
76 = "AOOLOWSF::aztec_adj_epetra_epetraPrecOp";
77 const std::string AOOLOWSF_setPrecondtionerOperator_str
78 = "AOOLOWSF::setPrecondtionerOperator";
79 const std::string AOOLOWSF_constructedAztecPreconditoner_str
80 = "AOOLOWSF::constructedAztecPreconditoner";
81 
82 
83 const std::string ForwardSolve_name = "Forward Solve";
84 const std::string AdjointSolve_name = "Adjoint Solve";
85 const std::string MaxIterations_name = "Max Iterations";
86 const int MaxIterations_default = 400;
87 const std::string Tolerance_name = "Tolerance";
88 const double Tolerance_default = 1e-6;
89 const std::string OutputEveryRhs_name = "Output Every RHS";
90 const bool OutputEveryRhs_default = false;
91 const std::string AztecOO_Settings_name = "AztecOO Settings";
92 
93 
94 } // namespace
95 
96 
97 namespace Thyra {
98 
99 
100 // Constructors/initializers/accessors
101 
102 
104  Teuchos::RCP<Teuchos::ParameterList> const& paramList
105  )
106  :epetraFwdOpViewExtractor_(Teuchos::rcp(new EpetraOperatorViewExtractorStd()))
107  ,defaultFwdMaxIterations_(MaxIterations_default)
108  ,defaultFwdTolerance_(Tolerance_default)
109  ,defaultAdjMaxIterations_(MaxIterations_default)
110  ,defaultAdjTolerance_(Tolerance_default)
111  ,outputEveryRhs_(OutputEveryRhs_default)
112  ,useAztecPrec_(false)
113 {
115  if(paramList.get())
116  setParameterList(paramList);
117 }
118 
119 
120 // Overridden from LinearOpWithSolveFactoryBase
121 
122 
124 {
125  return true;
126 }
127 
128 
130  const Teuchos::RCP<PreconditionerFactoryBase<double> > &precFactory,
131  const std::string &precFactoryName
132  )
133 {
134  TEUCHOS_TEST_FOR_EXCEPT(!precFactory.get());
135  Teuchos::RCP<const Teuchos::ParameterList>
136  precFactoryValidPL = precFactory->getValidParameters();
137  const std::string _precFactoryName =
138  ( precFactoryName != ""
139  ? precFactoryName
140  : ( precFactoryValidPL.get()
141  ? precFactoryValidPL->name()
142  : "GENERIC PRECONDITIONER FACTORY"
143  )
144  );
145  precFactory_ = precFactory;
146  precFactoryName_ = _precFactoryName;
148 }
149 
150 
151 Teuchos::RCP<PreconditionerFactoryBase<double> >
153 {
154  return precFactory_;
155 }
156 
157 
159  Teuchos::RCP<PreconditionerFactoryBase<double> > *precFactory,
160  std::string *precFactoryName
161  )
162 {
163  if(precFactory) *precFactory = precFactory_;
164  if(precFactoryName) *precFactoryName = precFactoryName_;
165  precFactory_ = Teuchos::null;
166  precFactoryName_ = "";
168 }
169 
170 
172  const LinearOpSourceBase<double> &fwdOpSrc
173  ) const
174 {
175  return epetraFwdOpViewExtractor_->isCompatible(*fwdOpSrc.getOp());
176 }
177 
178 
179 Teuchos::RCP<LinearOpWithSolveBase<double> >
181 {
182  return Teuchos::rcp(new AztecOOLinearOpWithSolve());
183 }
184 
185 
187  const Teuchos::RCP<const LinearOpSourceBase<double> > &fwdOpSrc,
188  LinearOpWithSolveBase<double> *Op,
189  const ESupportSolveUse supportSolveUse
190  ) const
191 {
192  this->initializeOp_impl(fwdOpSrc,Teuchos::null,Teuchos::null,false,Op);
193 }
194 
195 
197  const Teuchos::RCP<const LinearOpSourceBase<double> > &fwdOpSrc,
198  LinearOpWithSolveBase<double> *Op
199  ) const
200 {
201  this->initializeOp_impl(fwdOpSrc,Teuchos::null,Teuchos::null,true,Op);
202 }
203 
204 
206  const EPreconditionerInputType precOpType
207  ) const
208 {
209  const_cast<bool&>(useAztecPrec_) = (
210  paramList_.get()
211  &&
212  paramList_->sublist(ForwardSolve_name).sublist(AztecOO_Settings_name).get(
213  "Aztec Preconditioner","none"
214  )!="none"
215  );
216  switch(precOpType) {
217  case PRECONDITIONER_INPUT_TYPE_AS_OPERATOR:
218  return true;
219  break;
220  case PRECONDITIONER_INPUT_TYPE_AS_MATRIX:
221  return useAztecPrec_;
222  break;
223  default:
224  TEUCHOS_TEST_FOR_EXCEPT(true);
225  }
226  return PRECONDITIONER_INPUT_TYPE_AS_OPERATOR; // Should never be called!
227 }
228 
229 
231  const Teuchos::RCP<const LinearOpSourceBase<double> > &fwdOpSrc,
232  const Teuchos::RCP<const PreconditionerBase<double> > &prec,
233  LinearOpWithSolveBase<double> *Op,
234  const ESupportSolveUse supportSolveUse
235  ) const
236 {
237  TEUCHOS_TEST_FOR_EXCEPT(prec.get()==NULL);
238  this->initializeOp_impl(fwdOpSrc,prec,Teuchos::null,false,Op);
239 }
240 
241 
243  const Teuchos::RCP<const LinearOpSourceBase<double> > &fwdOpSrc,
244  const Teuchos::RCP<const LinearOpSourceBase<double> > &approxFwdOpSrc,
245  LinearOpWithSolveBase<double> *Op,
246  const ESupportSolveUse supportSolveUse
247  ) const
248 {
249  TEUCHOS_TEST_FOR_EXCEPT(approxFwdOpSrc.get()==NULL);
250  TEUCHOS_TEST_FOR_EXCEPT(approxFwdOpSrc->getOp().get()==NULL);
251  this->initializeOp_impl(fwdOpSrc,Teuchos::null,approxFwdOpSrc,false,Op);
252 }
253 
254 
256  LinearOpWithSolveBase<double> *Op,
257  Teuchos::RCP<const LinearOpSourceBase<double> > *fwdOpSrc,
258  Teuchos::RCP<const PreconditionerBase<double> > *prec,
259  Teuchos::RCP<const LinearOpSourceBase<double> > *approxFwdOpSrc,
260  ESupportSolveUse *supportSolveUse
261  ) const
262 {
263 #ifdef TEUCHOS_DEBUG
264  TEUCHOS_TEST_FOR_EXCEPT(Op==NULL);
265 #endif
267  *aztecOp = &Teuchos::dyn_cast<AztecOOLinearOpWithSolve>(*Op);
268  // Extract and unset the fwdOP and approxFwdOp objects
269  Teuchos::RCP<const LinearOpSourceBase<double> >
270  _fwdOpSrc = aztecOp->extract_fwdOpSrc(), // Will be null if not initialized!
271  _approxFwdOpSrc = aztecOp->extract_approxFwdOpSrc(); // Will be null if not set
272  if(fwdOpSrc) *fwdOpSrc = _fwdOpSrc;
273  if(approxFwdOpSrc) *approxFwdOpSrc = _approxFwdOpSrc;
274  // Only extract and uset the prec object if it is external. If it is
275  // internal, then we need to hold on to this so that we can reinitialize it
276  // later.
277  if(aztecOp->isExternalPrec()) {
278  Teuchos::RCP<const PreconditionerBase<double> >
279  _prec = aztecOp->extract_prec(); // Will be null if not external preconditioner was set
280  if(prec) *prec = _prec;
281  }
282  // ToDo: Extract the Epetra_Operator views what where used to initialize the
283  // forward and adjoint solvers! This is needed to make this totally
284  // stateless.
285 }
286 
287 
288 // Overridden from ParameterListAcceptor
289 
290 
292  Teuchos::RCP<Teuchos::ParameterList> const& paramList
293  )
294 {
295  TEUCHOS_TEST_FOR_EXCEPT(paramList.get()==NULL);
296  paramList->validateParameters(*this->getValidParameters());
297  paramList_ = paramList;
298  //
299  outputEveryRhs_ = paramList_->get(OutputEveryRhs_name,OutputEveryRhs_default);
300  // Foward Solve parameters
301  Teuchos::ParameterList
302  &fwdSolvePL = paramList_->sublist(ForwardSolve_name);
303  defaultFwdMaxIterations_ = fwdSolvePL.get(MaxIterations_name,defaultFwdMaxIterations_);
304  defaultFwdTolerance_ = fwdSolvePL.get(Tolerance_name,defaultFwdTolerance_);
305  // Adjoint Solve parameters
306  if( !paramList_->getPtr<Teuchos::ParameterList>(AdjointSolve_name) ) {
307  // If adjoint solve sublist is not set, then use the forward solve parameters
308  paramList_->sublist(AdjointSolve_name).setParameters(fwdSolvePL);
309  }
310  Teuchos::ParameterList
311  &adjSolvePL = paramList_->sublist(AdjointSolve_name);
312  defaultAdjMaxIterations_ = adjSolvePL.get(MaxIterations_name,defaultAdjMaxIterations_);
313  defaultAdjTolerance_ = adjSolvePL.get(Tolerance_name,defaultAdjTolerance_);
314  //
315  if(precFactory_.get()) {
316  // Only reset the PF's PL if the sublist exists or the PF does not already
317  // have a PL. We don't want to overwrite an externally set PL for the PF
318  // if we don't have a nested sublist defined here!
319  const bool nestedPFSublistExists = paramList_->isSublist(precFactoryName_);
320  const bool alreadyHasSublist = !is_null(precFactory_->getParameterList());
321  if( nestedPFSublistExists || !alreadyHasSublist ) {
322  precFactory_->setParameterList(Teuchos::sublist(paramList_,precFactoryName_));
323  }
324  }
325  Teuchos::readVerboseObjectSublist(&*paramList_,this);
326 }
327 
328 
329 Teuchos::RCP<Teuchos::ParameterList>
331 {
332  return paramList_;
333 }
334 
335 
336 Teuchos::RCP<Teuchos::ParameterList>
338 {
339  Teuchos::RCP<Teuchos::ParameterList> _paramList = paramList_;
340  paramList_ = Teuchos::null;
341  return _paramList;
342 }
343 
344 
345 Teuchos::RCP<const Teuchos::ParameterList>
347 {
348  return paramList_;
349 }
350 
351 
352 Teuchos::RCP<const Teuchos::ParameterList>
354 {
355  return thisValidParamList_;
356 }
357 
358 
359 // Public functions overridden from Teuchos::Describable
360 
361 
363 {
364  std::ostringstream oss;
365  oss << "Thyra::AztecOOLinearOpWithSolveFactory{";
366  oss << "precFactory=";
367  if(!is_null(precFactory_))
368  oss << precFactory_->description();
369  else
370  oss << "NULL";
371  oss << "}";
372  return oss.str();
373 }
374 
375 
376 // private
377 
378 
379 Teuchos::RCP<const Teuchos::ParameterList>
381 {
382  static Teuchos::RCP<Teuchos::ParameterList> validParamList;
383  if(validParamList.get()==NULL) {
384  validParamList = Teuchos::rcp(
385  new Teuchos::ParameterList("AztecOOLinearOpWithSolveFactory"));
386  validParamList->set(
387  OutputEveryRhs_name,OutputEveryRhs_default
388  ,"Determines if output is created for each individual RHS (true or 1) or if output\n"
389  "is just created for an entire set of RHSs (false or 0)."
390  );
391  static Teuchos::RCP<const Teuchos::ParameterList>
392  aztecParamList = getValidAztecOOParameters();
393  Teuchos::ParameterList
394  &fwdSolvePL = validParamList->sublist(
395  ForwardSolve_name, false
396  ,"Gives the options for the forward solve."
397  );
398  fwdSolvePL.set(
399  Tolerance_name,Tolerance_default
400  ,"The tolerence used in the convergence check (see the convergence test\n"
401  "in the sublist \"" + AztecOO_Settings_name + "\")"
402  );
403  fwdSolvePL.set(
404  MaxIterations_name,MaxIterations_default
405  ,"The maximum number of iterations the AztecOO solver is allowed to perform."
406  );
407  fwdSolvePL.sublist(
408  AztecOO_Settings_name,false
409  ,"Sets the parameters on the AztecOO object itself."
410  ).setParameters(*aztecParamList);
411  Teuchos::ParameterList
412  &adjSolvePL = validParamList->sublist(
413  AdjointSolve_name, false
414  ,"The options for the adjoint solve.\n"
415  "If this sublist is missing then the parameters from the\n"
416  "\""+ForwardSolve_name+"\" sublist are used instead."
417  );
418  // Make the adjoint solve have same defaults as forward solve
419  adjSolvePL.setParameters(fwdSolvePL);
420  }
421  return validParamList;
422 }
423 
424 
426 {
427  thisValidParamList_ = Teuchos::rcp(
428  new Teuchos::ParameterList(*generateAndGetValidParameters())
429  );
430  if(precFactory_.get()) {
431  Teuchos::RCP<const Teuchos::ParameterList>
432  precFactoryValidParamList = precFactory_->getValidParameters();
433  if(precFactoryValidParamList.get()) {
434  thisValidParamList_->sublist(precFactoryName_).setParameters(
435  *precFactoryValidParamList);
436  }
437  }
438  Teuchos::setupVerboseObjectSublist(&*thisValidParamList_);
439 }
440 
441 
443  const Teuchos::RCP<const LinearOpSourceBase<double> > &fwdOpSrc,
444  const Teuchos::RCP<const PreconditionerBase<double> > &prec,
445  const Teuchos::RCP<const LinearOpSourceBase<double> > &approxFwdOpSrc,
446  const bool reusePrec,
447  LinearOpWithSolveBase<double> *Op
448  ) const
449 {
450  using Teuchos::RCP;
451  using Teuchos::null;
452  using Teuchos::rcp;
453  using Teuchos::rcp_dynamic_cast;
454  using Teuchos::rcp_const_cast;
455  using Teuchos::set_extra_data;
456  using Teuchos::get_optional_extra_data;
457  using Teuchos::get_optional_nonconst_extra_data;
458  using Teuchos::outArg;
459  typedef EpetraExt::ProductOperator PO;
460 
461  const Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
462  const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
463  Teuchos::OSTab tab(out);
464  if(out.get() && static_cast<int>(verbLevel) > static_cast<int>(Teuchos::VERB_LOW))
465  *out << "\nEntering Thyra::AztecOOLinearOpWithSolveFactory::initializeOp_impl(...) ...\n";
466 
467  typedef Teuchos::VerboseObjectTempState<PreconditionerFactoryBase<double> > VOTSPF;
468  VOTSPF precFactoryOutputTempState(precFactory_,out,verbLevel);
469 
470 #ifdef TEUCHOS_DEBUG
471  TEUCHOS_TEST_FOR_EXCEPT(Op==NULL);
472  TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc.get()==NULL);
473  TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc->getOp().get()==NULL);
474 #endif
475 
476  //
477  // Determine whether the operators are EpetraLinearOp objects. If so, we're
478  // good to go. If not, we need to wrap it as an Epetra_Operator with some
479  // invasive code.
480  //
481  Teuchos::RCP<const LinearOpBase<double> >
482  tmpFwdOp = fwdOpSrc->getOp(),
483  tmpApproxFwdOp = ( approxFwdOpSrc.get() ? approxFwdOpSrc->getOp() : Teuchos::null );
484  Teuchos::RCP<const LinearOpBase<double> > fwdOp;
485  Teuchos::RCP<const LinearOpBase<double> > approxFwdOp;
486  if ( dynamic_cast<const EpetraLinearOpBase*>(tmpFwdOp.get())!=0 )
487  {
488  fwdOp = tmpFwdOp;
489  approxFwdOp = tmpApproxFwdOp;
490  }
491  else
492  {
493  fwdOp = makeEpetraWrapper(tmpFwdOp);
494  if (
495  tmpApproxFwdOp.get()
496  &&
497  dynamic_cast<const EpetraLinearOpBase*>(&*tmpApproxFwdOp.get())
498  )
499  {
500  approxFwdOp = makeEpetraWrapper(tmpApproxFwdOp);
501  }
502  }
503 
504  //
505  // Get the AztecOOLinearOpWithSolve object
506  //
508  *aztecOp = &Teuchos::dyn_cast<AztecOOLinearOpWithSolve>(*Op);
509 
510  //
511  // Unwrap and get the forward operator or matrix
512  //
513  Teuchos::RCP<const Epetra_Operator> epetra_epetraFwdOp;
514  EOpTransp epetra_epetraFwdOpTransp;
515  EApplyEpetraOpAs epetra_epetraFwdOpApplyAs;
516  EAdjointEpetraOp epetra_epetraFwdOpAdjointSupport;
517  double epetra_epetraFwdOpScalar;
518  epetraFwdOpViewExtractor_->getEpetraOpView(
519  fwdOp,
520  outArg(epetra_epetraFwdOp), outArg(epetra_epetraFwdOpTransp),
521  outArg(epetra_epetraFwdOpApplyAs), outArg(epetra_epetraFwdOpAdjointSupport),
522  outArg(epetra_epetraFwdOpScalar)
523  );
524  TEUCHOS_TEST_FOR_EXCEPTION(
525  epetra_epetraFwdOp.get()==NULL, std::logic_error
526  ,"Error, The input fwdOp object must be fully initialized "
527  "before calling this function!"
528  );
529 
530  //
531  // Get the preconditioner object to use
532  //
533  Teuchos::RCP<PreconditionerBase<double> > myPrec;
534  Teuchos::RCP<const PreconditionerBase<double> > precUsed;
535  if (prec.get()) {
536  // We will be used the passed in external preconditioner
537  precUsed = prec;
538  }
539  else if (precFactory_.get() ) {
540  // We will be creating our own preconditioner using an externally set
541  // preconditioner factory
542  myPrec =
543  ( !aztecOp->isExternalPrec()
544  ? Teuchos::rcp_const_cast<PreconditionerBase<double> >(
545  aztecOp->extract_prec())
546  : Teuchos::null
547  );
548  if(myPrec.get()) {
549  // ToDo: Get the forward operator and validate that it is the same
550  // operator that is used here!
551  }
552  else {
553  myPrec = precFactory_->createPrec();
554  }
555  precFactory_->initializePrec(fwdOpSrc,&*myPrec);
556  precUsed = myPrec;
557  }
558 
559  //
560  // Unwrap and get the preconditioner operator
561  //
562  RCP<const LinearOpBase<double> > rightPrecOp;
563  if (precUsed.get()) {
564  RCP<const LinearOpBase<double> > unspecified = precUsed->getUnspecifiedPrecOp();
565  RCP<const LinearOpBase<double> > left = precUsed->getLeftPrecOp();
566  RCP<const LinearOpBase<double> > right = precUsed->getRightPrecOp();
567  TEUCHOS_TEST_FOR_EXCEPTION(
568  !( left.get() || right.get() || unspecified.get() ), std::logic_error
569  ,"Error, at least one preconditoner linear operator objects must be set!"
570  );
571  if(unspecified.get()) {
572  rightPrecOp = unspecified;
573  }
574  else {
575  // Set a left, right or split preconditioner
576  TEUCHOS_TEST_FOR_EXCEPTION(
577  left.get(),std::logic_error
578  ,"Error, we can not currently handle a left"
579  " preconditioner with the AztecOO/Thyra adapters!"
580  );
581  rightPrecOp = right;
582  }
583  }
584  double wrappedPrecOpScalar = 0.0;
585  EOpTransp wrappedPrecOpTransp = NOTRANS;
586  RCP<const LinearOpBase<double> > wrappedPrecOp = null;
587  RCP<const EpetraLinearOpBase> epetraPrecOp;
588  Teuchos::RCP<const Epetra_Operator> epetra_epetraPrecOp;
589  EOpTransp epetra_epetraPrecOpTransp;
590  EApplyEpetraOpAs epetra_epetraPrecOpApplyAs;
591  EAdjointEpetraOp epetra_epetraPrecOpAdjointSupport;
592  EOpTransp overall_epetra_epetraPrecOpTransp;
593  if(rightPrecOp.get()) {
594  RCP<const LinearOpBase<double> > tmpWrappedPrecOp;
595  unwrap(
596  rightPrecOp,&wrappedPrecOpScalar,&wrappedPrecOpTransp,&tmpWrappedPrecOp);
597  if( dynamic_cast<const EpetraLinearOpBase*>(&*tmpWrappedPrecOp) ) {
598  wrappedPrecOp = tmpWrappedPrecOp;
599  }
600  else {
601  wrappedPrecOp = makeEpetraWrapper(tmpWrappedPrecOp);
602  }
603  epetraPrecOp = rcp_dynamic_cast<const EpetraLinearOpBase>(
604  wrappedPrecOp,true);
605  epetraPrecOp->getEpetraOpView(
606  outArg(epetra_epetraPrecOp), outArg(epetra_epetraPrecOpTransp),
607  outArg(epetra_epetraPrecOpApplyAs), outArg(epetra_epetraPrecOpAdjointSupport));
608  TEUCHOS_TEST_FOR_EXCEPTION(
609  epetra_epetraPrecOp.get()==NULL,std::logic_error
610  ,"Error, The input prec object and its embedded preconditioner"
611  " operator must be fully initialized before calling this function!"
612  );
613  // 2007/08/10: rabartl: This next set_extra_data(...) call is likely to be
614  // setting up a circular reference! Since epetra_epetraPrecOp was
615  // gotten from epetraPrecOp, if you set epetraPrecOp as extra data
616  // on the RCP epetra_epetraPrecOp then you have a circular reference!
617  //set_extra_data(
618  // epetraPrecOp, AOOLOWSF_epetraPrecOp_str, &epetra_epetraPrecOp,
619  // Teuchos::POST_DESTROY, false );
620  overall_epetra_epetraPrecOpTransp
621  = trans_trans(
622  real_trans(wrappedPrecOpTransp),
623  real_trans(epetra_epetraPrecOpTransp)
624  );
625  }
626 
627  //
628  // Unwrap and get the approximate forward operator to be used to generate a
629  // preconditioner
630  //
631  if(approxFwdOp.get()) {
632  // Note, here we just use the same members data that would be set for an
633  // extenral preconditioner operator since it is not getting used.
634  unwrap(approxFwdOp,&wrappedPrecOpScalar,&wrappedPrecOpTransp,&wrappedPrecOp);
635  epetraPrecOp = rcp_dynamic_cast<const EpetraLinearOpBase>(
636  wrappedPrecOp,true);
637  epetraPrecOp->getEpetraOpView(
638  outArg(epetra_epetraPrecOp), outArg(epetra_epetraPrecOpTransp),
639  outArg(epetra_epetraPrecOpApplyAs), outArg(epetra_epetraPrecOpAdjointSupport)
640  );
641  TEUCHOS_TEST_FOR_EXCEPTION(
642  epetra_epetraPrecOp.get()==NULL,std::logic_error
643  ,"Error, The input approxFwdOp object must be fully initialized"
644  " before calling this function!"
645  );
646  // 2007/08/10: rabartl: This next set_extra_data(...) call is likely to be
647  // setting up a circular reference! Since epetra_epetraPrecOp was
648  // gotten from epetraPrecOp, if you set epetraPrecOp as extra data
649  // on the RCP epetra_epetraPrecOp then you have a circular reference!
650  //set_extra_data(
651  // epetraPrecOp, AOOLOWSF_epetraPrecOp_str, &epetra_epetraPrecOp,
652  // Teuchos::POST_DESTROY, false
653  // );
654  overall_epetra_epetraPrecOpTransp
655  = trans_trans(
656  real_trans(wrappedPrecOpTransp),
657  real_trans(epetra_epetraPrecOpTransp)
658  );
659  }
660 
661  //
662  // Determine if the forward and preconditioner operators are a row matrices
663  // or not
664  //
665  RCP<const Epetra_RowMatrix>
666  rowmatrix_epetraFwdOp = rcp_dynamic_cast<const Epetra_RowMatrix>(
667  epetra_epetraFwdOp),
668  rowmatrix_epetraPrecOp = rcp_dynamic_cast<const Epetra_RowMatrix>(
669  epetra_epetraPrecOp);
670  //
671  // Determine the type of preconditoner
672  //
673  // Update useAztecPrec_, input value does not matter
674  this->supportsPreconditionerInputType(PRECONDITIONER_INPUT_TYPE_AS_MATRIX);
675  enum ELocalPrecType {
676  PT_NONE, PT_AZTEC_FROM_OP, PT_AZTEC_FROM_APPROX_FWD_MATRIX,
677  PT_FROM_PREC_OP, PT_UPPER_BOUND
678  };
679  ELocalPrecType localPrecType = PT_UPPER_BOUND;
680  if( precUsed.get()==NULL && approxFwdOp.get()==NULL && !useAztecPrec_ ) {
681  // No preconditioning at all!
682  localPrecType = PT_NONE;
683  }
684  else if( precUsed.get()==NULL && approxFwdOp.get()==NULL && useAztecPrec_ ) {
685  // We are using the forward matrix for the preconditioner using aztec
686  // preconditioners
687  localPrecType = PT_AZTEC_FROM_OP;
688  }
689  else if( approxFwdOp.get() && useAztecPrec_ ) {
690  // The preconditioner comes from the input as a matrix and we are using
691  // aztec preconditioners
692  localPrecType = PT_AZTEC_FROM_APPROX_FWD_MATRIX;
693  }
694  else if( precUsed.get() ) {
695  // The preconditioner comes as an external operator so let's use it as
696  // such
697  localPrecType = PT_FROM_PREC_OP;
698  }
699  TEUCHOS_TEST_FOR_EXCEPTION
700  (localPrecType == PT_UPPER_BOUND, std::logic_error,
701  "AztecOOLinearOpWithSolveFactory::initializeOp_impl(...): "
702  "localPrecType == PT_UPPER_BOUND. This means that previously, "
703  "this value might have been used uninitialized. "
704  "Please report this bug to the Stratimikos developers.");
705 
706  //
707  // Determine if aztecOp already contains solvers and if we need to
708  // reinitialize or not
709  //
710  RCP<AztecOO> aztecFwdSolver, aztecAdjSolver;
711  bool startingOver;
712  {
713  // Let's assume that fwdOp, prec and/or approxFwdOp are compatible with
714  // the already created AztecOO objects. If they are not, then the client
715  // should have created a new LOWSB object from scratch!
716  Teuchos::RCP<const LinearOpBase<double> > old_fwdOp;
717  Teuchos::RCP<const LinearOpSourceBase<double> > old_fwdOpSrc;
718  Teuchos::RCP<const PreconditionerBase<double> > old_prec;
719  bool old_isExternalPrec;
720  Teuchos::RCP<const LinearOpSourceBase<double> > old_approxFwdOpSrc;
721  Teuchos::RCP<AztecOO> old_aztecFwdSolver;
722  Teuchos::RCP<AztecOO> old_aztecAdjSolver;
723  double old_aztecSolverScalar;
724  aztecOp->uninitialize(
725  &old_fwdOp
726  ,&old_fwdOpSrc
727  ,&old_prec
728  ,&old_isExternalPrec
729  ,&old_approxFwdOpSrc
730  ,&old_aztecFwdSolver
731  ,NULL
732  ,&old_aztecAdjSolver
733  ,NULL
734  ,&old_aztecSolverScalar
735  );
736  if( old_aztecFwdSolver.get()==NULL ) {
737  // This has never been initialized before
738  startingOver = true;
739  }
740  else {
741  // Let's assume that fwdOp, prec and/or approxFwdOp are compatible with
742  // the already created AztecOO objects. If they are not, then the
743  // client should have created a new LOWSB object from scratch!
744  aztecFwdSolver = old_aztecFwdSolver;
745  aztecAdjSolver = old_aztecAdjSolver;
746  startingOver = false;
747  // We must wipe out the old preconditoner if we are not reusing the
748  // preconditioner
749  Ptr<bool> constructedAztecPreconditioner;
750  if(
751  !reusePrec
752  &&
753  !is_null(constructedAztecPreconditioner = get_optional_nonconst_extra_data<bool>(
754  aztecFwdSolver, "AOOLOWSF::constructedAztecPreconditoner") )
755  &&
756  *constructedAztecPreconditioner
757  )
758  {
759  aztecFwdSolver->DestroyPreconditioner();
760  *constructedAztecPreconditioner = false;
761  }
762  // We must see if we set an external preconditioner but will not do so
763  // again in which case we must blow away AztecOO and start over again!
764  Ptr<bool> setPreconditionerOperator;
765  if(
766  localPrecType != PT_FROM_PREC_OP
767  && !is_null( setPreconditionerOperator = get_optional_nonconst_extra_data<bool>(
768  aztecFwdSolver,"AOOLOWSF::setPreconditonerOperator") )
769  && *setPreconditionerOperator
770  )
771  {
772  // We must start over again since there is no way to unset an external
773  // preconditioner!
774  startingOver = true;
775  }
776  }
777  }
778 
779  //
780  // Create the AztecOO solvers if we are starting over
781  //
782  startingOver = true; // ToDo: Remove this and figure out why this is not working!
783  if(startingOver) {
784  // Forward solver
785  aztecFwdSolver = rcp(new AztecOO());
786  aztecFwdSolver->SetAztecOption(AZ_diagnostics,AZ_none); // This was turned off in NOX?
787  aztecFwdSolver->SetAztecOption(AZ_keep_info,1);
788  // Adjoint solver (if supported)
789  if(
790  epetra_epetraFwdOpAdjointSupport==EPETRA_OP_ADJOINT_SUPPORTED
791  &&
792  localPrecType!=PT_AZTEC_FROM_OP && localPrecType!=PT_AZTEC_FROM_APPROX_FWD_MATRIX
793  )
794  {
795  aztecAdjSolver = rcp(new AztecOO());
796  aztecAdjSolver->SetAztecOption(AZ_diagnostics,AZ_none);
797  //aztecAdjSolver->SetAztecOption(AZ_keep_info,1);
798  }
799  }
800 
801  //
802  // Set the options on the AztecOO solvers
803  //
804  if( startingOver ) {
805  if(paramList_.get())
807  &paramList_->sublist(ForwardSolve_name).sublist(AztecOO_Settings_name),
808  &*aztecFwdSolver
809  );
810  if(aztecAdjSolver.get() && paramList_.get())
812  &paramList_->sublist(AdjointSolve_name).sublist(AztecOO_Settings_name),
813  &*aztecAdjSolver
814  );
815  }
816 
817  //
818  // Process the forward operator
819  //
820  RCP<const Epetra_Operator>
821  aztec_epetra_epetraFwdOp,
822  aztec_epetra_epetraAdjOp;
823  // Forward solve
824  RCP<const Epetra_Operator>
825  epetraOps[]
826  = { epetra_epetraFwdOp };
827  Teuchos::ETransp
828  epetraOpsTransp[]
829  = { epetra_epetraFwdOpTransp==NOTRANS ? Teuchos::NO_TRANS : Teuchos::TRANS };
830  PO::EApplyMode
831  epetraOpsApplyMode[]
832  = { epetra_epetraFwdOpApplyAs==EPETRA_OP_APPLY_APPLY
833  ? PO::APPLY_MODE_APPLY
834  : PO::APPLY_MODE_APPLY_INVERSE };
835  if(
836  epetraOpsTransp[0] == Teuchos::NO_TRANS
837  &&
838  epetraOpsApplyMode[0] == PO::APPLY_MODE_APPLY
839  )
840  {
841  aztec_epetra_epetraFwdOp = epetra_epetraFwdOp;
842  }
843  else
844  {
845  aztec_epetra_epetraFwdOp = rcp(
846  new PO(1,epetraOps,epetraOpsTransp,epetraOpsApplyMode));
847  }
848  if(
849  startingOver
850  ||
851  aztec_epetra_epetraFwdOp.get() != aztecFwdSolver->GetUserOperator()
852  )
853  {
854  // Here we will be careful not to reset the forward operator in fears that
855  // it will blow out the internally created stuff.
856  aztecFwdSolver->SetUserOperator(
857  const_cast<Epetra_Operator*>(&*aztec_epetra_epetraFwdOp));
858  set_extra_data(
859  aztec_epetra_epetraFwdOp, AOOLOWSF_aztec_epetra_epetraFwdOp_str,
860  Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY, false
861  );
862  }
863  // Adjoint solve
864  if( aztecAdjSolver.get() ) {
865  epetraOpsTransp[0] = (
866  epetra_epetraFwdOpTransp==NOTRANS
867  ? Teuchos::TRANS
868  : Teuchos::NO_TRANS
869  );
870  if(
871  epetraOpsTransp[0] == Teuchos::NO_TRANS
872  &&
873  epetraOpsApplyMode[0] == PO::APPLY_MODE_APPLY
874  )
875  {
876  aztec_epetra_epetraAdjOp = epetra_epetraFwdOp;
877  }
878  else {
879  aztec_epetra_epetraAdjOp = rcp(
880  new PO(1,epetraOps,epetraOpsTransp,epetraOpsApplyMode));
881  }
882  aztecAdjSolver->SetUserOperator(
883  const_cast<Epetra_Operator*>(&*aztec_epetra_epetraAdjOp));
884  set_extra_data(
885  aztec_epetra_epetraAdjOp, AOOLOWSF_aztec_epetra_epetraAdjOp_str,
886  Teuchos::inOutArg(aztecAdjSolver), Teuchos::POST_DESTROY, false
887  );
888  }
889 
890  //
891  // Process the preconditioner
892  //
893  RCP<const Epetra_Operator>
894  aztec_fwd_epetra_epetraPrecOp,
895  aztec_adj_epetra_epetraPrecOp;
896  bool setAztecPreconditioner = false;
897  switch(localPrecType) {
898  case PT_NONE: {
899  //
900  // No preconditioning at all!
901  //
902  break;
903  }
904  case PT_AZTEC_FROM_OP: {
905  //
906  // We are using the forward matrix for the preconditioner using aztec
907  // preconditioners
908  //
909  if( startingOver || !reusePrec ) {
910  TEUCHOS_TEST_FOR_EXCEPTION(
911  rowmatrix_epetraFwdOp.get()==NULL, std::logic_error,
912  "AztecOOLinearOpWithSolveFactory::initializeOp_impl(...): "
913  "Error, There is no preconditioner given by client, but the client "
914  "passed in an Epetra_Operator for the forward operator of type \'"
915  <<typeName(*epetra_epetraFwdOp)<<"\' that does not "
916  "support the Epetra_RowMatrix interface!"
917  );
918  TEUCHOS_TEST_FOR_EXCEPTION(
919  epetra_epetraFwdOpTransp!=NOTRANS, std::logic_error,
920  "AztecOOLinearOpWithSolveFactory::initializeOp_impl(...):"
921  " Error, There is no preconditioner given by client and the client "
922  "passed in an Epetra_RowMatrix for the forward operator but the "
923  "overall transpose is not NOTRANS and therefore we can can just "
924  "hand this over to aztec without making a copy which is not supported here!"
925  );
926  aztecFwdSolver->SetPrecMatrix(
927  const_cast<Epetra_RowMatrix*>(&*rowmatrix_epetraFwdOp));
928  set_extra_data(
929  rowmatrix_epetraFwdOp, AOOLOWSF_rowmatrix_epetraFwdOp_str,
930  Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY, false
931  );
932  }
933  setAztecPreconditioner = true;
934  break;
935  }
936  case PT_AZTEC_FROM_APPROX_FWD_MATRIX: {
937  //
938  // The preconditioner comes from the input as a matrix and we are using
939  // aztec preconditioners
940  //
941  if( startingOver || !reusePrec ) {
942  TEUCHOS_TEST_FOR_EXCEPTION(
943  rowmatrix_epetraPrecOp.get()==NULL, std::logic_error
944  ,"AztecOOLinearOpWithSolveFactor::initializeOp_impl(...): The client "
945  "passed in an Epetra_Operator for the preconditioner matrix of type \'"
946  <<typeName(*epetra_epetraPrecOp)<<"\' that does not "
947  "support the Epetra_RowMatrix interface!"
948  );
949  TEUCHOS_TEST_FOR_EXCEPTION(
950  overall_epetra_epetraPrecOpTransp!=NOTRANS, std::logic_error
951  ,"AztecOOLinearOpWithSolveFactor::initializeOp_impl(...): Error, The client "
952  "passed in an Epetra_RowMatrix for the preconditoner matrix but the overall "
953  "transpose is not NOTRANS and therefore we can can just "
954  "hand this over to aztec without making a copy which is not supported here!"
955  );
956  aztecFwdSolver->SetPrecMatrix(
957  const_cast<Epetra_RowMatrix*>(&*rowmatrix_epetraPrecOp));
958  set_extra_data(
959  rowmatrix_epetraPrecOp, AOOLOWSF_rowmatrix_epetraPrecOp_str,
960  Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY, false
961  );
962  }
963  setAztecPreconditioner = true;
964  break;
965  }
966  case PT_FROM_PREC_OP: {
967  //
968  // The preconditioner comes as an operator so let's use it as such
969  //
970  // Forward solve
971  RCP<const Epetra_Operator>
972  theEpetraOps[]
973  = { epetra_epetraPrecOp };
974  Teuchos::ETransp
975  theEpetraOpsTransp[]
976  = { overall_epetra_epetraPrecOpTransp==NOTRANS
977  ? Teuchos::NO_TRANS
978  : Teuchos::TRANS };
979  // Here we must toggle the apply mode since aztecoo applies the
980  // preconditioner using ApplyInverse(...)
981  PO::EApplyMode
982  theEpetraOpsApplyMode[]
983  = { epetra_epetraPrecOpApplyAs==EPETRA_OP_APPLY_APPLY
984  ? PO::APPLY_MODE_APPLY_INVERSE
985  : PO::APPLY_MODE_APPLY };
986  if(
987  theEpetraOpsTransp[0] == Teuchos::NO_TRANS
988  &&
989  epetra_epetraPrecOpApplyAs==EPETRA_OP_APPLY_APPLY_INVERSE
990  )
991  {
992  aztec_fwd_epetra_epetraPrecOp = epetra_epetraPrecOp;
993  }
994  else {
995  aztec_fwd_epetra_epetraPrecOp = rcp(new PO(1,theEpetraOps,theEpetraOpsTransp,theEpetraOpsApplyMode));
996  }
997  aztecFwdSolver->SetPrecOperator(
998  const_cast<Epetra_Operator*>(&*aztec_fwd_epetra_epetraPrecOp));
999  set_extra_data(
1000  aztec_fwd_epetra_epetraPrecOp, AOOLOWSF_aztec_fwd_epetra_epetraPrecOp_str,
1001  Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY, false
1002  );
1003  // Adjoint solve
1004  if(
1005  aztecAdjSolver.get()
1006  &&
1007  epetra_epetraPrecOpAdjointSupport == EPETRA_OP_ADJOINT_SUPPORTED
1008  )
1009  {
1010  theEpetraOpsTransp[0] = (
1011  overall_epetra_epetraPrecOpTransp==NOTRANS
1012  ? Teuchos::TRANS
1013  : Teuchos::NO_TRANS
1014  );
1015  if(
1016  theEpetraOpsTransp[0] == Teuchos::NO_TRANS
1017  &&
1018  epetra_epetraPrecOpApplyAs==EPETRA_OP_APPLY_APPLY_INVERSE
1019  )
1020  {
1021  aztec_adj_epetra_epetraPrecOp = epetra_epetraPrecOp;
1022  }
1023  else {
1024  aztec_adj_epetra_epetraPrecOp = rcp(
1025  new PO(1,theEpetraOps,theEpetraOpsTransp,theEpetraOpsApplyMode));
1026  }
1027  aztecAdjSolver->SetPrecOperator(
1028  const_cast<Epetra_Operator*>(&*aztec_adj_epetra_epetraPrecOp));
1029  set_extra_data(
1030  aztec_adj_epetra_epetraPrecOp, AOOLOWSF_aztec_adj_epetra_epetraPrecOp_str,
1031  Teuchos::inOutArg(aztecAdjSolver), Teuchos::POST_DESTROY, false
1032  );
1033  set_extra_data<bool>(
1034  true, AOOLOWSF_setPrecondtionerOperator_str,
1035  Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY, false
1036  );
1037  }
1038  break;
1039  }
1040  default:
1041  TEUCHOS_TEST_FOR_EXCEPT(true);
1042  }
1043 
1044  //
1045  // Initialize the interal aztec preconditioner
1046  //
1047  if(setAztecPreconditioner) {
1048  if( startingOver || !reusePrec ) {
1049  double condNumEst = -1.0;
1050  TEUCHOS_TEST_FOR_EXCEPT(0!=aztecFwdSolver->ConstructPreconditioner(condNumEst));
1051  //aztecFwdSolver->SetAztecOption(AZ_pre_calc, AZ_calc);
1052  set_extra_data<bool>(
1053  true, AOOLOWSF_constructedAztecPreconditoner_str,
1054  Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY, false
1055  );
1056  }
1057  else {
1058  //aztecFwdSolver->SetAztecOption(AZ_pre_calc, AZ_reuse);
1059  }
1060  }
1061 
1062  //
1063  // Initialize the AztecOOLinearOpWithSolve object and set its options
1064  //
1065  if(aztecAdjSolver.get() && aztecAdjSolver->GetPrecOperator()) {
1066  aztecOp->initialize(
1067  fwdOp, fwdOpSrc,precUsed, prec.get()!=NULL, approxFwdOpSrc,
1068  aztecFwdSolver, true, aztecAdjSolver, true, epetra_epetraFwdOpScalar
1069  );
1070  }
1071  else {
1072  aztecOp->initialize(
1073  fwdOp, fwdOpSrc, precUsed, prec.get()!=NULL, approxFwdOpSrc,
1074  aztecFwdSolver, true, null, false, epetra_epetraFwdOpScalar
1075  );
1076  }
1077  aztecOp->fwdDefaultMaxIterations(defaultFwdMaxIterations_);
1078  aztecOp->fwdDefaultTol(defaultFwdTolerance_);
1079  aztecOp->adjDefaultMaxIterations(defaultAdjMaxIterations_);
1080  aztecOp->adjDefaultTol(defaultAdjTolerance_);
1081  aztecOp->outputEveryRhs(outputEveryRhs_);
1082  aztecOp->setOStream(this->getOStream());
1083  if(!is_null(this->getOverridingOStream()))
1084  aztecOp->setOverridingOStream(this->getOverridingOStream());
1085  aztecOp->setVerbLevel(this->getVerbLevel());
1086 
1087 #ifdef TEUCHOS_DEBUG
1088  if(paramList_.get())
1089  paramList_->validateParameters(*this->getValidParameters());
1090 #endif
1091 
1092  if(out.get() && static_cast<int>(verbLevel) > static_cast<int>(Teuchos::VERB_LOW))
1093  *out << "\nLeaving Thyra::AztecOOLinearOpWithSolveFactory::initializeOp_impl(...) ...\n";
1094 
1095 }
1096 
1097 
1098 } // namespace Thyra
1099 
1100 
1101 #endif // SUN_CXX
void setAztecOOParameters(Teuchos::ParameterList *pl, AztecOO *solver)
Setup an AztecOO solver object with a set of parameters.
Teuchos::RCP< PreconditionerFactoryBase< double > > getPreconditionerFactory() const
Teuchos::RCP< Teuchos::ParameterList > thisValidParamList_
bool supportsPreconditionerInputType(const EPreconditionerInputType precOpType) const
Teuchos::RCP< PreconditionerFactoryBase< double > > precFactory_
RCP< const LinearOpSourceBase< double > > extract_fwdOpSrc()
Extract the forward LinearOpBase<double> object so that it can be modified.
AztecOOLinearOpWithSolveFactory(Teuchos::RCP< Teuchos::ParameterList > const &paramList=Teuchos::null)
Construct uninitialized.
void initializeAndReuseOp(const Teuchos::RCP< const LinearOpSourceBase< double > > &fwdOpSrc, LinearOpWithSolveBase< double > *Op) const
bool isExternalPrec() const
Determine if the preconditioner was external or not.
void initializeApproxPreconditionedOp(const Teuchos::RCP< const LinearOpSourceBase< double > > &fwdOpSrc, const Teuchos::RCP< const LinearOpSourceBase< double > > &approxFwdOpSrc, LinearOpWithSolveBase< double > *Op, const ESupportSolveUse supportSolveUse) const
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
void uninitializeOp(LinearOpWithSolveBase< double > *Op, Teuchos::RCP< const LinearOpSourceBase< double > > *fwdOpSrc, Teuchos::RCP< const PreconditionerBase< double > > *prec, Teuchos::RCP< const LinearOpSourceBase< double > > *approxFwdOpSrc, ESupportSolveUse *supportSolveUse) const
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
void unsetPreconditionerFactory(Teuchos::RCP< PreconditionerFactoryBase< double > > *precFactory, std::string *precFactoryName)
Teuchos::RCP< LinearOpWithSolveBase< double > > createOp() const
void initializeOp_impl(const Teuchos::RCP< const LinearOpSourceBase< double > > &fwdOpSrc, const Teuchos::RCP< const PreconditionerBase< double > > &prec, const Teuchos::RCP< const LinearOpSourceBase< double > > &approxFwdOpSrc, const bool reusePrec, LinearOpWithSolveBase< double > *Op) const
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const &paramList)
void uninitialize(RCP< const LinearOpBase< double > > *fwdOp=NULL, RCP< const LinearOpSourceBase< double > > *fwdOpSrc=NULL, RCP< const PreconditionerBase< double > > *prec=NULL, bool *isExternalPrec=NULL, RCP< const LinearOpSourceBase< double > > *approxFwdOpSrc=NULL, RCP< AztecOO > *aztecFwdSolver=NULL, bool *allowInexactFwdSolve=NULL, RCP< AztecOO > *aztecAdjSolver=NULL, bool *allowInexactAdjSolve=NULL, double *aztecSolverScalar=NULL)
Uninitialize.
RCP< const PreconditionerBase< double > > extract_prec()
Extract the preconditioner.
Teuchos::RCP< const Teuchos::ParameterList > getParameterList() const
bool isCompatible(const LinearOpSourceBase< double > &fwdOpSrc) const
void initializePreconditionedOp(const Teuchos::RCP< const LinearOpSourceBase< double > > &fwdOpSrc, const Teuchos::RCP< const PreconditionerBase< double > > &prec, LinearOpWithSolveBase< double > *Op, const ESupportSolveUse supportSolveUse) const
void initializeOp(const Teuchos::RCP< const LinearOpSourceBase< double > > &fwdOpSrc, LinearOpWithSolveBase< double > *Op, const ESupportSolveUse supportSolveUse) const
void initialize(const RCP< const LinearOpBase< double > > &fwdOp, const RCP< const LinearOpSourceBase< double > > &fwdOpSrc, const RCP< const PreconditionerBase< double > > &prec, const bool isExternalPrec, const RCP< const LinearOpSourceBase< double > > &approxFwdOpSrc, const RCP< AztecOO > &aztecFwdSolver, const bool allowInexactFwdSolve=false, const RCP< AztecOO > &aztecAdjSolver=Teuchos::null, const bool allowInexactAdjSolve=false, const double aztecSolverScalar=1.0)
Sets up this object.
Teuchos::RCP< const Teuchos::ParameterList > getValidAztecOOParameters()
Return the list of all valid AztecOO parameters (to validate against).
void setPreconditionerFactory(const Teuchos::RCP< PreconditionerFactoryBase< double > > &precFactory, const std::string &precFactoryName)
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
Concrete LinearOpWithSolveBase subclass implemented using AztecOO.
static Teuchos::RCP< const Teuchos::ParameterList > generateAndGetValidParameters()
RCP< const LinearOpSourceBase< double > > extract_approxFwdOpSrc()
Extract the approximate forward LinearOpBase<double> object used to build the preconditioner.