Diagnose a Failed Solve¶
A failed nonlinear-programming status means that the returned iterate is not a certified solution. Most direct-collocation models are nonconvex, so Ipopt and SciPy normally seek a local solution and do not prove global optimality. Even for a convex model, successful termination still depends on consistent data, numerical scaling, and an appropriate solver configuration.
Read the actual failure¶
Start with the solver's status and message. For Ipopt, inspect
info["status"] and info["status_msg"]; for SciPy, inspect
result.success, result.status, and result.message. The message
distinguishes common cases:
- infeasible problem detected: check contradictory boundary, path, and phase-link constraints;
- restoration failed or invalid number: check domains of square roots, powers, divisions, and logarithms, including at the initial guess;
- maximum iterations exceeded: inspect feasibility and scaling before
merely increasing
max_iter; - tiny step or search-direction failure: look for redundant constraints, nearly dependent Jacobian rows, or badly scaled variables.
Enable more solver output while diagnosing. A different linear solver can help some Ipopt factorizations, but only if that backend is installed; it cannot fix an inconsistent model.
Check the mathematical model¶
- Verify units, signs, reference frames, and the order of every state, control, boundary value, and static parameter.
- Evaluate the initial guess against variable bounds and algebraic constraints.
- Check that phase endpoints and event equations are mutually consistent.
- Scale states, controls, objectives, and constraints so typical nonzero values are not separated by many orders of magnitude.
- Guard expression domains over the full allowed region, not only along the expected solution.
Temporarily removing one family of constraints can localize an inconsistency, but restore and revalidate every physical constraint before using the result.
Improve the initial guess¶
A useful guess should have positive phase durations, satisfy fixed endpoints, respect simple bounds, and follow the qualitative direction of the dynamics. For multi-phase models, initialize every phase and the shared static-parameter array. A forward simulation, analytical approximation, or previously solved nearby case is usually more effective than a constant guess.
Continuation is often practical: solve an easier problem first, then gradually tighten terminal targets, path limits, or model fidelity while warm-starting from the previous solution.
Choose a diagnostic discretization¶
Begin with a modest, physically placed mesh. Too few points can miss fast transients; an unnecessarily large first transcription can make the nonlinear program harder to diagnose. Place phase boundaries at known discontinuities or events. Compare Radau and Lobatto only after checking that both models use the same equations and constraints.
After obtaining a candidate, reconstruct it densely, integrate the dynamics independently when practical, and check between-node constraint violations. Then increase polynomial degree or refine the mesh and confirm that the trajectory, objective, and active constraints converge.
Solver success by itself is not a validation result. The maintained examples show problem-specific checks, and Error Checking and Mesh Refinement describes the supported refinement workflow.