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 namespace Thyra {
00037 
00049 enum ESolveMeasureNormType {
00050   SOLVE_MEASURE_ONE                   
00051   ,SOLVE_MEASURE_NORM_RESIDUAL        
00052   ,SOLVE_MEASURE_NORM_SOLUTION        
00053   ,SOLVE_MEASURE_NORM_INIT_RESIDUAL   
00054   ,SOLVE_MEASURE_NORM_RHS             
00055 };
00056 
00058 inline
00059 const char* toString(const ESolveMeasureNormType solveMeasureNormType)
00060 {
00061   switch(solveMeasureNormType) {
00062     case SOLVE_MEASURE_ONE:
00063       return "SOLVE_MEASURE_ONE";
00064     case SOLVE_MEASURE_NORM_RESIDUAL:
00065       return "SOLVE_MEASURE_NORM_RESIDUAL";
00066     case SOLVE_MEASURE_NORM_SOLUTION:
00067       return "SOLVE_MEASURE_NORM_SOLUTION";
00068     case SOLVE_MEASURE_NORM_INIT_RESIDUAL:
00069       return "SOLVE_MEASURE_NORM_INIT_RESIDUAL";
00070     case SOLVE_MEASURE_NORM_RHS:
00071       return "SOLVE_MEASURE_NORM_RHS";
00072     default:
00073       TEST_FOR_EXCEPT(true);
00074   }
00075   return NULL; // Never be called!
00076 }
00077 
00091 struct SolveMeasureType {
00093   ESolveMeasureNormType  numerator;
00095   ESolveMeasureNormType  denominator;
00097   SolveMeasureType()
00098     :numerator(SOLVE_MEASURE_ONE),denominator(SOLVE_MEASURE_ONE)
00099     {}
00101   SolveMeasureType(ESolveMeasureNormType _numerator, ESolveMeasureNormType _denominator)
00102     :numerator(_numerator),denominator(_denominator)
00103     {}
00105   void set(ESolveMeasureNormType _numerator, ESolveMeasureNormType _denominator)
00106     { numerator = _numerator; denominator = _denominator; }
00108   bool useDefault() const
00109     { return ( numerator==SOLVE_MEASURE_ONE && denominator==SOLVE_MEASURE_ONE ); }
00111   bool operator()(ESolveMeasureNormType _numerator, ESolveMeasureNormType _denominator) const
00112     { return ( numerator==_numerator && denominator==_denominator ); }
00113 };
00114 
00116 inline
00117 std::string toString(const SolveMeasureType& solveMeasureType)
00118 {
00119   std::ostringstream oss;
00120   oss << "("<<toString(solveMeasureType.numerator)<<")/("<<solveMeasureType.denominator<<")";
00121   return oss.str();
00122 }
00123 
00128 template <class Scalar>
00129 struct SolveCriteria {
00131   typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
00133   static ScalarMag unspecifiedTolerance() { return ScalarMag(-1); }
00136   SolveMeasureType solveMeasureType;
00139   ScalarMag requestedTol;
00143   Teuchos::RefCountPtr<Teuchos::ParameterList> extraParameters;
00145   SolveCriteria()
00146     :solveMeasureType()
00147     ,requestedTol(unspecifiedTolerance())
00148     {}
00150   SolveCriteria(
00151     SolveMeasureType _solveMeasureType, ScalarMag _requestedTol
00152     ,const Teuchos::RefCountPtr<Teuchos::ParameterList> &_extraParameters = Teuchos::null
00153     )
00154     :solveMeasureType(_solveMeasureType),requestedTol(_requestedTol),extraParameters(_extraParameters)
00155     {}
00156 };
00157 
00162 template <class Scalar>
00163 struct BlockSolveCriteria {
00165   SolveCriteria<Scalar> solveCriteria;
00167   int                     numRhs;
00169   BlockSolveCriteria()
00170     : solveCriteria(), numRhs(1)
00171     {}
00173   BlockSolveCriteria( const SolveCriteria<Scalar> &_solveCriteria, int _numRhs )
00174     : solveCriteria(_solveCriteria), numRhs(_numRhs)
00175     {}
00176 };
00177 
00182 class CatastrophicSolveFailure : public std::runtime_error
00183 {public: CatastrophicSolveFailure(const std::string& what_arg) : std::runtime_error(what_arg) {}};
00184 
00189 enum ESolveStatus {
00190   SOLVE_STATUS_CONVERGED        
00191   ,SOLVE_STATUS_UNCONVERGED     
00192   ,SOLVE_STATUS_UNKNOWN         
00193 };
00194 
00196 inline
00197 const char* toString(const ESolveStatus solveStatus)
00198 {
00199   switch(solveStatus) {
00200     case SOLVE_STATUS_CONVERGED:    return "SOLVE_STATUS_CONVERGED";
00201     case SOLVE_STATUS_UNCONVERGED:  return "SOLVE_STATUS_UNCONVERGED";
00202     case SOLVE_STATUS_UNKNOWN:      return "SOLVE_STATUS_UNKNOWN";
00203     default: TEST_FOR_EXCEPT(true);
00204   }
00205   return ""; // Never be called!
00206 }
00207 
00214 template <class Scalar>
00215 struct SolveStatus {
00217   typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
00219   static ScalarMag unknownTolerance() { return ScalarMag(-1); }
00221   ESolveStatus solveStatus;
00225   ScalarMag achievedTol;
00227   std::string message;
00230   Teuchos::RefCountPtr<Teuchos::ParameterList> extraParameters;
00232   SolveStatus()
00233     :solveStatus(SOLVE_STATUS_UNKNOWN), achievedTol(unknownTolerance())
00234     {}
00237   static std::string achievedTolToString( const ScalarMag &achievedTol )
00238     {
00239       if(achievedTol==unknownTolerance()) return "unknownTolerance()";
00240       std::ostringstream oss; oss << achievedTol; return oss.str();
00241     }
00242 };
00243 
00245 template <class Scalar>
00246 std::ostream& operator<<( std::ostream& out_arg, const SolveStatus<Scalar> &solveStatus )
00247 {
00248   Teuchos::RefCountPtr<Teuchos::FancyOStream>
00249     out = Teuchos::getFancyOStream(Teuchos::rcp(&out_arg,false));
00250   Teuchos::OSTab tab(out);
00251   *out
00252     << "solveStatus = " << toString(solveStatus.solveStatus) << std::endl
00253     << "achievedTol = " << SolveStatus<Scalar>::achievedTolToString(solveStatus.achievedTol) << std::endl
00254     << "message: \"" << solveStatus.message << "\"" << std::endl
00255     << "extraParameters:";
00256   if(solveStatus.extraParameters.get()) {
00257     *out << "\n";
00258     solveStatus.extraParameters->print(Teuchos::OSTab(out)(),1000,true);
00259   }
00260   else {
00261     *out << " NONE\n";
00262   }
00263   return out_arg;
00264 }
00265 
00271 enum ESupportSolveUse {
00272   SUPPORT_SOLVE_UNSPECIFIED  
00273   ,SUPPORT_SOLVE_FORWARD_ONLY  
00274   ,SUPPORT_SOLVE_TRANSPOSE_ONLY  
00275   ,SUPPORT_SOLVE_FORWARD_AND_TRANSPOSE  
00276 };
00277 
00282 enum EPreconditionerInputType {
00283   PRECONDITIONER_INPUT_TYPE_AS_OPERATOR  
00284   ,PRECONDITIONER_INPUT_TYPE_AS_MATRIX   
00285 };
00286 
00301 template <class Scalar>
00302 void accumulateSolveStatus(
00303   const SolveCriteria<Scalar>    &overallSolveCriteria
00304   ,const SolveStatus<Scalar>     &solveStatus
00305   ,SolveStatus<Scalar>           *overallSolveStatus
00306   )
00307 {
00308 #ifdef TEUCHOS_DEBUG
00309   TEST_FOR_EXCEPT(overallSolveStatus==NULL);
00310 #endif
00311   switch(solveStatus.solveStatus) {
00312     case SOLVE_STATUS_UNCONVERGED:
00313     {
00314       // First, if we see any unconverged solve status, then the entire block is
00315       // unconverged!
00316       overallSolveStatus->solveStatus = SOLVE_STATUS_UNCONVERGED;
00317       overallSolveStatus->message = solveStatus.message;
00318       overallSolveStatus->extraParameters = solveStatus.extraParameters;
00319       break;
00320     }
00321     case SOLVE_STATUS_UNKNOWN:
00322     {
00323       // Next, if any solve status is unknown, then if the overall solve
00324       // status says converged, then we have to mark it as unknown.  Note that
00325       // unknown could mean that the system is actually converged!
00326       switch(overallSolveStatus->solveStatus) {
00327         case SOLVE_STATUS_CONVERGED:
00328           overallSolveStatus->solveStatus = SOLVE_STATUS_UNKNOWN;
00329           break;
00330         case SOLVE_STATUS_UNCONVERGED:
00331         case SOLVE_STATUS_UNKNOWN:
00332           // If we get here then the overall solve status is either unknown
00333           // already or says unconverged and this will not change here!
00334           overallSolveStatus->message = solveStatus.message;
00335           overallSolveStatus->extraParameters = solveStatus.extraParameters;
00336           break;
00337         default:
00338           TEST_FOR_EXCEPT(true); // Corrupted enum?
00339       }
00340       break;
00341     }
00342     case SOLVE_STATUS_CONVERGED:
00343     {
00344       // If we get here then the overall solve status is either unknown,
00345       // unconverged, or converged and this will not change here!
00346       if(overallSolveStatus->message == "")
00347         overallSolveStatus->message = solveStatus.message;
00348       break;
00349     }
00350     default:
00351       TEST_FOR_EXCEPT(true); // Corrupted enum?
00352   }
00353   // Update the achieved tolerence to the maximum returned
00354   if( solveStatus.achievedTol > overallSolveStatus->achievedTol ) {
00355     overallSolveStatus->achievedTol = solveStatus.achievedTol;
00356   }
00357   // Set a message if none is set
00358   if(overallSolveStatus->message == "")
00359     overallSolveStatus->message = solveStatus.message;
00360   // Set the extra parameters if none is set
00361   if(overallSolveStatus->extraParameters.get()==NULL)
00362     overallSolveStatus->extraParameters = solveStatus.extraParameters;
00363 }
00364 
00365 } // namespace Thyra
00366 
00367 #endif // THYRA_SOLVE_SUPPORT_TYPES_HPP

Generated on Thu Sep 18 12:32:15 2008 for Thyra ANA Operator Solve Interfaces by doxygen 1.3.9.1