Skip to content

Commit

Permalink
Fix Fix misleading preequilibration failure messages
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dweindl committed Oct 25, 2023
1 parent c038ff5 commit e7dd6f5
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 14 deletions.
11 changes: 9 additions & 2 deletions include/amici/steadystateproblem.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
34 changes: 22 additions & 12 deletions src/steadystateproblem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 "
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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());
}

Expand Down

0 comments on commit e7dd6f5

Please sign in to comment.