From fc9b1cccce0b33afaaa5973c1cfda13404c3ac26 Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Wed, 12 Jul 2023 13:56:14 +0200 Subject: [PATCH] Improve error message when time step is cut too often/much. Changes ``` Program threw an exception: [/home/mblatt/src/dune/opm/opm-simulators/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp:586] Solver failed to converge after cutting timestep 11 times. ``` to ``` Simulation aborted: Solver failed to converge after cutting timestep 11 times. ``` Which seems more user friendly. --- opm/simulators/flow/FlowMainEbos.hpp | 43 +++++++++++-------- .../timestepping/AdaptiveTimeSteppingEbos.hpp | 7 ++- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/opm/simulators/flow/FlowMainEbos.hpp b/opm/simulators/flow/FlowMainEbos.hpp index 2599a4e4a..9909c0cf3 100644 --- a/opm/simulators/flow/FlowMainEbos.hpp +++ b/opm/simulators/flow/FlowMainEbos.hpp @@ -324,6 +324,27 @@ void handleExtraConvergenceOutput(SimulatorReport& report, // called by execute() or executeInitStep() int execute_(int (FlowMainEbos::* runOrInitFunc)(), bool cleanup) { + auto logger = [this](const std::exception& e, const std::string& message_start) { + std::ostringstream message; + message << message_start << e.what(); + + if (this->output_cout_) { + // in some cases exceptions are thrown before the logging system is set + // up. + if (OpmLog::hasBackend("STREAMLOG")) { + OpmLog::error(message.str()); + } + else { + std::cout << message.str() << "\n"; + } + } +#if HAVE_MPI + if (this->mpi_size_ > 1) + MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); +#endif + return EXIT_FAILURE; + }; + try { // deal with some administrative boilerplate @@ -342,25 +363,11 @@ void handleExtraConvergenceOutput(SimulatorReport& report, } return exitCode; } + catch (const LinearTimeSteppingBreakdown& e) { + return logger(e, "Simulation aborted: "); + } catch (const std::exception& e) { - std::ostringstream message; - message << "Program threw an exception: " << e.what(); - - if (this->output_cout_) { - // in some cases exceptions are thrown before the logging system is set - // up. - if (OpmLog::hasBackend("STREAMLOG")) { - OpmLog::error(message.str()); - } - else { - std::cout << message.str() << "\n"; - } - } -#if HAVE_MPI - if (this->mpi_size_ > 1) - MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); -#endif - return EXIT_FAILURE; + return logger(e, "Simulation aborted as program threw an unexpected exception: "); } } diff --git a/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp b/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp index 7c2a309b5..160f22a60 100644 --- a/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp @@ -446,6 +446,7 @@ std::set consistentlyFailingWells(const std::vector& sr std::string causeOfFailure; try { substepReport = solver.step(substepTimer); + if (solverVerbose_) { // report number of linear iterations OpmLog::debug("Overall linear iterations used: " + std::to_string(substepReport.total_linear_iterations)); @@ -580,7 +581,8 @@ std::set consistentlyFailingWells(const std::vector& sr if (solverVerbose_) { OpmLog::error(msg); } - OPM_THROW_NOLOG(NumericalProblem, msg); + // Use throw directly to prevent file and line + throw LinearTimeSteppingBreakdown{msg}; } // The new, chopped timestep. @@ -596,7 +598,8 @@ std::set consistentlyFailingWells(const std::vector& sr if (solverVerbose_) { OpmLog::error(msg); } - OPM_THROW_NOLOG(NumericalProblem, msg); + // Use throw directly to prevent file and line + throw LinearTimeSteppingBreakdown{msg}; } // Define utility function for chopping timestep.