Belos Package Browser (Single Doxygen Collection)  Development
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 
124  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& test1);
125 
128  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& test1,
129  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& test2);
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>
229  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& test1)
230 {
231  type_ = t;
232  tests_.push_back(test1);
233  status_ = Undefined;
234 }
235 
236 template <class ScalarType, class MV, class OP>
238  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& test1,
239  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> >& test2)
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.
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.
void print(std::ostream &os, int indent=0) const
Output formatted description of stopping test to output stream.
StatusType getStatus() const
Return the result of the most recent checkStatus call.
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:188
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.
StatusTestCombo(ComboType t)
Constructor.
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.
ComboType getComboType() const
Return the type of combination (OR, AND, or SEQ).
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.