Hello,
I am trying to figure out why a non-linear ordinary differential equation with analytical solution does not converge numerically (with FEM) under some conditions. This simple example could help me to understand some of the weaknesses of the newton solver for solving non-linear problems.
The equation results from a pure hydraulic balance:
\frac{du}{dt} + \sqrt{u} = f , and the variational formulation is as follows:
F=\int\limits_{\Omega}(\frac{du}{dt})v\,dx\,+\,\int\limits_{\Omega}(\sqrt{u})v\,dx\,-\,\int\limits_{\Omega}(f)v\,dx=0
There are three lines of code which may be determinant to achieve an accurate result without divergence:
Mesh definition: mesh = IntervalMesh(3,0,5)
u function initialization: u.vector()[:] = 1.0
Source therm value: f1 = Constant(0.5)
from fenics import *
import matplotlib.pyplot as plt
class BoundaryLeft(SubDomain):
def inside(self, x, on_boundary):
return on_boundary and (near(x[0], 0.))
#Define mesh
mesh=IntervalMesh(3,0,5)
#Define function space
V=FunctionSpace(mesh,'CG',1)
#Define boundary conditions
boundaryLeft=BoundaryLeft()
u_0 = Constant(0.0)
bc = DirichletBC(V,u_0,boundaryLeft)
#Define variational problem
u = Function(V)
u.vector()[:] = 1.0
#u = interpolate(Expression("x[0] + 1.0", element=V.ufl_element()), V)
v = TestFunction(V)
f1 = Constant(0.5)
F = v*u.dx(0)*dx+v*sqrt(u)*dx-v*f1*dx
solve(F == 0, u, bc,solver_parameters={"newton_solver": {
"relative_tolerance": 1e-7, "maximum_iterations": 50,
"convergence_criterion": "residual",
"linear_solver":"gmres", "preconditioner": "jacobi",
"krylov_solver":{"nonzero_initial_guess":True}}})
plot(u)
plot(mesh)
plt.show()
error_L2 = errornorm(u_0,u,'L2')
print(error_L2)
E.g. : Changing the source therm value below 0.5 leads to solution-failure.
Is it a problem of the finite element method? Solver implementation? Should I linearize the variational problem in these cases?
Thank you in advance,
Santiago