diff --git a/dumux/common/timeloop.hh b/dumux/common/timeloop.hh index b1bb27e460cdc7e7f89186f88dcebf884fca20ec..9636f82c0acb722fc58986c2fdadb66bd8ac2242 100644 --- a/dumux/common/timeloop.hh +++ b/dumux/common/timeloop.hh @@ -256,6 +256,12 @@ public: { using std::min; timeStepSize_ = min(dt, maxTimeStepSize()); + if (!finished() && Dune::FloatCmp::le(timeStepSize_, 0.0, 1e-14*endTime_)) + { + std::cerr << "You have set a very small timestep size (dt = " + << timeStepSize_ << "). This might lead to numerical problems!" + << std::endl; + } } /*! @@ -590,7 +596,7 @@ private: //! Adds a check point to the queue void setCheckPoint_(Scalar t) { - if (t < this->time()) + if (Dune::FloatCmp::le(t - this->time(), 0.0, this->timeStepSize()*1e-7)) { if (this->verbose()) std::cerr << "Couldn't insert checkpoint at t = " << t diff --git a/test/common/timeloop/test_timeloop.cc b/test/common/timeloop/test_timeloop.cc index 6e4017183554f5ec81228a60b85620d2cd08c650..76712a1987bfc76ae9fe5bf644e5edfaa69862c6 100644 --- a/test/common/timeloop/test_timeloop.cc +++ b/test/common/timeloop/test_timeloop.cc @@ -61,7 +61,6 @@ int main(int argc, char* argv[]) try DUNE_THROW(Dune::InvalidStateException, "Ended with wrong end time!"); } - // check point timeLoop { if (mpiHelper.rank() == 0) std::cout << std::endl << "------- Test check point time loop ----------" << std::endl; @@ -160,6 +159,44 @@ int main(int argc, char* argv[]) try timeLoop.reportTimeStep(); } + // check if setting the checkpoint at the current time shows error message + { + // redirect std::cerr + std::stringstream cerrBuffer; + std::streambuf* cerrOriginal = std::cerr.rdbuf(cerrBuffer.rdbuf()); + + Dumux::CheckPointTimeLoop<double> timeLoop(tStart, dt, tEnd); + timeLoop.setCheckPoint(tStart); + + // get result and reset buffer + const auto result = cerrBuffer.str(); + std::cerr.rdbuf(cerrOriginal); + std::cout << "Setting check point at the current time printed '" << result << "' to std::cerr" << std::endl; + + if (result.empty()) + DUNE_THROW(Dune::Exception, "Setting a checkpoint at the current time should print a warning to std::cerr"); + if (Dune::FloatCmp::eq(timeLoop.timeStepSize(), 0.0, 1e-10*tEnd)) + DUNE_THROW(Dune::Exception, "Time Loop reduced time step size to 0!"); + } + + // check if setting timestep to zero shows error message + { + // redirect std::cerr + std::stringstream cerrBuffer; + std::streambuf* cerrOriginal = std::cerr.rdbuf(cerrBuffer.rdbuf()); + + Dumux::TimeLoop<double> timeLoop(tStart, dt, tEnd); + timeLoop.setTimeStepSize(0.0); + + // get result and reset buffer + const auto result = cerrBuffer.str(); + std::cerr.rdbuf(cerrOriginal); + std::cout << "Setting zero time step printed '" << result << "' to std::cerr" << std::endl; + + if (result.empty()) + DUNE_THROW(Dune::Exception, "Setting a zero timeStepSize should print a warning to std::cerr"); + } + return 0; } // //////////////////////////////////