1c4762a1bSJed Brown static char help[] = "Demonstrates use of VecCreateGhost().\n\n";
2c4762a1bSJed Brown
31bb3edfdSPatrick Sanan /*
4c4762a1bSJed Brown Description: Ghost padding is one way to handle local calculations that
5c4762a1bSJed Brown involve values from other processors. VecCreateGhost() provides
6c4762a1bSJed Brown a way to create vectors with extra room at the end of the vector
7c4762a1bSJed Brown array to contain the needed ghost values from other processors,
8c4762a1bSJed Brown vector computations are otherwise unaffected.
91bb3edfdSPatrick Sanan */
10c4762a1bSJed Brown
11c4762a1bSJed Brown /*
12c4762a1bSJed Brown Include "petscvec.h" so that we can use vectors. Note that this file
13c4762a1bSJed Brown automatically includes:
14c4762a1bSJed Brown petscsys.h - base PETSc routines petscis.h - index sets
15c4762a1bSJed Brown petscviewer.h - viewers
16c4762a1bSJed Brown */
17c4762a1bSJed Brown #include <petscvec.h>
18c4762a1bSJed Brown
main(int argc,char ** argv)19d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv)
20d71ae5a4SJacob Faibussowitsch {
21c4762a1bSJed Brown PetscMPIInt rank, size;
22c4762a1bSJed Brown PetscInt nlocal = 6, nghost = 2, ifrom[2], i, rstart, rend;
23ab4fe330SFande Kong PetscBool flg, flg2, flg3, flg4, flg5;
24c4762a1bSJed Brown PetscScalar value, *array, *tarray = 0;
25c4762a1bSJed Brown Vec lx, gx, gxs;
26ab4fe330SFande Kong IS ghost;
27ab4fe330SFande Kong ISLocalToGlobalMapping mapping;
28c4762a1bSJed Brown
29327415f7SBarry Smith PetscFunctionBeginUser;
30*c8025a54SPierre Jolivet PetscCall(PetscInitialize(&argc, &argv, NULL, help));
319566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
329566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
33be096a46SBarry Smith PetscCheck(size == 2, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run example with two processors");
34c4762a1bSJed Brown
35c4762a1bSJed Brown /*
36c4762a1bSJed Brown Construct a two dimensional graph connecting nlocal degrees of
37c4762a1bSJed Brown freedom per processor. From this we will generate the global
38c4762a1bSJed Brown indices of needed ghost values
39c4762a1bSJed Brown
40c4762a1bSJed Brown For simplicity we generate the entire graph on each processor:
41c4762a1bSJed Brown in real application the graph would stored in parallel, but this
42c4762a1bSJed Brown example is only to demonstrate the management of ghost padding
43c4762a1bSJed Brown with VecCreateGhost().
44c4762a1bSJed Brown
45c4762a1bSJed Brown In this example we consider the vector as representing
46c4762a1bSJed Brown degrees of freedom in a one dimensional grid with periodic
47c4762a1bSJed Brown boundary conditions.
48c4762a1bSJed Brown
49c4762a1bSJed Brown ----Processor 1--------- ----Processor 2 --------
50c4762a1bSJed Brown 0 1 2 3 4 5 6 7 8 9 10 11
51c4762a1bSJed Brown |----|
52c4762a1bSJed Brown |-------------------------------------------------|
53c4762a1bSJed Brown
54c4762a1bSJed Brown */
55c4762a1bSJed Brown
56dd400576SPatrick Sanan if (rank == 0) {
579371c9d4SSatish Balay ifrom[0] = 11;
589371c9d4SSatish Balay ifrom[1] = 6;
59c4762a1bSJed Brown } else {
609371c9d4SSatish Balay ifrom[0] = 0;
619371c9d4SSatish Balay ifrom[1] = 5;
62c4762a1bSJed Brown }
63c4762a1bSJed Brown
64c4762a1bSJed Brown /*
65c4762a1bSJed Brown Create the vector with two slots for ghost points. Note that both
66c4762a1bSJed Brown the local vector (lx) and the global vector (gx) share the same
67c4762a1bSJed Brown array for storing vector values.
68c4762a1bSJed Brown */
699566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(NULL, NULL, "-allocate", &flg));
709566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(NULL, NULL, "-vecmpisetghost", &flg2));
719566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(NULL, NULL, "-minvalues", &flg3));
72c4762a1bSJed Brown if (flg) {
739566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nlocal + nghost, &tarray));
749566063dSJacob Faibussowitsch PetscCall(VecCreateGhostWithArray(PETSC_COMM_WORLD, nlocal, PETSC_DECIDE, nghost, ifrom, tarray, &gxs));
75c4762a1bSJed Brown } else if (flg2) {
769566063dSJacob Faibussowitsch PetscCall(VecCreate(PETSC_COMM_WORLD, &gxs));
779566063dSJacob Faibussowitsch PetscCall(VecSetType(gxs, VECMPI));
789566063dSJacob Faibussowitsch PetscCall(VecSetSizes(gxs, nlocal, PETSC_DECIDE));
799566063dSJacob Faibussowitsch PetscCall(VecMPISetGhost(gxs, nghost, ifrom));
80c4762a1bSJed Brown } else {
819566063dSJacob Faibussowitsch PetscCall(VecCreateGhost(PETSC_COMM_WORLD, nlocal, PETSC_DECIDE, nghost, ifrom, &gxs));
824b2bf6caSPierre Jolivet PetscCall(VecSet(gxs, 1.0));
834b2bf6caSPierre Jolivet if (rank == 1) PetscCall(VecSetValueLocal(gxs, 0, 2.0, INSERT_VALUES));
844b2bf6caSPierre Jolivet PetscCall(VecAssemblyBegin(gxs));
854b2bf6caSPierre Jolivet PetscCall(VecAssemblyEnd(gxs));
864b2bf6caSPierre Jolivet value = 0.0;
874b2bf6caSPierre Jolivet if (rank == 1) {
884b2bf6caSPierre Jolivet PetscCall(VecGetArray(gxs, &array));
894b2bf6caSPierre Jolivet value = array[0];
904b2bf6caSPierre Jolivet PetscCall(VecRestoreArray(gxs, &array));
914b2bf6caSPierre Jolivet }
92462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &value, 1, MPIU_SCALAR, MPIU_SUM, PETSC_COMM_WORLD));
934b2bf6caSPierre Jolivet PetscCheck(PetscIsCloseAtTolScalar(value, 2.0, PETSC_SMALL, PETSC_SMALL), PETSC_COMM_WORLD, PETSC_ERR_PLIB, "%g != 2.0", (double)PetscAbsScalar(value));
94c4762a1bSJed Brown }
95c4762a1bSJed Brown
96c4762a1bSJed Brown /*
97c4762a1bSJed Brown Test VecDuplicate()
98c4762a1bSJed Brown */
999566063dSJacob Faibussowitsch PetscCall(VecDuplicate(gxs, &gx));
1009566063dSJacob Faibussowitsch PetscCall(VecDestroy(&gxs));
101c4762a1bSJed Brown
102c4762a1bSJed Brown /*
103c4762a1bSJed Brown Access the local representation
104c4762a1bSJed Brown */
1059566063dSJacob Faibussowitsch PetscCall(VecGhostGetLocalForm(gx, &lx));
106c4762a1bSJed Brown
107c4762a1bSJed Brown /*
108c4762a1bSJed Brown Set the values from 0 to 12 into the "global" vector
109c4762a1bSJed Brown */
1109566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(gx, &rstart, &rend));
111c4762a1bSJed Brown for (i = rstart; i < rend; i++) {
112c4762a1bSJed Brown value = (PetscScalar)i;
1139566063dSJacob Faibussowitsch PetscCall(VecSetValues(gx, 1, &i, &value, INSERT_VALUES));
114c4762a1bSJed Brown }
1159566063dSJacob Faibussowitsch PetscCall(VecAssemblyBegin(gx));
1169566063dSJacob Faibussowitsch PetscCall(VecAssemblyEnd(gx));
117c4762a1bSJed Brown
1189566063dSJacob Faibussowitsch PetscCall(VecGhostUpdateBegin(gx, INSERT_VALUES, SCATTER_FORWARD));
1199566063dSJacob Faibussowitsch PetscCall(VecGhostUpdateEnd(gx, INSERT_VALUES, SCATTER_FORWARD));
120c4762a1bSJed Brown
121c4762a1bSJed Brown /*
122c4762a1bSJed Brown Print out each vector, including the ghost padding region.
123c4762a1bSJed Brown */
1249566063dSJacob Faibussowitsch PetscCall(VecGetArray(lx, &array));
12548a46eb9SPierre Jolivet for (i = 0; i < nlocal + nghost; i++) PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT " %g\n", i, (double)PetscRealPart(array[i])));
1269566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(lx, &array));
1279566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, PETSC_STDOUT));
1289566063dSJacob Faibussowitsch PetscCall(VecGhostRestoreLocalForm(gx, &lx));
129c4762a1bSJed Brown
130c4762a1bSJed Brown /* Another test that sets ghost values and then accumulates onto the owning processors using MIN_VALUES */
131c4762a1bSJed Brown if (flg3) {
1329566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "\nTesting VecGhostUpdate with MIN_VALUES\n"));
1339566063dSJacob Faibussowitsch PetscCall(VecGhostGetLocalForm(gx, &lx));
1349566063dSJacob Faibussowitsch PetscCall(VecGetArray(lx, &array));
135c4762a1bSJed Brown for (i = 0; i < nghost; i++) array[nlocal + i] = rank ? (PetscScalar)4 : (PetscScalar)8;
1369566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(lx, &array));
1379566063dSJacob Faibussowitsch PetscCall(VecGhostRestoreLocalForm(gx, &lx));
138c4762a1bSJed Brown
1399566063dSJacob Faibussowitsch PetscCall(VecGhostUpdateBegin(gx, MIN_VALUES, SCATTER_REVERSE));
1409566063dSJacob Faibussowitsch PetscCall(VecGhostUpdateEnd(gx, MIN_VALUES, SCATTER_REVERSE));
141c4762a1bSJed Brown
1429566063dSJacob Faibussowitsch PetscCall(VecGhostGetLocalForm(gx, &lx));
1439566063dSJacob Faibussowitsch PetscCall(VecGetArray(lx, &array));
144c4762a1bSJed Brown
14548a46eb9SPierre Jolivet for (i = 0; i < nlocal + nghost; i++) PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT " %g\n", i, (double)PetscRealPart(array[i])));
1469566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(lx, &array));
1479566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, PETSC_STDOUT));
1489566063dSJacob Faibussowitsch PetscCall(VecGhostRestoreLocalForm(gx, &lx));
149c4762a1bSJed Brown }
150c4762a1bSJed Brown
151ab4fe330SFande Kong PetscCall(PetscOptionsHasName(NULL, NULL, "-vecghostgetghostis", &flg4));
152ab4fe330SFande Kong if (flg4) {
153ab4fe330SFande Kong PetscCall(VecGhostGetGhostIS(gx, &ghost));
154ab4fe330SFande Kong PetscCall(ISView(ghost, PETSC_VIEWER_STDOUT_WORLD));
155ab4fe330SFande Kong }
156ab4fe330SFande Kong PetscCall(PetscOptionsHasName(NULL, NULL, "-getgtlmapping", &flg5));
157ab4fe330SFande Kong if (flg5) {
158ab4fe330SFande Kong PetscCall(VecGetLocalToGlobalMapping(gx, &mapping));
1594b2bf6caSPierre Jolivet if (rank == 0) PetscCall(ISLocalToGlobalMappingView(mapping, NULL));
160ab4fe330SFande Kong }
161ab4fe330SFande Kong
1629566063dSJacob Faibussowitsch PetscCall(VecDestroy(&gx));
163c4762a1bSJed Brown
1649566063dSJacob Faibussowitsch if (flg) PetscCall(PetscFree(tarray));
1659566063dSJacob Faibussowitsch PetscCall(PetscFinalize());
166b122ec5aSJacob Faibussowitsch return 0;
167c4762a1bSJed Brown }
168c4762a1bSJed Brown
169c4762a1bSJed Brown /*TEST
170c4762a1bSJed Brown
171c4762a1bSJed Brown test:
172c4762a1bSJed Brown nsize: 2
173c4762a1bSJed Brown
174c4762a1bSJed Brown test:
175c4762a1bSJed Brown suffix: 2
176c4762a1bSJed Brown nsize: 2
177c4762a1bSJed Brown args: -allocate
178c4762a1bSJed Brown output_file: output/ex9_1.out
179c4762a1bSJed Brown
180c4762a1bSJed Brown test:
181c4762a1bSJed Brown suffix: 3
182c4762a1bSJed Brown nsize: 2
183c4762a1bSJed Brown args: -vecmpisetghost
184c4762a1bSJed Brown output_file: output/ex9_1.out
185c4762a1bSJed Brown
186c4762a1bSJed Brown test:
187c4762a1bSJed Brown suffix: 4
188c4762a1bSJed Brown nsize: 2
189c4762a1bSJed Brown args: -minvalues
190c4762a1bSJed Brown output_file: output/ex9_2.out
191c4762a1bSJed Brown requires: !complex
192c4762a1bSJed Brown
193ab4fe330SFande Kong test:
194ab4fe330SFande Kong suffix: 5
195ab4fe330SFande Kong nsize: 2
196ab4fe330SFande Kong args: -vecghostgetghostis
197ab4fe330SFande Kong
198ab4fe330SFande Kong test:
199ab4fe330SFande Kong suffix: 6
200ab4fe330SFande Kong nsize: 2
201ab4fe330SFande Kong args: -getgtlmapping
202ab4fe330SFande Kong
203c4762a1bSJed Brown TEST*/
204