|
Stratimikos Package Browser (Single Doxygen Collection)
Version of the Day
|
00001 /*@Header 00002 // *********************************************************************** 00003 // 00004 // AztecOO: An Object-Oriented Aztec Linear Solver Package 00005 // Copyright (2002) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 //@HEADER 00028 */ 00029 00030 00031 #ifndef SUN_CXX 00032 00033 00034 #include "Thyra_AztecOOLinearOpWithSolveFactory.hpp" 00035 #include "Thyra_AztecOOLinearOpWithSolve.hpp" 00036 #include "Thyra_PreconditionerFactoryHelpers.hpp" 00037 #include "Thyra_EpetraOperatorViewExtractorStd.hpp" 00038 #include "Thyra_ScaledAdjointLinearOpBase.hpp" 00039 #include "Thyra_EpetraLinearOpBase.hpp" 00040 #include "Thyra_EpetraOperatorWrapper.hpp" 00041 #include "EpetraExt_ProductOperator.h" 00042 #include "Teuchos_VerboseObjectParameterListHelpers.hpp" 00043 #include "Teuchos_ParameterList.hpp" 00044 #include "Teuchos_dyn_cast.hpp" 00045 #include "AztecOOParameterList.hpp" 00046 00047 00048 namespace { 00049 00050 00051 const std::string AOOLOWSF_epetraPrecOp_str 00052 = "AOOLOWSF::epetraPrecOp"; 00053 const std::string AOOLOWSF_aztec_epetra_epetraFwdOp_str 00054 = "AOOLOWSF::aztec_epetra_epetraFwdOp"; 00055 const std::string AOOLOWSF_aztec_epetra_epetraAdjOp_str 00056 = "AOOLOWSF::aztec_epetra_epetraAdjOp"; 00057 const std::string AOOLOWSF_rowmatrix_epetraFwdOp_str 00058 = "AOOLOWSF::rowmatrix_epetraFwdOp"; 00059 const std::string AOOLOWSF_rowmatrix_epetraPrecOp_str 00060 = "AOOLOWSF::rowmatrix_epetraPrecOp"; 00061 const std::string AOOLOWSF_aztec_fwd_epetra_epetraPrecOp_str 00062 = "AOOLOWSF::aztec_fwd_epetra_epetraPrecOp"; 00063 const std::string AOOLOWSF_aztec_adj_epetra_epetraPrecOp_str 00064 = "AOOLOWSF::aztec_adj_epetra_epetraPrecOp"; 00065 const std::string AOOLOWSF_setPrecondtionerOperator_str 00066 = "AOOLOWSF::setPrecondtionerOperator"; 00067 const std::string AOOLOWSF_constructedAztecPreconditoner_str 00068 = "AOOLOWSF::constructedAztecPreconditoner"; 00069 00070 00071 const std::string ForwardSolve_name = "Forward Solve"; 00072 const std::string AdjointSolve_name = "Adjoint Solve"; 00073 const std::string MaxIterations_name = "Max Iterations"; 00074 const int MaxIterations_default = 400; 00075 const std::string Tolerance_name = "Tolerance"; 00076 const double Tolerance_default = 1e-6; 00077 const std::string OutputEveryRhs_name = "Output Every RHS"; 00078 const bool OutputEveryRhs_default = false; 00079 const std::string AztecOO_Settings_name = "AztecOO Settings"; 00080 00081 00082 } // namespace 00083 00084 00085 namespace Thyra { 00086 00087 00088 // Constructors/initializers/accessors 00089 00090 00091 AztecOOLinearOpWithSolveFactory::AztecOOLinearOpWithSolveFactory( 00092 Teuchos::RCP<Teuchos::ParameterList> const& paramList 00093 ) 00094 :epetraFwdOpViewExtractor_(Teuchos::rcp(new EpetraOperatorViewExtractorStd())) 00095 ,defaultFwdMaxIterations_(MaxIterations_default) 00096 ,defaultFwdTolerance_(Tolerance_default) 00097 ,defaultAdjMaxIterations_(MaxIterations_default) 00098 ,defaultAdjTolerance_(Tolerance_default) 00099 ,outputEveryRhs_(OutputEveryRhs_default) 00100 { 00101 updateThisValidParamList(); 00102 if(paramList.get()) 00103 setParameterList(paramList); 00104 } 00105 00106 00107 // Overridden from LinearOpWithSolveFactoryBase 00108 00109 00110 bool AztecOOLinearOpWithSolveFactory::acceptsPreconditionerFactory() const 00111 { 00112 return true; 00113 } 00114 00115 00116 void AztecOOLinearOpWithSolveFactory::setPreconditionerFactory( 00117 const Teuchos::RCP<PreconditionerFactoryBase<double> > &precFactory, 00118 const std::string &precFactoryName 00119 ) 00120 { 00121 TEUCHOS_TEST_FOR_EXCEPT(!precFactory.get()); 00122 Teuchos::RCP<const Teuchos::ParameterList> 00123 precFactoryValidPL = precFactory->getValidParameters(); 00124 const std::string _precFactoryName = 00125 ( precFactoryName != "" 00126 ? precFactoryName 00127 : ( precFactoryValidPL.get() 00128 ? precFactoryValidPL->name() 00129 : "GENERIC PRECONDITIONER FACTORY" 00130 ) 00131 ); 00132 precFactory_ = precFactory; 00133 precFactoryName_ = _precFactoryName; 00134 updateThisValidParamList(); 00135 } 00136 00137 00138 Teuchos::RCP<PreconditionerFactoryBase<double> > 00139 AztecOOLinearOpWithSolveFactory::getPreconditionerFactory() const 00140 { 00141 return precFactory_; 00142 } 00143 00144 00145 void AztecOOLinearOpWithSolveFactory::unsetPreconditionerFactory( 00146 Teuchos::RCP<PreconditionerFactoryBase<double> > *precFactory, 00147 std::string *precFactoryName 00148 ) 00149 { 00150 if(precFactory) *precFactory = precFactory_; 00151 if(precFactoryName) *precFactoryName = precFactoryName_; 00152 precFactory_ = Teuchos::null; 00153 precFactoryName_ = ""; 00154 updateThisValidParamList(); 00155 } 00156 00157 00158 bool AztecOOLinearOpWithSolveFactory::isCompatible( 00159 const LinearOpSourceBase<double> &fwdOpSrc 00160 ) const 00161 { 00162 return epetraFwdOpViewExtractor_->isCompatible(*fwdOpSrc.getOp()); 00163 } 00164 00165 00166 Teuchos::RCP<LinearOpWithSolveBase<double> > 00167 AztecOOLinearOpWithSolveFactory::createOp() const 00168 { 00169 return Teuchos::rcp(new AztecOOLinearOpWithSolve()); 00170 } 00171 00172 00173 void AztecOOLinearOpWithSolveFactory::initializeOp( 00174 const Teuchos::RCP<const LinearOpSourceBase<double> > &fwdOpSrc, 00175 LinearOpWithSolveBase<double> *Op, 00176 const ESupportSolveUse supportSolveUse 00177 ) const 00178 { 00179 this->initializeOp_impl(fwdOpSrc,Teuchos::null,Teuchos::null,false,Op); 00180 } 00181 00182 00183 void AztecOOLinearOpWithSolveFactory::initializeAndReuseOp( 00184 const Teuchos::RCP<const LinearOpSourceBase<double> > &fwdOpSrc, 00185 LinearOpWithSolveBase<double> *Op 00186 ) const 00187 { 00188 this->initializeOp_impl(fwdOpSrc,Teuchos::null,Teuchos::null,true,Op); 00189 } 00190 00191 00192 bool AztecOOLinearOpWithSolveFactory::supportsPreconditionerInputType( 00193 const EPreconditionerInputType precOpType 00194 ) const 00195 { 00196 const_cast<bool&>(useAztecPrec_) = ( 00197 paramList_.get() 00198 && 00199 paramList_->sublist(ForwardSolve_name).sublist(AztecOO_Settings_name).get( 00200 "Aztec Preconditioner","none" 00201 )!="none" 00202 ); 00203 switch(precOpType) { 00204 case PRECONDITIONER_INPUT_TYPE_AS_OPERATOR: 00205 return true; 00206 break; 00207 case PRECONDITIONER_INPUT_TYPE_AS_MATRIX: 00208 return useAztecPrec_; 00209 break; 00210 default: 00211 TEUCHOS_TEST_FOR_EXCEPT(true); 00212 } 00213 return PRECONDITIONER_INPUT_TYPE_AS_OPERATOR; // Should never be called! 00214 } 00215 00216 00217 void AztecOOLinearOpWithSolveFactory::initializePreconditionedOp( 00218 const Teuchos::RCP<const LinearOpSourceBase<double> > &fwdOpSrc, 00219 const Teuchos::RCP<const PreconditionerBase<double> > &prec, 00220 LinearOpWithSolveBase<double> *Op, 00221 const ESupportSolveUse supportSolveUse 00222 ) const 00223 { 00224 TEUCHOS_TEST_FOR_EXCEPT(prec.get()==NULL); 00225 this->initializeOp_impl(fwdOpSrc,prec,Teuchos::null,false,Op); 00226 } 00227 00228 00229 void AztecOOLinearOpWithSolveFactory::initializeApproxPreconditionedOp( 00230 const Teuchos::RCP<const LinearOpSourceBase<double> > &fwdOpSrc, 00231 const Teuchos::RCP<const LinearOpSourceBase<double> > &approxFwdOpSrc, 00232 LinearOpWithSolveBase<double> *Op, 00233 const ESupportSolveUse supportSolveUse 00234 ) const 00235 { 00236 TEUCHOS_TEST_FOR_EXCEPT(approxFwdOpSrc.get()==NULL); 00237 TEUCHOS_TEST_FOR_EXCEPT(approxFwdOpSrc->getOp().get()==NULL); 00238 this->initializeOp_impl(fwdOpSrc,Teuchos::null,approxFwdOpSrc,false,Op); 00239 } 00240 00241 00242 void AztecOOLinearOpWithSolveFactory::uninitializeOp( 00243 LinearOpWithSolveBase<double> *Op, 00244 Teuchos::RCP<const LinearOpSourceBase<double> > *fwdOpSrc, 00245 Teuchos::RCP<const PreconditionerBase<double> > *prec, 00246 Teuchos::RCP<const LinearOpSourceBase<double> > *approxFwdOpSrc, 00247 ESupportSolveUse *supportSolveUse 00248 ) const 00249 { 00250 #ifdef TEUCHOS_DEBUG 00251 TEUCHOS_TEST_FOR_EXCEPT(Op==NULL); 00252 #endif 00253 AztecOOLinearOpWithSolve 00254 *aztecOp = &Teuchos::dyn_cast<AztecOOLinearOpWithSolve>(*Op); 00255 // Extract and unset the fwdOP and approxFwdOp objects 00256 Teuchos::RCP<const LinearOpSourceBase<double> > 00257 _fwdOpSrc = aztecOp->extract_fwdOpSrc(), // Will be null if not initialized! 00258 _approxFwdOpSrc = aztecOp->extract_approxFwdOpSrc(); // Will be null if not set 00259 if(fwdOpSrc) *fwdOpSrc = _fwdOpSrc; 00260 if(approxFwdOpSrc) *approxFwdOpSrc = _approxFwdOpSrc; 00261 // Only extract and uset the prec object if it is external. If it is 00262 // internal, then we need to hold on to this so that we can reinitialize it 00263 // later. 00264 if(aztecOp->isExternalPrec()) { 00265 Teuchos::RCP<const PreconditionerBase<double> > 00266 _prec = aztecOp->extract_prec(); // Will be null if not external preconditioner was set 00267 if(prec) *prec = _prec; 00268 } 00269 // ToDo: Extract the Epetra_Operator views what where used to initialize the 00270 // forward and adjoint solvers! This is needed to make this totally 00271 // stateless. 00272 } 00273 00274 00275 // Overridden from ParameterListAcceptor 00276 00277 00278 void AztecOOLinearOpWithSolveFactory::setParameterList( 00279 Teuchos::RCP<Teuchos::ParameterList> const& paramList 00280 ) 00281 { 00282 TEUCHOS_TEST_FOR_EXCEPT(paramList.get()==NULL); 00283 paramList->validateParameters(*this->getValidParameters()); 00284 paramList_ = paramList; 00285 // 00286 outputEveryRhs_ = paramList_->get(OutputEveryRhs_name,OutputEveryRhs_default); 00287 // Foward Solve parameters 00288 Teuchos::ParameterList 00289 &fwdSolvePL = paramList_->sublist(ForwardSolve_name); 00290 defaultFwdMaxIterations_ = fwdSolvePL.get(MaxIterations_name,defaultFwdMaxIterations_); 00291 defaultFwdTolerance_ = fwdSolvePL.get(Tolerance_name,defaultFwdTolerance_); 00292 // Adjoint Solve parameters 00293 if( !paramList_->getPtr<Teuchos::ParameterList>(AdjointSolve_name) ) { 00294 // If adjoint solve sublist is not set, then use the forward solve parameters 00295 paramList_->sublist(AdjointSolve_name).setParameters(fwdSolvePL); 00296 } 00297 Teuchos::ParameterList 00298 &adjSolvePL = paramList_->sublist(AdjointSolve_name); 00299 defaultAdjMaxIterations_ = adjSolvePL.get(MaxIterations_name,defaultAdjMaxIterations_); 00300 defaultAdjTolerance_ = adjSolvePL.get(Tolerance_name,defaultAdjTolerance_); 00301 // 00302 if(precFactory_.get()) { 00303 // Only reset the PF's PL if the sublist exists or the PF does not already 00304 // have a PL. We don't want to overwrite an externally set PL for the PF 00305 // if we don't have a nested sublist defined here! 00306 const bool nestedPFSublistExists = paramList_->isSublist(precFactoryName_); 00307 const bool alreadyHasSublist = !is_null(precFactory_->getParameterList()); 00308 if( nestedPFSublistExists || !alreadyHasSublist ) { 00309 precFactory_->setParameterList(Teuchos::sublist(paramList_,precFactoryName_)); 00310 } 00311 } 00312 Teuchos::readVerboseObjectSublist(&*paramList_,this); 00313 } 00314 00315 00316 Teuchos::RCP<Teuchos::ParameterList> 00317 AztecOOLinearOpWithSolveFactory::getNonconstParameterList() 00318 { 00319 return paramList_; 00320 } 00321 00322 00323 Teuchos::RCP<Teuchos::ParameterList> 00324 AztecOOLinearOpWithSolveFactory::unsetParameterList() 00325 { 00326 Teuchos::RCP<Teuchos::ParameterList> _paramList = paramList_; 00327 paramList_ = Teuchos::null; 00328 return _paramList; 00329 } 00330 00331 00332 Teuchos::RCP<const Teuchos::ParameterList> 00333 AztecOOLinearOpWithSolveFactory::getParameterList() const 00334 { 00335 return paramList_; 00336 } 00337 00338 00339 Teuchos::RCP<const Teuchos::ParameterList> 00340 AztecOOLinearOpWithSolveFactory::getValidParameters() const 00341 { 00342 return thisValidParamList_; 00343 } 00344 00345 00346 // Public functions overridden from Teuchos::Describable 00347 00348 00349 std::string AztecOOLinearOpWithSolveFactory::description() const 00350 { 00351 std::ostringstream oss; 00352 oss << "Thyra::AztecOOLinearOpWithSolveFactory{"; 00353 oss << "precFactory="; 00354 if(!is_null(precFactory_)) 00355 oss << precFactory_->description(); 00356 else 00357 oss << "NULL"; 00358 oss << "}"; 00359 return oss.str(); 00360 } 00361 00362 00363 // private 00364 00365 00366 Teuchos::RCP<const Teuchos::ParameterList> 00367 AztecOOLinearOpWithSolveFactory::generateAndGetValidParameters() 00368 { 00369 static Teuchos::RCP<Teuchos::ParameterList> validParamList; 00370 if(validParamList.get()==NULL) { 00371 validParamList = Teuchos::rcp( 00372 new Teuchos::ParameterList("AztecOOLinearOpWithSolveFactory")); 00373 validParamList->set( 00374 OutputEveryRhs_name,OutputEveryRhs_default 00375 ,"Determines if output is created for each individual RHS (true or 1) or if output\n" 00376 "is just created for an entire set of RHSs (false or 0)." 00377 ); 00378 static Teuchos::RCP<const Teuchos::ParameterList> 00379 aztecParamList = getValidAztecOOParameters(); 00380 Teuchos::ParameterList 00381 &fwdSolvePL = validParamList->sublist( 00382 ForwardSolve_name, false 00383 ,"Gives the options for the forward solve." 00384 ); 00385 fwdSolvePL.set( 00386 Tolerance_name,Tolerance_default 00387 ,"The tolerence used in the convergence check (see the convergence test\n" 00388 "in the sublist \"" + AztecOO_Settings_name + "\")" 00389 ); 00390 fwdSolvePL.set( 00391 MaxIterations_name,MaxIterations_default 00392 ,"The maximum number of iterations the AztecOO solver is allowed to perform." 00393 ); 00394 fwdSolvePL.sublist( 00395 AztecOO_Settings_name,false 00396 ,"Sets the parameters on the AztecOO object itself." 00397 ).setParameters(*aztecParamList); 00398 Teuchos::ParameterList 00399 &adjSolvePL = validParamList->sublist( 00400 AdjointSolve_name, false 00401 ,"The options for the adjoint solve.\n" 00402 "If this sublist is missing then the parameters from the\n" 00403 "\""+ForwardSolve_name+"\" sublist are used instead." 00404 ); 00405 // Make the adjoint solve have same defaults as forward solve 00406 adjSolvePL.setParameters(fwdSolvePL); 00407 } 00408 return validParamList; 00409 } 00410 00411 00412 void AztecOOLinearOpWithSolveFactory::updateThisValidParamList() 00413 { 00414 thisValidParamList_ = Teuchos::rcp( 00415 new Teuchos::ParameterList(*generateAndGetValidParameters()) 00416 ); 00417 if(precFactory_.get()) { 00418 Teuchos::RCP<const Teuchos::ParameterList> 00419 precFactoryValidParamList = precFactory_->getValidParameters(); 00420 if(precFactoryValidParamList.get()) { 00421 thisValidParamList_->sublist(precFactoryName_).setParameters( 00422 *precFactoryValidParamList); 00423 } 00424 } 00425 Teuchos::setupVerboseObjectSublist(&*thisValidParamList_); 00426 } 00427 00428 00429 void AztecOOLinearOpWithSolveFactory::initializeOp_impl( 00430 const Teuchos::RCP<const LinearOpSourceBase<double> > &fwdOpSrc, 00431 const Teuchos::RCP<const PreconditionerBase<double> > &prec, 00432 const Teuchos::RCP<const LinearOpSourceBase<double> > &approxFwdOpSrc, 00433 const bool reusePrec, 00434 LinearOpWithSolveBase<double> *Op 00435 ) const 00436 { 00437 using Teuchos::RCP; 00438 using Teuchos::null; 00439 using Teuchos::rcp; 00440 using Teuchos::rcp_dynamic_cast; 00441 using Teuchos::rcp_const_cast; 00442 using Teuchos::set_extra_data; 00443 using Teuchos::get_optional_extra_data; 00444 using Teuchos::get_optional_nonconst_extra_data; 00445 using Teuchos::outArg; 00446 typedef EpetraExt::ProductOperator PO; 00447 00448 const Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream(); 00449 const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); 00450 Teuchos::OSTab tab(out); 00451 if(out.get() && static_cast<int>(verbLevel) > static_cast<int>(Teuchos::VERB_LOW)) 00452 *out << "\nEntering Thyra::AztecOOLinearOpWithSolveFactory::initializeOp_impl(...) ...\n"; 00453 00454 typedef Teuchos::VerboseObjectTempState<PreconditionerFactoryBase<double> > VOTSPF; 00455 VOTSPF precFactoryOutputTempState(precFactory_,out,verbLevel); 00456 00457 #ifdef TEUCHOS_DEBUG 00458 TEUCHOS_TEST_FOR_EXCEPT(Op==NULL); 00459 TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc.get()==NULL); 00460 TEUCHOS_TEST_FOR_EXCEPT(fwdOpSrc->getOp().get()==NULL); 00461 #endif 00462 00463 // 00464 // Determine whether the operators are EpetraLinearOp objects. If so, we're 00465 // good to go. If not, we need to wrap it as an Epetra_Operator with some 00466 // invasive code. 00467 // 00468 Teuchos::RCP<const LinearOpBase<double> > 00469 tmpFwdOp = fwdOpSrc->getOp(), 00470 tmpApproxFwdOp = ( approxFwdOpSrc.get() ? approxFwdOpSrc->getOp() : Teuchos::null ); 00471 Teuchos::RCP<const LinearOpBase<double> > fwdOp; 00472 Teuchos::RCP<const LinearOpBase<double> > approxFwdOp; 00473 if ( dynamic_cast<const EpetraLinearOpBase*>(tmpFwdOp.get())!=0 ) 00474 { 00475 fwdOp = tmpFwdOp; 00476 approxFwdOp = tmpApproxFwdOp; 00477 } 00478 else 00479 { 00480 fwdOp = makeEpetraWrapper(tmpFwdOp); 00481 if ( 00482 tmpApproxFwdOp.get() 00483 && 00484 dynamic_cast<const EpetraLinearOpBase*>(&*tmpApproxFwdOp.get()) 00485 ) 00486 { 00487 approxFwdOp = makeEpetraWrapper(tmpApproxFwdOp); 00488 } 00489 } 00490 00491 // 00492 // Get the AztecOOLinearOpWithSolve object 00493 // 00494 AztecOOLinearOpWithSolve 00495 *aztecOp = &Teuchos::dyn_cast<AztecOOLinearOpWithSolve>(*Op); 00496 00497 // 00498 // Unwrap and get the forward operator or matrix 00499 // 00500 Teuchos::RCP<const Epetra_Operator> epetra_epetraFwdOp; 00501 EOpTransp epetra_epetraFwdOpTransp; 00502 EApplyEpetraOpAs epetra_epetraFwdOpApplyAs; 00503 EAdjointEpetraOp epetra_epetraFwdOpAdjointSupport; 00504 double epetra_epetraFwdOpScalar; 00505 epetraFwdOpViewExtractor_->getEpetraOpView( 00506 fwdOp, 00507 outArg(epetra_epetraFwdOp), outArg(epetra_epetraFwdOpTransp), 00508 outArg(epetra_epetraFwdOpApplyAs), outArg(epetra_epetraFwdOpAdjointSupport), 00509 outArg(epetra_epetraFwdOpScalar) 00510 ); 00511 TEUCHOS_TEST_FOR_EXCEPTION( 00512 epetra_epetraFwdOp.get()==NULL, std::logic_error 00513 ,"Error, The input fwdOp object must be fully initialized " 00514 "before calling this function!" 00515 ); 00516 00517 // 00518 // Get the preconditioner object to use 00519 // 00520 Teuchos::RCP<PreconditionerBase<double> > myPrec; 00521 Teuchos::RCP<const PreconditionerBase<double> > precUsed; 00522 if (prec.get()) { 00523 // We will be used the passed in external preconditioner 00524 precUsed = prec; 00525 } 00526 else if (precFactory_.get() ) { 00527 // We will be creating our own preconditioner using an externally set 00528 // preconditioner factory 00529 myPrec = 00530 ( !aztecOp->isExternalPrec() 00531 ? Teuchos::rcp_const_cast<PreconditionerBase<double> >( 00532 aztecOp->extract_prec()) 00533 : Teuchos::null 00534 ); 00535 if(myPrec.get()) { 00536 // ToDo: Get the forward operator and validate that it is the same 00537 // operator that is used here! 00538 } 00539 else { 00540 myPrec = precFactory_->createPrec(); 00541 } 00542 precFactory_->initializePrec(fwdOpSrc,&*myPrec); 00543 precUsed = myPrec; 00544 } 00545 00546 // 00547 // Unwrap and get the preconditioner operator 00548 // 00549 RCP<const LinearOpBase<double> > rightPrecOp; 00550 if (precUsed.get()) { 00551 RCP<const LinearOpBase<double> > unspecified = precUsed->getUnspecifiedPrecOp(); 00552 RCP<const LinearOpBase<double> > left = precUsed->getLeftPrecOp(); 00553 RCP<const LinearOpBase<double> > right = precUsed->getRightPrecOp(); 00554 TEUCHOS_TEST_FOR_EXCEPTION( 00555 !( left.get() || right.get() || unspecified.get() ), std::logic_error 00556 ,"Error, at least one preconditoner linear operator objects must be set!" 00557 ); 00558 if(unspecified.get()) { 00559 rightPrecOp = unspecified; 00560 } 00561 else { 00562 // Set a left, right or split preconditioner 00563 TEUCHOS_TEST_FOR_EXCEPTION( 00564 left.get(),std::logic_error 00565 ,"Error, we can not currently handle a left" 00566 " preconditioner with the AztecOO/Thyra adapters!" 00567 ); 00568 rightPrecOp = right; 00569 } 00570 } 00571 double wrappedPrecOpScalar = 0.0; 00572 EOpTransp wrappedPrecOpTransp = NOTRANS; 00573 RCP<const LinearOpBase<double> > wrappedPrecOp = null; 00574 RCP<const EpetraLinearOpBase> epetraPrecOp; 00575 Teuchos::RCP<const Epetra_Operator> epetra_epetraPrecOp; 00576 EOpTransp epetra_epetraPrecOpTransp; 00577 EApplyEpetraOpAs epetra_epetraPrecOpApplyAs; 00578 EAdjointEpetraOp epetra_epetraPrecOpAdjointSupport; 00579 EOpTransp overall_epetra_epetraPrecOpTransp; 00580 if(rightPrecOp.get()) { 00581 RCP<const LinearOpBase<double> > tmpWrappedPrecOp; 00582 unwrap( 00583 rightPrecOp,&wrappedPrecOpScalar,&wrappedPrecOpTransp,&tmpWrappedPrecOp); 00584 if( dynamic_cast<const EpetraLinearOpBase*>(&*tmpWrappedPrecOp) ) { 00585 wrappedPrecOp = tmpWrappedPrecOp; 00586 } 00587 else { 00588 wrappedPrecOp = makeEpetraWrapper(tmpWrappedPrecOp); 00589 } 00590 epetraPrecOp = rcp_dynamic_cast<const EpetraLinearOpBase>( 00591 wrappedPrecOp,true); 00592 epetraPrecOp->getEpetraOpView( 00593 outArg(epetra_epetraPrecOp), outArg(epetra_epetraPrecOpTransp), 00594 outArg(epetra_epetraPrecOpApplyAs), outArg(epetra_epetraPrecOpAdjointSupport)); 00595 TEUCHOS_TEST_FOR_EXCEPTION( 00596 epetra_epetraPrecOp.get()==NULL,std::logic_error 00597 ,"Error, The input prec object and its embedded preconditioner" 00598 " operator must be fully initialized before calling this function!" 00599 ); 00600 // 2007/08/10: rabartl: This next set_extra_data(...) call is likely to be 00601 // setting up a circular reference! Since epetra_epetraPrecOp was 00602 // gotten from epetraPrecOp, if you set epetraPrecOp as extra data 00603 // on the RCP epetra_epetraPrecOp then you have a circular reference! 00604 //set_extra_data( 00605 // epetraPrecOp, AOOLOWSF_epetraPrecOp_str, &epetra_epetraPrecOp, 00606 // Teuchos::POST_DESTROY, false ); 00607 overall_epetra_epetraPrecOpTransp 00608 = trans_trans( 00609 real_trans(wrappedPrecOpTransp), 00610 real_trans(epetra_epetraPrecOpTransp) 00611 ); 00612 } 00613 00614 // 00615 // Unwrap and get the approximate forward operator to be used to generate a 00616 // preconditioner 00617 // 00618 if(approxFwdOp.get()) { 00619 // Note, here we just use the same members data that would be set for an 00620 // extenral preconditioner operator since it is not getting used. 00621 unwrap(approxFwdOp,&wrappedPrecOpScalar,&wrappedPrecOpTransp,&wrappedPrecOp); 00622 epetraPrecOp = rcp_dynamic_cast<const EpetraLinearOpBase>( 00623 wrappedPrecOp,true); 00624 epetraPrecOp->getEpetraOpView( 00625 outArg(epetra_epetraPrecOp), outArg(epetra_epetraPrecOpTransp), 00626 outArg(epetra_epetraPrecOpApplyAs), outArg(epetra_epetraPrecOpAdjointSupport) 00627 ); 00628 TEUCHOS_TEST_FOR_EXCEPTION( 00629 epetra_epetraPrecOp.get()==NULL,std::logic_error 00630 ,"Error, The input approxFwdOp object must be fully initialized" 00631 " before calling this function!" 00632 ); 00633 // 2007/08/10: rabartl: This next set_extra_data(...) call is likely to be 00634 // setting up a circular reference! Since epetra_epetraPrecOp was 00635 // gotten from epetraPrecOp, if you set epetraPrecOp as extra data 00636 // on the RCP epetra_epetraPrecOp then you have a circular reference! 00637 //set_extra_data( 00638 // epetraPrecOp, AOOLOWSF_epetraPrecOp_str, &epetra_epetraPrecOp, 00639 // Teuchos::POST_DESTROY, false 00640 // ); 00641 overall_epetra_epetraPrecOpTransp 00642 = trans_trans( 00643 real_trans(wrappedPrecOpTransp), 00644 real_trans(epetra_epetraPrecOpTransp) 00645 ); 00646 } 00647 00648 // 00649 // Determine if the forward and preconditioner operators are a row matrices 00650 // or not 00651 // 00652 RCP<const Epetra_RowMatrix> 00653 rowmatrix_epetraFwdOp = rcp_dynamic_cast<const Epetra_RowMatrix>( 00654 epetra_epetraFwdOp), 00655 rowmatrix_epetraPrecOp = rcp_dynamic_cast<const Epetra_RowMatrix>( 00656 epetra_epetraPrecOp); 00657 // 00658 // Determine the type of preconditoner 00659 // 00660 // Update useAztecPrec_, input value does not matter 00661 this->supportsPreconditionerInputType(PRECONDITIONER_INPUT_TYPE_AS_MATRIX); 00662 enum ELocalPrecType { 00663 PT_NONE, PT_AZTEC_FROM_OP, PT_AZTEC_FROM_APPROX_FWD_MATRIX, 00664 PT_FROM_PREC_OP 00665 }; 00666 ELocalPrecType localPrecType; 00667 if( precUsed.get()==NULL && approxFwdOp.get()==NULL && !useAztecPrec_ ) { 00668 // No preconditioning at all! 00669 localPrecType = PT_NONE; 00670 } 00671 else if( precUsed.get()==NULL && approxFwdOp.get()==NULL && useAztecPrec_ ) { 00672 // We are using the forward matrix for the preconditioner using aztec 00673 // preconditioners 00674 localPrecType = PT_AZTEC_FROM_OP; 00675 } 00676 else if( approxFwdOp.get() && useAztecPrec_ ) { 00677 // The preconditioner comes from the input as a matrix and we are using 00678 // aztec preconditioners 00679 localPrecType = PT_AZTEC_FROM_APPROX_FWD_MATRIX; 00680 } 00681 else if( precUsed.get() ) { 00682 // The preconditioner comes as an external operator so let's use it as 00683 // such 00684 localPrecType = PT_FROM_PREC_OP; 00685 } 00686 00687 // 00688 // Determine if aztecOp already contains solvers and if we need to 00689 // reinitialize or not 00690 // 00691 RCP<AztecOO> aztecFwdSolver, aztecAdjSolver; 00692 bool startingOver; 00693 { 00694 // Let's assume that fwdOp, prec and/or approxFwdOp are compatible with 00695 // the already created AztecOO objects. If they are not, then the client 00696 // should have created a new LOWSB object from scratch! 00697 Teuchos::RCP<const LinearOpBase<double> > old_fwdOp; 00698 Teuchos::RCP<const LinearOpSourceBase<double> > old_fwdOpSrc; 00699 Teuchos::RCP<const PreconditionerBase<double> > old_prec; 00700 bool old_isExternalPrec; 00701 Teuchos::RCP<const LinearOpSourceBase<double> > old_approxFwdOpSrc; 00702 Teuchos::RCP<AztecOO> old_aztecFwdSolver; 00703 Teuchos::RCP<AztecOO> old_aztecAdjSolver; 00704 double old_aztecSolverScalar; 00705 aztecOp->uninitialize( 00706 &old_fwdOp 00707 ,&old_fwdOpSrc 00708 ,&old_prec 00709 ,&old_isExternalPrec 00710 ,&old_approxFwdOpSrc 00711 ,&old_aztecFwdSolver 00712 ,NULL 00713 ,&old_aztecAdjSolver 00714 ,NULL 00715 ,&old_aztecSolverScalar 00716 ); 00717 if( old_aztecFwdSolver.get()==NULL ) { 00718 // This has never been initialized before 00719 startingOver = true; 00720 } 00721 else { 00722 // Let's assume that fwdOp, prec and/or approxFwdOp are compatible with 00723 // the already created AztecOO objects. If they are not, then the 00724 // client should have created a new LOWSB object from scratch! 00725 aztecFwdSolver = old_aztecFwdSolver; 00726 aztecAdjSolver = old_aztecAdjSolver; 00727 startingOver = false; 00728 // We must wipe out the old preconditoner if we are not reusing the 00729 // preconditioner 00730 Ptr<bool> constructedAztecPreconditioner; 00731 if( 00732 !reusePrec 00733 && 00734 !is_null(constructedAztecPreconditioner = get_optional_nonconst_extra_data<bool>( 00735 aztecFwdSolver, "AOOLOWSF::constructedAztecPreconditoner") ) 00736 && 00737 *constructedAztecPreconditioner 00738 ) 00739 { 00740 aztecFwdSolver->DestroyPreconditioner(); 00741 *constructedAztecPreconditioner = false; 00742 } 00743 // We must see if we set an external preconditioner but will not do so 00744 // again in which case we must blow away AztecOO and start over again! 00745 Ptr<bool> setPreconditionerOperator; 00746 if( 00747 localPrecType != PT_FROM_PREC_OP 00748 && !is_null( setPreconditionerOperator = get_optional_nonconst_extra_data<bool>( 00749 aztecFwdSolver,"AOOLOWSF::setPreconditonerOperator") ) 00750 && *setPreconditionerOperator 00751 ) 00752 { 00753 // We must start over again since there is no way to unset an external 00754 // preconditioner! 00755 startingOver = true; 00756 } 00757 } 00758 } 00759 00760 // 00761 // Create the AztecOO solvers if we are starting over 00762 // 00763 startingOver = true; // ToDo: Remove this and figure out why this is not working! 00764 if(startingOver) { 00765 // Forward solver 00766 aztecFwdSolver = rcp(new AztecOO()); 00767 aztecFwdSolver->SetAztecOption(AZ_diagnostics,AZ_none); // This was turned off in NOX? 00768 aztecFwdSolver->SetAztecOption(AZ_keep_info,1); 00769 // Adjoint solver (if supported) 00770 if( 00771 epetra_epetraFwdOpAdjointSupport==EPETRA_OP_ADJOINT_SUPPORTED 00772 && 00773 localPrecType!=PT_AZTEC_FROM_OP && localPrecType!=PT_AZTEC_FROM_APPROX_FWD_MATRIX 00774 ) 00775 { 00776 aztecAdjSolver = rcp(new AztecOO()); 00777 aztecAdjSolver->SetAztecOption(AZ_diagnostics,AZ_none); 00778 //aztecAdjSolver->SetAztecOption(AZ_keep_info,1); 00779 } 00780 } 00781 00782 // 00783 // Set the options on the AztecOO solvers 00784 // 00785 if( startingOver ) { 00786 if(paramList_.get()) 00787 setAztecOOParameters( 00788 ¶mList_->sublist(ForwardSolve_name).sublist(AztecOO_Settings_name), 00789 &*aztecFwdSolver 00790 ); 00791 if(aztecAdjSolver.get() && paramList_.get()) 00792 setAztecOOParameters( 00793 ¶mList_->sublist(AdjointSolve_name).sublist(AztecOO_Settings_name), 00794 &*aztecAdjSolver 00795 ); 00796 } 00797 00798 // 00799 // Process the forward operator 00800 // 00801 RCP<const Epetra_Operator> 00802 aztec_epetra_epetraFwdOp, 00803 aztec_epetra_epetraAdjOp; 00804 // Forward solve 00805 RCP<const Epetra_Operator> 00806 epetraOps[] 00807 = { epetra_epetraFwdOp }; 00808 Teuchos::ETransp 00809 epetraOpsTransp[] 00810 = { epetra_epetraFwdOpTransp==NOTRANS ? Teuchos::NO_TRANS : Teuchos::TRANS }; 00811 PO::EApplyMode 00812 epetraOpsApplyMode[] 00813 = { epetra_epetraFwdOpApplyAs==EPETRA_OP_APPLY_APPLY 00814 ? PO::APPLY_MODE_APPLY 00815 : PO::APPLY_MODE_APPLY_INVERSE }; 00816 if( 00817 epetraOpsTransp[0] == Teuchos::NO_TRANS 00818 && 00819 epetraOpsApplyMode[0] == PO::APPLY_MODE_APPLY 00820 ) 00821 { 00822 aztec_epetra_epetraFwdOp = epetra_epetraFwdOp; 00823 } 00824 else 00825 { 00826 aztec_epetra_epetraFwdOp = rcp( 00827 new PO(1,epetraOps,epetraOpsTransp,epetraOpsApplyMode)); 00828 } 00829 if( 00830 startingOver 00831 || 00832 aztec_epetra_epetraFwdOp.get() != aztecFwdSolver->GetUserOperator() 00833 ) 00834 { 00835 // Here we will be careful not to reset the forward operator in fears that 00836 // it will blow out the internally created stuff. 00837 aztecFwdSolver->SetUserOperator( 00838 const_cast<Epetra_Operator*>(&*aztec_epetra_epetraFwdOp)); 00839 set_extra_data( 00840 aztec_epetra_epetraFwdOp, AOOLOWSF_aztec_epetra_epetraFwdOp_str, 00841 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY, false 00842 ); 00843 } 00844 // Adjoint solve 00845 if( aztecAdjSolver.get() ) { 00846 epetraOpsTransp[0] = ( 00847 epetra_epetraFwdOpTransp==NOTRANS 00848 ? Teuchos::TRANS 00849 : Teuchos::NO_TRANS 00850 ); 00851 if( 00852 epetraOpsTransp[0] == Teuchos::NO_TRANS 00853 && 00854 epetraOpsApplyMode[0] == PO::APPLY_MODE_APPLY 00855 ) 00856 { 00857 aztec_epetra_epetraAdjOp = epetra_epetraFwdOp; 00858 } 00859 else { 00860 aztec_epetra_epetraAdjOp = rcp( 00861 new PO(1,epetraOps,epetraOpsTransp,epetraOpsApplyMode)); 00862 } 00863 aztecAdjSolver->SetUserOperator( 00864 const_cast<Epetra_Operator*>(&*aztec_epetra_epetraAdjOp)); 00865 set_extra_data( 00866 aztec_epetra_epetraAdjOp, AOOLOWSF_aztec_epetra_epetraAdjOp_str, 00867 Teuchos::inOutArg(aztecAdjSolver), Teuchos::POST_DESTROY, false 00868 ); 00869 } 00870 00871 // 00872 // Process the preconditioner 00873 // 00874 RCP<const Epetra_Operator> 00875 aztec_fwd_epetra_epetraPrecOp, 00876 aztec_adj_epetra_epetraPrecOp; 00877 bool setAztecPreconditioner = false; 00878 switch(localPrecType) { 00879 case PT_NONE: { 00880 // 00881 // No preconditioning at all! 00882 // 00883 break; 00884 } 00885 case PT_AZTEC_FROM_OP: { 00886 // 00887 // We are using the forward matrix for the preconditioner using aztec 00888 // preconditioners 00889 // 00890 if( startingOver || !reusePrec ) { 00891 TEUCHOS_TEST_FOR_EXCEPTION( 00892 rowmatrix_epetraFwdOp.get()==NULL, std::logic_error, 00893 "AztecOOLinearOpWithSolveFactory::initializeOp_impl(...): " 00894 "Error, There is no preconditioner given by client, but the client " 00895 "passed in an Epetra_Operator for the forward operator of type \'" 00896 <<typeName(*epetra_epetraFwdOp)<<"\' that does not " 00897 "support the Epetra_RowMatrix interface!" 00898 ); 00899 TEUCHOS_TEST_FOR_EXCEPTION( 00900 epetra_epetraFwdOpTransp!=NOTRANS, std::logic_error, 00901 "AztecOOLinearOpWithSolveFactory::initializeOp_impl(...):" 00902 " Error, There is no preconditioner given by client and the client " 00903 "passed in an Epetra_RowMatrix for the forward operator but the " 00904 "overall transpose is not NOTRANS and therefore we can can just " 00905 "hand this over to aztec without making a copy which is not supported here!" 00906 ); 00907 aztecFwdSolver->SetPrecMatrix( 00908 const_cast<Epetra_RowMatrix*>(&*rowmatrix_epetraFwdOp)); 00909 set_extra_data( 00910 rowmatrix_epetraFwdOp, AOOLOWSF_rowmatrix_epetraFwdOp_str, 00911 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY, false 00912 ); 00913 } 00914 setAztecPreconditioner = true; 00915 break; 00916 } 00917 case PT_AZTEC_FROM_APPROX_FWD_MATRIX: { 00918 // 00919 // The preconditioner comes from the input as a matrix and we are using 00920 // aztec preconditioners 00921 // 00922 if( startingOver || !reusePrec ) { 00923 TEUCHOS_TEST_FOR_EXCEPTION( 00924 rowmatrix_epetraPrecOp.get()==NULL, std::logic_error 00925 ,"AztecOOLinearOpWithSolveFactor::initializeOp_impl(...): The client " 00926 "passed in an Epetra_Operator for the preconditioner matrix of type \'" 00927 <<typeName(*epetra_epetraPrecOp)<<"\' that does not " 00928 "support the Epetra_RowMatrix interface!" 00929 ); 00930 TEUCHOS_TEST_FOR_EXCEPTION( 00931 overall_epetra_epetraPrecOpTransp!=NOTRANS, std::logic_error 00932 ,"AztecOOLinearOpWithSolveFactor::initializeOp_impl(...): Error, The client " 00933 "passed in an Epetra_RowMatrix for the preconditoner matrix but the overall " 00934 "transpose is not NOTRANS and therefore we can can just " 00935 "hand this over to aztec without making a copy which is not supported here!" 00936 ); 00937 aztecFwdSolver->SetPrecMatrix( 00938 const_cast<Epetra_RowMatrix*>(&*rowmatrix_epetraPrecOp)); 00939 set_extra_data( 00940 rowmatrix_epetraPrecOp, AOOLOWSF_rowmatrix_epetraPrecOp_str, 00941 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY, false 00942 ); 00943 } 00944 setAztecPreconditioner = true; 00945 break; 00946 } 00947 case PT_FROM_PREC_OP: { 00948 // 00949 // The preconditioner comes as an operator so let's use it as such 00950 // 00951 // Forward solve 00952 RCP<const Epetra_Operator> 00953 epetraOps[] 00954 = { epetra_epetraPrecOp }; 00955 Teuchos::ETransp 00956 epetraOpsTransp[] 00957 = { overall_epetra_epetraPrecOpTransp==NOTRANS 00958 ? Teuchos::NO_TRANS 00959 : Teuchos::TRANS }; 00960 // Here we must toggle the apply mode since aztecoo applies the 00961 // preconditioner using ApplyInverse(...) 00962 PO::EApplyMode 00963 epetraOpsApplyMode[] 00964 = { epetra_epetraPrecOpApplyAs==EPETRA_OP_APPLY_APPLY 00965 ? PO::APPLY_MODE_APPLY_INVERSE 00966 : PO::APPLY_MODE_APPLY }; 00967 if( 00968 epetraOpsTransp[0] == Teuchos::NO_TRANS 00969 && 00970 epetra_epetraPrecOpApplyAs==EPETRA_OP_APPLY_APPLY_INVERSE 00971 ) 00972 { 00973 aztec_fwd_epetra_epetraPrecOp = epetra_epetraPrecOp; 00974 } 00975 else { 00976 aztec_fwd_epetra_epetraPrecOp = rcp(new PO(1,epetraOps,epetraOpsTransp,epetraOpsApplyMode)); 00977 } 00978 aztecFwdSolver->SetPrecOperator( 00979 const_cast<Epetra_Operator*>(&*aztec_fwd_epetra_epetraPrecOp)); 00980 set_extra_data( 00981 aztec_fwd_epetra_epetraPrecOp, AOOLOWSF_aztec_fwd_epetra_epetraPrecOp_str, 00982 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY, false 00983 ); 00984 // Adjoint solve 00985 if( 00986 aztecAdjSolver.get() 00987 && 00988 epetra_epetraPrecOpAdjointSupport == EPETRA_OP_ADJOINT_SUPPORTED 00989 ) 00990 { 00991 epetraOpsTransp[0] = ( 00992 overall_epetra_epetraPrecOpTransp==NOTRANS 00993 ? Teuchos::TRANS 00994 : Teuchos::NO_TRANS 00995 ); 00996 if( 00997 epetraOpsTransp[0] == Teuchos::NO_TRANS 00998 && 00999 epetra_epetraPrecOpApplyAs==EPETRA_OP_APPLY_APPLY_INVERSE 01000 ) 01001 { 01002 aztec_adj_epetra_epetraPrecOp = epetra_epetraPrecOp; 01003 } 01004 else { 01005 aztec_adj_epetra_epetraPrecOp = rcp( 01006 new PO(1,epetraOps,epetraOpsTransp,epetraOpsApplyMode)); 01007 } 01008 aztecAdjSolver->SetPrecOperator( 01009 const_cast<Epetra_Operator*>(&*aztec_adj_epetra_epetraPrecOp)); 01010 set_extra_data( 01011 aztec_adj_epetra_epetraPrecOp, AOOLOWSF_aztec_adj_epetra_epetraPrecOp_str, 01012 Teuchos::inOutArg(aztecAdjSolver), Teuchos::POST_DESTROY, false 01013 ); 01014 set_extra_data<bool>( 01015 true, AOOLOWSF_setPrecondtionerOperator_str, 01016 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY, false 01017 ); 01018 } 01019 break; 01020 } 01021 default: 01022 TEUCHOS_TEST_FOR_EXCEPT(true); 01023 } 01024 01025 // 01026 // Initialize the interal aztec preconditioner 01027 // 01028 if(setAztecPreconditioner) { 01029 if( startingOver || !reusePrec ) { 01030 double condNumEst = -1.0; 01031 TEUCHOS_TEST_FOR_EXCEPT(0!=aztecFwdSolver->ConstructPreconditioner(condNumEst)); 01032 //aztecFwdSolver->SetAztecOption(AZ_pre_calc, AZ_calc); 01033 set_extra_data<bool>( 01034 true, AOOLOWSF_constructedAztecPreconditoner_str, 01035 Teuchos::inOutArg(aztecFwdSolver), Teuchos::POST_DESTROY, false 01036 ); 01037 } 01038 else { 01039 //aztecFwdSolver->SetAztecOption(AZ_pre_calc, AZ_reuse); 01040 } 01041 } 01042 01043 // 01044 // Initialize the AztecOOLinearOpWithSolve object and set its options 01045 // 01046 if(aztecAdjSolver.get() && aztecAdjSolver->GetPrecOperator()) { 01047 aztecOp->initialize( 01048 fwdOp, fwdOpSrc,precUsed, prec.get()!=NULL, approxFwdOpSrc, 01049 aztecFwdSolver, true, aztecAdjSolver, true, epetra_epetraFwdOpScalar 01050 ); 01051 } 01052 else { 01053 aztecOp->initialize( 01054 fwdOp, fwdOpSrc, precUsed, prec.get()!=NULL, approxFwdOpSrc, 01055 aztecFwdSolver, true, null, false, epetra_epetraFwdOpScalar 01056 ); 01057 } 01058 aztecOp->fwdDefaultMaxIterations(defaultFwdMaxIterations_); 01059 aztecOp->fwdDefaultTol(defaultFwdTolerance_); 01060 aztecOp->adjDefaultMaxIterations(defaultAdjMaxIterations_); 01061 aztecOp->adjDefaultTol(defaultAdjTolerance_); 01062 aztecOp->outputEveryRhs(outputEveryRhs_); 01063 aztecOp->setOStream(this->getOStream()); 01064 if(!is_null(this->getOverridingOStream())) 01065 aztecOp->setOverridingOStream(this->getOverridingOStream()); 01066 aztecOp->setVerbLevel(this->getVerbLevel()); 01067 01068 #ifdef TEUCHOS_DEBUG 01069 if(paramList_.get()) 01070 paramList_->validateParameters(*this->getValidParameters()); 01071 #endif 01072 01073 if(out.get() && static_cast<int>(verbLevel) > static_cast<int>(Teuchos::VERB_LOW)) 01074 *out << "\nLeaving Thyra::AztecOOLinearOpWithSolveFactory::initializeOp_impl(...) ...\n"; 01075 01076 } 01077 01078 01079 } // namespace Thyra 01080 01081 01082 #endif // SUN_CXX
1.7.6.1