178 MagnitudeType zero = Teuchos::ScalarTraits<MagnitudeType>::zero();
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) {
219 Teuchos::RCP<MV> cur_update = iSolver->getCurrentUpdate();
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_) {
269 }
else if (testvector_[*p2] == Teuchos::ScalarTraits<Scalar>::magnitude(Teuchos::ScalarTraits<Scalar>::zero())) {
271 }
else if (testvector_[*p2] <= tolerance_) {
277 TEUCHOS_TEST_FOR_EXCEPTION(
true, StatusTestError,
"StatusTestGenResSubNorm::checkStatus(): NaN has been detected.");
282 int need = (quorum_ == -1) ? curNumRHS_ : quorum_;
283 status_ = (have >= need) ? Passed : Failed;
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) {
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;
412 MagnitudeType zero = Teuchos::ScalarTraits<MagnitudeType>::zero();
413 MagnitudeType one = Teuchos::ScalarTraits<MagnitudeType>::one();
414 const LinearProblem<Scalar, MV, OP>& lp = iSolver->getProblem();
416 if (firstcallCheckStatus_) {
420 firstcallCheckStatus_ =
false;
423 Teuchos::RCP<const OP> Op = lp.getOperator();
424 Teuchos::RCP<const Belos::XpetraOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> > xOp =
425 Teuchos::rcp_dynamic_cast<const Belos::XpetraOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(Op);
426 TEUCHOS_TEST_FOR_EXCEPTION(xOp.is_null(),
MueLu::Exceptions::BadCast,
"Bad cast from \'const Belos::OperatorT\' to \'const Belos::XpetraOp\'. The origin type is " <<
typeid(
const OP).name() <<
".");
427 Teuchos::RCP<const Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> > xIntOp =
429 TEUCHOS_TEST_FOR_EXCEPTION(xIntOp.is_null(),
MueLu::Exceptions::BadCast,
"Cannot access Xpetra::Operator stored in Belos::XpetraOperator.");
430 Teuchos::RCP<const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > xMat =
431 Teuchos::rcp_dynamic_cast<const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xIntOp);
433 Teuchos::RCP<const Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > bMat = Teuchos::rcp_dynamic_cast<const Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xMat);
434 TEUCHOS_TEST_FOR_EXCEPTION(bMat.is_null(),
MueLu::Exceptions::BadCast,
"Bad cast from \'const Xpetra::Matrix\' to \'const Xpetra::BlockedCrsMatrix\'. The origin type is " <<
typeid(
const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>).name() <<
". Note: you need a BlockedCrsMatrix object for the StatusTestGenResSubNorm to work!");
435 mapExtractor_ = bMat->getRangeMapExtractor();
437 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor_->NumMaps() <= subIdx_,
MueLu::Exceptions::RuntimeError,
"The multivector is only split into " << mapExtractor_->NumMaps() <<
" sub parts. Cannot access sub-block " << subIdx_ <<
".");
440 if (scaletype_ == NormOfRHS) {
441 Teuchos::RCP<const MV> rhs = lp.getRHS();
442 numrhs_ = MVT::GetNumberVecs(*rhs);
443 scalevector_.resize(numrhs_);
444 MvSubNorm(*rhs, subIdx_, scalevector_, scalenormtype_);
445 }
else if (scaletype_ == NormOfInitRes) {
446 Teuchos::RCP<const MV> init_res = lp.getInitResVec();
447 numrhs_ = MVT::GetNumberVecs(*init_res);
448 scalevector_.resize(numrhs_);
449 MvSubNorm(*init_res, subIdx_, scalevector_, scalenormtype_);
450 }
else if (scaletype_ == NormOfPrecInitRes) {
451 Teuchos::RCP<const MV> init_res = lp.getInitPrecResVec();
452 numrhs_ = MVT::GetNumberVecs(*init_res);
453 scalevector_.resize(numrhs_);
454 MvSubNorm(*init_res, subIdx_, scalevector_, scalenormtype_);
455 }
else if (scaletype_ == NormOfFullInitRes) {
456 Teuchos::RCP<const MV> init_res = lp.getInitResVec();
457 numrhs_ = MVT::GetNumberVecs(*init_res);
458 scalevector_.resize(numrhs_);
459 MVT::MvNorm(*init_res, scalevector_, scalenormtype_);
461 }
else if (scaletype_ == NormOfFullPrecInitRes) {
462 Teuchos::RCP<const MV> init_res = lp.getInitPrecResVec();
463 numrhs_ = MVT::GetNumberVecs(*init_res);
464 scalevector_.resize(numrhs_);
465 MVT::MvNorm(*init_res, scalevector_, scalenormtype_);
467 }
else if (scaletype_ == NormOfFullScaledInitRes) {
468 Teuchos::RCP<const MV> init_res = lp.getInitResVec();
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) {
474 Teuchos::RCP<const MV> init_res = lp.getInitPrecResVec();
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) {