]> https://gitweb.dealii.org/ - dealii.git/commitdiff
add ConsecutiveControl 4401/head
authorDenis Davydov <davydden@gmail.com>
Wed, 17 May 2017 14:25:01 +0000 (16:25 +0200)
committerDenis Davydov <davydden@gmail.com>
Thu, 18 May 2017 05:54:43 +0000 (07:54 +0200)
doc/news/changes/minor/20170517DenisDavydov [new file with mode: 0644]
include/deal.II/lac/solver_control.h
source/lac/solver_control.cc
tests/lac/solver_control_05.cc [new file with mode: 0644]
tests/lac/solver_control_05.output [new file with mode: 0644]

diff --git a/doc/news/changes/minor/20170517DenisDavydov b/doc/news/changes/minor/20170517DenisDavydov
new file mode 100644 (file)
index 0000000..24bac6e
--- /dev/null
@@ -0,0 +1,5 @@
+New: add a new class ConsecutiveControl which returns SolverControl::State::success
+if and only if a certain positive number of consecutive iterations satisfy the
+specified tolerance.
+<br>
+(Denis Davydov, 2017/05/17)
index ec6d0435b2391d0c1446bc8bd69037a8d14c9c8d..71434fed6d1739c2c07a61df0b9c6813e4f22678 100644 (file)
@@ -528,6 +528,74 @@ public:
                        const double   check_value);
 };
 
+
+/**
+ * Specialization of @p SolverControl which returns SolverControl::State::success if
+ * and only if a certain positive number of consecutive iterations satisfy the
+ * specified tolerance. This is useful in cases when solving nonlinear problems
+ * using inexact Hessian.
+ *
+ * For example: The requested number of consecutively converged iterations is 2,
+ * the tolerance is 0.2. The ConsecutiveControl will return SolverControl::State::success
+ * only at the last step in the sequence 0.5, 0.0005, 1.0, 0.05, 0.01.
+ *
+ * @author Denis Davydov, 2017
+ */
+class ConsecutiveControl : public SolverControl
+{
+public:
+  /**
+   * Constructor. @p n_consecutive_iterations is the number of
+   * consecutive iterations which should satisfy the prescribed tolerance for
+   * convergence. Other arguments have the same meaning as those of the
+   * constructor of the SolverControl.
+   */
+  ConsecutiveControl (const unsigned int maxiter = 100,
+                      const double   tolerance   = 1.e-10,
+                      const unsigned int n_consecutive_iterations = 2,
+                      const bool     log_history = false,
+                      const bool     log_result  = false);
+
+  /**
+   * Initialize with a SolverControl object. The result will emulate
+   * SolverControl by setting @p n_consecutive_iterations to one.
+   */
+  ConsecutiveControl (const SolverControl &c);
+
+  /**
+   * Assign a SolverControl object to ConsecutiveControl. The result of the
+   * assignment will emulate SolverControl by setting @p n_consecutive_iterations
+   * to one.
+   */
+  ConsecutiveControl &operator= (const SolverControl &c);
+
+  /**
+   * Virtual destructor is needed as there are virtual functions in this
+   * class.
+   */
+  virtual ~ConsecutiveControl();
+
+  /**
+   * Decide about success or failure of an iteration, see the class description
+   * above.
+   */
+  virtual State check (const unsigned int step,
+                       const double   check_value);
+
+protected:
+  /**
+   * The number of consecutive iterations which should satisfy the prescribed
+   * tolerance for convergence.
+   */
+  unsigned int n_consecutive_iterations;
+
+  /**
+   * Counter for the number of consecutively converged iterations.
+   */
+  unsigned int n_converged_iterations;
+
+};
+
 /*@}*/
 //---------------------------------------------------------------------------
 
index 82d3a8452a6250fde28087d6fdf54383cfae95ae..ceb720cf707bd48b6dd989cc1d89e44b3dd16764 100644 (file)
@@ -349,4 +349,77 @@ IterationNumberControl::check (const unsigned int step,
     return SolverControl::check(step, check_value);
 }
 
+/*------------------------ ConsecutiveControl -------------------------------*/
+
+
+ConsecutiveControl::ConsecutiveControl(const unsigned int n,
+                                       const double       tolerance,
+                                       const unsigned int n_consecutive_iterations,
+                                       const bool m_log_history,
+                                       const bool m_log_result)
+  :
+  SolverControl (n, tolerance, m_log_history, m_log_result),
+  n_consecutive_iterations(n_consecutive_iterations),
+  n_converged_iterations(0)
+{
+  AssertThrow(n_consecutive_iterations>0,
+              ExcMessage("n_consecutive_iterations should be positive"));
+}
+
+
+
+ConsecutiveControl::ConsecutiveControl (const SolverControl &c)
+  :
+  SolverControl(c),
+  n_consecutive_iterations(1),
+  n_converged_iterations(0)
+{}
+
+
+
+ConsecutiveControl &
+ConsecutiveControl::operator= (const SolverControl &c)
+{
+  SolverControl::operator=(c);
+  n_consecutive_iterations = 1;
+  n_converged_iterations = 0;
+  return *this;
+}
+
+
+
+ConsecutiveControl::~ConsecutiveControl()
+{}
+
+
+SolverControl::State
+ConsecutiveControl::check (const unsigned int step,
+                           const double check_value)
+{
+  // reset the counter if ConsecutiveControl is being reused
+  if (step==0)
+    n_converged_iterations = 0;
+
+  SolverControl::State state = SolverControl::check(step, check_value);
+  // check if we need to override the success:
+  if (state == success)
+    {
+      n_converged_iterations++;
+      if (n_converged_iterations == n_consecutive_iterations)
+        {
+          return success;
+        }
+      else
+        {
+          lcheck = iterate;
+          return iterate;
+        }
+    }
+  else
+    {
+      n_converged_iterations = 0;
+      return state;
+    }
+}
+
 DEAL_II_NAMESPACE_CLOSE
diff --git a/tests/lac/solver_control_05.cc b/tests/lac/solver_control_05.cc
new file mode 100644 (file)
index 0000000..c9ca4fc
--- /dev/null
@@ -0,0 +1,53 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2017 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// test ConsecutiveControl
+
+
+#include "../tests.h"
+#include <deal.II/base/utilities.h>
+#include <cmath>
+#include <fstream>
+#include <iostream>
+#include <iomanip>
+#include <deal.II/lac/solver_control.h>
+
+
+int main(int argc, char **argv)
+{
+  std::ofstream logfile("output");
+  logfile.precision(4);
+  deallog.attach(logfile);
+  deallog.threshold_double(1.e-10);
+
+  {
+    ConsecutiveControl solver_control(12345, 1.e-3, 3, false, false);
+    //                                                     // n_converged_iterations:
+    deallog << solver_control.check(0,1.e-1) << std::endl; // 0
+    deallog << solver_control.check(1,1.e-4) << std::endl; // 1
+    deallog << solver_control.check(2,1.e-5) << std::endl; // 2
+    deallog << solver_control.check(3,2.e-3) << std::endl; // 0
+    deallog << solver_control.check(4,5.e-4) << std::endl; // 1
+    deallog << solver_control.check(5,4.e-4) << std::endl; // 2
+    deallog << solver_control.check(6,3.e-4) << std::endl; // 3 ==> success
+
+    // reuse
+    deallog << solver_control.check(0,3.e-4) << std::endl; // 1
+    deallog << solver_control.check(1,2.e-4) << std::endl; // 2
+    deallog << solver_control.check(2,1.e-4) << std::endl; // 3 ==> success
+
+  }
+}
diff --git a/tests/lac/solver_control_05.output b/tests/lac/solver_control_05.output
new file mode 100644 (file)
index 0000000..e9d49e3
--- /dev/null
@@ -0,0 +1,11 @@
+
+DEAL::0
+DEAL::0
+DEAL::0
+DEAL::0
+DEAL::0
+DEAL::0
+DEAL::1
+DEAL::0
+DEAL::0
+DEAL::1

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.