diff --git a/framework/include/timesteppers/TimeStepper.h b/framework/include/timesteppers/TimeStepper.h index d8f04e6b6a38..a2d9220e6354 100644 --- a/framework/include/timesteppers/TimeStepper.h +++ b/framework/include/timesteppers/TimeStepper.h @@ -101,6 +101,9 @@ class TimeStepper : public MooseObject, public Restartable, public ScalarCouplea void addSyncTime(const std::set & times); ///@} + /// Mark the current time step as failed due to external conditions + void failTimeStep() { _converged = false; } + protected: /** * Computes time step size for the initial time step diff --git a/framework/src/timesteppers/TimeStepper.C b/framework/src/timesteppers/TimeStepper.C index 13b02d373208..fcaead8f0821 100644 --- a/framework/src/timesteppers/TimeStepper.C +++ b/framework/src/timesteppers/TimeStepper.C @@ -165,6 +165,8 @@ TimeStepper::constrainStep(Real & dt) void TimeStepper::step() { + _converged = true; + if (!_executioner.legacyTimeExecution()) { _fe_problem.execTransfers(EXEC_TIMESTEP_BEGIN); @@ -177,6 +179,12 @@ TimeStepper::step() } _fe_problem.execute(EXEC_TIMESTEP_BEGIN); + if (!_converged) + { + _failure_count++; + _console << "Aborting by a Terminator" << std::endl; + return; + } _fe_problem.outputStep(EXEC_TIMESTEP_BEGIN); } @@ -193,6 +201,12 @@ TimeStepper::step() { _fe_problem.onTimestepEnd(); _fe_problem.execute(EXEC_TIMESTEP_END); + if (!_converged) + { + _failure_count++; + _console << "Aborting by a Terminator" << std::endl; + return; + } _fe_problem.execTransfers(EXEC_TIMESTEP_END); if (!_fe_problem.execMultiApps(EXEC_TIMESTEP_END)) diff --git a/framework/src/userobjects/Terminator.C b/framework/src/userobjects/Terminator.C index 4ed4e0cf9e42..7df379f82709 100644 --- a/framework/src/userobjects/Terminator.C +++ b/framework/src/userobjects/Terminator.C @@ -14,7 +14,9 @@ #include "Terminator.h" #include "MooseApp.h" #include "MooseEnum.h" -#include "Executioner.h" +#include "Transient.h" +#include "FixedPointSolve.h" +#include "TimeStepper.h" registerMooseObject("MooseApp", Terminator); @@ -164,7 +166,25 @@ Terminator::execute() _fe_problem.setFailNextNonlinearConvergenceCheck(); // Outside of a solve, trigger a time step fail else - getMooseApp().getExecutioner()->fixedPointSolve().failStep(); + { + auto executioner = getMooseApp().getExecutioner(); + if (executioner->legacyTimeExecution()) + executioner->fixedPointSolve().failStep(); + else + { + if (_fe_problem.getCurrentExecuteOnFlag() == FixedPointSolve::EXEC_FIXEDPOINT_BEGIN || + _fe_problem.getCurrentExecuteOnFlag() == FixedPointSolve::EXEC_FIXEDPOINT_END) + executioner->fixedPointSolve().failStep(); + else + { + Transient * transient = dynamic_cast(executioner); + if (transient) + transient->getTimeStepper()->failTimeStep(); + else + mooseError("Terminator must be used with Transient executioner."); + } + } + } } } }