10 #ifndef BELOS_STATUS_TEST_GEN_RESSUBNORM_H
11 #define BELOS_STATUS_TEST_GEN_RESSUBNORM_H
23 #ifdef HAVE_BELOS_THYRA
24 #include <Thyra_MultiVectorBase.hpp>
25 #include <Thyra_MultiVectorStdOps.hpp>
26 #include <Thyra_ProductMultiVectorBase.hpp>
39 template <
class ScalarType,
class MV,
class OP>
66 "StatusTestGenResSubNorm::StatusTestGenResSubNorm(): StatusTestGenResSubNorm only available for blocked operators (e.g., Thyra).");
85 "StatusTestGenResSubNorm::defineResForm(): StatusTestGenResSubNorm only available for blocked operators (e.g., Thyra).");
112 "StatusTestGenResSubNorm::defineScaleForm(): StatusTestGenResSubNorm only available for blocked operators (e.g., Thyra).");
163 void print(std::ostream& ,
int = 0)
const { }
227 {
return std::string(
""); }
231 #ifdef HAVE_BELOS_THYRA
234 template <
class ScalarType>
235 class StatusTestGenResSubNorm<ScalarType,Thyra::MultiVectorBase<ScalarType>,Thyra::LinearOpBase<ScalarType> >
236 :
public StatusTestResNorm<ScalarType,Thyra::MultiVectorBase<ScalarType>,Thyra::LinearOpBase<ScalarType> > {
240 typedef Thyra::MultiVectorBase<ScalarType> MV;
241 typedef Thyra::LinearOpBase<ScalarType> OP;
245 typedef MultiVecTraits<ScalarType,MV>
MVT;
246 typedef OperatorTraits<ScalarType,MV,OP> OT;
264 : tolerance_(Tolerance),
267 showMaxResNormOnly_(showMaxResNormOnly),
277 firstcallCheckStatus_(true),
278 firstcallDefineResForm_(true),
279 firstcallDefineScaleForm_(true) { }
297 "StatusTestGenResSubNorm::defineResForm(): The residual form has already been defined.");
298 firstcallDefineResForm_ =
false;
300 resnormtype_ = TypeOfNorm;
328 "StatusTestGenResSubNorm::defineScaleForm(): The scaling type has already been defined.");
329 firstcallDefineScaleForm_ =
false;
331 scaletype_ = TypeOfScaling;
332 scalenormtype_ = TypeOfNorm;
333 scalevalue_ = ScaleValue;
347 int setSubIdx (
size_t subIdx ) { subIdx_ = subIdx;
return(0);}
351 int setQuorum(
int quorum) {quorum_ = quorum;
return(0);}
354 int setShowMaxResNormOnly(
bool showMaxResNormOnly) {showMaxResNormOnly_ = showMaxResNormOnly;
return(0);}
369 const LinearProblem<ScalarType,MV,OP>& lp = iSolver->getProblem();
371 if (firstcallCheckStatus_) {
382 if ( curLSNum_ != lp.getLSNumber() ) {
386 curLSNum_ = lp.getLSNumber();
387 curLSIdx_ = lp.getLSIndex();
388 curBlksz_ = (int)curLSIdx_.size();
390 for (
int i=0; i<curBlksz_; ++i) {
391 if (curLSIdx_[i] > -1 && curLSIdx_[i] < numrhs_)
394 curNumRHS_ = validLS;
401 if (status_==
Passed) {
return status_; }
408 curSoln_ = lp.updateSolution( cur_update );
410 lp.computeCurrResVec( &*cur_res, &*curSoln_ );
412 MvSubNorm( *cur_res, subIdx_, tmp_resvector, resnormtype_ );
414 typename std::vector<int>::iterator pp = curLSIdx_.begin();
415 for (
int i=0; pp<curLSIdx_.end(); ++pp, ++i) {
418 resvector_[*pp] = tmp_resvector[i];
425 if ( scalevector_.size() > 0 ) {
426 typename std::vector<int>::iterator p = curLSIdx_.begin();
427 for (; p<curLSIdx_.end(); ++p) {
431 if ( scalevector_[ *p ] != zero ) {
433 testvector_[ *p ] = resvector_[ *p ] / scalevector_[ *p ] / scalevalue_;
435 testvector_[ *p ] = resvector_[ *p ] / scalevalue_;
441 typename std::vector<int>::iterator ppp = curLSIdx_.begin();
442 for (; ppp<curLSIdx_.end(); ++ppp) {
445 testvector_[ *ppp ] = resvector_[ *ppp ] / scalevalue_;
450 ind_.resize( curLSIdx_.size() );
451 typename std::vector<int>::iterator p2 = curLSIdx_.begin();
452 for (; p2<curLSIdx_.end(); ++p2) {
456 if (testvector_[ *p2 ] > tolerance_) {
458 }
else if (testvector_[ *p2 ] <= tolerance_) {
469 int need = (quorum_ == -1) ? curNumRHS_: quorum_;
490 firstcallCheckStatus_ =
true;
500 void print(std::ostream& os,
int indent = 0)
const {
501 os.setf(std::ios_base::scientific);
502 for (
int j = 0; j < indent; j ++)
507 os <<
", tol = " << tolerance_ << std::endl;
510 if(showMaxResNormOnly_ && curBlksz_ > 1) {
512 testvector_.begin()+curLSIdx_[0],testvector_.begin()+curLSIdx_[curBlksz_-1]
514 for (
int j = 0; j < indent + 13; j ++)
516 os <<
"max{residual["<<curLSIdx_[0]<<
"..."<<curLSIdx_[curBlksz_-1]<<
"]} = " << maxRelRes
517 << ( maxRelRes <= tolerance_ ?
" <= " :
" > " ) << tolerance_ << std::endl;
520 for (
int i=0; i<numrhs_; i++ ) {
521 for (
int j = 0; j < indent + 13; j ++)
523 os <<
"residual [ " << i <<
" ] = " << testvector_[ i ];
524 os << ((testvector_[i]<tolerance_) ?
" < " : (testvector_[i]==tolerance_) ?
" == " : (testvector_[i]>tolerance_) ?
" > " :
" " ) << tolerance_ << std::endl;
533 os << std::left << std::setw(13) << std::setfill(
'.');
546 os << std::left << std::setfill(
' ');
559 int getQuorum()
const {
return quorum_; }
562 size_t getSubIdx()
const {
return subIdx_; }
574 const std::vector<MagnitudeType>*
getTestValue()
const {
return(&testvector_);};
577 const std::vector<MagnitudeType>*
getResNormValue()
const {
return(&resvector_);};
580 const std::vector<MagnitudeType>*
getScaledNormValue()
const {
return(&scalevector_);};
601 const LinearProblem<ScalarType,MV,OP>& lp = iSolver->getProblem();
603 if (firstcallCheckStatus_) {
607 firstcallCheckStatus_ =
false;
612 scalevector_.resize( numrhs_ );
613 MvSubNorm( *rhs, subIdx_, scalevector_, scalenormtype_ );
618 scalevector_.resize( numrhs_ );
619 MvSubNorm( *init_res, subIdx_, scalevector_, scalenormtype_ );
624 scalevector_.resize( numrhs_ );
625 MvSubNorm( *init_res, subIdx_, scalevector_, scalenormtype_ );
630 scalevector_.resize( numrhs_ );
631 MVT::MvNorm( *init_res, scalevector_, scalenormtype_ );
637 scalevector_.resize( numrhs_ );
638 MVT::MvNorm( *init_res, scalevector_, scalenormtype_ );
644 scalevector_.resize( numrhs_ );
645 MVT::MvNorm( *init_res, scalevector_, scalenormtype_ );
646 MvScalingRatio( *init_res, subIdx_, scalevalue_ );
651 scalevector_.resize( numrhs_ );
652 MVT::MvNorm( *init_res, scalevector_, scalenormtype_ );
653 MvScalingRatio( *init_res, subIdx_, scalevalue_ );
659 resvector_.resize( numrhs_ );
660 testvector_.resize( numrhs_ );
662 curLSNum_ = lp.getLSNumber();
663 curLSIdx_ = lp.getLSIndex();
664 curBlksz_ = (int)curLSIdx_.size();
666 for (i=0; i<curBlksz_; ++i) {
667 if (curLSIdx_[i] > -1 && curLSIdx_[i] < numrhs_)
670 curNumRHS_ = validLS;
673 for (i=0; i<numrhs_; i++) { testvector_[i] = one; }
676 if (scalevalue_ == zero) {
690 std::ostringstream oss;
691 oss <<
"Belos::StatusTestGenResSubNorm<>: " << resFormStr();
692 oss <<
", tol = " << tolerance_;
704 std::string resFormStr()
const
706 std::ostringstream oss;
708 oss << ((resnormtype_==
OneNorm) ?
"1-Norm" : (resnormtype_==
TwoNorm) ?
"2-Norm" :
"Inf-Norm");
710 oss <<
" Res Vec [" << subIdx_ <<
"]) ";
713 if (scaletype_!=
None)
720 oss <<
" (User Scale)";
723 oss << ((scalenormtype_==
OneNorm) ?
"1-Norm" : (resnormtype_==
TwoNorm) ?
"2-Norm" :
"Inf-Norm");
725 oss <<
" Res0 [" << subIdx_ <<
"]";
727 oss <<
" Prec Res0 [" << subIdx_ <<
"]";
729 oss <<
" Full Res0 [" << subIdx_ <<
"]";
731 oss <<
" Full Prec Res0 [" << subIdx_ <<
"]";
733 oss <<
" scaled Full Res0 [" << subIdx_ <<
"]";
735 oss <<
" scaled Full Prec Res0 [" << subIdx_ <<
"]";
737 oss <<
" RHS [" << subIdx_ <<
"]";
756 typedef typename Thyra::ProductMultiVectorBase<ScalarType> TPMVB;
760 "Belos::StatusTestGenResSubNorm::MvSubNorm (Thyra specialization): "
761 "mv must be a Thyra::ProductMultiVector, but is of type " << thyProdVec);
769 void MvScalingRatio(
const MV& mv,
size_t block,
MagnitudeType& lengthRatio) {
772 typedef typename Thyra::ProductMultiVectorBase<ScalarType> TPMVB;
776 "Belos::StatusTestGenResSubNorm::MvScalingRatio (Thyra specialization): "
777 "mv must be a Thyra::ProductMultiVector, but is of type " << thyProdVec);
781 lengthRatio = Teuchos::as<MagnitudeType>(thySubVec->range()->dim()) / Teuchos::as<MagnitudeType>(thyProdVec->range()->dim());
799 bool showMaxResNormOnly_;
814 std::vector<MagnitudeType> scalevector_;
817 std::vector<MagnitudeType> resvector_;
820 std::vector<MagnitudeType> testvector_;
823 std::vector<int> ind_;
838 std::vector<int> curLSIdx_;
847 bool firstcallCheckStatus_;
850 bool firstcallDefineResForm_;
853 bool firstcallDefineScaleForm_;
859 #endif // HAVE_BELOS_THYRA
Teuchos::RCP< MV > getSolution()
Returns the current solution estimate that was computed for the most recent residual test...
int setQuorum(int)
Sets the number of residuals that must pass the convergence test before Passed is returned...
const std::vector< MagnitudeType > * getResNormValue() const
Returns the residual norm value, , computed in most recent call to CheckStatus.
ScaleType
The type of scaling to use on the residual norm value.
Exception thrown to signal error in a status test during Belos::StatusTest::checkStatus().
An implementation of StatusTestResNorm using a family of norms of subvectors of the residual vectors...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Declaration of basic traits for the multivector type.
void print(std::ostream &, int=0) const
Output formatted description of stopping test to output stream.
An abstract class of StatusTest for stopping criteria using residual norms.
int defineScaleForm(ScaleType, NormType, MagnitudeType=Teuchos::ScalarTraits< MagnitudeType >::one())
Define form of the scaling, its norm, its optional weighting std::vector, or, alternatively, define an explicit value.
void reset()
Resets the internal configuration to the initial state.
Class which defines basic traits for the operator type.
StatusType
Whether the StatusTest wants iteration to stop.
static int GetNumberVecs(const MV &mv)
Obtain the number of vectors in mv.
MagnitudeType getTolerance() const
Returns the value of the tolerance, , set in the constructor.
const std::vector< MagnitudeType > * getScaledNormValue() const
Returns the scaled norm value, .
StatusType getStatus() const
Return the result of the most recent CheckStatus call.
MultiVecTraits< ScalarType, MV > MVT
Traits class which defines basic operations on multivectors.
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
Creates a new empty MV containing numvecs columns.
StatusTestGenResSubNorm(MagnitudeType, size_t, int=-1, bool=false)
Constructor.
void printStatus(std::ostream &, StatusType) const
Print message for each status specific to this stopping test.
std::string description() const
Method to return description of the maximum iteration status test.
StatusType firstCallCheckStatusSetup(Iteration< ScalarType, MV, OP > *iSolver)
Call to setup initial scaling std::vector.
Class which describes the linear problem to be solved by the iterative solver.
int getQuorum() const
Returns the number of residuals that must pass the convergence test before Passed is returned...
int setSubIdx(size_t subIdx)
Set the block index of which we want to check the norm of the sub-residuals.
SCT::magnitudeType MagnitudeType
size_t getSubIdx() const
Returns the index of the block row the norms are calculated for.
const std::vector< MagnitudeType > * getTestValue() const
Returns the test value, , computed in most recent call to CheckStatus.
int setTolerance(MagnitudeType)
Set the value of the tolerance.
virtual ~StatusTestGenResSubNorm()
Destructor.
Belos::StatusTest abstract class for specifying a residual norm stopping criteria.
Teuchos::ScalarTraits< ScalarType > SCT
static magnitudeType magnitude(ScalarTypea)
NormType
The type of vector norm to compute.
bool getLOADetected() const
Returns a boolean indicating a loss of accuracy has been detected in computing the residual...
StatusType checkStatus(Iteration< ScalarType, MV, OP > *)
Check convergence status: Passed, Failed, or Undefined.
int setShowMaxResNormOnly(bool)
Set whether the only maximum residual norm is displayed when the print() method is called...
std::vector< int > convIndices()
Returns the std::vector containing the indices of the residuals that passed the test.
static void MvNorm(const MV &mv, std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &normvec, NormType type=TwoNorm)
Compute the norm of each individual vector of mv. Upon return, normvec[i] holds the value of ...
bool getShowMaxResNormOnly()
Returns whether the only maximum residual norm is displayed when the print() method is called...
int defineResForm(NormType)
Define norm of the residual.
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)