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

pressure nullspace for Stokes problem

+2 votes

Dear all,

I am trying to solve an "enclosed flow" Stokes problem, with Dirichlet BCs for the velocity on all of the boundary, using a mixed function space of P2/P1 elements.
The problem is solved with GMRES using a PETSc fieldsplit Schur preconditioner, where the preconditioning matrix for the Schur complement matrix is the pressure mass matrix.
I think that in order to achieve good convergence I need to remove the pressure nullspace from the system. There are examples of nullspaces for poisson and elasticity, but I don't know how to do this for subspace of a mixed function space.
Are there any examples around...? This seems like a pretty standard procedure.

Thanks a lot in advance

David

asked Jun 12, 2017 by dajuno FEniCS User (4,140 points)

Maybe you could write your formulation, because there essentially two ways: one is using the PETSc null_space command, which apparently projects your problem to the orthogonal space of the nullspace you define (I'm not sure how it really works). Another option is imposing orthogonality weakly, which in this case would be adding another variable which is constant in the entire domain, which is done in the poisson example you mention:

https://fenicsproject.org/olddocs/dolfin/1.4.0/python/demo/documented/neumann-poisson/python/documentation.html

The problem with the last one is that probably you preconditioner will change, but this is another thing I am not schur of (haha).

Yes, I don't want to use a Lagrangian multiplier but inform the solver of the nullspace directly.
Turns out GMRES does this automagically for consistent RHS, so I did not have to do anything.

However, it seems the correct approach would be the same as in the examples I linked, simply ignoring the components of the mixed function space that are not affected. Something like

    w = Function(W)    # W is mixed FS
    nullspace_basis = w.vector().copy()
    W.sub(1).dofmap().set(nullspace_basis, 1.0)
    nullspace_basis.apply('insert')
    nullspace = VectorSpaceBasis([nullspace_basis])
    nullspace.orthonormalize()

    # assemble A and apply BCs
    A.set_near_nullspace(nullspace)

Thanks

...