NewtonSolver residuals go to zero, meaningless solution

I am trying to solve a nonlinear Poisson equation. I hit some unexpected behaviour for a certain set of inputs, and I am unable to make sense of it. The NewtonSolver behaviour is puzzling to me, this is the solver output. Residuals are huge and then collapse to zero. Needless to say the solution is not ok.

2023-08-08 19:39:59.834 ( 238.182s) [main            ]              petsc.cpp:675   INFO| PETSc Krylov solver starting to solve system.
2023-08-08 19:39:59.841 ( 238.189s) [main            ]       NewtonSolver.cpp:36    INFO| Newton iteration 3: r (abs) = 2.87352e+115 (tol = 1e-10) r (rel) = 1.63805e+114(tol = 1e-06)
2023-08-08 19:39:59.843 ( 238.191s) [main            ]              petsc.cpp:675   INFO| PETSc Krylov solver starting to solve system.
2023-08-08 19:39:59.851 ( 238.199s) [main            ]       NewtonSolver.cpp:36    INFO| Newton iteration 4: r (abs) = 0 (tol = 1e-10) r (rel) = 0(tol = 1e-06)
2023-08-08 19:39:59.851 ( 238.199s) [main            ]       NewtonSolver.cpp:255   INFO| Newton solver finished in 4 iterations and 10008 linear solver iterations.

This is a MWE

import ufl
import numpy as np

from mpi4py import MPI
from petsc4py import PETSc

from dolfinx import mesh, fem, io, nls, log
from dolfinx.plot import create_vtk_mesh
def q(u):
    return ufl.exp(u)
L, W, S = [1.66666667, 1.66666667, 1.        ]
domain = mesh.create_rectangle(MPI.COMM_WORLD, np.array([[0,0],[L, W]]), [20,20], cell_type=mesh.CellType.quadrilateral)
x = ufl.SpatialCoordinate(domain)
u_ufl = x[1]*ufl.sin(2*3.14*x[0])*ufl.cos(S*3.14*x[1])
u_ufl_np = f"x[1]*np.sin(2*np.pi*x[0])*np.cos({S}*np.pi*x[1])"
f = - ufl.div(q(u_ufl)*ufl.grad(u_ufl))
V = fem.FunctionSpace(domain, ("CG", 2))
u_exact = lambda x: eval(u_ufl_np)
u_D = fem.Function(V)
u_D.interpolate(u_exact)
fdim = domain.topology.dim - 1
boundary_facets = mesh.locate_entities_boundary(domain, fdim, lambda x: np.full(x.shape[1], True, dtype=bool))
bc = fem.dirichletbc(u_D, fem.locate_dofs_topological(V, fdim, boundary_facets))
uh = fem.Function(V)
v = ufl.TestFunction(V)
F = q(uh)*ufl.dot(ufl.grad(uh), ufl.grad(v))*ufl.dx - f*v*ufl.dx
problem = fem.petsc.NonlinearProblem(F, uh, bcs=[bc])
solver = nls.petsc.NewtonSolver(MPI.COMM_WORLD, problem)
solver.convergence_criterion = "incremental"
solver.rtol = 1e-6
#solver.rtol = 1e-1
solver.report = True
##########
ksp = solver.krylov_solver
opts = PETSc.Options()
option_prefix = ksp.getOptionsPrefix()
opts[f"{option_prefix}ksp_type"] = "cg"
opts[f"{option_prefix}pc_type"] = "gamg"
opts[f"{option_prefix}pc_factor_mat_solver_type"] = "mumps"
ksp.setFromOptions()
##########
log.set_log_level(log.LogLevel.INFO)
n, converged = solver.solve(uh)
assert(converged)
print(f"Number of interations: {n:d}")


            

For inputs as L, W, S = [1.66666667, 1.1, 1. ] works fine, for example.
Any hints please?

I cannot reproduce your issue. Which version of petsc/dolfinx are you using?

2023-08-08 14:20:53.636 (   0.155s) [main            ]              petsc.cpp:698   INFO| PETSc Krylov solver starting to solve system.
2023-08-08 14:20:53.652 (   0.170s) [main            ]              petsc.cpp:698   INFO| PETSc Krylov solver starting to solve system.
2023-08-08 14:20:53.675 (   0.194s) [main            ]       NewtonSolver.cpp:36    INFO| Newton iteration 2: r (abs) = 5.00946 (tol = 1e-10) r (rel) = 0.285564(tol = 1e-06)
2023-08-08 14:20:53.678 (   0.197s) [main            ]              petsc.cpp:698   INFO| PETSc Krylov solver starting to solve system.
2023-08-08 14:20:53.693 (   0.212s) [main            ]       NewtonSolver.cpp:36    INFO| Newton iteration 3: r (abs) = 0.81439 (tol = 1e-10) r (rel) = 0.0464242(tol = 1e-06)
2023-08-08 14:20:53.696 (   0.215s) [main            ]              petsc.cpp:698   INFO| PETSc Krylov solver starting to solve system.
2023-08-08 14:20:53.712 (   0.230s) [main            ]       NewtonSolver.cpp:36    INFO| Newton iteration 4: r (abs) = 0.0488795 (tol = 1e-10) r (rel) = 0.00278637(tol = 1e-06)
2023-08-08 14:20:53.714 (   0.233s) [main            ]              petsc.cpp:698   INFO| PETSc Krylov solver starting to solve system.
2023-08-08 14:20:53.730 (   0.249s) [main            ]       NewtonSolver.cpp:36    INFO| Newton iteration 5: r (abs) = 0.000293275 (tol = 1e-10) r (rel) = 1.67181e-05(tol = 1e-06)
2023-08-08 14:20:53.733 (   0.251s) [main            ]              petsc.cpp:698   INFO| PETSc Krylov solver starting to solve system.
2023-08-08 14:20:53.747 (   0.266s) [main            ]       NewtonSolver.cpp:36    INFO| Newton iteration 6: r (abs) = 1.60868e-08 (tol = 1e-10) r (rel) = 9.17024e-10(tol = 1e-06)
2023-08-08 14:20:53.747 (   0.266s) [main            ]       NewtonSolver.cpp:255   INFO| Newton solver finished in 6 iterations and 237 linear solver iterations.

Oh my.
I have Dolfinx 0.6.0, installed via conda on Mac OS, two days ago actually. Trying to find out the PETSc version. Thanks a lot

I have tried to see if I can compute your right solution using the Jupyter Lab environment from the docker image docker run --init -ti -p 8888:8888 dolfinx/lab:stable # Access at http://localhost:8888, as found in installation docs.

Using the same MWE I get the error

ArityMismatch: Failure to conjugate test function in complex Form

As suggsted in other posts on this discourse site, I changed the line with the form definition from , as in the MWE

F = q(uh)*ufl.dot(ufl.grad(uh), ufl.grad(v))*ufl.dx - f*v*ufl.dx

to

type or paste code here

just to get another error

ArityMismatch: Adding expressions with non-matching form arguments ('conj(v_0)',) vs ('v_0',).

I am gobsmacked, is the Jupyter Lab environment the most up to date, how come you can run the same MWE with no problems?

Thank you so much for your invaluable support

Make sure that you are using the real mode kernel. If you are running it in jupyterlab, you can change the kernel to the one that does not have complex in the name.

If you are running a script on commandline, you should call source dolfinx-real-mode to set appropriate env variables

Got it, its called Python 3 kernel, fooled me as I was expecting “Dolfinx” somewhere in the name.
And it reproduces Nate’s result. Need only to figure out what’s wring with my conda installation.
Thank you so much

I get the correct solution using my conda installation and docker.io/dolfinx/lab:stable, but garbage when using docker.io/dolfinx/lab:nightly. Is it a PETSc issue? (3.19 vs 3.17?)

Conda installation

python -c "import petsc4py, dolfinx; print(dolfinx.__version__, dolfinx.git_commit_hash); print(petsc4py.__version__)"
0.6.0 7ac1d50b477b430858a9d3f53289bb950900528d
3.17.4

This installation uses the conda builds from around February or so:

conda list fenics
# packages in environment at /home/conpi/miniconda3/envs/dolfinx-r:
#
# Name                    Version                   Build  Channel
fenics-basix              0.6.0           py310hdf3cbec_0    conda-forge
fenics-dolfinx            0.6.0           py310hf97048e_101    conda-forge
fenics-ffcx               0.6.0              pyh56297ac_0    conda-forge
fenics-libbasix           0.6.0                h1284905_0    conda-forge
fenics-libdolfinx         0.6.0              h4cb9d57_101    conda-forge
fenics-ufcx               0.6.0                h56297ac_0    conda-forge
fenics-ufl                2023.1.1           pyhd8ed1ab_1    conda-forge

Docker dolfinx/lab:stable

print(dolfinx.__version__, dolfinx.git_commit_hash)
print(petsc4py.__version__)
0.6.0 24f86a9ce57df6978070dbee22b3eae8bb77235f
3.17.5

Docker dolfinx/lab:nightly

print(dolfinx.__version__, dolfinx.git_commit_hash)
print(petsc4py.__version__)
0.7.0.0 deac4f1cba124f09302f8bb501777f3e25a827c4
3.19.3

Solution:

2 Likes