Belos Package Browser (Single Doxygen Collection) Development
BelosStatusTestResNormOutput.hpp
Go to the documentation of this file.
00001 //@HEADER
00002 // ************************************************************************
00003 //
00004 //                 Belos: Block Linear Solvers Package
00005 //                  Copyright 2004 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 Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ************************************************************************
00040 //@HEADER
00041 //
00042 
00043 #ifndef BELOS_STATUS_TEST_RESNORM_OUTPUT_HPP
00044 #define BELOS_STATUS_TEST_RESNORM_OUTPUT_HPP
00045 
00051 #include <vector>
00052 #include "BelosConfigDefs.hpp"
00053 #include "BelosTypes.hpp"
00054 #include "BelosIteration.hpp"
00055 
00056 #include "BelosStatusTest.hpp"
00057 #include "BelosStatusTestCombo.hpp"
00058 #include "BelosStatusTestMaxIters.hpp"
00059 #include "BelosStatusTestResNorm.hpp"
00060 #include "BelosStatusTestOutput.hpp"
00061 
00062 namespace Belos {
00063 
00073 template <class ScalarType, class MV, class OP>
00074 class StatusTestResNormOutput : public StatusTestOutput<ScalarType,MV,OP> {
00075 
00076   typedef MultiVecTraits<ScalarType,MV> MVT;
00077   typedef Belos::StatusTestCombo<ScalarType,MV,OP>  StatusTestCombo_t;
00078   typedef Belos::StatusTestResNorm<ScalarType,MV,OP>  StatusTestResNorm_t;
00079   typedef Belos::StatusTestMaxIters<ScalarType,MV,OP>  StatusTestMaxIters_t;
00080 
00081  public:
00083 
00084 
00100   StatusTestResNormOutput(const Teuchos::RCP<OutputManager<ScalarType> > &printer, 
00101       Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test,
00102       int mod = 1,
00103       int printStates = Passed)
00104     : printer_(printer), 
00105       state_(Undefined), 
00106       headerPrinted_(false),
00107       stateTest_(printStates), 
00108       modTest_(mod), 
00109       lastNumIters_(-1),
00110       comboType_(0),
00111       numResTests_(0),
00112       blockSize_(1),
00113       currNumRHS_(0),
00114       currLSNum_(0),
00115       numLSDgts_(1), 
00116       numIterDgts_(1)
00117     {
00118       // Set the input test.
00119       setChild(test);
00120     }
00121 
00123   virtual ~StatusTestResNormOutput() {};
00125 
00127 
00128 
00145   StatusType checkStatus( Iteration<ScalarType,MV,OP>* solver ) 
00146   {
00147     TEUCHOS_TEST_FOR_EXCEPTION(iterTest_ == Teuchos::null,StatusTestError,"StatusTestResNormOutput::checkStatus():  iteration test pointer is null.");
00148     TEUCHOS_TEST_FOR_EXCEPTION(resTestVec_.size() == 0,StatusTestError,"StatusTestResNormOutput::checkStatus():  residual test pointer is null.");
00149     state_ = test_->checkStatus(solver);
00150 
00151     // Update some information for the header, if it has not printed or the linear system has changed.
00152     LinearProblem<ScalarType,MV,OP> currProb = solver->getProblem();
00153     //if (!headerPrinted_ || currLSNum_ != currProb.getLSNumber()) {
00154     if (currLSNum_ != currProb.getLSNumber()) {
00155       currLSNum_ = currProb.getLSNumber();
00156       blockSize_ = solver->getBlockSize();
00157       currIdx_ = currProb.getLSIndex();
00158       currNumRHS_ = currIdx_.size();
00159       numLSDgts_ = (int)std::floor((double)MVT::GetNumberVecs(*(currProb.getRHS())))+1;
00160       numIterDgts_ = (int)std::floor(std::log10((double)iterTest_->getMaxIters()))+1;
00161     }
00162     // Print out current iteration information if it hasn't already been printed, or the status has changed
00163     if (((iterTest_->getNumIters() % modTest_ == 0) && (iterTest_->getNumIters()!=lastNumIters_)) || (state_ == Passed)) {
00164       lastNumIters_ = iterTest_->getNumIters();
00165       if ( (state_ & stateTest_) == state_) {
00166         if ( printer_->isVerbosity(StatusTestDetails) ) {
00167           print( printer_->stream(StatusTestDetails) );
00168         }
00169         else if ( printer_->isVerbosity(Debug) ) {
00170           print( printer_->stream(Debug) );
00171         }
00172       }
00173     }
00174 
00175     return state_;
00176   }
00177 
00179   StatusType getStatus() const {
00180     return state_;
00181   }
00183 
00184 
00186 
00187 
00190   void setOutputManager(const Teuchos::RCP<OutputManager<ScalarType> > &printer) { printer_ = printer; }
00191 
00194   void setOutputFrequency(int mod) { modTest_ = mod; }
00195 
00200   void setChild(Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test) {
00201 
00202     // First check to see if this test is a combination test
00203     Teuchos::RCP<StatusTestCombo_t> comboTest = Teuchos::rcp_dynamic_cast<StatusTestCombo_t>(test);
00204     TEUCHOS_TEST_FOR_EXCEPTION(comboTest == Teuchos::null,StatusTestError,"StatusTestResNormOutput():  test must be a Belos::StatusTestCombo.");
00205     std::vector<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > tmpVec = comboTest->getStatusTests();
00206     
00207     // Get the number of tests.
00208     int numTests = tmpVec.size();
00209 
00210     // Find the maximum iteration and residual tests
00211     for (int i=0; i<numTests; ++i) {
00212       
00213       // Check if this is a maximum iteration test.
00214       Teuchos::RCP<StatusTestMaxIters_t> tmpItrTest = Teuchos::rcp_dynamic_cast<StatusTestMaxIters_t>(tmpVec[i]);
00215       if (tmpItrTest != Teuchos::null) {
00216         iterTest_ = tmpItrTest;
00217         continue;
00218       }
00219 
00220       // Check if this is a single residual test
00221       Teuchos::RCP<StatusTestResNorm_t> tmpResTest = Teuchos::rcp_dynamic_cast<StatusTestResNorm_t>(tmpVec[i]);
00222       // If the residual status test is a single test, put in the vector
00223       if (tmpResTest != Teuchos::null) {
00224   numResTests_ = 1;
00225         resTestVec_.resize( numResTests_ );
00226   resTestVec_[0] = tmpResTest;
00227         continue;
00228       }
00229   
00230       // Check if the residual test is a combination of several StatusTestResNorm objects.
00231       Teuchos::RCP<StatusTestCombo_t> tmpComboTest = Teuchos::rcp_dynamic_cast<StatusTestCombo_t>(tmpVec[i]);
00232       TEUCHOS_TEST_FOR_EXCEPTION(tmpComboTest == Teuchos::null,StatusTestError,"StatusTestResNormOutput():  test must be Belos::StatusTest[MaxIters|ResNorm|Combo].");
00233       tmpVec = tmpComboTest->getStatusTests();
00234       comboType_ = tmpComboTest->getComboType();
00235       numResTests_ = tmpVec.size();
00236       resTestVec_.resize( numResTests_ );
00237       for (int j=0; j<numResTests_; ++j) {
00238   tmpResTest = Teuchos::rcp_dynamic_cast<StatusTestResNorm_t>(tmpVec[j]);
00239   TEUCHOS_TEST_FOR_EXCEPTION(tmpResTest == Teuchos::null,StatusTestError,"StatusTestResNormOutput():  test must be a vector of Belos::StatusTestResNorm.");
00240   resTestVec_[j] = tmpResTest;
00241       }
00242     }
00243 
00244     // Keep the pointer to the new test and reset the state to Undefined.
00245     test_ = test;
00246     state_ = Undefined;
00247 
00248   }
00249  
00251   Teuchos::RCP<StatusTest<ScalarType,MV,OP> > getChild() const {
00252     return test_;
00253   }
00254 
00257   void setSolverDesc(const std::string& solverDesc) { solverDesc_ = solverDesc; }
00258 
00261   void setPrecondDesc(const std::string& precondDesc) { precondDesc_ = precondDesc; }
00263 
00264 
00266 
00267 
00272   void reset() { 
00273     state_ = Undefined;
00274     test_->reset();
00275     lastNumIters_ = -1;
00276     headerPrinted_ = false;
00277   }
00278 
00280 
00283   void resetNumCalls() {}
00284 
00286 
00288 
00289   
00291   void print(std::ostream& os, int indent = 0) const {
00292     std::string ind(indent,' ');
00293     std::string starLine(55,'*');
00294     std::string starFront(5,'*');
00295 
00296     os.setf(std::ios::scientific, std::ios::floatfield);
00297     os.precision(6);
00298     
00299     // Print header if this is the first call to this output status test.
00300     if (!headerPrinted_) {
00301       os << std::endl << ind << starLine << std::endl;
00302       os << ind << starFront << " Belos Iterative Solver: " << solverDesc_ << std::endl;
00303       if (precondDesc_ != "")
00304         os << ind << starFront << " Preconditioner: " << precondDesc_ << std::endl;
00305       os << ind << starFront << " Maximum Iterations: " << iterTest_->getMaxIters() << std::endl;
00306       os << ind << starFront << " Block Size: " << blockSize_ << std::endl;
00307       if (numResTests_ > 1) {
00308         os << ind << starFront << " Residual Tests (" 
00309            << ((comboType_ == StatusTestCombo_t::OR) ? "OR" : (comboType_ == StatusTestCombo_t::AND) ? "AND" :"SEQ")
00310            << "): " << std::endl;
00311       } else {
00312         os << ind << starFront << " Residual Test: " << std::endl;
00313       } 
00314       for (int i=0; i<numResTests_; ++i) {
00315         os << ind << starFront << "   Test " << i+1 << " : " << resTestVec_[i]->description() << std::endl;
00316       }
00317       os << ind << starLine << std::endl;
00318       headerPrinted_ = true;
00319     }
00320 
00321     // Print out residuals for each residual test.
00322     os.setf(std::ios_base::right, std::ios_base::adjustfield);
00323     std::string ind2( 7 + numIterDgts_, ' ' );
00324     os << ind << "Iter " << std::setw(numIterDgts_) << iterTest_->getNumIters() << ", ";
00325     for (int i=0; i<currNumRHS_; ++i) {
00326       if ( i > 0 && currIdx_[i]!=-1 ) {
00327         // Put in space where 'Iter :' is in the previous lines
00328         os << ind << ind2;
00329       }
00330       os << "[" << std::setw(numLSDgts_) << currIdx_[i]+1 << "] : ";
00331       for (int j=0; j<numResTests_; ++j) {
00332         if ( resTestVec_[j]->getStatus() != Undefined && currIdx_[i]!=-1 ) {
00333           os << std::setw(15) << (*resTestVec_[j]->getTestValue())[currIdx_[i]];
00334         } else {
00335           os << std::setw(15) << "---"; 
00336         }
00337       }
00338       os << std::endl;
00339     }
00340   }
00341  
00343 
00344   private:
00345     // Output manager.
00346     Teuchos::RCP<OutputManager<ScalarType> > printer_;
00347 
00348     // Overall status test.
00349     Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test_;
00350 
00351     // Iteration test (as passed in).
00352     Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > iterTest_;
00353 
00355     std::vector<Teuchos::RCP<StatusTestResNorm<ScalarType,MV,OP> > > resTestVec_;
00356 
00357     std::string solverDesc_;
00358     std::string precondDesc_;
00359     std::vector<int> currIdx_;
00360     StatusType state_;
00361     mutable bool headerPrinted_;
00362     int stateTest_, modTest_;
00363     int lastNumIters_, comboType_;
00364     int numResTests_, blockSize_;
00365     int currNumRHS_, currLSNum_;
00366     int numLSDgts_, numIterDgts_;
00367 };
00368 
00369 } // end of Belos namespace
00370 
00371 #endif /* BELOS_STATUS_TEST_RESNORM_OUTPUT_HPP */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines