Skip to content

CylindricalStokes(boundary='zero') leaves the pressure nullspace in place #577

Description

@lmoresi

What

uw.analytic.CylindricalStokes with boundary="zero" configures a solver without setting petsc_use_pressure_nullspace. Every other enclosed solution in the suite sets it.

src/underworld3/analytic/kramer.py, CylindricalStokes.apply_boundary_conditions:

if self.boundary == "zero":
    prescribed_velocity(solver, self.boundaries, (0.0, 0.0))
    return          # <- returns before the nullspace line

free_slip(solver, self.boundaries)
solver.petsc_use_pressure_nullspace = True

Why it matters

An annulus held at zero velocity on both arcs is an enclosed domain with velocity prescribed everywhere on its boundary. Its pressure is determined only up to a constant, so the saddle-point operator is singular in the pressure direction. A direct solve on that system does not necessarily fail — it can return a quiet, wrong answer with an arbitrary pressure offset, which is exactly the failure mode an exact solution exists to expose.

The free-slip branch of the same class is unaffected: it sets the nullspace.

How it hid

The nullspace was set once at the end of the method, after the zero branch's early return. Under the (now removed) FreeSlipWalls/FixedWalls mixins the setting was buried inside a wall type, so the omission was not visible where the conditions are written. With each solution stating the nullspace for itself it is one line on the page.

Found while making the mixin -> composition refactor behaviour-preserving; preserved verbatim there under a TODO(BUG) because that change is byte-equivalent by contract.

Fix

Set the nullspace in both branches. Needs its own regression test — the natural oracle is the pressure error against the exact Kramer solution for boundary="zero", which should be checked against the solution's own gauge rather than assumed zero-mean.

Requires the assess package (the case is skipped without it), so the test must carry the same skip as the rest of the Kramer coverage.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions