<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Dec 31, 2017 at 9:01 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:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">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 instead.<br>
 - call PCRegister.<br>
<br>
Correct ? Did I miss something ?<br></blockquote><div><br></div><div>Yes, I think that is right.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Seems I get things to work (without compose function).<br></blockquote><div><br></div><div>The purpose of Compose() is to avoid the dreaded downcast of C++ (this is explained in <a href="https://arxiv.org/abs/1209.1711">https://arxiv.org/abs/1209.1711</a>). Suppose you</div><div>have some PC and want to call</div><div><br></div><div>  PCJacobiSetRowMax()</div><div><br></div><div>In C++, you would first downcast your PC to PCJacobi, then check for NULL, and finally call the function. This is ugly. In PETSc, you</div><div>can take any PC, for example PCSOR, and call</div><div><br></div><div>  PCJacobiSetRowMax(sor, ...);</div><div><br></div><div>and it will just silently do nothing rather than failing. This makes user code much easier to write since you can write for all different PC</div><div>types without all the ugly checks.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
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 ?<br></blockquote><div><br></div><div>Here is the control flow. You call PCSetFromOptions() on the pc, then it looks up that function in pc->ops so make sure you set your</div><div>specific one there. That impl SetFromOptions gets called and customizes your object. What is not working?</div><div><br></div><div>   Matt</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
----- 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" <<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 (PCRegister) ?<br>
><br>
> Don't get the link. I'll try first with independent function (no compose) 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" <<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 <<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, "my_pc"):<br>
> > >>> maybe this already enables "-pc_type shell" or "-pc_type my_pc"... 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 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 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 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): 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 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 <<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 (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. 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 "not<br>
> > >>>>> so<br>
> > >>>>> handy" (that's OK as for now I am both the user and the PC provider).<br>
> > >>>>> I'd<br>
> > >>>>> like to package this in a more convenient way (a unique and "simple"<br>
> > >>>>> call<br>
> > >>>>> to PCRegister) to decouple the user from the PC machinery.<br>
> > >>>>><br>
> > >>>>> Franck<br>
> ><br>
> ><br>
><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="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>