[petsc-dev] PetscContainerSetPointer

Barry Smith bsmith at petsc.dev
Mon Aug 10 16:33:43 CDT 2020

> On Aug 10, 2020, at 3:27 PM, Mark Adams <mfadams at lbl.gov> wrote:
> I had some problems giving a container an PETSc object so I wrapped it in a struct. 
> I forget what problem I had. Maybe ISColoringDestroy can't take a void*.
> I'd like to check if I was just missing something. 
> Should something like this work?
>     ISColoring c;
>     ....
>     ierr = PetscContainerSetPointer(container,(void*)c);CHKERRQ(ierr);
>     ierr = PetscContainerSetUserDestroy(container, ISColoringDestroy);CHKERRQ(ierr);


   ISColoring is a plain old C struct: 

struct _n_ISColoring {
  PetscInt        refct;

so it seems like this should work. But ISColoringDestroy(), like most PETSc destroy functions, takes the address of the pointer as the argument (as opposed to the pointer itself, this is so XXXDestroy() can set the pointer to null to prevent it getting used again accidentally with a now meaningless value.) So there is a disconnect in how PETSc handles destroying objects (take the address of a pointer) and the pointer for containers (take a pointer). Looking back I just made the container concept as simple as possible and did not think about the API difference. We could fix it now but it might break a tiny bit of user code.

This should work

static PetscErrorCode MyISColoringDestroy(void *is)
   ISColoring tmp = (ISColoring)is;
   return ISColoringDestroy(&tmp);

ierr = PetscContainerSetUserDestroy(container, MyISColoringDestroy);CHKERRQ(ierr);

then you won't need the dummy struct.


More information about the petsc-dev mailing list