179 MagnitudeType zero = Teuchos::ScalarTraits<MagnitudeType>::zero();
180 const LinearProblem<Scalar, MV, OP>& lp = iSolver->getProblem();
182 if (firstcallCheckStatus_) {
183 StatusType status = firstCallCheckStatusSetup(iSolver);
184 if (status == Failed) {
193 if (curLSNum_ != lp.getLSNumber()) {
197 curLSNum_ = lp.getLSNumber();
198 curLSIdx_ = lp.getLSIndex();
199 curBlksz_ = (int)curLSIdx_.size();
201 for (
int i = 0; i < curBlksz_; ++i) {
202 if (curLSIdx_[i] > -1 && curLSIdx_[i] < numrhs_)
205 curNumRHS_ = validLS;
206 curSoln_ = Teuchos::null;
212 if (status_ == Passed) {
220 Teuchos::RCP<MV> cur_update = iSolver->getCurrentUpdate();
221 curSoln_ = lp.updateSolution(cur_update);
222 Teuchos::RCP<MV> cur_res = MVT::Clone(*curSoln_, MVT::GetNumberVecs(*curSoln_));
223 lp.computeCurrResVec(&*cur_res, &*curSoln_);
224 std::vector<MagnitudeType> tmp_resvector(MVT::GetNumberVecs(*cur_res));
225 MvSubNorm(*cur_res, subIdx_, tmp_resvector, resnormtype_);
227 typename std::vector<int>::iterator p = curLSIdx_.begin();
228 for (
int i = 0; p < curLSIdx_.end(); ++p, ++i) {
231 resvector_[*p] = tmp_resvector[i];
238 if (scalevector_.size() > 0) {
239 typename std::vector<int>::iterator pp = curLSIdx_.begin();
240 for (; pp < curLSIdx_.end(); ++pp) {
244 if (scalevector_[*pp] != zero) {
246 testvector_[*pp] = resvector_[*pp] / scalevector_[*pp] / scalevalue_;
248 testvector_[*pp] = resvector_[*pp] / scalevalue_;
253 typename std::vector<int>::iterator pp = curLSIdx_.begin();
254 for (; pp < curLSIdx_.end(); ++pp) {
257 testvector_[*pp] = resvector_[*pp] / scalevalue_;
262 ind_.resize(curLSIdx_.size());
263 typename std::vector<int>::iterator p2 = curLSIdx_.begin();
264 for (; p2 < curLSIdx_.end(); ++p2) {
268 if (testvector_[*p2] > tolerance_) {
270 }
else if (testvector_[*p2] == Teuchos::ScalarTraits<Scalar>::magnitude(Teuchos::ScalarTraits<Scalar>::zero())) {
272 }
else if (testvector_[*p2] <= tolerance_) {
278 TEUCHOS_TEST_FOR_EXCEPTION(
true, StatusTestError,
"StatusTestGenResSubNorm::checkStatus(): NaN has been detected.");
283 int need = (quorum_ == -1) ? curNumRHS_ : quorum_;
284 status_ = (have >= need) ? Passed : Failed;
314 void print(std::ostream& os,
int indent = 0)
const {
315 os.setf(std::ios_base::scientific);
316 for (
int j = 0; j < indent; j++)
318 printStatus(os, status_);
320 if (status_ == Undefined)
321 os <<
", tol = " << tolerance_ << std::endl;
324 if (showMaxResNormOnly_ && curBlksz_ > 1) {
326 testvector_.begin() + curLSIdx_[0], testvector_.begin() + curLSIdx_[curBlksz_ - 1]);
327 for (
int j = 0; j < indent + 13; j++)
329 os <<
"max{residual[" << curLSIdx_[0] <<
"..." << curLSIdx_[curBlksz_ - 1] <<
"]} = " << maxRelRes
330 << (maxRelRes <= tolerance_ ?
" <= " :
" > ") << tolerance_ << std::endl;
332 for (
int i = 0; i < numrhs_; i++) {
333 for (
int j = 0; j < indent + 13; j++)
335 os <<
"residual [ " << i <<
" ] = " << testvector_[i];
336 os << ((testvector_[i] < tolerance_) ?
" < " : (testvector_[i] == tolerance_) ?
" == "
337 : (testvector_[i] > tolerance_) ?
" > "
339 << tolerance_ << std::endl;
413 MagnitudeType zero = Teuchos::ScalarTraits<MagnitudeType>::zero();
414 MagnitudeType one = Teuchos::ScalarTraits<MagnitudeType>::one();
415 const LinearProblem<Scalar, MV, OP>& lp = iSolver->getProblem();
417 if (firstcallCheckStatus_) {
421 firstcallCheckStatus_ =
false;
424 Teuchos::RCP<const OP> Op = lp.getOperator();
425 Teuchos::RCP<const Belos::XpetraOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> > xOp =
426 Teuchos::rcp_dynamic_cast<const Belos::XpetraOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(Op);
427 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() <<
".");
428 Teuchos::RCP<const Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> > xIntOp =
430 TEUCHOS_TEST_FOR_EXCEPTION(xIntOp.is_null(),
MueLu::Exceptions::BadCast,
"Cannot access Xpetra::Operator stored in Belos::XpetraOperator.");
431 Teuchos::RCP<const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > xMat =
432 Teuchos::rcp_dynamic_cast<const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xIntOp);
434 Teuchos::RCP<const Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > bMat = Teuchos::rcp_dynamic_cast<const Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xMat);
435 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!");
436 mapExtractor_ = bMat->getRangeMapExtractor();
438 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_ <<
".");
441 if (scaletype_ == NormOfRHS) {
442 Teuchos::RCP<const MV> rhs = lp.getRHS();
443 numrhs_ = MVT::GetNumberVecs(*rhs);
444 scalevector_.resize(numrhs_);
445 MvSubNorm(*rhs, subIdx_, scalevector_, scalenormtype_);
446 }
else if (scaletype_ == NormOfInitRes) {
447 Teuchos::RCP<const MV> init_res = lp.getInitResVec();
448 numrhs_ = MVT::GetNumberVecs(*init_res);
449 scalevector_.resize(numrhs_);
450 MvSubNorm(*init_res, subIdx_, scalevector_, scalenormtype_);
451 }
else if (scaletype_ == NormOfPrecInitRes) {
452 Teuchos::RCP<const MV> init_res = lp.getInitPrecResVec();
453 numrhs_ = MVT::GetNumberVecs(*init_res);
454 scalevector_.resize(numrhs_);
455 MvSubNorm(*init_res, subIdx_, scalevector_, scalenormtype_);
456 }
else if (scaletype_ == NormOfFullInitRes) {
457 Teuchos::RCP<const MV> init_res = lp.getInitResVec();
458 numrhs_ = MVT::GetNumberVecs(*init_res);
459 scalevector_.resize(numrhs_);
460 MVT::MvNorm(*init_res, scalevector_, scalenormtype_);
462 }
else if (scaletype_ == NormOfFullPrecInitRes) {
463 Teuchos::RCP<const MV> init_res = lp.getInitPrecResVec();
464 numrhs_ = MVT::GetNumberVecs(*init_res);
465 scalevector_.resize(numrhs_);
466 MVT::MvNorm(*init_res, scalevector_, scalenormtype_);
468 }
else if (scaletype_ == NormOfFullScaledInitRes) {
469 Teuchos::RCP<const MV> init_res = lp.getInitResVec();
470 numrhs_ = MVT::GetNumberVecs(*init_res);
471 scalevector_.resize(numrhs_);
472 MVT::MvNorm(*init_res, scalevector_, scalenormtype_);
473 MvScalingRatio(*init_res, subIdx_, scalevalue_);
474 }
else if (scaletype_ == NormOfFullScaledPrecInitRes) {
475 Teuchos::RCP<const MV> init_res = lp.getInitPrecResVec();
476 numrhs_ = MVT::GetNumberVecs(*init_res);
477 scalevector_.resize(numrhs_);
478 MVT::MvNorm(*init_res, scalevector_, scalenormtype_);
479 MvScalingRatio(*init_res, subIdx_, scalevalue_);
481 numrhs_ = MVT::GetNumberVecs(*(lp.getRHS()));
484 resvector_.resize(numrhs_);
485 testvector_.resize(numrhs_);
487 curLSNum_ = lp.getLSNumber();
488 curLSIdx_ = lp.getLSIndex();
489 curBlksz_ = (int)curLSIdx_.size();
491 for (i = 0; i < curBlksz_; ++i) {
492 if (curLSIdx_[i] > -1 && curLSIdx_[i] < numrhs_)
495 curNumRHS_ = validLS;
498 for (i = 0; i < numrhs_; i++) {
499 testvector_[i] = one;
503 if (scalevalue_ == zero) {