diff --git a/NumLib/ODESolver/TimeDiscretization.h b/NumLib/ODESolver/TimeDiscretization.h
index db3fb84d8b7dcf4df55d617bb1df5306f867235e..49ce64cb86c93218e40ddcbe50d918ccaaa6341a 100644
--- a/NumLib/ODESolver/TimeDiscretization.h
+++ b/NumLib/ODESolver/TimeDiscretization.h
@@ -142,6 +142,18 @@ public:
     virtual void pushState(const double t, GlobalVector const& x,
                            InternalMatrixStorage const& strg) = 0;
 
+    /*!
+     * Restores the given vector x to its old value.
+     * Used only for repeating of the time step with new time step size when
+     * the current time step is rejected. The restored x is only used as
+     * an initial guess for linear solver in the first Picard nonlinear
+     * iteration.
+     *
+     * \param x The solution at the current time step, which is going to be
+     *          reset to its previous value.
+     */
+    virtual void popState(GlobalVector& x) = 0;
+
     /*! Indicate that the computation of a new timestep is being started now.
      *
      * \warning Currently changing timestep sizes are not supported. Thus,
@@ -262,6 +274,11 @@ public:
         MathLib::LinAlg::copy(x, _x_old);
     }
 
+    void popState(GlobalVector& x) override
+    {
+        MathLib::LinAlg::copy(_x_old, x);
+    }
+
     void nextTimestep(const double t, const double delta_t) override
     {
         _t = t;
@@ -314,6 +331,11 @@ public:
         MathLib::LinAlg::copy(x, _x_old);
     }
 
+    void popState(GlobalVector& x) override
+    {
+        MathLib::LinAlg::copy(_x_old, x);
+    }
+
     void nextTimestep(const double t, const double delta_t) override
     {
         _t_old = _t;
@@ -392,6 +414,11 @@ public:
         strg.pushMatrices();
     }
 
+    void popState(GlobalVector& x) override
+    {
+        MathLib::LinAlg::copy(_x_old, x);
+    }
+
     void nextTimestep(const double t, const double delta_t) override
     {
         _t = t;
@@ -463,6 +490,11 @@ public:
     void pushState(const double, GlobalVector const& x,
                    InternalMatrixStorage const&) override;
 
+    void popState(GlobalVector& x) override
+    {
+        MathLib::LinAlg::copy(*_xs_old[_xs_old.size()-1], x);
+    }
+
     void nextTimestep(const double t, const double delta_t) override
     {
         _t = t;
diff --git a/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp b/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp
index e1571221440478f3ffafb9ceebfde2de01626fe6..63ef785620750e543ce7246e945ac57edd38091f 100644
--- a/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp
+++ b/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp
@@ -16,6 +16,8 @@
 
 #include "EvolutionaryPIDcontroller.h"
 
+#include <logog/include/logog.hpp>
+
 namespace NumLib
 {
 bool EvolutionaryPIDcontroller::next(const double solution_error)
@@ -35,6 +37,13 @@ bool EvolutionaryPIDcontroller::next(const double solution_error)
 
         _ts_current = _ts_prev;
         _ts_current += h_new;
+
+        WARN("\tThis step is rejected due to the relative change from the\n"
+             "\tsolution of the previous time step to the current solution\n"
+             "\t exceeds the given tolerance of %g.\n"
+             "\tThis time step will be repeated with a new time step size of"
+             " %g or the simulation will be halted." , _tol, h_new);
+
         return false;
     }
 
diff --git a/ProcessLib/LiquidFlow/Tests.cmake b/ProcessLib/LiquidFlow/Tests.cmake
index d2933143d52615305e4acdd59e0ac982addc226f..e55c59e92002c1ade861139cde6bbba0b01257d6 100644
--- a/ProcessLib/LiquidFlow/Tests.cmake
+++ b/ProcessLib/LiquidFlow/Tests.cmake
@@ -105,10 +105,10 @@ AddTest(
     REQUIREMENTS NOT OGS_USE_MPI
     ABSTOL 1.1 RELTOL 1e-6
     DIFF_DATA
-    mesh2D.vtu gravity_driven_adaptive_dt_pcs_1_ts_11_t_300.000000.vtu OGS5_PRESSURE1 pressure
-    mesh2D.vtu gravity_driven_adaptive_dt_pcs_1_ts_11_t_300.000000.vtu OGS5_TEMPERATURE1 temperature
-    mesh2D.vtu gravity_driven_adaptive_dt_pcs_1_ts_11_t_300.000000.vtu v_x_ref v_x
-    mesh2D.vtu gravity_driven_adaptive_dt_pcs_1_ts_11_t_300.000000.vtu v_y_ref v_y
+    mesh2D.vtu gravity_driven_adaptive_dt_pcs_1_ts_10_t_300.000000.vtu OGS5_PRESSURE1 pressure
+    mesh2D.vtu gravity_driven_adaptive_dt_pcs_1_ts_10_t_300.000000.vtu OGS5_TEMPERATURE1 temperature
+    mesh2D.vtu gravity_driven_adaptive_dt_pcs_1_ts_10_t_300.000000.vtu v_x_ref v_x
+    mesh2D.vtu gravity_driven_adaptive_dt_pcs_1_ts_10_t_300.000000.vtu v_y_ref v_y
 )
 
 # PETSc/MPI
@@ -218,8 +218,8 @@ AddTest(
     REQUIREMENTS OGS_USE_MPI
     ABSTOL 1.1 RELTOL 1e-7
     DIFF_DATA
-    mesh2D.vtu gravity_driven_adaptive_dt_pcs_1_ts_11_t_300_000000_0.vtu OGS5_PRESSURE1 pressure
-    mesh2D.vtu gravity_driven_adaptive_dt_pcs_1_ts_11_t_300_000000_0.vtu OGS5_TEMPERATURE1 temperature
+    mesh2D.vtu gravity_driven_adaptive_dt_pcs_1_ts_10_t_300_000000_0.vtu OGS5_PRESSURE1 pressure
+    mesh2D.vtu gravity_driven_adaptive_dt_pcs_1_ts_10_t_300_000000_0.vtu OGS5_TEMPERATURE1 temperature
 # To be activated when the output of velocity is correct under PETSc version.
 #    mesh2D.vtu gravity_driven_pcs_1_ts_5_t_300_000000_0.vtu v_x_ref v_x
 #    mesh2D.vtu gravity_driven_pcs_1_ts_5_t_300_000000_0.vtu v_y_ref v_y
diff --git a/ProcessLib/RichardsFlow/Tests.cmake b/ProcessLib/RichardsFlow/Tests.cmake
index 35b569a8d578bc4b292ee4d98cadba46c1c6acb0..51b95a26429a61fedc27d2d3e99cbd465ea6f859 100644
--- a/ProcessLib/RichardsFlow/Tests.cmake
+++ b/ProcessLib/RichardsFlow/Tests.cmake
@@ -31,3 +31,29 @@ AddTest(
         ref_t_20000.000000.vtu richards_pcs_0_ts_18200_t_20000.000000.vtu pressure pressure
     REQUIREMENTS NOT OGS_USE_MPI
 )
+
+AddTest(
+    NAME 2D_RichardsFlow_h_us_quad_small_Adpative_dt
+    PATH Parabolic/Richards
+    EXECUTABLE ogs
+    EXECUTABLE_ARGS RichardsFlow_2d_small_adaptive_dt.prj
+    TESTER vtkdiff
+    ABSTOL 1e-8 RELTOL 1e-3
+    DIFF_DATA
+    ref_t_1600.000000.vtu richards_pcs_0_ts_805_t_1600.000000.vtu pressure pressure
+    REQUIREMENTS NOT OGS_USE_MPI
+)
+
+#PETSc/MPI
+AddTest(
+    NAME 2D_RichardsFlow_h_us_quad_small_Adpative_dt
+    PATH Parabolic/Richards
+    EXECUTABLE_ARGS RichardsFlow_2d_small_adaptive_dt.prj
+    WRAPPER mpirun
+    WRAPPER_ARGS -np 1
+    TESTER vtkdiff
+    REQUIREMENTS OGS_USE_MPI
+    ABSTOL 1e-8 RELTOL 1e-3
+    DIFF_DATA
+    ref_t_1600.000000.vtu richards_pcs_0_ts_805_t_1600_000000_0.vtu pressure pressure
+)
diff --git a/ProcessLib/UncoupledProcessesTimeLoop.cpp b/ProcessLib/UncoupledProcessesTimeLoop.cpp
index 60a7afc6c0ec3775c31f8b17bb725d46cc40625a..d39069ec0cc494f8cd3b82f86778d3b80543bf2d 100644
--- a/ProcessLib/UncoupledProcessesTimeLoop.cpp
+++ b/ProcessLib/UncoupledProcessesTimeLoop.cpp
@@ -620,21 +620,23 @@ double UncoupledProcessesTimeLoop::computeTimeStepping(
             continue;
         }
 
+        auto& time_disc = ppd.time_disc;
+        auto& mat_strg = *ppd.mat_strg;
+        auto& x = *_process_solutions[i];
         if (all_process_steps_accepted)
         {
-            auto& time_disc = ppd.time_disc;
-            auto& mat_strg = *ppd.mat_strg;
-            auto const& x = *_process_solutions[i];
             time_disc->pushState(t, x, mat_strg);
+            _repeating_times_of_rejected_step = 0;
         }
         else
         {
             if (t < _end_time)
             {
                 WARN(
-                    "Time step %d is rejected. "
-                    "The computation is back to the previous time.",
-                    accepted_steps + rejected_steps);
+                    "Time step %d was rejected %d times "
+                    "and it will be repeated with a reduced step size.",
+                    accepted_steps + 1, _repeating_times_of_rejected_step++);
+                time_disc->popState(x);
             }
         }
     }
@@ -642,13 +644,28 @@ double UncoupledProcessesTimeLoop::computeTimeStepping(
     if (!is_initial_step)
     {
         if (all_process_steps_accepted)
+        {
             accepted_steps++;
+            _last_step_rejected = false;
+        }
         else
         {
+            if (std::abs(dt -prev_dt) < std::numeric_limits<double>::min()
+                && _last_step_rejected)
+            {
+                OGS_FATAL("\tThis time step is rejected and the new computed"
+                          " step size is the same as\n"
+                          "\tthat was just used.\n"
+                          "\tSuggest to adjust the parameters of the time"
+                          " stepper or try other time stepper.\n"
+                          "\tThe program stops");
+            }
+
             if (t < _end_time)
             {
                 t -= prev_dt;
                 rejected_steps++;
+                _last_step_rejected = true;
             }
         }
     }
@@ -729,7 +746,7 @@ bool UncoupledProcessesTimeLoop::loop()
         t += dt;
         const double prev_dt = dt;
 
-        const std::size_t timesteps = accepted_steps + rejected_steps + 1;
+        const std::size_t timesteps = accepted_steps + 1;
         // TODO, input option for time unit.
         INFO("=== Time stepping at step #%u and time %g with step size %g",
              timesteps, t, dt);
diff --git a/ProcessLib/UncoupledProcessesTimeLoop.h b/ProcessLib/UncoupledProcessesTimeLoop.h
index df0c9e058b3fc1ba66587f458fbe733ee990053c..fe62579f90c291e370c095b19973a1b10d6ce969 100644
--- a/ProcessLib/UncoupledProcessesTimeLoop.h
+++ b/ProcessLib/UncoupledProcessesTimeLoop.h
@@ -66,6 +66,8 @@ private:
     std::unique_ptr<Output> _output;
     std::vector<std::unique_ptr<SingleProcessData>> _per_process_data;
 
+    bool _last_step_rejected = false;
+    bool _repeating_times_of_rejected_step = 0;
     const double _start_time;
     const double _end_time;
 
diff --git a/Tests/Data b/Tests/Data
index d482ae358213a45b0887765ba6105e57194dba4d..e9754efad6c6a2467a66f6d0138c94e999c3972e 160000
--- a/Tests/Data
+++ b/Tests/Data
@@ -1 +1 @@
-Subproject commit d482ae358213a45b0887765ba6105e57194dba4d
+Subproject commit e9754efad6c6a2467a66f6d0138c94e999c3972e