StatusType NormUpdate::checkStatus(const Solver::Generic& problem, NOX::StatusTest::CheckType checkType) { if (checkType == None) { status = Unevaluated; normUpdate = -1.0; return status; } // On the first iteration, the old and current solution are the same so // we should return the test as unconverged until there is a valid // old solution (i.e. the number of iterations is greater than zero). int niters = problem.getNumIterations(); if (niters == 0) { status = Unconverged; normUpdate = -1.0; return status; } // Check that F exists! if (!problem.getSolutionGroup().isF()) { status = Unconverged; normUpdate = -1.0; return status; } const Abstract::Vector& oldSoln = problem.getPreviousSolutionGroup().getX(); const Abstract::Vector& curSoln = problem.getSolutionGroup().getX(); if (Teuchos::is_null(updateVectorPtr)) updateVectorPtr = curSoln.clone(); updateVectorPtr->update(1.0, curSoln, -1.0, oldSoln, 0.0); int n = (scaleType == Scaled) ? updateVectorPtr->length() : 0; switch (normType) { case NOX::Abstract::Vector::TwoNorm: normUpdate = updateVectorPtr->norm(); if (scaleType == Scaled) normUpdate /= sqrt(1.0 * n); break; default: normUpdate = updateVectorPtr->norm(normType); if (scaleType == Scaled) normUpdate /= n; break; } status = (normUpdate < tolerance) ? Converged : Unconverged; return status; }
NOX::StatusTest::StatusType NOX::StatusTest::Stagnation:: checkStatus(const Solver::Generic& problem, NOX::StatusTest::CheckType checkType) { status = Unconverged; // This test should ignore the checkType! This test must be run // each iteration because it triggers after a set number of // iterations. // First time through we don't do anything int niters = problem.getNumIterations(); if (niters == 0) { lastIteration = 0; numSteps = 0; return Unconverged; } // Make sure we have not already counted the last nonlinear iteration. // This protects against multiple calls to checkStatus() in between // nonlinear iterations. bool isCounted = false; if (niters == lastIteration) { isCounted = true; } else lastIteration = niters; // Compute the convergence rate and set counter appropriately if (!isCounted) { convRate = problem.getSolutionGroup().getNormF() / problem.getPreviousSolutionGroup().getNormF(); if (convRate >= tolerance) numSteps ++; else numSteps = 0; } if (numSteps >= maxSteps) status = Failed; return status; }
NOX::StatusTest::StatusType NOX::StatusTest::FiniteValue:: checkStatus(const Solver::Generic& problem, NOX::StatusTest::CheckType checkType) { // Reset the check normValue = -1.0; const NOX::Abstract::Group& grp = problem.getSolutionGroup(); switch (checkType) { case NOX::StatusTest::Complete: case NOX::StatusTest::Minimal: if (vectorType == FVector) { if (normType == NOX::Abstract::Vector::TwoNorm) normValue = grp.getNormF(); // More efficient than recomputing norm else normValue = grp.getF().norm(normType); } else normValue = grp.getX().norm(normType); result = finiteNumberTest(normValue); status = (result == 0) ? Unconverged : Failed; break; case NOX::StatusTest::None: default: result = 1; status = Unevaluated; break; } return status; }