<div dir="ltr">Sorry about the delay on this - I'm still trying to decide on what's an elegant solution. I'll attempt to describe the issue and potential solutions, in case anyone has interest/ideas:<div><br></div><div><b>My understanding of the way things work now</b></div><div>- DMLocalToGlobal() sends data from "local" vectors to "global" vectors. </div><div>- This "l2g" map is in general surjective (onto) but not injective (into) because local subdomains can overlap.</div><div>- When DMLocalToGlobal() is called with INSERT_VALUES, there needs to be some mechanism to resolve this non-injectivity.</div><div>- The mechanism is to ignore the parts of the l2g map that aren't rank-local. </div><div>- This usually works very well because "local" vectors can usually be constructed to consist of degrees of freedom consisting of rank-local dof in the global representation (I like to call these "native"), plus additional dof corresponding to other dof, which are either on other ranks or not part of the global representation at all (ghosted boundaries).</div><div>- This breaks down for a DMDA with a single rank in a given coordinate direction, and periodic boundary conditions. You'll get an error trying due to the non-injectivity of the map, even after excluding off-rank communication (since the ghost region maps to native dof, which never happens otherwise)</div><div>- However, this isn't an issue in practice, because with DMDA you can just operate directly on a global vector. Local-to-global inserts aren't very useful in general.</div><div><br></div><div><b>Issue related to DMStag</b></div><div>- With DMStag, the same issue occurs as with DMDA (and this is the topic of this thread).</div><div>- However, operating directly on a global vector isn't currently convenient with DMStag, because global vectors aren't regularly blocked, while local vectors are. </div><div>- This is perhaps a design flaw to be addressed with DMStag, because the local representation is being used for two orthogonal purposes: padding out to obtain regular blocking, and padding out to include ghost regions.</div><div><br></div><div><b>Potential solutions</b></div><div>I can think of a few avenues to pursue, including</div><div>1. Whenever this could potentially arise, pad all local vectors with the necessary 0's and use ADD_VALUES [gross]</div><div>2. Add a dedicated "padded global" representation for DMStag, and tools for working with it. [elegant in that it resolves the design flaw above, but adds quite a lot of code]</div><div><br></div><div>but here's the idea  that I'm also intrigued by:</div><div>- It's an abuse of notation to use INSERT_VALUES for DMLocalToGlobal() in the first place</div><div>- Rather, it'd be more meaningful to use a new InsertMode value, INSERT_VALUES_LOCAL, deprecating the use of INSERT_VALUES for DMLocalToGlobal()*</div><div>- This name corresponds to SCATTER_REVERSE_LOCAL which gets called in e.g. DMLocalToGlobalBegin_DA(), or the equivalent logic in DMLocalToGlobalBegin() using PetscSection</div><div>- In most cases, this works just as before, but now the error message is more accurate - you can't use INSERT_VALUES_LOCAL when the l2g map isn't injective, even when ignoring parallel communication</div><div>- Add another new InsertMode value, INSERT_VALUES_INJECTIVE, which asks the DM implementation to resolve the non-injectivity of the l2g map</div><div>- In most cases, this would behave just like INSERT_VALUES_LOCAL and most users wouldn't know or care</div><div>- However, for the case of interest here, the implementation would be free to use its implementation-dependent data to "do the right thing"</div><div>- For DMStag, the right thing would be to behave consistently with the case with 2 or more ranks in the periodic direction (ignoring dof on ghost elements).</div><div>- This could be done by setting up another VecScatter during DMSetUp_Stag(), and using it with INSERT_VALUES_INJECTIVE</div><div><br></div><div>* eventually this could become an error if the l2g map was non-injective, but probably not for a long time if ever</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Am Do., 13. Juni 2019 um 15:09 Uhr schrieb Patrick Sanan <<a href="mailto:patrick.sanan@gmail.com" target="_blank">patrick.sanan@gmail.com</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr">I will attempt to just fix the underlying issue here, that is allow DMStagSetUniformCoordinates() to work for period boundary conditions with a single rank in the corresponding dimension.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Am Mi., 12. Juni 2019 um 19:10 Uhr schrieb Patrick Sanan <<a href="mailto:patrick.sanan@gmail.com" target="_blank">patrick.sanan@gmail.com</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr">Ah, okay, so unless something weird is going on, that probably should never have passed (if it's asking for periodic BCs with one rank in a given direction, and INSERT_VALUES, so it's not well-defined which of the multiple local dof mapping to a given global dof should be used). I'll try to reproduce and fix it and/or talk to Chris.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Am Mi., 12. Juni 2019 um 18:27 Uhr schrieb Balay, Satish via petsc-dev <<a href="mailto:petsc-dev@mcs.anl.gov" target="_blank">petsc-dev@mcs.anl.gov</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">On Wed, 12 Jun 2019, Lisandro Dalcin via petsc-dev wrote:<br>
<br>
> $ python test/runtests.py -v -i dmstag TestDMStag_2D_PXY<br>
> [0@kl-18232] Python 2.7 (/usr/local/opt/python@2/bin/python2.7)<br>
> [0@kl-18232] PETSc 3.11.2 development (conf: 'arch-darwin-c-debug')<br>
> [0@kl-18232] petsc4py 3.11.0 (build/lib.macosx-10.14-x86_64-2.7/petsc4py)<br>
> testCoordinates (test_dmstag.TestDMStag_2D_PXY) ... ERROR<br>
> testDMDAInterface (test_dmstag.TestDMStag_2D_PXY) ... ERROR<br>
> testDof (test_dmstag.TestDMStag_2D_PXY) ... ok<br>
> testGetOther (test_dmstag.TestDMStag_2D_PXY) ... ok<br>
> testGetVec (test_dmstag.TestDMStag_2D_PXY) ... ERROR<br>
> testMigrateVec (test_dmstag.TestDMStag_2D_PXY) ... ERROR<br>
<br>
I get:<br>
<br>
======================================================================<br>
ERROR: testCoordinates (test_dmstag.TestDMStag_2D_PXY)<br>
----------------------------------------------------------------------<br>
Traceback (most recent call last):<br>
  File "test/test_dmstag.py", line 39, in testCoordinates<br>
    self.da.setUniformCoordinates(0,1,0,1,0,1)<br>
  File "PETSc/DMStag.pyx", line 255, in petsc4py.PETSc.DMStag.setUniformCoordinates<br>
Error: error code 56<br>
[0] DMStagSetUniformCoordinates() line 1077 in /home/balay/petsc.z/src/dm/impls/stag/stagutils.c<br>
[0] DMStagSetUniformCoordinatesExplicit() line 1118 in /home/balay/petsc.z/src/dm/impls/stag/stagutils.c<br>
[0] DMStagSetUniformCoordinatesExplicit_2d() line 135 in /home/balay/petsc.z/src/dm/impls/stag/stag2d.c<br>
[0] DMLocalToGlobalBegin() line 2614 in /home/balay/petsc.z/src/dm/interface/dm.c<br>
[0] DMLocalToGlobalBegin_Stag() line 230 in /home/balay/petsc.z/src/dm/impls/stag/stag.c<br>
[0] No support for this operation for this object type<br>
[0] Local to Global scattering with INSERT_VALUES is not supported for single rank in a direction with boundary conditions (e.g. periodic) inducing a non-injective local->global map. Either change the boundary conditions, use a stencil width of zero, or use more than one rank in the relevant direction (e.g. -stag_ranks_x 2)<br>
<br>
Satish<br>
<br>
</blockquote></div>
</blockquote></div>
</blockquote></div>