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