Actual source code: inherit.c

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    151:    Logically Collective on PetscObject

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

    157:    Level: developer

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

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

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

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

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

    189:    Logically Collective

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

    198:    Level: developer

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

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

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

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

    228:    Logically Collective

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

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

    239:    Level: developer

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

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

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

    260:    Logically Collective on PetscViewer

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

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

    269:    Level: advanced

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

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

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

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

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

    327: #if defined(PETSC_USE_LOG)

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

    332:    Logically Collective on PetscViewer

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

    337:    Level: advanced

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

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

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

    356:    Not collective

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

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

    365:    Level: advanced

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

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

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

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

    398:    Level: developer

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

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

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

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

    420:    Level: developer

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

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

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

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

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

    445:     Not Collective

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

    453:     Level: developer

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

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

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

    471:     Not Collective

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

    476:     Level: developer

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

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

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

    491:     Not Collective

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

    496:     Level: developer

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

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

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

    516:    Logically Collective on PetscObject

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

    522:    Level: advanced

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

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

    538:    Not Collective

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

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

    547:    Level: advanced

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

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

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

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

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

    573:    Level: advanced

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

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

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

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

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

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

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

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

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

    643:    Not Collective

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

    652:    Level: advanced

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

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

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

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

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

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

    683:    Not Collective

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

    693:    Level: advanced

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

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

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

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

    715:    Logically Collective on PetscObject

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

    724:    Level: advanced

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

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

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

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

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

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

    750:    Logically Collective on PetscObject

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

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

    760:    Level: advanced

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

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

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

    781:    Logically Collective on PetscContainer

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

    786:    Level: advanced

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

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

    799:    Not Collective

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

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

    807:    Level: advanced

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

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

    823:    Logically Collective on PetscContainer

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

    829:    Level: advanced

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

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

    845:    Collective on PetscContainer

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

    850:    Level: advanced

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

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

    867:    Logically Collective on PetscContainer

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

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

    876:    Level: advanced

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

    887: PetscClassId PETSC_CONTAINER_CLASSID;

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

    895:    Collective

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

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

    903:    Level: advanced

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

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

    918:    Collective on obj

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

    923:    Options Database Keys:

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

    928:    Level: beginner

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

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

    941:    Collective on PetscObject

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

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

    949:    Level: advanced

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