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 
00034 namespace Thyra {
00035 
00045 enum ESolveTolType {
00046   SOLVE_TOL_DEFAULT                     
00047   ,SOLVE_TOL_REL_RESIDUAL_NORM          
00048   ,SOLVE_TOL_REL_SOLUTION_ERR_NORM      
00049 };
00050 
00052 inline
00053 const char* toString(const ESolveTolType solveTolType)
00054 {
00055   switch(solveTolType) {
00056     case SOLVE_TOL_DEFAULT: return"SOLVE_TOL_DEFAULT";
00057     case SOLVE_TOL_REL_RESIDUAL_NORM: return "SOLVE_TOL_REL_RESIDUAL_NORM";
00058     case SOLVE_TOL_REL_SOLUTION_ERR_NORM: return "SOLVE_TOL_REL_SOLUTION_ERR_NORM";
00059     default: TEST_FOR_EXCEPT(true);
00060   }
00061   return ""; // Never be called!
00062 }
00063 
00068 template <class Scalar>
00069 struct SolveCriteria {
00071   typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
00073   static ScalarMag unspecifiedTolerance() { return ScalarMag(-1); }
00075   static int unspecifiedMaxIterations() { return -1; }
00079   ESolveTolType    solveTolType;
00084   ScalarMag        requestedTol;
00092   int maxIterations;
00094   SolveCriteria()
00095     :solveTolType(SOLVE_TOL_DEFAULT)
00096     ,requestedTol(unspecifiedTolerance())
00097      ,maxIterations(unspecifiedMaxIterations())
00098     {}
00100   SolveCriteria(ESolveTolType _solveTolType, ScalarMag _requestedTol, int _maxIterations = unspecifiedMaxIterations())
00101     : solveTolType(_solveTolType), requestedTol(_requestedTol), maxIterations(_maxIterations)
00102     {}
00103 };
00104 
00109 template <class Scalar>
00110 struct BlockSolveCriteria {
00112   SolveCriteria<Scalar>   solveCriteria;
00114   int                     numRhs;
00116   BlockSolveCriteria()
00117     : solveCriteria(), numRhs(1)
00118     {}
00120   BlockSolveCriteria( const SolveCriteria<Scalar> &_solveCriteria, int _numRhs )
00121     : solveCriteria(_solveCriteria), numRhs(_numRhs)
00122     {}
00123 };
00124 
00129 class CatastrophicSolveFailure : public std::runtime_error
00130 {public: CatastrophicSolveFailure(const std::string& what_arg) : std::runtime_error(what_arg) {}};
00131 
00136 enum ESolveStatus {
00137   SOLVE_STATUS_CONVERGED        
00138   ,SOLVE_STATUS_UNCONVERGED     
00139   ,SOLVE_STATUS_UNKNOWN         
00140 };
00141 
00143 inline
00144 const char* toString(const ESolveStatus solveStatus)
00145 {
00146   switch(solveStatus) {
00147     case SOLVE_STATUS_CONVERGED:    return "SOLVE_STATUS_CONVERGED";
00148     case SOLVE_STATUS_UNCONVERGED:  return "SOLVE_STATUS_UNCONVERGED";
00149     case SOLVE_STATUS_UNKNOWN:      return "SOLVE_STATUS_UNKNOWN";
00150     default: TEST_FOR_EXCEPT(true);
00151   }
00152   return ""; // Never be called!
00153 }
00154 
00161 template <class Scalar>
00162 struct SolveStatus {
00164   typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
00166   static ScalarMag unknownTolerance() { return ScalarMag(-1); }
00168   ESolveStatus solveStatus;
00174   ScalarMag achievedTol;
00180   int iterations;
00182   std::string message;
00184   SolveStatus()
00185     :solveStatus(SOLVE_STATUS_UNKNOWN), achievedTol(unknownTolerance())
00186      ,iterations(1)
00187     {}
00188 
00191   static std::string achievedTolToString( const ScalarMag &achievedTol )
00192     {
00193       if(achievedTol==unknownTolerance()) return "unknownTolerance()";
00194       std::ostringstream oss; oss << achievedTol; return oss.str();
00195     }
00196 };
00197 
00202 enum EPreconditionerInputType {
00203   PRECONDITIONER_INPUT_TYPE_AS_OPERATOR  
00204   ,PRECONDITIONER_INPUT_TYPE_AS_MATRIX   
00205 };
00206 
00221 template <class Scalar>
00222 void accumulateSolveStatus(
00223   const SolveCriteria<Scalar>    &overallSolveCriteria
00224   ,const SolveStatus<Scalar>     &solveStatus
00225   ,SolveStatus<Scalar>           *overallSolveStatus
00226   )
00227 {
00228 #ifdef _DEBUG
00229   TEST_FOR_EXCEPT(overallSolveStatus==NULL);
00230 #endif
00231   switch(solveStatus.solveStatus) {
00232     case SOLVE_STATUS_UNCONVERGED:
00233     {
00234       // First, if we see any unconverged solve status, then the entire block is
00235       // unconverged!
00236       overallSolveStatus->solveStatus = SOLVE_STATUS_UNCONVERGED;
00237       overallSolveStatus->message = solveStatus.message;
00238       break;
00239     }
00240     case SOLVE_STATUS_UNKNOWN:
00241     {
00242       // Next, if any solve status is unknown, then if the overall solve status
00243       // says converged, then we have to mark it as unknown.  Note than unknown
00244       // could mean that the system is actually converged!
00245       switch(overallSolveStatus->solveStatus) {
00246         case SOLVE_STATUS_CONVERGED:
00247           overallSolveStatus->solveStatus = SOLVE_STATUS_UNKNOWN;
00248           break;
00249         case SOLVE_STATUS_UNCONVERGED:
00250         case SOLVE_STATUS_UNKNOWN:
00251           // If we get here then the overall solve status is either unknown
00252           // already or says unconverged and this will not change here!
00253           overallSolveStatus->message = solveStatus.message;
00254           break;
00255         default:
00256           TEST_FOR_EXCEPT(true); // Corrupted enum?
00257       }
00258       break;
00259     }
00260     case SOLVE_STATUS_CONVERGED:
00261     {
00262       // If we get here then the overall solve status is either unknown,
00263       // unconverged, or converged and this will not change here!
00264       if(overallSolveStatus->message == "")
00265         overallSolveStatus->message = solveStatus.message;
00266       break;
00267     }
00268     default:
00269       TEST_FOR_EXCEPT(true); // Corrupted enum?
00270   }
00271   // Update the achieved tolerence to the maximum returned
00272   if( solveStatus.achievedTol > overallSolveStatus->achievedTol ) {
00273     overallSolveStatus->achievedTol = solveStatus.achievedTol;
00274   }
00275   // Accumulate the total number of iterations
00276   overallSolveStatus->iterations += solveStatus.iterations;
00277   // Set a message if non is set
00278   if(overallSolveStatus->message == "")
00279     overallSolveStatus->message = solveStatus.message;
00280 }
00281 
00282 } // namespace Thyra
00283 
00284 #endif // THYRA_SOLVE_SUPPORT_TYPES_HPP

Generated on Thu Sep 18 12:39:52 2008 for Thyra ANA Operator/VectorBase Interfaces and Related Software by doxygen 1.3.9.1