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
00030
00031 #ifndef BELOS_STATUS_TEST_COMBO_H
00032 #define BELOS_STATUS_TEST_COMBO_H
00033
00039 #include "BelosStatusTest.hpp"
00040 #include <vector>
00041
00073 namespace Belos {
00074
00075 template <class ScalarType, class MV, class OP>
00076 class StatusTestCombo: public StatusTest<ScalarType,MV,OP> {
00077
00078 public:
00079
00080 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00081
00082 typedef std::vector< StatusTest<ScalarType,MV,OP>* > st_vector;
00083 typedef typename st_vector::iterator iterator;
00084 typedef typename st_vector::const_iterator const_iterator;
00085
00086 #endif // DOXYGEN_SHOULD_SKIP_THIS
00087
00089
00090
00094 enum ComboType {AND,
00095 OR,
00096 SEQ
00098 };
00100
00102
00103
00105 StatusTestCombo(ComboType t);
00106
00108 StatusTestCombo(ComboType t, StatusTest<ScalarType,MV,OP>& test1);
00109
00111 StatusTestCombo(ComboType t, StatusTest<ScalarType,MV,OP>& test1, StatusTest<ScalarType,MV,OP>& test2);
00112
00114 StatusTestCombo<ScalarType,MV,OP>& AddStatusTest(StatusTest<ScalarType,MV,OP>& add_test);
00115
00117 virtual ~StatusTestCombo() {};
00119
00121
00122
00124
00127 StatusType CheckStatus( IterativeSolver<ScalarType,MV,OP>* iSolver );
00128
00130 StatusType GetStatus() const { return(status_); };
00131
00133
00135
00136
00138
00140 void Reset();
00141
00143
00145
00146
00148 ComboType GetComboType() const {return(type_);};
00149
00151
00153
00154
00156
00159 bool ResidualVectorRequired() const;
00160
00162
00163
00164
00166 ostream& Print(ostream& os, int indent = 0) const;
00167
00169
00170 protected:
00171
00173
00174
00175 void OrOp( IterativeSolver<ScalarType,MV,OP>* iSolver );
00176
00178 void AndOp( IterativeSolver<ScalarType,MV,OP>* iSolver );
00179
00181 void SeqOp( IterativeSolver<ScalarType,MV,OP>* iSolver );
00182
00185 bool IsSafe(StatusTest<ScalarType,MV,OP>& test1);
00187
00188 private:
00189
00191
00192
00193 ComboType type_;
00194
00196 st_vector tests_;
00197
00199 StatusType status_;
00201
00202 };
00203
00204 template <class ScalarType, class MV, class OP>
00205 StatusTestCombo<ScalarType,MV,OP>::StatusTestCombo(ComboType t)
00206 {
00207 type_ = t;
00208 status_ = Unchecked;
00209 }
00210
00211 template <class ScalarType, class MV, class OP>
00212 StatusTestCombo<ScalarType,MV,OP>::StatusTestCombo(ComboType t, StatusTest<ScalarType,MV,OP>& test1)
00213 {
00214 type_ = t;
00215 tests_.push_back(&test1);
00216 status_ = Unchecked;
00217 }
00218
00219 template <class ScalarType, class MV, class OP>
00220 StatusTestCombo<ScalarType,MV,OP>::StatusTestCombo(ComboType t, StatusTest<ScalarType,MV,OP>& test1, StatusTest<ScalarType,MV,OP>& test2)
00221 {
00222 type_ = t;
00223 tests_.push_back(&test1);
00224 AddStatusTest(test2);
00225 status_ = Unchecked;
00226 }
00227
00228 template <class ScalarType, class MV, class OP>
00229 StatusTestCombo<ScalarType,MV,OP>& StatusTestCombo<ScalarType,MV,OP>::AddStatusTest(StatusTest<ScalarType,MV,OP>& add_test)
00230 {
00231 if (IsSafe(add_test))
00232 tests_.push_back(&add_test);
00233 else
00234 {
00235 const int indent = 2;
00236 cout << "\n*** WARNING! ***\n";
00237 cout << "This combo test currently consists of the following:\n";
00238 this->Print(cout, indent);
00239 cout << "Unable to add the following test:\n";
00240 add_test.Print(cout, indent);
00241 cout << "\n";
00242 }
00243 return *this;
00244 }
00245
00246 template <class ScalarType, class MV, class OP>
00247 bool StatusTestCombo<ScalarType,MV,OP>::IsSafe(StatusTest<ScalarType,MV,OP>& test1)
00248 {
00249
00250 if (&test1 == this)
00251 return false;
00252
00253
00254
00255 for (iterator i = tests_.begin(); i != tests_.end(); ++i) {
00256
00257 StatusTestCombo<ScalarType,MV,OP>* ptr = dynamic_cast< StatusTestCombo<ScalarType,MV,OP> *>(*i);
00258 if (ptr != NULL)
00259 if (!ptr->IsSafe(test1))
00260 return false;
00261 }
00262 return true;
00263 }
00264
00265 template <class ScalarType, class MV, class OP>
00266 bool StatusTestCombo<ScalarType,MV,OP>::ResidualVectorRequired() const
00267 {
00268
00269
00270
00271 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i) {
00272
00273 StatusTest<ScalarType,MV,OP>* ptr = dynamic_cast< StatusTest<ScalarType,MV,OP> *>(*i);
00274 if (ptr != NULL)
00275 if (ptr->ResidualVectorRequired())
00276 return true;
00277 }
00278
00279
00280 return false;
00281 }
00282
00283 template <class ScalarType, class MV, class OP>
00284 StatusType StatusTestCombo<ScalarType,MV,OP>::CheckStatus( IterativeSolver<ScalarType,MV,OP>* iSolver )
00285 {
00286 status_ = Unconverged;
00287
00288 if (type_ == OR)
00289 OrOp( iSolver );
00290 else if (type_ == AND)
00291 AndOp( iSolver );
00292 else
00293 SeqOp( iSolver );
00294
00295 return status_;
00296 }
00297
00298 template <class ScalarType, class MV, class OP>
00299 void StatusTestCombo<ScalarType,MV,OP>::Reset( )
00300 {
00301
00302 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i)
00303 {
00304 (*i)->Reset();
00305 }
00306
00307 status_ = Unchecked;
00308
00309 return;
00310 }
00311
00312 template <class ScalarType, class MV, class OP>
00313 void StatusTestCombo<ScalarType,MV,OP>::OrOp( IterativeSolver<ScalarType,MV,OP>* iSolver )
00314 {
00315 bool isFailed = false;
00316
00317
00318
00319 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i)
00320 {
00321 StatusType s = (*i)->CheckStatus( iSolver );
00322
00323
00324 if (s==Failed || s==NaN) isFailed = true;
00325
00326 if ((status_ == Unconverged) && (s != Unconverged)) {
00327 status_ = s;
00328 }
00329 }
00330
00331
00332 if (isFailed) status_ = Failed;
00333
00334 return;
00335 }
00336
00337 template <class ScalarType, class MV, class OP>
00338 void StatusTestCombo<ScalarType,MV,OP>::AndOp( IterativeSolver<ScalarType,MV,OP>* iSolver )
00339 {
00340 bool isUnconverged = false;
00341 bool isFailed = false;
00342
00343 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i) {
00344
00345 StatusType s = (*i)->CheckStatus( iSolver );
00346
00347
00348 if (s==Failed || s==NaN) isFailed = true;
00349
00350
00351
00352 if (s == Unconverged) {
00353 isUnconverged = true;
00354 status_ = Unconverged;
00355 }
00356
00357
00358
00359 if ((!isUnconverged) && (status_ == Unconverged)) {
00360 status_ = s;
00361 }
00362 }
00363
00364
00365 if (isFailed) status_ = Failed;
00366
00367 return;
00368 }
00369
00370 template <class ScalarType, class MV, class OP>
00371 void StatusTestCombo<ScalarType,MV,OP>::SeqOp( IterativeSolver<ScalarType,MV,OP>* iSolver )
00372 {
00373 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i) {
00374
00375 StatusType s = (*i)->CheckStatus( iSolver );
00376
00377
00378 if (s==Failed || s==NaN) {
00379 status_ = Failed;
00380 return;
00381 }
00382 else if (s==Unconverged) {
00383 status_ = s;
00384 return;
00385 }
00386 }
00387
00388 status_ = Converged;
00389
00390 return;
00391 }
00392
00393 template <class ScalarType, class MV, class OP>
00394 ostream& StatusTestCombo<ScalarType,MV,OP>::Print(ostream& os, int indent) const {
00395 for (int j = 0; j < indent; j ++)
00396 os << ' ';
00397 this->PrintStatus(os, status_);
00398 os << ((type_ == OR) ? "OR" : (type_ == AND) ? "AND" :"SEQ");
00399 os << " Combination";
00400 os << " -> " << endl;
00401
00402 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i)
00403 (*i)->Print(os, indent+2);
00404
00405 return os;
00406 }
00407
00408 }
00409
00410 #endif