This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

Newton solver works but SNES doesnt

+4 votes

When using Newton solver with zero initial guess:

Solving nonlinear variational problem.
  Newton iteration 0: r (abs) = 2.333e+01 (tol = 1.000e-08) r (rel) = 1.000e+00 (tol = 1.000e-07)
  Newton iteration 1: r (abs) = 2.264e+03 (tol = 1.000e-08) r (rel) = 9.701e+01 (tol = 1.000e-07)

The residual drops after this and converges in 10 iterations.

But when I use snes_solver with line search, it is unable to reduce the residual after obtaining the value above and produces:

Line search: Cubic step no good, shrinking lambda, current gnorm 3.205948897925e+03 lambda=1.0000000000000007e-13
      Line search: unable to find good step length! After 12 tries 
      Line search: fnorm=2.3334499970834795e+01, gnorm=3.2059488979247935e+03, ynorm=8.8411820675344393e+02, minlambda=9.9999999999999998e-13, lambda=1.0000000000000007e-13, initial slope=-5.4449888888888904e+02
  *** Warning: PETSc SNES solver diverged in 0 iterations with divergence reason DIVERGED_LINE_SEARCH.

Would someone know why is this happening ? Any fixes for this ? Thanks.

asked Aug 26, 2014 by shriram FEniCS User (1,540 points)

1 Answer

+3 votes
 
Best answer

Your example only shows 2 iterations for the newton solver but it is already clear what is going on.

Line search tests each new iteration to make sure the residual has decreased by a specified amount and, if the test fails, it searches along the 'direction' (line) of the newton step to find a point at which it does satisfy the test. If it still can't find a satisfactory answer, it crashes with the error you show.

Take a look at your first two iterations. The residual increases from 2.333e1 to 2.264e3. Line search rejects this and tries to find a suitable value, which apparently it cannot, so it crashes. The solution with snes is therefore to turn off line search (change it to 'basic'). If you post where you define your olver, we can help you.

BTW: The reason why your residual increases in another matter entirely. Maybe a zero initial guess is not a good one?

answered Aug 26, 2014 by mwelland FEniCS User (8,410 points)
selected Aug 26, 2014 by shriram

Thank you for your answer.
I changed my solver to:

 prm = solver.parameters
    prm['nonlinear_solver'] = 'snes'
    prm['snes_solver']['line_search'] = 'basic'
    prm['snes_solver']['linear_solver']= 'lu'

Now I see it converged as before, and the option 'basic' essentially does plain Newton Raphson. Is there a way to see the specific parameters of prm['snes_solver']['linear_solver'] alone that can be tweaked ? The command info(prm, True) prints out everything.

If you are using petsc, you can pass parameters to the linear (ksp) solver directly such as:

PETScOptions.set('ksp_gmres_restart', '30')
PETScOptions.set('pc_type', 'lu')
PETScOptions.set('ksp_type', 'preonly')
PETScOptions.set('ksp_monitor_true_residual', 'True')
PETScOptions.set('ksp_converged_reason', 'True')
PETScOptions.set('ksp_atol', '1e-15')
PETScOptions.set('ksp_rtol', '1e-6')
PETScOptions.set('ksp_max_it', '1000')

Useful list here:
KSP settings

And for SNES
SNES settings

If you want to stay with FEniCS solvers, I believe there is a way to set up your linear solver by itself and then tell the newton solver to use the given linear solver. This may also answer your other question re using nullspaces with the adaptivelinearsolver. Take a look here (and feel free to post your code here if you are successful so others know how to do it too!)

Thanks for your reply. I prefer to stay with python as much and as long as I can. The question on adaptive linear solver isnt mine though.

...