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

How to solve a NonlinearVariationalProblem with SNES

+3 votes

Wow is PETSc SNES powerful! I would really love to be able to tweak the nonlinear solver and krylov method in a complicated system I have, but I can't seem to get the PETScSNESSolver to work. If you have used this solver can you please correct my script below?

from dolfin import *

mesh = UnitSquareMesh(2,2)
V = FunctionSpace(mesh, "CG", 1)

u = Function(V)
v = TestFunction(V)

f = u**2*v*dx

nlproblem = NonlinearVariationalProblem(f, u)
solver = PETScSNESSolver("newtonls")
solver.solve(nlproblem, u.vector())

When I run this I get

TypeError: in method 'PETScSNESSolver_solve', argument 2 of type
'dolfin::NonlinearProblem &'

It looks to me like PETScSNESSolver.solve() wants an object of type NonlinearProblem, which is a base class without info, but rejects the object of type NonlinearVariationalProblem, which seems to be a subclass of NonlinearProblem.

asked Jan 26, 2016 by Gabriel Balaban FEniCS User (1,210 points)

Hi, did you see the snes demo? It seems that a lot of the snes solver properties can be tweaked via parameters. Of course ideally you would like to get the PETScSNESSolver from the NonlinearVariationalSolver and then access the underlying SNES object wrapped for petsc4py. I don't see an easy way to do it - maybe you should submit a feature request. Btw, NonlinearVariationalProblem is not a subclass of NonlinearProblem. The object of NonlinearProblem that the PETScSNESSolver takes is constructed here.

Thanks for the SNES demo MiroK,
That does allow you to use snes but limits you to the solve parameter interface for the krylov solver. I was hoping to access the KrylovSolver object in order to do some field splitting.

A labmate of mine has suggested

class MyNonlinearProblem(NonlinearProblem):
def F(self, b ,x):

def J(self, Ax:)

And implementing these two functions in dolfin, I think this is a good way to go.

I was hoping to access the KrylovSolver object in order to do some field splitting.

Gabriel, this shortcoming is known http://fenicsproject.org/pipermail/fenics/2015-July/002857.html but not so high on the priority list.

1 Answer

0 votes

Hi, maybe you can try this:

a=derivative(L,u,du)
problem=NonlinearVariationalProblem(L,u,bcs=bc,J=a)
solver=NonlinearVariationalSolver(problem)

solver.parameters['nonlinear_solver'] = 'snes'
solver.parameters["snes_solver"]["maximum_iterations"] = 50
solver.parameters["snes_solver"]["report"] = False
answered Jan 16, 2017 by walkandthink FEniCS Novice (320 points)
...