xref: /petsc/src/vec/vec/tutorials/ex9.c (revision 327415f76d85372a4417cf1aaa14db707d4d6c04)
1c4762a1bSJed Brown 
2c4762a1bSJed Brown static char help[] = "Demonstrates use of VecCreateGhost().\n\n";
3c4762a1bSJed Brown 
41bb3edfdSPatrick Sanan /*
5c4762a1bSJed Brown    Description: Ghost padding is one way to handle local calculations that
6c4762a1bSJed Brown       involve values from other processors. VecCreateGhost() provides
7c4762a1bSJed Brown       a way to create vectors with extra room at the end of the vector
8c4762a1bSJed Brown       array to contain the needed ghost values from other processors,
9c4762a1bSJed Brown       vector computations are otherwise unaffected.
101bb3edfdSPatrick Sanan */
11c4762a1bSJed Brown 
12c4762a1bSJed Brown /*
13c4762a1bSJed Brown   Include "petscvec.h" so that we can use vectors.  Note that this file
14c4762a1bSJed Brown   automatically includes:
15c4762a1bSJed Brown      petscsys.h       - base PETSc routines   petscis.h     - index sets
16c4762a1bSJed Brown      petscviewer.h - viewers
17c4762a1bSJed Brown */
18c4762a1bSJed Brown #include <petscvec.h>
19c4762a1bSJed Brown 
20c4762a1bSJed Brown int main(int argc,char **argv)
21c4762a1bSJed Brown {
22c4762a1bSJed Brown   PetscMPIInt    rank,size;
23c4762a1bSJed Brown   PetscInt       nlocal = 6,nghost = 2,ifrom[2],i,rstart,rend;
24c4762a1bSJed Brown   PetscBool      flg,flg2,flg3;
25c4762a1bSJed Brown   PetscScalar    value,*array,*tarray=0;
26c4762a1bSJed Brown   Vec            lx,gx,gxs;
27c4762a1bSJed Brown 
28*327415f7SBarry Smith   PetscFunctionBeginUser;
299566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc,&argv,(char*)0,help));
309566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank));
319566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size));
32be096a46SBarry Smith   PetscCheck(size == 2,PETSC_COMM_WORLD,PETSC_ERR_WRONG_MPI_SIZE,"Must run example with two processors");
33c4762a1bSJed Brown 
34c4762a1bSJed Brown   /*
35c4762a1bSJed Brown      Construct a two dimensional graph connecting nlocal degrees of
36c4762a1bSJed Brown      freedom per processor. From this we will generate the global
37c4762a1bSJed Brown      indices of needed ghost values
38c4762a1bSJed Brown 
39c4762a1bSJed Brown      For simplicity we generate the entire graph on each processor:
40c4762a1bSJed Brown      in real application the graph would stored in parallel, but this
41c4762a1bSJed Brown      example is only to demonstrate the management of ghost padding
42c4762a1bSJed Brown      with VecCreateGhost().
43c4762a1bSJed Brown 
44c4762a1bSJed Brown      In this example we consider the vector as representing
45c4762a1bSJed Brown      degrees of freedom in a one dimensional grid with periodic
46c4762a1bSJed Brown      boundary conditions.
47c4762a1bSJed Brown 
48c4762a1bSJed Brown         ----Processor  1---------  ----Processor 2 --------
49c4762a1bSJed Brown          0    1   2   3   4    5    6    7   8   9   10   11
50c4762a1bSJed Brown                                |----|
51c4762a1bSJed Brown          |-------------------------------------------------|
52c4762a1bSJed Brown 
53c4762a1bSJed Brown   */
54c4762a1bSJed Brown 
55dd400576SPatrick Sanan   if (rank == 0) {
56c4762a1bSJed Brown     ifrom[0] = 11; ifrom[1] = 6;
57c4762a1bSJed Brown   } else {
58c4762a1bSJed Brown     ifrom[0] = 0;  ifrom[1] = 5;
59c4762a1bSJed Brown   }
60c4762a1bSJed Brown 
61c4762a1bSJed Brown   /*
62c4762a1bSJed Brown      Create the vector with two slots for ghost points. Note that both
63c4762a1bSJed Brown      the local vector (lx) and the global vector (gx) share the same
64c4762a1bSJed Brown      array for storing vector values.
65c4762a1bSJed Brown   */
669566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(NULL,NULL,"-allocate",&flg));
679566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(NULL,NULL,"-vecmpisetghost",&flg2));
689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(NULL,NULL,"-minvalues",&flg3));
69c4762a1bSJed Brown   if (flg) {
709566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nlocal+nghost,&tarray));
719566063dSJacob Faibussowitsch     PetscCall(VecCreateGhostWithArray(PETSC_COMM_WORLD,nlocal,PETSC_DECIDE,nghost,ifrom,tarray,&gxs));
72c4762a1bSJed Brown   } else if (flg2) {
739566063dSJacob Faibussowitsch     PetscCall(VecCreate(PETSC_COMM_WORLD,&gxs));
749566063dSJacob Faibussowitsch     PetscCall(VecSetType(gxs,VECMPI));
759566063dSJacob Faibussowitsch     PetscCall(VecSetSizes(gxs,nlocal,PETSC_DECIDE));
769566063dSJacob Faibussowitsch     PetscCall(VecMPISetGhost(gxs,nghost,ifrom));
77c4762a1bSJed Brown   } else {
789566063dSJacob Faibussowitsch     PetscCall(VecCreateGhost(PETSC_COMM_WORLD,nlocal,PETSC_DECIDE,nghost,ifrom,&gxs));
79c4762a1bSJed Brown   }
80c4762a1bSJed Brown 
81c4762a1bSJed Brown   /*
82c4762a1bSJed Brown       Test VecDuplicate()
83c4762a1bSJed Brown   */
849566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(gxs,&gx));
859566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&gxs));
86c4762a1bSJed Brown 
87c4762a1bSJed Brown   /*
88c4762a1bSJed Brown      Access the local representation
89c4762a1bSJed Brown   */
909566063dSJacob Faibussowitsch   PetscCall(VecGhostGetLocalForm(gx,&lx));
91c4762a1bSJed Brown 
92c4762a1bSJed Brown   /*
93c4762a1bSJed Brown      Set the values from 0 to 12 into the "global" vector
94c4762a1bSJed Brown   */
959566063dSJacob Faibussowitsch   PetscCall(VecGetOwnershipRange(gx,&rstart,&rend));
96c4762a1bSJed Brown   for (i=rstart; i<rend; i++) {
97c4762a1bSJed Brown     value = (PetscScalar) i;
989566063dSJacob Faibussowitsch     PetscCall(VecSetValues(gx,1,&i,&value,INSERT_VALUES));
99c4762a1bSJed Brown   }
1009566063dSJacob Faibussowitsch   PetscCall(VecAssemblyBegin(gx));
1019566063dSJacob Faibussowitsch   PetscCall(VecAssemblyEnd(gx));
102c4762a1bSJed Brown 
1039566063dSJacob Faibussowitsch   PetscCall(VecGhostUpdateBegin(gx,INSERT_VALUES,SCATTER_FORWARD));
1049566063dSJacob Faibussowitsch   PetscCall(VecGhostUpdateEnd(gx,INSERT_VALUES,SCATTER_FORWARD));
105c4762a1bSJed Brown 
106c4762a1bSJed Brown   /*
107c4762a1bSJed Brown      Print out each vector, including the ghost padding region.
108c4762a1bSJed Brown   */
1099566063dSJacob Faibussowitsch   PetscCall(VecGetArray(lx,&array));
110c4762a1bSJed Brown   for (i=0; i<nlocal+nghost; i++) {
1119566063dSJacob Faibussowitsch     PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD,"%" PetscInt_FMT " %g\n",i,(double)PetscRealPart(array[i])));
112c4762a1bSJed Brown   }
1139566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(lx,&array));
1149566063dSJacob Faibussowitsch   PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD,PETSC_STDOUT));
1159566063dSJacob Faibussowitsch   PetscCall(VecGhostRestoreLocalForm(gx,&lx));
116c4762a1bSJed Brown 
117c4762a1bSJed Brown   /* Another test that sets ghost values and then accumulates onto the owning processors using MIN_VALUES */
118c4762a1bSJed Brown   if (flg3) {
1199566063dSJacob Faibussowitsch     if (rank == 0)PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD,"\nTesting VecGhostUpdate with MIN_VALUES\n"));
1209566063dSJacob Faibussowitsch     PetscCall(VecGhostGetLocalForm(gx,&lx));
1219566063dSJacob Faibussowitsch     PetscCall(VecGetArray(lx,&array));
122c4762a1bSJed Brown     for (i=0; i<nghost; i++) array[nlocal+i] = rank ? (PetscScalar)4 : (PetscScalar)8;
1239566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(lx,&array));
1249566063dSJacob Faibussowitsch     PetscCall(VecGhostRestoreLocalForm(gx,&lx));
125c4762a1bSJed Brown 
1269566063dSJacob Faibussowitsch     PetscCall(VecGhostUpdateBegin(gx,MIN_VALUES,SCATTER_REVERSE));
1279566063dSJacob Faibussowitsch     PetscCall(VecGhostUpdateEnd(gx,MIN_VALUES,SCATTER_REVERSE));
128c4762a1bSJed Brown 
1299566063dSJacob Faibussowitsch     PetscCall(VecGhostGetLocalForm(gx,&lx));
1309566063dSJacob Faibussowitsch     PetscCall(VecGetArray(lx,&array));
131c4762a1bSJed Brown 
132c4762a1bSJed Brown     for (i=0; i<nlocal+nghost; i++) {
1339566063dSJacob Faibussowitsch       PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD,"%" PetscInt_FMT " %g\n",i,(double)PetscRealPart(array[i])));
134c4762a1bSJed Brown     }
1359566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(lx,&array));
1369566063dSJacob Faibussowitsch     PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD,PETSC_STDOUT));
1379566063dSJacob Faibussowitsch     PetscCall(VecGhostRestoreLocalForm(gx,&lx));
138c4762a1bSJed Brown   }
139c4762a1bSJed Brown 
1409566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&gx));
141c4762a1bSJed Brown 
1429566063dSJacob Faibussowitsch   if (flg) PetscCall(PetscFree(tarray));
1439566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
144b122ec5aSJacob Faibussowitsch   return 0;
145c4762a1bSJed Brown }
146c4762a1bSJed Brown 
147c4762a1bSJed Brown /*TEST
148c4762a1bSJed Brown 
149c4762a1bSJed Brown      test:
150c4762a1bSJed Brown        nsize: 2
151c4762a1bSJed Brown 
152c4762a1bSJed Brown      test:
153c4762a1bSJed Brown        suffix: 2
154c4762a1bSJed Brown        nsize: 2
155c4762a1bSJed Brown        args: -allocate
156c4762a1bSJed Brown        output_file: output/ex9_1.out
157c4762a1bSJed Brown 
158c4762a1bSJed Brown      test:
159c4762a1bSJed Brown        suffix: 3
160c4762a1bSJed Brown        nsize: 2
161c4762a1bSJed Brown        args: -vecmpisetghost
162c4762a1bSJed Brown        output_file: output/ex9_1.out
163c4762a1bSJed Brown 
164c4762a1bSJed Brown      test:
165c4762a1bSJed Brown        suffix: 4
166c4762a1bSJed Brown        nsize: 2
167c4762a1bSJed Brown        args: -minvalues
168c4762a1bSJed Brown        output_file: output/ex9_2.out
169c4762a1bSJed Brown        requires: !complex
170c4762a1bSJed Brown 
171c4762a1bSJed Brown TEST*/
172