xref: /petsc/src/vec/is/sf/tests/ex16.c (revision d5b43468fb8780a8feea140ccd6fa3e6a50411cc)
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 {
65   PetscSF     sf;
66   PetscLayout layout;
67   PetscInt    N, n;
68   PetscInt    nA = -1, *A, offsetA = -1;
69   PetscInt    nB = -1, *B, offsetB = -1;
70   PetscMPIInt size, rank;
71   PetscInt    testnum;
72 
73   PetscFunctionBeginUser;
74   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
75   PetscCall(PetscOptionsGetInt(NULL, NULL, "-testnum", &testnum, NULL));
76   PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
77   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
78   PetscCheck(size == 3, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
79 
80   switch (testnum) {
81   case 0:
82     N = 4;
83     n = PETSC_DECIDE;
84     switch (rank) {
85     case 0:
86       nA      = 3;
87       offsetA = 100;
88       nB      = 1;
89       offsetB = 400;
90       break;
91     case 1:
92       nA      = 1;
93       offsetA = 200;
94       nB      = 1;
95       offsetB = 500;
96       break;
97     case 2:
98       nA      = 1;
99       offsetA = 300;
100       nB      = 2;
101       offsetB = 600;
102       break;
103     default:
104       SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
105     }
106     PetscCall(PetscMalloc1(nA, &A));
107     PetscCall(PetscMalloc1(nB, &B));
108     switch (rank) {
109     case 0:
110       A[0] = 1;
111       A[1] = 0;
112       A[2] = 2;
113       B[0] = 0;
114       break;
115     case 1:
116       A[0] = 3;
117       B[0] = 2;
118       break;
119     case 2:
120       A[0] = 3;
121       B[0] = 0;
122       B[1] = 3;
123       break;
124     default:
125       SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
126     }
127     break;
128   case 1:
129     N = 4;
130     n = PETSC_DECIDE;
131     switch (rank) {
132     case 0:
133       nA      = 3;
134       offsetA = 100;
135       break;
136     case 1:
137       nA      = 1;
138       offsetA = 200;
139       break;
140     case 2:
141       nA      = 1;
142       offsetA = 300;
143       break;
144     default:
145       SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
146     }
147     PetscCall(PetscMalloc1(nA, &A));
148     switch (rank) {
149     case 0:
150       A[0] = 1;
151       A[1] = 0;
152       A[2] = 2;
153       break;
154     case 1:
155       A[0] = 3;
156       break;
157     case 2:
158       A[0] = 3;
159       break;
160     default:
161       SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
162     }
163     nB      = nA;
164     B       = A;
165     offsetB = offsetA;
166     break;
167   case 2:
168     N = 4;
169     n = PETSC_DECIDE;
170     switch (rank) {
171     case 0:
172       nA      = 2;
173       offsetA = 100;
174       nB      = 1;
175       offsetB = 400;
176       break;
177     case 1:
178       nA      = 1;
179       offsetA = 200;
180       nB      = 1;
181       offsetB = 500;
182       break;
183     case 2:
184       nA      = 1;
185       offsetA = 300;
186       nB      = 2;
187       offsetB = 600;
188       break;
189     default:
190       SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
191     }
192     PetscCall(PetscMalloc1(nA, &A));
193     PetscCall(PetscMalloc1(nB, &B));
194     switch (rank) {
195     case 0:
196       A[0] = 0;
197       A[1] = 2;
198       B[0] = 0;
199       break;
200     case 1:
201       A[0] = 3;
202       B[0] = 2;
203       break;
204     case 2:
205       A[0] = 3;
206       B[0] = 0;
207       B[1] = 3;
208       break;
209     default:
210       SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
211     }
212     break;
213   }
214   PetscCall(PetscLayoutCreate(PETSC_COMM_WORLD, &layout));
215   PetscCall(PetscLayoutSetSize(layout, N));
216   PetscCall(PetscLayoutSetLocalSize(layout, n));
217   PetscCall(PetscLayoutSetBlockSize(layout, 1));
218   PetscCall(PetscSFCreateByMatchingIndices(layout, nA, A, NULL, offsetA, nB, B, NULL, offsetB, NULL, &sf));
219   PetscCall(PetscLayoutDestroy(&layout));
220   PetscCall(PetscFree(A));
221   if (testnum != 1) PetscCall(PetscFree(B));
222   PetscCall(PetscObjectSetName((PetscObject)sf, "sf"));
223   PetscCall(PetscSFView(sf, NULL));
224   PetscCall(PetscSFDestroy(&sf));
225 
226   PetscCall(PetscFinalize());
227   return 0;
228 }
229 
230 /*TEST
231 
232   test:
233     suffix: 0
234     nsize: 3
235     args: -testnum 0
236 
237   test:
238     suffix: 1
239     nsize: 3
240     args: -testnum 1
241 
242   test:
243     suffix: 2
244     nsize: 3
245     args: -testnum 2
246 
247 TEST*/
248