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