Actual source code: inherit.c

petsc-master 2014-12-28
Report Typos and Errors
  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: #if defined(PETSC_USE_LOG)
  9: PetscObject *PetscObjects      = 0;
 10: PetscInt    PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;
 11: #endif

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

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

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

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

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

 78:   PetscObjects                        = newPetscObjects;
 79:   PetscObjects[PetscObjectsMaxCounts] = h;
 80:   PetscObjectsMaxCounts               = newPetscObjectsMaxCounts;
 81: #endif
 82:   return(0);
 83: }

 85: extern PetscBool      PetscMemoryCollectMaximumUsage;
 86: extern PetscLogDouble PetscMemoryMaximumUsage;

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

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

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

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

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

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

156:    Logically Collective on PetscObject

158:    Input Parameter:
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:   }
189:   return(0);
190: }

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

197:    Logically Collective

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

206:    Level: developer

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

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

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

236: /*@C
237:    PetscObjectGetFortranCallback - get fortran callback function pointer and context

239:    Logically Collective

241:    Input Arguments:
242: +  obj - object on which to get callback
243: .  cbtype - callback type
244: -  cid - address of callback Id

246:    Output Arguments:
247: +  func - Fortran function (or NULL if not needed)
248: -  ctx - Fortran context (or NULL if not needed)

250:    Level: developer

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

260:   if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
261:   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");
262:   cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
263:   if (func) *func = cb->func;
264:   if (ctx) *ctx = cb->ctx;
265:   return(0);
266: }

268: #if defined(PETSC_USE_LOG)
271: /*@C
272:    PetscObjectsDump - Prints the currently existing objects.

274:    Logically Collective on PetscViewer

276:    Input Parameter:
277: +  fd - file pointer
278: -  all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects

280:    Options Database:
281: .  -objects_dump <all>

283:    Level: advanced

285:    Concepts: options database^printing

287: @*/
288: PetscErrorCode  PetscObjectsDump(FILE *fd,PetscBool all)
289: {
291:   PetscInt       i;
292: #if defined(PETSC_USE_DEBUG)
293:   PetscInt       j,k=0;
294: #endif
295:   PetscObject    h;

298:   if (PetscObjectsCounts) {
299:     PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");
300:     PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");
301:     for (i=0; i<PetscObjectsMaxCounts; i++) {
302:       if ((h = PetscObjects[i])) {
303:         PetscObjectName(h);
304:         {
305: #if defined(PETSC_USE_DEBUG)
306:         PetscStack *stack = 0;
307:         char       *create,*rclass;

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

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

329: #if defined(PETSC_USE_DEBUG)
330:         PetscMallocGetStack(h,&stack);
331:         if (stack) {
332:           for (j=k; j>=0; j--) {
333:             fprintf(fd,"      [%d]  %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]);
334:           }
335:         }
336: #endif
337:         }
338:       }
339:     }
340:   }
341:   return(0);
342: }
343: #endif

345: #if defined(PETSC_USE_LOG)

349: /*@C
350:    PetscObjectsView - Prints the currently existing objects.

352:    Logically Collective on PetscViewer

354:    Input Parameter:
355: .  viewer - must be an PETSCVIEWERASCII viewer

357:    Level: advanced

359:    Concepts: options database^printing

361: @*/
362: PetscErrorCode  PetscObjectsView(PetscViewer viewer)
363: {
365:   PetscBool      isascii;
366:   FILE           *fd;

369:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
370:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
371:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
372:   PetscViewerASCIIGetPointer(viewer,&fd);
373:   PetscObjectsDump(fd,PETSC_TRUE);
374:   return(0);
375: }

379: /*@C
380:    PetscObjectsGetObject - Get a pointer to a named object

382:    Not collective

384:    Input Parameter:
385: .  name - the name of an object

387:    Output Parameter:
388: .   obj - the object or null if there is no object

390:    Level: advanced

392:    Concepts: options database^printing

394: @*/
395: PetscErrorCode  PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
396: {
398:   PetscInt       i;
399:   PetscObject    h;
400:   PetscBool      flg;

403:   *obj = NULL;
404:   for (i=0; i<PetscObjectsMaxCounts; i++) {
405:     if ((h = PetscObjects[i])) {
406:       PetscObjectName(h);
407:       PetscStrcmp(h->name,name,&flg);
408:       if (flg) {
409:         *obj = h;
410:         if (classname) *classname = h->class_name;
411:         return(0);
412:       }
413:     }
414:   }
415:   return(0);
416: }

420: char *PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj)
421: {
423:   PetscInt       i;
424:   PetscObject    h;
425:   PetscBool      flg;

428:   *obj = NULL;
429:   for (i=0; i<PetscObjectsMaxCounts; i++) {
430:     if ((h = PetscObjects[i])) {
431:       PetscObjectName(h);if (ierr) return(0);
432:       PetscStrcmp(h->name,name,&flg);if (ierr) return(0);
433:       if (flg) {
434:         *obj = h;
435:         PetscFunctionReturn(h->class_name);
436:       }
437:     }
438:   }
439:   return(0);
440: }
441: #endif

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

448:     Not Collective

450:     Input Parameter:
451: +   obj - the PETSc object
452: .   handle - function that checks for options
453: .   destroy - function to destroy context if provided
454: -   ctx - optional context for check function

456:     Level: developer


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

461: @*/
462: PetscErrorCode  PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
463: {
466:   if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
467:   obj->optionhandler[obj->noptionhandler] = handle;
468:   obj->optiondestroy[obj->noptionhandler] = destroy;
469:   obj->optionctx[obj->noptionhandler++]   = ctx;
470:   return(0);
471: }

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

478:     Not Collective

480:     Input Parameter:
481: .   obj - the PETSc object

483:     Level: developer


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

488: @*/
489: PetscErrorCode  PetscObjectProcessOptionsHandlers(PetscObject obj)
490: {
491:   PetscInt       i;

496:   for (i=0; i<obj->noptionhandler; i++) {
497:     (*obj->optionhandler[i])(obj,obj->optionctx[i]);
498:   }
499:   return(0);
500: }

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

507:     Not Collective

509:     Input Parameter:
510: .   obj - the PETSc object

512:     Level: developer


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

517: @*/
518: PetscErrorCode  PetscObjectDestroyOptionsHandlers(PetscObject obj)
519: {
520:   PetscInt       i;

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


537: /*@
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: }

563: /*@
564:    PetscObjectGetReference - Gets the current reference count for
565:    any PETSc object.

567:    Not Collective

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

573:    Output Parameter:
574: .  cnt - the reference count

576:    Level: advanced

578: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
579: @*/
580: PetscErrorCode  PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
581: {
585:   *cnt = obj->refct;
586:   return(0);
587: }

591: /*@
592:    PetscObjectDereference - Indicates to any PetscObject that it is being
593:    referenced by one less PetscObject. This decreases the reference
594:    count for that object by one.

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

598:    Input Parameter:
599: .  obj - the PETSc object; this must be cast with (PetscObject), for example,
600:          PetscObjectDereference((PetscObject)mat);

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

604:    Level: advanced

606: .seealso: PetscObjectCompose(), PetscObjectReference()
607: @*/
608: PetscErrorCode  PetscObjectDereference(PetscObject obj)
609: {

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

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

638: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
639: {

644:   PetscObjectListRemoveReference(&obj->olist,name);
645:   return(0);
646: }

650: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
651: {
653:   char           *tname;
654:   PetscBool      skipreference;

657:   if (ptr) {
658:     PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
659:     if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
660:   }
661:   PetscObjectListAdd(&obj->olist,name,ptr);
662:   return(0);
663: }

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

673:   PetscObjectListFind(obj->olist,name,ptr);
674:   return(0);
675: }

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

685:   PetscFunctionListAdd(&obj->qlist,name,ptr);
686:   return(0);
687: }

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

697:   PetscFunctionListFind(obj->qlist,name,ptr);
698:   return(0);
699: }

703: /*@C
704:    PetscObjectCompose - Associates another PETSc object with a given PETSc object.

706:    Not Collective

708:    Input Parameters:
709: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
710:          PetscObjectCompose((PetscObject)mat,...);
711: .  name - name associated with the child object
712: -  ptr - the other PETSc object to associate with the PETSc object; this must also be
713:          cast with (PetscObject)

715:    Level: advanced

717:    Notes:
718:    The second objects reference count is automatically increased by one when it is
719:    composed.

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

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

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

731:    Concepts: objects^composing
732:    Concepts: composing objects

734: .seealso: PetscObjectQuery(), PetscContainerCreate()
735: @*/
736: PetscErrorCode  PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
737: {

744:   (*obj->bops->compose)(obj,name,ptr);
745:   return(0);
746: }

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

753:    Collective on the PetscObject

755:    Input Parameters:
756: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
757:          PetscObjectCompose((PetscObject)mat,...);
758: -  precision - the precision

760:    Level: advanced

762: .seealso: PetscObjectQuery(), PetscContainerCreate()
763: @*/
764: PetscErrorCode  PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
765: {
768:   obj->precision = precision;
769:   return(0);
770: }

774: /*@C
775:    PetscObjectQuery  - Gets a PETSc object associated with a given object.

777:    Not Collective

779:    Input Parameters:
780: +  obj - the PETSc object
781:          Thus must be cast with a (PetscObject), for example,
782:          PetscObjectCompose((PetscObject)mat,...);
783: .  name - name associated with child object
784: -  ptr - the other PETSc object associated with the PETSc object, this must be
785:          cast with (PetscObject*)

787:    Level: advanced

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

791:    Concepts: objects^composing
792:    Concepts: composing objects
793:    Concepts: objects^querying
794:    Concepts: querying objects

796: .seealso: PetscObjectCompose()
797: @*/
798: PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
799: {

806:   (*obj->bops->query)(obj,name,ptr);
807:   return(0);
808: }

810: /*MC
811:    PetscObjectComposeFunction - Associates a function with a given PETSc object.

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

817:    Logically Collective on PetscObject

819:    Input Parameters:
820: +  obj - the PETSc object; this must be cast with a (PetscObject), for example,
821:          PetscObjectCompose((PetscObject)mat,...);
822: .  name - name associated with the child function
823: .  fname - name of the function
824: -  fptr - function pointer

826:    Level: advanced

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

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

834:    Concepts: objects^composing functions
835:    Concepts: composing functions
836:    Concepts: functions^querying
837:    Concepts: objects^querying
838:    Concepts: querying objects

840: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
841: M*/

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

852:   (*obj->bops->composefunction)(obj,name,fptr);
853:   return(0);
854: }

856: /*MC
857:    PetscObjectQueryFunction - Gets a function associated with a given object.

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

863:    Logically Collective on PetscObject

865:    Input Parameters:
866: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
867:          PetscObjectQueryFunction((PetscObject)ksp,...);
868: -  name - name associated with the child function

870:    Output Parameter:
871: .  fptr - function pointer

873:    Level: advanced

875:    Concepts: objects^composing functions
876:    Concepts: composing functions
877:    Concepts: functions^querying
878:    Concepts: objects^querying
879:    Concepts: querying objects

881: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
882: M*/
885: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
886: {

892:   (*obj->bops->queryfunction)(obj,name,ptr);
893:   return(0);
894: }

896: struct _p_PetscContainer {
897:   PETSCHEADER(int);
898:   void           *ptr;
899:   PetscErrorCode (*userdestroy)(void*);
900: };

904: /*@C
905:    PetscContainerGetPointer - Gets the pointer value contained in the container.

907:    Not Collective

909:    Input Parameter:
910: .  obj - the object created with PetscContainerCreate()

912:    Output Parameter:
913: .  ptr - the pointer value

915:    Level: advanced

917: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
918:           PetscContainerSetPointer()
919: @*/
920: PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
921: {
925:   *ptr = obj->ptr;
926:   return(0);
927: }


932: /*@C
933:    PetscContainerSetPointer - Sets the pointer value contained in the container.

935:    Logically Collective on PetscContainer

937:    Input Parameters:
938: +  obj - the object created with PetscContainerCreate()
939: -  ptr - the pointer value

941:    Level: advanced

943: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
944:           PetscContainerGetPointer()
945: @*/
946: PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
947: {
951:   obj->ptr = ptr;
952:   return(0);
953: }

957: /*@C
958:    PetscContainerDestroy - Destroys a PETSc container object.

960:    Collective on PetscContainer

962:    Input Parameter:
963: .  obj - an object that was created with PetscContainerCreate()

965:    Level: advanced

967: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
968: @*/
969: PetscErrorCode  PetscContainerDestroy(PetscContainer *obj)
970: {

974:   if (!*obj) return(0);
976:   if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
977:   if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
978:   PetscHeaderDestroy(obj);
979:   return(0);
980: }

984: /*@C
985:    PetscContainerSetUserDestroy - Sets name of the user destroy function.

987:    Logically Collective on PetscContainer

989:    Input Parameter:
990: +  obj - an object that was created with PetscContainerCreate()
991: -  des - name of the user destroy function

993:    Level: advanced

995: .seealso: PetscContainerDestroy()
996: @*/
997: PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
998: {
1001:   obj->userdestroy = des;
1002:   return(0);
1003: }

1005: PetscClassId PETSC_CONTAINER_CLASSID;

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

1015:    Collective on MPI_Comm

1017:    Input Parameters:
1018: .  comm - MPI communicator that shares the object

1020:    Output Parameters:
1021: .  container - the container created

1023:    Level: advanced

1025: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
1026: @*/
1027: PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
1028: {
1030:   PetscContainer contain;

1034:   PetscSysInitializePackage();
1035:   PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);
1036:   *container = contain;
1037:   return(0);
1038: }

1042: /*@
1043:    PetscObjectSetFromOptions - Sets generic parameters from user options.

1045:    Collective on obj

1047:    Input Parameter:
1048: .  obj - the PetscObjcet

1050:    Options Database Keys:

1052:    Notes:
1053:    We have no generic options at present, so this does nothing

1055:    Level: beginner

1057: .keywords: set, options, database
1058: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
1059: @*/
1060: PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
1061: {
1064:   return(0);
1065: }

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

1072:    Collective on PetscObject

1074:    Input Parameters:
1075: .  obj - the PetscObject

1077:    Notes:
1078:    This does nothing at present.

1080:    Level: advanced

1082: .keywords: setup
1083: .seealso: PetscObjectDestroy()
1084: @*/
1085: PetscErrorCode  PetscObjectSetUp(PetscObject obj)
1086: {
1089:   return(0);
1090: }