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 #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;
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 "";
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
00315
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
00324
00325
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
00333
00334 overallSolveStatus->message = solveStatus.message;
00335 overallSolveStatus->extraParameters = solveStatus.extraParameters;
00336 break;
00337 default:
00338 TEST_FOR_EXCEPT(true);
00339 }
00340 break;
00341 }
00342 case SOLVE_STATUS_CONVERGED:
00343 {
00344
00345
00346 if(overallSolveStatus->message == "")
00347 overallSolveStatus->message = solveStatus.message;
00348 break;
00349 }
00350 default:
00351 TEST_FOR_EXCEPT(true);
00352 }
00353
00354 if( solveStatus.achievedTol > overallSolveStatus->achievedTol ) {
00355 overallSolveStatus->achievedTol = solveStatus.achievedTol;
00356 }
00357
00358 if(overallSolveStatus->message == "")
00359 overallSolveStatus->message = solveStatus.message;
00360
00361 if(overallSolveStatus->extraParameters.get()==NULL)
00362 overallSolveStatus->extraParameters = solveStatus.extraParameters;
00363 }
00364
00365 }
00366
00367 #endif // THYRA_SOLVE_SUPPORT_TYPES_HPP