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: #if defined(PETSC_USE_LOG)
 35:   PetscObject     *newPetscObjects;
 36:   PetscInt         newPetscObjectsMaxCounts,i;
 37: #endif

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

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

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

 80:     PetscObjects                        = newPetscObjects;
 81:     PetscObjects[PetscObjectsMaxCounts] = h;
 82:     PetscObjectsMaxCounts               = newPetscObjectsMaxCounts;
 83:   }
 84: #endif
 85:   return 0;
 86: }

 88: PETSC_INTERN PetscBool      PetscMemoryCollectMaximumUsage;
 89: PETSC_INTERN PetscLogDouble PetscMemoryMaximumUsage;

 91: /*
 92:     PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
 93:     the macro PetscHeaderDestroy().
 94: */
 95: PetscErrorCode  PetscHeaderDestroy_Private(PetscObject h)
 96: {
 98:   PetscLogObjectDestroy(h);
 99:   PetscComposedQuantitiesDestroy(h);
100:   if (PetscMemoryCollectMaximumUsage) {
101:     PetscLogDouble usage;
102:     PetscMemoryGetCurrentUsage(&usage);
103:     if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
104:   }
105:   /* first destroy things that could execute arbitrary code */
106:   if (h->python_destroy) {
107:     void           *python_context = h->python_context;
108:     PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
109:     h->python_context = NULL;
110:     h->python_destroy = NULL;

112:     (*python_destroy)(python_context);
113:   }
114:   PetscObjectDestroyOptionsHandlers(h);
115:   PetscObjectListDestroy(&h->olist);
116:   PetscCommDestroy(&h->comm);
117:   /* next destroy other things */
118:   h->classid = PETSCFREEDHEADER;

120:   PetscFunctionListDestroy(&h->qlist);
121:   PetscFree(h->type_name);
122:   PetscFree(h->name);
123:   PetscFree(h->prefix);
124:   PetscFree(h->fortran_func_pointers);
125:   PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);
126:   PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);

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

148: /*@C
149:    PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object

151:    Logically Collective on PetscObject

153:    Input Parameters:
154: +  src - source object
155: -  dest - destination object

157:    Level: developer

159:    Note:
160:    Both objects must have the same class.
161: @*/
162: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
163: {
164:   PetscFortranCallbackId cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE];


170:   PetscFree(dest->fortran_func_pointers);
171:   PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
172:   PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));

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

176:   PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
177:   for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) {
178:     PetscFree(dest->fortrancallback[cbtype]);
179:     PetscCalloc1(numcb[cbtype],&dest->fortrancallback[cbtype]);
180:     PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));
181:     dest->num_fortrancallback[cbtype] = src->num_fortrancallback[cbtype];
182:   }
183:   return 0;
184: }

186: /*@C
187:    PetscObjectSetFortranCallback - set fortran callback function pointer and context

189:    Logically Collective

191:    Input Parameters:
192: +  obj - object on which to set callback
193: .  cbtype - callback type (class or subtype)
194: .  cid - address of callback Id, updated if not yet initialized (zero)
195: .  func - Fortran function
196: -  ctx - Fortran context

198:    Level: developer

200: .seealso: PetscObjectGetFortranCallback()
201: @*/
202: PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx)
203: {
204:   const char     *subtype = NULL;

207:   if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name;
208:   if (!*cid) PetscFortranCallbackRegister(obj->classid,subtype,cid);
209:   if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) {
210:     PetscFortranCallbackId oldnum = obj->num_fortrancallback[cbtype];
211:     PetscFortranCallbackId newnum = PetscMax(*cid - PETSC_SMALLEST_FORTRAN_CALLBACK + 1, 2*oldnum);
212:     PetscFortranCallback   *callback;
213:     PetscMalloc1(newnum,&callback);
214:     PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));
215:     PetscFree(obj->fortrancallback[cbtype]);

217:     obj->fortrancallback[cbtype] = callback;
218:     obj->num_fortrancallback[cbtype] = newnum;
219:   }
220:   obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func;
221:   obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx;
222:   return 0;
223: }

225: /*@C
226:    PetscObjectGetFortranCallback - get fortran callback function pointer and context

228:    Logically Collective

230:    Input Parameters:
231: +  obj - object on which to get callback
232: .  cbtype - callback type
233: -  cid - address of callback Id

235:    Output Parameters:
236: +  func - Fortran function (or NULL if not needed)
237: -  ctx - Fortran context (or NULL if not needed)

239:    Level: developer

241: .seealso: PetscObjectSetFortranCallback()
242: @*/
243: PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
244: {
245:   PetscFortranCallback *cb;

250:   cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
251:   if (func) *func = cb->func;
252:   if (ctx) *ctx = cb->ctx;
253:   return 0;
254: }

256: #if defined(PETSC_USE_LOG)
257: /*@C
258:    PetscObjectsDump - Prints the currently existing objects.

260:    Logically Collective on PetscViewer

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

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

269:    Level: advanced

271: @*/
272: PetscErrorCode  PetscObjectsDump(FILE *fd,PetscBool all)
273: {
274:   PetscInt       i;
275: #if defined(PETSC_USE_DEBUG)
276:   PetscInt       j,k=0;
277: #endif
278:   PetscObject    h;

280:   if (PetscObjectsCounts) {
281:     PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");
282:     PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");
283:     for (i=0; i<PetscObjectsMaxCounts; i++) {
284:       if ((h = PetscObjects[i])) {
285:         PetscObjectName(h);
286:         {
287: #if defined(PETSC_USE_DEBUG)
288:         PetscStack *stack = NULL;
289:         char       *create,*rclass;

291:         /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */
292:         PetscMallocGetStack(h,&stack);
293:         if (stack) {
294:           k = stack->currentsize-2;
295:           if (!all) {
296:             k = 0;
297:             while (!stack->petscroutine[k]) k++;
298:             PetscStrstr(stack->function[k],"Create",&create);
299:             if (!create) {
300:               PetscStrstr(stack->function[k],"Get",&create);
301:             }
302:             PetscStrstr(stack->function[k],h->class_name,&rclass);
303:             if (!create) continue;
304:             if (!rclass) continue;
305:           }
306:         }
307: #endif

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

311: #if defined(PETSC_USE_DEBUG)
312:         PetscMallocGetStack(h,&stack);
313:         if (stack) {
314:           for (j=k; j>=0; j--) {
315:             fprintf(fd,"      [%d]  %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]);
316:           }
317:         }
318: #endif
319:         }
320:       }
321:     }
322:   }
323:   return 0;
324: }
325: #endif

327: #if defined(PETSC_USE_LOG)

329: /*@C
330:    PetscObjectsView - Prints the currently existing objects.

332:    Logically Collective on PetscViewer

334:    Input Parameter:
335: .  viewer - must be an PETSCVIEWERASCII viewer

337:    Level: advanced

339: @*/
340: PetscErrorCode  PetscObjectsView(PetscViewer viewer)
341: {
342:   PetscBool      isascii;
343:   FILE           *fd;

345:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
346:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
348:   PetscViewerASCIIGetPointer(viewer,&fd);
349:   PetscObjectsDump(fd,PETSC_TRUE);
350:   return 0;
351: }

353: /*@C
354:    PetscObjectsGetObject - Get a pointer to a named object

356:    Not collective

358:    Input Parameter:
359: .  name - the name of an object

361:    Output Parameters:
362: +  obj - the object or null if there is no object
363: -  classname - the name of the class

365:    Level: advanced

367: @*/
368: PetscErrorCode  PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
369: {
370:   PetscInt    i;
371:   PetscObject h;
372:   PetscBool   flg;

376:   *obj = NULL;
377:   for (i=0; i<PetscObjectsMaxCounts; i++) {
378:     if ((h = PetscObjects[i])) {
379:       PetscObjectName(h);
380:       PetscStrcmp(h->name,name,&flg);
381:       if (flg) {
382:         *obj = h;
383:         if (classname) *classname = h->class_name;
384:         return 0;
385:       }
386:     }
387:   }
388:   return 0;
389: }
390: #endif

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

395:    Input Parameters:
396: .  obj  - the PetscObject

398:    Level: developer

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

404: .seealso: PetscOptionsInsert()
405: @*/
406: PetscErrorCode PetscObjectSetPrintedOptions(PetscObject obj)
407: {
409:   obj->optionsprinted = PETSC_TRUE;
410:   return 0;
411: }

413: /*@
414:    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.

416:    Input Parameters:
417: +  pobj - the parent object
418: -  obj  - the PetscObject

420:    Level: developer

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

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

428: .seealso: PetscOptionsInsert(), PetscObjectSetPrintedOptions()
429: @*/
430: PetscErrorCode PetscObjectInheritPrintedOptions(PetscObject pobj,PetscObject obj)
431: {
432:   PetscMPIInt prank,size;

436:   MPI_Comm_rank(pobj->comm,&prank);
437:   MPI_Comm_size(obj->comm,&size);
438:   if (size == 1 && prank > 0) obj->optionsprinted = PETSC_TRUE;
439:   return 0;
440: }

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

445:     Not Collective

447:     Input Parameters:
448: +   obj - the PETSc object
449: .   handle - function that checks for options
450: .   destroy - function to destroy context if provided
451: -   ctx - optional context for check function

453:     Level: developer

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

457: @*/
458: PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscOptionItems*,PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
459: {
462:   obj->optionhandler[obj->noptionhandler] = handle;
463:   obj->optiondestroy[obj->noptionhandler] = destroy;
464:   obj->optionctx[obj->noptionhandler++]   = ctx;
465:   return 0;
466: }

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

471:     Not Collective

473:     Input Parameter:
474: .   obj - the PETSc object

476:     Level: developer

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

480: @*/
481: PetscErrorCode  PetscObjectProcessOptionsHandlers(PetscOptionItems *PetscOptionsObject,PetscObject obj)
482: {
484:   for (PetscInt i=0; i<obj->noptionhandler; i++) (*obj->optionhandler[i])(PetscOptionsObject,obj,obj->optionctx[i]);
485:   return 0;
486: }

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

491:     Not Collective

493:     Input Parameter:
494: .   obj - the PETSc object

496:     Level: developer

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

500: @*/
501: PetscErrorCode  PetscObjectDestroyOptionsHandlers(PetscObject obj)
502: {
504:   for (PetscInt i=0; i<obj->noptionhandler; i++) {
505:     if (obj->optiondestroy[i]) (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
506:   }
507:   obj->noptionhandler = 0;
508:   return 0;
509: }

511: /*@C
512:    PetscObjectReference - Indicates to any PetscObject that it is being
513:    referenced by another PetscObject. This increases the reference
514:    count for that object by one.

516:    Logically Collective on PetscObject

518:    Input Parameter:
519: .  obj - the PETSc object. This must be cast with (PetscObject), for example,
520:          PetscObjectReference((PetscObject)mat);

522:    Level: advanced

524: .seealso: PetscObjectCompose(), PetscObjectDereference()
525: @*/
526: PetscErrorCode  PetscObjectReference(PetscObject obj)
527: {
528:   if (!obj) return 0;
530:   obj->refct++;
531:   return 0;
532: }

534: /*@C
535:    PetscObjectGetReference - Gets the current reference count for
536:    any PETSc object.

538:    Not Collective

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

544:    Output Parameter:
545: .  cnt - the reference count

547:    Level: advanced

549: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
550: @*/
551: PetscErrorCode  PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
552: {
555:   *cnt = obj->refct;
556:   return 0;
557: }

559: /*@C
560:    PetscObjectDereference - Indicates to any PetscObject that it is being
561:    referenced by one less PetscObject. This decreases the reference
562:    count for that object by one.

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

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

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

573:    Level: advanced

575: .seealso: PetscObjectCompose(), PetscObjectReference()
576: @*/
577: PetscErrorCode  PetscObjectDereference(PetscObject obj)
578: {
579:   if (!obj) return 0;
581:   if (obj->bops->destroy) (*obj->bops->destroy)(&obj);
583:   return 0;
584: }

586: /* ----------------------------------------------------------------------- */
587: /*
588:      The following routines are the versions private to the PETSc object
589:      data structures.
590: */
591: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
592: {
595:   *comm = obj->comm;
596:   return 0;
597: }

599: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
600: {
602:   PetscObjectListRemoveReference(&obj->olist,name);
603:   return 0;
604: }

606: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
607: {
608:   if (ptr) {
609:     char      *tname;
610:     PetscBool skipreference;

612:     PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
614:   }
615:   PetscObjectListAdd(&obj->olist,name,ptr);
616:   return 0;
617: }

619: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
620: {
622:   PetscObjectListFind(obj->olist,name,ptr);
623:   return 0;
624: }

626: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
627: {
629:   PetscFunctionListAdd(&obj->qlist,name,ptr);
630:   return 0;
631: }

633: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
634: {
636:   PetscFunctionListFind(obj->qlist,name,ptr);
637:   return 0;
638: }

640: /*@C
641:    PetscObjectCompose - Associates another PETSc object with a given PETSc object.

643:    Not Collective

645:    Input Parameters:
646: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
647:          PetscObjectCompose((PetscObject)mat,...);
648: .  name - name associated with the child object
649: -  ptr - the other PETSc object to associate with the PETSc object; this must also be
650:          cast with (PetscObject)

652:    Level: advanced

654:    Notes:
655:    The second objects reference count is automatically increased by one when it is
656:    composed.

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

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

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

668: .seealso: PetscObjectQuery(), PetscContainerCreate(), PetscObjectComposeFunction(), PetscObjectQueryFunction()
669: @*/
670: PetscErrorCode  PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
671: {
676:   (*obj->bops->compose)(obj,name,ptr);
677:   return 0;
678: }

680: /*@C
681:    PetscObjectQuery  - Gets a PETSc object associated with a given object.

683:    Not Collective

685:    Input Parameters:
686: +  obj - the PETSc object
687:          Thus must be cast with a (PetscObject), for example,
688:          PetscObjectCompose((PetscObject)mat,...);
689: .  name - name associated with child object
690: -  ptr - the other PETSc object associated with the PETSc object, this must be
691:          cast with (PetscObject*)

693:    Level: advanced

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

697: .seealso: PetscObjectCompose(), PetscObjectComposeFunction(), PetscObjectQueryFunction()
698: @*/
699: PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
700: {
704:   (*obj->bops->query)(obj,name,ptr);
705:   return 0;
706: }

708: /*MC
709:    PetscObjectComposeFunction - Associates a function with a given PETSc object.

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

715:    Logically Collective on PetscObject

717:    Input Parameters:
718: +  obj - the PETSc object; this must be cast with a (PetscObject), for example,
719:          PetscObjectCompose((PetscObject)mat,...);
720: .  name - name associated with the child function
721: .  fname - name of the function
722: -  fptr - function pointer

724:    Level: advanced

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

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

732: .seealso: PetscObjectQueryFunction(), PetscContainerCreate() PetscObjectCompose(), PetscObjectQuery()
733: M*/

735: PetscErrorCode  PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
736: {
739:   (*obj->bops->composefunction)(obj,name,fptr);
740:   return 0;
741: }

743: /*MC
744:    PetscObjectQueryFunction - Gets a function associated with a given object.

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

750:    Logically Collective on PetscObject

752:    Input Parameters:
753: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
754:          PetscObjectQueryFunction((PetscObject)ksp,...);
755: -  name - name associated with the child function

757:    Output Parameter:
758: .  fptr - function pointer

760:    Level: advanced

762: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind(), PetscObjectCompose(), PetscObjectQuery()
763: M*/
764: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
765: {
768:   (*obj->bops->queryfunction)(obj,name,ptr);
769:   return 0;
770: }

772: struct _p_PetscContainer {
773:   PETSCHEADER(int);
774:   void           *ptr;
775:   PetscErrorCode (*userdestroy)(void*);
776: };

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

781:    Logically Collective on PetscContainer

783:    Input Parameter:
784: .  ctx - pointer to user-provided data

786:    Level: advanced

788: .seealso: PetscContainerDestroy(), PetscContainerSetUserDestroy()
789: @*/
790: PetscErrorCode PetscContainerUserDestroyDefault(void* ctx)
791: {
792:   PetscFree(ctx);
793:   return 0;
794: }

796: /*@C
797:    PetscContainerGetPointer - Gets the pointer value contained in the container.

799:    Not Collective

801:    Input Parameter:
802: .  obj - the object created with PetscContainerCreate()

804:    Output Parameter:
805: .  ptr - the pointer value

807:    Level: advanced

809: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
810:           PetscContainerSetPointer()
811: @*/
812: PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
813: {
816:   *ptr = obj->ptr;
817:   return 0;
818: }

820: /*@C
821:    PetscContainerSetPointer - Sets the pointer value contained in the container.

823:    Logically Collective on PetscContainer

825:    Input Parameters:
826: +  obj - the object created with PetscContainerCreate()
827: -  ptr - the pointer value

829:    Level: advanced

831: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
832:           PetscContainerGetPointer()
833: @*/
834: PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
835: {
838:   obj->ptr = ptr;
839:   return 0;
840: }

842: /*@C
843:    PetscContainerDestroy - Destroys a PETSc container object.

845:    Collective on PetscContainer

847:    Input Parameter:
848: .  obj - an object that was created with PetscContainerCreate()

850:    Level: advanced

852: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
853: @*/
854: PetscErrorCode  PetscContainerDestroy(PetscContainer *obj)
855: {
856:   if (!*obj) return 0;
858:   if (--((PetscObject)(*obj))->refct > 0) {*obj = NULL; return 0;}
859:   if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
860:   PetscHeaderDestroy(obj);
861:   return 0;
862: }

864: /*@C
865:    PetscContainerSetUserDestroy - Sets name of the user destroy function.

867:    Logically Collective on PetscContainer

869:    Input Parameters:
870: +  obj - an object that was created with PetscContainerCreate()
871: -  des - name of the user destroy function

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

876:    Level: advanced

878: .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1()
879: @*/
880: PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
881: {
883:   obj->userdestroy = des;
884:   return 0;
885: }

887: PetscClassId PETSC_CONTAINER_CLASSID;

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

895:    Collective

897:    Input Parameters:
898: .  comm - MPI communicator that shares the object

900:    Output Parameters:
901: .  container - the container created

903:    Level: advanced

905: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer(), PetscObjectCompose(), PetscObjectQuery()
906: @*/
907: PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
908: {
910:   PetscSysInitializePackage();
911:   PetscHeaderCreate(*container,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);
912:   return 0;
913: }

915: /*@
916:    PetscObjectSetFromOptions - Sets generic parameters from user options.

918:    Collective on obj

920:    Input Parameter:
921: .  obj - the PetscObjcet

923:    Options Database Keys:

925:    Notes:
926:    We have no generic options at present, so this does nothing

928:    Level: beginner

930: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
931: @*/
932: PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
933: {
935:   return 0;
936: }

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

941:    Collective on PetscObject

943:    Input Parameters:
944: .  obj - the PetscObject

946:    Notes:
947:    This does nothing at present.

949:    Level: advanced

951: .seealso: PetscObjectDestroy()
952: @*/
953: PetscErrorCode  PetscObjectSetUp(PetscObject obj)
954: {
956:   return 0;
957: }