<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Mar 1, 2016 at 10:36 AM, Jed Brown <span dir="ltr"><<a href="mailto:jed@jedbrown.org" target="_blank">jed@jedbrown.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Matthew Knepley <<a href="mailto:knepley@gmail.com">knepley@gmail.com</a>> writes:<br>
<br>
> On Tue, Mar 1, 2016 at 10:19 AM, Jed Brown <<a href="mailto:jed@jedbrown.org">jed@jedbrown.org</a>> wrote:<br>
><br>
>> Matthew Knepley <<a href="mailto:knepley@gmail.com">knepley@gmail.com</a>> writes:<br>
>> > I was confusing the VecGhostUpdate() above which puts local values in the<br>
>> > global vector<br>
>> > with the update which would refresh the local portion. The former update<br>
>> > should be called<br>
>> > automatically during assembly, which already happens in the<br>
>> > FormFunctionLocals,<br>
>><br>
>> Uh, no, and they don't use VecGhost...<br>
><br>
><br>
> Yes, it most certainly does happen when FormFunctionLocal is<br>
> used. PETSc calls Assembly, at least in the Plex variant. Of course,<br>
> they do not use VecGhost.<br>
<br>
SNESComputeFunction_DMDA:<br>
<br>
  switch (dmdasnes->residuallocalimode) {<br>
  case INSERT_VALUES: {<br>
    ierr = DMDAVecGetArray(dm,F,&f);CHKERRQ(ierr);<br>
    ierr = PetscLogEventBegin(SNES_FunctionEval,snes,X,F,0);CHKERRQ(ierr);<br>
    CHKMEMQ;<br>
    ierr = (*dmdasnes->residuallocal)(&info,x,f,dmdasnes->residuallocalctx);CHKERRQ(ierr);<br>
    CHKMEMQ;<br>
    ierr = PetscLogEventEnd(SNES_FunctionEval,snes,X,F,0);CHKERRQ(ierr);<br>
    ierr = DMDAVecRestoreArray(dm,F,&f);CHKERRQ(ierr);<br>
  } break;<br>
  case ADD_VALUES: {<br>
    Vec Floc;<br>
    ierr = DMGetLocalVector(dm,&Floc);CHKERRQ(ierr);<br>
    ierr = VecZeroEntries(Floc);CHKERRQ(ierr);<br>
    ierr = DMDAVecGetArray(dm,Floc,&f);CHKERRQ(ierr);<br>
    ierr = PetscLogEventBegin(SNES_FunctionEval,snes,X,F,0);CHKERRQ(ierr);<br>
    CHKMEMQ;<br>
    ierr = (*dmdasnes->residuallocal)(&info,x,f,dmdasnes->residuallocalctx);CHKERRQ(ierr);<br>
    CHKMEMQ;<br>
    ierr = PetscLogEventEnd(SNES_FunctionEval,snes,X,F,0);CHKERRQ(ierr);<br>
    ierr = DMDAVecRestoreArray(dm,Floc,&f);CHKERRQ(ierr);<br>
    ierr = VecZeroEntries(F);CHKERRQ(ierr);<br>
    ierr = DMLocalToGlobalBegin(dm,Floc,ADD_VALUES,F);CHKERRQ(ierr);<br>
    ierr = DMLocalToGlobalEnd(dm,Floc,ADD_VALUES,F);CHKERRQ(ierr);<br>
    ierr = DMRestoreLocalVector(dm,&Floc);CHKERRQ(ierr);<br>
  } break;<br>
<br>
See how this uses DMLocalToGlobal and there is no VecAssembly.<br></blockquote><div><br></div><div>Yes, no Assembly. We only call it for matrices. The asymmetry is a little strange.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
src/snes/utils/dmplexsnes.c is far more confusing, but still contains no<br>
VecAssembly.<br>
</blockquote></div><br>It does not seem confusing to me.</div><div class="gmail_extra"><br></div><div class="gmail_extra">   Matt<br clear="all"><div><br></div>-- <br><div class="gmail_signature">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></div>