1 static char help[] = "Test FEM layout and GlobalToNaturalSF\n\n";
2
3 /*
4 In order to see the vectors which are being tested, use
5
6 -ua_vec_view -s_vec_view
7 */
8
9 #include <petsc.h>
10 #include <exodusII.h>
11
12 #include <petsc/private/dmpleximpl.h>
13
main(int argc,char ** argv)14 int main(int argc, char **argv)
15 {
16 DM dm, pdm, dmU, dmA, dmS, dmUA, dmUA2, *dmList;
17 DM seqdmU, seqdmA, seqdmS, seqdmUA, seqdmUA2, *seqdmList;
18 Vec X, U, A, S, UA, UA2;
19 Vec seqX, seqU, seqA, seqS, seqUA, seqUA2;
20 IS isU, isA, isS, isUA;
21 IS seqisU, seqisA, seqisS, seqisUA;
22 PetscSection section;
23 const PetscInt fieldU = 0;
24 const PetscInt fieldA = 2;
25 const PetscInt fieldS = 1;
26 const PetscInt fieldUA[2] = {0, 2};
27 char ifilename[PETSC_MAX_PATH_LEN];
28 IS csIS;
29 const PetscInt *csID;
30 PetscInt *pStartDepth, *pEndDepth;
31 PetscInt order = 1;
32 PetscInt sdim, d, pStart, pEnd, p, numCS, set;
33 PetscMPIInt rank, size;
34 PetscSF migrationSF;
35
36 PetscCall(PetscInitialize(&argc, &argv, NULL, help));
37 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
38 PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
39 PetscOptionsBegin(PETSC_COMM_WORLD, NULL, "FEM Layout Options", "ex64");
40 PetscCall(PetscOptionsString("-i", "Filename to read", "ex64", ifilename, ifilename, sizeof(ifilename), NULL));
41 PetscOptionsEnd();
42
43 /* Read the mesh from a file in any supported format */
44 PetscCall(DMPlexCreateFromFile(PETSC_COMM_WORLD, ifilename, "ex64_plex", PETSC_TRUE, &dm));
45 PetscCall(DMPlexDistributeSetDefault(dm, PETSC_FALSE));
46 PetscCall(DMSetFromOptions(dm));
47 PetscCall(DMViewFromOptions(dm, NULL, "-dm_view"));
48 PetscCall(DMGetDimension(dm, &sdim));
49
50 /* Create the main section containing all fields */
51 PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion));
52 PetscCall(PetscSectionSetNumFields(section, 3));
53 PetscCall(PetscSectionSetFieldName(section, fieldU, "U"));
54 PetscCall(PetscSectionSetFieldName(section, fieldA, "Alpha"));
55 PetscCall(PetscSectionSetFieldName(section, fieldS, "Sigma"));
56 PetscCall(DMPlexGetChart(dm, &pStart, &pEnd));
57 PetscCall(PetscSectionSetChart(section, pStart, pEnd));
58 PetscCall(PetscMalloc2(sdim + 1, &pStartDepth, sdim + 1, &pEndDepth));
59 for (d = 0; d <= sdim; ++d) PetscCall(DMPlexGetDepthStratum(dm, d, &pStartDepth[d], &pEndDepth[d]));
60 /* Vector field U, Scalar field Alpha, Tensor field Sigma */
61 PetscCall(PetscSectionSetFieldComponents(section, fieldU, sdim));
62 PetscCall(PetscSectionSetFieldComponents(section, fieldA, 1));
63 PetscCall(PetscSectionSetFieldComponents(section, fieldS, sdim * (sdim + 1) / 2));
64
65 /* Going through cell sets then cells, and setting up storage for the sections */
66 PetscCall(DMGetLabelSize(dm, "Cell Sets", &numCS));
67 PetscCall(DMGetLabelIdIS(dm, "Cell Sets", &csIS));
68 if (csIS) PetscCall(ISGetIndices(csIS, &csID));
69 for (set = 0; set < numCS; set++) {
70 IS cellIS;
71 const PetscInt *cellID;
72 PetscInt numCells, cell, closureSize, *closureA = NULL;
73
74 PetscCall(DMGetStratumSize(dm, "Cell Sets", csID[set], &numCells));
75 PetscCall(DMGetStratumIS(dm, "Cell Sets", csID[set], &cellIS));
76 if (numCells > 0) {
77 /* dof layout ordered by increasing height in the DAG: cell, face, edge, vertex */
78 PetscInt dofUP1Tri[] = {2, 0, 0};
79 PetscInt dofAP1Tri[] = {1, 0, 0};
80 PetscInt dofUP2Tri[] = {2, 2, 0};
81 PetscInt dofAP2Tri[] = {1, 1, 0};
82 PetscInt dofUP1Quad[] = {2, 0, 0};
83 PetscInt dofAP1Quad[] = {1, 0, 0};
84 PetscInt dofUP2Quad[] = {2, 2, 2};
85 PetscInt dofAP2Quad[] = {1, 1, 1};
86 PetscInt dofS2D[] = {0, 0, 3};
87 PetscInt dofUP1Tet[] = {3, 0, 0, 0};
88 PetscInt dofAP1Tet[] = {1, 0, 0, 0};
89 PetscInt dofUP2Tet[] = {3, 3, 0, 0};
90 PetscInt dofAP2Tet[] = {1, 1, 0, 0};
91 PetscInt dofUP1Hex[] = {3, 0, 0, 0};
92 PetscInt dofAP1Hex[] = {1, 0, 0, 0};
93 PetscInt dofUP2Hex[] = {3, 3, 3, 3};
94 PetscInt dofAP2Hex[] = {1, 1, 1, 1};
95 PetscInt dofS3D[] = {0, 0, 0, 6};
96 PetscInt *dofU, *dofA, *dofS;
97
98 switch (sdim) {
99 case 2:
100 dofS = dofS2D;
101 break;
102 case 3:
103 dofS = dofS3D;
104 break;
105 default:
106 SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "No layout for dimension %" PetscInt_FMT, sdim);
107 }
108
109 /* Identify cell type based on closure size only. This works for Tri/Tet/Quad/Hex meshes
110 It will not be enough to identify more exotic elements like pyramid or prisms... */
111 PetscCall(ISGetIndices(cellIS, &cellID));
112 PetscCall(DMPlexGetTransitiveClosure(dm, cellID[0], PETSC_TRUE, &closureSize, &closureA));
113 switch (closureSize) {
114 case 7: /* Tri */
115 if (order == 1) {
116 dofU = dofUP1Tri;
117 dofA = dofAP1Tri;
118 } else {
119 dofU = dofUP2Tri;
120 dofA = dofAP2Tri;
121 }
122 break;
123 case 9: /* Quad */
124 if (order == 1) {
125 dofU = dofUP1Quad;
126 dofA = dofAP1Quad;
127 } else {
128 dofU = dofUP2Quad;
129 dofA = dofAP2Quad;
130 }
131 break;
132 case 15: /* Tet */
133 if (order == 1) {
134 dofU = dofUP1Tet;
135 dofA = dofAP1Tet;
136 } else {
137 dofU = dofUP2Tet;
138 dofA = dofAP2Tet;
139 }
140 break;
141 case 27: /* Hex */
142 if (order == 1) {
143 dofU = dofUP1Hex;
144 dofA = dofAP1Hex;
145 } else {
146 dofU = dofUP2Hex;
147 dofA = dofAP2Hex;
148 }
149 break;
150 default:
151 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Unknown element with closure size %" PetscInt_FMT, closureSize);
152 }
153 PetscCall(DMPlexRestoreTransitiveClosure(dm, cellID[0], PETSC_TRUE, &closureSize, &closureA));
154
155 for (cell = 0; cell < numCells; cell++) {
156 PetscInt *closure = NULL;
157
158 PetscCall(DMPlexGetTransitiveClosure(dm, cellID[cell], PETSC_TRUE, &closureSize, &closure));
159 for (p = 0; p < closureSize; ++p) {
160 /* Find depth of p */
161 for (d = 0; d <= sdim; ++d) {
162 if ((closure[2 * p] >= pStartDepth[d]) && (closure[2 * p] < pEndDepth[d])) {
163 PetscCall(PetscSectionSetDof(section, closure[2 * p], dofU[d] + dofA[d] + dofS[d]));
164 PetscCall(PetscSectionSetFieldDof(section, closure[2 * p], fieldU, dofU[d]));
165 PetscCall(PetscSectionSetFieldDof(section, closure[2 * p], fieldA, dofA[d]));
166 PetscCall(PetscSectionSetFieldDof(section, closure[2 * p], fieldS, dofS[d]));
167 }
168 }
169 }
170 PetscCall(DMPlexRestoreTransitiveClosure(dm, cellID[cell], PETSC_TRUE, &closureSize, &closure));
171 }
172 PetscCall(ISRestoreIndices(cellIS, &cellID));
173 PetscCall(ISDestroy(&cellIS));
174 }
175 }
176 if (csIS) PetscCall(ISRestoreIndices(csIS, &csID));
177 PetscCall(ISDestroy(&csIS));
178 PetscCall(PetscSectionSetUp(section));
179 PetscCall(DMSetLocalSection(dm, section));
180 PetscCall(PetscObjectViewFromOptions((PetscObject)section, NULL, "-dm_section_view"));
181 PetscCall(PetscSectionDestroy(§ion));
182
183 /* Get DM and IS for each field of dm */
184 PetscCall(DMCreateSubDM(dm, 1, &fieldU, &seqisU, &seqdmU));
185 PetscCall(DMCreateSubDM(dm, 1, &fieldA, &seqisA, &seqdmA));
186 PetscCall(DMCreateSubDM(dm, 1, &fieldS, &seqisS, &seqdmS));
187 PetscCall(DMCreateSubDM(dm, 2, fieldUA, &seqisUA, &seqdmUA));
188
189 PetscCall(PetscMalloc1(2, &seqdmList));
190 seqdmList[0] = seqdmU;
191 seqdmList[1] = seqdmA;
192
193 PetscCall(DMCreateSuperDM(seqdmList, 2, NULL, &seqdmUA2));
194 PetscCall(PetscFree(seqdmList));
195
196 PetscCall(DMGetGlobalVector(dm, &seqX));
197 PetscCall(DMGetGlobalVector(seqdmU, &seqU));
198 PetscCall(DMGetGlobalVector(seqdmA, &seqA));
199 PetscCall(DMGetGlobalVector(seqdmS, &seqS));
200 PetscCall(DMGetGlobalVector(seqdmUA, &seqUA));
201 PetscCall(DMGetGlobalVector(seqdmUA2, &seqUA2));
202
203 PetscCall(PetscObjectSetName((PetscObject)seqX, "seqX"));
204 PetscCall(PetscObjectSetName((PetscObject)seqU, "seqU"));
205 PetscCall(PetscObjectSetName((PetscObject)seqA, "seqAlpha"));
206 PetscCall(PetscObjectSetName((PetscObject)seqS, "seqSigma"));
207 PetscCall(PetscObjectSetName((PetscObject)seqUA, "seqUAlpha"));
208 PetscCall(PetscObjectSetName((PetscObject)seqUA2, "seqUAlpha2"));
209 PetscCall(VecSet(seqX, -111.));
210
211 /* Setting u to [x,y,z] and alpha to x^2+y^2+z^2 by writing in UAlpha then restricting to U and Alpha */
212 {
213 PetscSection sectionUA;
214 Vec UALoc;
215 PetscSection coordSection;
216 Vec coord;
217 PetscScalar *cval, *xyz;
218 PetscInt clSize, i, j;
219
220 PetscCall(DMGetLocalSection(seqdmUA, §ionUA));
221 PetscCall(DMGetLocalVector(seqdmUA, &UALoc));
222 PetscCall(VecGetArray(UALoc, &cval));
223 PetscCall(DMGetCoordinateSection(seqdmUA, &coordSection));
224 PetscCall(DMGetCoordinatesLocal(seqdmUA, &coord));
225 PetscCall(DMPlexGetChart(seqdmUA, &pStart, &pEnd));
226
227 for (p = pStart; p < pEnd; ++p) {
228 PetscInt dofUA, offUA;
229
230 PetscCall(PetscSectionGetDof(sectionUA, p, &dofUA));
231 if (dofUA > 0) {
232 xyz = NULL;
233 PetscCall(PetscSectionGetOffset(sectionUA, p, &offUA));
234 PetscCall(DMPlexVecGetClosure(seqdmUA, coordSection, coord, p, &clSize, &xyz));
235 cval[offUA + sdim] = 0.;
236 for (i = 0; i < sdim; ++i) {
237 cval[offUA + i] = 0;
238 for (j = 0; j < clSize / sdim; ++j) cval[offUA + i] += xyz[j * sdim + i];
239 cval[offUA + i] = cval[offUA + i] * sdim / clSize;
240 cval[offUA + sdim] += PetscSqr(cval[offUA + i]);
241 }
242 PetscCall(DMPlexVecRestoreClosure(seqdmUA, coordSection, coord, p, &clSize, &xyz));
243 }
244 }
245 PetscCall(VecRestoreArray(UALoc, &cval));
246 PetscCall(DMLocalToGlobalBegin(seqdmUA, UALoc, INSERT_VALUES, seqUA));
247 PetscCall(DMLocalToGlobalEnd(seqdmUA, UALoc, INSERT_VALUES, seqUA));
248 PetscCall(DMRestoreLocalVector(seqdmUA, &UALoc));
249
250 /* Update X */
251 PetscCall(VecISCopy(seqX, seqisUA, SCATTER_FORWARD, seqUA));
252 PetscCall(VecViewFromOptions(seqUA, NULL, "-ua_vec_view"));
253
254 /* Restrict to U and Alpha */
255 PetscCall(VecISCopy(seqX, seqisU, SCATTER_REVERSE, seqU));
256 PetscCall(VecISCopy(seqX, seqisA, SCATTER_REVERSE, seqA));
257
258 /* restrict to UA2 */
259 PetscCall(VecISCopy(seqX, seqisUA, SCATTER_REVERSE, seqUA2));
260 PetscCall(VecViewFromOptions(seqUA2, NULL, "-ua2_vec_view"));
261 }
262
263 {
264 PetscInt ovlp = 0;
265 PetscPartitioner part;
266
267 PetscCall(DMSetUseNatural(dm, PETSC_TRUE));
268 PetscCall(DMPlexGetPartitioner(dm, &part));
269 PetscCall(PetscPartitionerSetFromOptions(part));
270 PetscCall(DMPlexDistribute(dm, ovlp, &migrationSF, &pdm));
271 if (!pdm) pdm = dm;
272 if (migrationSF) {
273 PetscCall(DMPlexSetMigrationSF(pdm, migrationSF));
274 PetscCall(PetscSFDestroy(&migrationSF));
275 }
276 PetscCall(DMViewFromOptions(pdm, NULL, "-dm_view"));
277 }
278
279 /* Get DM and IS for each field of dm */
280 PetscCall(DMCreateSubDM(pdm, 1, &fieldU, &isU, &dmU));
281 PetscCall(DMCreateSubDM(pdm, 1, &fieldA, &isA, &dmA));
282 PetscCall(DMCreateSubDM(pdm, 1, &fieldS, &isS, &dmS));
283 PetscCall(DMCreateSubDM(pdm, 2, fieldUA, &isUA, &dmUA));
284
285 PetscCall(PetscMalloc1(2, &dmList));
286 dmList[0] = dmU;
287 dmList[1] = dmA;
288
289 PetscCall(DMCreateSuperDM(dmList, 2, NULL, &dmUA2));
290 PetscCall(PetscFree(dmList));
291
292 PetscCall(DMGetGlobalVector(pdm, &X));
293 PetscCall(DMGetGlobalVector(dmU, &U));
294 PetscCall(DMGetGlobalVector(dmA, &A));
295 PetscCall(DMGetGlobalVector(dmS, &S));
296 PetscCall(DMGetGlobalVector(dmUA, &UA));
297 PetscCall(DMGetGlobalVector(dmUA2, &UA2));
298
299 PetscCall(PetscObjectSetName((PetscObject)X, "X"));
300 PetscCall(PetscObjectSetName((PetscObject)U, "U"));
301 PetscCall(PetscObjectSetName((PetscObject)A, "Alpha"));
302 PetscCall(PetscObjectSetName((PetscObject)S, "Sigma"));
303 PetscCall(PetscObjectSetName((PetscObject)UA, "UAlpha"));
304 PetscCall(PetscObjectSetName((PetscObject)UA2, "UAlpha2"));
305 PetscCall(VecSet(X, -111.));
306
307 /* Setting u to [x,y,z] and alpha to x^2+y^2+z^2 by writing in UAlpha then restricting to U and Alpha */
308 {
309 PetscSection sectionUA;
310 Vec UALoc;
311 PetscSection coordSection;
312 Vec coord;
313 PetscScalar *cval, *xyz;
314 PetscInt clSize, i, j;
315
316 PetscCall(DMGetLocalSection(dmUA, §ionUA));
317 PetscCall(DMGetLocalVector(dmUA, &UALoc));
318 PetscCall(VecGetArray(UALoc, &cval));
319 PetscCall(DMGetCoordinateSection(dmUA, &coordSection));
320 PetscCall(DMGetCoordinatesLocal(dmUA, &coord));
321 PetscCall(DMPlexGetChart(dmUA, &pStart, &pEnd));
322
323 for (p = pStart; p < pEnd; ++p) {
324 PetscInt dofUA, offUA;
325
326 PetscCall(PetscSectionGetDof(sectionUA, p, &dofUA));
327 if (dofUA > 0) {
328 xyz = NULL;
329 PetscCall(PetscSectionGetOffset(sectionUA, p, &offUA));
330 PetscCall(DMPlexVecGetClosure(dmUA, coordSection, coord, p, &clSize, &xyz));
331 cval[offUA + sdim] = 0.;
332 for (i = 0; i < sdim; ++i) {
333 cval[offUA + i] = 0;
334 for (j = 0; j < clSize / sdim; ++j) cval[offUA + i] += xyz[j * sdim + i];
335 cval[offUA + i] = cval[offUA + i] * sdim / clSize;
336 cval[offUA + sdim] += PetscSqr(cval[offUA + i]);
337 }
338 PetscCall(DMPlexVecRestoreClosure(dmUA, coordSection, coord, p, &clSize, &xyz));
339 }
340 }
341 PetscCall(VecRestoreArray(UALoc, &cval));
342 PetscCall(DMLocalToGlobalBegin(dmUA, UALoc, INSERT_VALUES, UA));
343 PetscCall(DMLocalToGlobalEnd(dmUA, UALoc, INSERT_VALUES, UA));
344 PetscCall(DMRestoreLocalVector(dmUA, &UALoc));
345
346 /* Update X */
347 PetscCall(VecISCopy(X, isUA, SCATTER_FORWARD, UA));
348 PetscCall(VecViewFromOptions(UA, NULL, "-ua_vec_view"));
349
350 /* Restrict to U and Alpha */
351 PetscCall(VecISCopy(X, isU, SCATTER_REVERSE, U));
352 PetscCall(VecISCopy(X, isA, SCATTER_REVERSE, A));
353
354 /* restrict to UA2 */
355 PetscCall(VecISCopy(X, isUA, SCATTER_REVERSE, UA2));
356 PetscCall(VecViewFromOptions(UA2, NULL, "-ua2_vec_view"));
357 }
358
359 /* Verification */
360
361 Vec Xnat, Unat, Anat, UAnat, Snat, UA2nat;
362 PetscReal norm;
363 PetscCall(DMGetGlobalVector(dm, &Xnat));
364 PetscCall(DMGetGlobalVector(seqdmU, &Unat));
365 PetscCall(DMGetGlobalVector(seqdmA, &Anat));
366 PetscCall(DMGetGlobalVector(seqdmUA, &UAnat));
367 PetscCall(DMGetGlobalVector(seqdmS, &Snat));
368 PetscCall(DMGetGlobalVector(seqdmUA2, &UA2nat));
369
370 PetscCall(DMPlexGlobalToNaturalBegin(pdm, X, Xnat));
371 PetscCall(DMPlexGlobalToNaturalEnd(pdm, X, Xnat));
372 PetscCall(VecAXPY(Xnat, -1.0, seqX));
373 PetscCall(VecNorm(Xnat, NORM_INFINITY, &norm));
374 PetscCheck(norm <= PETSC_SQRT_MACHINE_EPSILON, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "X ||Vin - Vout|| = %g", (double)norm);
375
376 PetscCall(DMPlexGlobalToNaturalBegin(dmU, U, Unat));
377 PetscCall(DMPlexGlobalToNaturalEnd(dmU, U, Unat));
378 PetscCall(VecAXPY(Unat, -1.0, seqU));
379 PetscCall(VecNorm(Unat, NORM_INFINITY, &norm));
380 PetscCheck(norm <= PETSC_SQRT_MACHINE_EPSILON, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "U ||Vin - Vout|| = %g", (double)norm);
381
382 PetscCall(DMPlexGlobalToNaturalBegin(dmA, A, Anat));
383 PetscCall(DMPlexGlobalToNaturalEnd(dmA, A, Anat));
384 PetscCall(VecAXPY(Anat, -1.0, seqA));
385 PetscCall(VecNorm(Anat, NORM_INFINITY, &norm));
386 PetscCheck(norm <= PETSC_SQRT_MACHINE_EPSILON, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "A ||Vin - Vout|| = %g", (double)norm);
387
388 PetscCall(DMPlexGlobalToNaturalBegin(dmUA, UA, UAnat));
389 PetscCall(DMPlexGlobalToNaturalEnd(dmUA, UA, UAnat));
390 PetscCall(VecAXPY(UAnat, -1.0, seqUA));
391 PetscCall(VecNorm(UAnat, NORM_INFINITY, &norm));
392 PetscCheck(norm <= PETSC_SQRT_MACHINE_EPSILON, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "UA ||Vin - Vout|| = %g", (double)norm);
393
394 PetscCall(DMPlexGlobalToNaturalBegin(dmS, S, Snat));
395 PetscCall(DMPlexGlobalToNaturalEnd(dmS, S, Snat));
396 PetscCall(VecAXPY(Snat, -1.0, seqS));
397 PetscCall(VecNorm(Snat, NORM_INFINITY, &norm));
398 PetscCheck(norm <= PETSC_SQRT_MACHINE_EPSILON, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "S ||Vin - Vout|| = %g", (double)norm);
399
400 PetscCall(DMPlexGlobalToNaturalBegin(dmUA2, UA2, UA2nat));
401 PetscCall(DMPlexGlobalToNaturalEnd(dmUA2, UA2, UA2nat));
402 PetscCall(VecAXPY(UA2nat, -1.0, seqUA2));
403 PetscCall(VecNorm(UA2nat, NORM_INFINITY, &norm));
404 PetscCheck(norm <= PETSC_SQRT_MACHINE_EPSILON, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "UAlpha2 ||Vin - Vout|| = %g", (double)norm);
405
406 PetscCall(DMRestoreGlobalVector(dm, &Xnat));
407 PetscCall(DMRestoreGlobalVector(seqdmU, &Unat));
408 PetscCall(DMRestoreGlobalVector(seqdmA, &Anat));
409 PetscCall(DMRestoreGlobalVector(seqdmUA, &UAnat));
410 PetscCall(DMRestoreGlobalVector(seqdmS, &Snat));
411 PetscCall(DMRestoreGlobalVector(seqdmUA2, &UA2nat));
412
413 PetscCall(DMRestoreGlobalVector(seqdmUA2, &seqUA2));
414 PetscCall(DMRestoreGlobalVector(seqdmUA, &seqUA));
415 PetscCall(DMRestoreGlobalVector(seqdmS, &seqS));
416 PetscCall(DMRestoreGlobalVector(seqdmA, &seqA));
417 PetscCall(DMRestoreGlobalVector(seqdmU, &seqU));
418 PetscCall(DMRestoreGlobalVector(dm, &seqX));
419 PetscCall(DMDestroy(&seqdmU));
420 PetscCall(ISDestroy(&seqisU));
421 PetscCall(DMDestroy(&seqdmA));
422 PetscCall(ISDestroy(&seqisA));
423 PetscCall(DMDestroy(&seqdmS));
424 PetscCall(ISDestroy(&seqisS));
425 PetscCall(DMDestroy(&seqdmUA));
426 PetscCall(ISDestroy(&seqisUA));
427 PetscCall(DMDestroy(&seqdmUA2));
428
429 PetscCall(DMRestoreGlobalVector(dmUA2, &UA2));
430 PetscCall(DMRestoreGlobalVector(dmUA, &UA));
431 PetscCall(DMRestoreGlobalVector(dmS, &S));
432 PetscCall(DMRestoreGlobalVector(dmA, &A));
433 PetscCall(DMRestoreGlobalVector(dmU, &U));
434 PetscCall(DMRestoreGlobalVector(pdm, &X));
435 PetscCall(DMDestroy(&dmU));
436 PetscCall(ISDestroy(&isU));
437 PetscCall(DMDestroy(&dmA));
438 PetscCall(ISDestroy(&isA));
439 PetscCall(DMDestroy(&dmS));
440 PetscCall(ISDestroy(&isS));
441 PetscCall(DMDestroy(&dmUA));
442 PetscCall(ISDestroy(&isUA));
443 PetscCall(DMDestroy(&dmUA2));
444 PetscCall(DMDestroy(&pdm));
445 if (size > 1) PetscCall(DMDestroy(&dm));
446 PetscCall(PetscFree2(pStartDepth, pEndDepth));
447 PetscCall(PetscFinalize());
448 return 0;
449 }
450
451 /*TEST
452
453 build:
454 requires: !complex parmetis exodusii pnetcdf
455 # 2D seq
456 test:
457 suffix: 0
458 args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourSquareT-large.exo -dm_view -petscpartitioner_type parmetis
459 test:
460 suffix: 1
461 args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourSquareQ-large.exo -dm_view -petscpartitioner_type parmetis
462 test:
463 suffix: 2
464 args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourSquareH-large.exo -dm_view -petscpartitioner_type parmetis
465
466 # 2D par
467 test:
468 suffix: 3
469 nsize: 2
470 args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourSquareT-large.exo -dm_view -petscpartitioner_type parmetis
471 test:
472 suffix: 4
473 nsize: 2
474 args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourSquareQ-large.exo -dm_view -petscpartitioner_type parmetis
475 test:
476 suffix: 5
477 nsize: 2
478 args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourSquareH-large.exo -dm_view -petscpartitioner_type parmetis
479
480 #3d seq
481 test:
482 suffix: 6
483 args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourBrickHex-large.exo -dm_view -petscpartitioner_type parmetis
484 test:
485 suffix: 7
486 args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourBrickTet-large.exo -dm_view -petscpartitioner_type parmetis
487
488 #3d par
489 test:
490 suffix: 8
491 nsize: 2
492 args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourBrickHex-large.exo -dm_view -petscpartitioner_type parmetis
493 test:
494 suffix: 9
495 nsize: 2
496 args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/FourBrickTet-large.exo -dm_view -petscpartitioner_type parmetis
497
498 TEST*/
499