#include <base/config.h>
#include <base/subscriptor.h>
+#include <vector>
+
class ParameterHandler;
/*!@addtogroup Solvers */
*/
double set_tolerance (const double);
+ /**
+ * Enables writing residuals of
+ * each step into a vector for
+ * later analysis.
+ */
+ void enable_history_data();
+
+ /**
+ * Average error reduction over
+ * all steps.
+ *
+ * Requires
+ * enable_history_data()
+ */
+ double average_reduction() const;
+ /**
+ * Error reduction of the last
+ * step; for stationary
+ * iterations, this approximates
+ * the norm of the iteration
+ * matrix.
+ *
+ * Requires
+ * enable_history_data()
+ */
+ double final_reduction() const;
+
+ /**
+ * Error reduction of any
+ * iteration step.
+ *
+ * Requires
+ * enable_history_data()
+ */
+ double step_reduction(unsigned int step) const;
+
/**
* Log each iteration step. Use
* @p log_frequency for skipping
* Returns the @p log_result flag.
*/
bool log_result () const;
+
+ /**
+ * This exception is thrown if a
+ * function operating on the
+ * vector of history data of a
+ * SolverControl object id
+ * called, but storage of history
+ * data was not enabled by
+ * enable_history_data().
+ */
+ DeclException0(ExcHistoryDataRequired);
protected:
/**
* and @p lvalue are logged.
*/
bool m_log_result;
+
+ /**
+ * Control over the storage of
+ * history data. Set by
+ * enable_history_data().
+ */
+ bool history_data_enabled;
+
+ /**
+ * Vector storing the result
+ * after each iteration step for
+ * later statistical analysis.
+ *
+ * Use of this vector is enabled
+ * by enable_history_data().
+ */
+ std::vector<double> history_data;
};
+
//! Control of the stopping criterion depending on the initial residual.
/**
* Specialization of @p SolverControl which returns @p success if either
failure_residual(0),
m_log_history(m_log_history),
m_log_frequency(1),
- m_log_result(m_log_result)
+ m_log_result(m_log_result),
+ history_data_enabled(false)
{}
// come here, then store the
// residual for later comparisons
if (step==0)
- initial_val = check_value;
-
+ {
+ initial_val = check_value;
+ if (history_data_enabled)
+ history_data.resize(maxsteps);
+ }
+
if (m_log_history && ((step % m_log_frequency) == 0))
deallog << "Check " << step << "\t" << check_value << std::endl;
deallog << "Starting value " << check_value << std::endl;
}
+ if (history_data_enabled)
+ history_data[step] = check_value;
+
if (check_value <= tol)
{
if (m_log_result)
}
+void
+SolverControl::enable_history_data ()
+{
+ history_data_enabled = true;
+}
+
+
+double
+SolverControl::average_reduction() const
+{
+ if (lstep == 0)
+ return 0.;
+
+ Assert (history_data_enabled, ExcHistoryDataRequired());
+ Assert (history_data.size() > lstep, ExcInternalError());
+ Assert (history_data[0] > 0., ExcInternalError());
+ Assert (history_data[lstep] > 0., ExcInternalError());
+
+ return std::pow(history_data[lstep]/history_data[0], 1./lstep);
+}
+
+
+
+double
+SolverControl::step_reduction(unsigned int step) const
+{
+ Assert (history_data_enabled, ExcHistoryDataRequired());
+ Assert (history_data.size() > lstep, ExcInternalError());
+ Assert (step <=lstep, ExcIndexRange(step,1,lstep+1));
+ Assert (step>0, ExcIndexRange(step,1,lstep+1));
+
+ return history_data[step]/history_data[step-1];
+}
+
+
+double
+SolverControl::final_reduction() const
+{
+ return step_reduction(lstep);
+}
+
+
void
SolverControl::declare_parameters (ParameterHandler& param)
{