Actual source code: dagetelem.c

  1: #include <petsc/private/dmdaimpl.h>

  3: static PetscErrorCode DMDAGetElements_1D(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[])
  4: {
  5:   DM_DA   *da = (DM_DA *)dm->data;
  6:   PetscInt i, xs, xe, Xs, Xe;
  7:   PetscInt cnt = 0;

  9:   PetscFunctionBegin;
 10:   if (!da->e) {
 11:     PetscInt corners[2];

 13:     PetscCheck(da->s, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Cannot get elements for DMDA with zero stencil width");
 14:     PetscCall(DMDAGetCorners(dm, &xs, NULL, NULL, &xe, NULL, NULL));
 15:     PetscCall(DMDAGetGhostCorners(dm, &Xs, NULL, NULL, &Xe, NULL, NULL));
 16:     xe += xs;
 17:     Xe += Xs;
 18:     if (xs != Xs) xs -= 1;
 19:     da->ne = 1 * (xe - xs - 1);
 20:     PetscCall(PetscMalloc1(1 + 2 * da->ne, &da->e));
 21:     for (i = xs; i < xe - 1; i++) {
 22:       da->e[cnt++] = (i - Xs);
 23:       da->e[cnt++] = (i - Xs + 1);
 24:     }
 25:     da->nen = 2;

 27:     corners[0] = (xs - Xs);
 28:     corners[1] = (xe - 1 - Xs);
 29:     PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 2, corners, PETSC_COPY_VALUES, &da->ecorners));
 30:   }
 31:   *nel = da->ne;
 32:   *nen = da->nen;
 33:   *e   = da->e;
 34:   PetscFunctionReturn(PETSC_SUCCESS);
 35: }

 37: static PetscErrorCode DMDAGetElements_2D(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[])
 38: {
 39:   DM_DA   *da = (DM_DA *)dm->data;
 40:   PetscInt i, xs, xe, Xs, Xe;
 41:   PetscInt j, ys, ye, Ys, Ye;
 42:   PetscInt cnt = 0, cell[4], ns = 2;
 43:   PetscInt c, split[] = {0, 1, 3, 2, 3, 1};

 45:   PetscFunctionBegin;
 46:   if (!da->e) {
 47:     PetscInt corners[4], nn = 0;

 49:     PetscCheck(da->s, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Cannot get elements for DMDA with zero stencil width");

 51:     switch (da->elementtype) {
 52:     case DMDA_ELEMENT_Q1:
 53:       da->nen = 4;
 54:       break;
 55:     case DMDA_ELEMENT_P1:
 56:       da->nen = 3;
 57:       break;
 58:     default:
 59:       SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unknown element type %d", da->elementtype);
 60:     }
 61:     nn = da->nen;

 63:     if (da->elementtype == DMDA_ELEMENT_P1) ns = 2;
 64:     if (da->elementtype == DMDA_ELEMENT_Q1) ns = 1;
 65:     PetscCall(DMDAGetCorners(dm, &xs, &ys, NULL, &xe, &ye, NULL));
 66:     PetscCall(DMDAGetGhostCorners(dm, &Xs, &Ys, NULL, &Xe, &Ye, NULL));
 67:     xe += xs;
 68:     Xe += Xs;
 69:     if (xs != Xs) xs -= 1;
 70:     ye += ys;
 71:     Ye += Ys;
 72:     if (ys != Ys) ys -= 1;
 73:     da->ne = ns * (xe - xs - 1) * (ye - ys - 1);
 74:     PetscCall(PetscMalloc1(1 + nn * da->ne, &da->e));
 75:     for (j = ys; j < ye - 1; j++) {
 76:       for (i = xs; i < xe - 1; i++) {
 77:         cell[0] = (i - Xs) + (j - Ys) * (Xe - Xs);
 78:         cell[1] = (i - Xs + 1) + (j - Ys) * (Xe - Xs);
 79:         cell[2] = (i - Xs + 1) + (j - Ys + 1) * (Xe - Xs);
 80:         cell[3] = (i - Xs) + (j - Ys + 1) * (Xe - Xs);
 81:         if (da->elementtype == DMDA_ELEMENT_P1) {
 82:           for (c = 0; c < ns * nn; c++) da->e[cnt++] = cell[split[c]];
 83:         }
 84:         if (da->elementtype == DMDA_ELEMENT_Q1) {
 85:           for (c = 0; c < ns * nn; c++) da->e[cnt++] = cell[c];
 86:         }
 87:       }
 88:     }

 90:     corners[0] = (xs - Xs) + (ys - Ys) * (Xe - Xs);
 91:     corners[1] = (xe - 1 - Xs) + (ys - Ys) * (Xe - Xs);
 92:     corners[2] = (xs - Xs) + (ye - 1 - Ys) * (Xe - Xs);
 93:     corners[3] = (xe - 1 - Xs) + (ye - 1 - Ys) * (Xe - Xs);
 94:     PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 4, corners, PETSC_COPY_VALUES, &da->ecorners));
 95:   }
 96:   *nel = da->ne;
 97:   *nen = da->nen;
 98:   *e   = da->e;
 99:   PetscFunctionReturn(PETSC_SUCCESS);
100: }

102: static PetscErrorCode DMDAGetElements_3D(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[])
103: {
104:   DM_DA   *da = (DM_DA *)dm->data;
105:   PetscInt i, xs, xe, Xs, Xe;
106:   PetscInt j, ys, ye, Ys, Ye;
107:   PetscInt k, zs, ze, Zs, Ze;
108:   PetscInt cnt = 0, cell[8], ns = 6;
109:   PetscInt c, split[] = {0, 1, 3, 7, 0, 1, 7, 4, 1, 2, 3, 7, 1, 2, 7, 6, 1, 4, 5, 7, 1, 5, 6, 7};

111:   PetscFunctionBegin;
112:   if (!da->e) {
113:     PetscInt corners[8], nn = 0;

115:     PetscCheck(da->s, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Cannot get elements for DMDA with zero stencil width");

117:     switch (da->elementtype) {
118:     case DMDA_ELEMENT_Q1:
119:       da->nen = 8;
120:       break;
121:     case DMDA_ELEMENT_P1:
122:       da->nen = 4;
123:       break;
124:     default:
125:       SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unknown element type %d", da->elementtype);
126:     }
127:     nn = da->nen;

129:     if (da->elementtype == DMDA_ELEMENT_P1) ns = 6;
130:     if (da->elementtype == DMDA_ELEMENT_Q1) ns = 1;
131:     PetscCall(DMDAGetCorners(dm, &xs, &ys, &zs, &xe, &ye, &ze));
132:     PetscCall(DMDAGetGhostCorners(dm, &Xs, &Ys, &Zs, &Xe, &Ye, &Ze));
133:     xe += xs;
134:     Xe += Xs;
135:     if (xs != Xs) xs -= 1;
136:     ye += ys;
137:     Ye += Ys;
138:     if (ys != Ys) ys -= 1;
139:     ze += zs;
140:     Ze += Zs;
141:     if (zs != Zs) zs -= 1;
142:     da->ne = ns * (xe - xs - 1) * (ye - ys - 1) * (ze - zs - 1);
143:     PetscCall(PetscMalloc1(1 + nn * da->ne, &da->e));
144:     for (k = zs; k < ze - 1; k++) {
145:       for (j = ys; j < ye - 1; j++) {
146:         for (i = xs; i < xe - 1; i++) {
147:           cell[0] = (i - Xs) + (j - Ys) * (Xe - Xs) + (k - Zs) * (Xe - Xs) * (Ye - Ys);
148:           cell[1] = (i + 1 - Xs) + (j - Ys) * (Xe - Xs) + (k - Zs) * (Xe - Xs) * (Ye - Ys);
149:           cell[2] = (i + 1 - Xs) + (j + 1 - Ys) * (Xe - Xs) + (k - Zs) * (Xe - Xs) * (Ye - Ys);
150:           cell[3] = (i - Xs) + (j + 1 - Ys) * (Xe - Xs) + (k - Zs) * (Xe - Xs) * (Ye - Ys);
151:           cell[4] = (i - Xs) + (j - Ys) * (Xe - Xs) + (k + 1 - Zs) * (Xe - Xs) * (Ye - Ys);
152:           cell[5] = (i + 1 - Xs) + (j - Ys) * (Xe - Xs) + (k + 1 - Zs) * (Xe - Xs) * (Ye - Ys);
153:           cell[6] = (i + 1 - Xs) + (j + 1 - Ys) * (Xe - Xs) + (k + 1 - Zs) * (Xe - Xs) * (Ye - Ys);
154:           cell[7] = (i - Xs) + (j + 1 - Ys) * (Xe - Xs) + (k + 1 - Zs) * (Xe - Xs) * (Ye - Ys);
155:           if (da->elementtype == DMDA_ELEMENT_P1) {
156:             for (c = 0; c < ns * nn; c++) da->e[cnt++] = cell[split[c]];
157:           }
158:           if (da->elementtype == DMDA_ELEMENT_Q1) {
159:             for (c = 0; c < ns * nn; c++) da->e[cnt++] = cell[c];
160:           }
161:         }
162:       }
163:     }

165:     corners[0] = (xs - Xs) + (ys - Ys) * (Xe - Xs) + (zs - Zs) * (Xe - Xs) * (Ye - Ys);
166:     corners[1] = (xe - 1 - Xs) + (ys - Ys) * (Xe - Xs) + (zs - Zs) * (Xe - Xs) * (Ye - Ys);
167:     corners[2] = (xs - Xs) + (ye - 1 - Ys) * (Xe - Xs) + (zs - Zs) * (Xe - Xs) * (Ye - Ys);
168:     corners[3] = (xe - 1 - Xs) + (ye - 1 - Ys) * (Xe - Xs) + (zs - Zs) * (Xe - Xs) * (Ye - Ys);
169:     corners[4] = (xs - Xs) + (ys - Ys) * (Xe - Xs) + (ze - 1 - Zs) * (Xe - Xs) * (Ye - Ys);
170:     corners[5] = (xe - 1 - Xs) + (ys - Ys) * (Xe - Xs) + (ze - 1 - Zs) * (Xe - Xs) * (Ye - Ys);
171:     corners[6] = (xs - Xs) + (ye - 1 - Ys) * (Xe - Xs) + (ze - 1 - Zs) * (Xe - Xs) * (Ye - Ys);
172:     corners[7] = (xe - 1 - Xs) + (ye - 1 - Ys) * (Xe - Xs) + (ze - 1 - Zs) * (Xe - Xs) * (Ye - Ys);
173:     PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 8, corners, PETSC_COPY_VALUES, &da->ecorners));
174:   }
175:   *nel = da->ne;
176:   *nen = da->nen;
177:   *e   = da->e;
178:   PetscFunctionReturn(PETSC_SUCCESS);
179: }

181: /*@
182:   DMDAGetElementsCorners - Returns the global (x,y,z) indices of the lower left
183:   corner of the non-overlapping decomposition identified by `DMDAGetElements()`

185:   Not Collective

187:   Input Parameter:
188: . da - the `DMDA` object

190:   Output Parameters:
191: + gx - the x index
192: . gy - the y index
193: - gz - the z index

195:   Level: intermediate

197: .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements()`, `DMDAGetCorners()`, `DMDAGetGhostCorners()`, `DMDAGetElementsSizes()`,
198:           `DMDAGetElementsCornersIS()`, `DMDARestoreElementsCornersIS()`
199: @*/
200: PetscErrorCode DMDAGetElementsCorners(DM da, PetscInt *gx, PetscInt *gy, PetscInt *gz)
201: {
202:   PetscInt  xs, Xs;
203:   PetscInt  ys, Ys;
204:   PetscInt  zs, Zs;
205:   PetscBool isda;

207:   PetscFunctionBegin;
209:   if (gx) PetscAssertPointer(gx, 2);
210:   if (gy) PetscAssertPointer(gy, 3);
211:   if (gz) PetscAssertPointer(gz, 4);
212:   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isda));
213:   PetscCheck(isda, PetscObjectComm((PetscObject)da), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)da)->type_name);
214:   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, NULL, NULL, NULL));
215:   PetscCall(DMDAGetGhostCorners(da, &Xs, &Ys, &Zs, NULL, NULL, NULL));
216:   if (xs != Xs) xs -= 1;
217:   if (ys != Ys) ys -= 1;
218:   if (zs != Zs) zs -= 1;
219:   if (gx) *gx = xs;
220:   if (gy) *gy = ys;
221:   if (gz) *gz = zs;
222:   PetscFunctionReturn(PETSC_SUCCESS);
223: }

225: /*@
226:   DMDAGetElementsSizes - Gets the local number of elements per coordinate direction for the non-overlapping decomposition identified by `DMDAGetElements()`

228:   Not Collective

230:   Input Parameter:
231: . da - the `DMDA` object

233:   Output Parameters:
234: + mx - number of local elements in x-direction
235: . my - number of local elements in y-direction
236: - mz - number of local elements in z-direction

238:   Level: intermediate

240:   Note:
241:   It returns the same number of elements, irrespective of the `DMDAElementType`

243: .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements()`, `DMDAGetElementsCorners()`
244: @*/
245: PetscErrorCode DMDAGetElementsSizes(DM da, PetscInt *mx, PetscInt *my, PetscInt *mz)
246: {
247:   PetscInt  xs, xe, Xs;
248:   PetscInt  ys, ye, Ys;
249:   PetscInt  zs, ze, Zs;
250:   PetscInt  dim;
251:   PetscBool isda;

253:   PetscFunctionBegin;
255:   if (mx) PetscAssertPointer(mx, 2);
256:   if (my) PetscAssertPointer(my, 3);
257:   if (mz) PetscAssertPointer(mz, 4);
258:   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isda));
259:   PetscCheck(isda, PetscObjectComm((PetscObject)da), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)da)->type_name);
260:   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xe, &ye, &ze));
261:   PetscCall(DMDAGetGhostCorners(da, &Xs, &Ys, &Zs, NULL, NULL, NULL));
262:   xe += xs;
263:   if (xs != Xs) xs -= 1;
264:   ye += ys;
265:   if (ys != Ys) ys -= 1;
266:   ze += zs;
267:   if (zs != Zs) zs -= 1;
268:   if (mx) *mx = 0;
269:   if (my) *my = 0;
270:   if (mz) *mz = 0;
271:   PetscCall(DMGetDimension(da, &dim));
272:   switch (dim) {
273:   case 3:
274:     if (mz) *mz = ze - zs - 1; /* fall through */
275:   case 2:
276:     if (my) *my = ye - ys - 1; /* fall through */
277:   case 1:
278:     if (mx) *mx = xe - xs - 1;
279:     break;
280:   }
281:   PetscFunctionReturn(PETSC_SUCCESS);
282: }

284: /*@
285:   DMDASetElementType - Sets the element type to be returned by `DMDAGetElements()`

287:   Not Collective

289:   Input Parameter:
290: . da - the `DMDA` object

292:   Output Parameter:
293: . etype - the element type, currently either `DMDA_ELEMENT_P1` or `DMDA_ELEMENT_Q1`

295:   Level: intermediate

297: .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAElementType`, `DMDAGetElementType()`, `DMDAGetElements()`, `DMDARestoreElements()`,
298:           `DMDA_ELEMENT_P1`, `DMDA_ELEMENT_Q1`
299: @*/
300: PetscErrorCode DMDASetElementType(DM da, DMDAElementType etype)
301: {
302:   DM_DA    *dd = (DM_DA *)da->data;
303:   PetscBool isda;

305:   PetscFunctionBegin;
308:   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isda));
309:   if (!isda) PetscFunctionReturn(PETSC_SUCCESS);
310:   if (dd->elementtype != etype) {
311:     PetscCall(PetscFree(dd->e));
312:     PetscCall(ISDestroy(&dd->ecorners));

314:     dd->elementtype = etype;
315:     dd->ne          = 0;
316:     dd->nen         = 0;
317:     dd->e           = NULL;
318:   }
319:   PetscFunctionReturn(PETSC_SUCCESS);
320: }

322: /*@
323:   DMDAGetElementType - Gets the element type to be returned by `DMDAGetElements()`

325:   Not Collective

327:   Input Parameter:
328: . da - the `DMDA` object

330:   Output Parameter:
331: . etype - the element type, currently either `DMDA_ELEMENT_P1` or `DMDA_ELEMENT_Q1`

333:   Level: intermediate

335: .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements()`, `DMDARestoreElements()`,
336:           `DMDA_ELEMENT_P1`, `DMDA_ELEMENT_Q1`
337: @*/
338: PetscErrorCode DMDAGetElementType(DM da, DMDAElementType *etype)
339: {
340:   DM_DA    *dd = (DM_DA *)da->data;
341:   PetscBool isda;

343:   PetscFunctionBegin;
345:   PetscAssertPointer(etype, 2);
346:   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isda));
347:   PetscCheck(isda, PetscObjectComm((PetscObject)da), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)da)->type_name);
348:   *etype = dd->elementtype;
349:   PetscFunctionReturn(PETSC_SUCCESS);
350: }

352: /*@C
353:   DMDAGetElements - Gets an array containing the indices (in local coordinates)
354:   of all the local elements

356:   Not Collective

358:   Input Parameter:
359: . dm - the `DMDA` object

361:   Output Parameters:
362: + nel - number of local elements
363: . nen - number of nodes in each element (for example in one dimension it is 2, in two dimensions it is 3 (for `DMDA_ELEMENT_P1`) and 4
364:         (for `DMDA_ELEMENT_Q1`)
365: - e   - the local indices of the elements' vertices

367:   Level: intermediate

369:   Notes:
370:   Call `DMDARestoreElements()` once you have finished accessing the elements.

372:   Each process uniquely owns a subset of the elements. That is no element is owned by two or more processes.

374:   If on each process you integrate over its owned elements and use `ADD_VALUES` in `Vec`/`MatSetValuesLocal()` then you'll obtain the correct result.

376:   Fortran Note:
377:   Use
378: .vb
379:    PetscScalar, pointer :: e(:)
380: .ve
381:   to declare the element array

383: .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAElementType`, `DMDASetElementType()`, `VecSetValuesLocal()`, `MatSetValuesLocal()`,
384:           `DMGlobalToLocalBegin()`, `DMLocalToGlobalBegin()`, `DMDARestoreElements()`, `DMDA_ELEMENT_P1`, `DMDA_ELEMENT_Q1`, `DMDAGetElementsSizes()`,
385:           `DMDAGetElementsCorners()`
386: @*/
387: PetscErrorCode DMDAGetElements(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[])
388: {
389:   PetscInt  dim;
390:   DM_DA    *dd = (DM_DA *)dm->data;
391:   PetscBool isda;

393:   PetscFunctionBegin;
395:   PetscAssertPointer(nel, 2);
396:   PetscAssertPointer(nen, 3);
397:   PetscAssertPointer(e, 4);
398:   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMDA, &isda));
399:   PetscCheck(isda, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)dm)->type_name);
400:   PetscCheck(dd->stencil_type != DMDA_STENCIL_STAR, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DMDAGetElements() requires you use a stencil type of DMDA_STENCIL_BOX");
401:   PetscCall(DMGetDimension(dm, &dim));
402:   if (dd->e) {
403:     *nel = dd->ne;
404:     *nen = dd->nen;
405:     *e   = dd->e;
406:     PetscFunctionReturn(PETSC_SUCCESS);
407:   }
408:   if (dim == -1) {
409:     *nel = 0;
410:     *nen = 0;
411:     *e   = NULL;
412:   } else if (dim == 1) {
413:     PetscCall(DMDAGetElements_1D(dm, nel, nen, e));
414:   } else if (dim == 2) {
415:     PetscCall(DMDAGetElements_2D(dm, nel, nen, e));
416:   } else if (dim == 3) {
417:     PetscCall(DMDAGetElements_3D(dm, nel, nen, e));
418:   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
419:   PetscFunctionReturn(PETSC_SUCCESS);
420: }

422: /*@
423:   DMDAGetSubdomainCornersIS - Gets an index set containing the corner indices (in local coordinates)
424:   of the non-overlapping decomposition identified by `DMDAGetElements()`

426:   Not Collective

428:   Input Parameter:
429: . dm - the `DMDA` object

431:   Output Parameter:
432: . is - the index set

434:   Level: intermediate

436:   Note:
437:   Call `DMDARestoreSubdomainCornersIS()` once you have finished accessing the index set.

439: .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements()`, `DMDARestoreElementsCornersIS()`,
440:           `DMDAGetElementsSizes()`, `DMDAGetElementsCorners()`
441: @*/
442: PetscErrorCode DMDAGetSubdomainCornersIS(DM dm, IS *is)
443: {
444:   DM_DA    *dd = (DM_DA *)dm->data;
445:   PetscBool isda;

447:   PetscFunctionBegin;
449:   PetscAssertPointer(is, 2);
450:   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMDA, &isda));
451:   PetscCheck(isda, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for DM type %s", ((PetscObject)dm)->type_name);
452:   PetscCheck(dd->stencil_type != DMDA_STENCIL_STAR, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DMDAGetElement() requires you use a stencil type of DMDA_STENCIL_BOX");
453:   if (!dd->ecorners) { /* compute elements if not yet done */
454:     const PetscInt *e;
455:     PetscInt        nel, nen;

457:     PetscCall(DMDAGetElements(dm, &nel, &nen, &e));
458:     PetscCall(DMDARestoreElements(dm, &nel, &nen, &e));
459:   }
460:   *is = dd->ecorners;
461:   PetscFunctionReturn(PETSC_SUCCESS);
462: }

464: /*@C
465:   DMDARestoreElements - Restores the array obtained with `DMDAGetElements()`

467:   Not Collective

469:   Input Parameters:
470: + dm  - the `DM` object
471: . nel - number of local elements
472: . nen - number of nodes in each element
473: - e   - the local indices of the elements' vertices

475:   Level: intermediate

477:   Note:
478:   This restore signals the `DMDA` object that you no longer need access to the array information.

480: .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAElementType`, `DMDASetElementType()`, `DMDAGetElements()`
481: @*/
482: PetscErrorCode DMDARestoreElements(DM dm, PetscInt *nel, PetscInt *nen, const PetscInt *e[])
483: {
484:   PetscFunctionBegin;
486:   PetscAssertPointer(nel, 2);
487:   PetscAssertPointer(nen, 3);
488:   PetscAssertPointer(e, 4);
489:   if (nel) *nel = 0;
490:   if (nen) *nen = -1;
491:   if (e) *e = NULL;
492:   PetscFunctionReturn(PETSC_SUCCESS);
493: }

495: /*@
496:   DMDARestoreSubdomainCornersIS - Restores the `IS` obtained with `DMDAGetSubdomainCornersIS()`

498:   Not Collective

500:   Input Parameters:
501: + dm - the `DM` object
502: - is - the index set

504:   Level: intermediate

506: .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAElementType`, `DMDASetElementType()`, `DMDAGetSubdomainCornersIS()`
507: @*/
508: PetscErrorCode DMDARestoreSubdomainCornersIS(DM dm, IS *is)
509: {
510:   PetscFunctionBegin;
513:   *is = NULL;
514:   PetscFunctionReturn(PETSC_SUCCESS);
515: }