<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Apr 18, 2017 at 2:33 PM, Ingo Gaertner <span dir="ltr"><<a href="mailto:ingogaertner.tus@gmail.com" target="_blank">ingogaertner.tus@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div>The part that does not make sense is:<br>The code calculates that<br>face 11 (or edge 11 if you call the boundary of a 2D cell an edge) has the centroid c=(0.750000 1.000000 0.000000) and the normal n=(0.000000 0.500000 0.000000) and that<br>face 12 (or edge 12) has the centroid c=(0.000000 0.500000 0.000000) and the normal n=(-1.000000 -0.000000 0.000000).<br><span class="m_1492622701141221377gmail-"><span class="m_1492622701141221377gmail-m_-6171374370410339176gmail-m_8179380476569161657gmail-m_2360740100696784902gmail-">I understood your previous answer ("The normal should be outward, unless the face has orientation < 0") such that I have to reverse these normals to get an outward normal, because faces 11 and 12 have orientation=-2. But the normals </span></span>n=(0.000000 0.500000 0.000000) and  n=(-1.000000 -0.000000 0.000000) do already point outward. If I reverse them, they point inward.<br><br></div>I need a CONSISTENT rule how to make use of the normals obtained from DMPlexComputeGeometryFVM(dm, &cellgeom,&facegeom) to calculate OUTWARD pointing normals with respect to EACH INDIVIDUAL cell.<br></div>Or do I have to iterate over each face of each cell and use a geometric check to see if the calculated normals are pointing inward or outward?<br></div></div></div></blockquote><div><br></div><div>I apologize. I did not understand the question before. The convention I have chosen might not be the best one,</div><div>but it seems appropriate for FVM.</div><div><br></div><div>The orientation of a face normal is chosen such that </div><div><br></div><div>  n . r > 0</div><div><br></div><div>where r is the vector from the centroid of the left face to</div><div>the centroid of the right face. If we do GetSupport() for</div><div>a face we get back {l, r}, where r could be empty, meaning</div><div>the cell at infinity.</div><div><br></div><div>This convention means that I never have to check orientations</div><div>when I am using the facegeom[] stuff in FVM, I just need to have</div><div>{l, r} which I generally have in the loop.</div><div><br></div><div>  Thanks,</div><div><br></div><div>     Matt</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div></div>Thanks<span class="HOEnZb"><font color="#888888"><br></font></span></div><span class="HOEnZb"><font color="#888888">Ingo</font></span><div><div class="h5"><br><div><div><div><div><br><div><div class="gmail_extra"><br><div class="gmail_quote">2017-04-18 20:20 GMT+02:00 Matthew Knepley <span dir="ltr"><<a href="mailto:knepley@gmail.com" target="_blank">knepley@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="m_1492622701141221377gmail-">On Tue, Apr 18, 2017 at 12:46 AM, Ingo Gaertner <span dir="ltr"><<a href="mailto:ingogaertner.tus@gmail.com" target="_blank">ingogaertner.tus@gmail.com</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"><div dir="ltr"><span class="m_1492622701141221377gmail-m_-6171374370410339176gmail-m_8179380476569161657gmail-m_2360740100696784902gmail-"><div>Dear Matt,<br></div><div>please explain your previous answer ("The normal should be outward, unless the face has orientation < 0") with respect to my example.<br></div><div>As I think, the example shows that the face normals for faces 11 and 12 are pointing outward, although they have orientation=-2. For all other faces the normal direction and their orientation sign agree with what you said.<br></div></span></div></blockquote><div><br></div></span><div>1) You should destroy the objects at the end</div><div><br></div><div><div>  ierr = VecDestroy(&cellgeom);CHKERRQ(<wbr>ierr);</div><div>  ierr = VecDestroy(&facegeom);CHKERRQ(<wbr>ierr);</div><div>  ierr = DMDestroy(&dm);CHKERRQ(ierr);</div></div><div><br></div><div>2) You should call</div><div><br></div><div><div>  ierr = DMSetFromOptions(dm);CHKERRQ(i<wbr>err);</div><div>  ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr);</div></div><div><br></div><div>after DM creation to make it easier to customize and debug. Then we can use</div><div><br></div><div>  -dm_view ::ascii_info_detail</div><div><br></div><div>to look at the DM.</div><div><br></div><div>3) Lets look at Cell 0</div><div><br></div><div><div>[0]: 0 <---- 8 (0)</div><div>[0]: 0 <---- 13 (0)</div><div>[0]: 0 <---- 10 (-2)</div><div>[0]: 0 <---- 12 (-2)</div></div><div><br></div><div>There are two edges reversed. The edges themselves {8, 13, 10, 12}</div><div>should proceed counter-clockwise from the bottom, and have vertices</div><div><br></div><div><div>[0]: 8 <---- 2 (0)</div><div>[0]: 8 <---- 3 (0)</div><div>[0]: 13 <---- 3 (0)</div><div>[0]: 13 <---- 6 (0)</div><div>[0]: 10 <---- 5 (0)</div><div>[0]: 10 <---- 6 (0)</div><div>[0]: 12 <---- 2 (0)</div><div>[0]: 12 <---- 5 (0)</div></div><div><br></div><div>so we get as we expect</div><div><br></div><div>  2 --> 3 --> 6 --> 5</div><div><br></div><div>which agrees with the coordinates</div><div><br></div><div><div>  (   2) dim  2 offset   0 0. 0.</div><div>  (   3) dim  2 offset   2 0.5 0.</div><div>  (   4) dim  2 offset   4 1. 0.</div><div>  (   5) dim  2 offset   6 0. 1.</div><div>  (   6) dim  2 offset   8 0.5 1.</div><div>  (   7) dim  2 offset  10 1. 1.</div></div><div><br></div><div>Which part does not make sense?</div><div><br></div><div>  Thanks,</div><div><br></div><div>     Matt</div><div><div class="m_1492622701141221377gmail-h5"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><span class="m_1492622701141221377gmail-m_-6171374370410339176gmail-m_8179380476569161657gmail-m_2360740100696784902gmail-"><div></div><div>Thanks<span class="m_1492622701141221377gmail-m_-6171374370410339176gmail-HOEnZb"><font color="#888888"><br></font></span></div><span class="m_1492622701141221377gmail-m_-6171374370410339176gmail-HOEnZb"><font color="#888888"><div>Ingo<br></div></font></span></span><div><div class="m_1492622701141221377gmail-m_-6171374370410339176gmail-h5"><div class="gmail_extra"><br><div class="gmail_quote">2017-04-14 11:28 GMT+02:00 Ingo Gaertner <span dir="ltr"><<a href="mailto:ingogaertner.tus@gmail.com" target="_blank">ingogaertner.tus@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Thank you, Matt,<br>as you say, the face orientations do change sign when switching between the two adjacent cells. (I confused my program output. You are right.) But it seems not to be always correct to keep the normal direction for orientation>=0 and invert it for orientation<0:<br><br>I include sample code below to make my question more clear. The program creates a HexBoxMesh split horizontally in two cells (at x=0.5) It produces this output:<br><br>"Face centroids (c) and normals(n):<br>face #008 c=(0.250000 0.000000 0.000000) n=(-0.000000 -0.500000 0.000000)<br>face #009 c=(0.750000 0.000000 0.000000) n=(-0.000000 -0.500000 0.000000)<br>face #010 c=(0.250000 1.000000 0.000000) n=(0.000000 0.500000 0.000000)<br>face #011 c=(0.750000 1.000000 0.000000) n=(0.000000 0.500000 0.000000)<br>face #012 c=(0.000000 0.500000 0.000000) n=(-1.000000 -0.000000 0.000000)<br>face #013 c=(0.500000 0.500000 0.000000) n=(1.000000 0.000000 0.000000)<br>face #014 c=(1.000000 0.500000 0.000000) n=(1.000000 0.000000 0.000000)<br>Cell faces orientations:<br>cell #0, faces:[8 13 10 12] orientations:[0 0 -2 -2]<br>cell #1, faces:[9 14 11 13] orientations:[0 0 -2 -2]"<br><br>Looking at the face normals, all boundary normals point outside (good).<br>The normal of face #013 points outside with respect to the left cell #0, but inside w.r.t. the right cell #1.<br><br>Face 13 is shared between both cells. It has orientation 0 for cell #0, 
but orientation -2 for cell #1 (good).<br>What I don't understand is the orientation 
of face 12 (cell 0) and of face 11 (cell 1). These are negative, which 
would make them point into the cell. Have I done some other stupid mistake?<br><br>Thanks<br>Ingo<br><br>Here is the code:<br><br>static char help[] = "Check face normals orientations.\n\n";<br>#include <petscdmplex.h><br>#undef __FUNCT__<br>#define __FUNCT__ "main"<br><br>int main(int argc, char **argv)<br>{<br>  DM             dm;<br>  PetscErrorCode ierr;<br>  PetscFVCellGeom *cgeom;<br>  PetscFVFaceGeom *fgeom;<br>  Vec cellgeom,facegeom;<br>  int dim=2;<br>  int cells[]={2,1};<br>  int cStart,cEnd,fStart,fEnd;<br>  int coneSize,supportSize;<br>  const int *cone,*coneOrientation;<br><br>  ierr = PetscInitialize(&argc, &argv, NULL, help);CHKERRQ(ierr);<br>  ierr = PetscOptionsGetInt(NULL, NULL, "-dim", &dim, NULL);CHKERRQ(ierr);<br>  ierr = DMPlexCreateHexBoxMesh(PETSC_C<wbr>OMM_WORLD, dim, cells,DM_BOUNDARY_NONE,DM_BOUN<wbr>DARY_NONE,DM_BOUNDARY_NONE, &dm);CHKERRQ(ierr);<br><br>  ierr = DMPlexComputeGeometryFVM(dm, &cellgeom,&facegeom);CHKERRQ(i<wbr>err);<br>  ierr = VecGetArray(cellgeom, (PetscScalar**)&cgeom);CHKERRQ<wbr>(ierr);<br>  ierr = VecGetArray(facegeom, (PetscScalar**)&fgeom);CHKERRQ<wbr>(ierr);<br>  ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);<br>  ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);<br><br>  fprintf(stderr,"Face centroids (c) and normals(n):\n");<br>  for (int f=fStart;f<fEnd;f++){<br>    fprintf(stderr,"face #%03d c=(%03f %03f %03f) n=(%03f %03f %03f)\n",f,<br>      fgeom[f-fStart].centroid[0],fg<wbr>eom[f-fStart].centroid[1],fgeo<wbr>m[f-fStart].centroid[2],<br>      fgeom[f-fStart].normal[0],fgeo<wbr>m[f-fStart].normal[1],fgeom[f-<wbr>fStart].normal[2]);<br>  }<br><br>  fprintf(stderr,"Cell faces orientations:\n");<br>  for (int c=cStart;c<cEnd;c++){<br>      ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr);<br>      ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);<br>      ierr = DMPlexGetConeOrientation(dm, c, &coneOrientation);CHKERRQ(ierr<wbr>);<br>      if (dim==2){<br>        if (coneSize!=4){<br>          fprintf(stderr,"Expected coneSize 4, got %d.\n",coneSize);<br>          exit(1);<br>        }<br>        fprintf(stderr,"cell #%d, faces:[%d %d %d %d] orientations:[%d %d %d %d]\n",c,<br>          cone[0],cone[1],cone[2],cone[3<wbr>],<br>          coneOrientation[0],coneOrienta<wbr>tion[1],coneOrientation[2],con<wbr>eOrientation[3]<br>        );<br>      } else if (dim==3){<br>        if (coneSize!=6){<br>          fprintf(stderr,"Expected coneSize 6, got %d.\n",coneSize);<br>          exit(1);<br>        }<br>        fprintf(stderr,"cell #%d, faces:[%d %d %d %d %d %d] orientations:[%d %d %d %d %d %d]\n",c,<br>          cone[0],cone[1],cone[2],cone[3<wbr>],cone[4],cone[5],<br>          coneOrientation[0],coneOrienta<wbr>tion[1],coneOrientation[2],con<wbr>eOrientation[3],coneOrientatio<wbr>n[4],coneOrientation[5]<br>        );<br>      } else {<br>        fprintf(stderr,"Dimension %d not implemented.\n",dim);<br>        exit(1);<br>      }<br>  }<br>  ierr = PetscFinalize();<div><div class="m_1492622701141221377gmail-m_-6171374370410339176gmail-m_8179380476569161657h5"><br>}<br><br><div class="gmail_extra"><br><div class="gmail_quote">2017-04-14 11:00 GMT+02:00 Matthew Knepley <span dir="ltr"><<a href="mailto:knepley@gmail.com" target="_blank">knepley@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="m_1492622701141221377gmail-m_-6171374370410339176gmail-m_8179380476569161657m_2360740100696784902gmail-">On Wed, Apr 12, 2017 at 10:52 AM, Ingo Gaertner <span dir="ltr"><<a href="mailto:ingogaertner.tus@gmail.com" target="_blank">ingogaertner.tus@gmail.com</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"><div dir="ltr"><div><div><div><div><div><div><div>Hello,<br></div>I have problems determining the orientation of the face normals of a DMPlex.<br><br></div>I create a DMPlex, for example with DMPlexCreateHexBoxMesh().<br></div>Next, I get the face normals using DMPlexComputeGeometryFVM(DM dm, Vec *cellgeom, Vec *facegeom). facegeom gives the correct normals, but I don't know how the inside/outside is defined with respect to the adjacant cells?<br></div></div></div></div></div></blockquote><div><br></div></span><div>The normal should be outward, unless the face has orientation < 0.</div><span class="m_1492622701141221377gmail-m_-6171374370410339176gmail-m_8179380476569161657m_2360740100696784902gmail-"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div><div><div></div>Finally, I iterate over all cells. For each cell I iterate over the bounding faces (obtained from DMPlexGetCone) and try to obtain their orientation with respect to the current cell using DMPlexGetConeOrientation(). However, the six integers for the orientation are the same for each cell. I expect them to flip between neighbour cells, because if a face normal is pointing outside for any cell, the same normal is pointing inside for its neighbour. Apparently I have a misunderstanding here.<br></div></div></div></div></blockquote><div><br></div></span><div>I see the orientations changing sign for adjacent cells. Want to send a simple code? You should see this</div><div>for examples. You can run SNES ex12 with -dm_view ::ascii_info_detail to see the change in sign.</div><div><br></div><div>  Thanks,</div><div><br></div><div>     Matt</div><span class="m_1492622701141221377gmail-m_-6171374370410339176gmail-m_8179380476569161657m_2360740100696784902gmail-"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div><div></div>How can I make use of the face normals in facegeom and the orientation values from DMPlexGetConeOrientation() to get the outside face normals for each cell?<br><br></div>Thank you<br></div>Ingo<br></div><div id="m_1492622701141221377gmail-m_-6171374370410339176gmail-m_8179380476569161657m_2360740100696784902gmail-m_-1897645241821352774m_-6432344443275881332DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2"><br> <table style="border-top:1px solid rgb(211,212,222)">
        <tbody><tr>
      <td style="width:55px;padding-top:18px"><a href="https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail" target="_blank"><img src="https://ipmcdn.avast.com/images/icons/icon-envelope-tick-round-orange-animated-no-repeat-v1.gif" style="width:46px;height:29px" width="46" height="29"></a></td>
                <td style="width:470px;padding-top:17px;color:rgb(65,66,78);font-size:13px;font-family:arial,helvetica,sans-serif;line-height:18px">Virenfrei. <a href="https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail" style="color:rgb(68,83,234)" target="_blank">www.avast.com</a>               </td>
        </tr>
</tbody></table>
<a href="#m_1492622701141221377_m_-6171374370410339176_m_8179380476569161657_m_2360740100696784902_m_-1897645241821352774_m_-6432344443275881332_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2" width="1" height="1"></a></div>
</blockquote></span></div><span class="m_1492622701141221377gmail-m_-6171374370410339176gmail-m_8179380476569161657m_2360740100696784902gmail-HOEnZb"><font color="#888888"><br><br clear="all"><div><br></div>-- <br><div class="m_1492622701141221377gmail-m_-6171374370410339176gmail-m_8179380476569161657m_2360740100696784902gmail-m_-1897645241821352774gmail_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>
</font></span></div></div>
</blockquote></div><br></div></div></div></div>
</blockquote></div><br></div></div></div></div>
</blockquote></div></div></div><div><div class="m_1492622701141221377gmail-h5"><br><br clear="all"><div><br></div>-- <br><div class="m_1492622701141221377gmail-m_-6171374370410339176gmail_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></div></div>
</blockquote></div><br></div></div></div></div></div></div></div></div></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="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>