> On Aug 10, 2020, at 3:27 PM, Mark Adams <[email protected]> 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);
Mark
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.
Barry