1
2 #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/
3
DMDAGetElements_1D(DM dm,PetscInt * nel,PetscInt * nen,const PetscInt * e[])4 static PetscErrorCode DMDAGetElements_1D(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[])
5 {
6 PetscErrorCode ierr;
7 DM_DA *da = (DM_DA*)dm->data;
8 PetscInt i,xs,xe,Xs,Xe;
9 PetscInt cnt=0;
10
11 PetscFunctionBegin;
12 if (!da->e) {
13 PetscInt corners[2];
14
15 if (!da->s) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Cannot get elements for DMDA with zero stencil width");
16 ierr = DMDAGetCorners(dm,&xs,NULL,NULL,&xe,NULL,NULL);CHKERRQ(ierr);
17 ierr = DMDAGetGhostCorners(dm,&Xs,NULL,NULL,&Xe,NULL,NULL);CHKERRQ(ierr);
18 xe += xs; Xe += Xs; if (xs != Xs) xs -= 1;
19 da->ne = 1*(xe - xs - 1);
20 ierr = PetscMalloc1(1 + 2*da->ne,&da->e);CHKERRQ(ierr);
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;
26
27 corners[0] = (xs -Xs);
28 corners[1] = (xe-1-Xs);
29 ierr = ISCreateGeneral(PETSC_COMM_SELF,2,corners,PETSC_COPY_VALUES,&da->ecorners);CHKERRQ(ierr);
30 }
31 *nel = da->ne;
32 *nen = da->nen;
33 *e = da->e;
34 PetscFunctionReturn(0);
35 }
36
DMDAGetElements_2D(DM dm,PetscInt * nel,PetscInt * nen,const PetscInt * e[])37 static PetscErrorCode DMDAGetElements_2D(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[])
38 {
39 PetscErrorCode ierr;
40 DM_DA *da = (DM_DA*)dm->data;
41 PetscInt i,xs,xe,Xs,Xe;
42 PetscInt j,ys,ye,Ys,Ye;
43 PetscInt cnt=0, cell[4], ns=2;
44 PetscInt c, split[] = {0,1,3,
45 2,3,1};
46
47 PetscFunctionBegin;
48 if (!da->e) {
49 PetscInt corners[4],nn = 0;
50
51 if (!da->s) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Cannot get elements for DMDA with zero stencil width");
52
53 switch (da->elementtype) {
54 case DMDA_ELEMENT_Q1:
55 da->nen = 4;
56 break;
57 case DMDA_ELEMENT_P1:
58 da->nen = 3;
59 break;
60 default:
61 SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Unknown element type %d",da->elementtype);
62 break;
63 }
64 nn = da->nen;
65
66 if (da->elementtype == DMDA_ELEMENT_P1) {ns=2;}
67 if (da->elementtype == DMDA_ELEMENT_Q1) {ns=1;}
68 ierr = DMDAGetCorners(dm,&xs,&ys,NULL,&xe,&ye,NULL);CHKERRQ(ierr);
69 ierr = DMDAGetGhostCorners(dm,&Xs,&Ys,NULL,&Xe,&Ye,NULL);CHKERRQ(ierr);
70 xe += xs; Xe += Xs; if (xs != Xs) xs -= 1;
71 ye += ys; Ye += Ys; if (ys != Ys) ys -= 1;
72 da->ne = ns*(xe - xs - 1)*(ye - ys - 1);
73 ierr = PetscMalloc1(1 + nn*da->ne,&da->e);CHKERRQ(ierr);
74 for (j=ys; j<ye-1; j++) {
75 for (i=xs; i<xe-1; i++) {
76 cell[0] = (i-Xs) + (j-Ys)*(Xe-Xs);
77 cell[1] = (i-Xs+1) + (j-Ys)*(Xe-Xs);
78 cell[2] = (i-Xs+1) + (j-Ys+1)*(Xe-Xs);
79 cell[3] = (i-Xs) + (j-Ys+1)*(Xe-Xs);
80 if (da->elementtype == DMDA_ELEMENT_P1) {
81 for (c=0; c<ns*nn; c++) da->e[cnt++] = cell[split[c]];
82 }
83 if (da->elementtype == DMDA_ELEMENT_Q1) {
84 for (c=0; c<ns*nn; c++) da->e[cnt++] = cell[c];
85 }
86 }
87 }
88
89 corners[0] = (xs -Xs) + (ys -Ys)*(Xe-Xs);
90 corners[1] = (xe-1-Xs) + (ys -Ys)*(Xe-Xs);
91 corners[2] = (xs -Xs) + (ye-1-Ys)*(Xe-Xs);
92 corners[3] = (xe-1-Xs) + (ye-1-Ys)*(Xe-Xs);
93 ierr = ISCreateGeneral(PETSC_COMM_SELF,4,corners,PETSC_COPY_VALUES,&da->ecorners);CHKERRQ(ierr);
94 }
95 *nel = da->ne;
96 *nen = da->nen;
97 *e = da->e;
98 PetscFunctionReturn(0);
99 }
100
DMDAGetElements_3D(DM dm,PetscInt * nel,PetscInt * nen,const PetscInt * e[])101 static PetscErrorCode DMDAGetElements_3D(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[])
102 {
103 PetscErrorCode ierr;
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,
110 0,1,7,4,
111 1,2,3,7,
112 1,2,7,6,
113 1,4,5,7,
114 1,5,6,7};
115
116 PetscFunctionBegin;
117 if (!da->e) {
118 PetscInt corners[8],nn = 0;
119
120 if (!da->s) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Cannot get elements for DMDA with zero stencil width");
121
122 switch (da->elementtype) {
123 case DMDA_ELEMENT_Q1:
124 da->nen = 8;
125 break;
126 case DMDA_ELEMENT_P1:
127 da->nen = 4;
128 break;
129 default:
130 SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Unknown element type %d",da->elementtype);
131 break;
132 }
133 nn = da->nen;
134
135 if (da->elementtype == DMDA_ELEMENT_P1) {ns=6;}
136 if (da->elementtype == DMDA_ELEMENT_Q1) {ns=1;}
137 ierr = DMDAGetCorners(dm,&xs,&ys,&zs,&xe,&ye,&ze);CHKERRQ(ierr);
138 ierr = DMDAGetGhostCorners(dm,&Xs,&Ys,&Zs,&Xe,&Ye,&Ze);CHKERRQ(ierr);
139 xe += xs; Xe += Xs; if (xs != Xs) xs -= 1;
140 ye += ys; Ye += Ys; if (ys != Ys) ys -= 1;
141 ze += zs; Ze += Zs; if (zs != Zs) zs -= 1;
142 da->ne = ns*(xe - xs - 1)*(ye - ys - 1)*(ze - zs - 1);
143 ierr = PetscMalloc1(1 + nn*da->ne,&da->e);CHKERRQ(ierr);
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 }
164
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 ierr = ISCreateGeneral(PETSC_COMM_SELF,8,corners,PETSC_COPY_VALUES,&da->ecorners);CHKERRQ(ierr);
174 }
175 *nel = da->ne;
176 *nen = da->nen;
177 *e = da->e;
178 PetscFunctionReturn(0);
179 }
180
181 /*@
182 DMDAGetElementsCorners - Returns the global (x,y,z) indices of the lower left
183 corner of the non-overlapping decomposition identified by DMDAGetElements()
184
185 Not Collective
186
187 Input Parameter:
188 . da - the DM object
189
190 Output Parameters:
191 + gx - the x index
192 . gy - the y index
193 - gz - the z index
194
195 Level: intermediate
196
197 Notes:
198
199 .seealso: DMDAElementType, DMDASetElementType(), DMDAGetElements()
200 @*/
DMDAGetElementsCorners(DM da,PetscInt * gx,PetscInt * gy,PetscInt * gz)201 PetscErrorCode DMDAGetElementsCorners(DM da, PetscInt *gx, PetscInt *gy, PetscInt *gz)
202 {
203 PetscInt xs,Xs;
204 PetscInt ys,Ys;
205 PetscInt zs,Zs;
206 PetscBool isda;
207 PetscErrorCode ierr;
208
209 PetscFunctionBegin;
210 PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA);
211 if (gx) PetscValidIntPointer(gx,2);
212 if (gy) PetscValidIntPointer(gy,3);
213 if (gz) PetscValidIntPointer(gz,4);
214 ierr = PetscObjectTypeCompare((PetscObject)da,DMDA,&isda);CHKERRQ(ierr);
215 if (!isda) SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_USER,"Not for DM type %s",((PetscObject)da)->type_name);
216 ierr = DMDAGetCorners(da,&xs,&ys,&zs,NULL,NULL,NULL);CHKERRQ(ierr);
217 ierr = DMDAGetGhostCorners(da,&Xs,&Ys,&Zs,NULL,NULL,NULL);CHKERRQ(ierr);
218 if (xs != Xs) xs -= 1;
219 if (ys != Ys) ys -= 1;
220 if (zs != Zs) zs -= 1;
221 if (gx) *gx = xs;
222 if (gy) *gy = ys;
223 if (gz) *gz = zs;
224 PetscFunctionReturn(0);
225 }
226
227 /*@
228 DMDAGetElementsSizes - Gets the local number of elements per direction for the non-overlapping decomposition identified by DMDAGetElements()
229
230 Not Collective
231
232 Input Parameter:
233 . da - the DM object
234
235 Output Parameters:
236 + mx - number of local elements in x-direction
237 . my - number of local elements in y-direction
238 - mz - number of local elements in z-direction
239
240 Level: intermediate
241
242 Notes:
243 It returns the same number of elements, irrespective of the DMDAElementType
244
245 .seealso: DMDAElementType, DMDASetElementType(), DMDAGetElements
246 @*/
DMDAGetElementsSizes(DM da,PetscInt * mx,PetscInt * my,PetscInt * mz)247 PetscErrorCode DMDAGetElementsSizes(DM da, PetscInt *mx, PetscInt *my, PetscInt *mz)
248 {
249 PetscInt xs,xe,Xs;
250 PetscInt ys,ye,Ys;
251 PetscInt zs,ze,Zs;
252 PetscInt dim;
253 PetscBool isda;
254 PetscErrorCode ierr;
255
256 PetscFunctionBegin;
257 PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA);
258 if (mx) PetscValidIntPointer(mx,2);
259 if (my) PetscValidIntPointer(my,3);
260 if (mz) PetscValidIntPointer(mz,4);
261 ierr = PetscObjectTypeCompare((PetscObject)da,DMDA,&isda);CHKERRQ(ierr);
262 if (!isda) SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_USER,"Not for DM type %s",((PetscObject)da)->type_name);
263 ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xe,&ye,&ze);CHKERRQ(ierr);
264 ierr = DMDAGetGhostCorners(da,&Xs,&Ys,&Zs,NULL,NULL,NULL);CHKERRQ(ierr);
265 xe += xs; if (xs != Xs) xs -= 1;
266 ye += ys; if (ys != Ys) ys -= 1;
267 ze += zs; if (zs != Zs) zs -= 1;
268 if (mx) *mx = 0;
269 if (my) *my = 0;
270 if (mz) *mz = 0;
271 ierr = DMGetDimension(da,&dim);CHKERRQ(ierr);
272 switch (dim) {
273 case 3:
274 if (mz) *mz = ze - zs - 1;
275 case 2:
276 if (my) *my = ye - ys - 1;
277 case 1:
278 if (mx) *mx = xe - xs - 1;
279 break;
280 }
281 PetscFunctionReturn(0);
282 }
283
284 /*@
285 DMDASetElementType - Sets the element type to be returned by DMDAGetElements()
286
287 Not Collective
288
289 Input Parameter:
290 . da - the DMDA object
291
292 Output Parameters:
293 . etype - the element type, currently either DMDA_ELEMENT_P1 or DMDA_ELEMENT_Q1
294
295 Level: intermediate
296
297 .seealso: DMDAElementType, DMDAGetElementType(), DMDAGetElements(), DMDARestoreElements()
298 @*/
DMDASetElementType(DM da,DMDAElementType etype)299 PetscErrorCode DMDASetElementType(DM da, DMDAElementType etype)
300 {
301 DM_DA *dd = (DM_DA*)da->data;
302 PetscErrorCode ierr;
303 PetscBool isda;
304
305 PetscFunctionBegin;
306 PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA);
307 PetscValidLogicalCollectiveEnum(da,etype,2);
308 ierr = PetscObjectTypeCompare((PetscObject)da,DMDA,&isda);CHKERRQ(ierr);
309 if (!isda) PetscFunctionReturn(0);
310 if (dd->elementtype != etype) {
311 ierr = PetscFree(dd->e);CHKERRQ(ierr);
312 ierr = ISDestroy(&dd->ecorners);CHKERRQ(ierr);
313
314 dd->elementtype = etype;
315 dd->ne = 0;
316 dd->nen = 0;
317 dd->e = NULL;
318 }
319 PetscFunctionReturn(0);
320 }
321
322 /*@
323 DMDAGetElementType - Gets the element type to be returned by DMDAGetElements()
324
325 Not Collective
326
327 Input Parameter:
328 . da - the DMDA object
329
330 Output Parameters:
331 . etype - the element type, currently either DMDA_ELEMENT_P1 or DMDA_ELEMENT_Q1
332
333 Level: intermediate
334
335 .seealso: DMDAElementType, DMDASetElementType(), DMDAGetElements(), DMDARestoreElements()
336 @*/
DMDAGetElementType(DM da,DMDAElementType * etype)337 PetscErrorCode DMDAGetElementType(DM da, DMDAElementType *etype)
338 {
339 DM_DA *dd = (DM_DA*)da->data;
340 PetscErrorCode ierr;
341 PetscBool isda;
342
343 PetscFunctionBegin;
344 PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA);
345 PetscValidPointer(etype,2);
346 ierr = PetscObjectTypeCompare((PetscObject)da,DMDA,&isda);CHKERRQ(ierr);
347 if (!isda) SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_USER,"Not for DM type %s",((PetscObject)da)->type_name);
348 *etype = dd->elementtype;
349 PetscFunctionReturn(0);
350 }
351
352 /*@C
353 DMDAGetElements - Gets an array containing the indices (in local coordinates)
354 of all the local elements
355
356 Not Collective
357
358 Input Parameter:
359 . dm - the DM object
360
361 Output Parameters:
362 + nel - number of local elements
363 . nen - number of element nodes
364 - e - the local indices of the elements' vertices
365
366 Level: intermediate
367
368 Notes:
369 Call DMDARestoreElements() once you have finished accessing the elements.
370
371 Each process uniquely owns a subset of the elements. That is no element is owned by two or more processes.
372
373 If on each process you integrate over its owned elements and use ADD_VALUES in Vec/MatSetValuesLocal() then you'll obtain the correct result.
374
375 Not supported in Fortran
376
377 .seealso: DMDAElementType, DMDASetElementType(), VecSetValuesLocal(), MatSetValuesLocal(), DMGlobalToLocalBegin(), DMLocalToGlobalBegin()
378 @*/
DMDAGetElements(DM dm,PetscInt * nel,PetscInt * nen,const PetscInt * e[])379 PetscErrorCode DMDAGetElements(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[])
380 {
381 PetscInt dim;
382 PetscErrorCode ierr;
383 DM_DA *dd = (DM_DA*)dm->data;
384 PetscBool isda;
385
386 PetscFunctionBegin;
387 PetscValidHeaderSpecificType(dm,DM_CLASSID,1,DMDA);
388 PetscValidIntPointer(nel,2);
389 PetscValidIntPointer(nen,3);
390 PetscValidPointer(e,4);
391 ierr = PetscObjectTypeCompare((PetscObject)dm,DMDA,&isda);CHKERRQ(ierr);
392 if (!isda) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for DM type %s",((PetscObject)dm)->type_name);
393 if (dd->stencil_type == DMDA_STENCIL_STAR) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DMDAGetElements() requires you use a stencil type of DMDA_STENCIL_BOX");
394 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
395 if (dd->e) {
396 *nel = dd->ne;
397 *nen = dd->nen;
398 *e = dd->e;
399 PetscFunctionReturn(0);
400 }
401 if (dim==-1) {
402 *nel = 0; *nen = 0; *e = NULL;
403 } else if (dim==1) {
404 ierr = DMDAGetElements_1D(dm,nel,nen,e);CHKERRQ(ierr);
405 } else if (dim==2) {
406 ierr = DMDAGetElements_2D(dm,nel,nen,e);CHKERRQ(ierr);
407 } else if (dim==3) {
408 ierr = DMDAGetElements_3D(dm,nel,nen,e);CHKERRQ(ierr);
409 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
410 PetscFunctionReturn(0);
411 }
412
413 /*@
414 DMDAGetSubdomainCornersIS - Gets an index set containing the corner indices (in local coordinates)
415 of the non-overlapping decomposition identified by DMDAGetElements
416
417 Not Collective
418
419 Input Parameter:
420 . dm - the DM object
421
422 Output Parameters:
423 . is - the index set
424
425 Level: intermediate
426
427 Notes:
428 Call DMDARestoreSubdomainCornersIS() once you have finished accessing the index set.
429
430 .seealso: DMDAElementType, DMDASetElementType(), DMDAGetElements(), DMDARestoreElementsCornersIS()
431 @*/
DMDAGetSubdomainCornersIS(DM dm,IS * is)432 PetscErrorCode DMDAGetSubdomainCornersIS(DM dm,IS *is)
433 {
434 PetscErrorCode ierr;
435 DM_DA *dd = (DM_DA*)dm->data;
436 PetscBool isda;
437
438 PetscFunctionBegin;
439 PetscValidHeaderSpecificType(dm,DM_CLASSID,1,DMDA);
440 PetscValidPointer(is,2);
441 ierr = PetscObjectTypeCompare((PetscObject)dm,DMDA,&isda);CHKERRQ(ierr);
442 if (!isda) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Not for DM type %s",((PetscObject)dm)->type_name);
443 if (dd->stencil_type == DMDA_STENCIL_STAR) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DMDAGetElement() requires you use a stencil type of DMDA_STENCIL_BOX");
444 if (!dd->ecorners) { /* compute elements if not yet done */
445 const PetscInt *e;
446 PetscInt nel,nen;
447
448 ierr = DMDAGetElements(dm,&nel,&nen,&e);CHKERRQ(ierr);
449 ierr = DMDARestoreElements(dm,&nel,&nen,&e);CHKERRQ(ierr);
450 }
451 *is = dd->ecorners;
452 PetscFunctionReturn(0);
453 }
454
455 /*@C
456 DMDARestoreElements - Restores the array obtained with DMDAGetElements()
457
458 Not Collective
459
460 Input Parameter:
461 + dm - the DM object
462 . nel - number of local elements
463 . nen - number of element nodes
464 - e - the local indices of the elements' vertices
465
466 Level: intermediate
467
468 Note: You should not access these values after you have called this routine.
469
470 This restore signals the DMDA object that you no longer need access to the array information.
471
472 Not supported in Fortran
473
474 .seealso: DMDAElementType, DMDASetElementType(), DMDAGetElements()
475 @*/
DMDARestoreElements(DM dm,PetscInt * nel,PetscInt * nen,const PetscInt * e[])476 PetscErrorCode DMDARestoreElements(DM dm,PetscInt *nel,PetscInt *nen,const PetscInt *e[])
477 {
478 PetscFunctionBegin;
479 PetscValidHeaderSpecificType(dm,DM_CLASSID,1,DMDA);
480 PetscValidIntPointer(nel,2);
481 PetscValidIntPointer(nen,3);
482 PetscValidPointer(e,4);
483 *nel = 0;
484 *nen = -1;
485 *e = NULL;
486 PetscFunctionReturn(0);
487 }
488
489 /*@
490 DMDARestoreSubdomainCornersIS - Restores the IS obtained with DMDAGetSubdomainCornersIS()
491
492 Not Collective
493
494 Input Parameter:
495 + dm - the DM object
496 - is - the index set
497
498 Level: intermediate
499
500 Note:
501
502 .seealso: DMDAElementType, DMDASetElementType(), DMDAGetSubdomainCornersIS()
503 @*/
DMDARestoreSubdomainCornersIS(DM dm,IS * is)504 PetscErrorCode DMDARestoreSubdomainCornersIS(DM dm,IS *is)
505 {
506 PetscFunctionBegin;
507 PetscValidHeaderSpecificType(dm,DM_CLASSID,1,DMDA);
508 PetscValidHeaderSpecific(*is,IS_CLASSID,2);
509 *is = NULL;
510 PetscFunctionReturn(0);
511 }
512