Actual source code: inherit.c

  1: /*
  2:      Provides utility routines for manipulating any type of PETSc object.
  3: */
  4: #include <petsc/private/petscimpl.h>
  5: #include <petscviewer.h>

  7: #if defined(PETSC_USE_LOG)
  8: PETSC_INTERN PetscObject *PetscObjects;
  9: PETSC_INTERN PetscInt    PetscObjectsCounts;
 10: PETSC_INTERN PetscInt    PetscObjectsMaxCounts;
 11: PETSC_INTERN PetscBool   PetscObjectsLog;
 12: #endif

 14: #if defined(PETSC_USE_LOG)
 15: PetscObject *PetscObjects      = NULL;
 16: PetscInt    PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;
 17: PetscBool   PetscObjectsLog    = PETSC_FALSE;
 18: #endif

 20: PETSC_EXTERN PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm*);
 21: PETSC_EXTERN PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
 22: PETSC_EXTERN PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject*);
 23: PETSC_EXTERN PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],void (*)(void));
 24: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));

 26: /*
 27:    PetscHeaderCreate_Private - Creates a base PETSc object header and fills
 28:    in the default values.  Called by the macro PetscHeaderCreate().
 29: */
 30: PetscErrorCode  PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[],
 31:                                           MPI_Comm comm,PetscObjectDestroyFunction destroy,PetscObjectViewFunction view)
 32: {
 33:   static PetscInt idcnt = 1;
 34:   PetscErrorCode  ierr;
 35: #if defined(PETSC_USE_LOG)
 36:   PetscObject     *newPetscObjects;
 37:   PetscInt         newPetscObjectsMaxCounts,i;
 38: #endif

 41:   h->classid               = classid;
 42:   h->type                  = 0;
 43:   h->class_name            = (char*)class_name;
 44:   h->description           = (char*)descr;
 45:   h->mansec                = (char*)mansec;
 46:   h->prefix                = NULL;
 47:   h->refct                 = 1;
 48: #if defined(PETSC_HAVE_SAWS)
 49:   h->amsmem                = PETSC_FALSE;
 50: #endif
 51:   h->id                    = idcnt++;
 52:   h->parentid              = 0;
 53:   h->qlist                 = NULL;
 54:   h->olist                 = NULL;
 55:   h->bops->destroy         = destroy;
 56:   h->bops->view            = view;
 57:   h->bops->getcomm         = PetscObjectGetComm_Petsc;
 58:   h->bops->compose         = PetscObjectCompose_Petsc;
 59:   h->bops->query           = PetscObjectQuery_Petsc;
 60:   h->bops->composefunction = PetscObjectComposeFunction_Petsc;
 61:   h->bops->queryfunction   = PetscObjectQueryFunction_Petsc;

 63:   PetscCommDuplicate(comm,&h->comm,&h->tag);

 65: #if defined(PETSC_USE_LOG)
 66:   /* Keep a record of object created */
 67:   if (PetscObjectsLog) {
 68:     PetscObjectsCounts++;
 69:     for (i=0; i<PetscObjectsMaxCounts; i++) {
 70:       if (!PetscObjects[i]) {
 71:         PetscObjects[i] = h;
 72:         return(0);
 73:       }
 74:     }
 75:     /* Need to increase the space for storing PETSc objects */
 76:     if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
 77:     else                        newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
 78:     PetscCalloc1(newPetscObjectsMaxCounts,&newPetscObjects);
 79:     PetscArraycpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts);
 80:     PetscFree(PetscObjects);

 82:     PetscObjects                        = newPetscObjects;
 83:     PetscObjects[PetscObjectsMaxCounts] = h;
 84:     PetscObjectsMaxCounts               = newPetscObjectsMaxCounts;
 85:   }
 86: #endif
 87:   return(0);
 88: }

 90: PETSC_INTERN PetscBool      PetscMemoryCollectMaximumUsage;
 91: PETSC_INTERN PetscLogDouble PetscMemoryMaximumUsage;

 93: /*
 94:     PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
 95:     the macro PetscHeaderDestroy().
 96: */
 97: PetscErrorCode  PetscHeaderDestroy_Private(PetscObject h)
 98: {

103:   PetscLogObjectDestroy(h);
104:   PetscComposedQuantitiesDestroy(h);
105:   if (PetscMemoryCollectMaximumUsage) {
106:     PetscLogDouble usage;
107:     PetscMemoryGetCurrentUsage(&usage);
108:     if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
109:   }
110:   /* first destroy things that could execute arbitrary code */
111:   if (h->python_destroy) {
112:     void           *python_context = h->python_context;
113:     PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
114:     h->python_context = NULL;
115:     h->python_destroy = NULL;

117:     (*python_destroy)(python_context);
118:   }
119:   PetscObjectDestroyOptionsHandlers(h);
120:   PetscObjectListDestroy(&h->olist);
121:   PetscCommDestroy(&h->comm);
122:   /* next destroy other things */
123:   h->classid = PETSCFREEDHEADER;

125:   PetscFunctionListDestroy(&h->qlist);
126:   PetscFree(h->type_name);
127:   PetscFree(h->name);
128:   PetscFree(h->prefix);
129:   PetscFree(h->fortran_func_pointers);
130:   PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);
131:   PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);

133: #if defined(PETSC_USE_LOG)
134:   if (PetscObjectsLog) {
135:     PetscInt i;
136:     /* Record object removal from list of all objects */
137:     for (i=0; i<PetscObjectsMaxCounts; i++) {
138:       if (PetscObjects[i] == h) {
139:         PetscObjects[i] = NULL;
140:         PetscObjectsCounts--;
141:         break;
142:       }
143:     }
144:     if (!PetscObjectsCounts) {
145:       PetscFree(PetscObjects);
146:       PetscObjectsMaxCounts = 0;
147:     }
148:   }
149: #endif
150:   return(0);
151: }

153: /*@C
154:    PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object

156:    Logically Collective on PetscObject

158:    Input Parameters:
159: +  src - source object
160: -  dest - destination object

162:    Level: developer

164:    Note:
165:    Both objects must have the same class.
166: @*/
167: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
168: {
170:   PetscInt       cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE];

175:   if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class");

177:   PetscFree(dest->fortran_func_pointers);
178:   PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
179:   PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));

181:   dest->num_fortran_func_pointers = src->num_fortran_func_pointers;

183:   PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
184:   for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) {
185:     PetscFree(dest->fortrancallback[cbtype]);
186:     PetscCalloc1(numcb[cbtype],&dest->fortrancallback[cbtype]);
187:     PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));
188:     dest->num_fortrancallback[cbtype] = src->num_fortrancallback[cbtype];
189:   }
190:   return(0);
191: }

193: /*@C
194:    PetscObjectSetFortranCallback - set fortran callback function pointer and context

196:    Logically Collective

198:    Input Parameters:
199: +  obj - object on which to set callback
200: .  cbtype - callback type (class or subtype)
201: .  cid - address of callback Id, updated if not yet initialized (zero)
202: .  func - Fortran function
203: -  ctx - Fortran context

205:    Level: developer

207: .seealso: PetscObjectGetFortranCallback()
208: @*/
209: PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx)
210: {
212:   const char     *subtype = NULL;

216:   if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name;
217:   if (!*cid) {PetscFortranCallbackRegister(obj->classid,subtype,cid);}
218:   if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) {
219:     PetscInt             oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum);
220:     PetscFortranCallback *callback;
221:     PetscMalloc1(newnum,&callback);
222:     PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));
223:     PetscFree(obj->fortrancallback[cbtype]);

225:     obj->fortrancallback[cbtype] = callback;
226:     obj->num_fortrancallback[cbtype] = newnum;
227:   }
228:   obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func;
229:   obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx;
230:   return(0);
231: }

233: /*@C
234:    PetscObjectGetFortranCallback - get fortran callback function pointer and context

236:    Logically Collective

238:    Input Parameters:
239: +  obj - object on which to get callback
240: .  cbtype - callback type
241: -  cid - address of callback Id

243:    Output Parameters:
244: +  func - Fortran function (or NULL if not needed)
245: -  ctx - Fortran context (or NULL if not needed)

247:    Level: developer

249: .seealso: PetscObjectSetFortranCallback()
250: @*/
251: PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
252: {
253:   PetscFortranCallback *cb;

257:   if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
258:   if (PetscUnlikely(cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype])) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback not set on this object");
259:   cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
260:   if (func) *func = cb->func;
261:   if (ctx) *ctx = cb->ctx;
262:   return(0);
263: }

265: #if defined(PETSC_USE_LOG)
266: /*@C
267:    PetscObjectsDump - Prints the currently existing objects.

269:    Logically Collective on PetscViewer

271:    Input Parameters:
272: +  fd - file pointer
273: -  all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects

275:    Options Database:
276: .  -objects_dump <all> - print information about all the objects that exist at the end of the programs run

278:    Level: advanced

280: @*/
281: PetscErrorCode  PetscObjectsDump(FILE *fd,PetscBool all)
282: {
284:   PetscInt       i;
285: #if defined(PETSC_USE_DEBUG)
286:   PetscInt       j,k=0;
287: #endif
288:   PetscObject    h;

291:   if (PetscObjectsCounts) {
292:     PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");
293:     PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");
294:     for (i=0; i<PetscObjectsMaxCounts; i++) {
295:       if ((h = PetscObjects[i])) {
296:         PetscObjectName(h);
297:         {
298: #if defined(PETSC_USE_DEBUG)
299:         PetscStack *stack = NULL;
300:         char       *create,*rclass;

302:         /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */
303:         PetscMallocGetStack(h,&stack);
304:         if (stack) {
305:           k = stack->currentsize-2;
306:           if (!all) {
307:             k = 0;
308:             while (!stack->petscroutine[k]) k++;
309:             PetscStrstr(stack->function[k],"Create",&create);
310:             if (!create) {
311:               PetscStrstr(stack->function[k],"Get",&create);
312:             }
313:             PetscStrstr(stack->function[k],h->class_name,&rclass);
314:             if (!create) continue;
315:             if (!rclass) continue;
316:           }
317:         }
318: #endif

320:         PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);

322: #if defined(PETSC_USE_DEBUG)
323:         PetscMallocGetStack(h,&stack);
324:         if (stack) {
325:           for (j=k; j>=0; j--) {
326:             fprintf(fd,"      [%d]  %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]);
327:           }
328:         }
329: #endif
330:         }
331:       }
332:     }
333:   }
334:   return(0);
335: }
336: #endif

338: #if defined(PETSC_USE_LOG)

340: /*@C
341:    PetscObjectsView - Prints the currently existing objects.

343:    Logically Collective on PetscViewer

345:    Input Parameter:
346: .  viewer - must be an PETSCVIEWERASCII viewer

348:    Level: advanced

350: @*/
351: PetscErrorCode  PetscObjectsView(PetscViewer viewer)
352: {
354:   PetscBool      isascii;
355:   FILE           *fd;

358:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
359:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
360:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
361:   PetscViewerASCIIGetPointer(viewer,&fd);
362:   PetscObjectsDump(fd,PETSC_TRUE);
363:   return(0);
364: }

366: /*@C
367:    PetscObjectsGetObject - Get a pointer to a named object

369:    Not collective

371:    Input Parameter:
372: .  name - the name of an object

374:    Output Parameters:
375: +  obj - the object or null if there is no object
376: -  classname - the name of the class

378:    Level: advanced

380: @*/
381: PetscErrorCode  PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
382: {
384:   PetscInt       i;
385:   PetscObject    h;
386:   PetscBool      flg;

389:   *obj = NULL;
390:   for (i=0; i<PetscObjectsMaxCounts; i++) {
391:     if ((h = PetscObjects[i])) {
392:       PetscObjectName(h);
393:       PetscStrcmp(h->name,name,&flg);
394:       if (flg) {
395:         *obj = h;
396:         if (classname) *classname = h->class_name;
397:         return(0);
398:       }
399:     }
400:   }
401:   return(0);
402: }
403: #endif

405: /*@
406:    PetscObjectSetPrintedOptions - indicate to an object that it should behave as if it has already printed the help for its options

408:    Input Parameters:
409: .  obj  - the PetscObject

411:    Level: developer

413:    Developer Notes:
414:    This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by
415:    PCBJACOBI from all printing the same help messages to the screen

417: .seealso: PetscOptionsInsert()
418: @*/
419: PetscErrorCode PetscObjectSetPrintedOptions(PetscObject obj)
420: {
422:   obj->optionsprinted = PETSC_TRUE;
423:   return(0);
424: }

426: /*@
427:    PetscObjectInheritPrintedOptions - If the child object is not on the rank 0 process of the parent object and the child is sequential then the child gets it set.

429:    Input Parameters:
430: +  pobj - the parent object
431: -  obj  - the PetscObject

433:    Level: developer

435:    Developer Notes:
436:    This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by
437:    PCBJACOBI from all printing the same help messages to the screen

439:    This will not handle more complicated situations like with GASM where children may live on any subset of the parent's processes and overlap

441: .seealso: PetscOptionsInsert(), PetscObjectSetPrintedOptions()
442: @*/
443: PetscErrorCode PetscObjectInheritPrintedOptions(PetscObject pobj,PetscObject obj)
444: {
446:   PetscMPIInt    prank,size;

449:   MPI_Comm_rank(pobj->comm,&prank);
450:   MPI_Comm_size(obj->comm,&size);
451:   if (size == 1 && prank > 0) obj->optionsprinted = PETSC_TRUE;
452:   return(0);
453: }

455: /*@C
456:     PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.

458:     Not Collective

460:     Input Parameters:
461: +   obj - the PETSc object
462: .   handle - function that checks for options
463: .   destroy - function to destroy context if provided
464: -   ctx - optional context for check function

466:     Level: developer

468: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()

470: @*/
471: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscOptionItems*,PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
472: {
475:   if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
476:   obj->optionhandler[obj->noptionhandler] = handle;
477:   obj->optiondestroy[obj->noptionhandler] = destroy;
478:   obj->optionctx[obj->noptionhandler++]   = ctx;
479:   return(0);
480: }

482: /*@C
483:     PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object

485:     Not Collective

487:     Input Parameter:
488: .   obj - the PETSc object

490:     Level: developer

492: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()

494: @*/
495: PetscErrorCode  PetscObjectProcessOptionsHandlers(PetscOptionItems *PetscOptionsObject,PetscObject obj)
496: {
497:   PetscInt       i;

502:   for (i=0; i<obj->noptionhandler; i++) {
503:     (*obj->optionhandler[i])(PetscOptionsObject,obj,obj->optionctx[i]);
504:   }
505:   return(0);
506: }

508: /*@C
509:     PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object

511:     Not Collective

513:     Input Parameter:
514: .   obj - the PETSc object

516:     Level: developer

518: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()

520: @*/
521: PetscErrorCode  PetscObjectDestroyOptionsHandlers(PetscObject obj)
522: {
523:   PetscInt       i;

528:   for (i=0; i<obj->noptionhandler; i++) {
529:     if (obj->optiondestroy[i]) {
530:       (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
531:     }
532:   }
533:   obj->noptionhandler = 0;
534:   return(0);
535: }

537: /*@C
538:    PetscObjectReference - Indicates to any PetscObject that it is being
539:    referenced by another PetscObject. This increases the reference
540:    count for that object by one.

542:    Logically Collective on PetscObject

544:    Input Parameter:
545: .  obj - the PETSc object. This must be cast with (PetscObject), for example,
546:          PetscObjectReference((PetscObject)mat);

548:    Level: advanced

550: .seealso: PetscObjectCompose(), PetscObjectDereference()
551: @*/
552: PetscErrorCode  PetscObjectReference(PetscObject obj)
553: {
555:   if (!obj) return(0);
557:   obj->refct++;
558:   return(0);
559: }

561: /*@C
562:    PetscObjectGetReference - Gets the current reference count for
563:    any PETSc object.

565:    Not Collective

567:    Input Parameter:
568: .  obj - the PETSc object; this must be cast with (PetscObject), for example,
569:          PetscObjectGetReference((PetscObject)mat,&cnt);

571:    Output Parameter:
572: .  cnt - the reference count

574:    Level: advanced

576: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
577: @*/
578: PetscErrorCode  PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
579: {
583:   *cnt = obj->refct;
584:   return(0);
585: }

587: /*@C
588:    PetscObjectDereference - Indicates to any PetscObject that it is being
589:    referenced by one less PetscObject. This decreases the reference
590:    count for that object by one.

592:    Collective on PetscObject if reference reaches 0 otherwise Logically Collective

594:    Input Parameter:
595: .  obj - the PETSc object; this must be cast with (PetscObject), for example,
596:          PetscObjectDereference((PetscObject)mat);

598:    Notes:
599:     PetscObjectDestroy(PetscObject *obj)  sets the obj pointer to null after the call, this routine does not.

601:    Level: advanced

603: .seealso: PetscObjectCompose(), PetscObjectReference()
604: @*/
605: PetscErrorCode  PetscObjectDereference(PetscObject obj)
606: {

610:   if (!obj) return(0);
612:   if (obj->bops->destroy) {
613:     (*obj->bops->destroy)(&obj);
614:   } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
615:   return(0);
616: }

618: /* ----------------------------------------------------------------------- */
619: /*
620:      The following routines are the versions private to the PETSc object
621:      data structures.
622: */
623: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
624: {
627:   *comm = obj->comm;
628:   return(0);
629: }

631: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
632: {

637:   PetscObjectListRemoveReference(&obj->olist,name);
638:   return(0);
639: }

641: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
642: {
644:   char           *tname;
645:   PetscBool      skipreference;

648:   if (ptr) {
649:     PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
650:     if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
651:   }
652:   PetscObjectListAdd(&obj->olist,name,ptr);
653:   return(0);
654: }

656: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
657: {

662:   PetscObjectListFind(obj->olist,name,ptr);
663:   return(0);
664: }

666: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
667: {

672:   PetscFunctionListAdd(&obj->qlist,name,ptr);
673:   return(0);
674: }

676: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
677: {

682:   PetscFunctionListFind(obj->qlist,name,ptr);
683:   return(0);
684: }

686: /*@C
687:    PetscObjectCompose - Associates another PETSc object with a given PETSc object.

689:    Not Collective

691:    Input Parameters:
692: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
693:          PetscObjectCompose((PetscObject)mat,...);
694: .  name - name associated with the child object
695: -  ptr - the other PETSc object to associate with the PETSc object; this must also be
696:          cast with (PetscObject)

698:    Level: advanced

700:    Notes:
701:    The second objects reference count is automatically increased by one when it is
702:    composed.

704:    Replaces any previous object that had the same name.

706:    If ptr is null and name has previously been composed using an object, then that
707:    entry is removed from the obj.

709:    PetscObjectCompose() can be used with any PETSc object (such as
710:    Mat, Vec, KSP, SNES, etc.) or any user-provided object.  See
711:    PetscContainerCreate() for info on how to create an object from a
712:    user-provided pointer that may then be composed with PETSc objects.

714: .seealso: PetscObjectQuery(), PetscContainerCreate(), PetscObjectComposeFunction(), PetscObjectQueryFunction()
715: @*/
716: PetscErrorCode  PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
717: {

724:   if (obj == ptr) SETERRQ(PetscObjectComm((PetscObject)obj),PETSC_ERR_SUP,"Cannot compose object with itself");
725:   (*obj->bops->compose)(obj,name,ptr);
726:   return(0);
727: }

729: /*@C
730:    PetscObjectQuery  - Gets a PETSc object associated with a given object.

732:    Not Collective

734:    Input Parameters:
735: +  obj - the PETSc object
736:          Thus must be cast with a (PetscObject), for example,
737:          PetscObjectCompose((PetscObject)mat,...);
738: .  name - name associated with child object
739: -  ptr - the other PETSc object associated with the PETSc object, this must be
740:          cast with (PetscObject*)

742:    Level: advanced

744:    The reference count of neither object is increased in this call

746: .seealso: PetscObjectCompose(), PetscObjectComposeFunction(), PetscObjectQueryFunction()
747: @*/
748: PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
749: {

756:   (*obj->bops->query)(obj,name,ptr);
757:   return(0);
758: }

760: /*MC
761:    PetscObjectComposeFunction - Associates a function with a given PETSc object.

763:     Synopsis:
764: #include <petscsys.h>
765:     PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))

767:    Logically Collective on PetscObject

769:    Input Parameters:
770: +  obj - the PETSc object; this must be cast with a (PetscObject), for example,
771:          PetscObjectCompose((PetscObject)mat,...);
772: .  name - name associated with the child function
773: .  fname - name of the function
774: -  fptr - function pointer

776:    Level: advanced

778:    Notes:
779:    To remove a registered routine, pass in NULL for fptr().

781:    PetscObjectComposeFunction() can be used with any PETSc object (such as
782:    Mat, Vec, KSP, SNES, etc.) or any user-provided object.

784: .seealso: PetscObjectQueryFunction(), PetscContainerCreate() PetscObjectCompose(), PetscObjectQuery()
785: M*/

787: PetscErrorCode  PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
788: {

794:   (*obj->bops->composefunction)(obj,name,fptr);
795:   return(0);
796: }

798: /*MC
799:    PetscObjectQueryFunction - Gets a function associated with a given object.

801:     Synopsis:
802: #include <petscsys.h>
803:     PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))

805:    Logically Collective on PetscObject

807:    Input Parameters:
808: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
809:          PetscObjectQueryFunction((PetscObject)ksp,...);
810: -  name - name associated with the child function

812:    Output Parameter:
813: .  fptr - function pointer

815:    Level: advanced

817: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind(), PetscObjectCompose(), PetscObjectQuery()
818: M*/
819: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
820: {

826:   (*obj->bops->queryfunction)(obj,name,ptr);
827:   return(0);
828: }

830: struct _p_PetscContainer {
831:   PETSCHEADER(int);
832:   void           *ptr;
833:   PetscErrorCode (*userdestroy)(void*);
834: };

836: /*@C
837:    PetscContainerUserDestroyDefault - Default destroy routine for user-provided data that simply calls PetscFree().

839:    Logically Collective on PetscContainer

841:    Input Parameter:
842: .  ctx - pointer to user-provided data

844:    Level: advanced

846: .seealso: PetscContainerDestroy(), PetscContainerSetUserDestroy()
847: @*/
848: PetscErrorCode PetscContainerUserDestroyDefault(void* ctx)
849: {

853:   PetscFree(ctx);
854:   return(0);
855: }

857: /*@C
858:    PetscContainerGetPointer - Gets the pointer value contained in the container.

860:    Not Collective

862:    Input Parameter:
863: .  obj - the object created with PetscContainerCreate()

865:    Output Parameter:
866: .  ptr - the pointer value

868:    Level: advanced

870: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
871:           PetscContainerSetPointer()
872: @*/
873: PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
874: {
878:   *ptr = obj->ptr;
879:   return(0);
880: }

882: /*@C
883:    PetscContainerSetPointer - Sets the pointer value contained in the container.

885:    Logically Collective on PetscContainer

887:    Input Parameters:
888: +  obj - the object created with PetscContainerCreate()
889: -  ptr - the pointer value

891:    Level: advanced

893: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
894:           PetscContainerGetPointer()
895: @*/
896: PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
897: {
901:   obj->ptr = ptr;
902:   return(0);
903: }

905: /*@C
906:    PetscContainerDestroy - Destroys a PETSc container object.

908:    Collective on PetscContainer

910:    Input Parameter:
911: .  obj - an object that was created with PetscContainerCreate()

913:    Level: advanced

915: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
916: @*/
917: PetscErrorCode  PetscContainerDestroy(PetscContainer *obj)
918: {

922:   if (!*obj) return(0);
924:   if (--((PetscObject)(*obj))->refct > 0) {*obj = NULL; return(0);}
925:   if ((*obj)->userdestroy) { (*(*obj)->userdestroy)((*obj)->ptr); }
926:   PetscHeaderDestroy(obj);
927:   return(0);
928: }

930: /*@C
931:    PetscContainerSetUserDestroy - Sets name of the user destroy function.

933:    Logically Collective on PetscContainer

935:    Input Parameters:
936: +  obj - an object that was created with PetscContainerCreate()
937: -  des - name of the user destroy function

939:    Notes:
940:    Use PetscContainerUserDestroyDefault() if the memory was obtained by calling PetscMalloc or one of its variants for single memory allocation.

942:    Level: advanced

944: .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1()
945: @*/
946: PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
947: {
950:   obj->userdestroy = des;
951:   return(0);
952: }

954: PetscClassId PETSC_CONTAINER_CLASSID;

956: /*@C
957:    PetscContainerCreate - Creates a PETSc object that has room to hold
958:    a single pointer. This allows one to attach any type of data (accessible
959:    through a pointer) with the PetscObjectCompose() function to a PetscObject.
960:    The data item itself is attached by a call to PetscContainerSetPointer().

962:    Collective

964:    Input Parameters:
965: .  comm - MPI communicator that shares the object

967:    Output Parameters:
968: .  container - the container created

970:    Level: advanced

972: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer(), PetscObjectCompose(), PetscObjectQuery()
973: @*/
974: PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
975: {
977:   PetscContainer contain;

981:   PetscSysInitializePackage();
982:   PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);
983:   *container = contain;
984:   return(0);
985: }

987: /*@
988:    PetscObjectSetFromOptions - Sets generic parameters from user options.

990:    Collective on obj

992:    Input Parameter:
993: .  obj - the PetscObjcet

995:    Options Database Keys:

997:    Notes:
998:    We have no generic options at present, so this does nothing

1000:    Level: beginner

1002: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1003: @*/
1004: PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
1005: {
1008:   return(0);
1009: }

1011: /*@
1012:    PetscObjectSetUp - Sets up the internal data structures for the later use.

1014:    Collective on PetscObject

1016:    Input Parameters:
1017: .  obj - the PetscObject

1019:    Notes:
1020:    This does nothing at present.

1022:    Level: advanced

1024: .seealso: PetscObjectDestroy()
1025: @*/
1026: PetscErrorCode  PetscObjectSetUp(PetscObject obj)
1027: {
1030:   return(0);
1031: }