268 :
public StatusTestResNorm<ScalarType,Thyra::MultiVectorBase<ScalarType>,Thyra::LinearOpBase<ScalarType> > {
272 typedef Thyra::MultiVectorBase<ScalarType>
MV;
273 typedef Thyra::LinearOpBase<ScalarType>
OP;
275 typedef Teuchos::ScalarTraits<ScalarType>
SCT;
296 : tolerance_(Tolerance),
299 showMaxResNormOnly_(showMaxResNormOnly),
309 firstcallCheckStatus_(true),
310 firstcallDefineResForm_(true),
311 firstcallDefineScaleForm_(true) { }
327 int defineResForm(
NormType TypeOfNorm) {
328 TEUCHOS_TEST_FOR_EXCEPTION(firstcallDefineResForm_==
false,StatusTestError,
329 "StatusTestGenResSubNorm::defineResForm(): The residual form has already been defined.");
330 firstcallDefineResForm_ =
false;
332 resnormtype_ = TypeOfNorm;
359 TEUCHOS_TEST_FOR_EXCEPTION(firstcallDefineScaleForm_==
false,StatusTestError,
360 "StatusTestGenResSubNorm::defineScaleForm(): The scaling type has already been defined.");
361 firstcallDefineScaleForm_ =
false;
363 scaletype_ = TypeOfScaling;
364 scalenormtype_ = TypeOfNorm;
365 scalevalue_ = ScaleValue;
379 int setSubIdx (
size_t subIdx ) { subIdx_ = subIdx;
return(0);}
383 int setQuorum(
int quorum) {quorum_ = quorum;
return(0);}
386 int setShowMaxResNormOnly(
bool showMaxResNormOnly) {showMaxResNormOnly_ = showMaxResNormOnly;
return(0);}
400 MagnitudeType zero = Teuchos::ScalarTraits<MagnitudeType>::zero();
401 const LinearProblem<ScalarType,MV,OP>& lp = iSolver->getProblem();
403 if (firstcallCheckStatus_) {
404 StatusType status = firstCallCheckStatusSetup(iSolver);
414 if ( curLSNum_ != lp.getLSNumber() ) {
418 curLSNum_ = lp.getLSNumber();
419 curLSIdx_ = lp.getLSIndex();
420 curBlksz_ = (int)curLSIdx_.size();
422 for (
int i=0; i<curBlksz_; ++i) {
423 if (curLSIdx_[i] > -1 && curLSIdx_[i] < numrhs_)
426 curNumRHS_ = validLS;
427 curSoln_ = Teuchos::null;
433 if (status_==
Passed) {
return status_; }
439 Teuchos::RCP<MV> cur_update = iSolver->getCurrentUpdate();
440 curSoln_ = lp.updateSolution( cur_update );
442 lp.computeCurrResVec( &*cur_res, &*curSoln_ );
444 MvSubNorm( *cur_res, subIdx_, tmp_resvector, resnormtype_ );
446 typename std::vector<int>::iterator pp = curLSIdx_.begin();
447 for (
int i=0; pp<curLSIdx_.end(); ++pp, ++i) {
450 resvector_[*pp] = tmp_resvector[i];
457 if ( scalevector_.size() > 0 ) {
458 typename std::vector<int>::iterator p = curLSIdx_.begin();
459 for (; p<curLSIdx_.end(); ++p) {
463 if ( scalevector_[ *p ] != zero ) {
465 testvector_[ *p ] = resvector_[ *p ] / scalevector_[ *p ] / scalevalue_;
467 testvector_[ *p ] = resvector_[ *p ] / scalevalue_;
473 typename std::vector<int>::iterator ppp = curLSIdx_.begin();
474 for (; ppp<curLSIdx_.end(); ++ppp) {
477 testvector_[ *ppp ] = resvector_[ *ppp ] / scalevalue_;
482 ind_.resize( curLSIdx_.size() );
483 typename std::vector<int>::iterator p2 = curLSIdx_.begin();
484 for (; p2<curLSIdx_.end(); ++p2) {
488 if (testvector_[ *p2 ] > tolerance_) {
490 }
else if (testvector_[ *p2 ] <= tolerance_) {
496 TEUCHOS_TEST_FOR_EXCEPTION(
true,StatusTestError,
"StatusTestGenResSubNorm::checkStatus(): NaN has been detected.");
501 int need = (quorum_ == -1) ? curNumRHS_: quorum_;
522 firstcallCheckStatus_ =
true;
523 curSoln_ = Teuchos::null;
532 void print(std::ostream& os,
int indent = 0)
const {
533 os.setf(std::ios_base::scientific);
534 for (
int j = 0; j < indent; j ++)
539 os <<
", tol = " << tolerance_ << std::endl;
542 if(showMaxResNormOnly_ && curBlksz_ > 1) {
544 testvector_.begin()+curLSIdx_[0],testvector_.begin()+curLSIdx_[curBlksz_-1]
546 for (
int j = 0; j < indent + 13; j ++)
548 os <<
"max{residual["<<curLSIdx_[0]<<
"..."<<curLSIdx_[curBlksz_-1]<<
"]} = " << maxRelRes
549 << ( maxRelRes <= tolerance_ ?
" <= " :
" > " ) << tolerance_ << std::endl;
552 for (
int i=0; i<numrhs_; i++ ) {
553 for (
int j = 0; j < indent + 13; j ++)
555 os <<
"residual [ " << i <<
" ] = " << testvector_[ i ];
556 os << ((testvector_[i]<tolerance_) ?
" < " : (testvector_[i]==tolerance_) ?
" == " : (testvector_[i]>tolerance_) ?
" > " :
" " ) << tolerance_ << std::endl;
565 os << std::left << std::setw(13) << std::setfill(
'.');
578 os << std::left << std::setfill(
' ');
587 Teuchos::RCP<MV>
getSolution() {
return curSoln_; }
591 int getQuorum()
const {
return quorum_; }
594 size_t getSubIdx()
const {
return subIdx_; }
606 const std::vector<MagnitudeType>*
getTestValue()
const {
return(&testvector_);};
609 const std::vector<MagnitudeType>* getResNormValue()
const {
return(&resvector_);};
612 const std::vector<MagnitudeType>* getScaledNormValue()
const {
return(&scalevector_);};
629 StatusType firstCallCheckStatusSetup(Iteration<ScalarType,MV,OP>* iSolver) {
631 MagnitudeType zero = Teuchos::ScalarTraits<MagnitudeType>::zero();
632 MagnitudeType one = Teuchos::ScalarTraits<MagnitudeType>::one();
633 const LinearProblem<ScalarType,MV,OP>& lp = iSolver->getProblem();
635 if (firstcallCheckStatus_) {
639 firstcallCheckStatus_ =
false;
642 Teuchos::RCP<const MV> rhs = lp.getRHS();
644 scalevector_.resize( numrhs_ );
645 MvSubNorm( *rhs, subIdx_, scalevector_, scalenormtype_ );
648 Teuchos::RCP<const MV> init_res = lp.getInitResVec();
650 scalevector_.resize( numrhs_ );
651 MvSubNorm( *init_res, subIdx_, scalevector_, scalenormtype_ );
654 Teuchos::RCP<const MV> init_res = lp.getInitPrecResVec();
656 scalevector_.resize( numrhs_ );
657 MvSubNorm( *init_res, subIdx_, scalevector_, scalenormtype_ );
660 Teuchos::RCP<const MV> init_res = lp.getInitResVec();
662 scalevector_.resize( numrhs_ );
663 MVT::MvNorm( *init_res, scalevector_, scalenormtype_ );
664 scalevalue_ = Teuchos::ScalarTraits<MagnitudeType>::one();
667 Teuchos::RCP<const MV> init_res = lp.getInitPrecResVec();
669 scalevector_.resize( numrhs_ );
670 MVT::MvNorm( *init_res, scalevector_, scalenormtype_ );
671 scalevalue_ = Teuchos::ScalarTraits<MagnitudeType>::one();
674 Teuchos::RCP<const MV> init_res = lp.getInitResVec();
676 scalevector_.resize( numrhs_ );
677 MVT::MvNorm( *init_res, scalevector_, scalenormtype_ );
678 MvScalingRatio( *init_res, subIdx_, scalevalue_ );
681 Teuchos::RCP<const MV> init_res = lp.getInitPrecResVec();
683 scalevector_.resize( numrhs_ );
684 MVT::MvNorm( *init_res, scalevector_, scalenormtype_ );
685 MvScalingRatio( *init_res, subIdx_, scalevalue_ );
691 resvector_.resize( numrhs_ );
692 testvector_.resize( numrhs_ );
694 curLSNum_ = lp.getLSNumber();
695 curLSIdx_ = lp.getLSIndex();
696 curBlksz_ = (int)curLSIdx_.size();
698 for (i=0; i<curBlksz_; ++i) {
699 if (curLSIdx_[i] > -1 && curLSIdx_[i] < numrhs_)
702 curNumRHS_ = validLS;
705 for (i=0; i<numrhs_; i++) { testvector_[i] = one; }
708 if (scalevalue_ == zero) {
720 std::string description()
const
722 std::ostringstream oss;
723 oss <<
"Belos::StatusTestGenResSubNorm<>: " << resFormStr();
724 oss <<
", tol = " << tolerance_;
736 std::string resFormStr()
const
738 std::ostringstream oss;
740 oss << ((resnormtype_==
OneNorm) ?
"1-Norm" : (resnormtype_==
TwoNorm) ?
"2-Norm" :
"Inf-Norm");
742 oss <<
" Res Vec [" << subIdx_ <<
"]) ";
745 if (scaletype_!=
None)
752 oss <<
" (User Scale)";
755 oss << ((scalenormtype_==
OneNorm) ?
"1-Norm" : (resnormtype_==
TwoNorm) ?
"2-Norm" :
"Inf-Norm");
757 oss <<
" Res0 [" << subIdx_ <<
"]";
759 oss <<
" Prec Res0 [" << subIdx_ <<
"]";
761 oss <<
" Full Res0 [" << subIdx_ <<
"]";
763 oss <<
" Full Prec Res0 [" << subIdx_ <<
"]";
765 oss <<
" scaled Full Res0 [" << subIdx_ <<
"]";
767 oss <<
" scaled Full Prec Res0 [" << subIdx_ <<
"]";
769 oss <<
" RHS [" << subIdx_ <<
"]";
785 void MvSubNorm(
const MV& mv,
size_t block, std::vector<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>& normVec,
NormType type =
TwoNorm) {
786 Teuchos::RCP<const MV> input = Teuchos::rcpFromRef(mv);
788 typedef typename Thyra::ProductMultiVectorBase<ScalarType> TPMVB;
789 Teuchos::RCP<const TPMVB> thyProdVec = Teuchos::rcp_dynamic_cast<const TPMVB>(input);
791 TEUCHOS_TEST_FOR_EXCEPTION(thyProdVec == Teuchos::null, std::invalid_argument,
792 "Belos::StatusTestGenResSubNorm::MvSubNorm (Thyra specialization): "
793 "mv must be a Thyra::ProductMultiVector, but is of type " << thyProdVec);
795 Teuchos::RCP<const MV> thySubVec = thyProdVec->getMultiVectorBlock(block);
801 void MvScalingRatio(
const MV& mv,
size_t block,
MagnitudeType& lengthRatio) {
802 Teuchos::RCP<const MV> input = Teuchos::rcpFromRef(mv);
804 typedef typename Thyra::ProductMultiVectorBase<ScalarType> TPMVB;
805 Teuchos::RCP<const TPMVB> thyProdVec = Teuchos::rcp_dynamic_cast<const TPMVB>(input);
807 TEUCHOS_TEST_FOR_EXCEPTION(thyProdVec == Teuchos::null, std::invalid_argument,
808 "Belos::StatusTestGenResSubNorm::MvScalingRatio (Thyra specialization): "
809 "mv must be a Thyra::ProductMultiVector, but is of type " << thyProdVec);
811 Teuchos::RCP<const MV> thySubVec = thyProdVec->getMultiVectorBlock(block);
813 lengthRatio = Teuchos::as<MagnitudeType>(thySubVec->range()->dim()) / Teuchos::as<MagnitudeType>(thyProdVec->range()->dim());
831 bool showMaxResNormOnly_;
846 std::vector<MagnitudeType> scalevector_;
849 std::vector<MagnitudeType> resvector_;
852 std::vector<MagnitudeType> testvector_;
855 std::vector<int> ind_;
858 Teuchos::RCP<MV> curSoln_;
870 std::vector<int> curLSIdx_;
879 bool firstcallCheckStatus_;
882 bool firstcallDefineResForm_;
885 bool firstcallDefineScaleForm_;