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 std::string 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::RCP<Teuchos::ParameterList> extraParameters;
00145 SolveCriteria()
00146 :solveMeasureType()
00147 ,requestedTol(unspecifiedTolerance())
00148 {}
00150 SolveCriteria(
00151 SolveMeasureType _solveMeasureType, ScalarMag _requestedTol
00152 ,const Teuchos::RCP<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 std::string 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::RCP<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::RCP<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 *out << "message:";
00255 if (solveStatus.message.length()) {
00256 Teuchos::OSTab tab(out);
00257 *out << "\n" << solveStatus.message << "\n";
00258 }
00259 *out << "extraParameters:";
00260 if(solveStatus.extraParameters.get()) {
00261 *out << "\n";
00262 solveStatus.extraParameters->print(Teuchos::OSTab(out).o(),1000,true);
00263 }
00264 else {
00265 *out << " NONE\n";
00266 }
00267 return out_arg;
00268 }
00269
00275 enum ESupportSolveUse {
00276 SUPPORT_SOLVE_UNSPECIFIED
00277 ,SUPPORT_SOLVE_FORWARD_ONLY
00278 ,SUPPORT_SOLVE_TRANSPOSE_ONLY
00279 ,SUPPORT_SOLVE_FORWARD_AND_TRANSPOSE
00280 };
00281
00286 enum EPreconditionerInputType {
00287 PRECONDITIONER_INPUT_TYPE_AS_OPERATOR
00288 ,PRECONDITIONER_INPUT_TYPE_AS_MATRIX
00289 };
00290
00305 template <class Scalar>
00306 void accumulateSolveStatus(
00307 const SolveCriteria<Scalar> &overallSolveCriteria
00308 ,const SolveStatus<Scalar> &solveStatus
00309 ,SolveStatus<Scalar> *overallSolveStatus
00310 )
00311 {
00312 #ifdef TEUCHOS_DEBUG
00313 TEST_FOR_EXCEPT(overallSolveStatus==NULL);
00314 #endif
00315 switch(solveStatus.solveStatus) {
00316 case SOLVE_STATUS_UNCONVERGED:
00317 {
00318
00319
00320 overallSolveStatus->solveStatus = SOLVE_STATUS_UNCONVERGED;
00321 overallSolveStatus->message = solveStatus.message;
00322 overallSolveStatus->extraParameters = solveStatus.extraParameters;
00323 break;
00324 }
00325 case SOLVE_STATUS_UNKNOWN:
00326 {
00327
00328
00329
00330 switch(overallSolveStatus->solveStatus) {
00331 case SOLVE_STATUS_CONVERGED:
00332 overallSolveStatus->solveStatus = SOLVE_STATUS_UNKNOWN;
00333 break;
00334 case SOLVE_STATUS_UNCONVERGED:
00335 case SOLVE_STATUS_UNKNOWN:
00336
00337
00338 overallSolveStatus->message = solveStatus.message;
00339 overallSolveStatus->extraParameters = solveStatus.extraParameters;
00340 break;
00341 default:
00342 TEST_FOR_EXCEPT(true);
00343 }
00344 break;
00345 }
00346 case SOLVE_STATUS_CONVERGED:
00347 {
00348
00349
00350 if(overallSolveStatus->message == "")
00351 overallSolveStatus->message = solveStatus.message;
00352 break;
00353 }
00354 default:
00355 TEST_FOR_EXCEPT(true);
00356 }
00357
00358 if( solveStatus.achievedTol > overallSolveStatus->achievedTol ) {
00359 overallSolveStatus->achievedTol = solveStatus.achievedTol;
00360 }
00361
00362 if(overallSolveStatus->message == "")
00363 overallSolveStatus->message = solveStatus.message;
00364
00365 if(overallSolveStatus->extraParameters.get()==NULL)
00366 overallSolveStatus->extraParameters = solveStatus.extraParameters;
00367 }
00368
00369 }
00370
00371 #endif // THYRA_SOLVE_SUPPORT_TYPES_HPP