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< Teuchos::RCP<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,
00109 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& test1);
00110
00112 StatusTestCombo(ComboType t,
00113 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& test1,
00114 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& test2);
00115
00117 StatusTestCombo<ScalarType,MV,OP>& addStatusTest(const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& add_test);
00118
00120 virtual ~StatusTestCombo() {};
00122
00124
00125
00127
00130 StatusType checkStatus( Iteration<ScalarType,MV,OP>* iSolver );
00131
00133 StatusType getStatus() const { return(status_); };
00134
00136
00138
00139
00141
00143 void reset();
00144
00146
00148
00149
00151 ComboType getComboType() const {return(type_);};
00152
00154
00156
00157
00159 void print(std::ostream& os, int indent = 0) const;
00160
00162
00163 protected:
00164
00166
00167
00168 void orOp( Iteration<ScalarType,MV,OP>* iSolver );
00169
00171 void andOp( Iteration<ScalarType,MV,OP>* iSolver );
00172
00174 void seqOp( Iteration<ScalarType,MV,OP>* iSolver );
00175
00178 bool isSafe( const Teuchos:: RCP<StatusTest<ScalarType,MV,OP> >& test1);
00180
00181 private:
00182
00184
00185
00186 ComboType type_;
00187
00189 st_vector tests_;
00190
00192 StatusType status_;
00194
00195 };
00196
00197 template <class ScalarType, class MV, class OP>
00198 StatusTestCombo<ScalarType,MV,OP>::StatusTestCombo(ComboType t)
00199 {
00200 type_ = t;
00201 status_ = Undefined;
00202 }
00203
00204 template <class ScalarType, class MV, class OP>
00205 StatusTestCombo<ScalarType,MV,OP>::StatusTestCombo(ComboType t,
00206 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& test1)
00207 {
00208 type_ = t;
00209 tests_.push_back(test1);
00210 status_ = Undefined;
00211 }
00212
00213 template <class ScalarType, class MV, class OP>
00214 StatusTestCombo<ScalarType,MV,OP>::StatusTestCombo(ComboType t,
00215 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& test1,
00216 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& test2)
00217 {
00218 type_ = t;
00219 tests_.push_back(test1);
00220 addStatusTest(test2);
00221 status_ = Undefined;
00222 }
00223
00224 template <class ScalarType, class MV, class OP>
00225 StatusTestCombo<ScalarType,MV,OP>& StatusTestCombo<ScalarType,MV,OP>::addStatusTest(const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& add_test)
00226 {
00227 if (isSafe(add_test))
00228 tests_.push_back(add_test);
00229 else
00230 {
00231 const int indent = 2;
00232 std::cout << "\n*** WARNING! ***\n";
00233 std::cout << "This combo test currently consists of the following:\n";
00234 this->print(std::cout, indent);
00235 std::cout << "Unable to add the following test:\n";
00236 add_test->print(std::cout, indent);
00237 std::cout << "\n";
00238 }
00239 return *this;
00240 }
00241
00242 template <class ScalarType, class MV, class OP>
00243 bool StatusTestCombo<ScalarType,MV,OP>::isSafe( const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& test1)
00244 {
00245
00246 if (test1.get() == this)
00247 return false;
00248
00249
00250
00251 for (iterator i = tests_.begin(); i != tests_.end(); ++i) {
00252
00253 StatusTestCombo<ScalarType,MV,OP>* ptr = dynamic_cast<StatusTestCombo<ScalarType,MV,OP> *>(i->get());
00254 if (ptr != NULL)
00255 if (!ptr->isSafe(test1))
00256 return false;
00257 }
00258 return true;
00259 }
00260
00261 template <class ScalarType, class MV, class OP>
00262 StatusType StatusTestCombo<ScalarType,MV,OP>::checkStatus( Iteration<ScalarType,MV,OP>* iSolver )
00263 {
00264 status_ = Failed;
00265
00266 if (type_ == OR)
00267 orOp( iSolver );
00268 else if (type_ == AND)
00269 andOp( iSolver );
00270 else
00271 seqOp( iSolver );
00272
00273 return status_;
00274 }
00275
00276 template <class ScalarType, class MV, class OP>
00277 void StatusTestCombo<ScalarType,MV,OP>::reset( )
00278 {
00279
00280 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i)
00281 {
00282 (*i)->reset();
00283 }
00284
00285 status_ = Undefined;
00286
00287 return;
00288 }
00289
00290 template <class ScalarType, class MV, class OP>
00291 void StatusTestCombo<ScalarType,MV,OP>::orOp( Iteration<ScalarType,MV,OP>* iSolver )
00292 {
00293 status_ = Failed;
00294
00295
00296
00297 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i)
00298 {
00299 StatusType s = (*i)->checkStatus( iSolver );
00300
00301
00302 if (s==Passed) status_ = Passed;
00303 }
00304 }
00305
00306 template <class ScalarType, class MV, class OP>
00307 void StatusTestCombo<ScalarType,MV,OP>::andOp( Iteration<ScalarType,MV,OP>* iSolver )
00308 {
00309 bool isFailed = false;
00310
00311 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i) {
00312
00313 StatusType s = (*i)->checkStatus( iSolver );
00314
00315
00316 if (s==Failed) isFailed = true;
00317
00318
00319 if (s == Failed) {
00320 status_ = Failed;
00321 }
00322
00323
00324
00325 if ((!isFailed) && (status_ == Failed)) {
00326 status_ = s;
00327 }
00328 }
00329
00330
00331 if (isFailed) status_ = Failed;
00332
00333 return;
00334 }
00335
00336 template <class ScalarType, class MV, class OP>
00337 void StatusTestCombo<ScalarType,MV,OP>::seqOp( Iteration<ScalarType,MV,OP>* iSolver )
00338 {
00339 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i) {
00340
00341 StatusType s = (*i)->checkStatus( iSolver );
00342
00343
00344 if (s==Failed) {
00345 status_ = Failed;
00346 return;
00347 }
00348 else if (s==Undefined) {
00349 status_ = s;
00350 return;
00351 }
00352 }
00353
00354 status_ = Passed;
00355
00356 return;
00357 }
00358
00359 template <class ScalarType, class MV, class OP>
00360 void StatusTestCombo<ScalarType,MV,OP>::print(std::ostream& os, int indent) const {
00361 for (int j = 0; j < indent; j ++)
00362 os << ' ';
00363 this->printStatus(os, status_);
00364 os << ((type_ == OR) ? "OR" : (type_ == AND) ? "AND" :"SEQ");
00365 os << " Combination";
00366 os << " -> " << std::endl;
00367
00368 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i)
00369 (*i)->print(os, indent+2);
00370 }
00371
00372 }
00373
00374 #endif