Recently I have been comparing different non-linear solvers from scipy and was particularly impressed with the Newton-Krylov example in the Scipy Cookbook in which they solve a second order differential equation equation with non-linear reaction term in about 20 lines of code.
I modified the example code to solve the non-linear Poisson equation (also called the Poisson-Boltzmann equation, see page 17 in these notes) for semiconductor heterostructures, which has the form,
$$ \frac{d^2\phi}{dx^2} - k(x) \left(p(x,\phi) - n(x,\phi) + N^{+}(x)\right) = 0 $$
(This is the residual function that is passed to the solver.)
This is an electrostatics problem where $n(x,\phi)$ and $p(x,\phi)$ are nonlinear functions for the form $n_i(x) e^{-(E_i(x,\phi) - E_f)}$. The details here are not important, but the point is that the non-linear function vary exponentially with $\phi$ so the residual function can vary over a huge range ($10^{-6} - 10^{16})$ with a slight change in $\phi$.
I numerically solve this equation with scipy's Newton-Krylov, but it would never converge (in fact it would always report an error with the calculating the Jacobian). I switched from a Newton-Krylov solver to fsolve (which is based on MINPACK hybrd) and it worked first time!
Are there general reasons why Newton-Krylov is not a good fit to certain problems? Do the input equations need to be conditioned somehow?
Maybe more information is needed to comment, but why do you think fsolve worked in this case?
sol = newton_krylov(func, guess, method='gmres')
) fixed the problem. Not exactly sure why, but anyone else with this issue might consider doing the same. $\endgroup$