Here is a minimal example highlighting the two issues of your code
- The boundary condition is wrong
- The nullspace creation is overly complicated
import dolfinx
import numpy as np
import ufl
from mpi4py import MPI
from petsc4py import PETSc
N = 10
mesh = dolfinx.mesh.create_unit_cube(MPI.COMM_WORLD, N, N, N,
cell_type=dolfinx.mesh.CellType.hexahedron)
P2 = ufl.VectorElement("Lagrange", mesh.ufl_cell(), 2)
P1 = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), 1)
TH = ufl.MixedElement([P2, P1])
W = dolfinx.fem.FunctionSpace(mesh, TH)
def u_ex(x):
return np.vstack((4*(x[1]-1)*x[1]*(x[0]-1)*(x[0]-1)*x[0]*x[0]*(x[1]-0.5), -4*(x[0]-0.5)*x[1]*x[1]*x[0]*(x[1]-1)*(x[1]-1)*(x[0]-1), np.zeros_like(x[0])))
def p_ex(x):
return x[0]+x[1]+x[2]-3./2
V, V_to_W = W.sub(0).collapse()
Q, Q_to_W = W.sub(1).collapse()
### Define the boundary condition -> which in this case are only of Dirichlet type
uD = dolfinx.fem.Function(V)
uD.interpolate(u_ex)
# Create facet to cell connectivity required to determine boundary facets
tdim = mesh.topology.dim
fdim = tdim - 1
mesh.topology.create_connectivity(fdim, tdim)
boundary_facets = dolfinx.mesh.exterior_facet_indices(mesh.topology)
boundary_dofs = dolfinx.fem.locate_dofs_topological((W.sub(0),V), fdim, boundary_facets)
bcs = [dolfinx.fem.dirichletbc(uD, boundary_dofs, W.sub(0))]
(u, p) = ufl.TrialFunctions(W)
(v, q) = ufl.TestFunctions(W)
dx = ufl.Measure("dx", domain=mesh)
a = ufl.inner(ufl.grad(u), ufl.grad(v)) * dx + \
ufl.div(v)*p*dx + q*ufl.div(u)*dx
a_f = dolfinx.fem.form(a)
A = dolfinx.fem.petsc.assemble_matrix(a_f, bcs=bcs)
A.assemble()
ns_vec = dolfinx.fem.Function(W)
ns_vec.x.array[Q_to_W] = 1
dolfinx.la.orthonormalize([ns_vec.vector])
nullspace = PETSc.NullSpace().create(vectors=[ns_vec.vector])
assert nullspace.test(A)
A.setNearNullSpace(nullspace)