Thyra_BelosLinearOpWithSolveFactory.hpp

Go to the documentation of this file.
00001 
00002 #ifndef __sun
00003 
00004 #ifndef THYRA_BELOS_LINEAR_OP_WITH_SOLVE_FACTORY_HPP
00005 #define THYRA_BELOS_LINEAR_OP_WITH_SOLVE_FACTORY_HPP
00006 
00007 #include "Thyra_BelosLinearOpWithSolveFactoryDecl.hpp"
00008 #include "Thyra_BelosLinearOpWithSolve.hpp"
00009 #include "Thyra_ScaledAdjointLinearOpBase.hpp"
00010 #include "BelosBlockGmres.hpp"
00011 #include "BelosBlockCG.hpp"
00012 #include "BelosThyraAdapter.hpp"
00013 #include "BelosStatusTestMaxIters.hpp"
00014 #include "BelosStatusTestMaxRestarts.hpp"
00015 #include "BelosStatusTestResNorm.hpp"
00016 #include "BelosStatusTestOutputter.hpp"
00017 #include "BelosStatusTestCombo.hpp"
00018 #include "Teuchos_ParameterList.hpp"
00019 #include "Teuchos_dyn_cast.hpp"
00020 
00021 namespace Thyra {
00022 
00023 // Parameter names for Paramter List
00024 
00025 template<class Scalar>
00026 const std::string BelosLinearOpWithSolveFactory<Scalar>::SolverType_name = "Solver Type";
00027 template<class Scalar>
00028 const std::string BelosLinearOpWithSolveFactory<Scalar>::SolverType_default = "GMRES";
00029 template<class Scalar>
00030 const std::string BelosLinearOpWithSolveFactory<Scalar>::MaxIters_name = "Max Iters";
00031 template<class Scalar>
00032 const int         BelosLinearOpWithSolveFactory<Scalar>::MaxIters_default = 400;
00033 template<class Scalar>
00034 const std::string BelosLinearOpWithSolveFactory<Scalar>::MaxRestarts_name = "Max Restarts";
00035 template<class Scalar>
00036 const int         BelosLinearOpWithSolveFactory<Scalar>::MaxRestarts_default = 25;
00037 template<class Scalar>
00038 const std::string BelosLinearOpWithSolveFactory<Scalar>::BlockSize_name = "Block Size";
00039 template<class Scalar>
00040 const int         BelosLinearOpWithSolveFactory<Scalar>::BlockSize_default = 1; // ToDo: We need to make Belos robust when BlockSize > 1 !!!
00041 template<class Scalar>
00042 const std::string BelosLinearOpWithSolveFactory<Scalar>::AdjustableBlockSize_name = "Adjustable Block Size";
00043 template<class Scalar>
00044 const bool        BelosLinearOpWithSolveFactory<Scalar>::AdjustableBlockSize_default = true;
00045 template<class Scalar>
00046 const std::string BelosLinearOpWithSolveFactory<Scalar>::DefaultRelResNorm_name = "Default Rel Res Norm";
00047 template<class Scalar>
00048 const typename BelosLinearOpWithSolveFactory<Scalar>::MagnitudeType
00049                   BelosLinearOpWithSolveFactory<Scalar>::DefaultRelResNorm_default = 1e-6;
00050 template<class Scalar>
00051 const std::string BelosLinearOpWithSolveFactory<Scalar>::GMRES_name = "GMRES";
00052 template<class Scalar>
00053 const std::string BelosLinearOpWithSolveFactory<Scalar>::GMRES_MaxNumberOfKrylovVectors_name = "Max Number of Krylov Vectors";
00054 template<class Scalar>
00055 const int         BelosLinearOpWithSolveFactory<Scalar>::GMRES_MaxNumberOfKrylovVectors_default = 300; // Consistent with NOX::LinearSystemAztecOO
00056 template<class Scalar>
00057 const std::string BelosLinearOpWithSolveFactory<Scalar>::GMRES_Variant_name = "Variant";
00058 template<class Scalar>
00059 const std::string BelosLinearOpWithSolveFactory<Scalar>::GMRES_Variant_default = "Standard";
00060 template<class Scalar>
00061 const std::string BelosLinearOpWithSolveFactory<Scalar>::Outputter_name = "Outputter";
00062 template<class Scalar>
00063 const std::string BelosLinearOpWithSolveFactory<Scalar>::Outputter_OutputFrequency_name = "Output Frequency";
00064 template<class Scalar>
00065 const int         BelosLinearOpWithSolveFactory<Scalar>::Outputter_OutputFrequency_default = 10;
00066 template<class Scalar>
00067 const std::string BelosLinearOpWithSolveFactory<Scalar>::Outputter_OutputMaxResOnly_name = "Output Max Res Only";
00068 template<class Scalar>
00069 const bool        BelosLinearOpWithSolveFactory<Scalar>::Outputter_OutputMaxResOnly_default = true;
00070 
00071 // Constructors/initializers/accessors
00072 
00073 template<class Scalar>
00074 BelosLinearOpWithSolveFactory<Scalar>::BelosLinearOpWithSolveFactory()
00075   :useGmres_(true)
00076 {
00077   updateThisValidParamList();
00078 }
00079 
00080 template<class Scalar>
00081 BelosLinearOpWithSolveFactory<Scalar>::BelosLinearOpWithSolveFactory(
00082   const Teuchos::RefCountPtr<PreconditionerFactoryBase<Scalar> >  &precFactory
00083   )
00084   :useGmres_(true)
00085 {
00086   this->setPreconditionerFactory(precFactory);
00087 }
00088 
00089 // Overridden from LinearOpWithSolveFactoryBase
00090 
00091 template<class Scalar>
00092 bool BelosLinearOpWithSolveFactory<Scalar>::acceptsPreconditionerFactory() const
00093 {
00094   return true;
00095 }
00096 
00097 template<class Scalar>
00098 void BelosLinearOpWithSolveFactory<Scalar>::setPreconditionerFactory(
00099   const Teuchos::RefCountPtr<PreconditionerFactoryBase<Scalar> >  &precFactory
00100   ,const std::string                                              &precFactoryName
00101   )
00102 {
00103   TEST_FOR_EXCEPT(!precFactory.get());
00104   Teuchos::RefCountPtr<const Teuchos::ParameterList>
00105     precFactoryValidPL = precFactory->getValidParameters();
00106   const std::string _precFactoryName =
00107     ( precFactoryName != ""
00108       ? precFactoryName
00109       : ( precFactoryValidPL.get() ? precFactoryValidPL->name() : "GENERIC PRECONDITIONER FACTORY" )
00110       );
00111   precFactory_ = precFactory;
00112   precFactoryName_ = _precFactoryName;
00113   updateThisValidParamList();
00114 }
00115 
00116 template<class Scalar>
00117 Teuchos::RefCountPtr<PreconditionerFactoryBase<Scalar> >
00118 BelosLinearOpWithSolveFactory<Scalar>::getPreconditionerFactory() const
00119 {
00120   return precFactory_;
00121 }
00122 
00123 template<class Scalar>
00124 void BelosLinearOpWithSolveFactory<Scalar>::unsetPreconditionerFactory(
00125   Teuchos::RefCountPtr<PreconditionerFactoryBase<Scalar> >  *precFactory
00126   ,std::string                                              *precFactoryName
00127   )
00128 {
00129   if(precFactory) *precFactory = precFactory_;
00130   if(precFactoryName) *precFactoryName = precFactoryName_;
00131   precFactory_ = Teuchos::null;
00132   precFactoryName_ = "";
00133   updateThisValidParamList();
00134 }
00135 
00136 template<class Scalar>
00137 bool BelosLinearOpWithSolveFactory<Scalar>::isCompatible(
00138   const LinearOpSourceBase<Scalar> &fwdOpSrc
00139   ) const
00140 {
00141   if(precFactory_.get())
00142     return precFactory_->isCompatible(fwdOpSrc);
00143   return true; // Without a preconditioner, we are compatible with all linear operators!
00144 }
00145 
00146 template<class Scalar>
00147 Teuchos::RefCountPtr<LinearOpWithSolveBase<Scalar> >
00148 BelosLinearOpWithSolveFactory<Scalar>::createOp() const
00149 {
00150   return Teuchos::rcp(new BelosLinearOpWithSolve<Scalar>());
00151 }
00152 
00153 template<class Scalar>
00154 void BelosLinearOpWithSolveFactory<Scalar>::initializeOp(
00155   const Teuchos::RefCountPtr<const LinearOpSourceBase<Scalar> >    &fwdOpSrc
00156   ,LinearOpWithSolveBase<Scalar>                                   *Op
00157   ,const ESupportSolveUse                                          supportSolveUse
00158   ) const
00159 {
00160   using Teuchos::null;
00161   initializeOpImpl(fwdOpSrc,null,null,false,Op,supportSolveUse);
00162 }
00163 
00164 template<class Scalar>
00165 void BelosLinearOpWithSolveFactory<Scalar>::initializeAndReuseOp(
00166   const Teuchos::RefCountPtr<const LinearOpSourceBase<Scalar> >    &fwdOpSrc
00167   ,LinearOpWithSolveBase<Scalar>                                   *Op
00168   ) const
00169 {
00170   using Teuchos::null;
00171   initializeOpImpl(fwdOpSrc,null,null,true,Op,SUPPORT_SOLVE_UNSPECIFIED);
00172 }
00173 
00174 template<class Scalar>
00175 bool BelosLinearOpWithSolveFactory<Scalar>::supportsPreconditionerInputType(
00176   const EPreconditionerInputType precOpType
00177   ) const
00178 {
00179   if(precFactory_.get())
00180     return true;
00181   return (precOpType==PRECONDITIONER_INPUT_TYPE_AS_OPERATOR);
00182 }
00183 
00184 template<class Scalar>
00185 void BelosLinearOpWithSolveFactory<Scalar>::initializePreconditionedOp(
00186   const Teuchos::RefCountPtr<const LinearOpSourceBase<Scalar> >       &fwdOpSrc
00187   ,const Teuchos::RefCountPtr<const PreconditionerBase<Scalar> >      &prec
00188   ,LinearOpWithSolveBase<Scalar>                                      *Op
00189   ,const ESupportSolveUse                                             supportSolveUse
00190   ) const
00191 {
00192   using Teuchos::null;
00193   initializeOpImpl(fwdOpSrc,null,prec,false,Op,supportSolveUse);
00194 }
00195 
00196 template<class Scalar>
00197 void BelosLinearOpWithSolveFactory<Scalar>::initializeApproxPreconditionedOp(
00198   const Teuchos::RefCountPtr<const LinearOpSourceBase<Scalar> >      &fwdOpSrc
00199   ,const Teuchos::RefCountPtr<const LinearOpSourceBase<Scalar> >     &approxFwdOpSrc
00200   ,LinearOpWithSolveBase<Scalar>                                      *Op
00201   ,const ESupportSolveUse                                             supportSolveUse
00202   ) const
00203 {
00204   using Teuchos::null;
00205   initializeOpImpl(fwdOpSrc,approxFwdOpSrc,null,false,Op,supportSolveUse);
00206 }
00207 
00208 template<class Scalar>
00209 void BelosLinearOpWithSolveFactory<Scalar>::uninitializeOp(
00210   LinearOpWithSolveBase<Scalar>                               *Op
00211   ,Teuchos::RefCountPtr<const LinearOpSourceBase<Scalar> >    *fwdOpSrc
00212   ,Teuchos::RefCountPtr<const PreconditionerBase<Scalar> >    *prec
00213   ,Teuchos::RefCountPtr<const LinearOpSourceBase<Scalar> >    *approxFwdOpSrc
00214   ,ESupportSolveUse                                           *supportSolveUse
00215   ) const
00216 {
00217 #ifdef TEUCHOS_DEBUG
00218   TEST_FOR_EXCEPT(Op==NULL);
00219 #endif
00220   BelosLinearOpWithSolve<Scalar>
00221     &belosOp = Teuchos::dyn_cast<BelosLinearOpWithSolve<Scalar> >(*Op);
00222   Teuchos::RefCountPtr<const LinearOpSourceBase<Scalar> > 
00223     _fwdOpSrc = belosOp.extract_fwdOpSrc();
00224   Teuchos::RefCountPtr<const PreconditionerBase<Scalar> >
00225     _prec = ( belosOp.isExternalPrec() ? belosOp.extract_prec() : Teuchos::null );
00226   // Note: above we only extract the preconditioner if it was passed in
00227   // externally.  Otherwise, we need to hold on to it so that we can reuse it
00228   // in the next initialization.
00229   Teuchos::RefCountPtr<const LinearOpSourceBase<Scalar> >
00230     _approxFwdOpSrc = belosOp.extract_approxFwdOpSrc();
00231   ESupportSolveUse
00232     _supportSolveUse = belosOp.supportSolveUse();
00233   if(fwdOpSrc) *fwdOpSrc = _fwdOpSrc;
00234   if(prec) *prec = _prec;
00235   if(approxFwdOpSrc) *approxFwdOpSrc = _approxFwdOpSrc;
00236   if(supportSolveUse) *supportSolveUse = _supportSolveUse;
00237 }
00238 
00239 // Overridden from ParameterListAcceptor
00240 
00241 template<class Scalar>
00242 void BelosLinearOpWithSolveFactory<Scalar>::setParameterList(Teuchos::RefCountPtr<Teuchos::ParameterList> const& paramList)
00243 {
00244   TEST_FOR_EXCEPT(paramList.get()==NULL);
00245   paramList->validateParameters(*this->getValidParameters(),1); // Validate 0th and 1st level deep
00246   paramList_ = paramList;
00247   //
00248   if(precFactory_.get())
00249     precFactory_->setParameterList(Teuchos::sublist(paramList_,precFactoryName_));
00250   //
00251   const std::string &solverType = paramList_->get(SolverType_name,SolverType_default);
00252   if(solverType==GMRES_name)
00253     useGmres_ = true;
00254   else if(solverType=="CG")
00255     useGmres_ = false;
00256   else
00257     TEST_FOR_EXCEPTION(
00258       true,std::logic_error
00259       ,"Error, \"Solver Type\" = \"" << solverType << "\" is not recognized!"
00260       "  Valid values are \"GMRES\" and \"CG\""
00261       );
00262   // ToDo: Replace above with Teuchos::StringToIntMap ...
00263 }
00264 
00265 template<class Scalar>
00266 Teuchos::RefCountPtr<Teuchos::ParameterList>
00267 BelosLinearOpWithSolveFactory<Scalar>::getParameterList()
00268 {
00269   return paramList_;
00270 }
00271 
00272 template<class Scalar>
00273 Teuchos::RefCountPtr<Teuchos::ParameterList>
00274 BelosLinearOpWithSolveFactory<Scalar>::unsetParameterList()
00275 {
00276   Teuchos::RefCountPtr<Teuchos::ParameterList> _paramList = paramList_;
00277   paramList_ = Teuchos::null;
00278   return _paramList;
00279 }
00280 
00281 template<class Scalar>
00282 Teuchos::RefCountPtr<const Teuchos::ParameterList>
00283 BelosLinearOpWithSolveFactory<Scalar>::getParameterList() const
00284 {
00285   return paramList_;
00286 }
00287 
00288 template<class Scalar>
00289 Teuchos::RefCountPtr<const Teuchos::ParameterList>
00290 BelosLinearOpWithSolveFactory<Scalar>::getValidParameters() const
00291 {
00292   return thisValidParamList_;
00293 }
00294 
00295 // Public functions overridden from Teuchos::Describable
00296 
00297 template<class Scalar>
00298 std::string BelosLinearOpWithSolveFactory<Scalar>::description() const
00299 {
00300   std::ostringstream oss;
00301   oss << "Thyra::BelosLinearOpWithSolveFactory";
00302   //oss << "{";
00303   // ToDo: Fill this in some!
00304   //oss << "}";
00305   return oss.str();
00306 }
00307 
00308 // private
00309 
00310 template<class Scalar>
00311 Teuchos::RefCountPtr<const Teuchos::ParameterList>
00312 BelosLinearOpWithSolveFactory<Scalar>::generateAndGetValidParameters()
00313 {
00314   static Teuchos::RefCountPtr<Teuchos::ParameterList> validParamList;
00315   if(validParamList.get()==NULL) {
00316     validParamList = Teuchos::rcp(new Teuchos::ParameterList("BelosLinearOpWithSolveFactory"));
00317     validParamList->set(SolverType_name,SolverType_default);
00318     validParamList->set(MaxIters_name,MaxIters_default);
00319     validParamList->set(MaxRestarts_name,MaxRestarts_default);
00320     validParamList->set(BlockSize_name,BlockSize_default);
00321     validParamList->set(AdjustableBlockSize_name,AdjustableBlockSize_default);
00322     validParamList->set(DefaultRelResNorm_name,DefaultRelResNorm_default);
00323     Teuchos::ParameterList
00324       &gmresSL = validParamList->sublist(GMRES_name);
00325     gmresSL.set(GMRES_MaxNumberOfKrylovVectors_name,GMRES_MaxNumberOfKrylovVectors_default);
00326     gmresSL.set(GMRES_Variant_name,GMRES_Variant_default);
00327     Teuchos::ParameterList
00328       &outputterSL = validParamList->sublist(Outputter_name);
00329     outputterSL.set(Outputter_OutputFrequency_name,Outputter_OutputFrequency_default);
00330     outputterSL.set(Outputter_OutputMaxResOnly_name,Outputter_OutputMaxResOnly_default);
00331   }
00332   return validParamList;
00333 }
00334 
00335 template<class Scalar>
00336 void BelosLinearOpWithSolveFactory<Scalar>::updateThisValidParamList()
00337 {
00338   thisValidParamList_ = Teuchos::rcp(
00339     new Teuchos::ParameterList(*generateAndGetValidParameters())
00340     );
00341   if(precFactory_.get()) {
00342     Teuchos::RefCountPtr<const Teuchos::ParameterList>
00343       precFactoryValidParamList = precFactory_->getValidParameters();
00344     if(precFactoryValidParamList.get()) {
00345       thisValidParamList_->sublist(precFactoryName_).setParameters(*precFactoryValidParamList);
00346     }
00347   }
00348 }
00349 
00350 template<class Scalar>
00351 void BelosLinearOpWithSolveFactory<Scalar>::initializeOpImpl(
00352   const Teuchos::RefCountPtr<const LinearOpSourceBase<Scalar> >       &fwdOpSrc
00353   ,const Teuchos::RefCountPtr<const LinearOpSourceBase<Scalar> >      &approxFwdOpSrc
00354   ,const Teuchos::RefCountPtr<const PreconditionerBase<Scalar> >      &prec_in
00355   ,const bool                                                         reusePrec
00356   ,LinearOpWithSolveBase<Scalar>                                      *Op
00357   ,const ESupportSolveUse                                             supportSolveUse
00358   ) const
00359 {
00360 
00361   using Teuchos::RefCountPtr;
00362   using Teuchos::rcp;
00363   using Teuchos::set_extra_data;
00364   typedef Teuchos::ScalarTraits<Scalar> ST;
00365   typedef typename ST::magnitudeType ScalarMag;
00366   typedef MultiVectorBase<Scalar>    MV_t;
00367   typedef LinearOpBase<Scalar>       LO_t;
00368 
00369   const Teuchos::RefCountPtr<Teuchos::FancyOStream> out       = this->getOStream();
00370   const Teuchos::EVerbosityLevel                    verbLevel = this->getVerbLevel();
00371   Teuchos::OSTab tab(out);
00372   if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW))
00373     *out << "\nEntering Thyra::BelosLinearOpWithSolveFactory<"<<ST::name()<<">::initializeOpImpl(...) ...\n";
00374 
00375   typedef Teuchos::VerboseObjectTempState<PreconditionerFactoryBase<Scalar> > VOTSPF;
00376   VOTSPF precFactoryOutputTempState(precFactory_,out,verbLevel);
00377   
00378   TEST_FOR_EXCEPT(Op==NULL);
00379   TEST_FOR_EXCEPT(fwdOpSrc.get()==NULL);
00380   TEST_FOR_EXCEPT(fwdOpSrc->getOp().get()==NULL);
00381   Teuchos::RefCountPtr<const LinearOpBase<Scalar> >
00382     fwdOp = fwdOpSrc->getOp(),
00383     approxFwdOp = ( approxFwdOpSrc.get() ? approxFwdOpSrc->getOp() : Teuchos::null );
00384 
00385   //
00386   // Get the BelosLinearOpWithSolve interface
00387   //
00388   BelosLinearOpWithSolve<Scalar>
00389     *belosOp = &Teuchos::dyn_cast<BelosLinearOpWithSolve<Scalar> >(*Op);
00390   //
00391   // Get/Create the preconditioner
00392   //
00393   RefCountPtr<PreconditionerBase<Scalar> >         myPrec = Teuchos::null;
00394   RefCountPtr<const PreconditionerBase<Scalar> >   prec = Teuchos::null;
00395   if(prec_in.get()) {
00396     // Use an externally defined preconditioner
00397     prec = prec_in;
00398   }
00399   else {
00400     // Try and generate a preconditioner on our own
00401     if(precFactory_.get()) {
00402       myPrec =
00403         ( !belosOp->isExternalPrec()
00404           ? Teuchos::rcp_const_cast<PreconditionerBase<Scalar> >(belosOp->extract_prec())
00405           : Teuchos::null
00406           );
00407       bool hasExistingPrec = false;
00408       if(myPrec.get()) {
00409         hasExistingPrec = true;
00410         // ToDo: Get the forward operator and validate that it is the same
00411         // operator that is used here!
00412       }
00413       else {
00414         hasExistingPrec = false;
00415         myPrec = precFactory_->createPrec();
00416       }
00417       if( hasExistingPrec && reusePrec ) {
00418         // Just reuse the existing preconditioner again!
00419       }
00420       else {
00421         // Update the preconditioner
00422         if(approxFwdOp.get())
00423           precFactory_->initializePrec(approxFwdOpSrc,&*myPrec);
00424         else
00425           precFactory_->initializePrec(fwdOpSrc,&*myPrec);
00426       }
00427       prec = myPrec;
00428     }
00429   }
00430   //
00431   // Create the Belos linear problem
00432   //
00433   typedef Belos::LinearProblem<Scalar,MV_t,LO_t> LP_t;
00434   RefCountPtr<LP_t>
00435     lp = rcp(new LP_t());
00436   //
00437   // Set the operator
00438   //
00439   lp->SetOperator(fwdOp);
00440   //
00441   // Set the preconditioner
00442   //
00443   if(prec.get()) {
00444     RefCountPtr<const LinearOpBase<Scalar> > unspecified = prec->getUnspecifiedPrecOp();
00445     RefCountPtr<const LinearOpBase<Scalar> > left        = prec->getLeftPrecOp();
00446     RefCountPtr<const LinearOpBase<Scalar> > right       = prec->getRightPrecOp();
00447     TEST_FOR_EXCEPTION(
00448       !( left.get() || right.get() || unspecified.get() ), std::logic_error
00449       ,"Error, at least one preconditoner linear operator objects must be set!"
00450       );
00451     if(unspecified.get()) {
00452       lp->SetRightPrec(unspecified);
00453       // ToDo: Allow user to determine whether this should be placed on the
00454       // left or on the right through a parameter in the parameter list!
00455     }
00456     else {
00457       // Set a left, right or split preconditioner
00458       TEST_FOR_EXCEPTION(
00459         left.get(),std::logic_error
00460         ,"Error, we can not currently handle a left preconditioner!"
00461         );
00462       lp->SetRightPrec(right);
00463     }
00464   }
00465   if(myPrec.get()) {
00466     set_extra_data<RefCountPtr<PreconditionerBase<Scalar> > >(myPrec,"Belos::InternalPrec",&lp);
00467   }
00468   else if(prec.get()) {
00469     set_extra_data<RefCountPtr<const PreconditionerBase<Scalar> > >(prec,"Belos::ExternalPrec",&lp);
00470   }
00471   //
00472   // Set the block size
00473   //
00474   int blockSize = BlockSize_default;
00475   if(paramList_.get()) {
00476     blockSize = paramList_->get(BlockSize_name,blockSize);
00477   }
00478   lp->SetBlockSize(blockSize);
00479   //
00480   // Create the output manager 
00481   //
00482   typedef Belos::OutputManager<Scalar> OutputManager_t;
00483   const int belosVerbLevel =
00484     (
00485       verbLevel == Teuchos::VERB_DEFAULT || static_cast<int>(verbLevel)>=static_cast<int>(Teuchos::VERB_LOW)
00486       ? Belos::Warnings | Belos::FinalSummary | Belos::IterationDetails
00487       : Belos::Errors
00488       );
00489   RefCountPtr<OutputManager_t>
00490     outputManager = rcp(new OutputManager_t(0,belosVerbLevel));
00491   // Note: The stream itself will be set in the BelosLinearOpWithSolve object!
00492   //
00493   // Create the default status test
00494   //
00495   int         defaultMaxIterations = MaxIters_default;
00496   int         defaultMaxRestarts   = MaxRestarts_default;
00497   ScalarMag   defaultResNorm       = DefaultRelResNorm_default;
00498   int         outputFrequency      = Outputter_OutputFrequency_default;
00499   bool        outputMaxResOnly     = Outputter_OutputMaxResOnly_default;
00500   if(paramList_.get()) {
00501     defaultMaxIterations = paramList_->get(MaxIters_name,defaultMaxIterations);
00502     defaultMaxRestarts = paramList_->get(MaxRestarts_name,defaultMaxRestarts);
00503     defaultResNorm = paramList_->get(DefaultRelResNorm_name,defaultResNorm);
00504     Teuchos::ParameterList &outputterSL = paramList_->sublist(Outputter_name);
00505     outputFrequency = outputterSL.get(Outputter_OutputFrequency_name,outputFrequency);
00506     outputMaxResOnly = outputterSL.get(Outputter_OutputMaxResOnly_name,outputMaxResOnly);
00507   }
00508   //
00509   typedef Belos::StatusTestResNorm<Scalar,MV_t,LO_t>      StatusTestResNorm_t;
00510   typedef Belos::StatusTestMaxIters<Scalar,MV_t,LO_t>     StatusTestMaxIters_t;
00511   typedef Belos::StatusTestMaxRestarts<Scalar,MV_t,LO_t>  StatusTestMaxRestarts_t;
00512   typedef Belos::StatusTestOutputter<Scalar,MV_t,LO_t>    StatusTestOutputter_t;
00513   typedef Belos::StatusTestCombo<Scalar,MV_t,LO_t>        StatusTestCombo_t;
00514   RefCountPtr<StatusTestMaxIters_t>
00515     maxItersST = rcp(new StatusTestMaxIters_t(defaultMaxIterations));
00516   RefCountPtr<StatusTestMaxRestarts_t>
00517     maxRestartsST = rcp(new StatusTestMaxRestarts_t(defaultMaxRestarts));
00518   RefCountPtr<StatusTestResNorm_t>
00519     resNormST = rcp(new StatusTestResNorm_t(defaultResNorm,outputMaxResOnly));
00520   RefCountPtr<StatusTestOutputter_t>
00521     outputterResNormST = rcp(new StatusTestOutputter_t());
00522   outputterResNormST->outputFrequency(outputFrequency);
00523   outputterResNormST->outputMaxResOnly(outputMaxResOnly);
00524   outputterResNormST->resString("||A*x-b||/||b||");
00525   outputterResNormST->set_resNormStatusTest(resNormST);
00526   outputterResNormST->set_outputManager(outputManager);
00527   RefCountPtr<StatusTestCombo_t>
00528     maxItersOrRestartsST = rcp(new StatusTestCombo_t(StatusTestCombo_t::OR,*maxItersST,*maxRestartsST));
00529   set_extra_data(maxItersST,"maxItersST",&maxItersOrRestartsST);
00530   set_extra_data(maxRestartsST,"maxRestartsST",&maxItersOrRestartsST);
00531   RefCountPtr<StatusTestCombo_t>
00532     comboST = rcp(new StatusTestCombo_t(StatusTestCombo_t::OR,*maxItersOrRestartsST,*outputterResNormST));
00533   set_extra_data(maxItersOrRestartsST,"maxItersOrRestartsST",&comboST);
00534   set_extra_data(outputterResNormST,"resNormST",&comboST);
00535   //
00536   // Generate the solver
00537   //
00538   typedef Belos::IterativeSolver<Scalar,MV_t,LO_t> IterativeSolver_t;
00539   RefCountPtr<IterativeSolver_t> iterativeSolver = Teuchos::null;
00540   RefCountPtr<Teuchos::ParameterList> gmresPL;
00541   int maxNumberOfKrylovVectors = -1; // Only gets used if getPL.get()!=NULL
00542   if(useGmres_) {
00543     // Set the PL
00544     gmresPL = Teuchos::rcp(new Teuchos::ParameterList());
00545     gmresPL->set("Length",1);
00546     // Note, the "Length" will be reset based on the number of RHS in the
00547     // BelosLOWS::solve(...) function!  This is needed to avoid memory
00548     // problems!  Above I just set it to 1 to avoid any memory allocation
00549     // problems!
00550     maxNumberOfKrylovVectors = GMRES_MaxNumberOfKrylovVectors_default;
00551     std::string GMRES_Variant = GMRES_Variant_default;
00552     if(paramList_.get()) {
00553       Teuchos::ParameterList
00554         &_gmresPL = paramList_->sublist(GMRES_name);
00555       maxNumberOfKrylovVectors = _gmresPL.get(GMRES_MaxNumberOfKrylovVectors_name,GMRES_MaxNumberOfKrylovVectors_default);
00556       GMRES_Variant = _gmresPL.get(GMRES_Variant_name,GMRES_Variant_default);
00557     }
00558     gmresPL->set(GMRES_Variant_name,GMRES_Variant);
00559     // Create the solver!
00560     iterativeSolver = rcp(new Belos::BlockGmres<Scalar,MV_t,LO_t>(lp,comboST,outputManager,gmresPL));
00561   }
00562   else {
00563     iterativeSolver = rcp(new Belos::BlockCG<Scalar,MV_t,LO_t>(lp,comboST,outputManager));
00564   }
00565   //
00566   // Initialize the LOWS object
00567   //
00568   const bool adjustableBlockSize =
00569     ( paramList_.get()
00570       ? paramList_->get(AdjustableBlockSize_name,AdjustableBlockSize_default)
00571       : AdjustableBlockSize_default );
00572   belosOp->initialize(
00573     lp,adjustableBlockSize,maxNumberOfKrylovVectors,gmresPL,resNormST,iterativeSolver,outputManager
00574     ,fwdOpSrc,prec,myPrec.get()==NULL,approxFwdOpSrc,supportSolveUse
00575     );
00576   belosOp->setOStream(out);
00577   belosOp->setVerbLevel(verbLevel);
00578 #ifdef TEUCHOS_DEBUG
00579   if(paramList_.get()) {
00580     // Make sure we read the list correctly
00581     paramList_->validateParameters(*this->getValidParameters(),1); // Validate 0th and 1st level deep
00582   }
00583 #endif
00584   if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW))
00585     *out << "\nLeaving Thyra::BelosLinearOpWithSolveFactory<"<<ST::name()<<">::initializeOpImpl(...) ...\n";
00586 
00587 }
00588 
00589 } // namespace Thyra
00590 
00591 #endif // THYRA_BELOS_LINEAR_OP_WITH_SOLVE_FACTORY_HPP
00592 
00593 #endif // __sun

Generated on Thu Sep 18 12:30:22 2008 for Belos Package Browser (Single Doxygen Collection) by doxygen 1.3.9.1