<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Jan 2, 2018 at 6:04 AM, Franck Houssen <span dir="ltr"><<a href="mailto:franck.houssen@inria.fr" target="_blank">franck.houssen@inria.fr</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">----- Mail original -----<br>
> De: "Barry F. Smith" <<a href="mailto:bsmith@mcs.anl.gov">bsmith@mcs.anl.gov</a>><br>
> À: "Franck Houssen" <<a href="mailto:franck.houssen@inria.fr">franck.houssen@inria.fr</a>><br>
> Cc: "For users of the development version of PETSc" <<a href="mailto:petsc-dev@mcs.anl.gov">petsc-dev@mcs.anl.gov</a>><br>
> Envoyé: Dimanche 31 Décembre 2017 23:41:42<br>
> Objet: Re: [petsc-dev] How to pass user data to a registered PC (PCRegister) ?<br>
><br>
><br>
><br>
> > On Dec 31, 2017, at 8:40 AM, Franck Houssen <<a href="mailto:franck.houssen@inria.fr">franck.houssen@inria.fr</a>><br>
> > wrote:<br>
> ><br>
> > Seems finally, I got it to work.<br>
> > To get the options to work I had to call PetscOptionsBegin/End after/before<br>
> > PetscOptionsHead/Tail which is not what is done in the jacobi example: is<br>
> > this the right way to go ?<br>
><br>
>   Something is wrong.<br>
<br>
I felt there was something wrong !...<br>
<br>
> PetscOptionsBegin/end are called in PCSetFromOptions()<br>
>   that is suppose to wrap YOUR PCSetFromOptions_mypc().<br>
<br>
OK, sounds logical, that's how I expected things to be done. That's why I was suspicious: what worked should not !...<br>
<br>
I believed maybe the problem was connected to the fact that I do NOT use compose function, but, according to Matt's explanation, I would say no: the use of PetscComposeFunction seems independent from the PCSetFromOptions_mypc problem.<br>
<br>
Note: in my case, I believe I do not really need PetscCompose, I just need one (regular) function to initialize specific stuffs needed in my_pc (at least for a start). I can go to PetscCompose later if it turns out to be relevant (that's how I understand this).<br>
<br>
> Perhaps you are<br>
>   calling PCSetFromOptions_mypc directly which you should never do.<br>
<br>
No, I don't call PCSetFromOptions_mypc directly.<br>
<br>
> Your PCCreate_mypc() should stick the function pointer for<br>
>   PCSetFromOptions_mypc into the ops table like it does PCApply_mypc etc.<br>
>   Then you just directly use PCSetFromOptions.<br>
<br>
create_mpc(PC pc) { // CB for PCRegister<br>
  ...<br>
  pcPC->ops->setfromoptions = setupfromoptions_mypc;<br>
  ...<br>
}<br>
<br>
static PetscErrorCode setupfromoptions_mypc(<wbr>PetscOptionItems * PetscOptionsObject, PC pcPC) {<br>
  ...<br>
  PetscOptionsHead()<br>
  PetscOptionsBegin()<br>
  PetscOptionsStringArray("-<wbr>mypc_opt", ..., flag)<br>
  cout << "debug " << flag << endl;<br>
  PetscOptionsEnd()<br>
  PetscOptionsTail()<br>
}<br>
<br>
I got called on setupfromoptions_mypc when I call PCSetUpFromOptions().<br>
<br>
If I let PetscOptionsBegin/End, it looks like I read in the "correct" option data base, I get (cout) : "debug 1" (-my_opt is read)<br>
<br>
If I comment PetscOptionsBegin/End, seems I read an incorrect (empty ?) option data base, I get (cout) : "debug 0"<br></blockquote><div><br></div><div>Clearly something is being called with a wrong argument. I think Barry's suggestion is best. You know that Jacobi works</div><div>and processes options correctly. Change that one step at a time into your PC.</div><div><br></div><div>  Thanks,</div><div><br></div><div>     Matt</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Looks weird even if it's not blocking for now (I know there is problem but I can by pass it)<br>
<br>
><br>
>    Barry<br>
><br>
> ><br>
> > Franck<br>
> ><br>
> > PetscErrorCode PCSetFromOptions_mypc(<wbr>PetscOptionItems * PetscOptionsObject,<br>
> > PC pcPC) {<br>
> > PetscOptionsHead<br>
> > PetscOptionsBegin<br>
> > ... // PetscOptionsStringArray<br>
> > PetscOptionsEnd<br>
> > PetscOptionsTail<br>
> ><br>
> ><br>
> > ----- Mail original -----<br>
> >> De: "Franck Houssen" <<a href="mailto:franck.houssen@inria.fr">franck.houssen@inria.fr</a>><br>
> >> À: "Barry F. Smith" <<a href="mailto:bsmith@mcs.anl.gov">bsmith@mcs.anl.gov</a>><br>
> >> Cc: "For users of the development version of PETSc"<br>
> >> <<a href="mailto:petsc-dev@mcs.anl.gov">petsc-dev@mcs.anl.gov</a>><br>
> >> Envoyé: Dimanche 31 Décembre 2017 15:01:43<br>
> >> Objet: Re: [petsc-dev] How to pass user data to a registered PC<br>
> >> (PCRegister) ?<br>
> >><br>
> >> Using PCSHELL means calling:<br>
> >> - PCShellSetSetUp, PCShellSetApply, PCShellSetDestroy to set callbacks.<br>
> >> - PCShellSetContext/<wbr>PCShellGetContext to get/set context in callbacks.<br>
> >><br>
> >> To go from PCSHELL to PCRegister, one need to:<br>
> >> - #include <petsc/private/pcimpl.h> // Access to PC data/struct.<br>
> >> - Set callbacks with pc->ops->...<br>
> >> - NO more use ANY shell methods (context, name), but, use pc->data<br>
> >> instead.<br>
> >> - call PCRegister.<br>
> >><br>
> >> Correct ? Did I miss something ?<br>
> >><br>
> >> Seems I get things to work (without compose function).<br>
> >><br>
> >> The last problem I have is in the options: options are passed to<br>
> >> PetscInitialize but not found in the database (I mimic'ed the jacobi<br>
> >> example). Is there specific related to this ?<br>
> >><br>
> >><br>
> >> ----- Mail original -----<br>
> >>> De: "Franck Houssen" <<a href="mailto:franck.houssen@inria.fr">franck.houssen@inria.fr</a>><br>
> >>> À: "Barry F. Smith" <<a href="mailto:bsmith@mcs.anl.gov">bsmith@mcs.anl.gov</a>><br>
> >>> Cc: "For users of the development version of PETSc"<br>
> >>> <<a href="mailto:petsc-dev@mcs.anl.gov">petsc-dev@mcs.anl.gov</a>><br>
> >>> Envoyé: Samedi 30 Décembre 2017 17:12:09<br>
> >>> Objet: Re: [petsc-dev] How to pass user data to a registered PC<br>
> >>> (PCRegister) ?<br>
> >>><br>
> >>> Don't get the link. I'll try first with independent function (no compose)<br>
> >>> and<br>
> >>> see if this can work at least for a start.<br>
> >>><br>
> >>> Franck<br>
> >>><br>
> >>> ----- Mail original -----<br>
> >>>> De: "Barry F. Smith" <<a href="mailto:bsmith@mcs.anl.gov">bsmith@mcs.anl.gov</a>><br>
> >>>> À: "Franck Houssen" <<a href="mailto:franck.houssen@inria.fr">franck.houssen@inria.fr</a>><br>
> >>>> Cc: "For users of the development version of PETSc"<br>
> >>>> <<a href="mailto:petsc-dev@mcs.anl.gov">petsc-dev@mcs.anl.gov</a>><br>
> >>>> Envoyé: Vendredi 29 Décembre 2017 17:55:30<br>
> >>>> Objet: Re: [petsc-dev] How to pass user data to a registered PC<br>
> >>>> (PCRegister) ?<br>
> >>>><br>
> >>>><br>
> >>>><br>
> >>>>> On Dec 29, 2017, at 9:03 AM, Franck Houssen <<a href="mailto:franck.houssen@inria.fr">franck.houssen@inria.fr</a>><br>
> >>>>> wrote:<br>
> >>>>><br>
> >>>>> OK, on the highway now (bad ssh !), I'll try to check this out.<br>
> >>>>><br>
> >>>>> ----- Mail original -----<br>
> >>>>>> De: "Barry F. Smith" <<a href="mailto:bsmith@mcs.anl.gov">bsmith@mcs.anl.gov</a>><br>
> >>>>>> À: "Franck Houssen" <<a href="mailto:franck.houssen@inria.fr">franck.houssen@inria.fr</a>><br>
> >>>>>> Cc: "For users of the development version of PETSc"<br>
> >>>>>> <<a href="mailto:petsc-dev@mcs.anl.gov">petsc-dev@mcs.anl.gov</a>><br>
> >>>>>> Envoyé: Jeudi 28 Décembre 2017 18:21:48<br>
> >>>>>> Objet: Re: [petsc-dev] How to pass user data to a registered PC<br>
> >>>>>> (PCRegister) ?<br>
> >>>>>><br>
> >>>>>><br>
> >>>>>><br>
> >>>>>>> On Dec 28, 2017, at 10:34 AM, Franck Houssen<br>
> >>>>>>> <<a href="mailto:franck.houssen@inria.fr">franck.houssen@inria.fr</a>><br>
> >>>>>>> wrote:<br>
> >>>>>>><br>
> >>>>>>> ----- Mail original -----<br>
> >>>>>>>> De: "Barry F. Smith" <<a href="mailto:bsmith@mcs.anl.gov">bsmith@mcs.anl.gov</a>><br>
> >>>>>>>> À: "Franck Houssen" <<a href="mailto:franck.houssen@inria.fr">franck.houssen@inria.fr</a>><br>
> >>>>>>>> Cc: "For users of the development version of PETSc"<br>
> >>>>>>>> <<a href="mailto:petsc-dev@mcs.anl.gov">petsc-dev@mcs.anl.gov</a>><br>
> >>>>>>>> Envoyé: Jeudi 28 Décembre 2017 16:43:16<br>
> >>>>>>>> Objet: Re: [petsc-dev] How to pass user data to a registered PC<br>
> >>>>>>>> (PCRegister) ?<br>
> >>>>>>>><br>
> >>>>>>>><br>
> >>>>>>>> The register is for a new type of PC of which can have many<br>
> >>>>>>>> instantiations<br>
> >>>>>>>> at the same time.<br>
> >>>>>>><br>
> >>>>>>> OK, I didn't get that that way ! I was looking for a way to plug "my"<br>
> >>>>>>> pc<br>
> >>>>>>> at<br>
> >>>>>>> the command line this way: -pc_type my_pc.<br>
> >>>>>>> I already call PCSetType(pc, PCSHELL) and PCShellSetName(pc,<br>
> >>>>>>> "my_pc"):<br>
> >>>>>>> maybe this already enables "-pc_type shell" or "-pc_type my_pc"...<br>
> >>>>>>> And<br>
> >>>>>>> I<br>
> >>>>>>> didn't know it ! :D I'll try that.<br>
> >>>>>>><br>
> >>>>>>> I was looking for a way to integrate "my" (external) pc as any other<br>
> >>>>>>> regular/existing petsc pc (bjacobi, ...) like a kind of plugin but<br>
> >>>>>>> still<br>
> >>>>>>> integrated to the cmd line: I believed PCRegister was meant for that.<br>
> >>>>>><br>
> >>>>>>  Indeed it is exactly what it is meant for.  Please try to follow my<br>
> >>>>>>  recipe<br>
> >>>>>>  and let us know when you get stuck.<br>
> >>>>>><br>
> >>>>>><br>
> >>>>>>> Not sure if this is actually possible/enabled by the API.<br>
> >>>>>>><br>
> >>>>>>>> For example<br>
> >>>>>>>><br>
> >>>>>>>>  PCRegister("mypctype",mypc_<wbr>create);<br>
> >>>>>>>><br>
> >>>>>>>>  KSPCreate(&ksp1);<br>
> >>>>>>>>  KSPCreate(&ksp2);<br>
> >>>>>>>><br>
> >>>>>>>>  KSPGetPC(ksp1,&pc1);<br>
> >>>>>>>>  KSPGetPC(ksp2,&pc2);<br>
> >>>>>>>><br>
> >>>>>>>>  You don't want pc1 and pc2 to have the same dof multiplicities,<br>
> >>>>>>>>  domain<br>
> >>>>>>>>  intersections etc since they are associated with completely<br>
> >>>>>>>>  different<br>
> >>>>>>>>  linear systems and presumably meshes etc.<br>
> >>>>>>>><br>
> >>>>>>>><br>
> >>>>>>>>   Presumably you want each of pc1, pc2, to have their own version<br>
> >>>>>>>>   of<br>
> >>>>>>>>   the<br>
> >>>>>>>>   data so you need to stick it directly in the PC, for example<br>
> >>>>>>>><br>
> >>>>>>>> PCMypcSetDOFMultiplicities(<wbr>pc1,stuff);<br>
> >>>>>>>> PCMypcSetDOFMultiplicities(<wbr>pc2,otherstuff);<br>
> >>>>>>>><br>
> >>>>><br>
> >>>>> OK, I must provide/implement PCMypcSetDOFMultiplicities (add data to pc<br>
> >>>>> context) besides mypc_create: sounds logical.<br>
> >>>>> Is this OK if PCMypcSetDOFMultiplicities is independent from<br>
> >>>>> mypc_create<br>
> >>>>> ?<br>
> >>>>> I guess yes.<br>
> >>>>><br>
> >>>>> From what I remember/understand, I got lost here: from the jacobi<br>
> >>>>> example,<br>
> >>>>> mypc_create looks to be supposed (?) to call some kind of<br>
> >>>>> Petsc*ComposeFunction to associate PCMypcSetDOFMultiplicities to the pc<br>
> >>>>> (correct ?)... But, in the jacobi example, PCJacobiGetUseAbs_Jacobi is<br>
> >>>>> associated to PCJacobiGetUseAbs_C...<br>
> >>>><br>
> >>>>  the _C name is a string name that is used by PETSc to "find" the<br>
> >>>>  correct<br>
> >>>>  function pointer which is PCJacobiGetUseAbs_Jacobi. There is no<br>
> >>>> _C function.<br>
> >>><br>
> >>> ?!<br>
> >>><br>
> >>>><br>
> >>>>> Which turns out not to be implemented according to git grep ?! Got lost<br>
> >>>>> here (and looked for a way to pass user data directly to PCRegister):<br>
> >>>>> is<br>
> >>>>> PCMypcSetDOFMultiplicities supposed to be "attached/composed" or<br>
> >>>>> independent from the pc ?<br>
> >>>><br>
> >>>>   composed.<br>
> >>>><br>
> >>>>><br>
> >>>>>>> git grep PCJacobiGetUseAbs_C<br>
> >>>>> src/ksp/pc/impls/jacobi/<wbr>jacobi.c:  ierr =<br>
> >>>>> PetscObjectComposeFunction((<wbr>PetscObject)pc,"<wbr>PCJacobiGetUseAbs_C",<wbr>PCJacobiGetUseAbs_Jacobi);<wbr>CHKERRQ(ierr);<br>
> >>>>> src/ksp/pc/impls/jacobi/<wbr>jacobi.c:  ierr =<br>
> >>>>> PetscUseMethod(pc,"<wbr>PCJacobiGetUseAbs_C",(PC,<wbr>PetscBool*),(pc,flg));CHKERRQ(<wbr>ierr);<br>
> >>>>><br>
> >>>>> Sorry, for the short answer. Hope I succeeded to be clear enough.<br>
> >>>><br>
> >>>>   Just copy jacobi.c and start converting it over to your names and<br>
> >>>>   needs<br>
> >>>>   and you'll see it is actually really straightforward and not as<br>
> >>>>   complicated as you think it is.<br>
> >>>><br>
> >>>>   Barry<br>
> >>>><br>
> >>>>><br>
> >>>>>>>> You write as many of these Set() functions as you need for your<br>
> >>>>>>>> PCtype.<br>
> >>>>>>>> You<br>
> >>>>>>>> store the data inside the PC_Mypc data structure you create with<br>
> >>>>>>>> mypc_create(). Look at PCCreate_Jacobi() and PCJacobiSetType for the<br>
> >>>>>>>> pattern.<br>
> >>>>>>>><br>
> >>>>>>>> Barry<br>
> >>>>>>>><br>
> >>>>>>>><br>
> >>>>>>>>> On Dec 28, 2017, at 9:34 AM, Franck Houssen<br>
> >>>>>>>>> <<a href="mailto:franck.houssen@inria.fr">franck.houssen@inria.fr</a>><br>
> >>>>>>>>> wrote:<br>
> >>>>>>>>><br>
> >>>>>>>>> How to pass user data to a registered PC (PCRegister) ?<br>
> >>>>>>>>><br>
> >>>>>>>>> At first, I expected the signature would be "PetscErrorCode<br>
> >>>>>>>>> PCRegister(const char sname[],PetscErrorCode (*function)(PC, void<br>
> >>>>>>>>> *))"<br>
> >>>>>>>>> but<br>
> >>>>>>>>> it turns out to be "PetscErrorCode PCRegister(const char<br>
> >>>>>>>>> sname[],PetscErrorCode (*function)(PC))"<br>
> >>>>>>>>><br>
> >>>>>>>>> I try to integrate a PC that needs A but also other informations<br>
> >>>>>>>>> (dof<br>
> >>>>>>>>> multiplicities, domain intersections that the user must provide). I<br>
> >>>>>>>>> guess<br>
> >>>>>>>>> I can get A with PCGetOperators in the setup callback of the PC.<br>
> >>>>>>>>> But<br>
> >>>>>>>>> still<br>
> >>>>>>>>> not sure how to pass the other informations if I get to use<br>
> >>>>>>>>> PCRegister.<br>
> >>>>>>>>> I<br>
> >>>>>>>>> looked a few examples in the bitbucket (jacobi:<br>
> >>>>>>>>> src/ksp/ksp/examples/<wbr>tutorials/ex12.c and<br>
> >>>>>>>>> src/ksp/pc/impls/jacobi/<wbr>jacobi.c<br>
> >>>>>>>>> + SOR: src/ksp/pc/impls/sor/sor.c)... But didn't get any real<br>
> >>>>>>>>> relevant<br>
> >>>>>>>>> answer and feel a bit lost among the numerous pc !...<br>
> >>>>>>>>><br>
> >>>>>>>>> The idea is: for now I use PCSetType(pc, PCSHELL) and<br>
> >>>>>>>>> PCShellSetContext<br>
> >>>>>>>>> with a context who knows the extra needed informations which is<br>
> >>>>>>>>> "not<br>
> >>>>>>>>> so<br>
> >>>>>>>>> handy" (that's OK as for now I am both the user and the PC<br>
> >>>>>>>>> provider).<br>
> >>>>>>>>> I'd<br>
> >>>>>>>>> like to package this in a more convenient way (a unique and<br>
> >>>>>>>>> "simple"<br>
> >>>>>>>>> call<br>
> >>>>>>>>> to PCRegister) to decouple the user from the PC machinery.<br>
> >>>>>>>>><br>
> >>>>>>>>> Franck<br>
> >>>><br>
> >>>><br>
> >>><br>
> >><br>
><br>
><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div>What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead.<br>-- Norbert Wiener</div><div><br></div><div><a href="http://www.caam.rice.edu/~mk51/" target="_blank">https://www.cse.buffalo.edu/~knepley/</a><br></div></div></div></div></div>
</div></div>