Hi matt,

Many thanks for the help !!

Le 3/26/2020 à 11:38 PM, Matthew Knepley a écrit :

         17              18
   7-----8-----9-----14----15
    |               |                |
16,3    4    5,6    11   12,13
    |               |                |
    1-----2-----3-----9-----10
           19            20

so each face gets 2 dofs, one for each cell.When doing a cell integral, you only use the dof that is for that cell.

I think i understood. I put the beginning of the code for dof management in attachment. i defined : numDof[0*(user.dim+1)+user.dim] = internalDof; /* internalDof defined on cells */ numDof[0*(user.dim+1)+user.dim-1] = nbDofFaceEle; /* nbDofFaceEle defined on faces */ This way, the dof faces are not duplicated. They are defined on the face. (this part is commented in the source file)

Am i right ?

> The local-to-global would update the face dofs, so you would get each side.
>
This way, a  local-to-global  will update the face dofs ?


There is a reordering when you extract the closure. I have written one for spectral elements. We would need
another here that ordered all the "other" face dofs to the end.

You mean using PetscSectionSetPermutation ?
Or rewrite DMPlexSetClosurePermutationTensor in order to put all the face dofs at the end ?

I don't understand this part. I'm looking at the documentation for DMPlexSetClosurePermutationTensor.
https://www.mcs.anl.gov/petsc/petsc-current/src/dm/impls/plex/plex.c.html#DMPlexSetClosurePermutationTensor
It says that
----------------------
The closure in BFS ordering works through height strata (cells, edges, vertices) to produce the ordering
.vb
 0 1 2 3 8 9 14 15 11 10 13 12 4 5 7 6
.ve
--------------------------

which is what we want no ?



This seems a little complicated to me. Do you know how Andreas Klockner does it in Hedge? Or Tim Warburton?
I'm reading his book  (nodal discontinuous galerkin methods)

I just want to make sure I am not missing an elegant way to handle this.

    Here field 1 is synchronised with field 0, locally.
    But the external Face dof, field 2, have to be synchronised with the
    values of the adjacent cell.
    Is it possible to use something like  DMPlexGetFaceFields ?
    Is there an example of such use of PetscSection and synchronisation
    process ?

    For the parallel part, should i use PetscSF object ?


In parallel, integrals would be summed into the global vector, so each side has a 0 for the other face dof and the right contribution for its face dof. Then both sides get both solution dofs. It seems to work in my head.

    I read your article "Mesh Algorithms for PDE with Sieve I: Mesh
    Distribution". But it's refereeing to Matthew G. Knepley and Dmitry A.
    Karpeev. Sieve implementation.
    Technical Report ANL/MCS to appear, Argonne National Laboratory,
    January 2008.
    I couldn't find it. It is freely available ?


Don't bother reading that. There are later ones:

  There are two pretty good sources:

https://arxiv.org/abs/1505.04633
https://arxiv.org/abs/1506.06194

The last one is a follow-on to this paper

https://arxiv.org/abs/0908.4427

   Thanks,

      Matt

     >
     > I don't think you need extra vertices, > or coordinates, and for
    output I
     > recommend using DMPlexProject() to get
     > the solution in some space that can be plotted like P1, or
    anything else
     > supported by your visualization.

    I would like to use DMplex as much as i can, as i would in the future
    refine locally the mesh.

    I hope you're good in this difficult situation (covid19),

    Best regards,

    Yann

     >
     >    Thanks,
     >
     >       Matt
     >
     >      >
     >      >        We have an implementation of spectral element ordering
     >      >
>  (https://gitlab.com/petsc/petsc/-/blob/master/src/dm/impls/plex/examples/tutorials/ex6.c).
     >
     >      > Those share
     >      >        the whole element boundary.
     >      >
     >      >    2) What ghosts do you need?
     >     In order to compute the numerical fluxes of one element, i
    need the
     >     values of the surrounding nodes connected to the adjacent
    elements.
     >      >
     >      >    3) You want to store real space coordinates for a
    quadrature?
     >     It should be basically the same as PetscFE of higher order.
     >     I add some vertex needed to compute a polynomal solution of
    the desired
     >     order. That means that if i have a N, order of the local
    approximation,
     >     i need 0.5*(N+1)*(N+2) vertex to store in the DMPlex (in 2D), in
     >     order to :
     >     1) have the correct number of dof
     >     2) use ghost nodes to sync the values of the
    vertex/edge/facet for
     >     1D/2D/3D problem
     >     2) save correctly the solution
     >
     >     Does it make sense to you ?
     >
     >     Maybe like
     >
    
https://www.mcs.anl.gov/petsc/petsc-current/src/ts/examples/tutorials/ex11.c.html
     >     With the use of the function SplitFaces, which i didn't fully
     >     understood
     >     so far.
     >
     >     Thanks,
     >
     >     Yann
     >
     >      >
     >      >        We usually define a quadrature on the reference
    element once.
     >      >
     >      >    Thanks,
     >      >
     >      >      Matt
     >      >
     >      >     I found elements of answers in those threads :
     >      >
     >
    https://lists.mcs.anl.gov/pipermail/petsc-users/2016-August/029985.html
     >      >
     >
    https://lists.mcs.anl.gov/mailman/htdig/petsc-users/2019-October/039581.html
     >      >
     >      >     However, it's not clear for me where to begin.
     >      >
     >      >     Quoting Matt, i should :
     >      >     "  DMGetCoordinateDM(dm, &cdm);
     >      >         <Set field information into cdm instead of dm>
     >      >        DMCreateLocalVector(cdm, &coordinatesLocal);
     >      >        <Fill in higher order coordinate values>
     >      >        DMSetCoordinatesLocal(dm, coordinatesLocal);"
     >      >
     >      >     However, i will not create ghost nodes this way. And
    i'm not
     >     sure to
     >      >     keep the good ordering.
     >      >     This part should be implemented in the PetscFE
    interface, for
     >     high
     >      >     order
     >      >     discrete solutions.
     >      >     I did not succeed in finding the correct part of the
    source
     >     doing it.
     >      >
     >      >     Could you please give me some hint to begin correctly
    thoses
     >     tasks ?
     >      >
     >      >     Thanks,
     >      >
     >      >     Yann
     >      >
     >      >
     >      >
     >      > --
     >      > What most experimenters take for granted before they begin
    their
     >      > experiments is infinitely more interesting than any
    results to which
     >      > their experiments lead.
     >      > -- Norbert Wiener
     >      >
     >      > https://www.cse.buffalo.edu/~knepley/
     >     <http://www.cse.buffalo.edu/~knepley/>
     >
     >
     >
     > --
     > What most experimenters take for granted before they begin their
     > experiments is infinitely more interesting than any results to which
     > their experiments lead.
     > -- Norbert Wiener
     >
     > https://www.cse.buffalo.edu/~knepley/
    <http://www.cse.buffalo.edu/~knepley/>



--
What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead.
-- Norbert Wiener

https://www.cse.buffalo.edu/~knepley/ <http://www.cse.buffalo.edu/~knepley/>
static char help[] = "dof management with dmplex for DG problems, for simplices 
\n\n";

#include <petscdmplex.h>

typedef struct {
  PetscInt  dim;    /* Topological problem dimension */
  PetscInt  Nf;     /* Number of fields */
  PetscInt  Nc[1];  /* Number of components per field */
  PetscInt  N;      /* Order of polymomials used for approximation */
} AppCtx;

static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
{
  PetscBool      flg;
  PetscErrorCode ierr;

  PetscFunctionBeginUser;
  options->dim   = 2;
  options->Nf    = 1;
  options->Nc[0] = 1;
  options->N     = 4;

  ierr = PetscOptionsBegin(comm, "", "dof management with dmplex for DG 
problems (simplices) Options", "DMPLEX");CHKERRQ(ierr);
  ierr = PetscOptionsRangeInt("-dim", "Problem dimension", "dof_dg.c", 
options->dim, &options->dim, NULL,1,3);CHKERRQ(ierr);
  ierr = PetscOptionsInt("-order", "Order of polymomials used for 
approximation", "dof_dg.c", options->N, &options->N, &flg);CHKERRQ(ierr);
  ierr = PetscOptionsEnd();
  PetscFunctionReturn(0);
}


int main(int argc, char **argv) {
  DM             dm;
  PetscSection   s;
  Vec            u;
  PetscViewer    viewer;
  AppCtx         user;
  PetscInt       cells[3] = {2, 2, 2};
  PetscReal      lower[3] = {-1,-1,-1};
  PetscReal      upper[3] = {1,1,1};
  /* DG specification of the PetscSection                            */
  /* order of poly approx is stored in AppCtx user : user.N          */
  PetscInt       dofPerEle=0;    /* Number of dof per cell           */
  PetscInt       internalDof;    /* dof defined on the internal cell */
                                 /* so without the faces dof         */
  PetscInt       nbFace=0;       /* Number of faces per cell         */
  PetscInt       nbDofFaceEle=0; /* Number of dof per face           */

  PetscErrorCode ierr;

  ierr = PetscInitialize(&argc, &argv, NULL, help); if (ierr) return ierr;
  ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr);

  ierr = DMPlexCreateBoxMesh(PETSC_COMM_WORLD, user.dim, PETSC_FALSE, cells, 
lower, upper, NULL, PETSC_TRUE, &dm);CHKERRQ(ierr);
  ierr = DMSetFromOptions(dm);CHKERRQ(ierr);
  ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr);

  /* Total number of dof per element, number of faces per element and number of 
dof per face */
  if (user.dim == 2) {
    dofPerEle = (user.N+1)*(user.N+2)/2;
    nbFace = 3;
    nbDofFaceEle = user.N + 1;
    internalDof = dofPerEle - nbFace*nbDofFaceEle + 3;
  } else if (user.dim == 3) {
    dofPerEle = (user.N+1)*(user.N+2)*(user.N+3)/6;
    nbFace = 4;
    nbDofFaceEle = (user.N+1)*(user.N+2)/2;
    internalDof = dofPerEle - nbFace*nbDofFaceEle + (user.N + 1)*6 - 4;
  }

  PetscPrintf(MPI_COMM_WORLD,"\ndof per cell : %d\n",dofPerEle);
  PetscPrintf(MPI_COMM_WORLD,"dof per face : %d\n",nbDofFaceEle);
  PetscPrintf(MPI_COMM_WORLD,"internal dof : %d\n",internalDof);

  {
    PetscInt *numDof, d;
    /* numDof[f*(dim+1)+d] gives the number of dof for field f on      */
    /*   points of dimension d. For instance, numDof[1] is the number  */
    /*   of dof for field 0 on each edge.                              */
    ierr = PetscMalloc1(user.Nf*(user.dim+1), &numDof);CHKERRQ(ierr);
    /* fields 0, written generally to add easily more fields  */
    for (d = 0; d < user.Nf*(user.dim+1); ++d) numDof[d] = 0;
    /* we put only the interior dof for not duplicating the face nodes */
    numDof[0*(user.dim+1)+user.dim]   = internalDof;    /* internalDof defined 
on cells  */
    numDof[0*(user.dim+1)+user.dim-1] = nbDofFaceEle; /* nbDofFaceEle  defined 
on faces  */
    ierr = DMSetNumFields(dm, user.Nf);CHKERRQ(ierr);
    ierr = DMPlexCreateSection(dm, NULL, user.Nc, numDof, 0, NULL, NULL, NULL, 
NULL, &s);CHKERRQ(ierr);
    ierr = PetscFree(numDof);CHKERRQ(ierr);
  }
  /* Name the Field variable */
  ierr = PetscSectionSetFieldName(s, 0, "u");CHKERRQ(ierr);
  /* Tell the DM to use this data layout */
  ierr = DMSetLocalSection(dm, s);CHKERRQ(ierr);
  /* Create a Vec with this layout and view it */
  ierr = DMGetGlobalVector(dm, &u);CHKERRQ(ierr);

  ierr = PetscViewerCreate(PETSC_COMM_WORLD, &viewer);CHKERRQ(ierr);
  ierr = PetscViewerSetType(viewer, PETSCVIEWERVTK);CHKERRQ(ierr);
  ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr);
  ierr = PetscViewerFileSetName(viewer, "sol.vtk");CHKERRQ(ierr);
  ierr = VecView(u, viewer);CHKERRQ(ierr);
  ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
  ierr = DMRestoreGlobalVector(dm, &u);CHKERRQ(ierr);

  /* Cleanup */
  ierr = PetscSectionDestroy(&s);CHKERRQ(ierr);
  ierr = DMDestroy(&dm);CHKERRQ(ierr);

  ierr = PetscFinalize();
  return ierr;
}

Reply via email to