* Change maximum number of steps.
*/
unsigned int set_max_steps (const unsigned int);
+
+ /**
+ * Enables the failure
+ * check. Solving is stopped with
+ * @p{ReturnState} @p{failure} if
+ * @p{residual>failure_residual} with
+ * @p{failure_residual:=rel_failure_residual*first_residual}.
+ */
+ void set_failure_criterion (const double rel_failure_residual);
+
+ /**
+ * Disables failure check and
+ * resets
+ * @p{relative_failure_residual}
+ * and @p{failure_residual} to
+ * zero.
+ */
+ void clear_failure_criterion ();
/**
* Tolerance.
* Prescribed tolerance to be achieved.
*/
double tol;
-
+
/**
* Last value of the convergence criterion.
*/
*/
unsigned int lstep;
+ /**
+ * Is set to @p{true} by
+ * @p{set_failure_criterion} and
+ * enables failure checking.
+ */
+ bool check_failure;
+
+ /*
+ * Stores the
+ * @p{rel_failure_residual} set by
+ * @p{set_failure_criterion}
+ */
+ double relative_failure_residual;
+
+
+ /**
+ * @p{failure_residual} equals the
+ * first residual multiplied by
+ * @p{relative_crit} set by
+ * @p{set_failure_criterion} (see there).
+ *
+ * Until the first residual is
+ * known it is 0.
+ */
+ double failure_residual;
+
+
/**
* Log convergence history to @p{deallog}.
*/
}
+inline void
+SolverControl::set_failure_criterion (const double rel_failure_residual)
+{
+ relative_failure_residual=rel_failure_residual;
+ check_failure=true;
+}
+
+
+inline void
+SolverControl::clear_failure_criterion ()
+{
+ relative_failure_residual=0;
+ failure_residual=0;
+ check_failure=false;
+}
+
+
inline double
SolverControl::tolerance () const
{
#include <base/parameter_handler.h>
#include <lac/solver_control.h>
+#include <cmath>
/*----------------------- SolverControl ---------------------------------*/
tol(tolerance),
lvalue(1.e300),
lstep(0),
+ check_failure(false),
+ relative_failure_residual(0),
+ failure_residual(0),
_log_history(_log_history),
_log_frequency(1),
_log_result(_log_result)
lstep = step;
lvalue = check_value;
- if ((step==0) && _log_result)
- deallog << "Starting value " << check_value << endl;
+ if (step==0)
+ {
+ if (check_failure)
+ failure_residual=relative_failure_residual*check_value;
+
+ if (_log_result)
+ deallog << "Starting value " << check_value << endl;
+ }
- if (step >= maxsteps)
+
+ if ((step >= maxsteps) ||
+ (check_failure && ((check_value > failure_residual) ||
+ isnan(check_value))))
{
if (_log_result)
deallog << "Failure step " << step
<< " value " << check_value << endl;
return success;
}
+
return iterate;
}