Belos Package Browser (Single Doxygen Collection) Development
Loading...
Searching...
No Matches
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
88namespace Belos {
89
90template <class ScalarType, class MV, class OP>
91class 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
111 SEQ
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
186protected:
187
189
190
191 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
208
210
212 st_vector tests_;
213
217
218};
219
220template <class ScalarType, class MV, class OP>
222{
223 type_ = t;
224 status_ = Undefined;
225}
226
227template <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
236template <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
247template <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
265template <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
284template <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
299template <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
313template <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
329template <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
359template <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
382template <class ScalarType, class MV, class OP>
383void 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 */
Pure virtual base class for defining the status testing capabilities of Belos.
A class for extending the status testing capabilities of Belos via logical combinations.
void seqOp(Iteration< ScalarType, MV, OP > *iSolver)
Use this for checkStatus when this is a sequential AND type combo. Updates status.
ComboType
The test can be either the AND of all the component tests, or the OR of all the component tests,...
void andOp(Iteration< ScalarType, MV, OP > *iSolver)
Use this for checkStatus when this is an AND type combo. Updates status.
StatusType status_
The current status.
ComboType getComboType() const
Return the type of combination (OR, AND, or SEQ).
StatusType getStatus() const
Return the result of the most recent checkStatus call.
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.
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 type_
The type of combination (OR, AND, or SEQ)
StatusTestCombo< ScalarType, MV, OP > & addStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &add_test)
Add another test to this combination.
StatusType checkStatus(Iteration< ScalarType, MV, OP > *iSolver)
Check convergence status of the iterative solver.
StatusTestCombo(ComboType t)
Constructor.
virtual ~StatusTestCombo()
Destructor.
void print(std::ostream &os, int indent=0) const
Output formatted description of stopping test to output stream.
st_vector getStatusTests()
Return the vector of status tests.
void reset()
Resets all the status tests in this combination to their initial internal state.
A pure virtual class for defining the status tests for the Belos iterative solvers.
StatusType
Whether the StatusTest wants iteration to stop.
Definition: BelosTypes.hpp:189
@ Undefined
Definition: BelosTypes.hpp:191