From 8c356ea949e8fa1ed9dba56307ab84732ad04336 Mon Sep 17 00:00:00 2001
From: Dmitri Naumov <dmitri.naumov@ufz.de>
Date: Mon, 2 Mar 2020 17:33:49 +0100
Subject: [PATCH] [NL/TS] Move time increment clamping in free fct.

---
 .../Algorithms/EvolutionaryPIDcontroller.cpp  | 27 +++-----------
 .../Algorithms/EvolutionaryPIDcontroller.h    |  4 ---
 .../IterationNumberBasedTimeStepping.cpp      | 24 ++-----------
 .../IterationNumberBasedTimeStepping.h        |  4 ---
 .../Algorithms/TimeStepAlgorithm.cpp          | 35 +++++++++++++++++++
 .../Algorithms/TimeStepAlgorithm.h            | 10 ++++++
 6 files changed, 51 insertions(+), 53 deletions(-)
 create mode 100644 NumLib/TimeStepping/Algorithms/TimeStepAlgorithm.cpp

diff --git a/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp b/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp
index b9ec34a2b66..1f8a692ac89 100644
--- a/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp
+++ b/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp
@@ -56,7 +56,8 @@ bool EvolutionaryPIDcontroller::next(double const solution_error,
                                               : 0.5 * _ts_current.dt();
 
         h_new = limitStepSize(h_new, is_previous_step_accepted);
-        h_new = possiblyClampToNextFixedTime(h_new);
+        h_new = possiblyClampDtToNextFixedTime(_ts_current.current(), h_new,
+                                               _fixed_output_times);
 
         _ts_current = _ts_prev;
         _ts_current += h_new;
@@ -116,7 +117,8 @@ bool EvolutionaryPIDcontroller::next(double const solution_error,
         }
 
         h_new = limitStepSize(h_new, is_previous_step_accepted);
-        h_new = possiblyClampToNextFixedTime(h_new);
+        h_new = possiblyClampDtToNextFixedTime(_ts_current.current(), h_new,
+                                               _fixed_output_times);
         _dt_vector.push_back(h_new);
 
         _ts_prev = _ts_current;
@@ -165,27 +167,6 @@ double EvolutionaryPIDcontroller::limitStepSize(
     return limited_h;
 }
 
-double EvolutionaryPIDcontroller::possiblyClampToNextFixedTime(
-    const double h_new) const
-{
-    auto const specific_time =
-        std::upper_bound(std::cbegin(_fixed_output_times),
-                         std::cend(_fixed_output_times), _ts_current.current());
-
-    if (specific_time == std::cend(_fixed_output_times))
-    {
-        return h_new;
-    }
-
-    if ((*specific_time > _ts_current.current()) &&
-        (_ts_current.current() + h_new - *specific_time > 0.0))
-    {
-        return *specific_time - _ts_current.current();
-    }
-
-    return h_new;
-}
-
 void EvolutionaryPIDcontroller::addFixedOutputTimes(
     std::vector<double> const& extra_fixed_output_times)
 {
diff --git a/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.h b/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.h
index 069daca9aab..af5a598e642 100644
--- a/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.h
+++ b/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.h
@@ -111,10 +111,6 @@ private:
      */
     double limitStepSize(const double h_new,
                          const bool previous_step_accepted) const;
-
-    /// If any time will be reached with given time increment, it will be
-    /// reduced, otherwise the input will be returned.
-    double possiblyClampToNextFixedTime(const double h_new) const;
 };
 
 /// Create an EvolutionaryPIDcontroller time stepper from the given
diff --git a/NumLib/TimeStepping/Algorithms/IterationNumberBasedTimeStepping.cpp b/NumLib/TimeStepping/Algorithms/IterationNumberBasedTimeStepping.cpp
index b240bca0a67..a204a053b02 100644
--- a/NumLib/TimeStepping/Algorithms/IterationNumberBasedTimeStepping.cpp
+++ b/NumLib/TimeStepping/Algorithms/IterationNumberBasedTimeStepping.cpp
@@ -79,7 +79,8 @@ bool IterationNumberBasedTimeStepping::next(double const /*solution_error*/,
 
     // prepare the next time step info
     _ts_current = _ts_prev;
-    _ts_current += possiblyClampToNextFixedTime(getNextTimeStepSize());
+    _ts_current += possiblyClampDtToNextFixedTime(
+        _ts_current.current(), getNextTimeStepSize(), _fixed_output_times);
 
     return true;
 }
@@ -133,27 +134,6 @@ double IterationNumberBasedTimeStepping::getNextTimeStepSize() const
     return dt;
 }
 
-double IterationNumberBasedTimeStepping::possiblyClampToNextFixedTime(
-    const double h_new) const
-{
-    auto const specific_time =
-        std::upper_bound(std::cbegin(_fixed_output_times),
-                         std::cend(_fixed_output_times), _ts_current.current());
-
-    if (specific_time == std::cend(_fixed_output_times))
-    {
-        return h_new;
-    }
-
-    if ((*specific_time > _ts_current.current()) &&
-        (_ts_current.current() + h_new - *specific_time > 0.0))
-    {
-        return *specific_time - _ts_current.current();
-    }
-
-    return h_new;
-}
-
 void IterationNumberBasedTimeStepping::addFixedOutputTimes(
     std::vector<double> const& extra_fixed_output_times)
 {
diff --git a/NumLib/TimeStepping/Algorithms/IterationNumberBasedTimeStepping.h b/NumLib/TimeStepping/Algorithms/IterationNumberBasedTimeStepping.h
index f911e773d12..9dcf45eacbc 100644
--- a/NumLib/TimeStepping/Algorithms/IterationNumberBasedTimeStepping.h
+++ b/NumLib/TimeStepping/Algorithms/IterationNumberBasedTimeStepping.h
@@ -116,10 +116,6 @@ private:
     /// Find a multiplier for the given number of iterations.
     double findMultiplier(int number_iterations) const;
 
-    /// If any time will be reached with given time increment, it will be
-    /// reduced, otherwise the input will be returned.
-    double possiblyClampToNextFixedTime(const double h_new) const;
-
     /// This vector stores the number of iterations to which the respective
     /// multiplier coefficient will be applied.
     const std::vector<int> _iter_times_vector;
diff --git a/NumLib/TimeStepping/Algorithms/TimeStepAlgorithm.cpp b/NumLib/TimeStepping/Algorithms/TimeStepAlgorithm.cpp
new file mode 100644
index 00000000000..0f627b3bfc0
--- /dev/null
+++ b/NumLib/TimeStepping/Algorithms/TimeStepAlgorithm.cpp
@@ -0,0 +1,35 @@
+/**
+ * \file
+ * \copyright
+ * Copyright (c) 2012-2020, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ */
+
+#include "TimeStepAlgorithm.h"
+
+#include <algorithm>
+
+namespace NumLib
+{
+double possiblyClampDtToNextFixedTime(
+    double const t, double const dt,
+    std::vector<double> const& fixed_output_times)
+{
+    auto const specific_time = std::upper_bound(
+        std::cbegin(fixed_output_times), std::cend(fixed_output_times), t);
+
+    if (specific_time == std::cend(fixed_output_times))
+    {
+        return dt;
+    }
+
+    if ((*specific_time > t) && (t + dt - *specific_time > 0.0))
+    {
+        return *specific_time - t;
+    }
+
+    return dt;
+}
+}  // namespace NumLib
diff --git a/NumLib/TimeStepping/Algorithms/TimeStepAlgorithm.h b/NumLib/TimeStepping/Algorithms/TimeStepAlgorithm.h
index d0285855b37..faf0a559f57 100644
--- a/NumLib/TimeStepping/Algorithms/TimeStepAlgorithm.h
+++ b/NumLib/TimeStepping/Algorithms/TimeStepAlgorithm.h
@@ -141,4 +141,14 @@ protected:
     std::vector<double> _dt_vector;
 };
 
+/// If any of the fixed times will be reached with given time increment, it will
+/// be reduced, otherwise the input will be returned.
+/// \pre The input vector of fixed times must be sorted.
+/// \param t Current time.
+/// \param dt Suggested time increment.
+/// \param fixed_output_times Sorted list of times which are to be reached.
+double possiblyClampDtToNextFixedTime(
+    double const t, double const dt,
+    std::vector<double> const& fixed_output_times);
+
 }  // namespace NumLib
-- 
GitLab