Hi!
I’m trying to use block preconditioners in mixed finite element, but I guess my my mapping is wrong. I’m get the following error:
petsc4py.PETSc.Error: error code 60
[15] SNESSolve() at /home/conda/feedstock_root/build_artifacts/petsc_1677582998761/work/src/snes/interface/snes.c:4692
[15] SNESSolve_NEWTONLS() at /home/conda/feedstock_root/build_artifacts/petsc_1677582998761/work/src/snes/impls/ls/ls.c:210
[15] KSPSolve() at /home/conda/feedstock_root/build_artifacts/petsc_1677582998761/work/src/ksp/ksp/interface/itfunc.c:1071
[15] KSPSolve_Private() at /home/conda/feedstock_root/build_artifacts/petsc_1677582998761/work/src/ksp/ksp/interface/itfunc.c:825
[15] KSPSetUp() at /home/conda/feedstock_root/build_artifacts/petsc_1677582998761/work/src/ksp/ksp/interface/itfunc.c:406
[15] PCSetUp() at /home/conda/feedstock_root/build_artifacts/petsc_1677582998761/work/src/ksp/pc/interface/precon.c:994
[15] PCSetUp_FieldSplit() at /home/conda/feedstock_root/build_artifacts/petsc_1677582998761/work/src/ksp/pc/impls/fieldsplit/fieldsplit.c:667
[15] MatCreateSubMatrix() at /home/conda/feedstock_root/build_artifacts/petsc_1677582998761/work/src/mat/interface/matrix.c:8382
[15] MatCreateSubMatrix_MPIAIJ() at /home/conda/feedstock_root/build_artifacts/petsc_1677582998761/work/src/mat/impls/aij/mpi/mpiaij.c:3427
[15] MatCreateSubMatrix_MPIAIJ_nonscalable() at /home/conda/feedstock_root/build_artifacts/petsc_1677582998761/work/src/mat/impls/aij/mpi/mpiaij.c:3809
[15] Nonconforming object sizes
[15] Local column sizes 132618 do not add up to total number of columns 8484
Below follows a mwe of my current code:
V = VectorElement("CG", domain.ufl_cell(), 1)
Q = FiniteElement("CG", domain.ufl_cell(), 1)
solution_space = MixedElement([V,Q])
W = FunctionSpace(domain, solution_space)
W0, _ = W.sub(0).collapse()
W1, _ = W.sub(1).collapse()
w = Function(W)
(u, p) = w.split()
(du, dp) = TrialFunctions(W)
(v, q) = TestFunctions(W)
F_momentum = (
dot(dot(u,nabla_grad(u)),v)*dx
+ (1/Re)*inner(grad(u),grad(v))*dx
- inner(p,div(v))*dx
+ inner(tau_SUPG*grad(v)*u,dot(u,grad(u)) - (1/Re)*div(grad(u)) + grad(p))*dx
)
F_continuity = (
(q*div(u))*dx
+ inner(tau_PSPG*grad(q), dot(u,grad(u)) - (1/Re)*div(grad(u)) + grad(p))*dx
)
F = form([F_momentum, F_continuity])
jacobian = form(
[
[derivative(F_momentum, u, du) , derivative(F_momentum, p, dp)],
[derivative(F_continuity, u, du) , derivative(F_continuity, p, dp)],
]
)
P = form([[jacobian[0][0], None], [None, inner(dp,q)*dx]])
# Assemble Jacobian and mass matrices and residual vector
jacobian_matrix = create_matrix_block(jacobian)
P_matrix = create_matrix_block(P)
residual_vector = create_vector_block(F)
# Create nonlinear solver
nonlinear_solver = PETSc.SNES().create(comm)
nonlinear_solver.getKSP().setType("fgmres")
nonlinear_solver.getKSP().getPC().setType("fieldsplit")
V_map = W0.dofmap.index_map
Q_map = W1.dofmap.index_map
offset_u = V_map.local_range[0]*W0.dofmap.index_map_bs + Q_map.local_range[0]
offset_p = offset_u + V_map.size_local*W0.dofmap.index_map_bs
is_u = PETSc.IS().createStride(V_map.size_local*W0.dofmap.index_map_bs, offset_u, 1, comm=PETSc.COMM_SELF)
is_p = PETSc.IS().createStride(Q_map.size_local, offset_p, 1, comm=PETSc.COMM_SELF)
nonlinear_solver.getKSP().getPC().setFieldSplitIS(("u", is_u),("p", is_p))
ksp_u, ksp_p = nonlinear_solver.getKSP().getPC().getFieldSplitSubKSP()
# Velocity block
ksp_u.setType("preonly")
ksp_u.getPC().setType("hypre")
# Pressure block
ksp_p.setType("preonly")
ksp_p.getPC().setType("jacobi")
# Solve nonlinear problem
problem = Nonlinear_PDE_SNES_Problem(F, jacobian, [u, p], boundary_conditions_navier_stokes, P)
nonlinear_solver.setFunction(problem.F_block, residual_vector)
nonlinear_solver.setJacobian(problem.J_block, jacobian_matrix, P_matrix)
# Create solution vector
x = create_vector_block(F)
u = Function(W0)
p = Function(W1)
with u.vector.localForm() as _u, p.vector.localForm() as _p:
scatter_local_vectors(
x,
[_u.array_r, _p.array_r],
[
(u.function_space.dofmap.index_map, u.function_space.dofmap.index_map_bs),
(p.function_space.dofmap.index_map, p.function_space.dofmap.index_map_bs),
],
)
x.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)
nonlinear_solver.solve(None, x)
Can anyone figure out what’s going on? Thank you.