00001 /* @HEADER@ */ 00002 // ************************************************************************ 00003 // 00004 // Playa: Programmable Linear Algebra 00005 // Copyright 2012 Sandia Corporation 00006 // 00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00008 // the U.S. Government retains certain rights in this software. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu) 00038 // 00039 00040 /* @HEADER@ */ 00041 00042 00043 // $Id$ 00044 // $Source$ 00045 00046 00047 // 00048 00049 00050 #ifndef NOX_STATUSTEST_SAFECOMBO_H 00051 #define NOX_STATUSTEST_SAFECOMBO_H 00052 00053 #include "NOX_StatusTest_Generic.H" // base class 00054 #include "NOX_Common.H" // class data element (vector) 00055 #include "Teuchos_RefCountPtr.hpp" 00056 00057 namespace NOX { 00058 00059 namespace StatusTest { 00060 00061 /*! 00062 \brief Arbitrary combination of status tests, implemented with safe memory management. 00063 00064 In the \c AND (see NOX::StatusTest::Combo::ComboType) combination, the 00065 result is \c Unconverged (see NOX::StatusTest::StatusType) if \e any of 00066 the tests is \c Unconverged. Otherwise, the result is equal to the 00067 result of the \e first test in the list that is either \c Converged 00068 or \c Failed. It is not recommended to mix \c Converged and \c 00069 Failed tests in an \c AND combination. 00070 00071 In the \c OR combination, the result is \c Unconverged if \e all of 00072 the tests are \c Unconverged. Otherwise, it is the result of the \e 00073 first test in the list that is either \c Converged or \c 00074 Failed. Therefore, it will generally make sense to put the \c Failed 00075 -type tests at the end of the \c OR list. 00076 00077 \note We call checkStatus on \e every convergence test, though some 00078 may be called with the NOX::StatusTest::None option. 00079 00080 \note This is identical in operation to StatusTest::Combo. but stores 00081 the constituent subtests using a reference-counted pointer. This ensures 00082 safe behavior if the constituent subtests go out of scope before the combo. 00083 - KL 24 August 2004. 00084 00085 \author Tammy Kolda (SNL 8950) 00086 \author Kevin Long (SNL 8962) 00087 */ 00088 class SafeCombo : public Generic { 00089 00090 public: 00091 00092 /*! 00093 \brief The test can be either the AND of all the component tests, 00094 or the OR of all the component tests. 00095 */ 00096 enum ComboType { 00097 //! Logically "AND" together the results of the tests in this combination 00098 AND, 00099 //! Logically "OR" together the results of the tests in this combination 00100 OR 00101 }; 00102 00103 //! Constructor 00104 SafeCombo(ComboType t); 00105 00106 //! Constructor with a single test. 00107 SafeCombo(ComboType t, const Teuchos::RCP<Generic>& a); 00108 00109 //! Constructor with two tests. 00110 SafeCombo(ComboType t, const Teuchos::RCP<Generic>& a, 00111 const Teuchos::RCP<Generic>& b); 00112 00113 //! Add another test to this combination. 00114 /*! 00115 Calls isSafe() to determine if it is safe to add \c a to the combination. 00116 */ 00117 virtual SafeCombo& addStatusTest(const Teuchos::RCP<Generic>& a); 00118 00119 //! Destructor 00120 virtual ~SafeCombo(); 00121 00122 /*! 00123 \brief Calls checkStatus(problem, NOX::StatusTest::Minimal) 00124 */ 00125 virtual StatusType checkStatus(const NOX::Solver::Generic& problem); 00126 00127 /*! 00128 \brief Tests stopping criterion. 00129 00130 See addOp() and orOp() for details. 00131 */ 00132 #ifdef TRILINOS_6 00133 virtual StatusType checkStatusEfficiently(const NOX::Solver::Generic& problem, NOX::StatusTest::CheckType checkType); 00134 #else 00135 virtual StatusType checkStatus(const NOX::Solver::Generic& problem, NOX::StatusTest::CheckType checkType); 00136 #endif 00137 00138 virtual StatusType getStatus() const; 00139 00140 virtual std::ostream& print(std::ostream& stream, int indent = 0) const; 00141 00142 protected: 00143 00144 //! Use this for checkStatus when this is an OR type combo. Updates NOX::StatusTest::Combo::status. 00145 /*! 00146 If there is a combination of NOX::StatusTest::Failed and 00147 NOX::StatusTest::Converged in the tests that are OR'd together, 00148 the value of status for this test is set to the status of the 00149 first test it encounters which is not NOX::Status::Unconvered. The 00150 tests are evaluated in the order that they were added to the 00151 combination. 00152 00153 \note We compute the status of all tests in the combination for 00154 the sake of completeness, even if we could determine the status of 00155 this combination test without that check. 00156 00157 */ 00158 virtual void orOp(const Solver::Generic& problem, NOX::StatusTest::CheckType checkType); 00159 00160 //! Use this for checkStatus when this is an AND type combo. Updates NOX::StatusTest::Combo::status. 00161 /*! 00162 00163 If any tests are NOX::StatusTest::Unconverged, then the status of 00164 this test is NOX::StatusTest::Unconverged. If there is a 00165 combination of NOX::StatusTest::Failed and 00166 NOX::StatusTest::Converged in the tests that are AND'd together, 00167 the value of status for this test is set to the status of the 00168 first test it encounters. The tests are evaluated in the 00169 order that they were added to the combination. 00170 00171 \note We compute the status of all tests in the combination for 00172 the sake of completeness, even if we could determine the status of 00173 this combination test without that check. 00174 */ 00175 virtual void andOp(const Solver::Generic& problem, NOX::StatusTest::CheckType checkType); 00176 00177 /*! \brief Check whether or not it is safe to add \c a to this list 00178 of tests. 00179 00180 This is necessary to avoid any infinite recursions 00181 (i.e., a test cannot own a copy of itself). 00182 */ 00183 bool isSafe(const Teuchos::RCP<Generic>& a); 00184 00185 private: 00186 00187 //! Type of test 00188 const ComboType type; 00189 00190 //! Vector of generic status tests 00191 std::vector<Teuchos::RCP<Generic> > tests; 00192 00193 //! %Status 00194 StatusType status; 00195 00196 }; // class Combo 00197 00198 } // namespace Status 00199 } // namespace NOX 00200 00201 #endif