Belos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BelosStatusTestCombo.hpp
Go to the documentation of this file.
1 
2 //@HEADER
3 // ************************************************************************
4 //
5 // Belos: Block Linear Solvers Package
6 // Copyright 2004 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ************************************************************************
41 //@HEADER
42 //
43 
44 #ifndef BELOS_STATUS_TEST_COMBO_H
45 #define BELOS_STATUS_TEST_COMBO_H
46 
52 #include "BelosStatusTest.hpp"
53 #include <vector>
54 
88 namespace Belos {
89 
90 template <class ScalarType, class MV, class OP>
91 class StatusTestCombo: public StatusTest<ScalarType,MV,OP> {
92 
93  public:
94 
95 #ifndef DOXYGEN_SHOULD_SKIP_THIS
96 
97  typedef std::vector< Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > st_vector;
98  typedef typename st_vector::iterator iterator;
99  typedef typename st_vector::const_iterator const_iterator;
100 
101 #endif // DOXYGEN_SHOULD_SKIP_THIS
102 
104 
105 
109  enum ComboType {AND,
110  OR,
113  };
115 
117 
118 
121 
125 
130 
135 
137  virtual ~StatusTestCombo() {};
139 
141 
142 
149 
153  StatusType getStatus() const { return(status_); };
154 
156 
158 
159 
161 
163  void reset();
164 
166 
168 
169 
171  ComboType getComboType() const { return type_; }
172 
174  st_vector getStatusTests() { return tests_; }
175 
177 
179 
180 
182  void print(std::ostream& os, int indent = 0) const;
183 
185 
186 protected:
187 
189 
190  void orOp( Iteration<ScalarType,MV,OP>* iSolver );
192 
194  void andOp( Iteration<ScalarType,MV,OP>* iSolver );
195 
197  void seqOp( Iteration<ScalarType,MV,OP>* iSolver );
198 
201  bool isSafe( const Teuchos:: RCP<StatusTest<ScalarType,MV,OP> >& test1);
203 
204  private:
205 
207 
210 
212  st_vector tests_;
213 
217 
218 };
219 
220 template <class ScalarType, class MV, class OP>
222 {
223  type_ = t;
224  status_ = Undefined;
225 }
226 
227 template <class ScalarType, class MV, class OP>
230 {
231  type_ = t;
232  tests_.push_back(test1);
233  status_ = Undefined;
234 }
235 
236 template <class ScalarType, class MV, class OP>
240 {
241  type_ = t;
242  tests_.push_back(test1);
243  addStatusTest(test2);
244  status_ = Undefined;
245 }
246 
247 template <class ScalarType, class MV, class OP>
249 {
250  if (isSafe(add_test))
251  tests_.push_back(add_test);
252  else
253  {
254  const int indent = 2;
255  std::cout << "\n*** WARNING! ***\n";
256  std::cout << "This combo test currently consists of the following:\n";
257  this->print(std::cout, indent);
258  std::cout << "Unable to add the following test:\n";
259  add_test->print(std::cout, indent);
260  std::cout << "\n";
261  }
262  return *this;
263 }
264 
265 template <class ScalarType, class MV, class OP>
267 {
268  // Are we trying to add "this" to "this"? This would result in an infinite recursion.
269  if (test1.get() == this)
270  return false;
271 
272  // Recursively test that we're not adding something that's already
273  // in the list because that can also lead to infinite recursions.
274  for (iterator i = tests_.begin(); i != tests_.end(); ++i) {
275 
277  if (ptr != NULL)
278  if (!ptr->isSafe(test1))
279  return false;
280  }
281  return true;
282 }
283 
284 template <class ScalarType, class MV, class OP>
286 {
287  status_ = Failed;
288 
289  if (type_ == OR)
290  orOp( iSolver );
291  else if (type_ == AND)
292  andOp( iSolver );
293  else
294  seqOp( iSolver );
295 
296  return status_;
297 }
298 
299 template <class ScalarType, class MV, class OP>
301 {
302  // Resets all status tests in my list.
303  for (const_iterator i = tests_.begin(); i != tests_.end(); ++i)
304  {
305  (*i)->reset();
306  }
307  // Reset my status.
308  status_ = Undefined;
309  //
310  return;
311 }
312 
313 template <class ScalarType, class MV, class OP>
315 {
316  status_ = Failed;
317 
318  // Checks the status of each test. The first test it encounters, if
319  // any, that is unconverged is the status that it sets itself too.
320  for (const_iterator i = tests_.begin(); i != tests_.end(); ++i)
321  {
322  StatusType s = (*i)->checkStatus( iSolver );
323 
324  // Check for failure.
325  if (s==Passed) status_ = Passed;
326  }
327 }
328 
329 template <class ScalarType, class MV, class OP>
331 {
332  bool isFailed = false;
333 
334  for (const_iterator i = tests_.begin(); i != tests_.end(); ++i) {
335 
336  StatusType s = (*i)->checkStatus( iSolver );
337 
338  // Check for failure.
339  if (s==Failed) isFailed = true;
340 
341  // If any of the tests are failed, then the AND test is failed.
342  if (s == Failed) {
343  status_ = Failed;
344  }
345 
346  // If this is the first test and it's failed, copy its
347  // status to the combo status.
348  if ((!isFailed) && (status_ == Failed)) {
349  status_ = s;
350  }
351  }
352 
353  // Any failure is a complete failure
354  if (isFailed) status_ = Failed;
355 
356  return;
357 }
358 
359 template <class ScalarType, class MV, class OP>
361 {
362  for (const_iterator i = tests_.begin(); i != tests_.end(); ++i) {
363 
364  StatusType s = (*i)->checkStatus( iSolver );
365 
366  // Check for failure.
367  if (s==Failed) {
368  status_ = Failed;
369  return;
370  }
371  else if (s==Undefined) {
372  status_ = s;
373  return;
374  }
375  }
376  // If we make it here, we have converged
377  status_ = Passed;
378 
379  return;
380 }
381 
382 template <class ScalarType, class MV, class OP>
383 void StatusTestCombo<ScalarType,MV,OP>::print(std::ostream& os, int indent) const {
384  for (int j = 0; j < indent; j ++)
385  os << ' ';
386  this->printStatus(os, status_);
387  os << ((type_ == OR) ? "OR" : (type_ == AND) ? "AND" :"SEQ");
388  os << " Combination";
389  os << " -> " << std::endl;
390 
391  for (const_iterator i = tests_.begin(); i != tests_.end(); ++i)
392  (*i)->print(os, indent+2);
393 }
394 
395 } // end namespace Belos
396 
397 #endif /* BELOS_STATUS_TEST_COMBO_H */
ComboType
The test can be either the AND of all the component tests, or the OR of all the component tests...
StatusType checkStatus(Iteration< ScalarType, MV, OP > *iSolver)
Check convergence status of the iterative solver.
Pure virtual base class for defining the status testing capabilities of Belos.
ComboType getComboType() const
Return the type of combination (OR, AND, or SEQ).
StatusType status_
The current status.
ComboType type_
The type of combination (OR, AND, or SEQ)
void seqOp(Iteration< ScalarType, MV, OP > *iSolver)
Use this for checkStatus when this is a sequential AND type combo. Updates status.
StatusTestCombo< ScalarType, MV, OP > & addStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &add_test)
Add another test to this combination.
A pure virtual class for defining the status tests for the Belos iterative solvers.
virtual ~StatusTestCombo()
Destructor.
StatusType
Whether the StatusTest wants iteration to stop.
Definition: BelosTypes.hpp:189
void andOp(Iteration< ScalarType, MV, OP > *iSolver)
Use this for checkStatus when this is an AND type combo. Updates status.
void orOp(Iteration< ScalarType, MV, OP > *iSolver)
Use this for checkStatus when this is an OR type combo. Updates status.
st_vector tests_
Vector of generic status tests.
void print(std::ostream &os, int indent=0) const
Output formatted description of stopping test to output stream.
StatusTestCombo(ComboType t)
Constructor.
StatusType getStatus() const
Return the result of the most recent checkStatus call.
bool isSafe(const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &test1)
Check whether or not it is safe to add a to the list of tests.
A class for extending the status testing capabilities of Belos via logical combinations.
st_vector getStatusTests()
Return the vector of status tests.
void reset()
Resets all the status tests in this combination to their initial internal state.