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

Smith, Barry F. bsmith at mcs.anl.gov
Sun Dec 31 16:41:42 CST 2017



> On Dec 31, 2017, at 8:40 AM, Franck Houssen <franck.houssen at inria.fr> wrote:
> 
> Seems finally, I got it to work.
> To get the options to work I had to call PetscOptionsBegin/End after/before PetscOptionsHead/Tail which is not what is done in the jacobi example: is this the right way to go ?

  Something is wrong. PetscOptionsBegin/end are called in PCSetFromOptions() that is suppose to wrap YOUR PCSetFromOptions_mypc(). Perhaps you are calling PCSetFromOptions_mypc directly which you should never do. Your PCCreate_mypc() should stick the function pointer for PCSetFromOptions_mypc into the ops table like it does PCApply_mypc etc. Then you just directly use PCSetFromOptions.

   Barry

> 
> Franck
> 
> PetscErrorCode PCSetFromOptions_mypc(PetscOptionItems * PetscOptionsObject, PC pcPC) {
> PetscOptionsHead
> PetscOptionsBegin
> ... // PetscOptionsStringArray
> PetscOptionsEnd
> PetscOptionsTail
> 
> 
> ----- Mail original -----
>> De: "Franck Houssen" <franck.houssen at inria.fr>
>> À: "Barry F. Smith" <bsmith at mcs.anl.gov>
>> Cc: "For users of the development version of PETSc" <petsc-dev at mcs.anl.gov>
>> Envoyé: Dimanche 31 Décembre 2017 15:01:43
>> Objet: Re: [petsc-dev] How to pass user data to a registered PC (PCRegister) ?
>> 
>> Using PCSHELL means calling:
>> - PCShellSetSetUp, PCShellSetApply, PCShellSetDestroy to set callbacks.
>> - PCShellSetContext/PCShellGetContext to get/set context in callbacks.
>> 
>> To go from PCSHELL to PCRegister, one need to:
>> - #include <petsc/private/pcimpl.h> // Access to PC data/struct.
>> - Set callbacks with pc->ops->...
>> - NO more use ANY shell methods (context, name), but, use pc->data instead.
>> - call PCRegister.
>> 
>> Correct ? Did I miss something ?
>> 
>> Seems I get things to work (without compose function).
>> 
>> The last problem I have is in the options: options are passed to
>> PetscInitialize but not found in the database (I mimic'ed the jacobi
>> example). Is there specific related to this ?
>> 
>> 
>> ----- Mail original -----
>>> De: "Franck Houssen" <franck.houssen at inria.fr>
>>> À: "Barry F. Smith" <bsmith at mcs.anl.gov>
>>> Cc: "For users of the development version of PETSc" <petsc-dev at mcs.anl.gov>
>>> Envoyé: Samedi 30 Décembre 2017 17:12:09
>>> Objet: Re: [petsc-dev] How to pass user data to a registered PC
>>> (PCRegister) ?
>>> 
>>> Don't get the link. I'll try first with independent function (no compose)
>>> and
>>> see if this can work at least for a start.
>>> 
>>> Franck
>>> 
>>> ----- 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é: Vendredi 29 Décembre 2017 17:55:30
>>>> Objet: Re: [petsc-dev] How to pass user data to a registered PC
>>>> (PCRegister) ?
>>>> 
>>>> 
>>>> 
>>>>> 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