static char help[] = "\n\n"; /* Demonstrates using DM_BOUNDARY_GHOSTED how to handle a rotated boundary conditions where one edge is connected to its immediate neighbor Consider the domain (with natural numbering) 6 7 8 3 4 5 0 1 2 The ghost points along the bottom (directly below the three columns above) should be 0 3 and 6 while the ghost points along the left side should be 0 1 2 Note that the ghosted local vectors extend in both the x and y directions so, for example if we have a single MPI process the ghosted vector has (in the original natural numbering) x x x x x 2 6 7 8 x 1 3 4 5 x 0 0 1 2 x x 0 3 6 x where x indicates a location that is not updated by the communication and should be used. For this to make sense the number of grid points in the x and y directions must be the same This ghost point mapping was suggested by: Wenbo Zhao */ #include #include int main(int argc,char **argv) { PetscInt M = 6; DM da; Vec local,global,natural; PetscInt i,start,end,*ifrom,x,y,xm,ym; PetscScalar *xnatural; IS from,to; AO ao; VecScatter scatter1,scatter2; PetscViewer subviewer; PetscFunctionBeginUser; PetscCall(PetscInitialize(&argc,&argv,(char*)0,help)); /* Create distributed array and get vectors */ PetscCall(DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_GHOSTED,DM_BOUNDARY_GHOSTED,DMDA_STENCIL_STAR,M,M,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,&da)); PetscCall(DMSetUp(da)); PetscCall(DMCreateGlobalVector(da,&global)); PetscCall(DMCreateLocalVector(da,&local)); /* construct global to local scatter for the left side of the domain to the ghost on the bottom */ PetscCall(DMDAGetCorners(da,&x,&y,NULL,&xm,&ym,NULL)); if (!y) { /* only processes on the bottom of the domain fill up the ghost locations */ PetscCall(ISCreateStride(PETSC_COMM_SELF,xm,1,1,&to)); } else { PetscCall(ISCreateStride(PETSC_COMM_SELF,0,0,0,&to)); } PetscCall(PetscMalloc1(xm,&ifrom)); for (i=x;i