<div dir="ltr"><div>Good morning,</div><div><br></div><div>Sorry for picking this back up such a long time after the initial response, but I am now in a good place to implement this change after thoroughly testing the preconditioner shell alone.</div><div><br></div><div>I have been looking for resources but it is still not clear to me how to use the MATSHELL for this purpose. Do I have to create my own MATSHELL that is basically just the solution and the shift itself, or at least operations that do this? Or is the matshell simply a dummy object that will allow me to interface the solution and ashift?</div><div><br></div><div>In either of this cases I am still not sure how to begin this process, are there any helpful examples that I could model  the MATSHELL from? KSP example ex15.c was incredibly helpful for the creation of my PCSHELL so it would be very helpful if there is something similar for the MATSHELL, and passing the ashift.</div><div><br></div><div>Thank you,</div><div><br></div><div>-Alfredo<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Sep 30, 2021 at 5:09 PM Barry Smith <<a href="mailto:bsmith@petsc.dev">bsmith@petsc.dev</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;"><div><br></div><div>  Alfredo,</div><div><br></div>  I think the best approach for you to use is to have your own MATSHELL and your own PCSHELL. You will use your MATSHELL as the second matrix argument to TSSetIJacobian(). It should record the current x and the current shift. <div><br></div><div>  Your PCSHELL will then, in PCSetUp(), get access to the current x and the current shift from your MATSHELL and build itself. In other words most of your</div><div><br></div><div><blockquote type="cite"><div dir="ltr"><div>/ Get necessary objects from TS context<br>  TSGetTime(ts,&time);<br>  TSGetApplicationContext(ts,&user);<br>  TSGetSolution(ts,&X);<br>  TSGetTimeStep(ts,&dt);<br>  TSGetStepNumber(ts, &stepi);<br>  TSGetDM(ts,&da);<br><br>  tdt = time+dt;<br>  // Update preconditioner context with current values<br>  ierr = ShellPCSetUp(pc,da,tdt,dt,X,user);CHKERRQ(ierr);</div></div></blockquote> </div><div> code will disappear and you won't need to mess with the internals of the TS (getting current dt etc) at all. What you need is handed off to your TSSetIJacobian() function which will stick it into your MATSHELL. So nice and clean code.</div><div><br></div><div>  Regarding the PCDestroy() for your PCSHELL. It only gets called when the PC is finally destroyed which is when the TS is destroy. So if building your PC in PCSetUp() requires creating new objects you should destroy any previous ones when you create the new ones, hence "lost" objects won't persist in the code.</div><div><br></div><div>  Barry</div><div><br></div><div><br></div><div><br></div><div><br><div><br><blockquote type="cite"><div>On Sep 30, 2021, at 4:14 PM, Alfredo J Duarte Gomez <<a href="mailto:aduarteg@utexas.edu" target="_blank">aduarteg@utexas.edu</a>> wrote:</div><br><div><div dir="ltr">Good afternoon PETSC team,<div><br></div><div>I am currently developing an application for PETSC in which I use my own preconditioner with a PCSHELL.</div><div><br></div><div>I have successfully set all the functions and the performance of the preconditioner is good. I am using this PCSHELL within a TS object, and it is imperative that the objects in the PCSHELL context are freed every time since the memory requirements of those are large.</div><div><br></div><div>I have set up the Preconditioner before the TS starts with the following block of code:</div><div>----------------------------------------------------------------------------------------------------</div><div><br></div><div>ierr = PCSetType(pc,PCSHELL);CHKERRQ(ierr);<br>  ierr = ShellPCCreate(&shell);CHKERRQ(ierr);<br>  ierr = PCShellSetApply(pc,MatrixFreePreconditioner);CHKERRQ(ierr);<br>  ierr = PCShellSetContext(pc,shell);CHKERRQ(ierr);<br>  ierr = PCShellSetDestroy(pc,ShellPCDestroy);CHKERRQ(ierr);<br>  ierr = PCShellSetName(pc,"MyPreconditioner");CHKERRQ(ierr);<br>  ierr = ShellPCSetUp(pc,da,0.0,dt,u,user);CHKERRQ(ierr);<br>  ierr = TSSetPreStep(ts,PreStep);CHKERRQ(ierr);<br></div><div><br></div><div>------------------------------------------------------------------------------------------------</div><div><br></div><div>The shell context is then updated by using the following code within the TSPreStep function:</div><div><br></div><div>---------------------------------------------------------------------------</div><div><br></div><div> ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);<br>  ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);<br>  ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);<br><br>  // Get necessary objects from TS context<br>  TSGetTime(ts,&time);<br>  TSGetApplicationContext(ts,&user);<br>  TSGetSolution(ts,&X);<br>  TSGetTimeStep(ts,&dt);<br>  TSGetStepNumber(ts, &stepi);<br>  TSGetDM(ts,&da);<br><br>  tdt = time+dt;<br>  // Update preconditioner context with current values<br>  ierr = ShellPCSetUp(pc,da,tdt,dt,X,user);CHKERRQ(ierr);<br></div><div>---------------------------------------------------------------------------</div><div><div><br></div><div>I have set up the necessary code in the function ShellPCDestroy to free the objects within this context, however I am unsure when/if this function is called automatically. Do I have to free the context myself after every step? How would I call the function myself?</div><div><br></div><div>I am running out of memory after a few steps, and I think this shell context is the culprit.</div><div><br></div><div>In addition to that, is it possible to get what is called the "ashift" <span style="font-family:"Times New Roman";font-size:inherit">dF/dU + a*dF/dU_t in this function from the TS object?</span></div><div><br></div><div><a href="https://petsc.org/release/docs/manualpages/TS/TSSetIJacobian.html" target="_blank">https://petsc.org/release/docs/manualpages/TS/TSSetIJacobian.html</a><br></div><div><br></div><div>I need it as an input for my preconditioner (currrently hardcoded for TSBEULER where ashift is always 1/dt).</div><div><br></div><div>Thank you,</div><div><br></div><div>-Alfredo</div><div><br></div>-- <br><div dir="ltr"><div dir="ltr"><div><div dir="ltr"><font face="arial, sans-serif">Alfredo Duarte</font><div><font face="arial, sans-serif">Graduate Research Assistant</font></div><div><font face="arial, sans-serif">The University of Texas at Austin</font></div></div></div></div></div></div></div>
</div></blockquote></div><br></div></div></blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><font face="arial, sans-serif">Alfredo Duarte</font><div><font face="arial, sans-serif">Graduate Research Assistant</font></div><div><font face="arial, sans-serif">The University of Texas at Austin</font></div></div></div></div></div>