00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef BELOS_STATUS_TEST_OUTPUTTER_HPP
00030 #define BELOS_STATUS_TEST_OUTPUTTER_HPP
00031
00037 #include "BelosStatusTestResNorm.hpp"
00038 #include "BelosLinearProblem.hpp"
00039 #include "BelosMultiVecTraits.hpp"
00040 #include "BelosOutputManager.hpp"
00041 #include "Teuchos_VerboseObject.hpp"
00042 #include "Teuchos_StandardCompositionMacros.hpp"
00043 #include "Teuchos_StandardMemberCompositionMacros.hpp"
00044
00045 namespace Belos {
00046
00051 template <class ScalarType, class MV, class OP>
00052 class StatusTestOutputter: public StatusTest<ScalarType,MV,OP> {
00053 public:
00054
00057
00059 typedef Teuchos::ScalarTraits<ScalarType> ST;
00061 typedef typename ST::magnitudeType MagnitudeType;
00063 typedef StatusTestResNorm<ScalarType,MV,OP> StatusTestResNorm_t;
00064
00067
00070 STANDARD_MEMBER_COMPOSITION_MEMBERS( int, outputFrequency )
00071
00072
00073 STANDARD_MEMBER_COMPOSITION_MEMBERS( bool, outputMaxResOnly )
00074
00076 STANDARD_MEMBER_COMPOSITION_MEMBERS( std::string, resString )
00077
00079 STANDARD_COMPOSITION_MEMBERS( StatusTestResNorm_t, resNormStatusTest )
00080
00081
00083 STANDARD_COMPOSITION_MEMBERS( OutputManager<ScalarType>, outputManager )
00084
00086 StatusTestOutputter(
00087 const int outputFrequency = -1
00088 ,const bool outputMaxResOnly = true
00089 ,const std::string &resString = "||A*x-b||/||b||"
00090 );
00091
00093
00096
00098 StatusType CheckStatus(IterativeSolver<ScalarType,MV,OP>* iSolver);
00100 StatusType GetStatus() const;
00102 void Reset();
00104 bool ResidualVectorRequired() const;
00106 ostream& Print(ostream& os, int indent) const;
00107
00109
00110 private:
00111
00112 int callsSinceLastOutput_;
00113 bool iterZeroWasOutput_;
00114 int lastRestart_;
00115
00116 };
00117
00118
00119
00120
00121
00122
00123 template <class ScalarType, class MV, class OP>
00124 StatusTestOutputter<ScalarType,MV,OP>::StatusTestOutputter(
00125 const int outputFrequency
00126 ,const bool outputMaxResOnly
00127 ,const std::string &resString
00128 )
00129 :outputFrequency_(outputFrequency)
00130 ,outputMaxResOnly_(outputMaxResOnly)
00131 ,resString_(resString)
00132 ,callsSinceLastOutput_(10000)
00133 ,iterZeroWasOutput_(false)
00134 {}
00135
00136
00137
00138 template <class ScalarType, class MV, class OP>
00139 StatusType StatusTestOutputter<ScalarType,MV,OP>::CheckStatus(IterativeSolver<ScalarType,MV,OP>* iSolver)
00140 {
00141 typedef MultiVecTraits<ScalarType,MV> MVT;
00142 StatusType status = resNormStatusTest_->CheckStatus(iSolver);
00143 RefCountPtr<LinearProblem<ScalarType,MV,OP> > lp = iSolver->GetLinearProblem();
00144 const int currIter = iSolver->GetNumIters();
00145 const int currRestart = iSolver->GetNumRestarts();
00146 if(currIter==0 && !iterZeroWasOutput_)
00147 lastRestart_ = -1;
00148 ++callsSinceLastOutput_;
00149 if(
00150 ( outputFrequency() > 0 )
00151 &&
00152 (
00153 status==Converged
00154 ||
00155 callsSinceLastOutput_>=outputFrequency()
00156 ||
00157 currRestart > lastRestart_
00158 ||
00159 ( currIter==0 && !iterZeroWasOutput_ )
00160 )
00161 )
00162 {
00163 const int currRhsOffset = lp->GetRHSIndex();
00164 const int currNumRhs = lp->GetNumToSolve();
00165 TEST_FOR_EXCEPT(resNormStatusTest_->GetTestValue()==NULL);
00166 const std::vector<MagnitudeType> &resTestValuesVector = *resNormStatusTest_->GetTestValue();
00167 std::ostream &out = *outputManager_->GetOStream();
00168 if(status==Converged)
00169 out << "[Converged]";
00170 out << "iter="<<currIter<<", restart="<<currRestart;
00171 const MagnitudeType maxRelRes = *std::max_element(
00172 resTestValuesVector.begin()+currRhsOffset,resTestValuesVector.begin()+currRhsOffset+currNumRhs
00173 );
00174 if(currNumRhs==1) {
00175 out << ", "<<resString()<<"="<<maxRelRes<<"\n";
00176 }
00177 else {
00178 if(outputMaxResOnly()) {
00179 out << ", max{"<<resString()<<",i="<<currRhsOffset<<"..."<<currRhsOffset+currNumRhs-1<<"}=" << maxRelRes << "\n";
00180 }
00181 else {
00182 out << ", "<<resString()<<":\n";
00183 for(int i=0; i<currNumRhs; ++i) {
00184 out <<" "<<(i+currRhsOffset)<<": "<<resTestValuesVector[i+currRhsOffset]<<"\n";
00185 }
00186 }
00187 }
00188 if(currIter==0) {
00189 iterZeroWasOutput_ = true;
00190 }
00191 else {
00192 iterZeroWasOutput_ = false;
00193 }
00194 lastRestart_ = currRestart;
00195 callsSinceLastOutput_ = 0;
00196 }
00197 return status;
00198 }
00199
00200 template <class ScalarType, class MV, class OP>
00201 StatusType StatusTestOutputter<ScalarType,MV,OP>::GetStatus() const
00202 {
00203 return resNormStatusTest_->GetStatus();
00204 }
00205
00206 template <class ScalarType, class MV, class OP>
00207 void StatusTestOutputter<ScalarType,MV,OP>::Reset()
00208 {
00209 return resNormStatusTest_->Reset();
00210 callsSinceLastOutput_ = 10000;
00211 iterZeroWasOutput_ = false;
00212 }
00213
00214 template <class ScalarType, class MV, class OP>
00215 bool StatusTestOutputter<ScalarType,MV,OP>::ResidualVectorRequired() const
00216 {
00217 return resNormStatusTest_->ResidualVectorRequired();
00218 }
00219
00220 template <class ScalarType, class MV, class OP>
00221 ostream& StatusTestOutputter<ScalarType,MV,OP>::Print(ostream& os, int indent) const
00222 {
00223 return resNormStatusTest_->Print(os,indent);
00224 }
00225
00226 }
00227
00228 #endif // BELOS_STATUS_TEST_OUTPUTTER_HPP