<div class="gmail_quote">On Mon, Jun 6, 2011 at 21:21, Barry Smith <span dir="ltr"><<a href="mailto:bsmith@mcs.anl.gov">bsmith@mcs.anl.gov</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div id=":oh"> Yes, that is the whole point (in the same way I want DM's propagated down inside mulgrid and fieldsplit created subksps and pcs) So for example it can be set in the main program into the SNES (or TS) and is accessible deep inside some nested preconditioner that is a problem specific PC beasty thing.<br>
</div></blockquote><div><br></div><div>So with PCFieldSplit, a DMComposite should be taken apart and have just the pieces forwarded on. The global DMComposite wouldn't be much use for a nested PC.</div><div><br></div>
<div>The same occurs with the application context. I imagine that each branch of the PCFieldSplit is almost an independent code that implements the right interface. It should not need to take apart the global app context to find itself. So here's some top-level code. The vht object is the top level app context.</div>
<div><br></div><div><div>      PCFieldSplitSetIS(pc,"s",vht->all.sblock);</div><div>      PCFieldSplitSetIS(pc,"e",vht->all.eblock);</div><div>      PCFieldSplitGetSubKSP(pc,&nsub,&subksp);</div>
<div>      stk_ksp = subksp[0];</div><div>      KSPGetPC(stk_ksp,&stk_pc);</div><div>      PCSetType(stk_pc,PCFIELDSPLIT);</div><div>      PCFieldSplitSetIS(stk_pc,"u",vht->stokes->ublock);</div><div>      PCFieldSplitSetIS(stk_pc,"p",vht->stokes->pblock);</div>
<div>      KSPSetApplicationContext(stk_ksp,vht);</div></div><div><br></div><div>It would be better to replace the last five lines with</div><div><br></div><div>      StokesKSPConfigure(vht->stokes,stk_ksp);</div><div>
<br></div><div>Which would end up using KSPSetApplicationContext() to set the stokes context on the nested ksp. Note that the Stokes context no longer needs to find itself within a larger scope, and it no longer even has access to that higher level.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div id=":oh"><div class="im">
> What happens when a component is accessed from multiple places?<br>
<br>
</div>   Not sure what you mean by multiple places.<br></div></blockquote><div><br></div><div>For example, a PC containing expensive setup (e.g. direct solve) might be used as part of a stand-alone linear solve and as part of a fieldsplit preconditioner for some larger nonlinear problem. If the user had an application context on that thing, it probably shouldn't be overwritten by SNESSetApplicationContext().</div>
<div><br></div><div>The argument here is just that an inner object might not have a unique parent. In such cases, it would seem easier to manage if the first parent (or a direct call by the user) took precedence instead of the last parent.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div id=":oh"><div class="im">
><br>
> I wonder if this forwarding should be made to not overwrite what is already there. That is, if the user sets it explicitly, then it will not be overwritten by a parent.<br>
<br>
</div>   Hmm, yes this gets tricky. I general I think it should overwrite and the user needs to set it differently if they want after they set it on the outside.  So they do TSSetApplicationContext() and then TSGetSNES, SNESGetKSP, KSPGetPC etc etc to change it down there.<br>
</div></blockquote><div><br></div><div>This is fine, but adds a little order dependence at configuration time. It does not seem too onerous if the user does something like StokesKSPConfigure() above.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div id=":oh"><div class="im">
> How should MatShellSetOperation behave? Should it error or do nothing when the matrix type is not MATSHELL?<br>
<br>
</div>   Error<br>
<div class="im"><br></div></div></blockquote><div><br></div><div>Okay, this is not the current behavior and this pre-historic snippet indicates the current behavior is intentional.</div><div><div><br></div><div>  if (op == MATOP_DESTROY) {</div>
<div>    ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr);</div><div>    if (flg) {</div></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div id=":oh"><div class="im">
> If the current behavior is to be preserved, what is your recommended way to get a context into the function overloading a method on a non-MATSHELL Mat?<br>
<br>
</div>    PetscObjectCompose()<br></div></blockquote><div><br></div><div>This means that the user's context has to be a PetscObject. I'm always torn whether to make my application context a PetscObject. I usually end up doing so, but it seems to me that it should only be necessary for extraordinay things. Maybe this qualifies.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div id=":oh">
<br>
    If there is one particular pattern of a non-MATSHELL matrix needing a user provided function overloading on a regular basis we need to examine that pattern and see what is most appropriate.</div></blockquote></div><br>
<div>I use it to provide matrix-free implementations of the global operation with MatNest. Thus I'm not using MatMult_Nest(), but I am taking advantage of MatGetSubMatrix_Nest() and similar. The reason for the global operation is that it makes one traversal of the mesh instead of one traversal per "block". I don't want to depend on an assembled format because assembling the true Jacobian is very expensive and the assembled matrix is slow to work with.</div>