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>
39template <
class ScalarType,
class MV,
class OP,
class DM = DefaultDenseMatrix<
int,ScalarType>>
44 typedef Teuchos::ScalarTraits<ScalarType>
SCT;
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
234template <
class ScalarType>
235class StatusTestGenResSubNorm<ScalarType,Thyra::MultiVectorBase<ScalarType>,Thyra::LinearOpBase<ScalarType>,
DefaultDenseMatrix<int,ScalarType> >
236 :
public StatusTestResNorm<ScalarType,Thyra::MultiVectorBase<ScalarType>,Thyra::LinearOpBase<ScalarType>,DefaultDenseMatrix<int,ScalarType> > {
240 typedef Thyra::MultiVectorBase<ScalarType> MV;
241 typedef Thyra::LinearOpBase<ScalarType> OP;
242 typedef DefaultDenseMatrix<int,ScalarType> DM;
244 typedef Teuchos::ScalarTraits<ScalarType>
SCT;
246 typedef MultiVecTraits<ScalarType,MV,DM>
MVT;
247 typedef OperatorTraits<ScalarType,MV,OP> OT;
264 StatusTestGenResSubNorm(
MagnitudeType Tolerance,
size_t subIdx,
int quorum = -1,
bool showMaxResNormOnly =
false )
265 : tolerance_(Tolerance),
268 showMaxResNormOnly_(showMaxResNormOnly),
278 firstcallCheckStatus_(true),
279 firstcallDefineResForm_(true),
280 firstcallDefineScaleForm_(true) { }
297 TEUCHOS_TEST_FOR_EXCEPTION(firstcallDefineResForm_==
false,StatusTestError,
298 "StatusTestGenResSubNorm::defineResForm(): The residual form has already been defined.");
299 firstcallDefineResForm_ =
false;
301 resnormtype_ = TypeOfNorm;
328 TEUCHOS_TEST_FOR_EXCEPTION(firstcallDefineScaleForm_==
false,StatusTestError,
329 "StatusTestGenResSubNorm::defineScaleForm(): The scaling type has already been defined.");
330 firstcallDefineScaleForm_ =
false;
332 scaletype_ = TypeOfScaling;
333 scalenormtype_ = TypeOfNorm;
334 scalevalue_ = ScaleValue;
348 int setSubIdx (
size_t subIdx ) { subIdx_ = subIdx;
return(0);}
352 int setQuorum(
int quorum) {quorum_ = quorum;
return(0);}
355 int setShowMaxResNormOnly(
bool showMaxResNormOnly) {showMaxResNormOnly_ = showMaxResNormOnly;
return(0);}
369 MagnitudeType zero = Teuchos::ScalarTraits<MagnitudeType>::zero();
370 const LinearProblem<ScalarType,MV,OP,DM>& lp = iSolver->getProblem();
372 if (firstcallCheckStatus_) {
383 if ( curLSNum_ != lp.getLSNumber() ) {
387 curLSNum_ = lp.getLSNumber();
388 curLSIdx_ = lp.getLSIndex();
389 curBlksz_ = (int)curLSIdx_.size();
391 for (
int i=0; i<curBlksz_; ++i) {
392 if (curLSIdx_[i] > -1 && curLSIdx_[i] < numrhs_)
395 curNumRHS_ = validLS;
396 curSoln_ = Teuchos::null;
402 if (status_==
Passed) {
return status_; }
408 Teuchos::RCP<MV> cur_update = iSolver->getCurrentUpdate();
409 curSoln_ = lp.updateSolution( cur_update );
410 Teuchos::RCP<MV> cur_res = MVT::Clone( *curSoln_, MVT::GetNumberVecs( *curSoln_ ) );
411 lp.computeCurrResVec( &*cur_res, &*curSoln_ );
412 std::vector<MagnitudeType> tmp_resvector( MVT::GetNumberVecs( *cur_res ) );
413 MvSubNorm( *cur_res, subIdx_, tmp_resvector, resnormtype_ );
415 typename std::vector<int>::iterator pp = curLSIdx_.begin();
416 for (
int i=0; pp<curLSIdx_.end(); ++pp, ++i) {
419 resvector_[*pp] = tmp_resvector[i];
426 if ( scalevector_.size() > 0 ) {
427 typename std::vector<int>::iterator p = curLSIdx_.begin();
428 for (; p<curLSIdx_.end(); ++p) {
432 if ( scalevector_[ *p ] != zero ) {
434 testvector_[ *p ] = resvector_[ *p ] / scalevector_[ *p ] / scalevalue_;
436 testvector_[ *p ] = resvector_[ *p ] / scalevalue_;
442 typename std::vector<int>::iterator ppp = curLSIdx_.begin();
443 for (; ppp<curLSIdx_.end(); ++ppp) {
446 testvector_[ *ppp ] = resvector_[ *ppp ] / scalevalue_;
451 ind_.resize( curLSIdx_.size() );
452 typename std::vector<int>::iterator p2 = curLSIdx_.begin();
453 for (; p2<curLSIdx_.end(); ++p2) {
457 if (testvector_[ *p2 ] > tolerance_) {
459 }
else if (testvector_[ *p2 ] <= tolerance_) {
465 TEUCHOS_TEST_FOR_EXCEPTION(
true,StatusTestNaNError,
"StatusTestGenResSubNorm::checkStatus(): NaN has been detected.");
470 int need = (quorum_ == -1) ? curNumRHS_: quorum_;
491 firstcallCheckStatus_ =
true;
492 curSoln_ = Teuchos::null;
501 void print(std::ostream& os,
int indent = 0)
const {
502 os.setf(std::ios_base::scientific);
503 for (
int j = 0; j < indent; j ++)
508 os <<
", tol = " << tolerance_ << std::endl;
511 if(showMaxResNormOnly_ && curBlksz_ > 1) {
513 testvector_.begin()+curLSIdx_[0],testvector_.begin()+curLSIdx_[curBlksz_-1]
515 for (
int j = 0; j < indent + 13; j ++)
517 os <<
"max{residual["<<curLSIdx_[0]<<
"..."<<curLSIdx_[curBlksz_-1]<<
"]} = " << maxRelRes
518 << ( maxRelRes <= tolerance_ ?
" <= " :
" > " ) << tolerance_ << std::endl;
521 for (
int i=0; i<numrhs_; i++ ) {
522 for (
int j = 0; j < indent + 13; j ++)
524 os <<
"residual [ " << i <<
" ] = " << testvector_[ i ];
525 os << ((testvector_[i]<tolerance_) ?
" < " : (testvector_[i]==tolerance_) ?
" == " : (testvector_[i]>tolerance_) ?
" > " :
" " ) << tolerance_ << std::endl;
534 os << std::left << std::setw(13) << std::setfill(
'.');
547 os << std::left << std::setfill(
' ');
556 Teuchos::RCP<MV>
getSolution() {
return curSoln_; }
560 int getQuorum()
const {
return quorum_; }
563 size_t getSubIdx()
const {
return subIdx_; }
575 const std::vector<MagnitudeType>*
getTestValue()
const {
return(&testvector_);};
578 const std::vector<MagnitudeType>*
getResNormValue()
const {
return(&resvector_);};
581 const std::vector<MagnitudeType>*
getScaledNormValue()
const {
return(&scalevector_);};
600 MagnitudeType zero = Teuchos::ScalarTraits<MagnitudeType>::zero();
601 MagnitudeType one = Teuchos::ScalarTraits<MagnitudeType>::one();
602 const LinearProblem<ScalarType,MV,OP,DM>& lp = iSolver->getProblem();
604 if (firstcallCheckStatus_) {
608 firstcallCheckStatus_ =
false;
611 Teuchos::RCP<const MV> rhs = lp.getRHS();
612 numrhs_ = MVT::GetNumberVecs( *rhs );
613 scalevector_.resize( numrhs_ );
614 MvSubNorm( *rhs, subIdx_, scalevector_, scalenormtype_ );
617 Teuchos::RCP<const MV> init_res = lp.getInitResVec();
618 numrhs_ = MVT::GetNumberVecs( *init_res );
619 scalevector_.resize( numrhs_ );
620 MvSubNorm( *init_res, subIdx_, scalevector_, scalenormtype_ );
623 Teuchos::RCP<const MV> init_res = lp.getInitPrecResVec();
624 numrhs_ = MVT::GetNumberVecs( *init_res );
625 scalevector_.resize( numrhs_ );
626 MvSubNorm( *init_res, subIdx_, scalevector_, scalenormtype_ );
629 Teuchos::RCP<const MV> init_res = lp.getInitResVec();
630 numrhs_ = MVT::GetNumberVecs( *init_res );
631 scalevector_.resize( numrhs_ );
632 MVT::MvNorm( *init_res, scalevector_, scalenormtype_ );
633 scalevalue_ = Teuchos::ScalarTraits<MagnitudeType>::one();
636 Teuchos::RCP<const MV> init_res = lp.getInitPrecResVec();
637 numrhs_ = MVT::GetNumberVecs( *init_res );
638 scalevector_.resize( numrhs_ );
639 MVT::MvNorm( *init_res, scalevector_, scalenormtype_ );
640 scalevalue_ = Teuchos::ScalarTraits<MagnitudeType>::one();
643 Teuchos::RCP<const MV> init_res = lp.getInitResVec();
644 numrhs_ = MVT::GetNumberVecs( *init_res );
645 scalevector_.resize( numrhs_ );
646 MVT::MvNorm( *init_res, scalevector_, scalenormtype_ );
647 MvScalingRatio( *init_res, subIdx_, scalevalue_ );
650 Teuchos::RCP<const MV> init_res = lp.getInitPrecResVec();
651 numrhs_ = MVT::GetNumberVecs( *init_res );
652 scalevector_.resize( numrhs_ );
653 MVT::MvNorm( *init_res, scalevector_, scalenormtype_ );
654 MvScalingRatio( *init_res, subIdx_, scalevalue_ );
657 numrhs_ = MVT::GetNumberVecs( *(lp.getRHS()) );
660 resvector_.resize( numrhs_ );
661 testvector_.resize( numrhs_ );
663 curLSNum_ = lp.getLSNumber();
664 curLSIdx_ = lp.getLSIndex();
665 curBlksz_ = (int)curLSIdx_.size();
667 for (i=0; i<curBlksz_; ++i) {
668 if (curLSIdx_[i] > -1 && curLSIdx_[i] < numrhs_)
671 curNumRHS_ = validLS;
674 for (i=0; i<numrhs_; i++) { testvector_[i] = one; }
677 if (scalevalue_ == zero) {
691 std::ostringstream oss;
692 oss <<
"Belos::StatusTestGenResSubNorm<>: " << resFormStr();
693 oss <<
", tol = " << tolerance_;
705 std::string resFormStr()
const
707 std::ostringstream oss;
709 oss << ((resnormtype_==
OneNorm) ?
"1-Norm" : (resnormtype_==
TwoNorm) ?
"2-Norm" :
"Inf-Norm");
711 oss <<
" Res Vec [" << subIdx_ <<
"]) ";
714 if (scaletype_!=
None)
721 oss <<
" (User Scale)";
724 oss << ((scalenormtype_==
OneNorm) ?
"1-Norm" : (resnormtype_==
TwoNorm) ?
"2-Norm" :
"Inf-Norm");
726 oss <<
" Res0 [" << subIdx_ <<
"]";
728 oss <<
" Prec Res0 [" << subIdx_ <<
"]";
730 oss <<
" Full Res0 [" << subIdx_ <<
"]";
732 oss <<
" Full Prec Res0 [" << subIdx_ <<
"]";
734 oss <<
" scaled Full Res0 [" << subIdx_ <<
"]";
736 oss <<
" scaled Full Prec Res0 [" << subIdx_ <<
"]";
738 oss <<
" RHS [" << subIdx_ <<
"]";
754 void MvSubNorm(
const MV& mv,
size_t block, std::vector<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>& normVec,
NormType type =
TwoNorm) {
755 Teuchos::RCP<const MV> input = Teuchos::rcpFromRef(mv);
757 typedef typename Thyra::ProductMultiVectorBase<ScalarType> TPMVB;
758 Teuchos::RCP<const TPMVB> thyProdVec = Teuchos::rcp_dynamic_cast<const TPMVB>(input);
760 TEUCHOS_TEST_FOR_EXCEPTION(thyProdVec == Teuchos::null, std::invalid_argument,
761 "Belos::StatusTestGenResSubNorm::MvSubNorm (Thyra specialization): "
762 "mv must be a Thyra::ProductMultiVector, but is of type " << thyProdVec);
764 Teuchos::RCP<const MV> thySubVec = thyProdVec->getMultiVectorBlock(block);
766 MVT::MvNorm(*thySubVec,normVec,type);
770 void MvScalingRatio(
const MV& mv,
size_t block,
MagnitudeType& lengthRatio) {
771 Teuchos::RCP<const MV> input = Teuchos::rcpFromRef(mv);
773 typedef typename Thyra::ProductMultiVectorBase<ScalarType> TPMVB;
774 Teuchos::RCP<const TPMVB> thyProdVec = Teuchos::rcp_dynamic_cast<const TPMVB>(input);
776 TEUCHOS_TEST_FOR_EXCEPTION(thyProdVec == Teuchos::null, std::invalid_argument,
777 "Belos::StatusTestGenResSubNorm::MvScalingRatio (Thyra specialization): "
778 "mv must be a Thyra::ProductMultiVector, but is of type " << thyProdVec);
780 Teuchos::RCP<const MV> thySubVec = thyProdVec->getMultiVectorBlock(block);
782 lengthRatio = Teuchos::as<MagnitudeType>(thySubVec->range()->dim()) / Teuchos::as<MagnitudeType>(thyProdVec->range()->dim());
800 bool showMaxResNormOnly_;
815 std::vector<MagnitudeType> scalevector_;
818 std::vector<MagnitudeType> resvector_;
821 std::vector<MagnitudeType> testvector_;
824 std::vector<int> ind_;
827 Teuchos::RCP<MV> curSoln_;
839 std::vector<int> curLSIdx_;
848 bool firstcallCheckStatus_;
851 bool firstcallDefineResForm_;
854 bool firstcallDefineScaleForm_;
Class which describes the linear problem to be solved by the iterative solver.
Declaration of basic traits for the multivector type.
Class which defines basic traits for the operator type.
Belos::StatusTest abstract class for specifying a residual norm stopping criteria.
Alternative run-time polymorphic interface for operators.
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.
virtual ~StatusTestGenResSubNorm()
Destructor.
SCT::magnitudeType MagnitudeType
int setTolerance(MagnitudeType)
Set the value of the tolerance.
int setQuorum(int)
Sets the number of residuals that must pass the convergence test before Passed is returned.
Teuchos::RCP< MV > getSolution()
Returns the current solution estimate that was computed for the most recent residual test.
const std::vector< MagnitudeType > * getScaledNormValue() const
Returns the scaled norm value, .
StatusType checkStatus(Iteration< ScalarType, MV, OP, DM > *)
Check convergence status: Passed, Failed, or Undefined.
StatusType firstCallCheckStatusSetup(Iteration< ScalarType, MV, OP, DM > *iSolver)
Call to setup initial scaling vector.
int getQuorum() const
Returns the number of residuals that must pass the convergence test before Passed is returned.
int defineResForm(NormType)
Define norm of the residual.
size_t getSubIdx() const
Returns the index of the block row the norms are calculated for.
void reset()
Resets the internal configuration to the initial state.
bool getShowMaxResNormOnly()
Returns whether the only maximum residual norm is displayed when the print() method is called.
StatusTestGenResSubNorm(MagnitudeType, size_t, int=-1, bool=false)
Constructor.
StatusType getStatus() const
Return the result of the most recent CheckStatus call.
bool getLOADetected() const
Returns a boolean indicating a loss of accuracy has been detected in computing the residual.
Teuchos::ScalarTraits< ScalarType > SCT
void print(std::ostream &, int=0) const
Output formatted description of stopping test to output stream.
int defineScaleForm(ScaleType, NormType, MagnitudeType=Teuchos::ScalarTraits< MagnitudeType >::one())
Define form of the scaling, its norm, its optional weighting vector, or, alternatively,...
MultiVecTraits< ScalarType, MV, DM > MVT
std::vector< int > convIndices()
Returns the std::vector containing the indices of the residuals that passed the test.
void printStatus(std::ostream &, StatusType) const
Print message for each status specific to this stopping test.
const std::vector< MagnitudeType > * getTestValue() const
Returns the test value, , computed in most recent call to CheckStatus.
std::string description() const
Method to return description of the maximum iteration status test
const std::vector< MagnitudeType > * getResNormValue() const
Returns the residual norm value, , computed in most recent call to CheckStatus.
MagnitudeType getTolerance() const
Returns the value of the tolerance, , set in the constructor.
int setShowMaxResNormOnly(bool)
Set whether the only maximum residual norm is displayed when the print() method is called.
int setSubIdx(size_t subIdx)
Set the block index of which we want to check the norm of the sub-residuals.
An abstract class of StatusTest for stopping criteria using residual norms.
NormType
The type of vector norm to compute.
StatusType
Whether the StatusTest wants iteration to stop.
Teuchos::SerialDenseMatrix< Ordinal, Scalar > DefaultDenseMatrix
ScaleType
The type of scaling to use on the residual norm value.
@ NormOfFullScaledPrecInitRes
@ NormOfFullScaledInitRes