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 terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 // @HEADER
00028 //
00029 
00030 #ifndef BELOS_STATUS_TEST_RESNORM_OUTPUT_HPP
00031 #define BELOS_STATUS_TEST_RESNORM_OUTPUT_HPP
00032 
00038 #include <vector>
00039 #include "BelosConfigDefs.hpp"
00040 #include "BelosTypes.hpp"
00041 #include "BelosIteration.hpp"
00042 
00043 #include "BelosStatusTest.hpp"
00044 #include "BelosStatusTestCombo.hpp"
00045 #include "BelosStatusTestMaxIters.hpp"
00046 #include "BelosStatusTestResNorm.hpp"
00047 #include "BelosStatusTestOutput.hpp"
00048 
00049 namespace Belos {
00050 
00060 template <class ScalarType, class MV, class OP>
00061 class StatusTestResNormOutput : public StatusTestOutput<ScalarType,MV,OP> {
00062 
00063   typedef MultiVecTraits<ScalarType,MV> MVT;
00064   typedef Belos::StatusTestCombo<ScalarType,MV,OP>  StatusTestCombo_t;
00065   typedef Belos::StatusTestResNorm<ScalarType,MV,OP>  StatusTestResNorm_t;
00066   typedef Belos::StatusTestMaxIters<ScalarType,MV,OP>  StatusTestMaxIters_t;
00067 
00068  public:
00070 
00071 
00087   StatusTestResNormOutput(const Teuchos::RCP<OutputManager<ScalarType> > &printer, 
00088       Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test,
00089       int mod = 1,
00090       int printStates = Passed)
00091     : printer_(printer), 
00092       state_(Undefined), 
00093       headerPrinted_(false),
00094       stateTest_(printStates), 
00095       modTest_(mod), 
00096       lastNumIters_(-1),
00097       comboType_(0),
00098       numResTests_(0),
00099       blockSize_(1),
00100       currNumRHS_(0),
00101       currLSNum_(0),
00102       numLSDgts_(1), 
00103       numIterDgts_(1)
00104     {
00105       // Set the input test.
00106       setChild(test);
00107     }
00108 
00110   virtual ~StatusTestResNormOutput() {};
00112 
00114 
00115 
00132   StatusType checkStatus( Iteration<ScalarType,MV,OP>* solver ) 
00133   {
00134     TEST_FOR_EXCEPTION(iterTest_ == Teuchos::null,StatusTestError,"StatusTestResNormOutput::checkStatus():  iteration test pointer is null.");
00135     TEST_FOR_EXCEPTION(resTestVec_.size() == 0,StatusTestError,"StatusTestResNormOutput::checkStatus():  residual test pointer is null.");
00136     state_ = test_->checkStatus(solver);
00137 
00138     // Update some information for the header, if it has not printed or the linear system has changed.
00139     LinearProblem<ScalarType,MV,OP> currProb = solver->getProblem();
00140     //if (!headerPrinted_ || currLSNum_ != currProb.getLSNumber()) {
00141     if (currLSNum_ != currProb.getLSNumber()) {
00142       currLSNum_ = currProb.getLSNumber();
00143       blockSize_ = solver->getBlockSize();
00144       currIdx_ = currProb.getLSIndex();
00145       currNumRHS_ = currIdx_.size();
00146       numLSDgts_ = (int)std::floor((double)MVT::GetNumberVecs(*(currProb.getRHS())))+1;
00147       numIterDgts_ = (int)std::floor(std::log10((double)iterTest_->getMaxIters()))+1;
00148     }
00149     // Print out current iteration information if it hasn't already been printed, or the status has changed
00150     if (((iterTest_->getNumIters() % modTest_ == 0) && (iterTest_->getNumIters()!=lastNumIters_)) || (state_ == Passed)) {
00151       lastNumIters_ = iterTest_->getNumIters();
00152       if ( (state_ & stateTest_) == state_) {
00153         if ( printer_->isVerbosity(StatusTestDetails) ) {
00154           print( printer_->stream(StatusTestDetails) );
00155         }
00156         else if ( printer_->isVerbosity(Debug) ) {
00157           print( printer_->stream(Debug) );
00158         }
00159       }
00160     }
00161 
00162     return state_;
00163   }
00164 
00166   StatusType getStatus() const {
00167     return state_;
00168   }
00170 
00171 
00173 
00174 
00177   void setOutputManager(const Teuchos::RCP<OutputManager<ScalarType> > &printer) { printer_ = printer; }
00178 
00181   void setOutputFrequency(int mod) { modTest_ = mod; }
00182 
00187   void setChild(Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test) {
00188 
00189     // First check to see if this test is a combination test
00190     Teuchos::RCP<StatusTestCombo_t> tmpComboTest = Teuchos::rcp_dynamic_cast<StatusTestCombo_t>(test);
00191     TEST_FOR_EXCEPTION(tmpComboTest == Teuchos::null,StatusTestError,"StatusTestResNormOutput():  test must be a Belos::StatusTestCombo.");
00192     std::vector<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > tmpVec = tmpComboTest->getStatusTests();
00193     
00194     // Get the number of tests.
00195     int numTests = tmpVec.size();
00196 
00197     // Find the maximum iteration and residual tests
00198     for (int i=0; i<numTests; ++i) {
00199       
00200       // Check if this is a maximum iteration test.
00201       Teuchos::RCP<StatusTestMaxIters_t> tmpItrTest = Teuchos::rcp_dynamic_cast<StatusTestMaxIters_t>(tmpVec[i]);
00202       if (tmpItrTest != Teuchos::null) {
00203         iterTest_ = tmpItrTest;
00204         continue;
00205       }
00206 
00207       // Check if this is a single residual test
00208       Teuchos::RCP<StatusTestResNorm_t> tmpResTest = Teuchos::rcp_dynamic_cast<StatusTestResNorm_t>(tmpVec[i]);
00209       // If the residual status test is a single test, put in the vector
00210       if (tmpResTest != Teuchos::null) {
00211   numResTests_ = 1;
00212         resTestVec_.resize( numResTests_ );
00213   resTestVec_[0] = tmpResTest;
00214         continue;
00215       }
00216   
00217       // Check if the residual test is a combination of several StatusTestResNorm objects.
00218       Teuchos::RCP<StatusTestCombo_t> tmpComboTest = Teuchos::rcp_dynamic_cast<StatusTestCombo_t>(tmpVec[i]);
00219       TEST_FOR_EXCEPTION(tmpComboTest == Teuchos::null,StatusTestError,"StatusTestResNormOutput():  test must be Belos::StatusTest[MaxIters|ResNorm|Combo].");
00220       tmpVec = tmpComboTest->getStatusTests();
00221       comboType_ = tmpComboTest->getComboType();
00222       numResTests_ = tmpVec.size();
00223       resTestVec_.resize( numResTests_ );
00224       for (int j=0; j<numResTests_; ++j) {
00225   tmpResTest = Teuchos::rcp_dynamic_cast<StatusTestResNorm_t>(tmpVec[j]);
00226   TEST_FOR_EXCEPTION(tmpResTest == Teuchos::null,StatusTestError,"StatusTestResNormOutput():  test must be a vector of Belos::StatusTestResNorm.");
00227   resTestVec_[j] = tmpResTest;
00228       }
00229     }
00230 
00231     // Keep the pointer to the new test and reset the state to Undefined.
00232     test_ = test;
00233     state_ = Undefined;
00234 
00235   }
00236  
00238   Teuchos::RCP<StatusTest<ScalarType,MV,OP> > getChild() const {
00239     return test_;
00240   }
00241 
00244   void setSolverDesc(const std::string& solverDesc) { solverDesc_ = solverDesc; }
00245 
00248   void setPrecondDesc(const std::string& precondDesc) { precondDesc_ = precondDesc; }
00250 
00251 
00253 
00254 
00259   void reset() { 
00260     state_ = Undefined;
00261     test_->reset();
00262     lastNumIters_ = -1;
00263     headerPrinted_ = false;
00264   }
00265 
00267 
00270   void resetNumCalls() {}
00271 
00273 
00275 
00276   
00278   void print(std::ostream& os, int indent = 0) const {
00279     std::string ind(indent,' ');
00280     std::string starLine(55,'*');
00281     std::string starFront(5,'*');
00282 
00283     os.setf(std::ios::scientific, std::ios::floatfield);
00284     os.precision(6);
00285     
00286     // Print header if this is the first call to this output status test.
00287     if (!headerPrinted_) {
00288       os << std::endl << ind << starLine << std::endl;
00289       os << ind << starFront << " Belos Iterative Solver: " << solverDesc_ << std::endl;
00290       if (precondDesc_ != "")
00291         os << ind << starFront << " Preconditioner: " << precondDesc_ << std::endl;
00292       os << ind << starFront << " Maximum Iterations: " << iterTest_->getMaxIters() << std::endl;
00293       os << ind << starFront << " Block Size: " << blockSize_ << std::endl;
00294       if (numResTests_ > 1) {
00295         os << ind << starFront << " Residual Tests (" 
00296            << ((comboType_ == StatusTestCombo_t::OR) ? "OR" : (comboType_ == StatusTestCombo_t::AND) ? "AND" :"SEQ")
00297            << "): " << std::endl;
00298       } else {
00299         os << ind << starFront << " Residual Test: " << std::endl;
00300       } 
00301       for (int i=0; i<numResTests_; ++i) {
00302         os << ind << starFront << "   Test " << i+1 << " : " << resTestVec_[i]->description() << std::endl;
00303       }
00304       os << ind << starLine << std::endl;
00305       headerPrinted_ = true;
00306     }
00307 
00308     // Print out residuals for each residual test.
00309     os.setf(std::ios_base::right, std::ios_base::adjustfield);
00310     std::string ind2( 7 + numIterDgts_, ' ' );
00311     os << ind << "Iter " << std::setw(numIterDgts_) << iterTest_->getNumIters() << ", ";
00312     for (int i=0; i<currNumRHS_; ++i) {
00313       if ( i > 0 && currIdx_[i]!=-1 ) {
00314         // Put in space where 'Iter :' is in the previous lines
00315         os << ind << ind2;
00316       }
00317       os << "[" << std::setw(numLSDgts_) << currIdx_[i]+1 << "] : ";
00318       for (int j=0; j<numResTests_; ++j) {
00319         if ( resTestVec_[j]->getStatus() != Undefined && currIdx_[i]!=-1 ) {
00320           os << std::setw(15) << (*resTestVec_[j]->getTestValue())[currIdx_[i]];
00321         } else {
00322           os << std::setw(15) << "---"; 
00323         }
00324       }
00325       os << std::endl;
00326     }
00327   }
00328  
00330 
00331   private:
00332     // Output manager.
00333     Teuchos::RCP<OutputManager<ScalarType> > printer_;
00334 
00335     // Overall status test.
00336     Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test_;
00337 
00338     // Iteration test (as passed in).
00339     Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > iterTest_;
00340 
00342     std::vector<Teuchos::RCP<StatusTestResNorm<ScalarType,MV,OP> > > resTestVec_;
00343 
00344     std::string solverDesc_;
00345     std::string precondDesc_;
00346     std::vector<int> currIdx_;
00347     StatusType state_;
00348     mutable bool headerPrinted_;
00349     int stateTest_, modTest_;
00350     int lastNumIters_, comboType_;
00351     int numResTests_, blockSize_;
00352     int currNumRHS_, currLSNum_;
00353     int numLSDgts_, numIterDgts_;
00354 };
00355 
00356 } // end of Belos namespace
00357 
00358 #endif /* BELOS_STATUS_TEST_RESNORM_OUTPUT_HPP */

Generated on Tue Jul 13 09:27:03 2010 for Belos by  doxygen 1.4.7