def METHOD_NAME(self, pc):
    from firedrake import (TrialFunction, TestFunction, dx, inner,
                           grad, split, Constant, parameters)
    from firedrake.assemble import allocate_matrix, assemble, TwoFormAssembler
    if pc.getType() != "python":
        raise ValueError("Expecting PC type python")
    prefix = pc.getOptionsPrefix() + "pcd_"
    # we assume P has things stuffed inside of it
    _, P = pc.getOperators()
    context = P.getPythonContext()
    test, trial = context.a.arguments()
    if test.function_space() != trial.function_space():
        raise ValueError("Pressure space test and trial space differ")
    Q = test.function_space()
    p = TrialFunction(Q)
    q = TestFunction(Q)
    mass = p*q*dx
    # Regularisation to avoid having to think about nullspaces.
    stiffness = inner(grad(p), grad(q))*dx + Constant(1e-6)*p*q*dx
    opts = PETSc.Options()
    # we're inverting Mp and Kp, so default them to assembled.
    # Fp only needs its action, so default it to mat-free.
    # These can of course be overridden.
    # only Fp is referred to in update, so that's the only
    # one we stash.
    default = parameters["default_matrix_type"]
    Mp_mat_type = opts.getString(prefix+"Mp_mat_type", default)
    Kp_mat_type = opts.getString(prefix+"Kp_mat_type", default)
    self.Fp_mat_type = opts.getString(prefix+"Fp_mat_type", "matfree")
    Mp = assemble(mass, form_compiler_parameters=context.fc_params,
                  mat_type=Mp_mat_type,
                  options_prefix=prefix + "Mp_")
    Kp = assemble(stiffness, form_compiler_parameters=context.fc_params,
                  mat_type=Kp_mat_type,
                  options_prefix=prefix + "Kp_")
    # FIXME: Should we transfer nullspaces over.  I think not.
    Mksp = PETSc.KSP().create(comm=pc.comm)
    Mksp.incrementTabLevel(1, parent=pc)
    Mksp.setOptionsPrefix(prefix + "Mp_")
    Mksp.setOperators(Mp.petscmat)
    Mksp.setUp()
    Mksp.setFromOptions()
    self.Mksp = Mksp
    Kksp = PETSc.KSP().create(comm=pc.comm)
    Kksp.incrementTabLevel(1, parent=pc)
    Kksp.setOptionsPrefix(prefix + "Kp_")
    Kksp.setOperators(Kp.petscmat)
    Kksp.setUp()
    Kksp.setFromOptions()
    self.Kksp = Kksp
    state = context.appctx["state"]
    Re = context.appctx.get("Re", 1.0)
    velid = context.appctx["velocity_space"]
    u0 = split(state)[velid]
    fp = 1.0/Re * inner(grad(p), grad(q))*dx + inner(u0, grad(p))*q*dx
    self.Re = Re
    self.Fp = allocate_matrix(fp, form_compiler_parameters=context.fc_params,
                              mat_type=self.Fp_mat_type,
                              options_prefix=prefix + "Fp_")
    self._assemble_Fp = TwoFormAssembler(fp, tensor=self.Fp,
                                         form_compiler_parameters=context.fc_params).assemble
    self._assemble_Fp()
    Fpmat = self.Fp.petscmat
    self.workspace = [Fpmat.createVecLeft() for i in (0, 1)]