xref: /petsc/src/vec/is/sf/tests/ex16.c (revision a69119a591a03a9d906b29c0a4e9802e4d7c9795)
1 static char help[] = "Test PetscSFCreateByMatchingIndices\n\n";
2 
3 #include <petsc.h>
4 #include <petscsf.h>
5 
6 /* Test PetscSFCreateByMatchingIndices.
7 
8 testnum 0:
9 
10   rank             : 0            1            2
11   numRootIndices   : 3            1            1
12   rootIndices      : [1 0 2]      [3]          [3]
13   rootLocalOffset  : 100          200          300
14   layout           : [0 1]        [2]          [3]
15   numLeafIndices   : 1            1            2
16   leafIndices      : [0]          [2]          [0 3]
17   leafLocalOffset  : 400          500          600
18 
19 would build the following SF:
20 
21   [0] 400 <- (0,101)
22   [1] 500 <- (0,102)
23   [2] 600 <- (0,101)
24   [2] 601 <- (2,300)
25 
26 testnum 1:
27 
28   rank             : 0               1               2
29   numRootIndices   : 3               1               1
30   rootIndices      : [1 0 2]         [3]             [3]
31   rootLocalOffset  : 100             200             300
32   layout           : [0 1]           [2]             [3]
33   numLeafIndices   : numRootIndices  numRootIndices  numRootIndices
34   leafIndices      : rootIndices     rootIndices     rootIndices
35   leafLocalOffset  : rootLocalOffset rootLocalOffset rootLocalOffset
36 
37 would build the following SF:
38 
39   [1] 200 <- (2,300)
40 
41 testnum 2:
42 
43   No one claims ownership of global index 1, but no one needs it.
44 
45   rank             : 0            1            2
46   numRootIndices   : 2            1            1
47   rootIndices      : [0 2]        [3]          [3]
48   rootLocalOffset  : 100          200          300
49   layout           : [0 1]        [2]          [3]
50   numLeafIndices   : 1            1            2
51   leafIndices      : [0]          [2]          [0 3]
52   leafLocalOffset  : 400          500          600
53 
54 would build the following SF:
55 
56   [0] 400 <- (0,100)
57   [1] 500 <- (0,101)
58   [2] 600 <- (0,100)
59   [2] 601 <- (2,300)
60 
61 */
62 
63 int main(int argc, char **argv) {
64   PetscSF     sf;
65   PetscLayout layout;
66   PetscInt    N, n;
67   PetscInt    nA = -1, *A, offsetA = -1;
68   PetscInt    nB = -1, *B, offsetB = -1;
69   PetscMPIInt size, rank;
70   PetscInt    testnum;
71 
72   PetscFunctionBeginUser;
73   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
74   PetscCall(PetscOptionsGetInt(NULL, NULL, "-testnum", &testnum, NULL));
75   PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
76   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
77   PetscCheck(size == 3, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
78 
79   switch (testnum) {
80   case 0:
81     N = 4;
82     n = PETSC_DECIDE;
83     switch (rank) {
84     case 0:
85       nA      = 3;
86       offsetA = 100;
87       nB      = 1;
88       offsetB = 400;
89       break;
90     case 1:
91       nA      = 1;
92       offsetA = 200;
93       nB      = 1;
94       offsetB = 500;
95       break;
96     case 2:
97       nA      = 1;
98       offsetA = 300;
99       nB      = 2;
100       offsetB = 600;
101       break;
102     default: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
103     }
104     PetscCall(PetscMalloc1(nA, &A));
105     PetscCall(PetscMalloc1(nB, &B));
106     switch (rank) {
107     case 0:
108       A[0] = 1;
109       A[1] = 0;
110       A[2] = 2;
111       B[0] = 0;
112       break;
113     case 1:
114       A[0] = 3;
115       B[0] = 2;
116       break;
117     case 2:
118       A[0] = 3;
119       B[0] = 0;
120       B[1] = 3;
121       break;
122     default: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
123     }
124     break;
125   case 1:
126     N = 4;
127     n = PETSC_DECIDE;
128     switch (rank) {
129     case 0:
130       nA      = 3;
131       offsetA = 100;
132       break;
133     case 1:
134       nA      = 1;
135       offsetA = 200;
136       break;
137     case 2:
138       nA      = 1;
139       offsetA = 300;
140       break;
141     default: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
142     }
143     PetscCall(PetscMalloc1(nA, &A));
144     switch (rank) {
145     case 0:
146       A[0] = 1;
147       A[1] = 0;
148       A[2] = 2;
149       break;
150     case 1: A[0] = 3; break;
151     case 2: A[0] = 3; break;
152     default: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
153     }
154     nB      = nA;
155     B       = A;
156     offsetB = offsetA;
157     break;
158   case 2:
159     N = 4;
160     n = PETSC_DECIDE;
161     switch (rank) {
162     case 0:
163       nA      = 2;
164       offsetA = 100;
165       nB      = 1;
166       offsetB = 400;
167       break;
168     case 1:
169       nA      = 1;
170       offsetA = 200;
171       nB      = 1;
172       offsetB = 500;
173       break;
174     case 2:
175       nA      = 1;
176       offsetA = 300;
177       nB      = 2;
178       offsetB = 600;
179       break;
180     default: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
181     }
182     PetscCall(PetscMalloc1(nA, &A));
183     PetscCall(PetscMalloc1(nB, &B));
184     switch (rank) {
185     case 0:
186       A[0] = 0;
187       A[1] = 2;
188       B[0] = 0;
189       break;
190     case 1:
191       A[0] = 3;
192       B[0] = 2;
193       break;
194     case 2:
195       A[0] = 3;
196       B[0] = 0;
197       B[1] = 3;
198       break;
199     default: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
200     }
201     break;
202   }
203   PetscCall(PetscLayoutCreate(PETSC_COMM_WORLD, &layout));
204   PetscCall(PetscLayoutSetSize(layout, N));
205   PetscCall(PetscLayoutSetLocalSize(layout, n));
206   PetscCall(PetscLayoutSetBlockSize(layout, 1));
207   PetscCall(PetscSFCreateByMatchingIndices(layout, nA, A, NULL, offsetA, nB, B, NULL, offsetB, NULL, &sf));
208   PetscCall(PetscLayoutDestroy(&layout));
209   PetscCall(PetscFree(A));
210   if (testnum != 1) PetscCall(PetscFree(B));
211   PetscCall(PetscObjectSetName((PetscObject)sf, "sf"));
212   PetscCall(PetscSFView(sf, NULL));
213   PetscCall(PetscSFDestroy(&sf));
214 
215   PetscCall(PetscFinalize());
216   return 0;
217 }
218 
219 /*TEST
220 
221   test:
222     suffix: 0
223     nsize: 3
224     args: -testnum 0
225 
226   test:
227     suffix: 1
228     nsize: 3
229     args: -testnum 1
230 
231   test:
232     suffix: 2
233     nsize: 3
234     args: -testnum 2
235 
236 TEST*/
237