42 #include "Thyra_AztecOOLinearOpWithSolve.hpp" 
   43 #include "Thyra_LinearOpWithSolveHelpers.hpp" 
   45 #include "Thyra_EpetraOperatorWrapper.hpp" 
   46 #include "Teuchos_BLAS_types.hpp" 
   47 #include "Teuchos_TimeMonitor.hpp" 
   48 #include "Teuchos_Time.hpp" 
   49 #include "Teuchos_implicit_cast.hpp" 
   79 class SetAztecSolveState {
 
   87   ~SetAztecSolveState();
 
   98 SetAztecSolveState::SetAztecSolveState(
 
  104   :aztecSolver_(aztecSolver.assert_not_null())
 
  109   verbLevel_ = verbLevel;
 
  115       fancyOStream_= Teuchos::tab(
 
  120       aztecSolver_->SetOutputStream(*fancyOStream_);
 
  121       aztecSolver_->SetErrorStream(*fancyOStream_);
 
  131     outputFrequency_ = aztecSolver_->GetAllAztecOptions()[AZ_output];
 
  132     aztecSolver_->SetAztecOption(AZ_output,0);
 
  136   convergenceTest_ = aztecSolver_->GetAztecOption(AZ_conv);
 
  148     aztecSolver_->SetAztecOption(AZ_conv,AZ_rhs);
 
  157     aztecSolver_->SetAztecOption(AZ_conv,AZ_r0);
 
  166 SetAztecSolveState::~SetAztecSolveState()
 
  172       aztecSolver_->SetOutputStream(std::cout);
 
  173       aztecSolver_->SetErrorStream(std::cerr);
 
  174       *fancyOStream_ << 
"\n";
 
  178     aztecSolver_->SetAztecOption(AZ_output,outputFrequency_);
 
  182   aztecSolver_->SetAztecOption(AZ_conv,convergenceTest_);
 
  197   const int fwdDefaultMaxIterations_in
 
  198   ,
const double fwdDefaultTol_in
 
  199   ,
const int adjDefaultMaxIterations_in
 
  200   ,
const double adjDefaultTol_in
 
  201   ,
const bool outputEveryRhs_in
 
  203   :fwdDefaultMaxIterations_(fwdDefaultMaxIterations_in)
 
  204   ,fwdDefaultTol_(fwdDefaultTol_in)
 
  205   ,adjDefaultMaxIterations_(adjDefaultMaxIterations_in)
 
  206   ,adjDefaultTol_(adjDefaultTol_in)
 
  207   ,outputEveryRhs_(outputEveryRhs_in)
 
  208   ,isExternalPrec_(false)
 
  209   ,allowInexactFwdSolve_(false)
 
  210   ,allowInexactAdjSolve_(false)
 
  211   ,aztecSolverScalar_(0.0)
 
  219   ,
const bool isExternalPrec_in
 
  222   ,
const bool allowInexactFwdSolve
 
  224   ,
const bool allowInexactAdjSolve
 
  225   ,
const double aztecSolverScalar
 
  234   fwdOpSrc_ = fwdOpSrc;
 
  235   isExternalPrec_ = isExternalPrec_in;
 
  237   approxFwdOpSrc_ = approxFwdOpSrc;
 
  238   aztecFwdSolver_ = aztecFwdSolver;
 
  239   allowInexactFwdSolve_ = allowInexactFwdSolve;
 
  240   aztecAdjSolver_ = aztecAdjSolver;
 
  241   allowInexactAdjSolve_ = allowInexactAdjSolve;
 
  242   aztecSolverScalar_ = aztecSolverScalar;
 
  243   const std::string fwdOpLabel = fwdOp_->getObjectLabel();
 
  244   if (fwdOpLabel.length())
 
  253     _fwdOpSrc = fwdOpSrc_;
 
  254   fwdOpSrc_ = Teuchos::null;
 
  264   prec_ = Teuchos::null;
 
  271   return isExternalPrec_;
 
  279     _approxFwdOpSrc = approxFwdOpSrc_;
 
  280   approxFwdOpSrc_ = Teuchos::null;
 
  281   return _approxFwdOpSrc;
 
  289   bool *isExternalPrec_inout,
 
  292   bool *allowInexactFwdSolve,
 
  294   bool *allowInexactAdjSolve,
 
  295   double *aztecSolverScalar
 
  298   if (fwdOp) *fwdOp = fwdOp_;
 
  299   if (fwdOpSrc) *fwdOpSrc = fwdOpSrc_;
 
  300   if (prec) *prec = prec_;
 
  301   if (isExternalPrec_inout) *isExternalPrec_inout = isExternalPrec_;
 
  302   if (approxFwdOpSrc) *approxFwdOpSrc = approxFwdOpSrc_;
 
  303   if (aztecFwdSolver) *aztecFwdSolver = aztecFwdSolver_;
 
  304   if (allowInexactFwdSolve) *allowInexactFwdSolve = allowInexactFwdSolve_;
 
  305   if (aztecAdjSolver) *aztecAdjSolver = aztecAdjSolver_;
 
  306   if (allowInexactAdjSolve) *allowInexactAdjSolve = allowInexactAdjSolve_;
 
  307   if (aztecSolverScalar) *aztecSolverScalar = aztecSolverScalar_;
 
  309   fwdOp_ = Teuchos::null;
 
  310   fwdOpSrc_ = Teuchos::null;
 
  311   prec_ = Teuchos::null;
 
  312   isExternalPrec_ = 
false; 
 
  313   approxFwdOpSrc_ = Teuchos::null;
 
  314   aztecFwdSolver_ = Teuchos::null;
 
  315   allowInexactFwdSolve_ = 
false;
 
  316   aztecAdjSolver_ = Teuchos::null;
 
  317   allowInexactAdjSolve_ = 
false;
 
  318   aztecSolverScalar_ = 0.0;
 
  328   return ( fwdOp_.get() ? fwdOp_->range() : Teuchos::null );
 
  335   return ( fwdOp_.get() ? fwdOp_->domain() : Teuchos::null );
 
  342   return Teuchos::null; 
 
  351   std::ostringstream oss;
 
  355     oss << 
"fwdOp="<<fwdOp_->description()<<
"";
 
  369   using Teuchos::describe;
 
  381         << 
"rangeDim=" << this->
range()->dim()
 
  382         << 
",domainDim="<< this->
domain()->dim() << 
"}\n";
 
  385         out << 
"fwdOp = " << 
describe(*fwdOp_,verbLevel);
 
  388         out << 
"prec = " << 
describe(*prec_,verbLevel);
 
  390       if (!
is_null(aztecFwdSolver_)) {
 
  397             << 
"Aztec Fwd Mat = " 
  401             << 
"Aztec Fwd Prec Op = " 
  405             << 
"Aztec Fwd Prec Mat = " 
  408       if (!
is_null(aztecAdjSolver_)) {
 
  415             << 
"Aztec Adj Mat = " 
  419             << 
"Aztec Adj Prec Op = " 
  423             << 
"Aztec Adj Prec Mat = " 
  442   return ::Thyra::opSupported(*fwdOp_,M_trans);
 
  454   Thyra::apply( *fwdOp_, M_trans, X, Y, alpha, beta );
 
  465   return (
nonnull(aztecAdjSolver_));
 
  485       allowInexactFwdSolve_
 
  496       allowInexactFwdSolve_
 
  504     if (aztecAdjSolver_.
get()==NULL)
 
  518       allowInexactFwdSolve_
 
  529       allowInexactFwdSolve_
 
  553   using Teuchos::rcpFromRef;
 
  554   using Teuchos::rcpFromPtr;
 
  559   THYRA_FUNC_TIME_MONITOR(
"Stratimikos: AztecOOLOWS");
 
  561   totalTimer.start(
true);
 
  565   OSTab tab = this->getOSTab();
 
  567     *out << 
"\nSolving block system using AztecOO ...\n\n";
 
  575     solveMeasureType = solveCriteria->solveMeasureType;
 
  576     assertSupportsSolveMeasureType(*
this, M_trans, solveMeasureType);
 
  588     aztecSolver = ( aztecOpTransp == 
NOTRANS ? aztecFwdSolver_  : aztecAdjSolver_ );
 
  602   double tol = ( aztecOpTransp==
NOTRANS ? fwdDefaultTol() : adjDefaultTol() );
 
  603   int maxIterations = ( aztecOpTransp==
NOTRANS 
  604     ? fwdDefaultMaxIterations() : adjDefaultMaxIterations() );
 
  605   bool isDefaultSolveCriteria = 
true;
 
  607     if ( solveCriteria->requestedTol != SC::unspecifiedTolerance() ) {
 
  608       tol = solveCriteria->requestedTol;
 
  609       isDefaultSolveCriteria = 
false;
 
  611     if (
nonnull(solveCriteria->extraParameters)) {
 
  612       maxIterations = solveCriteria->extraParameters->get(
"Maximum Iterations",maxIterations);
 
  626   if (opWrapper == 0) {
 
  635   int totalIterations = 0;
 
  644   const int m = B.
domain()->dim();
 
  646   for( 
int j = 0; j < m; ++j ) {
 
  648     THYRA_FUNC_TIME_MONITOR_DIFF(
"Stratimikos: AztecOOLOWS:SingleSolve", SingleSolve);
 
  661     if (opWrapper == 0) {
 
  662       epetra_b_j = rcpFromRef(*const_cast<Epetra_Vector*>((*epetra_B)(j)));
 
  663       epetra_x_j = rcpFromRef(*(*epetra_X)(j));
 
  678     aztecSolver->
SetRHS(&*epetra_b_j);
 
  679     aztecSolver->
SetLHS(&*epetra_x_j);
 
  687         setAztecSolveState(aztecSolver,out,verbLevel,solveMeasureType);
 
  688       aztecSolver->
Iterate( maxIterations, tol );
 
  699     if (aztecSolverScalar_ != 1.0)
 
  700       epetra_x_j->Scale(1.0/aztecSolverScalar_);
 
  705     if (opWrapper != 0) {
 
  713     const int iterations = aztecSolver->
NumIters();
 
  716     std::ostringstream oss;
 
  717     bool converged = 
false;
 
  718     if (AZ_status[AZ_why]==AZ_normal) { oss << 
"Aztec returned AZ_normal."; converged = 
true; }
 
  719     else if (AZ_status[AZ_why]==AZ_param) oss << 
"Aztec returned AZ_param.";
 
  720     else if (AZ_status[AZ_why]==AZ_breakdown) oss << 
"Aztec returned AZ_breakdown.";
 
  721     else if (AZ_status[AZ_why]==AZ_loss) oss << 
"Aztec returned AZ_loss.";
 
  722     else if (AZ_status[AZ_why]==AZ_ill_cond) oss << 
"Aztec returned AZ_ill_cond.";
 
  723     else if (AZ_status[AZ_why]==AZ_maxits) oss << 
"Aztec returned AZ_maxits.";
 
  724     else oss << 
"Aztec returned an unknown status?";
 
  725     oss << 
"  Iterations = " << iterations << 
".";
 
  726     oss << 
"  Achieved Tolerance = " << achievedTol << 
".";
 
  728     if (out.
get() && 
static_cast<int>(verbLevel) > static_cast<int>(
Teuchos::VERB_NONE) && outputEveryRhs())
 
  734     totalIterations += iterations;
 
  736     solveStatus.
message = oss.str();
 
  737     if ( isDefaultSolveCriteria ) {
 
  759   epetra_X = Teuchos::null;
 
  760   epetra_B = Teuchos::null;
 
  767   if (isDefaultSolveCriteria) {
 
  769     overallSolveStatus.
achievedTol = SS::unknownTolerance();
 
  775   std::ostringstream oss;
 
  779     << 
" on m = "<<m<<
" RHSs using " << totalIterations << 
" cumulative iterations" 
  780     << 
" for an average of " << (totalIterations/m) << 
" iterations/RHS and" 
  781     << 
" total CPU time of "<<totalTimer.totalElapsedTime()<<
" sec.";
 
  782   overallSolveStatus.
message = oss.str();
 
  801       << 
"\nTotal solve time = "<<totalTimer.totalElapsedTime()<<
" sec\n";
 
  803   return overallSolveStatus;
 
RCP< Epetra_MultiVector > get_Epetra_MultiVector(const Epetra_Map &map, const RCP< MultiVectorBase< double > > &mv)
 
virtual bool opSupportedImpl(EOpTransp M_trans) const 
 
bool is_null(const boost::shared_ptr< T > &p)
 
void copyEpetraIntoThyra(const Epetra_MultiVector &x, const Ptr< VectorBase< double > > &thyraVec) const 
 
basic_OSTab< char > OSTab
 
RCP< T > create_weak() const 
 
const double * GetAztecStatus() const 
 
basic_FancyOStream< CharT, Traits > & o() const 
 
RCP< const LinearOpSourceBase< double > > extract_fwdOpSrc()
Extract the forward LinearOpBase<double> object so that it can be modified. 
 
bool isExternalPrec() const 
Determine if the preconditioner was external or not. 
 
double ScaledResidual() const 
 
std::string description() const 
 
EOpTransp real_trans(EOpTransp transp)
 
virtual bool solveSupportsSolveMeasureTypeImpl(EOpTransp M_trans, const SolveMeasureType &solveMeasureType) const 
 
virtual const Epetra_Map & OperatorDomainMap() const =0
 
virtual void applyImpl(const EOpTransp M_trans, const MultiVectorBase< double > &X, const Ptr< MultiVectorBase< double > > &Y, const double alpha, const double beta) const 
 
virtual bool solveSupportsImpl(EOpTransp M_trans) const 
 
RCP< const VectorSpaceBase< double > > domain() const 
 
virtual const Epetra_Map & OperatorRangeMap() const =0
 
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const 
 
void start(bool reset=false)
 
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
 
int SetLHS(Epetra_MultiVector *X)
 
RCP< const VectorBase< Scalar > > col(Ordinal j) const 
 
virtual std::string description() const 
 
TypeTo implicit_cast(const TypeFrom &t)
 
Epetra_Operator * GetPrecOperator() const 
 
virtual void setObjectLabel(const std::string &objectLabel)
 
int SetRHS(Epetra_MultiVector *B)
 
Epetra_RowMatrix * GetPrecMatrix() const 
 
Epetra_Operator * GetUserOperator() const 
 
void copyThyraIntoEpetra(const VectorBase< double > &thyraVec, Epetra_MultiVector &x) const 
 
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
 
bool nonnull(const boost::shared_ptr< T > &p)
 
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. 
 
Epetra_RowMatrix * GetUserMatrix() const 
 
double totalElapsedTime(bool readCurrentTime=false) const 
 
RCP< ParameterList > extraParameters
 
#define TEUCHOS_ASSERT(assertion_test)
 
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. 
 
RCP< const LinearOpBase< double > > clone() const 
 
int Iterate(long long MaxIters, double Tolerance)
 
RCP< const VectorSpaceBase< double > > range() const 
 
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
 
SolveStatus< double > solveImpl(const EOpTransp M_trans, const MultiVectorBase< double > &B, const Ptr< MultiVectorBase< double > > &X, const Ptr< const SolveCriteria< double > > solveCriteria) const 
 
std::string typeName(const T &t)
 
RCP< const LinearOpSourceBase< double > > extract_approxFwdOpSrc()
Extract the approximate forward LinearOpBase<double> object used to build the preconditioner. 
 
AztecOOLinearOpWithSolve(const int fwdDefaultMaxIterations=400, const double fwdDefaultTol=1e-6, const int adjDefaultMaxIterations=400, const double adjDefaultTol=1e-6, const bool outputEveryRhs=false)