00001 // $Id$ 00002 // $Source$ 00003 00004 //@HEADER 00005 // ************************************************************************ 00006 // 00007 // NOX: An Object-Oriented Nonlinear Solver Package 00008 // Copyright (2002) Sandia Corporation 00009 // 00010 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00011 // license for use of this work by or on behalf of the U.S. Government. 00012 // 00013 // This library is free software; you can redistribute it and/or modify 00014 // it under the terms of the GNU Lesser General Public License as 00015 // published by the Free Software Foundation; either version 2.1 of the 00016 // License, or (at your option) any later version. 00017 // 00018 // This library is distributed in the hope that it will be useful, but 00019 // WITHOUT ANY WARRANTY; without even the implied warranty of 00020 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00021 // Lesser General Public License for more details. 00022 // 00023 // You should have received a copy of the GNU Lesser General Public 00024 // License along with this library; if not, write to the Free Software 00025 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00026 // USA 00027 // Questions? Contact Tammy Kolda (tgkolda@sandia.gov) or Roger Pawlowski 00028 // (rppawlo@sandia.gov), Sandia National Laboratories. 00029 // 00030 // ************************************************************************ 00031 //@HEADER 00032 00033 #ifndef NOX_STATUSTEST_SAFECOMBO_H 00034 #define NOX_STATUSTEST_SAFECOMBO_H 00035 00036 #include "NOX_StatusTest_Generic.H" // base class 00037 #include "NOX_Common.H" // class data element (vector) 00038 #include "Teuchos_RefCountPtr.hpp" 00039 00040 namespace NOX { 00041 00042 namespace StatusTest { 00043 00044 /*! 00045 \brief Arbitrary combination of status tests, implemented with safe memory management. 00046 00047 In the \c AND (see NOX::StatusTest::Combo::ComboType) combination, the 00048 result is \c Unconverged (see NOX::StatusTest::StatusType) if \e any of 00049 the tests is \c Unconverged. Otherwise, the result is equal to the 00050 result of the \e first test in the list that is either \c Converged 00051 or \c Failed. It is not recommended to mix \c Converged and \c 00052 Failed tests in an \c AND combination. 00053 00054 In the \c OR combination, the result is \c Unconverged if \e all of 00055 the tests are \c Unconverged. Otherwise, it is the result of the \e 00056 first test in the list that is either \c Converged or \c 00057 Failed. Therefore, it will generally make sense to put the \c Failed 00058 -type tests at the end of the \c OR list. 00059 00060 \note We call checkStatus on \e every convergence test, though some 00061 may be called with the NOX::StatusTest::None option. 00062 00063 \note This is identical in operation to StatusTest::Combo. but stores 00064 the constituent subtests using a reference-counted pointer. This ensures 00065 safe behavior if the constituent subtests go out of scope before the combo. 00066 - KL 24 August 2004. 00067 00068 \author Tammy Kolda (SNL 8950) 00069 \author Kevin Long (SNL 8962) 00070 */ 00071 class SafeCombo : public Generic { 00072 00073 public: 00074 00075 /*! 00076 \brief The test can be either the AND of all the component tests, 00077 or the OR of all the component tests. 00078 */ 00079 enum ComboType { 00080 //! Logically "AND" together the results of the tests in this combination 00081 AND, 00082 //! Logically "OR" together the results of the tests in this combination 00083 OR 00084 }; 00085 00086 //! Constructor 00087 SafeCombo(ComboType t); 00088 00089 //! Constructor with a single test. 00090 SafeCombo(ComboType t, const Teuchos::RCP<Generic>& a); 00091 00092 //! Constructor with two tests. 00093 SafeCombo(ComboType t, const Teuchos::RCP<Generic>& a, 00094 const Teuchos::RCP<Generic>& b); 00095 00096 //! Add another test to this combination. 00097 /*! 00098 Calls isSafe() to determine if it is safe to add \c a to the combination. 00099 */ 00100 virtual SafeCombo& addStatusTest(const Teuchos::RCP<Generic>& a); 00101 00102 //! Destructor 00103 virtual ~SafeCombo(); 00104 00105 /*! 00106 \brief Calls checkStatus(problem, NOX::StatusTest::Minimal) 00107 */ 00108 virtual StatusType checkStatus(const NOX::Solver::Generic& problem); 00109 00110 /*! 00111 \brief Tests stopping criterion. 00112 00113 See addOp() and orOp() for details. 00114 */ 00115 #ifdef TRILINOS_6 00116 virtual StatusType checkStatusEfficiently(const NOX::Solver::Generic& problem, NOX::StatusTest::CheckType checkType); 00117 #else 00118 virtual StatusType checkStatus(const NOX::Solver::Generic& problem, NOX::StatusTest::CheckType checkType); 00119 #endif 00120 00121 virtual StatusType getStatus() const; 00122 00123 virtual ostream& print(std::ostream& stream, int indent = 0) const; 00124 00125 protected: 00126 00127 //! Use this for checkStatus when this is an OR type combo. Updates NOX::StatusTest::Combo::status. 00128 /*! 00129 If there is a combination of NOX::StatusTest::Failed and 00130 NOX::StatusTest::Converged in the tests that are OR'd together, 00131 the value of status for this test is set to the status of the 00132 first test it encounters which is not NOX::Status::Unconvered. The 00133 tests are evaluated in the order that they were added to the 00134 combination. 00135 00136 \note We compute the status of all tests in the combination for 00137 the sake of completeness, even if we could determine the status of 00138 this combination test without that check. 00139 00140 */ 00141 virtual void orOp(const Solver::Generic& problem, NOX::StatusTest::CheckType checkType); 00142 00143 //! Use this for checkStatus when this is an AND type combo. Updates NOX::StatusTest::Combo::status. 00144 /*! 00145 00146 If any tests are NOX::StatusTest::Unconverged, then the status of 00147 this test is NOX::StatusTest::Unconverged. If there is a 00148 combination of NOX::StatusTest::Failed and 00149 NOX::StatusTest::Converged in the tests that are AND'd together, 00150 the value of status for this test is set to the status of the 00151 first test it encounters. The tests are evaluated in the 00152 order that they were added to the combination. 00153 00154 \note We compute the status of all tests in the combination for 00155 the sake of completeness, even if we could determine the status of 00156 this combination test without that check. 00157 */ 00158 virtual void andOp(const Solver::Generic& problem, NOX::StatusTest::CheckType checkType); 00159 00160 /*! \brief Check whether or not it is safe to add \c a to this list 00161 of tests. 00162 00163 This is necessary to avoid any infinite recursions 00164 (i.e., a test cannot own a copy of itself). 00165 */ 00166 bool isSafe(const Teuchos::RCP<Generic>& a); 00167 00168 private: 00169 00170 //! Type of test 00171 const ComboType type; 00172 00173 //! Vector of generic status tests 00174 vector<Teuchos::RCP<Generic> > tests; 00175 00176 //! %Status 00177 StatusType status; 00178 00179 }; // class Combo 00180 00181 } // namespace Status 00182 } // namespace NOX 00183 00184 #endif