Dear Matt,

I tried it, but it doesn't seem to work.
Attached is a very small working example illustrating the problem.
I create a DMPlexBox Mesh, periodic in the Y direction. I then scale the Y coordinates with a factor 10, and add 1.0 to it. Both DMGetCoordinatesLocal and DMGetCellCoordinatesLocal. Then I evaluate the coordinates with DMPlexGetCellCoordinates. Most of the Y coordinates are correct, but not all of them - for instance, the minimum Y coordinate is 0.0, and this should be 1.0.

Am I doing something wrong?

Thanks and best regards,

Berend.

On 5/17/23 17:58, Matthew Knepley wrote:
On Wed, May 17, 2023 at 11:20 AM Berend van Wachem <berend.vanwac...@ovgu.de 
<mailto:berend.vanwac...@ovgu.de>> wrote:

    Dear Matt,

    Is there a way to 'redo' the DMLocalizeCoordinates() ? Or to undo it?
    Alternatively, can we make the calling of DMLocalizeCoordinates() in the  
DMPlexCreate...() routines optional?

    Otherwise, we would have to copy all arrays of coordinates from 
DMGetCoordinatesLocal() and DMGetCellCoordinatesLocal() before
    scaling them.


I am likely not being clear. I think all you have to do is the following:

   DMGetCoordinatesLocal(dm, &xl);
   VecScale(xl, scale);
   DMSetCoordinatesLocal(dm, xl);
   DMGetCellCoordinatesLocal(dm, &xl);
   VecScale(xl, scale);
   DMSetCellCoordinatesLocal(dm, xl);

Does this not work?

   Thanks,

      Matt

    Best regards, Berend.

    On 5/17/23 16:35, Matthew Knepley wrote:
     > On Wed, May 17, 2023 at 10:21 AM Berend van Wachem <berend.vanwac...@ovgu.de 
<mailto:berend.vanwac...@ovgu.de>
    <mailto:berend.vanwac...@ovgu.de <mailto:berend.vanwac...@ovgu.de>>> wrote:
     >
     >     Dear Matt,
     >
     >     Thanks for getting back to me so quickly.
     >
     >     If I scale each of the coordinates of the mesh (say, I want to cube 
each
     >     co-ordinate), and I do this for both:
     >
     >     DMGetCoordinatesLocal();
     >     DMGetCellCoordinatesLocal();
     >
     >     How do I know I am not cubing one coordinate multiple times?
     >
     >
     > Good question. Right now, the only connection between the two sets of 
coordinates is DMLocalizeCoordinates(). Since
    sometimes
     > people want to do non-trivial things to
     > coordinates, I prefer not to push in an API for "just" scaling, but I 
could be convinced
     > the other way.
     >
     >    Thanks,
     >
     >       Matt
     >
     >     Thanks, Berend.
     >
     >     On 5/17/23 16:10, Matthew Knepley wrote:
     >      > On Wed, May 17, 2023 at 10:02 AM Berend van Wachem
     >      > <berend.vanwac...@ovgu.de <mailto:berend.vanwac...@ovgu.de> 
<mailto:berend.vanwac...@ovgu.de
    <mailto:berend.vanwac...@ovgu.de>> <mailto:berend.vanwac...@ovgu.de 
<mailto:berend.vanwac...@ovgu.de>
     >     <mailto:berend.vanwac...@ovgu.de 
<mailto:berend.vanwac...@ovgu.de>>>> wrote:
     >      >
     >      >     Dear PETSc Team,
     >      >
     >      >     We are using DMPlex, and we create a mesh using
     >      >
     >      >     DMPlexCreateBoxMesh (.... );
     >      >
     >      >     and get a uniform mesh. The mesh is periodic.
     >      >
     >      >     We typically want to "scale" the coordinates (vertices) of 
the mesh,
     >      >     and
     >      >     to achieve this, we call
     >      >
     >      >     DMGetCoordinatesLocal(dm, &coordinates);
     >      >
     >      >     and scale the entries in the Vector coordinates appropriately.
     >      >
     >      >     and then
     >      >
     >      >     DMSetCoordinatesLocal(dm, coordinates);
     >      >
     >      >
     >      >     After this, we localise the coordinates by calling
     >      >
     >      >     DMLocalizeCoordinates(dm);
     >      >
     >      >     This worked fine up to PETSc 3.18, but with versions after 
this, the
     >      >     coordinates we get from the call
     >      >
     >      >     DMPlexGetCellCoordinates(dm, CellID, &isDG, &CoordSize,
     >      >     &ArrayCoordinates, &Coordinates);
     >      >
     >      >     are no longer correct if the mesh is periodic. A number of the
     >      >     coordinates returned from calling DMPlexGetCellCoordinates 
are wrong.
     >      >
     >      >     I think, this is because DMLocalizeCoordinates is now 
automatically
     >      >     called within the routine DMPlexCreateBoxMesh.
     >      >
     >      >     So, my question is: How should we scale the coordinates from 
a periodic
     >      >     DMPlex mesh so that they are reflected correctly when calling 
both
     >      >     DMGetCoordinatesLocal and DMPlexGetCellCoordinates, with 
PETSc versions
     >      >       >= 3.18?
     >      >
     >      >
     >      > I think we might have to add an API function. For now, when you 
scale
     >      > the coordinates,
     >      > can you scale both copies?
     >      >
     >      >    DMGetCoordinatesLocal()
     >      >    DMGetCellCoordinatesLocal();
     >      >
     >      > and then set them back.
     >      >
     >      >    Thanks,
     >      >
     >      >       Matt
     >      >
     >      >     Many thanks, Berend.
     >      >
     >      > --
     >      > 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/ 
<https://www.cse.buffalo.edu/~knepley/>
    <https://www.cse.buffalo.edu/~knepley/ 
<https://www.cse.buffalo.edu/~knepley/>> <http://www.cse.buffalo.edu/~knepley/
    <http://www.cse.buffalo.edu/~knepley/>
     >     <http://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/ 
<https://www.cse.buffalo.edu/~knepley/> <http://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/>
#include <petsc.h>
#include <petscdmplex.h>
#include <assert.h>
static char help[] = "Vertices Example";

#define MF_MAX(a, b) ((a) > (b) ? (a) : (b))
#define MF_MIN(a, b) ((a) < (b) ? (a) : (b))

int main(int argc, char **argv)
{
  DM dm;
  PetscErrorCode ierr;
  const PetscInt dim = 3;
  const PetscBool cellSimplex = PETSC_FALSE;
  const PetscBool interpBefore = PETSC_FALSE;
  const PetscInt iSize[3] = {5, 5, 5};
  const PetscScalar Xmin[3] = {0.0, 0.0, 0.0};
  const PetscScalar Xmax[3] = {1.0, 1.0, 1.0};
  const DMBoundaryType MeshPeriodicity[3] = {DM_BOUNDARY_NONE, DM_BOUNDARY_PERIODIC, DM_BOUNDARY_NONE};
  Vec coordinates;
  PetscScalar *coordinatesArray;
  PetscInt coordVecSize;
  PetscInt CellHeight, CellStart, CellEnd;
  PetscReal yMinCoord = 1000.0, yMaxCoord = -1000.0;

  PetscFunctionBegin;

  ierr = PetscInitialize(&argc, &argv, (char *) 0, help);
  CHKERRQ(ierr);

  ierr = DMPlexCreateBoxMesh(PETSC_COMM_WORLD, dim, cellSimplex, iSize, Xmin, Xmax, MeshPeriodicity, interpBefore, &dm);
  CHKERRQ(ierr);
  ierr = DMSetFromOptions(dm);
  CHKERRQ(ierr);

  /* First scale/set the coordinates from DMGetCoordinatesLocal*/
  ierr = DMGetCoordinatesLocal(dm, &coordinates);
  CHKERRQ(ierr);
  ierr = VecGetLocalSize(coordinates, &coordVecSize);
  CHKERRQ(ierr);
  assert(coordVecSize % 3 == 0);
  ierr = VecGetArray(coordinates, &coordinatesArray);
  CHKERRQ(ierr);
  for (PetscInt i = 0; i < coordVecSize; i += dim)
  {
    PetscScalar *coord = &coordinatesArray[i];
    coord[1] *= 10 + 1.0;
  }
  ierr = VecRestoreArray(coordinates, &coordinatesArray);
  CHKERRQ(ierr);
  ierr = DMSetCoordinatesLocal(dm, coordinates);
  CHKERRQ(ierr);

  /* Secondly, scale/set the coordinates from DMGetCellCoordinatesLocal */
  ierr = DMGetCellCoordinatesLocal(dm, &coordinates);
  CHKERRQ(ierr);
  ierr = VecGetSize(coordinates, &coordVecSize);
  CHKERRQ(ierr);
  assert(coordVecSize % 3 == 0);
  ierr = VecGetArray(coordinates, &coordinatesArray);
  CHKERRQ(ierr);
  for (PetscInt i = 0; i < coordVecSize; i += dim)
  {
    PetscScalar *coord = &coordinatesArray[i];
    coord[1] *= 10 + 1.0;
  }
  ierr = VecRestoreArray(coordinates, &coordinatesArray);
  CHKERRQ(ierr);
  ierr = DMSetCellCoordinatesLocal(dm, coordinates);
  CHKERRQ(ierr);

  /* Check the vertices per Cell basis: */
  ierr = DMPlexGetVTKCellHeight(dm, &CellHeight);
  CHKERRQ(ierr);
  ierr = DMPlexGetHeightStratum(dm, CellHeight, &CellStart, &CellEnd);
  CHKERRQ(ierr);

  for (PetscInt LocalCellID = CellStart; LocalCellID < CellEnd; LocalCellID++)
  {
    PetscScalar *Coordinates;
    const PetscScalar *ArrayCoordinates;
    PetscInt CoordSize;
    PetscBool isDG;
    ierr = DMPlexGetCellCoordinates(dm, LocalCellID, &isDG, &CoordSize, &ArrayCoordinates, &Coordinates);
    CHKERRQ(ierr);
    assert(CoordSize % 3 == 0);
    for (PetscInt v = 0; v < CoordSize / 3; v++)
    {
      yMinCoord = MF_MIN(yMinCoord, Coordinates[3 * v + 1]);
      yMaxCoord = MF_MAX(yMaxCoord, Coordinates[3 * v + 1]);
    }
    ierr = DMPlexRestoreCellCoordinates(dm, LocalCellID, &isDG, &CoordSize, &ArrayCoordinates, &Coordinates);
    CHKERRQ(ierr);
  }
  printf("Y-min coord: %e, Y-min coord: %e\n", yMinCoord, yMaxCoord);
  PetscFinalize();
}

Reply via email to