MPC: lifetime of MultiPointConstraint

Hi, I see that in the following snippet there is an MPI failure:

from typing import Any

import dolfinx
import dolfinx_mpc
import ufl
from mpi4py import MPI


def test_broken() -> None:
    def myfun() -> Any:
        mesh = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, 5, 5)
        V = dolfinx.fem.functionspace(mesh, ("Lagrange", 1))
        mpc = dolfinx_mpc.MultiPointConstraint(V)
        mpc.finalize()
        base = ufl.TestFunction(V) * ufl.dx
        return dolfinx_mpc.assemble_vector(dolfinx.fem.form(base), mpc)

    vec = myfun()
    assert vec is not None
    vec1 = vec.duplicate()
    assert vec1 is not None

The failure happen in the duplicate(), and is related to the fact that mpc is released after myfun():

[0]PETSC ERROR: Caught signal number 11 SEGV: Segmentation Violation, probably memory access out of range
[0]PETSC ERROR: Try option -start_in_debugger or -on_error_attach_debugger
[0]PETSC ERROR: or see FAQ — PETSc 3.23.2 documentation and FAQ — PETSc 3.23.2 documentation
[0]PETSC ERROR: configure using --with-debugging=yes, recompile, link, and run
[0]PETSC ERROR: to get more information on the crash.
[0]PETSC ERROR: Run with -malloc_debug to check if memory corruption is causing the crash.
MPI_ABORT was invoked on rank 0 in communicator MPI_COMM_WORLD
Proc: [[7410,1],0]
Errorcode: 59
NOTE: invoking MPI_ABORT causes Open MPI to kill all MPI processes.
You may or may not see output from other processes, depending on
exactly when Open MPI kills them.
prterun has exited due to process rank 0 with PID 0 on node Ideapad-Lenovo calling
“abort”. This may have caused other processes in the application to be
terminated by signals sent by prterun (as reported here).

If I keep the mpc instance alive, the duplication works fine.
Is this expected? Or should the petscvec own its communicator?

Thanks,
Mattia

The easiest workaround here is to use vec = dolfinx.fem.Function(mpc.function_space) which you can send into your assembler as dolfinx_mpc.assemble_vector(dolfinx.fem.form(base), mpc, vec.x.petsc_vec)

it will keep the index-map of the function space alive, which means that the communicator could be duplicated.