Thyra_SolveSupportTypes.hpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //    Thyra: Interfaces and Support for Abstract Numerical Algorithms
00005 //                 Copyright (2004) 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 #ifndef THYRA_SOLVE_SUPPORT_TYPES_HPP
00030 #define THYRA_SOLVE_SUPPORT_TYPES_HPP
00031 
00032 #include "Thyra_OperatorVectorTypes.hpp"
00033 #include "Teuchos_ParameterList.hpp"
00034 #include "Teuchos_FancyOStream.hpp"
00035 
00036 
00037 namespace Thyra {
00038 
00039 
00046 enum ESolveMeasureNormType {
00047   SOLVE_MEASURE_ONE                   
00048   ,SOLVE_MEASURE_NORM_RESIDUAL        
00049   ,SOLVE_MEASURE_NORM_SOLUTION        
00050   ,SOLVE_MEASURE_NORM_INIT_RESIDUAL   
00051   ,SOLVE_MEASURE_NORM_RHS             
00052 };
00053 
00054 
00059 inline
00060 const std::string toString(const ESolveMeasureNormType solveMeasureNormType)
00061 {
00062   switch(solveMeasureNormType) {
00063     case SOLVE_MEASURE_ONE:
00064       return "SOLVE_MEASURE_ONE";
00065     case SOLVE_MEASURE_NORM_RESIDUAL:
00066       return "SOLVE_MEASURE_NORM_RESIDUAL";
00067     case SOLVE_MEASURE_NORM_SOLUTION:
00068       return "SOLVE_MEASURE_NORM_SOLUTION";
00069     case SOLVE_MEASURE_NORM_INIT_RESIDUAL:
00070       return "SOLVE_MEASURE_NORM_INIT_RESIDUAL";
00071     case SOLVE_MEASURE_NORM_RHS:
00072       return "SOLVE_MEASURE_NORM_RHS";
00073     default:
00074       TEST_FOR_EXCEPT(true);
00075   }
00076   return NULL; // Never be called!
00077 }
00078 
00079 
00093 struct SolveMeasureType {
00095   ESolveMeasureNormType  numerator;
00097   ESolveMeasureNormType  denominator;
00099   SolveMeasureType()
00100     :numerator(SOLVE_MEASURE_ONE),denominator(SOLVE_MEASURE_ONE)
00101     {}
00103   SolveMeasureType(ESolveMeasureNormType _numerator, ESolveMeasureNormType _denominator)
00104     :numerator(_numerator),denominator(_denominator)
00105     {}
00107   void set(ESolveMeasureNormType _numerator, ESolveMeasureNormType _denominator)
00108     { numerator = _numerator; denominator = _denominator; }
00110   bool useDefault() const
00111     { return ( numerator==SOLVE_MEASURE_ONE && denominator==SOLVE_MEASURE_ONE ); }
00113   bool operator()(ESolveMeasureNormType _numerator, ESolveMeasureNormType _denominator) const
00114     { return ( numerator==_numerator && denominator==_denominator ); }
00115 };
00116 
00117 
00122 inline
00123 std::string toString(const SolveMeasureType& solveMeasureType)
00124 {
00125   std::ostringstream oss;
00126   oss << "("<<toString(solveMeasureType.numerator)<<")/("<<solveMeasureType.denominator<<")";
00127   return oss.str();
00128 }
00129 
00130 
00135 template <class Scalar>
00136 struct SolveCriteria {
00138   typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
00140   static ScalarMag unspecifiedTolerance() { return ScalarMag(-1); }
00143   SolveMeasureType solveMeasureType;
00146   ScalarMag requestedTol;
00150   Teuchos::RCP<Teuchos::ParameterList> extraParameters;
00152   SolveCriteria()
00153     :solveMeasureType()
00154     ,requestedTol(unspecifiedTolerance())
00155     {}
00157   SolveCriteria(
00158     SolveMeasureType _solveMeasureType, ScalarMag _requestedTol
00159     ,const Teuchos::RCP<Teuchos::ParameterList> &_extraParameters = Teuchos::null
00160     )
00161     :solveMeasureType(_solveMeasureType),requestedTol(_requestedTol),extraParameters(_extraParameters)
00162     {}
00163 };
00164 
00165 
00170 template <class Scalar>
00171 struct THYRA_DEPRECATED BlockSolveCriteria {
00173   SolveCriteria<Scalar> solveCriteria;
00175   int                     numRhs;
00177   BlockSolveCriteria()
00178     : solveCriteria(), numRhs(1)
00179     {}
00181   BlockSolveCriteria( const SolveCriteria<Scalar> &_solveCriteria, int _numRhs )
00182     : solveCriteria(_solveCriteria), numRhs(_numRhs)
00183     {}
00184 };
00185 
00186 
00191 class CatastrophicSolveFailure : public std::runtime_error
00192 {public: CatastrophicSolveFailure(const std::string& what_arg) : std::runtime_error(what_arg) {}};
00193 
00194 
00199 enum ESolveStatus {
00200   SOLVE_STATUS_CONVERGED        
00201   ,SOLVE_STATUS_UNCONVERGED     
00202   ,SOLVE_STATUS_UNKNOWN         
00203 };
00204 
00205 
00210 inline
00211 const std::string toString(const ESolveStatus solveStatus)
00212 {
00213   switch(solveStatus) {
00214     case SOLVE_STATUS_CONVERGED:    return "SOLVE_STATUS_CONVERGED";
00215     case SOLVE_STATUS_UNCONVERGED:  return "SOLVE_STATUS_UNCONVERGED";
00216     case SOLVE_STATUS_UNKNOWN:      return "SOLVE_STATUS_UNKNOWN";
00217     default: TEST_FOR_EXCEPT(true);
00218   }
00219   return ""; // Never be called!
00220 }
00221 
00222 
00229 template <class Scalar>
00230 struct SolveStatus {
00232   typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
00234   static ScalarMag unknownTolerance() { return ScalarMag(-1); }
00236   ESolveStatus solveStatus;
00240   ScalarMag achievedTol;
00242   std::string message;
00245   Teuchos::RCP<Teuchos::ParameterList> extraParameters;
00247   SolveStatus()
00248     :solveStatus(SOLVE_STATUS_UNKNOWN), achievedTol(unknownTolerance())
00249     {}
00252   static std::string achievedTolToString( const ScalarMag &achievedTol )
00253     {
00254       if(achievedTol==unknownTolerance()) return "unknownTolerance()";
00255       std::ostringstream oss; oss << achievedTol; return oss.str();
00256     }
00257 };
00258 
00259 
00264 template <class Scalar>
00265 std::ostream& operator<<( std::ostream& out_arg, const SolveStatus<Scalar> &solveStatus )
00266 {
00267   Teuchos::RCP<Teuchos::FancyOStream>
00268     out = Teuchos::getFancyOStream(Teuchos::rcp(&out_arg,false));
00269   Teuchos::OSTab tab(out);
00270   *out
00271     << "solveStatus = " << toString(solveStatus.solveStatus) << std::endl
00272     << "achievedTol = " << SolveStatus<Scalar>::achievedTolToString(solveStatus.achievedTol) << std::endl;
00273   *out << "message:";
00274   if (solveStatus.message.length()) {
00275     Teuchos::OSTab tab2(out);
00276     *out << "\n" << solveStatus.message << "\n";
00277   }
00278   *out << "extraParameters:";
00279   if(solveStatus.extraParameters.get()) {
00280     *out << "\n";
00281     Teuchos::OSTab tab3(out);
00282     solveStatus.extraParameters->print(*out, 1000, true);
00283   }
00284   else {
00285     *out << " NONE\n";
00286   }
00287   return out_arg;
00288 }
00289 
00290 
00296 enum ESupportSolveUse {
00297   SUPPORT_SOLVE_UNSPECIFIED  
00298   ,SUPPORT_SOLVE_FORWARD_ONLY  
00299   ,SUPPORT_SOLVE_TRANSPOSE_ONLY  
00300   ,SUPPORT_SOLVE_FORWARD_AND_TRANSPOSE  
00301 };
00302 
00303 
00308 enum EPreconditionerInputType {
00309   PRECONDITIONER_INPUT_TYPE_AS_OPERATOR  
00310   ,PRECONDITIONER_INPUT_TYPE_AS_MATRIX   
00311 };
00312 
00313 
00318 template <class Scalar>
00319 void accumulateSolveStatusInit(
00320   const Ptr<SolveStatus<Scalar> > &overallSolveStatus
00321   )
00322 {
00323   overallSolveStatus->solveStatus = SOLVE_STATUS_CONVERGED;
00324 }
00325 
00326 
00343 template <class Scalar>
00344 void accumulateSolveStatus(
00345   const SolveCriteria<Scalar>, // ToDo: Never used, need to take this out!
00346   const SolveStatus<Scalar> &solveStatus,
00347   const Ptr<SolveStatus<Scalar> > &overallSolveStatus
00348   )
00349 {
00350   switch(solveStatus.solveStatus) {
00351     case SOLVE_STATUS_UNCONVERGED:
00352     {
00353       // First, if we see any unconverged solve status, then the entire block is
00354       // unconverged!
00355       overallSolveStatus->solveStatus = SOLVE_STATUS_UNCONVERGED;
00356       overallSolveStatus->message = solveStatus.message;
00357       overallSolveStatus->extraParameters = solveStatus.extraParameters;
00358       break;
00359     }
00360     case SOLVE_STATUS_UNKNOWN:
00361     {
00362       // Next, if any solve status is unknown, then if the overall solve
00363       // status says converged, then we have to mark it as unknown.  Note that
00364       // unknown could mean that the system is actually converged!
00365       switch(overallSolveStatus->solveStatus) {
00366         case SOLVE_STATUS_CONVERGED:
00367           overallSolveStatus->solveStatus = SOLVE_STATUS_UNKNOWN;
00368           break;
00369         case SOLVE_STATUS_UNCONVERGED:
00370         case SOLVE_STATUS_UNKNOWN:
00371           // If we get here then the overall solve status is either unknown
00372           // already or says unconverged and this will not change here!
00373           overallSolveStatus->message = solveStatus.message;
00374           overallSolveStatus->extraParameters = solveStatus.extraParameters;
00375           break;
00376         default:
00377           TEST_FOR_EXCEPT(true); // Corrupted enum?
00378       }
00379       break;
00380     }
00381     case SOLVE_STATUS_CONVERGED:
00382     {
00383       // If we get here then the overall solve status is either unknown,
00384       // unconverged, or converged and this will not change here!
00385       if(overallSolveStatus->message == "")
00386         overallSolveStatus->message = solveStatus.message;
00387       break;
00388     }
00389     default:
00390       TEST_FOR_EXCEPT(true); // Corrupted enum?
00391   }
00392   // Update the achieved tolerence to the maximum returned
00393   if( solveStatus.achievedTol > overallSolveStatus->achievedTol ) {
00394     overallSolveStatus->achievedTol = solveStatus.achievedTol;
00395   }
00396   // Set a message if none is set
00397   if(overallSolveStatus->message == "")
00398     overallSolveStatus->message = solveStatus.message;
00399   // Set the extra parameters if none is set
00400   if(overallSolveStatus->extraParameters.get()==NULL)
00401     overallSolveStatus->extraParameters = solveStatus.extraParameters;
00402 }
00403 
00404 
00409 template <class Scalar>
00410 THYRA_DEPRECATED
00411 void accumulateSolveStatus(
00412   const SolveCriteria<Scalar>, // ToDo: Never used, need to take this out!
00413   const SolveStatus<Scalar> &solveStatus,
00414   SolveStatus<Scalar> *overallSolveStatus
00415   )
00416 {
00417   accumulateSolveStatus(
00418     SolveCriteria<Scalar>(),
00419     solveStatus, Teuchos::ptr(overallSolveStatus)
00420     );
00421 }
00422 
00423 
00424 } // namespace Thyra
00425 
00426 
00427 #endif // THYRA_SOLVE_SUPPORT_TYPES_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Apr 13 10:00:24 2011 for Thyra by  doxygen 1.6.3