Actual source code: dalocal.c
petsc-3.3-p7 2013-05-11
2: /*
3: Code for manipulating distributed regular arrays in parallel.
4: */
6: #include <petsc-private/daimpl.h> /*I "petscdmda.h" I*/
8: /*
9: This allows the DMDA vectors to properly tell MATLAB their dimensions
10: */
11: #if defined(PETSC_HAVE_MATLAB_ENGINE)
12: #include <engine.h> /* MATLAB include file */
13: #include <mex.h> /* MATLAB include file */
14: EXTERN_C_BEGIN
17: PetscErrorCode VecMatlabEnginePut_DA2d(PetscObject obj,void *mengine)
18: {
20: PetscInt n,m;
21: Vec vec = (Vec)obj;
22: PetscScalar *array;
23: mxArray *mat;
24: DM da;
27: PetscObjectQuery((PetscObject)vec,"DM",(PetscObject*)&da);
28: if (!da) SETERRQ(((PetscObject)vec)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vector not associated with a DMDA");
29: DMDAGetGhostCorners(da,0,0,0,&m,&n,0);
31: VecGetArray(vec,&array);
32: #if !defined(PETSC_USE_COMPLEX)
33: mat = mxCreateDoubleMatrix(m,n,mxREAL);
34: #else
35: mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX);
36: #endif
37: PetscMemcpy(mxGetPr(mat),array,n*m*sizeof(PetscScalar));
38: PetscObjectName(obj);
39: engPutVariable((Engine *)mengine,obj->name,mat);
40:
41: VecRestoreArray(vec,&array);
42: return(0);
43: }
44: EXTERN_C_END
45: #endif
50: PetscErrorCode DMCreateLocalVector_DA(DM da,Vec* g)
51: {
53: DM_DA *dd = (DM_DA*)da->data;
58: VecCreate(PETSC_COMM_SELF,g);
59: VecSetSizes(*g,dd->nlocal,PETSC_DETERMINE);
60: VecSetBlockSize(*g,dd->w);
61: VecSetType(*g,da->vectype);
62: PetscObjectCompose((PetscObject)*g,"DM",(PetscObject)da);
63: #if defined(PETSC_HAVE_MATLAB_ENGINE)
64: if (dd->w == 1 && dd->dim == 2) {
65: PetscObjectComposeFunctionDynamic((PetscObject)*g,"PetscMatlabEnginePut_C","VecMatlabEnginePut_DA2d",VecMatlabEnginePut_DA2d);
66: }
67: #endif
68: return(0);
69: }
73: /*@C
74: DMDACreateSection - Create a PetscSection inside the DMDA that describes data layout. This allows multiple fields with
75: different numbers of dofs on vertices, cells, and faces in each direction.
77: Input Parameters:
78: + dm- The DMDA
79: . numFields - The number of fields
80: . numComp - The number of components in each field, or PETSC_NULL for 1
81: . numVertexDof - The number of dofs per vertex for each field, or PETSC_NULL
82: . numFaceDof - The number of dofs per face for each field and direction, or PETSC_NULL
83: - numCellDof - The number of dofs per cell for each field, or PETSC_NULL
85: Level: developer
87: Note:
88: The default DMDA numbering is as follows:
90: - Cells: [0, nC)
91: - Vertices: [nC, nC+nV)
92: - X-Faces: [nC+nV, nC+nV+nXF) normal is +- x-dir
93: - Y-Faces: [nC+nV+nXF, nC+nV+nXF+nYF) normal is +- y-dir
94: - Z-Faces: [nC+nV+nXF+nYF, nC+nV+nXF+nYF+nZF) normal is +- z-dir
96: We interpret the default DMDA partition as a cell partition, and the data assignment as a cell assignment.
97: @*/
98: PetscErrorCode DMDACreateSection(DM dm, PetscInt numComp[], PetscInt numVertexDof[], PetscInt numFaceDof[], PetscInt numCellDof[])
99: {
100: DM_DA *da = (DM_DA *) dm->data;
101: const PetscInt dim = da->dim;
102: const PetscInt mx = (da->Xe - da->Xs)/da->w, my = da->Ye - da->Ys, mz = da->Ze - da->Zs;
103: const PetscInt nC = (mx )*(dim > 1 ? (my )*(dim > 2 ? (mz ) : 1) : 1);
104: const PetscInt nVx = mx+1;
105: const PetscInt nVy = dim > 1 ? (my+1) : 1;
106: const PetscInt nVz = dim > 2 ? (mz+1) : 1;
107: const PetscInt nV = nVx*nVy*nVz;
108: const PetscInt nxF = (dim > 1 ? (my )*(dim > 2 ? (mz ) : 1) : 1);
109: const PetscInt nXF = (mx+1)*nxF;
110: const PetscInt nyF = mx*(dim > 2 ? mz : 1);
111: const PetscInt nYF = dim > 1 ? (my+1)*nyF : 0;
112: const PetscInt nzF = mx*(dim > 1 ? my : 0);
113: const PetscInt nZF = dim > 2 ? (mz+1)*nzF : 0;
114: const PetscInt cStart = 0, cEnd = cStart+nC;
115: const PetscInt vStart = cEnd, vEnd = vStart+nV;
116: const PetscInt xfStart = vEnd, xfEnd = xfStart+nXF;
117: const PetscInt yfStart = xfEnd, yfEnd = yfStart+nYF;
118: const PetscInt zfStart = yfEnd, zfEnd = zfStart+nZF;
119: const PetscInt pStart = 0, pEnd = zfEnd;
120: PetscInt numFields, numVertexTotDof = 0, numCellTotDof = 0, numFaceTotDof[3] = {0, 0, 0};
121: PetscSF sf;
122: PetscMPIInt rank;
123: const PetscMPIInt *neighbors;
124: PetscInt *localPoints;
125: PetscSFNode *remotePoints;
126: PetscInt nleaves = 0, nleavesCheck = 0;
127: PetscInt f, v, c, xf, yf, zf, xn, yn, zn;
132: MPI_Comm_rank(((PetscObject) dm)->comm, &rank);
133: /* Create local section */
134: DMDAGetInfo(dm, 0,0,0,0,0,0,0, &numFields, 0,0,0,0,0);
135: for(f = 0; f < numFields; ++f) {
136: if (numVertexDof) {numVertexTotDof += numVertexDof[f];}
137: if (numCellDof) {numCellTotDof += numCellDof[f];}
138: if (numFaceDof) {numFaceTotDof[0] += numFaceDof[f*dim+0];
139: numFaceTotDof[1] += dim > 1 ? numFaceDof[f*dim+1] : 0;
140: numFaceTotDof[2] += dim > 2 ? numFaceDof[f*dim+2] : 0;}
141: }
142: PetscSectionCreate(((PetscObject) dm)->comm, &dm->defaultSection);
143: if (numFields > 1) {
144: PetscSectionSetNumFields(dm->defaultSection, numFields);
145: for(f = 0; f < numFields; ++f) {
146: const char *name;
148: DMDAGetFieldName(dm, f, &name);
149: PetscSectionSetFieldName(dm->defaultSection, f, name);
150: if (numComp) {
151: PetscSectionSetFieldComponents(dm->defaultSection, f, numComp[f]);
152: }
153: }
154: } else {
155: numFields = 0;
156: }
157: PetscSectionSetChart(dm->defaultSection, pStart, pEnd);
158: if (numVertexDof) {
159: for(v = vStart; v < vEnd; ++v) {
160: for(f = 0; f < numFields; ++f) {
161: PetscSectionSetFieldDof(dm->defaultSection, v, f, numVertexDof[f]);
162: }
163: PetscSectionSetDof(dm->defaultSection, v, numVertexTotDof);
164: }
165: }
166: if (numFaceDof) {
167: for(xf = xfStart; xf < xfEnd; ++xf) {
168: for(f = 0; f < numFields; ++f) {
169: PetscSectionSetFieldDof(dm->defaultSection, xf, f, numFaceDof[f*dim+0]);
170: }
171: PetscSectionSetDof(dm->defaultSection, xf, numFaceTotDof[0]);
172: }
173: for(yf = yfStart; yf < yfEnd; ++yf) {
174: for(f = 0; f < numFields; ++f) {
175: PetscSectionSetFieldDof(dm->defaultSection, yf, f, numFaceDof[f*dim+1]);
176: }
177: PetscSectionSetDof(dm->defaultSection, yf, numFaceTotDof[1]);
178: }
179: for(zf = zfStart; zf < zfEnd; ++zf) {
180: for(f = 0; f < numFields; ++f) {
181: PetscSectionSetFieldDof(dm->defaultSection, zf, f, numFaceDof[f*dim+2]);
182: }
183: PetscSectionSetDof(dm->defaultSection, zf, numFaceTotDof[2]);
184: }
185: }
186: if (numCellDof) {
187: for(c = cStart; c < cEnd; ++c) {
188: for(f = 0; f < numFields; ++f) {
189: PetscSectionSetFieldDof(dm->defaultSection, c, f, numCellDof[f]);
190: }
191: PetscSectionSetDof(dm->defaultSection, c, numCellTotDof);
192: }
193: }
194: PetscSectionSetUp(dm->defaultSection);
195: /* Create mesh point SF */
196: DMDAGetNeighbors(dm, &neighbors);
197: for(zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) {
198: for(yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) {
199: for(xn = 0; xn < 3; ++xn) {
200: const PetscInt xp = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0;
201: const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn];
203: if (neighbor >= 0 && neighbor != rank) {
204: nleaves += (!xp ? nVx : 1) * (!yp ? nVy : 1) * (!zp ? nVz : 1); /* vertices */
205: if (xp && !yp && !zp) {
206: nleaves += nxF; /* x faces */
207: } else if (yp && !zp && !xp) {
208: nleaves += nyF; /* y faces */
209: } else if (zp && !xp && !yp) {
210: nleaves += nzF; /* z faces */
211: }
212: }
213: }
214: }
215: }
216: PetscMalloc2(nleaves,PetscInt,&localPoints,nleaves,PetscSFNode,&remotePoints);
217: for(zn = 0; zn < (dim > 2 ? 3 : 1); ++zn) {
218: for(yn = 0; yn < (dim > 1 ? 3 : 1); ++yn) {
219: for(xn = 0; xn < 3; ++xn) {
220: const PetscInt xp = xn-1, yp = dim > 1 ? yn-1 : 0, zp = dim > 2 ? zn-1 : 0;
221: const PetscInt neighbor = neighbors[(zn*3+yn)*3+xn];
223: if (neighbor >= 0 && neighbor != rank) {
224: if (xp < 0) { /* left */
225: if (yp < 0) { /* bottom */
226: if (zp < 0) { /* back */
227: nleavesCheck += 1; /* left bottom back vertex */
228: } else if (zp > 0) { /* front */
229: nleavesCheck += 1; /* left bottom front vertex */
230: } else {
231: nleavesCheck += nVz; /* left bottom vertices */
232: }
233: } else if (yp > 0) { /* top */
234: if (zp < 0) { /* back */
235: nleavesCheck += 1; /* left top back vertex */
236: } else if (zp > 0) { /* front */
237: nleavesCheck += 1; /* left top front vertex */
238: } else {
239: nleavesCheck += nVz; /* left top vertices */
240: }
241: } else {
242: if (zp < 0) { /* back */
243: nleavesCheck += nVy; /* left back vertices */
244: } else if (zp > 0) { /* front */
245: nleavesCheck += nVy; /* left front vertices */
246: } else {
247: nleavesCheck += nVy*nVz; /* left vertices */
248: nleavesCheck += nxF; /* left faces */
249: }
250: }
251: } else if (xp > 0) { /* right */
252: if (yp < 0) { /* bottom */
253: if (zp < 0) { /* back */
254: nleavesCheck += 1; /* right bottom back vertex */
255: } else if (zp > 0) { /* front */
256: nleavesCheck += 1; /* right bottom front vertex */
257: } else {
258: nleavesCheck += nVz; /* right bottom vertices */
259: }
260: } else if (yp > 0) { /* top */
261: if (zp < 0) { /* back */
262: nleavesCheck += 1; /* right top back vertex */
263: } else if (zp > 0) { /* front */
264: nleavesCheck += 1; /* right top front vertex */
265: } else {
266: nleavesCheck += nVz; /* right top vertices */
267: }
268: } else {
269: if (zp < 0) { /* back */
270: nleavesCheck += nVy; /* right back vertices */
271: } else if (zp > 0) { /* front */
272: nleavesCheck += nVy; /* right front vertices */
273: } else {
274: nleavesCheck += nVy*nVz; /* right vertices */
275: nleavesCheck += nxF; /* right faces */
276: }
277: }
278: } else {
279: if (yp < 0) { /* bottom */
280: if (zp < 0) { /* back */
281: nleavesCheck += nVx; /* bottom back vertices */
282: } else if (zp > 0) { /* front */
283: nleavesCheck += nVx; /* bottom front vertices */
284: } else {
285: nleavesCheck += nVx*nVz; /* bottom vertices */
286: nleavesCheck += nyF; /* bottom faces */
287: }
288: } else if (yp > 0) { /* top */
289: if (zp < 0) { /* back */
290: nleavesCheck += nVx; /* top back vertices */
291: } else if (zp > 0) { /* front */
292: nleavesCheck += nVx; /* top front vertices */
293: } else {
294: nleavesCheck += nVx*nVz; /* top vertices */
295: nleavesCheck += nyF; /* top faces */
296: }
297: } else {
298: if (zp < 0) { /* back */
299: nleavesCheck += nVx*nVy; /* back vertices */
300: nleavesCheck += nzF; /* back faces */
301: } else if (zp > 0) { /* front */
302: nleavesCheck += nVx*nVy; /* front vertices */
303: nleavesCheck += nzF; /* front faces */
304: } else {
305: /* Nothing is shared from the interior */
306: }
307: }
308: }
309: }
310: }
311: }
312: }
313: if (nleaves != nleavesCheck) SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "The number of leaves %d did not match the number of remote leaves %d", nleaves, nleavesCheck);
314: PetscSFCreate(((PetscObject) dm)->comm, &sf);
315: PetscSFSetGraph(sf, pEnd, nleaves, localPoints, PETSC_OWN_POINTER, remotePoints, PETSC_OWN_POINTER);
316: /* Create global section */
317: PetscSectionCreateGlobalSection(dm->defaultSection, sf, &dm->defaultGlobalSection);
318: PetscSFDestroy(&sf);
319: /* Create default SF */
320: DMCreateDefaultSF(dm, dm->defaultSection, dm->defaultGlobalSection);
321: return(0);
322: }
324: /* ------------------------------------------------------------------- */
325: #if defined(PETSC_HAVE_ADIC)
327: EXTERN_C_BEGIN
328: #include <adic/ad_utils.h>
329: EXTERN_C_END
333: /*@C
334: DMDAGetAdicArray - Gets an array of derivative types for a DMDA
336: Input Parameter:
337: + da - information about my local patch
338: - ghosted - do you want arrays for the ghosted or nonghosted patch
340: Output Parameters:
341: + vptr - array data structured to be passed to ad_FormFunctionLocal()
342: . array_start - actual start of 1d array of all values that adiC can access directly (may be null)
343: - tdof - total number of degrees of freedom represented in array_start (may be null)
345: Notes:
346: The vector values are NOT initialized and may have garbage in them, so you may need
347: to zero them.
349: Returns the same type of object as the DMDAVecGetArray() except its elements are
350: derivative types instead of PetscScalars
352: Level: advanced
354: .seealso: DMDARestoreAdicArray()
356: @*/
357: PetscErrorCode DMDAGetAdicArray(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof)
358: {
360: PetscInt j,i,deriv_type_size,xs,ys,xm,ym,zs,zm,itdof;
361: char *iarray_start;
362: void **iptr = (void**)vptr;
363: DM_DA *dd = (DM_DA*)da->data;
367: if (ghosted) {
368: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
369: if (dd->adarrayghostedin[i]) {
370: *iptr = dd->adarrayghostedin[i];
371: iarray_start = (char*)dd->adstartghostedin[i];
372: itdof = dd->ghostedtdof;
373: dd->adarrayghostedin[i] = PETSC_NULL;
374: dd->adstartghostedin[i] = PETSC_NULL;
375:
376: goto done;
377: }
378: }
379: xs = dd->Xs;
380: ys = dd->Ys;
381: zs = dd->Zs;
382: xm = dd->Xe-dd->Xs;
383: ym = dd->Ye-dd->Ys;
384: zm = dd->Ze-dd->Zs;
385: } else {
386: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
387: if (dd->adarrayin[i]) {
388: *iptr = dd->adarrayin[i];
389: iarray_start = (char*)dd->adstartin[i];
390: itdof = dd->tdof;
391: dd->adarrayin[i] = PETSC_NULL;
392: dd->adstartin[i] = PETSC_NULL;
393:
394: goto done;
395: }
396: }
397: xs = dd->xs;
398: ys = dd->ys;
399: zs = dd->zs;
400: xm = dd->xe-dd->xs;
401: ym = dd->ye-dd->ys;
402: zm = dd->ze-dd->zs;
403: }
404: deriv_type_size = PetscADGetDerivTypeSize();
406: switch (dd->dim) {
407: case 1: {
408: void *ptr;
409: itdof = xm;
411: PetscMalloc(xm*deriv_type_size,&iarray_start);
413: ptr = (void*)(iarray_start - xs*deriv_type_size);
414: *iptr = (void*)ptr;
415: break;}
416: case 2: {
417: void **ptr;
418: itdof = xm*ym;
420: PetscMalloc((ym+1)*sizeof(void*)+xm*ym*deriv_type_size,&iarray_start);
422: ptr = (void**)(iarray_start + xm*ym*deriv_type_size - ys*sizeof(void*));
423: for(j=ys;j<ys+ym;j++) {
424: ptr[j] = iarray_start + deriv_type_size*(xm*(j-ys) - xs);
425: }
426: *iptr = (void*)ptr;
427: break;}
428: case 3: {
429: void ***ptr,**bptr;
430: itdof = xm*ym*zm;
432: PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*deriv_type_size,&iarray_start);
434: ptr = (void***)(iarray_start + xm*ym*zm*deriv_type_size - zs*sizeof(void*));
435: bptr = (void**)(iarray_start + xm*ym*zm*deriv_type_size + zm*sizeof(void**));
437: for(i=zs;i<zs+zm;i++) {
438: ptr[i] = bptr + ((i-zs)*ym - ys);
439: }
440: for (i=zs; i<zs+zm; i++) {
441: for (j=ys; j<ys+ym; j++) {
442: ptr[i][j] = iarray_start + deriv_type_size*(xm*ym*(i-zs) + xm*(j-ys) - xs);
443: }
444: }
446: *iptr = (void*)ptr;
447: break;}
448: default:
449: SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
450: }
452: done:
453: /* add arrays to the checked out list */
454: if (ghosted) {
455: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
456: if (!dd->adarrayghostedout[i]) {
457: dd->adarrayghostedout[i] = *iptr ;
458: dd->adstartghostedout[i] = iarray_start;
459: dd->ghostedtdof = itdof;
460: break;
461: }
462: }
463: } else {
464: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
465: if (!dd->adarrayout[i]) {
466: dd->adarrayout[i] = *iptr ;
467: dd->adstartout[i] = iarray_start;
468: dd->tdof = itdof;
469: break;
470: }
471: }
472: }
473: if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Too many DMDA ADIC arrays obtained");
474: if (tdof) *tdof = itdof;
475: if (array_start) *(void**)array_start = iarray_start;
476: return(0);
477: }
481: /*@C
482: DMDARestoreAdicArray - Restores an array of derivative types for a DMDA
483:
484: Input Parameter:
485: + da - information about my local patch
486: - ghosted - do you want arrays for the ghosted or nonghosted patch
488: Output Parameters:
489: + ptr - array data structured to be passed to ad_FormFunctionLocal()
490: . array_start - actual start of 1d array of all values that adiC can access directly
491: - tdof - total number of degrees of freedom represented in array_start
493: Level: advanced
495: .seealso: DMDAGetAdicArray()
497: @*/
498: PetscErrorCode DMDARestoreAdicArray(DM da,PetscBool ghosted,void *ptr,void *array_start,PetscInt *tdof)
499: {
500: PetscInt i;
501: void **iptr = (void**)ptr,iarray_start = 0;
502:
505: if (ghosted) {
506: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
507: if (dd->adarrayghostedout[i] == *iptr) {
508: iarray_start = dd->adstartghostedout[i];
509: dd->adarrayghostedout[i] = PETSC_NULL;
510: dd->adstartghostedout[i] = PETSC_NULL;
511: break;
512: }
513: }
514: if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
515: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
516: if (!dd->adarrayghostedin[i]){
517: dd->adarrayghostedin[i] = *iptr;
518: dd->adstartghostedin[i] = iarray_start;
519: break;
520: }
521: }
522: } else {
523: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
524: if (dd->adarrayout[i] == *iptr) {
525: iarray_start = dd->adstartout[i];
526: dd->adarrayout[i] = PETSC_NULL;
527: dd->adstartout[i] = PETSC_NULL;
528: break;
529: }
530: }
531: if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
532: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
533: if (!dd->adarrayin[i]){
534: dd->adarrayin[i] = *iptr;
535: dd->adstartin[i] = iarray_start;
536: break;
537: }
538: }
539: }
540: return(0);
541: }
545: PetscErrorCode ad_DAGetArray(DM da,PetscBool ghosted,void *iptr)
546: {
549: DMDAGetAdicArray(da,ghosted,iptr,0,0);
550: return(0);
551: }
555: PetscErrorCode ad_DARestoreArray(DM da,PetscBool ghosted,void *iptr)
556: {
559: DMDARestoreAdicArray(da,ghosted,iptr,0,0);
560: return(0);
561: }
563: #endif
567: /*@C
568: DMDAGetArray - Gets a work array for a DMDA
570: Input Parameter:
571: + da - information about my local patch
572: - ghosted - do you want arrays for the ghosted or nonghosted patch
574: Output Parameters:
575: . vptr - array data structured
577: Note: The vector values are NOT initialized and may have garbage in them, so you may need
578: to zero them.
580: Level: advanced
582: .seealso: DMDARestoreArray(), DMDAGetAdicArray()
584: @*/
585: PetscErrorCode DMDAGetArray(DM da,PetscBool ghosted,void *vptr)
586: {
588: PetscInt j,i,xs,ys,xm,ym,zs,zm;
589: char *iarray_start;
590: void **iptr = (void**)vptr;
591: DM_DA *dd = (DM_DA*)da->data;
595: if (ghosted) {
596: for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
597: if (dd->arrayghostedin[i]) {
598: *iptr = dd->arrayghostedin[i];
599: iarray_start = (char*)dd->startghostedin[i];
600: dd->arrayghostedin[i] = PETSC_NULL;
601: dd->startghostedin[i] = PETSC_NULL;
602:
603: goto done;
604: }
605: }
606: xs = dd->Xs;
607: ys = dd->Ys;
608: zs = dd->Zs;
609: xm = dd->Xe-dd->Xs;
610: ym = dd->Ye-dd->Ys;
611: zm = dd->Ze-dd->Zs;
612: } else {
613: for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
614: if (dd->arrayin[i]) {
615: *iptr = dd->arrayin[i];
616: iarray_start = (char*)dd->startin[i];
617: dd->arrayin[i] = PETSC_NULL;
618: dd->startin[i] = PETSC_NULL;
619:
620: goto done;
621: }
622: }
623: xs = dd->xs;
624: ys = dd->ys;
625: zs = dd->zs;
626: xm = dd->xe-dd->xs;
627: ym = dd->ye-dd->ys;
628: zm = dd->ze-dd->zs;
629: }
631: switch (dd->dim) {
632: case 1: {
633: void *ptr;
635: PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);
637: ptr = (void*)(iarray_start - xs*sizeof(PetscScalar));
638: *iptr = (void*)ptr;
639: break;}
640: case 2: {
641: void **ptr;
643: PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);
645: ptr = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*));
646: for(j=ys;j<ys+ym;j++) {
647: ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs);
648: }
649: *iptr = (void*)ptr;
650: break;}
651: case 3: {
652: void ***ptr,**bptr;
654: PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);
656: ptr = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*));
657: bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**));
658: for(i=zs;i<zs+zm;i++) {
659: ptr[i] = bptr + ((i-zs)*ym - ys);
660: }
661: for (i=zs; i<zs+zm; i++) {
662: for (j=ys; j<ys+ym; j++) {
663: ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
664: }
665: }
667: *iptr = (void*)ptr;
668: break;}
669: default:
670: SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
671: }
673: done:
674: /* add arrays to the checked out list */
675: if (ghosted) {
676: for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
677: if (!dd->arrayghostedout[i]) {
678: dd->arrayghostedout[i] = *iptr ;
679: dd->startghostedout[i] = iarray_start;
680: break;
681: }
682: }
683: } else {
684: for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
685: if (!dd->arrayout[i]) {
686: dd->arrayout[i] = *iptr ;
687: dd->startout[i] = iarray_start;
688: break;
689: }
690: }
691: }
692: return(0);
693: }
697: /*@C
698: DMDARestoreArray - Restores an array of derivative types for a DMDA
699:
700: Input Parameter:
701: + da - information about my local patch
702: . ghosted - do you want arrays for the ghosted or nonghosted patch
703: - vptr - array data structured to be passed to ad_FormFunctionLocal()
705: Level: advanced
707: .seealso: DMDAGetArray(), DMDAGetAdicArray()
709: @*/
710: PetscErrorCode DMDARestoreArray(DM da,PetscBool ghosted,void *vptr)
711: {
712: PetscInt i;
713: void **iptr = (void**)vptr,*iarray_start = 0;
714: DM_DA *dd = (DM_DA*)da->data;
715:
718: if (ghosted) {
719: for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
720: if (dd->arrayghostedout[i] == *iptr) {
721: iarray_start = dd->startghostedout[i];
722: dd->arrayghostedout[i] = PETSC_NULL;
723: dd->startghostedout[i] = PETSC_NULL;
724: break;
725: }
726: }
727: for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
728: if (!dd->arrayghostedin[i]){
729: dd->arrayghostedin[i] = *iptr;
730: dd->startghostedin[i] = iarray_start;
731: break;
732: }
733: }
734: } else {
735: for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
736: if (dd->arrayout[i] == *iptr) {
737: iarray_start = dd->startout[i];
738: dd->arrayout[i] = PETSC_NULL;
739: dd->startout[i] = PETSC_NULL;
740: break;
741: }
742: }
743: for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
744: if (!dd->arrayin[i]){
745: dd->arrayin[i] = *iptr;
746: dd->startin[i] = iarray_start;
747: break;
748: }
749: }
750: }
751: return(0);
752: }
756: /*@C
757: DMDAGetAdicMFArray - Gets an array of derivative types for a DMDA for matrix-free ADIC.
758:
759: Input Parameter:
760: + da - information about my local patch
761: - ghosted - do you want arrays for the ghosted or nonghosted patch?
763: Output Parameters:
764: + vptr - array data structured to be passed to ad_FormFunctionLocal()
765: . array_start - actual start of 1d array of all values that adiC can access directly (may be null)
766: - tdof - total number of degrees of freedom represented in array_start (may be null)
768: Notes:
769: The vector values are NOT initialized and may have garbage in them, so you may need
770: to zero them.
772: This routine returns the same type of object as the DMDAVecGetArray(), except its
773: elements are derivative types instead of PetscScalars.
775: Level: advanced
777: .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
779: @*/
780: PetscErrorCode DMDAGetAdicMFArray(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof)
781: {
783: PetscInt j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
784: char *iarray_start;
785: void **iptr = (void**)vptr;
786: DM_DA *dd = (DM_DA*)da->data;
790: if (ghosted) {
791: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
792: if (dd->admfarrayghostedin[i]) {
793: *iptr = dd->admfarrayghostedin[i];
794: iarray_start = (char*)dd->admfstartghostedin[i];
795: itdof = dd->ghostedtdof;
796: dd->admfarrayghostedin[i] = PETSC_NULL;
797: dd->admfstartghostedin[i] = PETSC_NULL;
798:
799: goto done;
800: }
801: }
802: xs = dd->Xs;
803: ys = dd->Ys;
804: zs = dd->Zs;
805: xm = dd->Xe-dd->Xs;
806: ym = dd->Ye-dd->Ys;
807: zm = dd->Ze-dd->Zs;
808: } else {
809: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
810: if (dd->admfarrayin[i]) {
811: *iptr = dd->admfarrayin[i];
812: iarray_start = (char*)dd->admfstartin[i];
813: itdof = dd->tdof;
814: dd->admfarrayin[i] = PETSC_NULL;
815: dd->admfstartin[i] = PETSC_NULL;
816:
817: goto done;
818: }
819: }
820: xs = dd->xs;
821: ys = dd->ys;
822: zs = dd->zs;
823: xm = dd->xe-dd->xs;
824: ym = dd->ye-dd->ys;
825: zm = dd->ze-dd->zs;
826: }
828: switch (dd->dim) {
829: case 1: {
830: void *ptr;
831: itdof = xm;
833: PetscMalloc(xm*2*sizeof(PetscScalar),&iarray_start);
835: ptr = (void*)(iarray_start - xs*2*sizeof(PetscScalar));
836: *iptr = (void*)ptr;
837: break;}
838: case 2: {
839: void **ptr;
840: itdof = xm*ym;
842: PetscMalloc((ym+1)*sizeof(void*)+xm*ym*2*sizeof(PetscScalar),&iarray_start);
844: ptr = (void**)(iarray_start + xm*ym*2*sizeof(PetscScalar) - ys*sizeof(void*));
845: for(j=ys;j<ys+ym;j++) {
846: ptr[j] = iarray_start + 2*sizeof(PetscScalar)*(xm*(j-ys) - xs);
847: }
848: *iptr = (void*)ptr;
849: break;}
850: case 3: {
851: void ***ptr,**bptr;
852: itdof = xm*ym*zm;
854: PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*2*sizeof(PetscScalar),&iarray_start);
856: ptr = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
857: bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
858: for(i=zs;i<zs+zm;i++) {
859: ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
860: }
861: for (i=zs; i<zs+zm; i++) {
862: for (j=ys; j<ys+ym; j++) {
863: ptr[i][j] = iarray_start + 2*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
864: }
865: }
867: *iptr = (void*)ptr;
868: break;}
869: default:
870: SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
871: }
873: done:
874: /* add arrays to the checked out list */
875: if (ghosted) {
876: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
877: if (!dd->admfarrayghostedout[i]) {
878: dd->admfarrayghostedout[i] = *iptr ;
879: dd->admfstartghostedout[i] = iarray_start;
880: dd->ghostedtdof = itdof;
881: break;
882: }
883: }
884: } else {
885: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
886: if (!dd->admfarrayout[i]) {
887: dd->admfarrayout[i] = *iptr ;
888: dd->admfstartout[i] = iarray_start;
889: dd->tdof = itdof;
890: break;
891: }
892: }
893: }
894: if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
895: if (tdof) *tdof = itdof;
896: if (array_start) *(void**)array_start = iarray_start;
897: return(0);
898: }
902: PetscErrorCode DMDAGetAdicMFArray4(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof)
903: {
905: PetscInt j,i,xs,ys,xm,ym,itdof = 0;
906: char *iarray_start;
907: void **iptr = (void**)vptr;
908: DM_DA *dd = (DM_DA*)da->data;
912: if (ghosted) {
913: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
914: if (dd->admfarrayghostedin[i]) {
915: *iptr = dd->admfarrayghostedin[i];
916: iarray_start = (char*)dd->admfstartghostedin[i];
917: itdof = dd->ghostedtdof;
918: dd->admfarrayghostedin[i] = PETSC_NULL;
919: dd->admfstartghostedin[i] = PETSC_NULL;
920:
921: goto done;
922: }
923: }
924: xs = dd->Xs;
925: ys = dd->Ys;
926: xm = dd->Xe-dd->Xs;
927: ym = dd->Ye-dd->Ys;
928: } else {
929: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
930: if (dd->admfarrayin[i]) {
931: *iptr = dd->admfarrayin[i];
932: iarray_start = (char*)dd->admfstartin[i];
933: itdof = dd->tdof;
934: dd->admfarrayin[i] = PETSC_NULL;
935: dd->admfstartin[i] = PETSC_NULL;
936:
937: goto done;
938: }
939: }
940: xs = dd->xs;
941: ys = dd->ys;
942: xm = dd->xe-dd->xs;
943: ym = dd->ye-dd->ys;
944: }
946: switch (dd->dim) {
947: case 2: {
948: void **ptr;
949: itdof = xm*ym;
951: PetscMalloc((ym+1)*sizeof(void*)+xm*ym*5*sizeof(PetscScalar),&iarray_start);
953: ptr = (void**)(iarray_start + xm*ym*5*sizeof(PetscScalar) - ys*sizeof(void*));
954: for(j=ys;j<ys+ym;j++) {
955: ptr[j] = iarray_start + 5*sizeof(PetscScalar)*(xm*(j-ys) - xs);
956: }
957: *iptr = (void*)ptr;
958: break;}
959: default:
960: SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
961: }
963: done:
964: /* add arrays to the checked out list */
965: if (ghosted) {
966: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
967: if (!dd->admfarrayghostedout[i]) {
968: dd->admfarrayghostedout[i] = *iptr ;
969: dd->admfstartghostedout[i] = iarray_start;
970: dd->ghostedtdof = itdof;
971: break;
972: }
973: }
974: } else {
975: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
976: if (!dd->admfarrayout[i]) {
977: dd->admfarrayout[i] = *iptr ;
978: dd->admfstartout[i] = iarray_start;
979: dd->tdof = itdof;
980: break;
981: }
982: }
983: }
984: if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
985: if (tdof) *tdof = itdof;
986: if (array_start) *(void**)array_start = iarray_start;
987: return(0);
988: }
992: PetscErrorCode DMDAGetAdicMFArray9(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof)
993: {
995: PetscInt j,i,xs,ys,xm,ym,itdof = 0;
996: char *iarray_start;
997: void **iptr = (void**)vptr;
998: DM_DA *dd = (DM_DA*)da->data;
1002: if (ghosted) {
1003: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1004: if (dd->admfarrayghostedin[i]) {
1005: *iptr = dd->admfarrayghostedin[i];
1006: iarray_start = (char*)dd->admfstartghostedin[i];
1007: itdof = dd->ghostedtdof;
1008: dd->admfarrayghostedin[i] = PETSC_NULL;
1009: dd->admfstartghostedin[i] = PETSC_NULL;
1010:
1011: goto done;
1012: }
1013: }
1014: xs = dd->Xs;
1015: ys = dd->Ys;
1016: xm = dd->Xe-dd->Xs;
1017: ym = dd->Ye-dd->Ys;
1018: } else {
1019: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1020: if (dd->admfarrayin[i]) {
1021: *iptr = dd->admfarrayin[i];
1022: iarray_start = (char*)dd->admfstartin[i];
1023: itdof = dd->tdof;
1024: dd->admfarrayin[i] = PETSC_NULL;
1025: dd->admfstartin[i] = PETSC_NULL;
1026:
1027: goto done;
1028: }
1029: }
1030: xs = dd->xs;
1031: ys = dd->ys;
1032: xm = dd->xe-dd->xs;
1033: ym = dd->ye-dd->ys;
1034: }
1036: switch (dd->dim) {
1037: case 2: {
1038: void **ptr;
1039: itdof = xm*ym;
1041: PetscMalloc((ym+1)*sizeof(void*)+xm*ym*10*sizeof(PetscScalar),&iarray_start);
1043: ptr = (void**)(iarray_start + xm*ym*10*sizeof(PetscScalar) - ys*sizeof(void*));
1044: for(j=ys;j<ys+ym;j++) {
1045: ptr[j] = iarray_start + 10*sizeof(PetscScalar)*(xm*(j-ys) - xs);
1046: }
1047: *iptr = (void*)ptr;
1048: break;}
1049: default:
1050: SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
1051: }
1053: done:
1054: /* add arrays to the checked out list */
1055: if (ghosted) {
1056: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1057: if (!dd->admfarrayghostedout[i]) {
1058: dd->admfarrayghostedout[i] = *iptr ;
1059: dd->admfstartghostedout[i] = iarray_start;
1060: dd->ghostedtdof = itdof;
1061: break;
1062: }
1063: }
1064: } else {
1065: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1066: if (!dd->admfarrayout[i]) {
1067: dd->admfarrayout[i] = *iptr ;
1068: dd->admfstartout[i] = iarray_start;
1069: dd->tdof = itdof;
1070: break;
1071: }
1072: }
1073: }
1074: if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
1075: if (tdof) *tdof = itdof;
1076: if (array_start) *(void**)array_start = iarray_start;
1077: return(0);
1078: }
1082: /*@C
1083: DMDAGetAdicMFArrayb - Gets an array of derivative types for a DMDA for matrix-free ADIC.
1084:
1085: Input Parameter:
1086: + da - information about my local patch
1087: - ghosted - do you want arrays for the ghosted or nonghosted patch?
1089: Output Parameters:
1090: + vptr - array data structured to be passed to ad_FormFunctionLocal()
1091: . array_start - actual start of 1d array of all values that adiC can access directly (may be null)
1092: - tdof - total number of degrees of freedom represented in array_start (may be null)
1094: Notes:
1095: The vector values are NOT initialized and may have garbage in them, so you may need
1096: to zero them.
1098: This routine returns the same type of object as the DMDAVecGetArray(), except its
1099: elements are derivative types instead of PetscScalars.
1101: Level: advanced
1103: .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()
1105: @*/
1106: PetscErrorCode DMDAGetAdicMFArrayb(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof)
1107: {
1109: PetscInt j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
1110: char *iarray_start;
1111: void **iptr = (void**)vptr;
1112: DM_DA *dd = (DM_DA*)da->data;
1113: PetscInt bs = dd->w,bs1 = bs+1;
1117: if (ghosted) {
1118: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1119: if (dd->admfarrayghostedin[i]) {
1120: *iptr = dd->admfarrayghostedin[i];
1121: iarray_start = (char*)dd->admfstartghostedin[i];
1122: itdof = dd->ghostedtdof;
1123: dd->admfarrayghostedin[i] = PETSC_NULL;
1124: dd->admfstartghostedin[i] = PETSC_NULL;
1125:
1126: goto done;
1127: }
1128: }
1129: xs = dd->Xs;
1130: ys = dd->Ys;
1131: zs = dd->Zs;
1132: xm = dd->Xe-dd->Xs;
1133: ym = dd->Ye-dd->Ys;
1134: zm = dd->Ze-dd->Zs;
1135: } else {
1136: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1137: if (dd->admfarrayin[i]) {
1138: *iptr = dd->admfarrayin[i];
1139: iarray_start = (char*)dd->admfstartin[i];
1140: itdof = dd->tdof;
1141: dd->admfarrayin[i] = PETSC_NULL;
1142: dd->admfstartin[i] = PETSC_NULL;
1143:
1144: goto done;
1145: }
1146: }
1147: xs = dd->xs;
1148: ys = dd->ys;
1149: zs = dd->zs;
1150: xm = dd->xe-dd->xs;
1151: ym = dd->ye-dd->ys;
1152: zm = dd->ze-dd->zs;
1153: }
1155: switch (dd->dim) {
1156: case 1: {
1157: void *ptr;
1158: itdof = xm;
1160: PetscMalloc(xm*bs1*sizeof(PetscScalar),&iarray_start);
1162: ptr = (void*)(iarray_start - xs*bs1*sizeof(PetscScalar));
1163: *iptr = (void*)ptr;
1164: break;}
1165: case 2: {
1166: void **ptr;
1167: itdof = xm*ym;
1169: PetscMalloc((ym+1)*sizeof(void*)+xm*ym*bs1*sizeof(PetscScalar),&iarray_start);
1171: ptr = (void**)(iarray_start + xm*ym*bs1*sizeof(PetscScalar) - ys*sizeof(void*));
1172: for(j=ys;j<ys+ym;j++) {
1173: ptr[j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*(j-ys) - xs);
1174: }
1175: *iptr = (void*)ptr;
1176: break;}
1177: case 3: {
1178: void ***ptr,**bptr;
1179: itdof = xm*ym*zm;
1181: PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*bs1*sizeof(PetscScalar),&iarray_start);
1183: ptr = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
1184: bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
1185: for(i=zs;i<zs+zm;i++) {
1186: ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
1187: }
1188: for (i=zs; i<zs+zm; i++) {
1189: for (j=ys; j<ys+ym; j++) {
1190: ptr[i][j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
1191: }
1192: }
1194: *iptr = (void*)ptr;
1195: break;}
1196: default:
1197: SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
1198: }
1200: done:
1201: /* add arrays to the checked out list */
1202: if (ghosted) {
1203: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1204: if (!dd->admfarrayghostedout[i]) {
1205: dd->admfarrayghostedout[i] = *iptr ;
1206: dd->admfstartghostedout[i] = iarray_start;
1207: dd->ghostedtdof = itdof;
1208: break;
1209: }
1210: }
1211: } else {
1212: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1213: if (!dd->admfarrayout[i]) {
1214: dd->admfarrayout[i] = *iptr ;
1215: dd->admfstartout[i] = iarray_start;
1216: dd->tdof = itdof;
1217: break;
1218: }
1219: }
1220: }
1221: if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
1222: if (tdof) *tdof = itdof;
1223: if (array_start) *(void**)array_start = iarray_start;
1224: return(0);
1225: }
1229: /*@C
1230: DMDARestoreAdicMFArray - Restores an array of derivative types for a DMDA.
1231:
1232: Input Parameter:
1233: + da - information about my local patch
1234: - ghosted - do you want arrays for the ghosted or nonghosted patch?
1236: Output Parameters:
1237: + ptr - array data structure to be passed to ad_FormFunctionLocal()
1238: . array_start - actual start of 1d array of all values that adiC can access directly
1239: - tdof - total number of degrees of freedom represented in array_start
1241: Level: advanced
1243: .seealso: DMDAGetAdicArray()
1245: @*/
1246: PetscErrorCode DMDARestoreAdicMFArray(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof)
1247: {
1248: PetscInt i;
1249: void **iptr = (void**)vptr,*iarray_start = 0;
1250: DM_DA *dd = (DM_DA*)da->data;
1251:
1254: if (ghosted) {
1255: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1256: if (dd->admfarrayghostedout[i] == *iptr) {
1257: iarray_start = dd->admfstartghostedout[i];
1258: dd->admfarrayghostedout[i] = PETSC_NULL;
1259: dd->admfstartghostedout[i] = PETSC_NULL;
1260: break;
1261: }
1262: }
1263: if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1264: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1265: if (!dd->admfarrayghostedin[i]){
1266: dd->admfarrayghostedin[i] = *iptr;
1267: dd->admfstartghostedin[i] = iarray_start;
1268: break;
1269: }
1270: }
1271: } else {
1272: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1273: if (dd->admfarrayout[i] == *iptr) {
1274: iarray_start = dd->admfstartout[i];
1275: dd->admfarrayout[i] = PETSC_NULL;
1276: dd->admfstartout[i] = PETSC_NULL;
1277: break;
1278: }
1279: }
1280: if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1281: for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1282: if (!dd->admfarrayin[i]){
1283: dd->admfarrayin[i] = *iptr;
1284: dd->admfstartin[i] = iarray_start;
1285: break;
1286: }
1287: }
1288: }
1289: return(0);
1290: }
1294: PetscErrorCode admf_DAGetArray(DM da,PetscBool ghosted,void *iptr)
1295: {
1298: DMDAGetAdicMFArray(da,ghosted,iptr,0,0);
1299: return(0);
1300: }
1304: PetscErrorCode admf_DARestoreArray(DM da,PetscBool ghosted,void *iptr)
1305: {
1308: DMDARestoreAdicMFArray(da,ghosted,iptr,0,0);
1309: return(0);
1310: }