From e7dd6f53e791add3f65e9476255f9759a62c57ec Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Wed, 25 Oct 2023 07:55:45 +0200 Subject: [PATCH] Fix Fix misleading preequilibration failure messages When preequilibration (or finding a steadystate in general) fails, `SteadystateProblem::handleSteadyStateFailure` produced `AMICI simulation failed: Steady state computation failed. First run of Newton solver failed. Simulation to steady state failed: No convergence was achieved. Second run of Newton solver failed.`, even in cases where no Newton solve or no simulation was attempted. This is confusing and is changed here, so that the message now reflects what has actually happened. Closes #2178 --- include/amici/steadystateproblem.h | 11 ++++++++-- src/steadystateproblem.cpp | 34 +++++++++++++++++++----------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/include/amici/steadystateproblem.h b/include/amici/steadystateproblem.h index b3af55c20a..dc19c014c4 100644 --- a/include/amici/steadystateproblem.h +++ b/include/amici/steadystateproblem.h @@ -208,8 +208,15 @@ class SteadystateProblem { /** * @brief Stores state and throws an exception if equilibration failed - */ - [[noreturn]] void handleSteadyStateFailure(); + * @param tried_newton_1 Whether any Newton step was attempted before + * simulation + * @param tried_simulation Whether simulation was attempted + * @param tried_newton_2 Whether any Newton step was attempted after + * simulation + */ + [[noreturn]] void handleSteadyStateFailure( + bool tried_newton_1, bool tried_simulation, bool tried_newton_2 + ); /** * @brief Assembles the error message to be thrown. diff --git a/src/steadystateproblem.cpp b/src/steadystateproblem.cpp index 816d0a4c53..c655b9b386 100644 --- a/src/steadystateproblem.cpp +++ b/src/steadystateproblem.cpp @@ -60,9 +60,9 @@ SteadystateProblem::SteadystateProblem(Solver const& solver, Model const& model) "sensitivities during simulation"); if (solver.getSensitivityMethod() == SensitivityMethod::forward && model.getSteadyStateComputationMode() - == SteadyStateComputationMode::newtonOnly + == SteadyStateComputationMode::newtonOnly && model.getSteadyStateSensitivityMode() - == SteadyStateSensitivityMode::integrationOnly) + == SteadyStateSensitivityMode::integrationOnly) throw AmiException("For forward sensitivity analysis steady-state " "computation mode 'newtonOnly' and steady-state " "sensitivity mode 'integrationOnly' are not " @@ -152,7 +152,10 @@ void SteadystateProblem::findSteadyState( /* Nothing worked, throw an as informative error as possible */ if (!checkSteadyStateSuccess()) - handleSteadyStateFailure(); + handleSteadyStateFailure( + !turnOffNewton, !turnOffSimulation, + !turnOffNewton && !turnOffSimulation + ); } void SteadystateProblem::findSteadyStateByNewtonsMethod( @@ -394,16 +397,23 @@ void SteadystateProblem::getQuadratureBySimulation( } } -[[noreturn]] void SteadystateProblem::handleSteadyStateFailure() { +[[noreturn]] void SteadystateProblem::handleSteadyStateFailure( + bool tried_newton_1, bool tried_simulation, bool tried_newton_2 +) { /* Throw error message according to error codes */ - std::string errorString = "Steady state computation failed. " - "First run of Newton solver failed"; - writeErrorString(&errorString, steady_state_status_[0]); - errorString.append(" Simulation to steady state failed"); - writeErrorString(&errorString, steady_state_status_[1]); - errorString.append(" Second run of Newton solver failed"); - writeErrorString(&errorString, steady_state_status_[2]); - + std::string errorString = "Steady state computation failed."; + if (tried_newton_1) { + errorString.append(" First run of Newton solver failed"); + writeErrorString(&errorString, steady_state_status_[0]); + } + if (tried_simulation) { + errorString.append(" Simulation to steady state failed"); + writeErrorString(&errorString, steady_state_status_[1]); + } + if (tried_newton_2) { + errorString.append(" Second run of Newton solver failed"); + writeErrorString(&errorString, steady_state_status_[2]); + } throw AmiException(errorString.c_str()); }