From 15f5761d42179d3bef11b6c32a8ac1421bae050c Mon Sep 17 00:00:00 2001
From: Simon Scholz <simon.scholz@iws.uni-stuttgart.de>
Date: Mon, 6 May 2019 11:55:54 +0200
Subject: [PATCH] [timeloop] make it possible to extend the current timestep to
 the next CheckPoint

(cherry picked from commit c265029eba80f47e5626eb14de44a4cd7e6733b1)
---
 dumux/common/timeloop.hh | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/dumux/common/timeloop.hh b/dumux/common/timeloop.hh
index deae729407..b3fd5ce739 100644
--- a/dumux/common/timeloop.hh
+++ b/dumux/common/timeloop.hh
@@ -421,18 +421,18 @@ public:
     void advanceTimeStep() override
     {
         const auto dt = this->timeStepSize();
-        const auto nextTime = this->time()+dt;
+        const auto newTime = this->time()+dt;
 
         //! Check point management, TimeLoop::isCheckPoint() has to be called after this!
         // if we reached a periodic check point
-        if (periodicCheckPoints_ && Dune::FloatCmp::eq(nextTime - lastPeriodicCheckPoint_, deltaPeriodicCheckPoint_, 1e-7))
+        if (periodicCheckPoints_ && Dune::FloatCmp::eq(newTime - lastPeriodicCheckPoint_, deltaPeriodicCheckPoint_, 1e-7))
         {
             lastPeriodicCheckPoint_ += deltaPeriodicCheckPoint_;
             isCheckPoint_ = true;
         }
 
         // or a manually set check point
-        else if (!checkPoints_.empty() && Dune::FloatCmp::eq(nextTime - checkPoints_.front(), 0.0, 1e-7))
+        else if (!checkPoints_.empty() && Dune::FloatCmp::eq(newTime - checkPoints_.front(), 0.0, 1e-7))
         {
             checkPoints_.pop();
             isCheckPoint_ = true;
@@ -454,6 +454,21 @@ public:
         using std::max;
         if (isCheckPoint_)
             this->setTimeStepSize(max(dt, previousTimeStepSize));
+
+        // if there is a check point soon check if the time step after the next time step would be smaller
+        // than 20% of the next time step, if yes increase the suggested next time step to exactly reach the check point
+        // (in the limits of the maximum time step size)
+        auto nextDt = this->timeStepSize();
+        const auto threshold = 0.2*nextDt;
+        const auto nextTime = this->time() + nextDt;
+
+        if (periodicCheckPoints_ && Dune::FloatCmp::le(lastPeriodicCheckPoint_ + deltaPeriodicCheckPoint_ - nextTime, threshold))
+            nextDt = lastPeriodicCheckPoint_ + deltaPeriodicCheckPoint_ - this->time();
+
+        if (!checkPoints_.empty() && Dune::FloatCmp::le(checkPoints_.front() - nextTime, threshold))
+            nextDt = checkPoints_.front() - this->time();
+
+        this->setTimeStepSize(nextDt);
     }
 
     /*!
-- 
GitLab