Belos Version of the Day
Loading...
Searching...
No Matches
BelosStatusTestCombo.hpp
Go to the documentation of this file.
1
2// @HEADER
3// *****************************************************************************
4// Belos: Block Linear Solvers Package
5//
6// Copyright 2004-2016 NTESS and the Belos contributors.
7// SPDX-License-Identifier: BSD-3-Clause
8// *****************************************************************************
9// @HEADER
10//
11
12#ifndef BELOS_STATUS_TEST_COMBO_H
13#define BELOS_STATUS_TEST_COMBO_H
14
19
20#include "BelosStatusTest.hpp"
21#include <vector>
22
55
56namespace Belos {
57
58template <class ScalarType, class MV, class OP, class DM = DefaultDenseMatrix<int,ScalarType>>
59class StatusTestCombo: public StatusTest<ScalarType,MV,OP,DM> {
60
61 public:
62
63#ifndef DOXYGEN_SHOULD_SKIP_THIS
64
65 typedef std::vector< Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > > st_vector;
66 typedef typename st_vector::iterator iterator;
67 typedef typename st_vector::const_iterator const_iterator;
68
69#endif // DOXYGEN_SHOULD_SKIP_THIS
70
72
73
77 enum ComboType {AND,
81 };
83
85
86
89
92 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> >& test1);
93
96 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> >& test1,
97 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> >& test2);
98
103
105 virtual ~StatusTestCombo() {};
107
109
110
117
121 StatusType getStatus() const { return(status_); };
122
124
126
127
129
131 void reset();
132
134
136
137
139 ComboType getComboType() const { return type_; }
140
142 st_vector getStatusTests() { return tests_; }
143
145
147
148
150 void print(std::ostream& os, int indent = 0) const;
151
153
154protected:
155
157
158
160
163
166
169 bool isSafe( const Teuchos:: RCP<StatusTest<ScalarType,MV,OP,DM> >& test1);
171
172 private:
173
175
176
177 ComboType type_;
178
180 st_vector tests_;
181
183 StatusType status_;
185
186};
187
188template <class ScalarType, class MV, class OP, class DM>
194
195template <class ScalarType, class MV, class OP, class DM>
197 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> >& test1)
198{
199 type_ = t;
200 tests_.push_back(test1);
201 status_ = Undefined;
202}
203
204template <class ScalarType, class MV, class OP, class DM>
206 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> >& test1,
207 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> >& test2)
208{
209 type_ = t;
210 tests_.push_back(test1);
211 addStatusTest(test2);
212 status_ = Undefined;
213}
214
215template <class ScalarType, class MV, class OP, class DM>
217{
218 if (isSafe(add_test))
219 tests_.push_back(add_test);
220 else
221 {
222 const int indent = 2;
223 std::cout << "\n*** WARNING! ***\n";
224 std::cout << "This combo test currently consists of the following:\n";
225 this->print(std::cout, indent);
226 std::cout << "Unable to add the following test:\n";
227 add_test->print(std::cout, indent);
228 std::cout << "\n";
229 }
230 return *this;
231}
232
233template <class ScalarType, class MV, class OP, class DM>
235{
236 // Are we trying to add "this" to "this"? This would result in an infinite recursion.
237 if (test1.get() == this)
238 return false;
239
240 // Recursively test that we're not adding something that's already
241 // in the list because that can also lead to infinite recursions.
242 for (iterator i = tests_.begin(); i != tests_.end(); ++i) {
243
245 if (ptr != NULL)
246 if (!ptr->isSafe(test1))
247 return false;
248 }
249 return true;
250}
251
252template <class ScalarType, class MV, class OP, class DM>
254{
255 status_ = Failed;
256
257 if (type_ == OR)
258 orOp( iSolver );
259 else if (type_ == AND)
260 andOp( iSolver );
261 else
262 seqOp( iSolver );
263
264 return status_;
265}
266
267template <class ScalarType, class MV, class OP, class DM>
269{
270 // Resets all status tests in my list.
271 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i)
272 {
273 (*i)->reset();
274 }
275 // Reset my status.
276 status_ = Undefined;
277 //
278 return;
279}
280
281template <class ScalarType, class MV, class OP, class DM>
283{
284 status_ = Failed;
285
286 // Checks the status of each test. The first test it encounters, if
287 // any, that is unconverged is the status that it sets itself too.
288 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i)
289 {
290 StatusType s = (*i)->checkStatus( iSolver );
291
292 // Check for failure.
293 if (s==Passed) status_ = Passed;
294 }
295}
296
297template <class ScalarType, class MV, class OP, class DM>
299{
300 bool isFailed = false;
301
302 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i) {
303
304 StatusType s = (*i)->checkStatus( iSolver );
305
306 // Check for failure.
307 if (s==Failed) isFailed = true;
308
309 // If any of the tests are failed, then the AND test is failed.
310 if (s == Failed) {
311 status_ = Failed;
312 }
313
314 // If this is the first test and it's failed, copy its
315 // status to the combo status.
316 if ((!isFailed) && (status_ == Failed)) {
317 status_ = s;
318 }
319 }
320
321 // Any failure is a complete failure
322 if (isFailed) status_ = Failed;
323
324 return;
325}
326
327template <class ScalarType, class MV, class OP, class DM>
329{
330 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i) {
331
332 StatusType s = (*i)->checkStatus( iSolver );
333
334 // Check for failure.
335 if (s==Failed) {
336 status_ = Failed;
337 return;
338 }
339 else if (s==Undefined) {
340 status_ = s;
341 return;
342 }
343 }
344 // If we make it here, we have converged
345 status_ = Passed;
346
347 return;
348}
349
350template <class ScalarType, class MV, class OP, class DM>
351void StatusTestCombo<ScalarType,MV,OP,DM>::print(std::ostream& os, int indent) const {
352 for (int j = 0; j < indent; j ++)
353 os << ' ';
354 this->printStatus(os, status_);
355 os << ((type_ == OR) ? "OR" : (type_ == AND) ? "AND" :"SEQ");
356 os << " Combination";
357 os << " -> " << std::endl;
358
359 for (const_iterator i = tests_.begin(); i != tests_.end(); ++i)
360 (*i)->print(os, indent+2);
361}
362
363} // end namespace Belos
364
365#endif /* BELOS_STATUS_TEST_COMBO_H */
Pure virtual base class for defining the status testing capabilities of Belos.
StatusType checkStatus(Iteration< ScalarType, MV, OP, DM > *iSolver)
Check convergence status of the iterative solver.
StatusType getStatus() const
Return the result of the most recent checkStatus call.
bool isSafe(const Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > &test1)
StatusTestCombo(ComboType t, const Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > &test1)
Single test constructor.
void seqOp(Iteration< ScalarType, MV, OP, DM > *iSolver)
Use this for checkStatus when this is a sequential AND type combo. Updates status.
StatusTestCombo(ComboType t, const Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > &test1, const Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > &test2)
Dual test constructor.
void print(std::ostream &os, int indent=0) const
Output formatted description of stopping test to output stream.
StatusTestCombo(ComboType t)
Constructor.
void andOp(Iteration< ScalarType, MV, OP, DM > *iSolver)
Use this for checkStatus when this is an AND type combo. Updates status.
void reset()
Resets all the status tests in this combination to their initial internal state.
StatusTestCombo< ScalarType, MV, OP, DM > & addStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > &add_test)
Add another test to this combination.
st_vector getStatusTests()
Return the vector of status tests.
virtual ~StatusTestCombo()
Destructor.
void orOp(Iteration< ScalarType, MV, OP, DM > *iSolver)
Use this for checkStatus when this is an OR type combo. Updates status.
ComboType getComboType() const
Return the type of combination (OR, AND, or SEQ).
StatusTest()
Constructor.
virtual void printStatus(std::ostream &os, StatusType type) const
Output the result of the most recent CheckStatus call.
StatusType
Whether the StatusTest wants iteration to stop.

Generated for Belos by doxygen 1.15.0