[petsc-dev] How to pass user data to a registered PC (PCRegister) ?

Smith, Barry F. bsmith at mcs.anl.gov
Fri Dec 29 10:55:30 CST 2017



> On Dec 29, 2017, at 9:03 AM, Franck Houssen <franck.houssen at inria.fr> wrote:
> 
> OK, on the highway now (bad ssh !), I'll try to check this out.
> 
> ----- Mail original -----
>> De: "Barry F. Smith" <bsmith at mcs.anl.gov>
>> À: "Franck Houssen" <franck.houssen at inria.fr>
>> Cc: "For users of the development version of PETSc" <petsc-dev at mcs.anl.gov>
>> Envoyé: Jeudi 28 Décembre 2017 18:21:48
>> Objet: Re: [petsc-dev] How to pass user data to a registered PC (PCRegister) ?
>> 
>> 
>> 
>>> On Dec 28, 2017, at 10:34 AM, Franck Houssen <franck.houssen at inria.fr>
>>> wrote:
>>> 
>>> ----- Mail original -----
>>>> De: "Barry F. Smith" <bsmith at mcs.anl.gov>
>>>> À: "Franck Houssen" <franck.houssen at inria.fr>
>>>> Cc: "For users of the development version of PETSc"
>>>> <petsc-dev at mcs.anl.gov>
>>>> Envoyé: Jeudi 28 Décembre 2017 16:43:16
>>>> Objet: Re: [petsc-dev] How to pass user data to a registered PC
>>>> (PCRegister) ?
>>>> 
>>>> 
>>>>  The register is for a new type of PC of which can have many
>>>>  instantiations
>>>>  at the same time.
>>> 
>>> OK, I didn't get that that way ! I was looking for a way to plug "my" pc at
>>> the command line this way: -pc_type my_pc.
>>> I already call PCSetType(pc, PCSHELL) and PCShellSetName(pc, "my_pc"):
>>> maybe this already enables "-pc_type shell" or "-pc_type my_pc"... And I
>>> didn't know it ! :D I'll try that.
>>> 
>>> I was looking for a way to integrate "my" (external) pc as any other
>>> regular/existing petsc pc (bjacobi, ...) like a kind of plugin but still
>>> integrated to the cmd line: I believed PCRegister was meant for that.
>> 
>>   Indeed it is exactly what it is meant for.  Please try to follow my recipe
>>   and let us know when you get stuck.
>> 
>> 
>>> Not sure if this is actually possible/enabled by the API.
>>> 
>>>> For example
>>>> 
>>>>   PCRegister("mypctype",mypc_create);
>>>> 
>>>>   KSPCreate(&ksp1);
>>>>   KSPCreate(&ksp2);
>>>> 
>>>>   KSPGetPC(ksp1,&pc1);
>>>>   KSPGetPC(ksp2,&pc2);
>>>> 
>>>>   You don't want pc1 and pc2 to have the same dof multiplicities, domain
>>>>   intersections etc since they are associated with completely different
>>>>   linear systems and presumably meshes etc.
>>>> 
>>>> 
>>>>    Presumably you want each of pc1, pc2, to have their own version of the
>>>>    data so you need to stick it directly in the PC, for example
>>>> 
>>>>  PCMypcSetDOFMultiplicities(pc1,stuff);
>>>> PCMypcSetDOFMultiplicities(pc2,otherstuff);
>>>> 
> 
> OK, I must provide/implement PCMypcSetDOFMultiplicities (add data to pc context) besides mypc_create: sounds logical.
> Is this OK if PCMypcSetDOFMultiplicities is independent from mypc_create ? I guess yes.
> 
> From what I remember/understand, I got lost here: from the jacobi example, mypc_create looks to be supposed (?) to call some kind of Petsc*ComposeFunction to associate PCMypcSetDOFMultiplicities to the pc (correct ?)... But, in the jacobi example, PCJacobiGetUseAbs_Jacobi is associated to PCJacobiGetUseAbs_C...

  the _C name is a string name that is used by PETSc to "find" the correct function pointer which is PCJacobiGetUseAbs_Jacobi. There is no 
_C function.

> Which turns out not to be implemented according to git grep ?! Got lost here (and looked for a way to pass user data directly to PCRegister): is PCMypcSetDOFMultiplicities supposed to be "attached/composed" or independent from the pc ?

   composed.

> 
>>> git grep PCJacobiGetUseAbs_C
> src/ksp/pc/impls/jacobi/jacobi.c:  ierr = PetscObjectComposeFunction((PetscObject)pc,"PCJacobiGetUseAbs_C",PCJacobiGetUseAbs_Jacobi);CHKERRQ(ierr);
> src/ksp/pc/impls/jacobi/jacobi.c:  ierr = PetscUseMethod(pc,"PCJacobiGetUseAbs_C",(PC,PetscBool*),(pc,flg));CHKERRQ(ierr);
> 
> Sorry, for the short answer. Hope I succeeded to be clear enough.

   Just copy jacobi.c and start converting it over to your names and needs and you'll see it is actually really straightforward and not as complicated as you think it is.

   Barry

> 
>>>> You write as many of these Set() functions as you need for your PCtype.
>>>> You
>>>> store the data inside the PC_Mypc data structure you create with
>>>> mypc_create(). Look at PCCreate_Jacobi() and PCJacobiSetType for the
>>>> pattern.
>>>> 
>>>>  Barry
>>>> 
>>>> 
>>>>> On Dec 28, 2017, at 9:34 AM, Franck Houssen <franck.houssen at inria.fr>
>>>>> wrote:
>>>>> 
>>>>> How to pass user data to a registered PC (PCRegister) ?
>>>>> 
>>>>> At first, I expected the signature would be "PetscErrorCode
>>>>> PCRegister(const char sname[],PetscErrorCode (*function)(PC, void *))"
>>>>> but
>>>>> it turns out to be "PetscErrorCode PCRegister(const char
>>>>> sname[],PetscErrorCode (*function)(PC))"
>>>>> 
>>>>> I try to integrate a PC that needs A but also other informations (dof
>>>>> multiplicities, domain intersections that the user must provide). I guess
>>>>> I can get A with PCGetOperators in the setup callback of the PC. But
>>>>> still
>>>>> not sure how to pass the other informations if I get to use PCRegister. I
>>>>> looked a few examples in the bitbucket (jacobi:
>>>>> src/ksp/ksp/examples/tutorials/ex12.c and
>>>>> src/ksp/pc/impls/jacobi/jacobi.c
>>>>> + SOR: src/ksp/pc/impls/sor/sor.c)... But didn't get any real relevant
>>>>> answer and feel a bit lost among the numerous pc !...
>>>>> 
>>>>> The idea is: for now I use PCSetType(pc, PCSHELL) and PCShellSetContext
>>>>> with a context who knows the extra needed informations which is "not so
>>>>> handy" (that's OK as for now I am both the user and the PC provider). I'd
>>>>> like to package this in a more convenient way (a unique and "simple" call
>>>>> to PCRegister) to decouple the user from the PC machinery.
>>>>> 
>>>>> Franck



More information about the petsc-dev mailing list