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

Newton Solver max value

0 votes

Hi!

I am sorry if my question is too simple or if the answer is in another topic, but I couldn't find it.

Is there a way of setting up a maximum value for tolerance when solving a nonlinear problem with Newton solver?

For example, if the problem is diverging:

...
Newton iteration 15: r (abs) = 1.836e+09 (tol = 1.000e-12) r (rel) = 1.292e+06 (tol = 1.000e-07)
Newton iteration 16: r (abs) = 7.548e+08 (tol = 1.000e-12) r (rel) = 5.312e+05 (tol = 1.000e-07)
Newton iteration 17: r (abs) = 1.952e+09 (tol = 1.000e-12) r (rel) = 1.374e+06 (tol = 1.000e-07)
Newton iteration 18: r (abs) = 1.811e+10 (tol = 1.000e-12) r (rel) = 1.274e+07 (tol = 1.000e-07)
Newton iteration 19: r (abs) = 7.576e+09 (tol = 1.000e-12) r (rel) = 5.332e+06 (tol = 1.000e-07)
Newton iteration 20: r (abs) = 2.295e+09 (tol = 1.000e-12) r (rel) = 1.615e+06 (tol = 1.000e-07)
...

I already know that this solution won't converge, so setting up some maximum value (1e+05, for example) to stop this attempt would really save some time!

Thanks!

asked May 14, 2016 by C. Okubo FEniCS Novice (470 points)

1 Answer

+1 vote
 
Best answer

Hello,

I suppose you are using the Newton method available in FEniCS, as we can see in http://fenicsproject.org/documentation/tutorial/nonlinear.html

On the solver, you can define some parameters:

absolute_tolerance
convergence_criterion
error_on_nonconvergence
linear_solver
maximum_iterations
method
preconditioner
relative_tolerance
relaxation_parameter
report
krylov_solver
lu_solver

From what I see, you can define the tolerance for the newton solver by using the following:

problem = NonlinearVariationalProblem(F, u_, bcs, J)
solver  = NonlinearVariationalSolver(problem)

prm = solver.parameters
prm['newton_solver']['absolute_tolerance'] = 1E-8
prm['newton_solver']['relative_tolerance'] = 1E-7

Also, you might want to take a look at the "convergence_criterion", which by can be 'residual' (default) or 'incremental'.

If you still can not find your solution, I recommend you develop your netwon solver "manually". Also demonstrated on the same link.

du = Function(V)
u  = Function(V)  # u = u_k + omega*du
omega = 1.0       # relaxation parameter
eps = 1.0
tol = 1.0E-5
iter = 0
maxiter = 25
while eps > tol and iter < maxiter:
    iter += 1
    A, b = assemble_system(a, L, bcs_du)
    solve(A, du.vector(), b)
    eps = numpy.linalg.norm(du.vector().array(), ord=numpy.Inf)
    print 'Norm:', eps
    u.vector()[:] = u_k.vector() + omega*du.vector()
    u_k.assign(u)

Where you can evaluate the value of the variable "eps" from within the newton iteration.

answered May 19, 2016 by lhdamiani FEniCS User (2,580 points)
selected May 20, 2016 by C. Okubo

Thanks for the answer!!

...