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