Date: 2013-07-02T14:38:53+00:00

Actual source code: inherit.c
petsc-3.4.2 2013-07-02

      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;
    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:         k    = stack->currentsize-2;
    300:         if (!all) {
    301:           k = 0;
    302:           while (!stack->petscroutine[k]) k++;
    303:           PetscStrstr(stack->function[k],"Create",&create);
    304:           if (!create) {
    305:             PetscStrstr(stack->function[k],"Get",&create);
    306:           }
    307:           PetscStrstr(stack->function[k],h->class_name,&rclass);

    309:           if (!create) continue;
    310:           if (!rclass) continue;
    311:         }
    312: #endif

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

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

    332: /*@C
    333:    PetscObjectsView - Prints the currently existing objects.

    335:    Logically Collective on PetscViewer

    337:    Input Parameter:
    338: .  viewer - must be an PETSCVIEWERASCII viewer

    340:    Level: advanced

    342:    Concepts: options database^printing

    344: @*/
    345: PetscErrorCode  PetscObjectsView(PetscViewer viewer)
    346: {
    348:   PetscBool      isascii;
    349:   FILE           *fd;

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

    362: /*@C
    363:    PetscObjectsGetObject - Get a pointer to a named object

    365:    Not collective

    367:    Input Parameter:
    368: .  name - the name of an object

    370:    Output Parameter:
    371: .   obj - the object or null if there is no object

    373:    Level: advanced

    375:    Concepts: options database^printing

    377: @*/
    378: PetscErrorCode  PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
    379: {
    381:   PetscInt       i;
    382:   PetscObject    h;
    383:   PetscBool      flg;

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

    403: char *PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj)
    404: {
    406:   PetscInt       i;
    407:   PetscObject    h;
    408:   PetscBool      flg;

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

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

    430:     Not Collective

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

    438:     Level: developer

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

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

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

    460:     Not Collective

    462:     Input Parameter:
    463: .   obj - the PETSc object

    465:     Level: developer

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

    470: @*/
    471: PetscErrorCode  PetscObjectProcessOptionsHandlers(PetscObject obj)
    472: {
    473:   PetscInt       i;

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

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

    489:     Not Collective

    491:     Input Parameter:
    492: .   obj - the PETSc object

    494:     Level: developer

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

    499: @*/
    500: PetscErrorCode  PetscObjectDestroyOptionsHandlers(PetscObject obj)
    501: {
    502:   PetscInt       i;

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

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

    524:    Logically Collective on PetscObject

    526:    Input Parameter:
    527: .  obj - the PETSc object. This must be cast with (PetscObject), for example,
    528:          PetscObjectReference((PetscObject)mat);

    530:    Level: advanced

    532: .seealso: PetscObjectCompose(), PetscObjectDereference()
    533: @*/
    534: PetscErrorCode  PetscObjectReference(PetscObject obj)
    535: {
    537:   if (!obj) return(0);
    539:   obj->refct++;
    540:   return(0);
    541: }

    545: /*@
    546:    PetscObjectGetReference - Gets the current reference count for
    547:    any PETSc object.

    549:    Not Collective

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

    555:    Output Parameter:
    556: .  cnt - the reference count

    558:    Level: advanced

    560: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
    561: @*/
    562: PetscErrorCode  PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
    563: {
    567:   *cnt = obj->refct;
    568:   return(0);
    569: }

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

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

    580:    Input Parameter:
    581: .  obj - the PETSc object; this must be cast with (PetscObject), for example,
    582:          PetscObjectDereference((PetscObject)mat);

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

    586:    Level: advanced

    588: .seealso: PetscObjectCompose(), PetscObjectReference()
    589: @*/
    590: PetscErrorCode  PetscObjectDereference(PetscObject obj)
    591: {

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

    602: /* ----------------------------------------------------------------------- */
    603: /*
    604:      The following routines are the versions private to the PETSc object
    605:      data structures.
    606: */
    609: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
    610: {
    613:   *comm = obj->comm;
    614:   return(0);
    615: }

    619: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
    620: {

    625:   PetscObjectListRemoveReference(&obj->olist,name);
    626:   return(0);
    627: }

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

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

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

    654:   PetscObjectListFind(obj->olist,name,ptr);
    655:   return(0);
    656: }

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

    666:   PetscFunctionListAdd(&obj->qlist,name,ptr);
    667:   return(0);
    668: }

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

    678:   PetscFunctionListFind(obj->qlist,name,ptr);
    679:   return(0);
    680: }

    684: /*@C
    685:    PetscObjectCompose - Associates another PETSc object with a given PETSc object.

    687:    Not Collective

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

    696:    Level: advanced

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

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

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

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

    712:    Concepts: objects^composing
    713:    Concepts: composing objects

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

    725:   (*obj->bops->compose)(obj,name,ptr);
    726:   return(0);
    727: }

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

    734:    Collective on the PetscObject

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

    741:    Level: advanced

    743: .seealso: PetscObjectQuery(), PetscContainerCreate()
    744: @*/
    745: PetscErrorCode  PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
    746: {
    749:   obj->precision = precision;
    750:   return(0);
    751: }

    755: /*@C
    756:    PetscObjectQuery  - Gets a PETSc object associated with a given object.

    758:    Not Collective

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

    768:    Level: advanced

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

    772:    Concepts: objects^composing
    773:    Concepts: composing objects
    774:    Concepts: objects^querying
    775:    Concepts: querying objects

    777: .seealso: PetscObjectCompose()
    778: @*/
    779: PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
    780: {

    787:   (*obj->bops->query)(obj,name,ptr);
    788:   return(0);
    789: }

    791: /*MC
    792:    PetscObjectComposeFunction - Associates a function with a given PETSc object.

    794:     Synopsis:
    795:     #include "petscsys.h"
    796:     PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))

    798:    Logically Collective on PetscObject

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

    807:    Level: advanced

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

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

    815:    Concepts: objects^composing functions
    816:    Concepts: composing functions
    817:    Concepts: functions^querying
    818:    Concepts: objects^querying
    819:    Concepts: querying objects

    821: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
    822: M*/

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

    833:   (*obj->bops->composefunction)(obj,name,fptr);
    834:   return(0);
    835: }

    837: /*MC
    838:    PetscObjectQueryFunction - Gets a function associated with a given object.

    840:     Synopsis:
    841:     #include "petscsys.h"
    842:     PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))

    844:    Logically Collective on PetscObject

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

    851:    Output Parameter:
    852: .  fptr - function pointer

    854:    Level: advanced

    856:    Concepts: objects^composing functions
    857:    Concepts: composing functions
    858:    Concepts: functions^querying
    859:    Concepts: objects^querying
    860:    Concepts: querying objects

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

    873:   (*obj->bops->queryfunction)(obj,name,ptr);
    874:   return(0);
    875: }

    877: struct _p_PetscContainer {
    878:   PETSCHEADER(int);
    879:   void           *ptr;
    880:   PetscErrorCode (*userdestroy)(void*);
    881: };

    885: /*@C
    886:    PetscContainerGetPointer - Gets the pointer value contained in the container.

    888:    Not Collective

    890:    Input Parameter:
    891: .  obj - the object created with PetscContainerCreate()

    893:    Output Parameter:
    894: .  ptr - the pointer value

    896:    Level: advanced

    898: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
    899:           PetscContainerSetPointer()
    900: @*/
    901: PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
    902: {
    906:   *ptr = obj->ptr;
    907:   return(0);
    908: }

    913: /*@C
    914:    PetscContainerSetPointer - Sets the pointer value contained in the container.

    916:    Logically Collective on PetscContainer

    918:    Input Parameters:
    919: +  obj - the object created with PetscContainerCreate()
    920: -  ptr - the pointer value

    922:    Level: advanced

    924: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
    925:           PetscContainerGetPointer()
    926: @*/
    927: PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
    928: {
    932:   obj->ptr = ptr;
    933:   return(0);
    934: }

    938: /*@C
    939:    PetscContainerDestroy - Destroys a PETSc container object.

    941:    Collective on PetscContainer

    943:    Input Parameter:
    944: .  obj - an object that was created with PetscContainerCreate()

    946:    Level: advanced

    948: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
    949: @*/
    950: PetscErrorCode  PetscContainerDestroy(PetscContainer *obj)
    951: {

    955:   if (!*obj) return(0);
    957:   if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
    958:   if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
    959:   PetscHeaderDestroy(obj);
    960:   return(0);
    961: }

    965: /*@C
    966:    PetscContainerSetUserDestroy - Sets name of the user destroy function.

    968:    Logically Collective on PetscContainer

    970:    Input Parameter:
    971: +  obj - an object that was created with PetscContainerCreate()
    972: -  des - name of the user destroy function

    974:    Level: advanced

    976: .seealso: PetscContainerDestroy()
    977: @*/
    978: PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
    979: {
    982:   obj->userdestroy = des;
    983:   return(0);
    984: }

    986: PetscClassId PETSC_CONTAINER_CLASSID;

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

    996:    Collective on MPI_Comm

    998:    Input Parameters:
    999: .  comm - MPI communicator that shares the object

    1001:    Output Parameters:
    1002: .  container - the container created

    1004:    Level: advanced

    1006: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
    1007: @*/
    1008: PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
    1009: {
    1011:   PetscContainer contain;

    1015:   PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);
    1016:   *container = contain;
    1017:   return(0);
    1018: }

    1022: /*@
    1023:    PetscObjectSetFromOptions - Sets generic parameters from user options.

    1025:    Collective on obj

    1027:    Input Parameter:
    1028: .  obj - the PetscObjcet

    1030:    Options Database Keys:

    1032:    Notes:
    1033:    We have no generic options at present, so this does nothing

    1035:    Level: beginner

    1037: .keywords: set, options, database
    1038: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
    1039: @*/
    1040: PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
    1041: {
    1044:   return(0);
    1045: }

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

    1052:    Collective on PetscObject

    1054:    Input Parameters:
    1055: .  obj - the PetscObject

    1057:    Notes:
    1058:    This does nothing at present.

    1060:    Level: advanced

    1062: .keywords: setup
    1063: .seealso: PetscObjectDestroy()
    1064: @*/
    1065: PetscErrorCode  PetscObjectSetUp(PetscObject obj)
    1066: {
    1069:   return(0);
    1070: }