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).");
86 TEUCHOS_UNREACHABLE_RETURN(0);
112 "StatusTestGenResSubNorm::defineScaleForm(): StatusTestGenResSubNorm only available for blocked operators (e.g., Thyra).");
113 TEUCHOS_UNREACHABLE_RETURN(0);
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;
244 typedef Teuchos::ScalarTraits<ScalarType>
SCT;
246 typedef MultiVecTraits<ScalarType,MV,DM>
MVT;
247 typedef OperatorTraits<ScalarType,MV,OP> OT;
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 );
411 lp.computeCurrResVec( &*cur_res, &*curSoln_ );
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();
613 scalevector_.resize( numrhs_ );
614 MvSubNorm( *rhs, subIdx_, scalevector_, scalenormtype_ );
617 Teuchos::RCP<const MV> init_res = lp.getInitResVec();
619 scalevector_.resize( numrhs_ );
620 MvSubNorm( *init_res, subIdx_, scalevector_, scalenormtype_ );
623 Teuchos::RCP<const MV> init_res = lp.getInitPrecResVec();
625 scalevector_.resize( numrhs_ );
626 MvSubNorm( *init_res, subIdx_, scalevector_, scalenormtype_ );
629 Teuchos::RCP<const MV> init_res = lp.getInitResVec();
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();
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();
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();
652 scalevector_.resize( numrhs_ );
653 MVT::MvNorm( *init_res, scalevector_, scalenormtype_ );
654 MvScalingRatio( *init_res, subIdx_, scalevalue_ );
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);
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.
Traits class which defines basic operations on multivectors.
static void MvNorm(const MV &mv, std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &normvec, NormType type=TwoNorm)
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
static int GetNumberVecs(const MV &mv)
Exception thrown to signal error in a status test during Belos::StatusTest::checkStatus().
virtual ~StatusTestGenResSubNorm()
Destructor.
SCT::magnitudeType MagnitudeType
int setTolerance(MagnitudeType)
Set the value of the tolerance.
Teuchos::RCP< MV > getSolution()
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 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
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.
ScaleType
The type of scaling to use on the residual norm value.
@ NormOfFullScaledPrecInitRes
@ NormOfFullScaledInitRes
Teuchos::SerialDenseMatrix< Ordinal, Scalar > DefaultDenseMatrix