From 2d78c55dbc4abbd3fec70ad0fd26e6fef9b51b48 Mon Sep 17 00:00:00 2001
From: Wenqing Wang <wenqing.wang@ufz.de>
Date: Tue, 1 Aug 2017 18:00:05 +0200
Subject: [PATCH] [dt] Fixed a bug in time stepper when non-linear solver is
 rejected

---
 ProcessLib/UncoupledProcessesTimeLoop.cpp | 43 +++++++++++------------
 1 file changed, 21 insertions(+), 22 deletions(-)

diff --git a/ProcessLib/UncoupledProcessesTimeLoop.cpp b/ProcessLib/UncoupledProcessesTimeLoop.cpp
index 33f96af26a7..9e655eba37d 100644
--- a/ProcessLib/UncoupledProcessesTimeLoop.cpp
+++ b/ProcessLib/UncoupledProcessesTimeLoop.cpp
@@ -126,6 +126,7 @@ struct SingleProcessData
     //! other members of this struct to their concrety types.
     NumLib::NonlinearSolverTag const nonlinear_solver_tag;
     NumLib::NonlinearSolverBase& nonlinear_solver;
+    bool nonlinear_solver_converged;
     std::unique_ptr<NumLib::ConvergenceCriterion> conv_crit;
 
     std::unique_ptr<NumLib::TimeDiscretization> time_disc;
@@ -152,6 +153,7 @@ SingleProcessData::SingleProcessData(
     : timestepper(std::move(timestepper_)),
       nonlinear_solver_tag(NLTag),
       nonlinear_solver(nonlinear_solver),
+      nonlinear_solver_converged(true),
       conv_crit(std::move(conv_crit_)),
       time_disc(std::move(time_disc_)),
       process(process_),
@@ -164,6 +166,7 @@ SingleProcessData::SingleProcessData(SingleProcessData&& spd)
     : timestepper(std::move(spd.timestepper)),
       nonlinear_solver_tag(spd.nonlinear_solver_tag),
       nonlinear_solver(spd.nonlinear_solver),
+      nonlinear_solver_converged(spd.nonlinear_solver_converged),
       conv_crit(std::move(spd.conv_crit)),
       time_disc(std::move(spd.time_disc)),
       tdisc_ode_sys(std::move(spd.tdisc_ode_sys)),
@@ -572,6 +575,7 @@ double UncoupledProcessesTimeLoop::computeTimeStepping(
                        : time_disc->getRelativeChangeFromPreviousTimestep(
                              x, norm_type))
                 : 0.;
+
         if (!timestepper->next(solution_error) &&
             // In case of FixedTimeStepping, which makes timestepper->next(...)
             // return false when the ending time is reached.
@@ -581,6 +585,12 @@ double UncoupledProcessesTimeLoop::computeTimeStepping(
             all_process_steps_accepted = false;
         }
 
+        if (!ppd.nonlinear_solver_converged)
+        {
+            WARN("Time step will be rejected due to nonlinear solver diverged");
+            all_process_steps_accepted = false;
+        }
+
         if (timestepper->getTimeStep().dt() >
                 std::numeric_limits<double>::min() ||
             std::abs(t - timestepper->end()) <
@@ -658,15 +668,16 @@ double UncoupledProcessesTimeLoop::computeTimeStepping(
         }
         else
         {
-            if (std::abs(dt -prev_dt) < std::numeric_limits<double>::min()
-                && _last_step_rejected)
+            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");
+                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)
@@ -769,20 +780,6 @@ bool UncoupledProcessesTimeLoop::loop()
         INFO("[time] Time step #%u took %g s.", timesteps,
              time_timestep.elapsed());
 
-        if (!nonlinear_solver_succeeded)
-        {
-            WARN(
-                "Time step %d is rejected due to "
-                "the divergence of the non-linear solver.\n"
-                "\tThe time stepping steps back to the previous time\n"
-                "\tand starts again with the half of the current step size.",
-                timesteps);
-            t -= prev_dt;
-            dt *= 0.5;
-            rejected_steps++;
-            continue;
-        }
-
         dt = computeTimeStepping(prev_dt, t, accepted_steps, rejected_steps);
 
         if (t + dt > _end_time ||
@@ -855,6 +852,7 @@ bool UncoupledProcessesTimeLoop::solveUncoupledEquationSystems(
         const auto nonlinear_solver_succeeded =
             solveOneTimeStepOneProcess(x, timestep_id, t, dt, *spd,
                                        void_staggered_coupling_term, *_output);
+        spd->nonlinear_solver_converged = nonlinear_solver_succeeded;
         pcs.postTimestep(x);
         pcs.computeSecondaryVariable(t, x, void_staggered_coupling_term);
 
@@ -933,6 +931,7 @@ bool UncoupledProcessesTimeLoop::solveCoupledEquationSystemsByStaggeredScheme(
 
             const auto nonlinear_solver_succeeded = solveOneTimeStepOneProcess(
                 x, timestep_id, t, dt, *spd, coupling_term, *_output);
+            spd->nonlinear_solver_converged = nonlinear_solver_succeeded;
 
             INFO(
                 "[time] Solving process #%u took %g s in time step #%u "
-- 
GitLab