10 #ifndef BELOS_XPETRA_STATUS_TEST_GEN_RES_SUB_NORM_HPP
11 #define BELOS_XPETRA_STATUS_TEST_GEN_RES_SUB_NORM_HPP
19 #include <BelosConfigDefs.hpp>
20 #include <BelosTypes.hpp>
21 #include <BelosOperatorT.hpp>
22 #include <BelosXpetraAdapterOperator.hpp>
23 #include <BelosStatusTestGenResSubNorm.hpp>
30 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
31 class StatusTestGenResSubNorm<
Scalar, Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>, Belos::OperatorT<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > >
32 :
public StatusTestResNorm<Scalar, Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>, Belos::OperatorT<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > > {
38 typedef Belos::OperatorT<MV>
OP;
42 typedef MultiVecTraits<Scalar, MV>
MVT;
43 typedef OperatorTraits<Scalar, MV, OP>
OT;
60 StatusTestGenResSubNorm(
MagnitudeType Tolerance,
size_t subIdx,
int quorum = -1,
bool showMaxResNormOnly =
false)
61 : tolerance_(Tolerance)
64 , showMaxResNormOnly_(showMaxResNormOnly)
65 , resnormtype_(TwoNorm)
66 , scaletype_(NormOfInitRes)
67 , scalenormtype_(TwoNorm)
74 , firstcallCheckStatus_(true)
75 , firstcallDefineResForm_(true)
76 , firstcallDefineScaleForm_(true)
77 , mapExtractor_(Teuchos::null) {}
80 virtual ~StatusTestGenResSubNorm(){};
93 int defineResForm(NormType TypeOfNorm) {
95 "StatusTestGenResSubNorm::defineResForm(): The residual form has already been defined.");
96 firstcallDefineResForm_ =
false;
98 resnormtype_ = TypeOfNorm;
126 "StatusTestGenResSubNorm::defineScaleForm(): The scaling type has already been defined.");
127 firstcallDefineScaleForm_ =
false;
129 scaletype_ = TypeOfScaling;
130 scalenormtype_ = TypeOfNorm;
131 scalevalue_ = ScaleValue;
140 int setTolerance(MagnitudeType tolerance) {
141 tolerance_ = tolerance;
148 int setSubIdx(
size_t subIdx) {
155 int setQuorum(
int quorum) {
161 int setShowMaxResNormOnly(
bool showMaxResNormOnly) {
162 showMaxResNormOnly_ = showMaxResNormOnly;
177 StatusType checkStatus(Iteration<Scalar, MV, OP>* iSolver) {
179 const LinearProblem<Scalar, MV, OP>& lp = iSolver->getProblem();
181 if (firstcallCheckStatus_) {
182 StatusType status = firstCallCheckStatusSetup(iSolver);
183 if (status == Failed) {
192 if (curLSNum_ != lp.getLSNumber()) {
196 curLSNum_ = lp.getLSNumber();
197 curLSIdx_ = lp.getLSIndex();
198 curBlksz_ = (int)curLSIdx_.size();
200 for (
int i = 0; i < curBlksz_; ++i) {
201 if (curLSIdx_[i] > -1 && curLSIdx_[i] < numrhs_)
204 curNumRHS_ = validLS;
205 curSoln_ = Teuchos::null;
211 if (status_ == Passed) {
220 curSoln_ = lp.updateSolution(cur_update);
221 Teuchos::RCP<MV> cur_res = MVT::Clone(*curSoln_, MVT::GetNumberVecs(*curSoln_));
222 lp.computeCurrResVec(&*cur_res, &*curSoln_);
223 std::vector<MagnitudeType> tmp_resvector(MVT::GetNumberVecs(*cur_res));
224 MvSubNorm(*cur_res, subIdx_, tmp_resvector, resnormtype_);
226 typename std::vector<int>::iterator p = curLSIdx_.begin();
227 for (
int i = 0; p < curLSIdx_.end(); ++p, ++i) {
230 resvector_[*p] = tmp_resvector[i];
237 if (scalevector_.size() > 0) {
238 typename std::vector<int>::iterator pp = curLSIdx_.begin();
239 for (; pp < curLSIdx_.end(); ++pp) {
243 if (scalevector_[*pp] != zero) {
245 testvector_[*pp] = resvector_[*pp] / scalevector_[*pp] / scalevalue_;
247 testvector_[*pp] = resvector_[*pp] / scalevalue_;
252 typename std::vector<int>::iterator pp = curLSIdx_.begin();
253 for (; pp < curLSIdx_.end(); ++pp) {
256 testvector_[*pp] = resvector_[*pp] / scalevalue_;
261 ind_.resize(curLSIdx_.size());
262 typename std::vector<int>::iterator p2 = curLSIdx_.begin();
263 for (; p2 < curLSIdx_.end(); ++p2) {
267 if (testvector_[*p2] > tolerance_) {
271 }
else if (testvector_[*p2] <= tolerance_) {
282 int need = (quorum_ == -1) ? curNumRHS_ : quorum_;
283 status_ = (have >= need) ? Passed : Failed;
289 StatusType getStatus()
const {
return (status_); };
303 firstcallCheckStatus_ =
true;
304 curSoln_ = Teuchos::null;
313 void print(std::ostream& os,
int indent = 0)
const {
314 os.setf(std::ios_base::scientific);
315 for (
int j = 0; j < indent; j++)
317 printStatus(os, status_);
319 if (status_ == Undefined)
320 os <<
", tol = " << tolerance_ << std::endl;
323 if (showMaxResNormOnly_ && curBlksz_ > 1) {
324 const MagnitudeType maxRelRes = *std::max_element(
325 testvector_.begin() + curLSIdx_[0], testvector_.begin() + curLSIdx_[curBlksz_ - 1]);
326 for (
int j = 0; j < indent + 13; j++)
328 os <<
"max{residual[" << curLSIdx_[0] <<
"..." << curLSIdx_[curBlksz_ - 1] <<
"]} = " << maxRelRes
329 << (maxRelRes <= tolerance_ ?
" <= " :
" > ") << tolerance_ << std::endl;
331 for (
int i = 0; i < numrhs_; i++) {
332 for (
int j = 0; j < indent + 13; j++)
334 os <<
"residual [ " << i <<
" ] = " << testvector_[i];
335 os << ((testvector_[i] < tolerance_) ?
" < " : (testvector_[i] == tolerance_) ?
" == "
336 : (testvector_[i] > tolerance_) ?
" > "
338 << tolerance_ << std::endl;
346 void printStatus(std::ostream& os, StatusType type)
const {
347 os << std::left << std::setw(13) << std::setfill(
'.');
360 os << std::left << std::setfill(
' ');
373 int getQuorum()
const {
return quorum_; }
376 size_t getSubIdx()
const {
return subIdx_; }
379 bool getShowMaxResNormOnly() {
return showMaxResNormOnly_; }
382 std::vector<int> convIndices() {
return ind_; }
385 MagnitudeType getTolerance()
const {
return (tolerance_); };
388 const std::vector<MagnitudeType>* getTestValue()
const {
return (&testvector_); };
391 const std::vector<MagnitudeType>* getResNormValue()
const {
return (&resvector_); };
394 const std::vector<MagnitudeType>* getScaledNormValue()
const {
return (&scalevector_); };
398 bool getLOADetected()
const {
return false; }
410 StatusType firstCallCheckStatusSetup(Iteration<Scalar, MV, OP>* iSolver) {
414 const LinearProblem<Scalar, MV, OP>& lp = iSolver->getProblem();
416 if (firstcallCheckStatus_) {
420 firstcallCheckStatus_ =
false;
425 Teuchos::rcp_dynamic_cast<
const Belos::XpetraOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(Op);
435 mapExtractor_ = bMat->getRangeMapExtractor();
440 if (scaletype_ == NormOfRHS) {
442 numrhs_ = MVT::GetNumberVecs(*rhs);
443 scalevector_.resize(numrhs_);
444 MvSubNorm(*rhs, subIdx_, scalevector_, scalenormtype_);
445 }
else if (scaletype_ == NormOfInitRes) {
447 numrhs_ = MVT::GetNumberVecs(*init_res);
448 scalevector_.resize(numrhs_);
449 MvSubNorm(*init_res, subIdx_, scalevector_, scalenormtype_);
450 }
else if (scaletype_ == NormOfPrecInitRes) {
452 numrhs_ = MVT::GetNumberVecs(*init_res);
453 scalevector_.resize(numrhs_);
454 MvSubNorm(*init_res, subIdx_, scalevector_, scalenormtype_);
455 }
else if (scaletype_ == NormOfFullInitRes) {
457 numrhs_ = MVT::GetNumberVecs(*init_res);
458 scalevector_.resize(numrhs_);
459 MVT::MvNorm(*init_res, scalevector_, scalenormtype_);
461 }
else if (scaletype_ == NormOfFullPrecInitRes) {
463 numrhs_ = MVT::GetNumberVecs(*init_res);
464 scalevector_.resize(numrhs_);
465 MVT::MvNorm(*init_res, scalevector_, scalenormtype_);
467 }
else if (scaletype_ == NormOfFullScaledInitRes) {
469 numrhs_ = MVT::GetNumberVecs(*init_res);
470 scalevector_.resize(numrhs_);
471 MVT::MvNorm(*init_res, scalevector_, scalenormtype_);
472 MvScalingRatio(*init_res, subIdx_, scalevalue_);
473 }
else if (scaletype_ == NormOfFullScaledPrecInitRes) {
475 numrhs_ = MVT::GetNumberVecs(*init_res);
476 scalevector_.resize(numrhs_);
477 MVT::MvNorm(*init_res, scalevector_, scalenormtype_);
478 MvScalingRatio(*init_res, subIdx_, scalevalue_);
480 numrhs_ = MVT::GetNumberVecs(*(lp.getRHS()));
483 resvector_.resize(numrhs_);
484 testvector_.resize(numrhs_);
486 curLSNum_ = lp.getLSNumber();
487 curLSIdx_ = lp.getLSIndex();
488 curBlksz_ = (int)curLSIdx_.size();
490 for (i = 0; i < curBlksz_; ++i) {
491 if (curLSIdx_[i] > -1 && curLSIdx_[i] < numrhs_)
494 curNumRHS_ = validLS;
497 for (i = 0; i < numrhs_; i++) {
498 testvector_[i] = one;
502 if (scalevalue_ == zero) {
514 std::string description()
const {
515 std::ostringstream oss;
516 oss <<
"Belos::StatusTestGenResSubNorm<>: " << resFormStr();
517 oss <<
", tol = " << tolerance_;
527 std::string resFormStr()
const {
528 std::ostringstream oss;
530 oss << ((resnormtype_ == OneNorm) ?
"1-Norm" : (resnormtype_ == TwoNorm) ?
"2-Norm"
533 oss <<
" Res Vec [" << subIdx_ <<
"]) ";
536 if (scaletype_ !=
None) {
541 if (scaletype_ == UserProvided)
542 oss <<
" (User Scale)";
545 oss << ((scalenormtype_ == OneNorm) ?
"1-Norm" : (resnormtype_ == TwoNorm) ?
"2-Norm"
547 if (scaletype_ == NormOfInitRes)
548 oss <<
" Res0 [" << subIdx_ <<
"]";
549 else if (scaletype_ == NormOfPrecInitRes)
550 oss <<
" Prec Res0 [" << subIdx_ <<
"]";
551 else if (scaletype_ == NormOfFullInitRes)
552 oss <<
" Full Res0 [" << subIdx_ <<
"]";
553 else if (scaletype_ == NormOfFullPrecInitRes)
554 oss <<
" Full Prec Res0 [" << subIdx_ <<
"]";
555 else if (scaletype_ == NormOfFullScaledInitRes)
556 oss <<
" scaled Full Res0 [" << subIdx_ <<
"]";
557 else if (scaletype_ == NormOfFullScaledPrecInitRes)
558 oss <<
" scaled Full Prec Res0 [" << subIdx_ <<
"]";
560 oss <<
" RHS [" << subIdx_ <<
"]";
580 MVT::MvNorm(*SubVec, normVec, type);
584 void MvScalingRatio(
const MV& mv,
size_t block, MagnitudeType& lengthRatio) {
589 lengthRatio = Teuchos::as<MagnitudeType>(SubVec->getGlobalLength()) / Teuchos::as<MagnitudeType>(input->getGlobalLength());
597 MagnitudeType tolerance_;
606 bool showMaxResNormOnly_;
609 NormType resnormtype_;
612 ScaleType scaletype_;
615 NormType scalenormtype_;
618 MagnitudeType scalevalue_;
621 std::vector<MagnitudeType> scalevector_;
624 std::vector<MagnitudeType> resvector_;
627 std::vector<MagnitudeType> testvector_;
630 std::vector<int> ind_;
645 std::vector<int> curLSIdx_;
654 bool firstcallCheckStatus_;
657 bool firstcallDefineResForm_;
660 bool firstcallDefineScaleForm_;
Exception indicating invalid cast attempted.
SCT::magnitudeType MagnitudeType
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
MultiVecTraits< Scalar, MV > MVT
MueLu::DefaultScalar Scalar
OperatorTraits< Scalar, MV, OP > OT
Teuchos::ScalarTraits< Scalar > SCT
Xpetra::BlockedCrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > BCRS
Xpetra::MapExtractor< Scalar, LocalOrdinal, GlobalOrdinal, Node > ME
Exception throws to report errors in the internal logical of the program.
Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > MV
Belos::OperatorT< MV > OP