Hello,
I have a problem similar to the one in Error setting PETSc options repeatedly. I want to solve a non-linear problem with an iterative scheme, where the system matrix (not the right-hand side as in the similar problem) changes in each iteration. After a couple of iterations, I obtain the error
problem = dolfinx.fem.petsc.LinearProblem(a, L, bcs=[bc], petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
File "/usr/lib/petsc/lib/python3/dist-packages/dolfinx/fem/petsc.py", line 594, in __init__
opts[k] = v
File "PETSc/Options.pyx", line 23, in petsc4py.PETSc.Options.__setitem__
File "PETSc/Options.pyx", line 91, in petsc4py.PETSc.Options.setValue
petsc4py.PETSc.Error: error code 55
I think I should not initialize a new LinearSolver in each iteration, but how do I update the bilinear form a otherwise? Here is some code that leads to the error:
import dolfinx
from mpi4py import MPI
import ufl
import numpy as np
mesh = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, 16, 16, cell_type=dolfinx.mesh.CellType.triangle)
V = dolfinx.fem.FunctionSpace(mesh, ("CG", 1))
u_h = dolfinx.fem.Function(V)
p = dolfinx.fem.Constant(mesh,1.5)
f = dolfinx.fem.Constant(mesh,1.)
def u_exact(x):
return x[0]*x[1]
u_h.interpolate(u_exact)
def KacanovStep(u_h):
from ufl import conditional
#from petsc4py import PETSc
def ufl_max(a, b):
return conditional(a > b, a, b)
def ufl_min(a, b):
return conditional(a < b, a, b)
V = u_h.function_space
mesh = V.mesh
eps_min_sq = dolfinx.fem.Constant(mesh,0.01)
eps_max_sq = dolfinx.fem.Constant(mesh,100.)
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)
# Define bilinear form and right-hand side
a = (ufl_min(eps_max_sq,ufl_max(eps_min_sq,ufl.dot(ufl.grad(u_h),ufl.grad(u_h))))**(p/2-1)*ufl.dot(ufl.grad(u), ufl.grad(v))) * ufl.dx
L = f * v * ufl.dx
# Apply homogeneous Dirichlet boundary conditions
def boundary(x):
return np.full((1, x.shape[1]), True)
boundary_facets = dolfinx.mesh.locate_entities_boundary(mesh, mesh.topology.dim - 1,boundary)
bc = dolfinx.fem.dirichletbc(u_h, dolfinx.fem.locate_dofs_topological(V, mesh.topology.dim - 1, boundary_facets))
problem = dolfinx.fem.petsc.LinearProblem(a, L, bcs=[bc], petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
u_h = problem.solve()
return u_h
for curIter in range(0,1000):
u_h = KacanovStep(u_h)
print('nrIter =', curIter,'J(u_h) =',dolfinx.fem.assemble_scalar(dolfinx.fem.form((1/p*ufl.inner(ufl.grad(u_h),ufl.grad(u_h))**(p/2))*ufl.dx)))