80 const SolveCriteria<Scalar> &solveCriteria,
81 const int convergenceTestFrequency
86 typedef ScalarTraits<ScalarMag> SMT;
90 TEUCHOS_ASSERT_INEQUALITY(solveCriteria.requestedTol, >=, SMT::zero());
91 TEUCHOS_ASSERT_INEQUALITY(solveCriteria.solveMeasureType.numerator, !=, SOLVE_MEASURE_ONE);
92 TEUCHOS_ASSERT(nonnull(solveCriteria.numeratorReductionFunc) ||
93 nonnull(solveCriteria.denominatorReductionFunc) );
97 solveCriteria_ = solveCriteria;
98 convergenceTestFrequency_ = convergenceTestFrequency;
102 compute_r_ = solveCriteria.solveMeasureType.contains(SOLVE_MEASURE_NORM_RESIDUAL);
104 compute_x_ = (compute_r_ ||
105 solveCriteria.solveMeasureType.contains(SOLVE_MEASURE_NORM_SOLUTION));
124 Belos::Iteration<Scalar,MV,OP> *iSolver
131 TEUCHOS_ASSERT(iSolver);
134 const int currIter = iSolver->getNumIters();
136 if (currIter == 0 || currIter % convergenceTestFrequency_ != 0) {
138 return Belos::Undefined;
141 const RCP<FancyOStream> out = this->getOStream();
142 const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
144 const Belos::LinearProblem<Scalar,MV,OP>& lp = iSolver->getProblem();
145 const int numRhs = lp.getRHS()->domain()->dim();
148 if (solveCriteria_.solveMeasureType.contains(SOLVE_MEASURE_NORM_RHS)) {
149 TEUCHOS_TEST_FOR_EXCEPT_MSG(
true,
"ToDo: Handle ||b||");
153 if (solveCriteria_.solveMeasureType.contains(SOLVE_MEASURE_NORM_INIT_RESIDUAL)) {
154 TEUCHOS_TEST_FOR_EXCEPT_MSG(
true,
"ToDo: Handle ||r0||");
158 RCP<MultiVectorBase<Scalar> > X;
160 RCP<MV> X_update = iSolver->getCurrentUpdate();
161 X = lp.updateSolution(X_update);
165 RCP<MultiVectorBase<Scalar> > R;
167 R = createMembers(lp.getOperator()->range(), X->domain());
168 lp.computeCurrResVec(&*R, &*X);
173 lastNumerator_.resize(numRhs);
174 lastDenominator_.resize(numRhs);
176 for (
int j = 0; j < numRhs; ++j) {
177 const RCP<const VectorBase<Scalar> > x_j = (nonnull(X) ? X->col(j) : null);
178 const RCP<const VectorBase<Scalar> > r_j = (nonnull(R) ? R->col(j) : null);
179 lastNumerator_[j] = computeReductionFunctional(
180 solveCriteria_.solveMeasureType.numerator,
181 solveCriteria_.numeratorReductionFunc.ptr(),
182 x_j.ptr(), r_j.ptr() );
183 lastDenominator_[j] = computeReductionFunctional(
184 solveCriteria_.solveMeasureType.denominator,
185 solveCriteria_.denominatorReductionFunc.ptr(),
186 x_j.ptr(), r_j.ptr() );
191 bool systemsAreConverged =
true;
192 lastAchievedTol_.resize(numRhs);
194 for (
int j = 0; j < numRhs; ++j) {
195 const ScalarMag convRatio = lastNumerator_[j] / lastDenominator_[j];
196 lastAchievedTol_[j] = convRatio;
197 const bool sys_converged_j = (convRatio <= solveCriteria_.requestedTol);
198 if (includesVerbLevel(verbLevel, Teuchos::VERB_MEDIUM)) {
199 printRhsStatus(currIter, j, *out);
201 if (!sys_converged_j) {
202 systemsAreConverged =
false;
206 lastRtnStatus_ = (systemsAreConverged ? Belos::Passed : Belos::Failed);
207 lastCurrIter_ = currIter;
209 return lastRtnStatus_;
252 ESolveMeasureNormType measureType,
253 const Ptr<
const ReductionFunctional<Scalar> > &reductFunc,
254 const Ptr<
const VectorBase<Scalar> > &x,
255 const Ptr<
const VectorBase<Scalar> > &r
258 typedef ScalarTraits<ScalarMag> SMT;
260 Ptr<const VectorBase<Scalar> > v;
261 switch(measureType) {
262 case SOLVE_MEASURE_ONE:
265 case SOLVE_MEASURE_NORM_RESIDUAL:
268 case SOLVE_MEASURE_NORM_SOLUTION:
271 case SOLVE_MEASURE_NORM_INIT_RESIDUAL:
272 TEUCHOS_TEST_FOR_EXCEPT_MSG(
true,
"ToDo: Handle ||r0||!)")
273 case SOLVE_MEASURE_NORM_RHS:
274 TEUCHOS_TEST_FOR_EXCEPT_MSG(
true,
"ToDo: Handle ||b||!)");
275 TEUCHOS_SWITCH_DEFAULT_DEBUG_ASSERT();
277 if (rtn >= SMT::zero()) {
280 else if (nonnull(v) && rtn < SMT::zero()) {
281 if (nonnull(reductFunc)) {
282 rtn = reductFunc->reduce(*v);
288 TEUCHOS_IF_ELSE_DEBUG_ASSERT();