Actual source code: dalocal.c

  2: /*
  3:   Code for manipulating distributed regular arrays in parallel.
  4: */

  6: #include <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 */
 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: }
 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:   VecSetType(*g,da->vectype);
 61:   VecSetBlockSize(*g,dd->w);
 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: /*@
 74:    DMGetLocalVector - Gets a Seq PETSc vector that
 75:    may be used with the DMXXX routines. This vector has spaces for the ghost values.

 77:    Not Collective

 79:    Input Parameter:
 80: .  dm - the distributed array

 82:    Output Parameter:
 83: .  g - the local vector

 85:    Level: beginner

 87:    Note:
 88:    The vector values are NOT initialized and may have garbage in them, so you may need
 89:    to zero them.

 91:    The output parameter, g, is a regular PETSc vector that should be returned with 
 92:    DMRestoreLocalVector() DO NOT call VecDestroy() on it.

 94:    VecStride*() operations can be useful when using DM with dof > 1

 96: .keywords: distributed array, create, local, vector

 98: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
 99:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
100:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
101:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
102: @*/
103: PetscErrorCode  DMGetLocalVector(DM dm,Vec* g)
104: {
105:   PetscErrorCode ierr,i;

110:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
111:     if (dm->localin[i]) {
112:       *g             = dm->localin[i];
113:       dm->localin[i] = PETSC_NULL;
114:       goto alldone;
115:     }
116:   }
117:   DMCreateLocalVector(dm,g);

119:   alldone:
120:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
121:     if (!dm->localout[i]) {
122:       dm->localout[i] = *g;
123:       break;
124:     }
125:   }
126:   return(0);
127: }

131: /*@
132:    DMRestoreLocalVector - Returns a Seq PETSc vector that
133:      obtained from DMGetLocalVector(). Do not use with vector obtained via
134:      DMCreateLocalVector().

136:    Not Collective

138:    Input Parameter:
139: +  dm - the distributed array
140: -  g - the local vector

142:    Level: beginner

144: .keywords: distributed array, create, local, vector

146: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
147:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
148:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
149: @*/
150: PetscErrorCode  DMRestoreLocalVector(DM dm,Vec* g)
151: {
153:   PetscInt       i,j;

158:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
159:     if (*g == dm->localout[j]) {
160:       dm->localout[j] = PETSC_NULL;
161:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
162:         if (!dm->localin[i]) {
163:           dm->localin[i] = *g;
164:           goto alldone;
165:         }
166:       }
167:     }
168:   }
169:   VecDestroy(g);
170:   alldone:
171:   return(0);
172: }

176: /*@
177:    DMGetGlobalVector - Gets a MPI PETSc vector that
178:    may be used with the DMXXX routines.

180:    Collective on DM

182:    Input Parameter:
183: .  dm - the distributed array

185:    Output Parameter:
186: .  g - the global vector

188:    Level: beginner

190:    Note:
191:    The vector values are NOT initialized and may have garbage in them, so you may need
192:    to zero them.

194:    The output parameter, g, is a regular PETSc vector that should be returned with 
195:    DMRestoreGlobalVector() DO NOT call VecDestroy() on it.

197:    VecStride*() operations can be useful when using DM with dof > 1

199: .keywords: distributed array, create, Global, vector

201: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
202:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
203:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
204:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

206: @*/
207: PetscErrorCode  DMGetGlobalVector(DM dm,Vec* g)
208: {
210:   PetscInt       i;

215:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
216:     if (dm->globalin[i]) {
217:       *g             = dm->globalin[i];
218:       dm->globalin[i] = PETSC_NULL;
219:       goto alldone;
220:     }
221:   }
222:   DMCreateGlobalVector(dm,g);

224:   alldone:
225:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
226:     if (!dm->globalout[i]) {
227:       dm->globalout[i] = *g;
228:       break;
229:     }
230:   }
231:   return(0);
232: }

236: /*@
237:    DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM

239:    Collective on DM

241:    Input Parameter:
242: .  dm - the distributed array

244:    Level: developer

246: .keywords: distributed array, create, Global, vector

248: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
249:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
250:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
251:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

253: @*/
254: PetscErrorCode  DMClearGlobalVectors(DM dm)
255: {
257:   PetscInt       i;

261:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
262:     if (dm->globalout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of global vectors that has a global vector obtained with DMGetGlobalVector()");
263:     VecDestroy(&dm->globalin[i]);
264:   }
265:   return(0);
266: }

270: /*@
271:    DMRestoreGlobalVector - Returns a Seq PETSc vector that
272:      obtained from DMGetGlobalVector(). Do not use with vector obtained via
273:      DMCreateGlobalVector().

275:    Not Collective

277:    Input Parameter:
278: +  dm - the distributed array
279: -  g - the global vector

281:    Level: beginner

283: .keywords: distributed array, create, global, vector

285: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
286:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
287:           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
288: @*/
289: PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec* g)
290: {
292:   PetscInt       i,j;

297:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
298:     if (*g == dm->globalout[j]) {
299:       dm->globalout[j] = PETSC_NULL;
300:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
301:         if (!dm->globalin[i]) {
302:           dm->globalin[i] = *g;
303:           goto alldone;
304:         }
305:       }
306:     }
307:   }
308:   VecDestroy(g);
309:   alldone:
310:   return(0);
311: }

313: /* ------------------------------------------------------------------- */
314: #if defined(PETSC_HAVE_ADIC)

317: #include <adic/ad_utils.h>

322: /*@C
323:      DMDAGetAdicArray - Gets an array of derivative types for a DMDA
324:           
325:     Input Parameter:
326: +    da - information about my local patch
327: -    ghosted - do you want arrays for the ghosted or nonghosted patch

329:     Output Parameters:
330: +    vptr - array data structured to be passed to ad_FormFunctionLocal()
331: .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
332: -    tdof - total number of degrees of freedom represented in array_start (may be null)

334:      Notes:
335:        The vector values are NOT initialized and may have garbage in them, so you may need
336:        to zero them.

338:        Returns the same type of object as the DMDAVecGetArray() except its elements are 
339:            derivative types instead of PetscScalars

341:      Level: advanced

343: .seealso: DMDARestoreAdicArray()

345: @*/
346: PetscErrorCode  DMDAGetAdicArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
347: {
349:   PetscInt       j,i,deriv_type_size,xs,ys,xm,ym,zs,zm,itdof;
350:   char           *iarray_start;
351:   void           **iptr = (void**)vptr;
352:   DM_DA          *dd = (DM_DA*)da->data;

356:   if (ghosted) {
357:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
358:       if (dd->adarrayghostedin[i]) {
359:         *iptr                   = dd->adarrayghostedin[i];
360:         iarray_start            = (char*)dd->adstartghostedin[i];
361:         itdof                   = dd->ghostedtdof;
362:         dd->adarrayghostedin[i] = PETSC_NULL;
363:         dd->adstartghostedin[i] = PETSC_NULL;
364: 
365:         goto done;
366:       }
367:     }
368:     xs = dd->Xs;
369:     ys = dd->Ys;
370:     zs = dd->Zs;
371:     xm = dd->Xe-dd->Xs;
372:     ym = dd->Ye-dd->Ys;
373:     zm = dd->Ze-dd->Zs;
374:   } else {
375:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
376:       if (dd->adarrayin[i]) {
377:         *iptr            = dd->adarrayin[i];
378:         iarray_start     = (char*)dd->adstartin[i];
379:         itdof            = dd->tdof;
380:         dd->adarrayin[i] = PETSC_NULL;
381:         dd->adstartin[i] = PETSC_NULL;
382: 
383:         goto done;
384:       }
385:     }
386:     xs = dd->xs;
387:     ys = dd->ys;
388:     zs = dd->zs;
389:     xm = dd->xe-dd->xs;
390:     ym = dd->ye-dd->ys;
391:     zm = dd->ze-dd->zs;
392:   }
393:   deriv_type_size = PetscADGetDerivTypeSize();

395:   switch (dd->dim) {
396:     case 1: {
397:       void *ptr;
398:       itdof = xm;

400:       PetscMalloc(xm*deriv_type_size,&iarray_start);

402:       ptr   = (void*)(iarray_start - xs*deriv_type_size);
403:       *iptr = (void*)ptr;
404:       break;}
405:     case 2: {
406:       void **ptr;
407:       itdof = xm*ym;

409:       PetscMalloc((ym+1)*sizeof(void*)+xm*ym*deriv_type_size,&iarray_start);

411:       ptr  = (void**)(iarray_start + xm*ym*deriv_type_size - ys*sizeof(void*));
412:       for(j=ys;j<ys+ym;j++) {
413:         ptr[j] = iarray_start + deriv_type_size*(xm*(j-ys) - xs);
414:       }
415:       *iptr = (void*)ptr;
416:       break;}
417:     case 3: {
418:       void ***ptr,**bptr;
419:       itdof = xm*ym*zm;

421:       PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*deriv_type_size,&iarray_start);

423:       ptr  = (void***)(iarray_start + xm*ym*zm*deriv_type_size - zs*sizeof(void*));
424:       bptr = (void**)(iarray_start + xm*ym*zm*deriv_type_size + zm*sizeof(void**));

426:       for(i=zs;i<zs+zm;i++) {
427:         ptr[i] = bptr + ((i-zs)*ym - ys);
428:       }
429:       for (i=zs; i<zs+zm; i++) {
430:         for (j=ys; j<ys+ym; j++) {
431:           ptr[i][j] = iarray_start + deriv_type_size*(xm*ym*(i-zs) + xm*(j-ys) - xs);
432:         }
433:       }

435:       *iptr = (void*)ptr;
436:       break;}
437:     default:
438:       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
439:   }

441:   done:
442:   /* add arrays to the checked out list */
443:   if (ghosted) {
444:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
445:       if (!dd->adarrayghostedout[i]) {
446:         dd->adarrayghostedout[i] = *iptr ;
447:         dd->adstartghostedout[i] = iarray_start;
448:         dd->ghostedtdof          = itdof;
449:         break;
450:       }
451:     }
452:   } else {
453:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
454:       if (!dd->adarrayout[i]) {
455:         dd->adarrayout[i] = *iptr ;
456:         dd->adstartout[i] = iarray_start;
457:         dd->tdof          = itdof;
458:         break;
459:       }
460:     }
461:   }
462:   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Too many DMDA ADIC arrays obtained");
463:   if (tdof)        *tdof = itdof;
464:   if (array_start) *(void**)array_start = iarray_start;
465:   return(0);
466: }

470: /*@C
471:      DMDARestoreAdicArray - Restores an array of derivative types for a DMDA
472:           
473:     Input Parameter:
474: +    da - information about my local patch
475: -    ghosted - do you want arrays for the ghosted or nonghosted patch

477:     Output Parameters:
478: +    ptr - array data structured to be passed to ad_FormFunctionLocal()
479: .    array_start - actual start of 1d array of all values that adiC can access directly
480: -    tdof - total number of degrees of freedom represented in array_start

482:      Level: advanced

484: .seealso: DMDAGetAdicArray()

486: @*/
487: PetscErrorCode  DMDARestoreAdicArray(DM da,PetscBool  ghosted,void *ptr,void *array_start,PetscInt *tdof)
488: {
489:   PetscInt  i;
490:   void      **iptr = (void**)ptr,iarray_start = 0;
491: 
494:   if (ghosted) {
495:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
496:       if (dd->adarrayghostedout[i] == *iptr) {
497:         iarray_start             = dd->adstartghostedout[i];
498:         dd->adarrayghostedout[i] = PETSC_NULL;
499:         dd->adstartghostedout[i] = PETSC_NULL;
500:         break;
501:       }
502:     }
503:     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
504:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
505:       if (!dd->adarrayghostedin[i]){
506:         dd->adarrayghostedin[i] = *iptr;
507:         dd->adstartghostedin[i] = iarray_start;
508:         break;
509:       }
510:     }
511:   } else {
512:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
513:       if (dd->adarrayout[i] == *iptr) {
514:         iarray_start      = dd->adstartout[i];
515:         dd->adarrayout[i] = PETSC_NULL;
516:         dd->adstartout[i] = PETSC_NULL;
517:         break;
518:       }
519:     }
520:     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
521:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
522:       if (!dd->adarrayin[i]){
523:         dd->adarrayin[i]   = *iptr;
524:         dd->adstartin[i]   = iarray_start;
525:         break;
526:       }
527:     }
528:   }
529:   return(0);
530: }

534: PetscErrorCode  ad_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
535: {
538:   DMDAGetAdicArray(da,ghosted,iptr,0,0);
539:   return(0);
540: }

544: PetscErrorCode  ad_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
545: {
548:   DMDARestoreAdicArray(da,ghosted,iptr,0,0);
549:   return(0);
550: }

552: #endif

556: /*@C
557:      DMDAGetArray - Gets a work array for a DMDA

559:     Input Parameter:
560: +    da - information about my local patch
561: -    ghosted - do you want arrays for the ghosted or nonghosted patch

563:     Output Parameters:
564: .    vptr - array data structured

566:     Note:  The vector values are NOT initialized and may have garbage in them, so you may need
567:            to zero them.

569:   Level: advanced

571: .seealso: DMDARestoreArray(), DMDAGetAdicArray()

573: @*/
574: PetscErrorCode  DMDAGetArray(DM da,PetscBool  ghosted,void *vptr)
575: {
577:   PetscInt       j,i,xs,ys,xm,ym,zs,zm;
578:   char           *iarray_start;
579:   void           **iptr = (void**)vptr;
580:   DM_DA          *dd = (DM_DA*)da->data;

584:   if (ghosted) {
585:     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
586:       if (dd->arrayghostedin[i]) {
587:         *iptr                 = dd->arrayghostedin[i];
588:         iarray_start          = (char*)dd->startghostedin[i];
589:         dd->arrayghostedin[i] = PETSC_NULL;
590:         dd->startghostedin[i] = PETSC_NULL;
591: 
592:         goto done;
593:       }
594:     }
595:     xs = dd->Xs;
596:     ys = dd->Ys;
597:     zs = dd->Zs;
598:     xm = dd->Xe-dd->Xs;
599:     ym = dd->Ye-dd->Ys;
600:     zm = dd->Ze-dd->Zs;
601:   } else {
602:     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
603:       if (dd->arrayin[i]) {
604:         *iptr          = dd->arrayin[i];
605:         iarray_start   = (char*)dd->startin[i];
606:         dd->arrayin[i] = PETSC_NULL;
607:         dd->startin[i] = PETSC_NULL;
608: 
609:         goto done;
610:       }
611:     }
612:     xs = dd->xs;
613:     ys = dd->ys;
614:     zs = dd->zs;
615:     xm = dd->xe-dd->xs;
616:     ym = dd->ye-dd->ys;
617:     zm = dd->ze-dd->zs;
618:   }

620:   switch (dd->dim) {
621:     case 1: {
622:       void *ptr;

624:       PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);

626:       ptr   = (void*)(iarray_start - xs*sizeof(PetscScalar));
627:       *iptr = (void*)ptr;
628:       break;}
629:     case 2: {
630:       void **ptr;

632:       PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);

634:       ptr  = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*));
635:       for(j=ys;j<ys+ym;j++) {
636:         ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs);
637:       }
638:       *iptr = (void*)ptr;
639:       break;}
640:     case 3: {
641:       void ***ptr,**bptr;

643:       PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);

645:       ptr  = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*));
646:       bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**));
647:       for(i=zs;i<zs+zm;i++) {
648:         ptr[i] = bptr + ((i-zs)*ym - ys);
649:       }
650:       for (i=zs; i<zs+zm; i++) {
651:         for (j=ys; j<ys+ym; j++) {
652:           ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
653:         }
654:       }

656:       *iptr = (void*)ptr;
657:       break;}
658:     default:
659:       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
660:   }

662:   done:
663:   /* add arrays to the checked out list */
664:   if (ghosted) {
665:     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
666:       if (!dd->arrayghostedout[i]) {
667:         dd->arrayghostedout[i] = *iptr ;
668:         dd->startghostedout[i] = iarray_start;
669:         break;
670:       }
671:     }
672:   } else {
673:     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
674:       if (!dd->arrayout[i]) {
675:         dd->arrayout[i] = *iptr ;
676:         dd->startout[i] = iarray_start;
677:         break;
678:       }
679:     }
680:   }
681:   return(0);
682: }

686: /*@C
687:      DMDARestoreArray - Restores an array of derivative types for a DMDA
688:           
689:     Input Parameter:
690: +    da - information about my local patch
691: .    ghosted - do you want arrays for the ghosted or nonghosted patch
692: -    vptr - array data structured to be passed to ad_FormFunctionLocal()

694:      Level: advanced

696: .seealso: DMDAGetArray(), DMDAGetAdicArray()

698: @*/
699: PetscErrorCode  DMDARestoreArray(DM da,PetscBool  ghosted,void *vptr)
700: {
701:   PetscInt  i;
702:   void      **iptr = (void**)vptr,*iarray_start = 0;
703:   DM_DA     *dd = (DM_DA*)da->data;
704: 
707:   if (ghosted) {
708:     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
709:       if (dd->arrayghostedout[i] == *iptr) {
710:         iarray_start           = dd->startghostedout[i];
711:         dd->arrayghostedout[i] = PETSC_NULL;
712:         dd->startghostedout[i] = PETSC_NULL;
713:         break;
714:       }
715:     }
716:     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
717:       if (!dd->arrayghostedin[i]){
718:         dd->arrayghostedin[i] = *iptr;
719:         dd->startghostedin[i] = iarray_start;
720:         break;
721:       }
722:     }
723:   } else {
724:     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
725:       if (dd->arrayout[i] == *iptr) {
726:         iarray_start    = dd->startout[i];
727:         dd->arrayout[i] = PETSC_NULL;
728:         dd->startout[i] = PETSC_NULL;
729:         break;
730:       }
731:     }
732:     for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) {
733:       if (!dd->arrayin[i]){
734:         dd->arrayin[i]  = *iptr;
735:         dd->startin[i]  = iarray_start;
736:         break;
737:       }
738:     }
739:   }
740:   return(0);
741: }

745: /*@C
746:      DMDAGetAdicMFArray - Gets an array of derivative types for a DMDA for matrix-free ADIC.
747:           
748:      Input Parameter:
749: +    da - information about my local patch
750: -    ghosted - do you want arrays for the ghosted or nonghosted patch?

752:      Output Parameters:
753: +    vptr - array data structured to be passed to ad_FormFunctionLocal()
754: .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
755: -    tdof - total number of degrees of freedom represented in array_start (may be null)

757:      Notes: 
758:      The vector values are NOT initialized and may have garbage in them, so you may need
759:      to zero them.

761:      This routine returns the same type of object as the DMDAVecGetArray(), except its
762:      elements are derivative types instead of PetscScalars.

764:      Level: advanced

766: .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()

768: @*/
769: PetscErrorCode  DMDAGetAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
770: {
772:   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
773:   char           *iarray_start;
774:   void           **iptr = (void**)vptr;
775:   DM_DA          *dd = (DM_DA*)da->data;

779:   if (ghosted) {
780:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
781:       if (dd->admfarrayghostedin[i]) {
782:         *iptr                     = dd->admfarrayghostedin[i];
783:         iarray_start              = (char*)dd->admfstartghostedin[i];
784:         itdof                     = dd->ghostedtdof;
785:         dd->admfarrayghostedin[i] = PETSC_NULL;
786:         dd->admfstartghostedin[i] = PETSC_NULL;
787: 
788:         goto done;
789:       }
790:     }
791:     xs = dd->Xs;
792:     ys = dd->Ys;
793:     zs = dd->Zs;
794:     xm = dd->Xe-dd->Xs;
795:     ym = dd->Ye-dd->Ys;
796:     zm = dd->Ze-dd->Zs;
797:   } else {
798:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
799:       if (dd->admfarrayin[i]) {
800:         *iptr              = dd->admfarrayin[i];
801:         iarray_start       = (char*)dd->admfstartin[i];
802:         itdof              = dd->tdof;
803:         dd->admfarrayin[i] = PETSC_NULL;
804:         dd->admfstartin[i] = PETSC_NULL;
805: 
806:         goto done;
807:       }
808:     }
809:     xs = dd->xs;
810:     ys = dd->ys;
811:     zs = dd->zs;
812:     xm = dd->xe-dd->xs;
813:     ym = dd->ye-dd->ys;
814:     zm = dd->ze-dd->zs;
815:   }

817:   switch (dd->dim) {
818:     case 1: {
819:       void *ptr;
820:       itdof = xm;

822:       PetscMalloc(xm*2*sizeof(PetscScalar),&iarray_start);

824:       ptr   = (void*)(iarray_start - xs*2*sizeof(PetscScalar));
825:       *iptr = (void*)ptr;
826:       break;}
827:     case 2: {
828:       void **ptr;
829:       itdof = xm*ym;

831:       PetscMalloc((ym+1)*sizeof(void*)+xm*ym*2*sizeof(PetscScalar),&iarray_start);

833:       ptr  = (void**)(iarray_start + xm*ym*2*sizeof(PetscScalar) - ys*sizeof(void*));
834:       for(j=ys;j<ys+ym;j++) {
835:         ptr[j] = iarray_start + 2*sizeof(PetscScalar)*(xm*(j-ys) - xs);
836:       }
837:       *iptr = (void*)ptr;
838:       break;}
839:     case 3: {
840:       void ***ptr,**bptr;
841:       itdof = xm*ym*zm;

843:       PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*2*sizeof(PetscScalar),&iarray_start);

845:       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
846:       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
847:       for(i=zs;i<zs+zm;i++) {
848:         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
849:       }
850:       for (i=zs; i<zs+zm; i++) {
851:         for (j=ys; j<ys+ym; j++) {
852:           ptr[i][j] = iarray_start + 2*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
853:         }
854:       }

856:       *iptr = (void*)ptr;
857:       break;}
858:     default:
859:       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
860:   }

862:   done:
863:   /* add arrays to the checked out list */
864:   if (ghosted) {
865:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
866:       if (!dd->admfarrayghostedout[i]) {
867:         dd->admfarrayghostedout[i] = *iptr ;
868:         dd->admfstartghostedout[i] = iarray_start;
869:         dd->ghostedtdof            = itdof;
870:         break;
871:       }
872:     }
873:   } else {
874:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
875:       if (!dd->admfarrayout[i]) {
876:         dd->admfarrayout[i] = *iptr ;
877:         dd->admfstartout[i] = iarray_start;
878:         dd->tdof            = itdof;
879:         break;
880:       }
881:     }
882:   }
883:   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
884:   if (tdof)        *tdof = itdof;
885:   if (array_start) *(void**)array_start = iarray_start;
886:   return(0);
887: }

891: PetscErrorCode  DMDAGetAdicMFArray4(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
892: {
894:   PetscInt       j,i,xs,ys,xm,ym,itdof = 0;
895:   char           *iarray_start;
896:   void           **iptr = (void**)vptr;
897:   DM_DA          *dd = (DM_DA*)da->data;

901:   if (ghosted) {
902:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
903:       if (dd->admfarrayghostedin[i]) {
904:         *iptr                     = dd->admfarrayghostedin[i];
905:         iarray_start              = (char*)dd->admfstartghostedin[i];
906:         itdof                     = dd->ghostedtdof;
907:         dd->admfarrayghostedin[i] = PETSC_NULL;
908:         dd->admfstartghostedin[i] = PETSC_NULL;
909: 
910:         goto done;
911:       }
912:     }
913:     xs = dd->Xs;
914:     ys = dd->Ys;
915:     xm = dd->Xe-dd->Xs;
916:     ym = dd->Ye-dd->Ys;
917:   } else {
918:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
919:       if (dd->admfarrayin[i]) {
920:         *iptr              = dd->admfarrayin[i];
921:         iarray_start       = (char*)dd->admfstartin[i];
922:         itdof              = dd->tdof;
923:         dd->admfarrayin[i] = PETSC_NULL;
924:         dd->admfstartin[i] = PETSC_NULL;
925: 
926:         goto done;
927:       }
928:     }
929:     xs = dd->xs;
930:     ys = dd->ys;
931:     xm = dd->xe-dd->xs;
932:     ym = dd->ye-dd->ys;
933:   }

935:   switch (dd->dim) {
936:     case 2: {
937:       void **ptr;
938:       itdof = xm*ym;

940:       PetscMalloc((ym+1)*sizeof(void*)+xm*ym*5*sizeof(PetscScalar),&iarray_start);

942:       ptr  = (void**)(iarray_start + xm*ym*5*sizeof(PetscScalar) - ys*sizeof(void*));
943:       for(j=ys;j<ys+ym;j++) {
944:         ptr[j] = iarray_start + 5*sizeof(PetscScalar)*(xm*(j-ys) - xs);
945:       }
946:       *iptr = (void*)ptr;
947:       break;}
948:     default:
949:       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
950:   }

952:   done:
953:   /* add arrays to the checked out list */
954:   if (ghosted) {
955:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
956:       if (!dd->admfarrayghostedout[i]) {
957:         dd->admfarrayghostedout[i] = *iptr ;
958:         dd->admfstartghostedout[i] = iarray_start;
959:         dd->ghostedtdof            = itdof;
960:         break;
961:       }
962:     }
963:   } else {
964:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
965:       if (!dd->admfarrayout[i]) {
966:         dd->admfarrayout[i] = *iptr ;
967:         dd->admfstartout[i] = iarray_start;
968:         dd->tdof            = itdof;
969:         break;
970:       }
971:     }
972:   }
973:   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
974:   if (tdof)        *tdof = itdof;
975:   if (array_start) *(void**)array_start = iarray_start;
976:   return(0);
977: }

981: PetscErrorCode  DMDAGetAdicMFArray9(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
982: {
984:   PetscInt       j,i,xs,ys,xm,ym,itdof = 0;
985:   char           *iarray_start;
986:   void           **iptr = (void**)vptr;
987:   DM_DA          *dd = (DM_DA*)da->data;

991:   if (ghosted) {
992:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
993:       if (dd->admfarrayghostedin[i]) {
994:         *iptr                     = dd->admfarrayghostedin[i];
995:         iarray_start              = (char*)dd->admfstartghostedin[i];
996:         itdof                     = dd->ghostedtdof;
997:         dd->admfarrayghostedin[i] = PETSC_NULL;
998:         dd->admfstartghostedin[i] = PETSC_NULL;
999: 
1000:         goto done;
1001:       }
1002:     }
1003:     xs = dd->Xs;
1004:     ys = dd->Ys;
1005:     xm = dd->Xe-dd->Xs;
1006:     ym = dd->Ye-dd->Ys;
1007:   } else {
1008:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1009:       if (dd->admfarrayin[i]) {
1010:         *iptr              = dd->admfarrayin[i];
1011:         iarray_start       = (char*)dd->admfstartin[i];
1012:         itdof              = dd->tdof;
1013:         dd->admfarrayin[i] = PETSC_NULL;
1014:         dd->admfstartin[i] = PETSC_NULL;
1015: 
1016:         goto done;
1017:       }
1018:     }
1019:     xs = dd->xs;
1020:     ys = dd->ys;
1021:     xm = dd->xe-dd->xs;
1022:     ym = dd->ye-dd->ys;
1023:   }

1025:   switch (dd->dim) {
1026:     case 2: {
1027:       void **ptr;
1028:       itdof = xm*ym;

1030:       PetscMalloc((ym+1)*sizeof(void*)+xm*ym*10*sizeof(PetscScalar),&iarray_start);

1032:       ptr  = (void**)(iarray_start + xm*ym*10*sizeof(PetscScalar) - ys*sizeof(void*));
1033:       for(j=ys;j<ys+ym;j++) {
1034:         ptr[j] = iarray_start + 10*sizeof(PetscScalar)*(xm*(j-ys) - xs);
1035:       }
1036:       *iptr = (void*)ptr;
1037:       break;}
1038:     default:
1039:       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
1040:   }

1042:   done:
1043:   /* add arrays to the checked out list */
1044:   if (ghosted) {
1045:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1046:       if (!dd->admfarrayghostedout[i]) {
1047:         dd->admfarrayghostedout[i] = *iptr ;
1048:         dd->admfstartghostedout[i] = iarray_start;
1049:         dd->ghostedtdof            = itdof;
1050:         break;
1051:       }
1052:     }
1053:   } else {
1054:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1055:       if (!dd->admfarrayout[i]) {
1056:         dd->admfarrayout[i] = *iptr ;
1057:         dd->admfstartout[i] = iarray_start;
1058:         dd->tdof            = itdof;
1059:         break;
1060:       }
1061:     }
1062:   }
1063:   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
1064:   if (tdof)        *tdof = itdof;
1065:   if (array_start) *(void**)array_start = iarray_start;
1066:   return(0);
1067: }

1071: /*@C
1072:      DMDAGetAdicMFArrayb - Gets an array of derivative types for a DMDA for matrix-free ADIC.
1073:           
1074:      Input Parameter:
1075: +    da - information about my local patch
1076: -    ghosted - do you want arrays for the ghosted or nonghosted patch?

1078:      Output Parameters:
1079: +    vptr - array data structured to be passed to ad_FormFunctionLocal()
1080: .    array_start - actual start of 1d array of all values that adiC can access directly (may be null)
1081: -    tdof - total number of degrees of freedom represented in array_start (may be null)

1083:      Notes: 
1084:      The vector values are NOT initialized and may have garbage in them, so you may need
1085:      to zero them.

1087:      This routine returns the same type of object as the DMDAVecGetArray(), except its
1088:      elements are derivative types instead of PetscScalars.

1090:      Level: advanced

1092: .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray()

1094: @*/
1095: PetscErrorCode  DMDAGetAdicMFArrayb(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
1096: {
1098:   PetscInt       j,i,xs,ys,xm,ym,zs,zm,itdof = 0;
1099:   char           *iarray_start;
1100:   void           **iptr = (void**)vptr;
1101:   DM_DA          *dd = (DM_DA*)da->data;
1102:   PetscInt       bs = dd->w,bs1 = bs+1;

1106:   if (ghosted) {
1107:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1108:       if (dd->admfarrayghostedin[i]) {
1109:         *iptr                     = dd->admfarrayghostedin[i];
1110:         iarray_start              = (char*)dd->admfstartghostedin[i];
1111:         itdof                     = dd->ghostedtdof;
1112:         dd->admfarrayghostedin[i] = PETSC_NULL;
1113:         dd->admfstartghostedin[i] = PETSC_NULL;
1114: 
1115:         goto done;
1116:       }
1117:     }
1118:     xs = dd->Xs;
1119:     ys = dd->Ys;
1120:     zs = dd->Zs;
1121:     xm = dd->Xe-dd->Xs;
1122:     ym = dd->Ye-dd->Ys;
1123:     zm = dd->Ze-dd->Zs;
1124:   } else {
1125:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1126:       if (dd->admfarrayin[i]) {
1127:         *iptr              = dd->admfarrayin[i];
1128:         iarray_start       = (char*)dd->admfstartin[i];
1129:         itdof              = dd->tdof;
1130:         dd->admfarrayin[i] = PETSC_NULL;
1131:         dd->admfstartin[i] = PETSC_NULL;
1132: 
1133:         goto done;
1134:       }
1135:     }
1136:     xs = dd->xs;
1137:     ys = dd->ys;
1138:     zs = dd->zs;
1139:     xm = dd->xe-dd->xs;
1140:     ym = dd->ye-dd->ys;
1141:     zm = dd->ze-dd->zs;
1142:   }

1144:   switch (dd->dim) {
1145:     case 1: {
1146:       void *ptr;
1147:       itdof = xm;

1149:       PetscMalloc(xm*bs1*sizeof(PetscScalar),&iarray_start);

1151:       ptr   = (void*)(iarray_start - xs*bs1*sizeof(PetscScalar));
1152:       *iptr = (void*)ptr;
1153:       break;}
1154:     case 2: {
1155:       void **ptr;
1156:       itdof = xm*ym;

1158:       PetscMalloc((ym+1)*sizeof(void*)+xm*ym*bs1*sizeof(PetscScalar),&iarray_start);

1160:       ptr  = (void**)(iarray_start + xm*ym*bs1*sizeof(PetscScalar) - ys*sizeof(void*));
1161:       for(j=ys;j<ys+ym;j++) {
1162:         ptr[j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*(j-ys) - xs);
1163:       }
1164:       *iptr = (void*)ptr;
1165:       break;}
1166:     case 3: {
1167:       void ***ptr,**bptr;
1168:       itdof = xm*ym*zm;

1170:       PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*bs1*sizeof(PetscScalar),&iarray_start);

1172:       ptr  = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*));
1173:       bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**));
1174:       for(i=zs;i<zs+zm;i++) {
1175:         ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*);
1176:       }
1177:       for (i=zs; i<zs+zm; i++) {
1178:         for (j=ys; j<ys+ym; j++) {
1179:           ptr[i][j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs);
1180:         }
1181:       }

1183:       *iptr = (void*)ptr;
1184:       break;}
1185:     default:
1186:       SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim);
1187:   }

1189:   done:
1190:   /* add arrays to the checked out list */
1191:   if (ghosted) {
1192:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1193:       if (!dd->admfarrayghostedout[i]) {
1194:         dd->admfarrayghostedout[i] = *iptr ;
1195:         dd->admfstartghostedout[i] = iarray_start;
1196:         dd->ghostedtdof            = itdof;
1197:         break;
1198:       }
1199:     }
1200:   } else {
1201:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1202:       if (!dd->admfarrayout[i]) {
1203:         dd->admfarrayout[i] = *iptr ;
1204:         dd->admfstartout[i] = iarray_start;
1205:         dd->tdof            = itdof;
1206:         break;
1207:       }
1208:     }
1209:   }
1210:   if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained");
1211:   if (tdof)        *tdof = itdof;
1212:   if (array_start) *(void**)array_start = iarray_start;
1213:   return(0);
1214: }

1218: /*@C
1219:      DMDARestoreAdicMFArray - Restores an array of derivative types for a DMDA.
1220:           
1221:      Input Parameter:
1222: +    da - information about my local patch
1223: -    ghosted - do you want arrays for the ghosted or nonghosted patch?

1225:      Output Parameters:
1226: +    ptr - array data structure to be passed to ad_FormFunctionLocal()
1227: .    array_start - actual start of 1d array of all values that adiC can access directly
1228: -    tdof - total number of degrees of freedom represented in array_start

1230:      Level: advanced

1232: .seealso: DMDAGetAdicArray()

1234: @*/
1235: PetscErrorCode  DMDARestoreAdicMFArray(DM da,PetscBool  ghosted,void *vptr,void *array_start,PetscInt *tdof)
1236: {
1237:   PetscInt  i;
1238:   void      **iptr = (void**)vptr,*iarray_start = 0;
1239:   DM_DA     *dd = (DM_DA*)da->data;
1240: 
1243:   if (ghosted) {
1244:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1245:       if (dd->admfarrayghostedout[i] == *iptr) {
1246:         iarray_start               = dd->admfstartghostedout[i];
1247:         dd->admfarrayghostedout[i] = PETSC_NULL;
1248:         dd->admfstartghostedout[i] = PETSC_NULL;
1249:         break;
1250:       }
1251:     }
1252:     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1253:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1254:       if (!dd->admfarrayghostedin[i]){
1255:         dd->admfarrayghostedin[i] = *iptr;
1256:         dd->admfstartghostedin[i] = iarray_start;
1257:         break;
1258:       }
1259:     }
1260:   } else {
1261:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1262:       if (dd->admfarrayout[i] == *iptr) {
1263:         iarray_start        = dd->admfstartout[i];
1264:         dd->admfarrayout[i] = PETSC_NULL;
1265:         dd->admfstartout[i] = PETSC_NULL;
1266:         break;
1267:       }
1268:     }
1269:     if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list");
1270:     for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) {
1271:       if (!dd->admfarrayin[i]){
1272:         dd->admfarrayin[i] = *iptr;
1273:         dd->admfstartin[i] = iarray_start;
1274:         break;
1275:       }
1276:     }
1277:   }
1278:   return(0);
1279: }

1283: PetscErrorCode  admf_DAGetArray(DM da,PetscBool  ghosted,void *iptr)
1284: {
1287:   DMDAGetAdicMFArray(da,ghosted,iptr,0,0);
1288:   return(0);
1289: }

1293: PetscErrorCode  admf_DARestoreArray(DM da,PetscBool  ghosted,void *iptr)
1294: {
1297:   DMDARestoreAdicMFArray(da,ghosted,iptr,0,0);
1298:   return(0);
1299: }