NOX_StatusTest_SafeCombo.H
Go to the documentation of this file.
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

Site Contact