00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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 "";
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 "";
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
00235
00236 overallSolveStatus->solveStatus = SOLVE_STATUS_UNCONVERGED;
00237 overallSolveStatus->message = solveStatus.message;
00238 break;
00239 }
00240 case SOLVE_STATUS_UNKNOWN:
00241 {
00242
00243
00244
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
00252
00253 overallSolveStatus->message = solveStatus.message;
00254 break;
00255 default:
00256 TEST_FOR_EXCEPT(true);
00257 }
00258 break;
00259 }
00260 case SOLVE_STATUS_CONVERGED:
00261 {
00262
00263
00264 if(overallSolveStatus->message == "")
00265 overallSolveStatus->message = solveStatus.message;
00266 break;
00267 }
00268 default:
00269 TEST_FOR_EXCEPT(true);
00270 }
00271
00272 if( solveStatus.achievedTol > overallSolveStatus->achievedTol ) {
00273 overallSolveStatus->achievedTol = solveStatus.achievedTol;
00274 }
00275
00276 overallSolveStatus->iterations += solveStatus.iterations;
00277
00278 if(overallSolveStatus->message == "")
00279 overallSolveStatus->message = solveStatus.message;
00280 }
00281
00282 }
00283
00284 #endif // THYRA_SOLVE_SUPPORT_TYPES_HPP