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

Floating point exception! Solving nonlinear Poisson problem with sqrt

+1 vote

Hi,
I have the problem following nonlinear problems discussed here
http://fenicsproject.org/documentation/tutorial/nonlinear.html

I changed the problem slightly to input sqrt(inner(nabla_grad(u_), nabla_grad(u_))) into the nonlinear function. This is euclidean norm of u_ and I need to work with such nonlinearities. As soon as I try to solve equation with this setting I obtain

[0]PETSC ERROR: Floating point exception!
[0]PETSC ERROR: Infinite or not-a-number generated in norm!

I think there should be no such error since inner(nabla_grad(u_), nabla_grad(u_)) should be non negative number. Moreover if I add some small number to it and compute sqrt(0.0001+inner(nabla_grad(u_), nabla_grad(u_))) it does then converge.

Please could you help me what I am doing wrong?

Thank you,
Vojtech.

Complete code:

from dolfin import *
import numpy

mesh = dolfin.UnitSquareMesh(50, 50)
tol = 1E-14
def left_boundary(x, on_boundary):
    return on_boundary and abs(x[0]) < tol

def right_boundary(x, on_boundary):
    return on_boundary and abs(x[0]-1) < tol

V = FunctionSpace(mesh, 'Lagrange', 1)
Gamma_0 = DirichletBC(V, Constant(0.0), left_boundary)
Gamma_1 = DirichletBC(V, Constant(1.0), right_boundary)
bcs = [Gamma_0, Gamma_1]

def q(u):#fenics examples
    m=2
    return (1+u)**m

du = TrialFunction(V)
u_ = Function(V)     # most recently computed solution
v  = TestFunction(V)

F  = inner(q(sqrt(inner(nabla_grad(u_), nabla_grad(u_))))*nabla_grad(u_), nabla_grad(v))*dx
#F  = inner(q(sqrt(0.0001+inner(nabla_grad(u_), nabla_grad(u_))))*nabla_grad(u_), nabla_grad(v))*dx#works well
#F  = inner(q(u_)*nabla_grad(u_), nabla_grad(v))*dx #works well
J  = derivative(F, u_, du)  # Gateaux derivative in dir. of du


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
prm['newton_solver']['maximum_iterations'] = 25
prm['newton_solver']['relaxation_parameter'] = 1.0

solver.solve()
asked Apr 16, 2014 by kulvv1am FEniCS Novice (270 points)

1 Answer

+2 votes

The problem is that the operator F is non-differentiable if "nabla_grad(u_)" is 0, which is the case for your initial guess of u_. Hence the first Newton-step is not well-defined and you get nans in your result.

The solution is to use an initial guess with a non-zero gradient. Try

u_ = interpolate(Expression("x[0]"), V)
answered Apr 23, 2014 by simon_funke FEniCS Novice (690 points)
...