Actual source code: inherit.c

petsc-3.4.4 2014-03-13
  2: /*
  3:      Provides utility routines for manipulating any type of PETSc object.
  4: */
  5: #include <petsc-private/petscimpl.h>  /*I   "petscsys.h"    I*/
  6: #include <petscviewer.h>

  8: PetscObject *PetscObjects      = 0;
  9: PetscInt    PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;

 11: extern PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm*);
 12: extern PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
 13: extern PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject*);
 14: extern PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],void (*)(void));
 15: extern PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));

 19: /*
 20:    PetscHeaderCreate_Private - Creates a base PETSc object header and fills
 21:    in the default values.  Called by the macro PetscHeaderCreate().
 22: */
 23: PetscErrorCode  PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[],
 24:                                           MPI_Comm comm,PetscErrorCode (*des)(PetscObject*),PetscErrorCode (*vie)(PetscObject,PetscViewer))
 25: {
 26:   static PetscInt idcnt = 1;
 27:   PetscErrorCode  ierr;
 28:   PetscObject     *newPetscObjects;
 29:   PetscInt         newPetscObjectsMaxCounts,i;

 32:   h->classid               = classid;
 33:   h->type                  = 0;
 34:   h->class_name            = (char*)class_name;
 35:   h->description           = (char*)descr;
 36:   h->mansec                = (char*)mansec;
 37:   h->prefix                = 0;
 38:   h->refct                 = 1;
 39: #if defined(PETSC_HAVE_AMS)
 40:   h->amsmem                = -1;
 41: #endif
 42:   h->id                    = idcnt++;
 43:   h->parentid              = 0;
 44:   h->qlist                 = 0;
 45:   h->olist                 = 0;
 46:   h->precision             = (PetscPrecision) sizeof(PetscReal);
 47:   h->bops->destroy         = des;
 48:   h->bops->view            = vie;
 49:   h->bops->getcomm         = PetscObjectGetComm_Petsc;
 50:   h->bops->compose         = PetscObjectCompose_Petsc;
 51:   h->bops->query           = PetscObjectQuery_Petsc;
 52:   h->bops->composefunction = PetscObjectComposeFunction_Petsc;
 53:   h->bops->queryfunction   = PetscObjectQueryFunction_Petsc;

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

 57:   /* Keep a record of object created */
 58:   PetscObjectsCounts++;
 59:   for (i=0; i<PetscObjectsMaxCounts; i++) {
 60:     if (!PetscObjects[i]) {
 61:       PetscObjects[i] = h;
 62:       return(0);
 63:     }
 64:   }
 65:   /* Need to increase the space for storing PETSc objects */
 66:   if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
 67:   else                        newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
 68:   PetscMalloc(newPetscObjectsMaxCounts*sizeof(PetscObject),&newPetscObjects);
 69:   PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));
 70:   PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));
 71:   PetscFree(PetscObjects);

 73:   PetscObjects                        = newPetscObjects;
 74:   PetscObjects[PetscObjectsMaxCounts] = h;
 75:   PetscObjectsMaxCounts               = newPetscObjectsMaxCounts;
 76:   return(0);
 77: }

 79: extern PetscBool      PetscMemoryCollectMaximumUsage;
 80: extern PetscLogDouble PetscMemoryMaximumUsage;

 84: /*
 85:     PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
 86:     the macro PetscHeaderDestroy().
 87: */
 88: PetscErrorCode  PetscHeaderDestroy_Private(PetscObject h)
 89: {
 91:   PetscInt       i;

 95:   PetscObjectAMSViewOff(h);
 96:   PetscLogObjectDestroy(h);
 97:   PetscComposedQuantitiesDestroy(h);
 98:   if (PetscMemoryCollectMaximumUsage) {
 99:     PetscLogDouble usage;
100:     PetscMemoryGetCurrentUsage(&usage);
101:     if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
102:   }
103:   /* first destroy things that could execute arbitrary code */
104:   if (h->python_destroy) {
105:     void           *python_context = h->python_context;
106:     PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
107:     h->python_context = 0;
108:     h->python_destroy = 0;

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

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

127:   /* Record object removal from list of all objects */
128:   for (i=0; i<PetscObjectsMaxCounts; i++) {
129:     if (PetscObjects[i] == h) {
130:       PetscObjects[i] = 0;
131:       PetscObjectsCounts--;
132:       break;
133:     }
134:   }
135:   if (!PetscObjectsCounts) {
136:     PetscFree(PetscObjects);
137:     PetscObjectsMaxCounts = 0;
138:   }
139:   return(0);
140: }

144: /*@C
145:    PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object

147:    Logically Collective on PetscObject

149:    Input Parameter:
150: +  src - source object
151: -  dest - destination object

153:    Level: developer

155:    Note:
156:    Both objects must have the same class.
157: @*/
158: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
159: {
161:   PetscInt       cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE];

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

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

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

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

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

189:    Logically Collective

191:    Input Arguments:
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: {
205:   const char     *subtype = NULL;

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

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

228: /*@C
229:    PetscObjectGetFortranCallback - get fortran callback function pointer and context

231:    Logically Collective

233:    Input Arguments:
234: +  obj - object on which to get callback
235: .  cbtype - callback type
236: -  cid - address of callback Id

238:    Output Arguments:
239: +  func - Fortran function (or NULL if not needed)
240: -  ctx - Fortran context (or NULL if not needed)

242:    Level: developer

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

252:   if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
253:   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");
254:   cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
255:   if (func) *func = cb->func;
256:   if (ctx) *ctx = cb->ctx;
257:   return(0);
258: }

262: /*@C
263:    PetscObjectsDump - Prints the currently existing objects.

265:    Logically Collective on PetscViewer

267:    Input Parameter:
268: +  viewer - must be an PETSCVIEWERASCII viewer
269: -  all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects

271:    Level: advanced

273:    Concepts: options database^printing

275: @*/
276: PetscErrorCode  PetscObjectsDump(FILE *fd,PetscBool all)
277: {
279:   PetscInt       i;
280: #if defined(PETSC_USE_DEBUG)
281:   PetscInt       j,k;
282: #endif
283:   PetscObject    h;

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

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

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

317: #if defined(PETSC_USE_DEBUG)
318:         PetscMallocGetStack(h,&stack);
319:         if (stack) {
320:           for (j=k; j>=0; j--) {
321:             fprintf(fd,"      [%d]  %s() in %s%s\n",PetscGlobalRank,stack->function[j],stack->directory[j],stack->file[j]);
322:           }
323:         }
324: #endif
325:         }
326:       }
327:     }
328:   }
329:   return(0);
330: }


335: /*@C
336:    PetscObjectsView - Prints the currently existing objects.

338:    Logically Collective on PetscViewer

340:    Input Parameter:
341: .  viewer - must be an PETSCVIEWERASCII viewer

343:    Level: advanced

345:    Concepts: options database^printing

347: @*/
348: PetscErrorCode  PetscObjectsView(PetscViewer viewer)
349: {
351:   PetscBool      isascii;
352:   FILE           *fd;

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

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

368:    Not collective

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

373:    Output Parameter:
374: .   obj - the object or null if there is no object

376:    Level: advanced

378:    Concepts: options database^printing

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: }

406: char *PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj)
407: {
409:   PetscInt       i;
410:   PetscObject    h;
411:   PetscBool      flg;

414:   *obj = NULL;
415:   for (i=0; i<PetscObjectsMaxCounts; i++) {
416:     if ((h = PetscObjects[i])) {
417:       PetscObjectName(h);if (ierr) return(0);
418:       PetscStrcmp(h->name,name,&flg);if (ierr) return(0);
419:       if (flg) {
420:         *obj = h;
421:         PetscFunctionReturn(h->class_name);
422:       }
423:     }
424:   }
425:   return(0);
426: }

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

433:     Not Collective

435:     Input Parameter:
436: +   obj - the PETSc object
437: .   handle - function that checks for options
438: .   destroy - function to destroy context if provided
439: -   ctx - optional context for check function

441:     Level: developer


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

446: @*/
447: PetscErrorCode  PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
448: {
451:   if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
452:   obj->optionhandler[obj->noptionhandler] = handle;
453:   obj->optiondestroy[obj->noptionhandler] = destroy;
454:   obj->optionctx[obj->noptionhandler++]   = ctx;
455:   return(0);
456: }

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

463:     Not Collective

465:     Input Parameter:
466: .   obj - the PETSc object

468:     Level: developer


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

473: @*/
474: PetscErrorCode  PetscObjectProcessOptionsHandlers(PetscObject obj)
475: {
476:   PetscInt       i;

481:   for (i=0; i<obj->noptionhandler; i++) {
482:     (*obj->optionhandler[i])(obj,obj->optionctx[i]);
483:   }
484:   return(0);
485: }

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

492:     Not Collective

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

497:     Level: developer


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

502: @*/
503: PetscErrorCode  PetscObjectDestroyOptionsHandlers(PetscObject obj)
504: {
505:   PetscInt       i;

510:   for (i=0; i<obj->noptionhandler; i++) {
511:     if (obj->optiondestroy[i]) {
512:       (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
513:     }
514:   }
515:   obj->noptionhandler = 0;
516:   return(0);
517: }


522: /*@
523:    PetscObjectReference - Indicates to any PetscObject that it is being
524:    referenced by another PetscObject. This increases the reference
525:    count for that object by one.

527:    Logically Collective on PetscObject

529:    Input Parameter:
530: .  obj - the PETSc object. This must be cast with (PetscObject), for example,
531:          PetscObjectReference((PetscObject)mat);

533:    Level: advanced

535: .seealso: PetscObjectCompose(), PetscObjectDereference()
536: @*/
537: PetscErrorCode  PetscObjectReference(PetscObject obj)
538: {
540:   if (!obj) return(0);
542:   obj->refct++;
543:   return(0);
544: }

548: /*@
549:    PetscObjectGetReference - Gets the current reference count for
550:    any PETSc object.

552:    Not Collective

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

558:    Output Parameter:
559: .  cnt - the reference count

561:    Level: advanced

563: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
564: @*/
565: PetscErrorCode  PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
566: {
570:   *cnt = obj->refct;
571:   return(0);
572: }

576: /*@
577:    PetscObjectDereference - Indicates to any PetscObject that it is being
578:    referenced by one less PetscObject. This decreases the reference
579:    count for that object by one.

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

583:    Input Parameter:
584: .  obj - the PETSc object; this must be cast with (PetscObject), for example,
585:          PetscObjectDereference((PetscObject)mat);

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

589:    Level: advanced

591: .seealso: PetscObjectCompose(), PetscObjectReference()
592: @*/
593: PetscErrorCode  PetscObjectDereference(PetscObject obj)
594: {

599:   if (obj->bops->destroy) {
600:     (*obj->bops->destroy)(&obj);
601:   } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
602:   return(0);
603: }

605: /* ----------------------------------------------------------------------- */
606: /*
607:      The following routines are the versions private to the PETSc object
608:      data structures.
609: */
612: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
613: {
616:   *comm = obj->comm;
617:   return(0);
618: }

622: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
623: {

628:   PetscObjectListRemoveReference(&obj->olist,name);
629:   return(0);
630: }

634: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
635: {
637:   char           *tname;
638:   PetscBool      skipreference;

641:   if (ptr) {
642:     PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
643:     if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
644:   }
645:   PetscObjectListAdd(&obj->olist,name,ptr);
646:   return(0);
647: }

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

657:   PetscObjectListFind(obj->olist,name,ptr);
658:   return(0);
659: }

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

669:   PetscFunctionListAdd(&obj->qlist,name,ptr);
670:   return(0);
671: }

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

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

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

690:    Not Collective

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

699:    Level: advanced

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

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

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

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

715:    Concepts: objects^composing
716:    Concepts: composing objects

718: .seealso: PetscObjectQuery(), PetscContainerCreate()
719: @*/
720: PetscErrorCode  PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
721: {

728:   (*obj->bops->compose)(obj,name,ptr);
729:   return(0);
730: }

734: /*@C
735:    PetscObjectSetPrecision - sets the precision used within a given object.

737:    Collective on the PetscObject

739:    Input Parameters:
740: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
741:          PetscObjectCompose((PetscObject)mat,...);
742: -  precision - the precision

744:    Level: advanced

746: .seealso: PetscObjectQuery(), PetscContainerCreate()
747: @*/
748: PetscErrorCode  PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
749: {
752:   obj->precision = precision;
753:   return(0);
754: }

758: /*@C
759:    PetscObjectQuery  - Gets a PETSc object associated with a given object.

761:    Not Collective

763:    Input Parameters:
764: +  obj - the PETSc object
765:          Thus must be cast with a (PetscObject), for example,
766:          PetscObjectCompose((PetscObject)mat,...);
767: .  name - name associated with child object
768: -  ptr - the other PETSc object associated with the PETSc object, this must be
769:          cast with (PetscObject*)

771:    Level: advanced

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

775:    Concepts: objects^composing
776:    Concepts: composing objects
777:    Concepts: objects^querying
778:    Concepts: querying objects

780: .seealso: PetscObjectCompose()
781: @*/
782: PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
783: {

790:   (*obj->bops->query)(obj,name,ptr);
791:   return(0);
792: }

794: /*MC
795:    PetscObjectComposeFunction - Associates a function with a given PETSc object.

797:     Synopsis:
798:     #include "petscsys.h"
799:     PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))

801:    Logically Collective on PetscObject

803:    Input Parameters:
804: +  obj - the PETSc object; this must be cast with a (PetscObject), for example,
805:          PetscObjectCompose((PetscObject)mat,...);
806: .  name - name associated with the child function
807: .  fname - name of the function
808: -  fptr - function pointer

810:    Level: advanced

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

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

818:    Concepts: objects^composing functions
819:    Concepts: composing functions
820:    Concepts: functions^querying
821:    Concepts: objects^querying
822:    Concepts: querying objects

824: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
825: M*/

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

836:   (*obj->bops->composefunction)(obj,name,fptr);
837:   return(0);
838: }

840: /*MC
841:    PetscObjectQueryFunction - Gets a function associated with a given object.

843:     Synopsis:
844:     #include "petscsys.h"
845:     PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))

847:    Logically Collective on PetscObject

849:    Input Parameters:
850: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
851:          PetscObjectQueryFunction((PetscObject)ksp,...);
852: -  name - name associated with the child function

854:    Output Parameter:
855: .  fptr - function pointer

857:    Level: advanced

859:    Concepts: objects^composing functions
860:    Concepts: composing functions
861:    Concepts: functions^querying
862:    Concepts: objects^querying
863:    Concepts: querying objects

865: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
866: M*/
869: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
870: {

876:   (*obj->bops->queryfunction)(obj,name,ptr);
877:   return(0);
878: }

880: struct _p_PetscContainer {
881:   PETSCHEADER(int);
882:   void           *ptr;
883:   PetscErrorCode (*userdestroy)(void*);
884: };

888: /*@C
889:    PetscContainerGetPointer - Gets the pointer value contained in the container.

891:    Not Collective

893:    Input Parameter:
894: .  obj - the object created with PetscContainerCreate()

896:    Output Parameter:
897: .  ptr - the pointer value

899:    Level: advanced

901: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
902:           PetscContainerSetPointer()
903: @*/
904: PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
905: {
909:   *ptr = obj->ptr;
910:   return(0);
911: }


916: /*@C
917:    PetscContainerSetPointer - Sets the pointer value contained in the container.

919:    Logically Collective on PetscContainer

921:    Input Parameters:
922: +  obj - the object created with PetscContainerCreate()
923: -  ptr - the pointer value

925:    Level: advanced

927: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
928:           PetscContainerGetPointer()
929: @*/
930: PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
931: {
935:   obj->ptr = ptr;
936:   return(0);
937: }

941: /*@C
942:    PetscContainerDestroy - Destroys a PETSc container object.

944:    Collective on PetscContainer

946:    Input Parameter:
947: .  obj - an object that was created with PetscContainerCreate()

949:    Level: advanced

951: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
952: @*/
953: PetscErrorCode  PetscContainerDestroy(PetscContainer *obj)
954: {

958:   if (!*obj) return(0);
960:   if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
961:   if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
962:   PetscHeaderDestroy(obj);
963:   return(0);
964: }

968: /*@C
969:    PetscContainerSetUserDestroy - Sets name of the user destroy function.

971:    Logically Collective on PetscContainer

973:    Input Parameter:
974: +  obj - an object that was created with PetscContainerCreate()
975: -  des - name of the user destroy function

977:    Level: advanced

979: .seealso: PetscContainerDestroy()
980: @*/
981: PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
982: {
985:   obj->userdestroy = des;
986:   return(0);
987: }

989: PetscClassId PETSC_CONTAINER_CLASSID;

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

999:    Collective on MPI_Comm

1001:    Input Parameters:
1002: .  comm - MPI communicator that shares the object

1004:    Output Parameters:
1005: .  container - the container created

1007:    Level: advanced

1009: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
1010: @*/
1011: PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
1012: {
1014:   PetscContainer contain;

1018:   PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);
1019:   *container = contain;
1020:   return(0);
1021: }

1025: /*@
1026:    PetscObjectSetFromOptions - Sets generic parameters from user options.

1028:    Collective on obj

1030:    Input Parameter:
1031: .  obj - the PetscObjcet

1033:    Options Database Keys:

1035:    Notes:
1036:    We have no generic options at present, so this does nothing

1038:    Level: beginner

1040: .keywords: set, options, database
1041: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1042: @*/
1043: PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
1044: {
1047:   return(0);
1048: }

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

1055:    Collective on PetscObject

1057:    Input Parameters:
1058: .  obj - the PetscObject

1060:    Notes:
1061:    This does nothing at present.

1063:    Level: advanced

1065: .keywords: setup
1066: .seealso: PetscObjectDestroy()
1067: @*/
1068: PetscErrorCode  PetscObjectSetUp(PetscObject obj)
1069: {
1072:   return(0);
1073: }