fix(LogicalReaclibReaction): Properly class reverse reactions

Previously there was a bug where some reverse reactions were being
classed as forward reactions. This results in a failure of many
timesteps due to the reverse reactions very high molar flows
This commit is contained in:
2025-11-24 14:57:14 -05:00
parent ce8717b248
commit b335bf7100
5 changed files with 239 additions and 88 deletions

View File

@@ -46,20 +46,28 @@ namespace gridfire::utils {
};
static inline std::unordered_map<int, std::string> kinsol_ret_code_map {
{0, "KIN_SUCCESS: The solver succeeded."},
{1, "KIN_STEP_LT_STPTOL: The solver step size became less than the stopping tolerance."},
{2, "KIN_RES_REPTD_ERR: The residual function repeatedly failed recoverably."},
{-1, "KIN_MEM_NULL: The KINSOL memory structure is NULL."},
{-2, "KIN_ILL_INPUT: An illegal input was detected."},
{1, "KIN_INITIAL_GUESS_OKAY: The guess, u=u0, satisfied the system F(u) = 0 within the tolerances specified"},
{2, "KIN_STEP_LT_STPTOL: KINSOL stopped based on scaled step length. This means that the current iterate may be an approximate solution of the given nonlinear system, but it is also quite possible that the algorithm is “stalled” (making insufficient progress) near an invalid solution, or that the scalar, scsteptol, is too large."},
{99, "KIN_WARNING: KINSOL succeeded but in an unusual way"},
{-1, "KIN_MEM_NULL: The KINSOL memory pointer is NULL."},
{-2, "KIN_ILL_INPUT: An illegal value was specified for an input argument."},
{-3, "KIN_NO_MALLOC: The KINSOL memory structure has not been allocated."},
{-4, "KIN_MEM_FAIL: Memory allocation failed."},
{-5, "KIN_LINIT_FAIL: The linear solver's initialization function failed."},
{-6, "KIN_LSETUP_FAIL: The linear solver's setup function failed."},
{-7, "KIN_LSOLVE_FAIL: The linear solver's solve function failed."},
{-8, "KIN_RESFUNC_FAIL: The residual function failed in an unrecoverable manner."},
{-9, "KIN_CONSTR_FAIL: The inequality constraint was violated and the solver was unable to recover."},
{-10, "KIN_NLS_INIT_FAIL: The nonlinear solver's initialization function failed."},
{-11, "KIN_NLS_SETUP_FAIL: The nonlinear solver's setup function failed."},
{-12, "KIN_NLS_FAIL: The nonlinear solver's solve function failed."}
{-4, "KIN_MEM_FAIL: A memory allocation failed."},
{-5, "KIN_LINESEARCH_NONCONV: The line search algorithm was unable to find an iterate sufficiently distinct from the current iterate."},
{-6, "KIN_MAXITER_REACHED: The maximum number of iterations was reached before convergence."},
{-7, "KIN_MXNEWT_5X_EXCEEDED: Five consecutive steps have been taken that satisfy a scaled step length test."},
{-8, "KIN_LINESEARCH_BCFAIL: The line search algorithm was unable to satisfy the beta-condition for nbcf fails iterations."},
{-9, "KIN_LINSOLV_NO_RECOVERY: The linear solver's solve function failed recoverably, but the Jacobian data is already current."},
{-10, "KIN_LINIT_FAIL: The linear solver's init routine failed."},
{-11, "KIN_LSETUP_FAIL: The linear solver's setup function failed in an unrecoverable manner."},
{-12, "KIN_LSOLVE_FAIL: The linear solver's solve function failed in an unrecoverable manner."},
{-13, "KIN_SYSFUNC_FAIL: The system function failed in an unrecoverable manner."},
{-14, "KIN_FIRST_SYSFUNC_ERR: The system function failed at the first call."},
{-15, "KIN_REPTD_SYSFUNC_ERR: Unable to correct repeated recoverable system function errors."},
{-16, "KIN_VECTOROP_ERR: A vector operation failed."},
{-17, "KIN_CONTEXT_ERR: A context error occurred."},
{-18, "KIN_DAMPING_FN_ERR: The damping function failed."},
{-19, "KIN_DEPTH_FN_ERR: The depth function failed."}
};
inline const std::unordered_map<int, std::string>& sundials_retcode_map(const SUNDIALS_RET_CODE_TYPES type) {
@@ -96,4 +104,27 @@ namespace gridfire::utils {
return vec;
}
inline void check_sundials_flag(const int flag, const std::string& func_name, const SUNDIALS_RET_CODE_TYPES type) {
if (flag < 0) {
const auto& ret_code_map = sundials_retcode_map(type);
if (!ret_code_map.contains(flag)) {
switch (type) {
case (SUNDIALS_RET_CODE_TYPES::CVODE):
throw exceptions::CVODESolverFailureError("CVODE error in " + func_name + ": Unknown error code: " + std::to_string(flag));
case (SUNDIALS_RET_CODE_TYPES::KINSOL):
throw exceptions::KINSolSolverFailureError("KINSol error in " + func_name + ": Unknown error code: " + std::to_string(flag));
default:
throw exceptions::CVODESolverFailureError("SUNDIALS error in " + func_name + ": Unknown error code: " + std::to_string(flag));
}
}
switch (type) {
case (SUNDIALS_RET_CODE_TYPES::CVODE):
throw exceptions::CVODESolverFailureError("CVODE error in " + func_name + ": " + ret_code_map.at(flag));
case (SUNDIALS_RET_CODE_TYPES::KINSOL):
throw exceptions::KINSolSolverFailureError("KINSol error in " + func_name + ": " + ret_code_map.at(flag));
default:
throw exceptions::CVODESolverFailureError("SUNDIALS error in " + func_name + ": " + ret_code_map.at(flag));
}
}
}
}